From 81d1dd7465524b1fd0f19a9d4acd1934e6c4a5a3 Mon Sep 17 00:00:00 2001 From: ishuen <12228644+ishuen@users.noreply.github.com> Date: Tue, 11 Oct 2022 21:04:06 +0800 Subject: [PATCH 01/79] Remove extra arrow and adjust cross position --- .../mermaid/src/diagrams/sequence/svgDraw.js | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index 0dc437721..ed4373514 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -752,7 +752,7 @@ export const insertSequenceNumber = function (elem) { // .style("fill", '#f00'); }; /** - * Setup arrow head and define the marker. The result is appended to the svg. + * Setup cross head and define the marker. The result is appended to the svg. * * @param {any} elem */ @@ -764,26 +764,16 @@ export const insertArrowCrossHead = function (elem) { .attr('markerWidth', 15) .attr('markerHeight', 8) .attr('orient', 'auto') - .attr('refX', 16) - .attr('refY', 4); - - // The arrow - marker - .append('path') - .attr('fill', 'black') - .attr('stroke', '#000000') - .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 9,2 V 6 L16,4 Z'); - + .attr('refX', 4) + .attr('refY', 5); // The cross marker .append('path') .attr('fill', 'none') .attr('stroke', '#000000') .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7'); + .attr('stroke-width', '1pt') + .attr('d', 'M 1,2 L 6,7 M 6,2 L 1,7'); // this is actual shape for arrowhead }; From 1d9fefe7ac65990e4dd06a7e0e29976a873db844 Mon Sep 17 00:00:00 2001 From: Per Brolin Date: Fri, 4 Nov 2022 12:44:13 +0100 Subject: [PATCH 02/79] Added pie --- cypress/platform/per.html | 46 +++-- demos/pie.html | 2 +- .../mermaid/src/diagrams/pie/parser/pie.jison | 10 +- packages/mermaid/src/diagrams/pie/pieDb.js | 13 ++ .../mermaid/src/diagrams/pie/pieDetector.ts | 4 +- .../mermaid/src/diagrams/pie/pieRenderer.js | 187 +++++++++++++++++- 6 files changed, 239 insertions(+), 23 deletions(-) diff --git a/cypress/platform/per.html b/cypress/platform/per.html index 4fca4c808..f68a3f50b 100644 --- a/cypress/platform/per.html +++ b/cypress/platform/per.html @@ -6,6 +6,10 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> +
Security check
-flowchart LR
-A-->B
-        
-
-            mindmap
-          root
-            ch1
-            ch2
-        
- - - +bar title Pets adopted by volunteers + "Dogs" : 386 + "Cats" : 85 + "Rats" : 15 + + + + + + + + + + From b9dcdb00a55a1eeebba430613982129c28940573 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Fri, 18 Nov 2022 17:44:59 +0000 Subject: [PATCH 43/79] test(e2e): move mindmap tests to mindmap.spec.js Currently, we have mindmap tests in the cypress/integration/rendering/mermaid.spec.js which is a bit odd. They should probably all be in the mindmap.spec.js file. --- cypress/integration/rendering/mermaid.spec.js | 74 ------------------- cypress/integration/rendering/mindmap.spec.js | 72 +++++++++++++++++- 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/cypress/integration/rendering/mermaid.spec.js b/cypress/integration/rendering/mermaid.spec.js index 4b7de3027..c75c59017 100644 --- a/cypress/integration/rendering/mermaid.spec.js +++ b/cypress/integration/rendering/mermaid.spec.js @@ -1,75 +1 @@ import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; - -describe('Mindmap', () => { - it('square shape', () => { - imgSnapshotTest( - ` -mindmap - root[ - The root - ] - `, - {} - ); - cy.get('svg'); - }); - it('rounded rect shape', () => { - imgSnapshotTest( - ` -mindmap - root(( - The root - )) - `, - {} - ); - cy.get('svg'); - }); - it('circle shape', () => { - imgSnapshotTest( - ` -mindmap - root( - The root - ) - `, - {} - ); - cy.get('svg'); - }); - it('default shape', () => { - imgSnapshotTest( - ` -mindmap - The root - `, - {} - ); - cy.get('svg'); - }); - it('adding children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - `, - {} - ); - cy.get('svg'); - }); - it('adding grand children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - child3 - `, - {} - ); - cy.get('svg'); - }); -}); diff --git a/cypress/integration/rendering/mindmap.spec.js b/cypress/integration/rendering/mindmap.spec.js index f0cc2bc3f..61179b238 100644 --- a/cypress/integration/rendering/mindmap.spec.js +++ b/cypress/integration/rendering/mindmap.spec.js @@ -110,6 +110,76 @@ root {} ); }); - + it('square shape', () => { + imgSnapshotTest( + ` +mindmap + root[ + The root + ] + `, + {} + ); + cy.get('svg'); + }); + it('rounded rect shape', () => { + imgSnapshotTest( + ` +mindmap + root(( + The root + )) + `, + {} + ); + cy.get('svg'); + }); + it('circle shape', () => { + imgSnapshotTest( + ` +mindmap + root( + The root + ) + `, + {} + ); + cy.get('svg'); + }); + it('default shape', () => { + imgSnapshotTest( + ` +mindmap + The root + `, + {} + ); + cy.get('svg'); + }); + it('adding children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + `, + {} + ); + cy.get('svg'); + }); + it('adding grand children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + child3 + `, + {} + ); + cy.get('svg'); + }); /* The end */ }); From 57edcfe87d7dacd16f308d02651d9f9a976c33c5 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Fri, 18 Nov 2022 17:46:52 +0000 Subject: [PATCH 44/79] test(e2e): remove unused mermaid.spec.js file All tests have been moved to `mindmap.spec.js` in a previous commit. --- cypress/integration/rendering/mermaid.spec.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 cypress/integration/rendering/mermaid.spec.js diff --git a/cypress/integration/rendering/mermaid.spec.js b/cypress/integration/rendering/mermaid.spec.js deleted file mode 100644 index c75c59017..000000000 --- a/cypress/integration/rendering/mermaid.spec.js +++ /dev/null @@ -1 +0,0 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; From 537a627b754d4a9d4926968726d77bd533a719ad Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Fri, 18 Nov 2022 01:14:17 +0000 Subject: [PATCH 45/79] test(e2e): test for mindmap before snapshot Sometimes, the mindmap e2e tests take a snapshot when the mindmap SVG has been created, but hasn't yet been fully rendered. This adds a quick check for a mindmap section root, so that the snapshot is only taken after the mindmap diagram has started rendering. I was also running into JSDoc ESLint warnings, so I moved the file into a TypeScript file to fix those warnings. --- .../{mindmap.spec.js => mindmap.spec.ts} | 78 +++++++++++++++---- cypress/tsconfig.json | 8 ++ 2 files changed, 71 insertions(+), 15 deletions(-) rename cypress/integration/rendering/{mindmap.spec.js => mindmap.spec.ts} (66%) create mode 100644 cypress/tsconfig.json diff --git a/cypress/integration/rendering/mindmap.spec.js b/cypress/integration/rendering/mindmap.spec.ts similarity index 66% rename from cypress/integration/rendering/mindmap.spec.js rename to cypress/integration/rendering/mindmap.spec.ts index 61179b238..62c7e785b 100644 --- a/cypress/integration/rendering/mindmap.spec.js +++ b/cypress/integration/rendering/mindmap.spec.ts @@ -1,12 +1,32 @@ import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; +/** + * Check whether the SVG Element has a Mindmap root + * + * Sometimes, Cypress takes a snapshot before the mermaid mindmap has finished + * generating the SVG. + * + * @param $p - The element to check. + */ +function shouldHaveRoot($p: JQuery) { + // get HTML Element from jquery element + const svgElement = $p[0]; + expect(svgElement.nodeName).equal('svg'); + + const sectionRoots = svgElement.getElementsByClassName('mindmap-node section-root'); + // mindmap should have at least one root section + expect(sectionRoots).to.have.lengthOf.at.least(1); +} + describe('Mindmaps', () => { it('Only a root', () => { imgSnapshotTest( `mindmap root `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -15,7 +35,9 @@ root `mindmap root[root] `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -24,7 +46,9 @@ root[root] `mindmap root[A root with a long text that wraps to keep the node size in check] `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -34,7 +58,9 @@ root[A root with a long text that wraps to keep the node size in check] root[root] ::icon(mdi mdi-fire) `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -48,7 +74,9 @@ root))bang(( a)A cloud( ::icon(mdi mdi-fire) `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -60,7 +88,9 @@ root))bang(( a))Another bang(( a)A cloud( `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -78,7 +108,9 @@ root grandchild 5 grandchild 6 `, - {} + {}, + undefined, + shouldHaveRoot ); }); @@ -98,7 +130,9 @@ root gc6((grand
child 6)) ::icon(mdi mdi-fire) `, - {} + {}, + undefined, + shouldHaveRoot ); }); it('text shouhld wrap with icon', () => { @@ -107,7 +141,9 @@ root root Child3(A node with an icon and with a long text that wraps to keep the node size in check) `, - {} + {}, + undefined, + shouldHaveRoot ); }); it('square shape', () => { @@ -118,7 +154,9 @@ mindmap The root ] `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); @@ -130,7 +168,9 @@ mindmap The root )) `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); @@ -142,7 +182,9 @@ mindmap The root ) `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); @@ -152,7 +194,9 @@ mindmap mindmap The root `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); @@ -164,7 +208,9 @@ mindmap child1 child2 `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); @@ -177,7 +223,9 @@ mindmap child2 child3 `, - {} + {}, + undefined, + shouldHaveRoot ); cy.get('svg'); }); diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 000000000..e3351cebe --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es2020", + "lib": ["es2020", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} From fd76e0e27095997c2ac21902c0629cd6600e30d9 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Thu, 17 Nov 2022 23:54:25 +0000 Subject: [PATCH 46/79] chore: replace dagre/dagre-d3 with dagre-d3-es Replace the dagre and dagre-d3 libraries with dagre-d3-es. Both dagre and dagre-d3 are deprecated and unmaintained, and haven't been updated for more than 3 years. Since dagre-d3 still requires an old version of d3, this causes a bunch of security warnings, e.g. https://github.com/advisories/GHSA-36jr-mh4h-2g58 The [dagre-d3-es](https://github.com/tbo47/dagre-es) package is a fork that contains support for `"d3": "^7.6.1"`. Also, it's ESM, so we will hopefully get smaller bundle sizes too. The only issue is that this fork isn't very well used (only has 3000 weekly downloads), compared to `dagre-d3`'s 250,000 weekly downloads. (although to be fair, a large proportion of dagre-d3's downloads probably come from mermaid) Since it's is a less popular package, **I've pinned `dagre-d3-es` to `"7.0.2"` instead of `"^7.0.2"`**. This does mean if there is a bug in `dagre-d3-es`, we will have to manually bump it ourselves, but it also means we won't accidentally be sending a buggy version of `dagre-d3-es` out to users in cases something changes (it might be worth disabling renovate for this if we're feeling paranoid!) --- package.json | 3 -- packages/mermaid/package.json | 6 +--- packages/mermaid/src/dagre-wrapper/index.js | 4 +-- .../dagre-wrapper/mermaid-graphlib.spec.js | 1 - .../src/diagrams/class/classRenderer.js | 4 +-- .../mermaid/src/diagrams/er/erRenderer.js | 4 +-- .../src/diagrams/flowchart/flowChartShapes.js | 25 ++++++------- .../src/diagrams/flowchart/flowRenderer-v2.js | 2 +- .../src/diagrams/flowchart/flowRenderer.js | 8 ++--- .../requirement/requirementRenderer.js | 4 +-- .../src/diagrams/state/stateRenderer.js | 4 +-- packages/mermaid/src/tests/setup.ts | 2 +- pnpm-lock.yaml | 35 +++++++------------ 13 files changed, 42 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 7bd648877..70fac0ea9 100644 --- a/package.json +++ b/package.json @@ -105,9 +105,6 @@ "vitepress-plugin-search": "^1.0.4-alpha.15", "vitest": "^0.25.1" }, - "resolutions": { - "d3": "^7.6.1" - }, "sideEffects": [ "**/*.css", "**/*.scss" diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 842e9ba9a..f79ffe6f3 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -54,8 +54,7 @@ "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", - "dagre": "^0.8.5", - "dagre-d3": "^0.6.4", + "dagre-d3-es": "7.0.2", "dompurify": "2.4.1", "fast-clone": "^1.5.13", "graphlib": "^2.1.8", @@ -98,9 +97,6 @@ "typescript": "^4.8.4", "unist-util-flatmap": "^1.0.0" }, - "resolutions": { - "d3": "^7.0.0" - }, "files": [ "dist", "README.md" diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js index 72652ff8c..43fe311b3 100644 --- a/packages/mermaid/src/dagre-wrapper/index.js +++ b/packages/mermaid/src/dagre-wrapper/index.js @@ -1,4 +1,4 @@ -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import insertMarkers from './markers'; import { updateNodeBounds } from './shapes/util'; @@ -95,7 +95,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => { log.info('### Layout ###'); log.info('#############################################'); log.info(graph); - dagre.layout(graph); + dagreLayout(graph); log.info('Graph after layout:', graphlib.json.write(graph)); // Move the nodes to the correct place let diff = 0; diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js index 8155bbf70..a09e17f02 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js @@ -1,5 +1,4 @@ import graphlib from 'graphlib'; -import dagre from 'dagre'; import { validate, adjustClustersAndEdges, diff --git a/packages/mermaid/src/diagrams/class/classRenderer.js b/packages/mermaid/src/diagrams/class/classRenderer.js index 23b586192..357647427 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer.js +++ b/packages/mermaid/src/diagrams/class/classRenderer.js @@ -1,5 +1,5 @@ import { select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import svgDraw from './svgDraw'; @@ -238,7 +238,7 @@ export const draw = function (text, id, _version, diagObj) { } }); - dagre.layout(g); + dagreLayout(g); g.nodes().forEach(function (v) { if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') { log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index 323bb4607..57aa737ab 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -1,6 +1,6 @@ import graphlib from 'graphlib'; import { line, curveBasis, select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import { getConfig } from '../../config'; import { log } from '../../logger'; import erMarkers from './erMarkers'; @@ -637,7 +637,7 @@ export const draw = function (text, id, _version, diagObj) { // Add all the relationships to the graph const relationships = addRelationships(diagObj.db.getRelationships(), g); - dagre.layout(g); // Node and edge positions will be updated + dagreLayout(g); // Node and edge positions will be updated // Adjust the positions of the entities so that they adhere to the layout adjustEntities(svg, g); diff --git a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js index b66bfe730..d02d484c4 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js +++ b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js @@ -1,4 +1,5 @@ -import dagreD3 from 'dagre-d3'; +import { intersectPolygon } from 'dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js'; +import { intersectRect } from 'dagre-d3-es/src/dagre-js/intersect/intersect-rect.js'; /** * @param parent @@ -17,7 +18,7 @@ function question(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, s, s, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -42,7 +43,7 @@ function hexagon(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -64,7 +65,7 @@ function rect_left_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -85,7 +86,7 @@ function lean_right(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -106,7 +107,7 @@ function lean_left(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -127,7 +128,7 @@ function trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -148,7 +149,7 @@ function inv_trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -170,7 +171,7 @@ function rect_right_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -194,7 +195,7 @@ function stadium(parent, bbox, node) { .attr('height', h); node.intersect = function (point) { - return dagreD3.intersect.rect(node, point); + return intersectRect(node, point); }; return shapeSvg; } @@ -221,7 +222,7 @@ function subroutine(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -270,7 +271,7 @@ function cylinder(parent, bbox, node) { .attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')'); node.intersect = function (point) { - const pos = dagreD3.intersect.rect(node, point); + const pos = intersectRect(node, point); const x = pos.x - node.x; if ( diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js index 6b7c4c1bf..86eb52504 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js @@ -5,7 +5,7 @@ import flowDb from './flowDb'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index c403b7fe3..0fcbce545 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -1,8 +1,9 @@ import graphlib from 'graphlib'; import { select, curveLinear, selectAll } from 'd3'; import { getConfig } from '../../config'; -import dagreD3 from 'dagre-d3'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { render as Render } from 'dagre-d3-es'; +import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; @@ -370,7 +371,6 @@ export const draw = function (text, id, _version, diagObj) { addEdges(edges, g, diagObj); // Create the renderer - const Render = dagreD3.render; const render = new Render(); // Add custom shapes @@ -390,7 +390,7 @@ export const draw = function (text, id, _version, diagObj) { .attr('orient', 'auto'); const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z'); - dagreD3.util.applyStyle(path, edge[type + 'Style']); + applyStyle(path, edge[type + 'Style']); }; // Override normal arrowhead defined in d3. Remove style & add class to allow css styling. diff --git a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js index 79d67e76e..0338ec50c 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js +++ b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js @@ -1,5 +1,5 @@ import { line, select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import { configureSvgSize } from '../../setupGraphViewbox'; @@ -348,7 +348,7 @@ export const draw = (text, id, _version, diagObj) => { drawReqs(requirements, g, svg); drawElements(elements, g, svg); addRelationships(relationships, g); - dagre.layout(g); + dagreLayout(g); adjustEntities(svg, g); relationships.forEach(function (rel) { diff --git a/packages/mermaid/src/diagrams/state/stateRenderer.js b/packages/mermaid/src/diagrams/state/stateRenderer.js index 73717a645..783460cc6 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer.js @@ -1,5 +1,5 @@ import { select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import graphlib from 'graphlib'; import { log } from '../../logger'; import common from '../common/common'; @@ -239,7 +239,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = ); }); - dagre.layout(graph); + dagreLayout(graph); log.debug('Graph after layout', graph.nodes()); const svgElem = diagram.node(); diff --git a/packages/mermaid/src/tests/setup.ts b/packages/mermaid/src/tests/setup.ts index e8058c517..b3330787c 100644 --- a/packages/mermaid/src/tests/setup.ts +++ b/packages/mermaid/src/tests/setup.ts @@ -1,3 +1,3 @@ import { vi } from 'vitest'; vi.mock('d3'); -vi.mock('dagre-d3'); +vi.mock('dagre-d3-es'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11703bd03..0a04f741e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,8 +1,5 @@ lockfileVersion: 5.4-inlineSpecifiers -overrides: - d3: ^7.6.1 - importers: .: @@ -167,14 +164,11 @@ importers: specifier: ^6.0.0 version: 6.0.0 d3: - specifier: ^7.6.1 + specifier: ^7.0.0 version: 7.6.1 - dagre: - specifier: ^0.8.5 - version: 0.8.5 - dagre-d3: - specifier: ^0.6.4 - version: 0.6.4 + dagre-d3-es: + specifier: 7.0.2 + version: 7.0.2 dompurify: specifier: 2.4.1 version: 2.4.1 @@ -318,7 +312,7 @@ importers: specifier: ^2.1.0 version: 2.1.0_cytoscape@3.23.0 d3: - specifier: ^7.6.1 + specifier: ^7.0.0 version: 7.6.1 khroma: specifier: ^2.0.0 @@ -4800,20 +4794,11 @@ packages: d3-zoom: 3.0.0 dev: false - /dagre-d3/0.6.4: - resolution: {integrity: sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==} + /dagre-d3-es/7.0.2: + resolution: {integrity: sha512-m9+5yhzkf9gyklDMdWlQC/8bayGVlTF8GspmN6XC6nnZjas6kAmffvh0c/EcyFhQ+fp4QIl0fMpNdv76AJGlVQ==} dependencies: d3: 7.6.1 - dagre: 0.8.5 - graphlib: 2.1.8 - lodash: 4.17.21 - dev: false - - /dagre/0.8.5: - resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==} - dependencies: - graphlib: 2.1.8 - lodash: 4.17.21 + lodash-es: 4.17.21 dev: false /dargs/7.0.0: @@ -7905,6 +7890,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash-es/4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true From 70f024735b57ac5b29b5c339ac871078ab46fa5a Mon Sep 17 00:00:00 2001 From: Mason Malone <651224+MasonM@users.noreply.github.com> Date: Wed, 16 Nov 2022 19:36:51 -0800 Subject: [PATCH 47/79] Add title support using YAML frontmatter --- __mocks__/d3.ts | 12 ++++ .../rendering/classDiagram-v2.spec.js | 12 ++++ .../integration/rendering/erDiagram.spec.js | 13 ++++ .../rendering/flowchart-v2.spec.js | 11 +++ .../integration/rendering/gitGraph.spec.js | 11 +++ .../rendering/stateDiagram-v2.spec.js | 12 ++++ demos/classchart.html | 3 + demos/er.html | 3 + demos/flowchart.html | 6 ++ demos/git.html | 3 + demos/journey.html | 6 +- demos/state.html | 6 ++ docs/config/setup/modules/defaultConfig.md | 2 +- docs/syntax/classDiagram.md | 12 ++++ docs/syntax/entityRelationshipDiagram.md | 6 ++ docs/syntax/flowchart.md | 12 ++++ docs/syntax/gitgraph.md | 6 ++ docs/syntax/stateDiagram.md | 6 ++ package.json | 2 + packages/mermaid/src/Diagram.ts | 11 +++ packages/mermaid/src/config.type.ts | 5 ++ packages/mermaid/src/defaultConfig.ts | 52 ++++++++++++++ .../mermaid/src/diagram-api/detectType.ts | 3 +- .../src/diagram-api/frontmatter.spec.ts | 71 +++++++++++++++++++ .../mermaid/src/diagram-api/frontmatter.ts | 39 ++++++++++ .../mermaid/src/diagrams/class/classDb.js | 4 ++ .../src/diagrams/class/classRenderer-v2.js | 3 + packages/mermaid/src/diagrams/class/styles.js | 5 ++ packages/mermaid/src/diagrams/er/erDb.js | 4 ++ .../mermaid/src/diagrams/er/erRenderer.js | 3 + packages/mermaid/src/diagrams/er/styles.js | 6 ++ .../mermaid/src/diagrams/flowchart/flowDb.js | 4 ++ .../src/diagrams/flowchart/flowRenderer-v2.js | 3 + .../mermaid/src/diagrams/flowchart/styles.ts | 6 ++ .../mermaid/src/diagrams/git/gitGraphAst.js | 4 ++ .../src/diagrams/git/gitGraphRenderer.js | 7 ++ packages/mermaid/src/diagrams/git/styles.js | 5 ++ .../mermaid/src/diagrams/state/stateDb.js | 4 ++ .../src/diagrams/state/stateRenderer-v2.js | 4 +- packages/mermaid/src/diagrams/state/styles.js | 6 ++ .../mermaid/src/docs/syntax/classDiagram.md | 6 ++ .../docs/syntax/entityRelationshipDiagram.md | 3 + packages/mermaid/src/docs/syntax/flowchart.md | 6 ++ packages/mermaid/src/docs/syntax/gitgraph.md | 3 + .../mermaid/src/docs/syntax/stateDiagram.md | 3 + packages/mermaid/src/utils.spec.js | 31 ++++++++ packages/mermaid/src/utils.ts | 27 +++++++ pnpm-lock.yaml | 10 +++ 48 files changed, 477 insertions(+), 5 deletions(-) create mode 100644 packages/mermaid/src/diagram-api/frontmatter.spec.ts create mode 100644 packages/mermaid/src/diagram-api/frontmatter.ts diff --git a/__mocks__/d3.ts b/__mocks__/d3.ts index 67f09b6f4..f90d93557 100644 --- a/__mocks__/d3.ts +++ b/__mocks__/d3.ts @@ -53,6 +53,18 @@ export const MockD3 = (name, parent) => { get __parent() { return parent; }, + node() { + return { + getBBox() { + return { + x: 5, + y: 10, + height: 15, + width: 20, + }; + }, + }; + }, }; elem.append = (name) => { const mockElem = MockD3(name, elem); diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index e36693a65..f9ed7c64b 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -496,4 +496,16 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); + + it('1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- + title: simple class diagram + --- + classDiagram-v2 + class Class10 + `, + {} + ); + }); }); diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 057b36dc1..dea3c7620 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -273,4 +273,17 @@ describe('Entity Relationship Diagram', () => { ); cy.get('svg'); }); + + it('1433: should render a simple ER diagram with a title', () => { + imgSnapshotTest( + `--- + title: simple ER diagram + --- + erDiagram + CUSTOMER ||--o{ ORDER : places + ORDER ||--|{ LINE-ITEM : contains + `, + {} + ); + }); }); diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 61dccfb84..cdf0d07ca 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -663,4 +663,15 @@ flowchart RL { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); + it('1433: should render a titled flowchart with titleTopMargin set to 0', () => { + imgSnapshotTest( + `--- + title: Simple flowchart + --- + flowchart TD + A --> B + `, + { titleTopMargin: 0 } + ); + }); }); diff --git a/cypress/integration/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js index afb39b62e..cb70f7272 100644 --- a/cypress/integration/rendering/gitGraph.spec.js +++ b/cypress/integration/rendering/gitGraph.spec.js @@ -322,4 +322,15 @@ describe('Git Graph diagram', () => { {} ); }); + it('1433: should render a simple gitgraph with a title', () => { + imgSnapshotTest( + `--- + title: simple gitGraph + --- + gitGraph + commit + `, + {} + ); + }); }); diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 5b43c890c..7c322c1b3 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -559,4 +559,16 @@ stateDiagram-v2 ); }); }); + it('1433: should render a simple state diagram with a title', () => { + imgSnapshotTest( + `--- + title: simple state diagram + --- + stateDiagram-v2 + [*] --> State1 + State1 --> [*] + `, + {} + ); + }); }); diff --git a/demos/classchart.html b/demos/classchart.html index 5979152d6..3481bbad5 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -17,6 +17,9 @@

Class diagram demos

+    ---
+    title: Demo Class Diagram
+    ---
 		classDiagram
       accTitle: Demo Class Diagram
       accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
diff --git a/demos/er.html b/demos/er.html
index 4c1a72c20..06fbf020e 100644
--- a/demos/er.html
+++ b/demos/er.html
@@ -20,6 +20,9 @@
   
     
 
+---
+title: This is a title
+---
 erDiagram
   %% title This is a title
   %% accDescription Test a description
diff --git a/demos/flowchart.html b/demos/flowchart.html
index e11bfcb26..60e6160c3 100644
--- a/demos/flowchart.html
+++ b/demos/flowchart.html
@@ -17,6 +17,9 @@
     

Sample 1

graph

+    ---
+    title: This is a complicated flow
+    ---
     graph LR
       accTitle: This is a complicated flow
       accDescr: This is the descriptoin for the complicated flow.
@@ -221,6 +224,9 @@
     

Sample 2

graph

+    ---
+    title: What to buy
+    ---
     graph TD
       accTitle: What to buy
       accDescr: Options of what to buy with Christmas money
diff --git a/demos/git.html b/demos/git.html
index 15b4401db..5e683152a 100644
--- a/demos/git.html
+++ b/demos/git.html
@@ -16,6 +16,9 @@
   
     

Git diagram demo

+    ---
+    title: Simple Git diagram
+    ---
     gitGraph:
     options
     {
diff --git a/demos/journey.html b/demos/journey.html
index c5c6c25e8..71eecb584 100644
--- a/demos/journey.html
+++ b/demos/journey.html
@@ -16,8 +16,10 @@
   
     

Journey diagram demo

-         journey
-    title My working day
+     ---
+     title: My working day 
+     ---
+     journey
       accTitle: Very simple journey demo
       accDescr: 2 main sections: work and home, each with just a few tasks
 
diff --git a/demos/state.html b/demos/state.html
index dbe2286a3..9f126cbc2 100644
--- a/demos/state.html
+++ b/demos/state.html
@@ -17,6 +17,9 @@
     

State diagram demos

Very simple showing change from State1 to State2

+    ---
+    title: Very simple diagram
+    ---
 		stateDiagram
 		  accTitle: This is the accessible title
       accDescr:This is an accessible description
@@ -43,6 +46,9 @@
       
     

+    ---
+    title: Very simple diagram
+    ---
 		stateDiagram-v2
 		  accTitle: This is the accessible title
       accDescr: This is an accessible description
diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md
index c7ad1402f..05f6f8a2c 100644
--- a/docs/config/setup/modules/defaultConfig.md
+++ b/docs/config/setup/modules/defaultConfig.md
@@ -14,7 +14,7 @@
 
 #### Defined in
 
-[defaultConfig.ts:1881](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1881)
+[defaultConfig.ts:1933](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1933)
 
 ---
 
diff --git a/docs/syntax/classDiagram.md b/docs/syntax/classDiagram.md
index d57125c84..e29c7295e 100644
--- a/docs/syntax/classDiagram.md
+++ b/docs/syntax/classDiagram.md
@@ -14,6 +14,9 @@ The class diagram is the main building block of object-oriented modeling. It is
 Mermaid can render class diagrams.
 
 ```mermaid-example
+---
+title: Animal example
+---
 classDiagram
     note "From Duck till Zebra"
     Animal <|-- Duck
@@ -40,6 +43,9 @@ classDiagram
 ```
 
 ```mermaid
+---
+title: Animal example
+---
 classDiagram
     note "From Duck till Zebra"
     Animal <|-- Duck
@@ -77,6 +83,9 @@ A single instance of a class in the diagram contains three compartments:
 - The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
 
 ```mermaid-example
+---
+title: Bank example
+---
 classDiagram
     class BankAccount
     BankAccount : +String owner
@@ -87,6 +96,9 @@ classDiagram
 ```
 
 ```mermaid
+---
+title: Bank example
+---
 classDiagram
     class BankAccount
     BankAccount : +String owner
diff --git a/docs/syntax/entityRelationshipDiagram.md b/docs/syntax/entityRelationshipDiagram.md
index fef7b6fee..9b938bc36 100644
--- a/docs/syntax/entityRelationshipDiagram.md
+++ b/docs/syntax/entityRelationshipDiagram.md
@@ -13,6 +13,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si
 Mermaid can render ER diagrams
 
 ```mermaid-example
+---
+title: Order example
+---
 erDiagram
     CUSTOMER ||--o{ ORDER : places
     ORDER ||--|{ LINE-ITEM : contains
@@ -20,6 +23,9 @@ erDiagram
 ```
 
 ```mermaid
+---
+title: Order example
+---
 erDiagram
     CUSTOMER ||--o{ ORDER : places
     ORDER ||--|{ LINE-ITEM : contains
diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md
index 234f46236..a6094499a 100644
--- a/docs/syntax/flowchart.md
+++ b/docs/syntax/flowchart.md
@@ -15,11 +15,17 @@ It can also accommodate different arrow types, multi directional arrows, and lin
 ### A node (default)
 
 ```mermaid-example
+---
+title: Node
+---
 flowchart LR
     id
 ```
 
 ```mermaid
+---
+title: Node
+---
 flowchart LR
     id
 ```
@@ -33,11 +39,17 @@ found for the node that will be used. Also if you define edges for the node late
 one previously defined will be used when rendering the box.
 
 ```mermaid-example
+---
+title: Node with text
+---
 flowchart LR
     id1[This is the text in the box]
 ```
 
 ```mermaid
+---
+title: Node with text
+---
 flowchart LR
     id1[This is the text in the box]
 ```
diff --git a/docs/syntax/gitgraph.md b/docs/syntax/gitgraph.md
index cd1a3f12a..051e7ce39 100644
--- a/docs/syntax/gitgraph.md
+++ b/docs/syntax/gitgraph.md
@@ -13,6 +13,9 @@ These kind of diagram are particularly helpful to developers and devops teams to
 Mermaid can render Git diagrams
 
 ```mermaid-example
+    ---
+    title: Example Git diagram
+    ---
     gitGraph
        commit
        commit
@@ -27,6 +30,9 @@ Mermaid can render Git diagrams
 ```
 
 ```mermaid
+    ---
+    title: Example Git diagram
+    ---
     gitGraph
        commit
        commit
diff --git a/docs/syntax/stateDiagram.md b/docs/syntax/stateDiagram.md
index ec91411f6..1cec5afca 100644
--- a/docs/syntax/stateDiagram.md
+++ b/docs/syntax/stateDiagram.md
@@ -11,6 +11,9 @@
 Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
 
 ```mermaid-example
+---
+title: Simple sample
+---
 stateDiagram-v2
     [*] --> Still
     Still --> [*]
@@ -22,6 +25,9 @@ stateDiagram-v2
 ```
 
 ```mermaid
+---
+title: Simple sample
+---
 stateDiagram-v2
     [*] --> Still
     Still --> [*]
diff --git a/package.json b/package.json
index 7bd648877..1b904cb17 100644
--- a/package.json
+++ b/package.json
@@ -60,6 +60,7 @@
     "@types/eslint": "^8.4.10",
     "@types/express": "^4.17.14",
     "@types/jsdom": "^20.0.1",
+    "@types/js-yaml": "^4.0.5",
     "@types/lodash": "^4.14.188",
     "@types/mdast": "^3.0.10",
     "@types/node": "^18.11.9",
@@ -90,6 +91,7 @@
     "jest": "^29.3.1",
     "jison": "^0.4.18",
     "jsdom": "^20.0.2",
+    "js-yaml": "^4.1.0",
     "lint-staged": "^13.0.3",
     "path-browserify": "^1.0.1",
     "pnpm": "^7.15.0",
diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts
index 798adf501..574dd0fac 100644
--- a/packages/mermaid/src/Diagram.ts
+++ b/packages/mermaid/src/Diagram.ts
@@ -2,6 +2,7 @@ import * as configApi from './config';
 import { log } from './logger';
 import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
 import { detectType, getDiagramLoader } from './diagram-api/detectType';
+import { extractFrontMatter } from './diagram-api/frontmatter';
 import { isDetailedError, type DetailedError } from './utils';
 
 export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
@@ -29,6 +30,16 @@ export class Diagram {
     this.db.clear?.();
     this.renderer = diagram.renderer;
     this.parser = diagram.parser;
+    const originalParse = this.parser.parse.bind(this.parser);
+    // Wrap the jison parse() method to handle extracting frontmatter.
+    //
+    // This can't be done in this.parse() because some code
+    // directly calls diagram.parser.parse(), bypassing this.parse().
+    //
+    // Similarly, we can't do this in getDiagramFromText() because some code
+    // calls diagram.db.clear(), which would reset anything set by
+    // extractFrontMatter().
+    this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db));
     this.parser.parser.yy = this.db;
     if (diagram.init) {
       diagram.init(cnf);
diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts
index cbcd2f661..ff199ca8b 100644
--- a/packages/mermaid/src/config.type.ts
+++ b/packages/mermaid/src/config.type.ts
@@ -189,6 +189,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig {
 }
 
 export interface GitGraphDiagramConfig extends BaseDiagramConfig {
+  titleTopMargin?: number;
   diagramPadding?: number;
   nodeLabel?: NodeLabel;
   mainBranchName?: string;
@@ -227,6 +228,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
 export type PieDiagramConfig = BaseDiagramConfig;
 
 export interface ErDiagramConfig extends BaseDiagramConfig {
+  titleTopMargin?: number;
   diagramPadding?: number;
   layoutDirection?: string;
   minEntityWidth?: number;
@@ -238,6 +240,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
 }
 
 export interface StateDiagramConfig extends BaseDiagramConfig {
+  titleTopMargin?: number;
   arrowMarkerAbsolute?: boolean;
   dividerMargin?: number;
   sizeUnit?: number;
@@ -258,6 +261,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
 }
 
 export interface ClassDiagramConfig extends BaseDiagramConfig {
+  titleTopMargin?: number;
   arrowMarkerAbsolute?: boolean;
   dividerMargin?: number;
   padding?: number;
@@ -343,6 +347,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
 }
 
 export interface FlowchartDiagramConfig extends BaseDiagramConfig {
+  titleTopMargin?: number;
   arrowMarkerAbsolute?: boolean;
   diagramPadding?: number;
   htmlLabels?: boolean;
diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts
index 2ddae580c..37d4f71ff 100644
--- a/packages/mermaid/src/defaultConfig.ts
+++ b/packages/mermaid/src/defaultConfig.ts
@@ -154,6 +154,17 @@ const config: Partial = {
 
   /** The object containing configurations specific for flowcharts */
   flowchart: {
+    /**
+     * ### titleTopMargin
+     *
+     * | Parameter      | Description                                    | Type    | Required | Values             |
+     * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
+     * | titleTopMargin | Margin top for the text over the flowchart     | Integer | Required | Any Positive Value |
+     *
+     * **Notes:** Default value: 25
+     */
+    titleTopMargin: 25,
+
     /**
      * | Parameter      | Description                                     | Type    | Required | Values             |
      * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
@@ -851,6 +862,16 @@ const config: Partial = {
     sectionColours: ['#fff'],
   },
   class: {
+    /**
+     * ### titleTopMargin
+     *
+     * | Parameter      | Description                                    | Type    | Required | Values             |
+     * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
+     * | titleTopMargin | Margin top for the text over the class diagram | Integer | Required | Any Positive Value |
+     *
+     * **Notes:** Default value: 25
+     */
+    titleTopMargin: 25,
     arrowMarkerAbsolute: false,
     dividerMargin: 10,
     padding: 5,
@@ -884,6 +905,16 @@ const config: Partial = {
     defaultRenderer: 'dagre-wrapper',
   },
   state: {
+    /**
+     * ### titleTopMargin
+     *
+     * | Parameter      | Description                                    | Type    | Required | Values             |
+     * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
+     * | titleTopMargin | Margin top for the text over the state diagram | Integer | Required | Any Positive Value |
+     *
+     * **Notes:** Default value: 25
+     */
+    titleTopMargin: 25,
     dividerMargin: 10,
     sizeUnit: 5,
     padding: 8,
@@ -932,6 +963,17 @@ const config: Partial = {
 
   /** The object containing configurations specific for entity relationship diagrams */
   er: {
+    /**
+     * ### titleTopMargin
+     *
+     * | Parameter      | Description                                    | Type    | Required | Values             |
+     * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
+     * | titleTopMargin | Margin top for the text over the diagram       | Integer | Required | Any Positive Value |
+     *
+     * **Notes:** Default value: 25
+     */
+    titleTopMargin: 25,
+
     /**
      * | Parameter      | Description                                     | Type    | Required | Values             |
      * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ |
@@ -1085,6 +1127,16 @@ const config: Partial = {
     line_height: 20,
   },
   gitGraph: {
+    /**
+     * ### titleTopMargin
+     *
+     * | Parameter      | Description                                    | Type    | Required | Values             |
+     * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ |
+     * | titleTopMargin | Margin top for the text over the Git diagram   | Integer | Required | Any Positive Value |
+     *
+     * **Notes:** Default value: 25
+     */
+    titleTopMargin: 25,
     diagramPadding: 8,
     nodeLabel: {
       width: 75,
diff --git a/packages/mermaid/src/diagram-api/detectType.ts b/packages/mermaid/src/diagram-api/detectType.ts
index 1c1abc51c..6f9857221 100644
--- a/packages/mermaid/src/diagram-api/detectType.ts
+++ b/packages/mermaid/src/diagram-api/detectType.ts
@@ -1,6 +1,7 @@
 import { MermaidConfig } from '../config.type';
 import { log } from '../logger';
 import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';
+import { frontMatterRegex } from './frontmatter';
 
 const directive =
   /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
@@ -31,7 +32,7 @@ const detectors: Record = {};
  * @returns A graph definition key
  */
 export const detectType = function (text: string, config?: MermaidConfig): string {
-  text = text.replace(directive, '').replace(anyComment, '\n');
+  text = text.replace(frontMatterRegex, '').replace(directive, '').replace(anyComment, '\n');
   for (const [key, { detector }] of Object.entries(detectors)) {
     const diagram = detector(text, config);
     if (diagram) {
diff --git a/packages/mermaid/src/diagram-api/frontmatter.spec.ts b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
new file mode 100644
index 000000000..92aa70573
--- /dev/null
+++ b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
@@ -0,0 +1,71 @@
+import { vi } from 'vitest';
+import { extractFrontMatter } from './frontmatter';
+
+const dbMock = () => ({ setDiagramTitle: vi.fn() });
+
+describe('extractFrontmatter', () => {
+  it('returns text unchanged if no frontmatter', () => {
+    expect(extractFrontMatter('diagram', null)).toEqual('diagram');
+  });
+
+  it('returns text unchanged if frontmatter lacks closing delimiter', () => {
+    const text = `---\ntitle: foo\ndiagram`;
+    expect(extractFrontMatter(text, null)).toEqual(text);
+  });
+
+  it('handles empty frontmatter', () => {
+    const db = dbMock();
+    const text = `---\n\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).not.toHaveBeenCalled();
+  });
+
+  it('handles frontmatter without mappings', () => {
+    const db = dbMock();
+    const text = `---\n1\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).not.toHaveBeenCalled();
+  });
+
+  it('does not try to parse frontmatter at the end', () => {
+    const db = dbMock();
+    const text = `diagram\n---\ntitle: foo\n---\n`;
+    expect(extractFrontMatter(text, db)).toEqual(text);
+    expect(db.setDiagramTitle).not.toHaveBeenCalled();
+  });
+
+  it('handles frontmatter with multiple delimiters', () => {
+    const db = dbMock();
+    const text = `---\ntitle: foo---bar\n---\ndiagram\n---\ntest`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram\n---\ntest');
+    expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar');
+  });
+
+  it('handles frontmatter with title', () => {
+    const db = dbMock();
+    const text = `---\ntitle: foo\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
+  });
+
+  it('handles booleans in frontmatter properly', () => {
+    const db = dbMock();
+    const text = `---\ntitle: true\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).toHaveBeenCalledWith('true');
+  });
+
+  it('ignores unspecified frontmatter keys', () => {
+    const db = dbMock();
+    const text = `---\ninvalid: true\ntitle: foo\ntest: bar\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).toHaveBeenCalledWith('foo');
+  });
+
+  it('throws exception for invalid YAML syntax', () => {
+    const text = `---\n!!!\n---\ndiagram`;
+    expect(() => extractFrontMatter(text, null)).toThrow(
+      'tag suffix cannot contain exclamation marks'
+    );
+  });
+});
diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts
new file mode 100644
index 000000000..46b161582
--- /dev/null
+++ b/packages/mermaid/src/diagram-api/frontmatter.ts
@@ -0,0 +1,39 @@
+// The "* as yaml" part is necessary for tree-shaking
+import * as yaml from 'js-yaml';
+
+// Match Jekyll-style front matter blocks (https://jekyllrb.com/docs/front-matter/).
+// Based on regex used by Jekyll: https://github.com/jekyll/jekyll/blob/6dd3cc21c40b98054851846425af06c64f9fb466/lib/jekyll/document.rb#L10
+// Note that JS doesn't support the "\A" anchor, which means we can't use
+// multiline mode.
+// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents
+export const frontMatterRegex = /^(?:\s*---\s*[\r\n])(.*?)(?:[\r\n]\s*---\s*[\r\n]+)/s;
+
+type FrontMatterMetadata = {
+  title?: string;
+};
+
+/**
+ * Extract and parse frontmatter from text, if present, and sets appropriate
+ * properties in the provided db.
+ * @param text -
+ * @param db -
+ * @returns text with frontmatter stripped out
+ */
+export function extractFrontMatter(text: string, db: any): string {
+  const matches = text.match(frontMatterRegex);
+  if (matches) {
+    const parsed: FrontMatterMetadata = yaml.load(matches[1], {
+      // To keep things simple, only allow strings, arrays, and plain objects.
+      // https://www.yaml.org/spec/1.2/spec.html#id2802346
+      schema: yaml.FAILSAFE_SCHEMA,
+    }) as FrontMatterMetadata;
+
+    if (parsed && parsed.title) {
+      db?.setDiagramTitle(parsed.title);
+    }
+
+    return text.slice(matches[0].length);
+  } else {
+    return text;
+  }
+}
diff --git a/packages/mermaid/src/diagrams/class/classDb.js b/packages/mermaid/src/diagrams/class/classDb.js
index 83ef6072b..9830c059e 100644
--- a/packages/mermaid/src/diagrams/class/classDb.js
+++ b/packages/mermaid/src/diagrams/class/classDb.js
@@ -10,6 +10,8 @@ import {
   getAccDescription,
   setAccDescription,
   clear as commonClear,
+  setDiagramTitle,
+  getDiagramTitle,
 } from '../../commonDb';
 
 const MERMAID_DOM_ID_PREFIX = 'classid-';
@@ -408,4 +410,6 @@ export default {
   getTooltip,
   setTooltip,
   lookUpDomId,
+  setDiagramTitle,
+  getDiagramTitle,
 };
diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.js b/packages/mermaid/src/diagrams/class/classRenderer-v2.js
index fbc2e4833..bca3c01c8 100644
--- a/packages/mermaid/src/diagrams/class/classRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.js
@@ -3,6 +3,7 @@ import graphlib from 'graphlib';
 import { log } from '../../logger';
 import { getConfig } from '../../config';
 import { render } from '../../dagre-wrapper/index.js';
+import utils from '../../utils';
 import { curveLinear } from 'd3';
 import { interpolateToCurve, getStylesFromArray } from '../../utils';
 import { setupGraphViewbox } from '../../setupGraphViewbox';
@@ -429,6 +430,8 @@ export const draw = function (text, id, _version, diagObj) {
     id
   );
 
+  utils.insertTitle(svg, 'classTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
+
   setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
 
   // Add label rects for non html labels
diff --git a/packages/mermaid/src/diagrams/class/styles.js b/packages/mermaid/src/diagrams/class/styles.js
index bc391114e..981cd7b73 100644
--- a/packages/mermaid/src/diagrams/class/styles.js
+++ b/packages/mermaid/src/diagrams/class/styles.js
@@ -148,6 +148,11 @@ g.classGroup line {
   font-size: 11px;
 }
 
+.classTitleText {
+  text-anchor: middle;
+  font-size: 18px;
+  fill: ${options.textColor};
+}
 `;
 
 export default getStyles;
diff --git a/packages/mermaid/src/diagrams/er/erDb.js b/packages/mermaid/src/diagrams/er/erDb.js
index ad3454f84..96b60836b 100644
--- a/packages/mermaid/src/diagrams/er/erDb.js
+++ b/packages/mermaid/src/diagrams/er/erDb.js
@@ -8,6 +8,8 @@ import {
   getAccDescription,
   setAccDescription,
   clear as commonClear,
+  setDiagramTitle,
+  getDiagramTitle,
 } from '../../commonDb';
 
 let entities = {};
@@ -94,4 +96,6 @@ export default {
   getAccTitle,
   setAccDescription,
   getAccDescription,
+  setDiagramTitle,
+  getDiagramTitle,
 };
diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js
index 323bb4607..c6d00d4a7 100644
--- a/packages/mermaid/src/diagrams/er/erRenderer.js
+++ b/packages/mermaid/src/diagrams/er/erRenderer.js
@@ -3,6 +3,7 @@ import { line, curveBasis, select } from 'd3';
 import dagre from 'dagre';
 import { getConfig } from '../../config';
 import { log } from '../../logger';
+import utils from '../../utils';
 import erMarkers from './erMarkers';
 import { configureSvgSize } from '../../setupGraphViewbox';
 import addSVGAccessibilityFields from '../../accessibility';
@@ -649,6 +650,8 @@ export const draw = function (text, id, _version, diagObj) {
 
   const padding = conf.diagramPadding;
 
+  utils.insertTitle(svg, 'entityTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
+
   const svgBounds = svg.node().getBBox();
   const width = svgBounds.width + padding * 2;
   const height = svgBounds.height + padding * 2;
diff --git a/packages/mermaid/src/diagrams/er/styles.js b/packages/mermaid/src/diagrams/er/styles.js
index 907d813b6..42dbcebde 100644
--- a/packages/mermaid/src/diagrams/er/styles.js
+++ b/packages/mermaid/src/diagrams/er/styles.js
@@ -27,6 +27,12 @@ const getStyles = (options) =>
     .relationshipLine {
       stroke: ${options.lineColor};
     }
+
+  .entityTitleText {
+    text-anchor: middle;
+    font-size: 18px;
+    fill: ${options.textColor};
+  }    
 `;
 
 export default getStyles;
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.js b/packages/mermaid/src/diagrams/flowchart/flowDb.js
index 6abc22659..38754c667 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.js
@@ -10,6 +10,8 @@ import {
   getAccDescription,
   setAccDescription,
   clear as commonClear,
+  setDiagramTitle,
+  getDiagramTitle,
 } from '../../commonDb';
 
 const MERMAID_DOM_ID_PREFIX = 'flowchart-';
@@ -785,4 +787,6 @@ export default {
   },
   exists,
   makeUniq,
+  setDiagramTitle,
+  getDiagramTitle,
 };
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
index 6b7c4c1bf..5f0288b03 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
@@ -3,6 +3,7 @@ import { select, curveLinear, selectAll } from 'd3';
 
 import flowDb from './flowDb';
 import { getConfig } from '../../config';
+import utils from '../../utils';
 
 import { render } from '../../dagre-wrapper/index.js';
 import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
@@ -437,6 +438,8 @@ export const draw = function (text, id, _version, diagObj) {
   const element = root.select('#' + id + ' g');
   render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
 
+  utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
+
   setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
 
   // Index nodes
diff --git a/packages/mermaid/src/diagrams/flowchart/styles.ts b/packages/mermaid/src/diagrams/flowchart/styles.ts
index 82fb1f875..a89d33d3d 100644
--- a/packages/mermaid/src/diagrams/flowchart/styles.ts
+++ b/packages/mermaid/src/diagrams/flowchart/styles.ts
@@ -103,6 +103,12 @@ const getStyles = (options: FlowChartStyleOptions) =>
     pointer-events: none;
     z-index: 100;
   }
+
+  .flowchartTitleText {
+    text-anchor: middle;
+    font-size: 18px;
+    fill: ${options.textColor};
+  }
 `;
 
 export default getStyles;
diff --git a/packages/mermaid/src/diagrams/git/gitGraphAst.js b/packages/mermaid/src/diagrams/git/gitGraphAst.js
index 496e578b7..65980933d 100644
--- a/packages/mermaid/src/diagrams/git/gitGraphAst.js
+++ b/packages/mermaid/src/diagrams/git/gitGraphAst.js
@@ -10,6 +10,8 @@ import {
   getAccDescription,
   setAccDescription,
   clear as commonClear,
+  setDiagramTitle,
+  getDiagramTitle,
 } from '../../commonDb';
 
 let mainBranchName = getConfig().gitGraph.mainBranchName;
@@ -529,5 +531,7 @@ export default {
   getAccTitle,
   getAccDescription,
   setAccDescription,
+  setDiagramTitle,
+  getDiagramTitle,
   commitType,
 };
diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js
index 71698a500..75e8d445d 100644
--- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js
+++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js
@@ -1,6 +1,7 @@
 import { select } from 'd3';
 import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI';
 import { log } from '../../logger';
+import utils from '../../utils';
 import addSVGAccessibilityFields from '../../accessibility';
 
 let allCommitsDict = {};
@@ -521,6 +522,12 @@ export const draw = function (txt, id, ver, diagObj) {
   }
   drawArrows(diagram, allCommitsDict);
   drawCommits(diagram, allCommitsDict, true);
+  utils.insertTitle(
+    diagram,
+    'gitTitleText',
+    gitGraphConfig.titleTopMargin,
+    diagObj.db.getDiagramTitle()
+  );
 
   // Setup the view box and size of the svg element
   setupGraphViewbox(
diff --git a/packages/mermaid/src/diagrams/git/styles.js b/packages/mermaid/src/diagrams/git/styles.js
index 7e09ff7e0..741760235 100644
--- a/packages/mermaid/src/diagrams/git/styles.js
+++ b/packages/mermaid/src/diagrams/git/styles.js
@@ -51,6 +51,11 @@ const getStyles = (options) =>
   }
 
   .arrow { stroke-width: 8; stroke-linecap: round; fill: none}
+  .gitTitleText {
+    text-anchor: middle;
+    font-size: 18px;
+    fill: ${options.textColor};
+  }
   }
 `;
 
diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js
index 5e82eaf78..19ecbe65f 100644
--- a/packages/mermaid/src/diagrams/state/stateDb.js
+++ b/packages/mermaid/src/diagrams/state/stateDb.js
@@ -9,6 +9,8 @@ import {
   getAccDescription,
   setAccDescription,
   clear as commonClear,
+  setDiagramTitle,
+  getDiagramTitle,
 } from '../../commonDb';
 
 import {
@@ -571,4 +573,6 @@ export default {
   addStyleClass,
   setCssClass,
   addDescription,
+  setDiagramTitle,
+  getDiagramTitle,
 };
diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
index 752b70e44..03c678789 100644
--- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
@@ -5,6 +5,7 @@ import { render } from '../../dagre-wrapper/index.js';
 import { log } from '../../logger';
 import { configureSvgSize } from '../../setupGraphViewbox';
 import common from '../common/common';
+import utils from '../../utils';
 import addSVGAccessibilityFields from '../../accessibility';
 import {
   DEFAULT_DIAGRAM_DIRECTION,
@@ -437,8 +438,9 @@ export const draw = function (text, id, _version, diag) {
 
   const padding = 8;
 
-  const bounds = svg.node().getBBox();
+  utils.insertTitle(svg, 'statediagramTitleText', conf.titleTopMargin, diag.db.getDiagramTitle());
 
+  const bounds = svg.node().getBBox();
   const width = bounds.width + padding * 2;
   const height = bounds.height + padding * 2;
 
diff --git a/packages/mermaid/src/diagrams/state/styles.js b/packages/mermaid/src/diagrams/state/styles.js
index 4a1c46512..f4783b477 100644
--- a/packages/mermaid/src/diagrams/state/styles.js
+++ b/packages/mermaid/src/diagrams/state/styles.js
@@ -194,6 +194,12 @@ g.stateGroup line {
   stroke: ${options.lineColor};
   stroke-width: 1;
 }
+
+.statediagramTitleText {
+  text-anchor: middle;
+  font-size: 18px;
+  fill: ${options.textColor};
+}
 `;
 
 export default getStyles;
diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md
index 20bdd657f..6ef0b82c9 100644
--- a/packages/mermaid/src/docs/syntax/classDiagram.md
+++ b/packages/mermaid/src/docs/syntax/classDiagram.md
@@ -8,6 +8,9 @@ The class diagram is the main building block of object-oriented modeling. It is
 Mermaid can render class diagrams.
 
 ```mermaid-example
+---
+title: Animal example
+---
 classDiagram
     note "From Duck till Zebra"
     Animal <|-- Duck
@@ -45,6 +48,9 @@ A single instance of a class in the diagram contains three compartments:
 - The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
 
 ```mermaid-example
+---
+title: Bank example
+---
 classDiagram
     class BankAccount
     BankAccount : +String owner
diff --git a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md
index e52b0df4c..c666877c5 100644
--- a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md
+++ b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md
@@ -7,6 +7,9 @@ Note that practitioners of ER modelling almost always refer to _entity types_ si
 Mermaid can render ER diagrams
 
 ```mermaid-example
+---
+title: Order example
+---
 erDiagram
     CUSTOMER ||--o{ ORDER : places
     ORDER ||--|{ LINE-ITEM : contains
diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md
index 25252e54d..5888db105 100644
--- a/packages/mermaid/src/docs/syntax/flowchart.md
+++ b/packages/mermaid/src/docs/syntax/flowchart.md
@@ -9,6 +9,9 @@ It can also accommodate different arrow types, multi directional arrows, and lin
 ### A node (default)
 
 ```mermaid-example
+---
+title: Node
+---
 flowchart LR
     id
 ```
@@ -22,6 +25,9 @@ found for the node that will be used. Also if you define edges for the node late
 one previously defined will be used when rendering the box.
 
 ```mermaid-example
+---
+title: Node with text
+---
 flowchart LR
     id1[This is the text in the box]
 ```
diff --git a/packages/mermaid/src/docs/syntax/gitgraph.md b/packages/mermaid/src/docs/syntax/gitgraph.md
index b19c1e2cd..c3210af31 100644
--- a/packages/mermaid/src/docs/syntax/gitgraph.md
+++ b/packages/mermaid/src/docs/syntax/gitgraph.md
@@ -7,6 +7,9 @@ These kind of diagram are particularly helpful to developers and devops teams to
 Mermaid can render Git diagrams
 
 ```mermaid-example
+    ---
+    title: Example Git diagram
+    ---
     gitGraph
        commit
        commit
diff --git a/packages/mermaid/src/docs/syntax/stateDiagram.md b/packages/mermaid/src/docs/syntax/stateDiagram.md
index e28819e7a..9293e1083 100644
--- a/packages/mermaid/src/docs/syntax/stateDiagram.md
+++ b/packages/mermaid/src/docs/syntax/stateDiagram.md
@@ -5,6 +5,9 @@
 Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
 
 ```mermaid-example
+---
+title: Simple sample
+---
 stateDiagram-v2
     [*] --> Still
     Still --> [*]
diff --git a/packages/mermaid/src/utils.spec.js b/packages/mermaid/src/utils.spec.js
index 4a511b3c0..04cf9b769 100644
--- a/packages/mermaid/src/utils.spec.js
+++ b/packages/mermaid/src/utils.spec.js
@@ -4,6 +4,7 @@ import assignWithDepth from './assignWithDepth';
 import { detectType } from './diagram-api/detectType';
 import { addDiagrams } from './diagram-api/diagram-orchestration';
 import memoize from 'lodash/memoize';
+import { MockD3 } from 'd3';
 addDiagrams();
 
 describe('when assignWithDepth: should merge objects within objects', function () {
@@ -232,6 +233,16 @@ Alice->Bob: hi`;
     const type = detectType(str);
     expect(type).toBe('gitGraph');
   });
+  it('should handle frontmatter', function () {
+    const str = '---\ntitle: foo\n---\n  gitGraph TB:\nbfs1:queue';
+    const type = detectType(str);
+    expect(type).toBe('gitGraph');
+  });
+  it('should handle frontmatter with leading spaces', function () {
+    const str = '    ---\ntitle: foo\n---\n  gitGraph TB:\nbfs1:queue';
+    const type = detectType(str);
+    expect(type).toBe('gitGraph');
+  });
 });
 describe('when finding substring in array ', function () {
   it('should return the array index that contains the substring', function () {
@@ -340,3 +351,23 @@ describe('when initializing the id generator', function () {
     expect(idGenerator.next()).toEqual(lastId + 1);
   });
 });
+
+describe('when inserting titles', function () {
+  it('should do nothing when title is empty', function () {
+    const svg = MockD3('svg');
+    utils.insertTitle(svg, 'testClass', 0, '');
+    expect(svg.__children.length).toBe(0);
+  });
+
+  it('should insert title centered', function () {
+    const svg = MockD3('svg');
+    utils.insertTitle(svg, 'testClass', 5, 'test title');
+    expect(svg.__children.length).toBe(1);
+    const text = svg.__children[0];
+    expect(text.__name).toBe('text');
+    expect(text.text).toHaveBeenCalledWith('test title');
+    expect(text.attr).toHaveBeenCalledWith('x', 15);
+    expect(text.attr).toHaveBeenCalledWith('y', -5);
+    expect(text.attr).toHaveBeenCalledWith('class', 'testClass');
+  });
+});
diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts
index 3eecd5f4f..82f89d61a 100644
--- a/packages/mermaid/src/utils.ts
+++ b/packages/mermaid/src/utils.ts
@@ -885,6 +885,32 @@ export function getErrorMessage(error: unknown): string {
   return String(error);
 }
 
+/**
+ * Appends  element with the given title, centered.
+ *
+ * @param parent - d3 svg object to append title to
+ * @param cssClass - CSS class for the  element containing the title
+ * @param titleTopMargin - Margin in pixels between title and rest of the graph
+ * @param title - The title. If empty, returns immediately.
+ */
+export const insertTitle = (
+  parent,
+  cssClass: string,
+  titleTopMargin: number,
+  title?: string
+): void => {
+  if (!title) {
+    return;
+  }
+  const bounds = parent.node().getBBox();
+  parent
+    .append('text')
+    .text(title)
+    .attr('x', bounds.x + bounds.width / 2)
+    .attr('y', -titleTopMargin)
+    .attr('class', cssClass);
+};
+
 export default {
   assignWithDepth,
   wrapLabel,
@@ -907,4 +933,5 @@ export default {
   initIdGenerator: initIdGenerator,
   directiveSanitizer,
   sanitizeCss,
+  insertTitle,
 };
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 85afcb31d..3fa800f71 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -25,6 +25,9 @@ importers:
       '@types/express':
         specifier: ^4.17.14
         version: 4.17.14
+      '@types/js-yaml':
+        specifier: ^4.0.5
+        version: 4.0.5
       '@types/jsdom':
         specifier: ^20.0.1
         version: 20.0.1
@@ -115,6 +118,9 @@ importers:
       jison:
         specifier: ^0.4.18
         version: 0.4.18
+      js-yaml:
+        specifier: ^4.1.0
+        version: 4.1.0
       jsdom:
         specifier: ^20.0.2
         version: 20.0.2
@@ -2466,6 +2472,10 @@ packages:
       '@types/istanbul-lib-report': 3.0.0
     dev: true
 
+  /@types/js-yaml/4.0.5:
+    resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
+    dev: true
+
   /@types/jsdom/20.0.1:
     resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
     dependencies:

From e3b9dbdf1338424bcbca3f89cf27eba1ac0f05eb Mon Sep 17 00:00:00 2001
From: endolith 
Date: Sat, 19 Nov 2022 09:08:35 -0500
Subject: [PATCH 48/79] Fix typos

---
 packages/mermaid/src/docs/config/usage.md           | 2 +-
 packages/mermaid/src/docs/syntax/c4c.md             | 2 +-
 packages/mermaid/src/docs/syntax/classDiagram.md    | 2 +-
 packages/mermaid/src/docs/syntax/flowchart.md       | 2 +-
 packages/mermaid/src/docs/syntax/mindmap.md         | 2 +-
 packages/mermaid/src/docs/syntax/pie.md             | 2 +-
 packages/mermaid/src/docs/syntax/sequenceDiagram.md | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/packages/mermaid/src/docs/config/usage.md b/packages/mermaid/src/docs/config/usage.md
index 187f3f89c..3eac4ad6f 100644
--- a/packages/mermaid/src/docs/config/usage.md
+++ b/packages/mermaid/src/docs/config/usage.md
@@ -347,7 +347,7 @@ This is the preferred way of configuring mermaid.
 
 ## Using the mermaid object
 
-Is it possible to set some configuration via the mermaid object. The two parameters that are supported using this
+It is possible to set some configuration via the mermaid object. The two parameters that are supported using this
 approach are:
 
 - mermaid.startOnLoad
diff --git a/packages/mermaid/src/docs/syntax/c4c.md b/packages/mermaid/src/docs/syntax/c4c.md
index f9850f2cd..78528f7b9 100644
--- a/packages/mermaid/src/docs/syntax/c4c.md
+++ b/packages/mermaid/src/docs/syntax/c4c.md
@@ -318,7 +318,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60")
         Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.")
     }
 
-    Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){
+    Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){
         Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md index 20bdd657f..b827d62b1 100644 --- a/packages/mermaid/src/docs/syntax/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -379,7 +379,7 @@ click className href "url" "tooltip" ## Notes -It is possible to add notes on digram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` +It is possible to add notes on diagram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` ### Examples diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 25252e54d..a6b3e9a04 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -665,7 +665,7 @@ flowchart LR ## Configuration... -Is it possible to adjust the width of the rendered flowchart. +It is possible to adjust the width of the rendered flowchart. This is done by defining **mermaid.flowchartConfig** or by the CLI to use a JSON file with the configuration. How to use the CLI is described in the mermaidCLI page. mermaid.flowchartConfig can be set to a JSON string with config parameters or the corresponding object. diff --git a/packages/mermaid/src/docs/syntax/mindmap.md b/packages/mermaid/src/docs/syntax/mindmap.md index af7a3df85..bd73a76b7 100644 --- a/packages/mermaid/src/docs/syntax/mindmap.md +++ b/packages/mermaid/src/docs/syntax/mindmap.md @@ -15,7 +15,7 @@ mindmap Popularisation British popular psychology author Tony Buzan Research - On effectivness
and eatures + On effectiveness
and features On Automatic creation Uses Creative techniques diff --git a/packages/mermaid/src/docs/syntax/pie.md b/packages/mermaid/src/docs/syntax/pie.md index 4e14efce1..2fe8c3e54 100644 --- a/packages/mermaid/src/docs/syntax/pie.md +++ b/packages/mermaid/src/docs/syntax/pie.md @@ -22,7 +22,7 @@ Drawing a pie chart is really simple in mermaid. - Followed by dataSet. Pie slices will be ordered clockwise in the same order as the labels. - `label` for a section in the pie diagram within `" "` quotes. - Followed by `:` colon as separator - - Followed by `positive numeric value` (supported upto two decimal places) + - Followed by `positive numeric value` (supported up to two decimal places) [pie] [showData] (OPTIONAL) [title] [titlevalue] (OPTIONAL) diff --git a/packages/mermaid/src/docs/syntax/sequenceDiagram.md b/packages/mermaid/src/docs/syntax/sequenceDiagram.md index beb417ee2..9c28883c9 100644 --- a/packages/mermaid/src/docs/syntax/sequenceDiagram.md +++ b/packages/mermaid/src/docs/syntax/sequenceDiagram.md @@ -534,7 +534,7 @@ text.actor { ## Configuration -Is it possible to adjust the margins for rendering the sequence diagram. +It is possible to adjust the margins for rendering the sequence diagram. This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration. How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page. From 2a0f6d4cc98f936ffc4a814cf78dff8ca32a5652 Mon Sep 17 00:00:00 2001 From: Doug Finke Date: Sat, 19 Nov 2022 11:20:13 -0500 Subject: [PATCH 49/79] Integrations added - Visual Studio Code [Polyglot Interactive Notebooks] --- packages/mermaid/src/docs/misc/integrations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/mermaid/src/docs/misc/integrations.md b/packages/mermaid/src/docs/misc/integrations.md index 4c87d170e..31f2d09d0 100644 --- a/packages/mermaid/src/docs/misc/integrations.md +++ b/packages/mermaid/src/docs/misc/integrations.md @@ -33,6 +33,7 @@ They also serve as proof of concept, for the variety of things that can be built - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin) - [JetBrains IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) - [mermerd](https://github.com/KarnerTh/mermerd) +- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive) ## CRM/ERP/Similar From a11ab3d5ea1477c02101eb7c4279b1dc0d2ef126 Mon Sep 17 00:00:00 2001 From: Mason Malone <651224+MasonM@users.noreply.github.com> Date: Sat, 19 Nov 2022 12:48:17 -0800 Subject: [PATCH 50/79] Disallow leading whitespace before delimiter --- .../integration/rendering/classDiagram-v2.spec.js | 10 +++++----- cypress/integration/rendering/erDiagram.spec.js | 12 ++++++------ cypress/integration/rendering/flowchart-v2.spec.js | 10 +++++----- cypress/integration/rendering/gitGraph.spec.js | 10 +++++----- .../integration/rendering/stateDiagram-v2.spec.js | 12 ++++++------ demos/classchart.html | 6 +++--- demos/flowchart.html | 12 ++++++------ demos/git.html | 6 +++--- demos/journey.html | 6 +++--- demos/state.html | 12 ++++++------ packages/mermaid/src/diagram-api/frontmatter.spec.ts | 7 +++++++ packages/mermaid/src/diagram-api/frontmatter.ts | 2 +- packages/mermaid/src/utils.spec.js | 5 ++--- 13 files changed, 58 insertions(+), 52 deletions(-) diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index f9ed7c64b..f97458857 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -500,11 +500,11 @@ describe('Class diagram V2', () => { it('1433: should render a simple class with a title', () => { imgSnapshotTest( `--- - title: simple class diagram - --- - classDiagram-v2 - class Class10 - `, +title: simple class diagram +--- +classDiagram-v2 +class Class10 +`, {} ); }); diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index dea3c7620..8e8946170 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -277,12 +277,12 @@ describe('Entity Relationship Diagram', () => { it('1433: should render a simple ER diagram with a title', () => { imgSnapshotTest( `--- - title: simple ER diagram - --- - erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - `, +title: simple ER diagram +--- +erDiagram +CUSTOMER ||--o{ ORDER : places +ORDER ||--|{ LINE-ITEM : contains +`, {} ); }); diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index cdf0d07ca..30ae4f0d2 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -666,11 +666,11 @@ flowchart RL it('1433: should render a titled flowchart with titleTopMargin set to 0', () => { imgSnapshotTest( `--- - title: Simple flowchart - --- - flowchart TD - A --> B - `, +title: Simple flowchart +--- +flowchart TD +A --> B +`, { titleTopMargin: 0 } ); }); diff --git a/cypress/integration/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js index cb70f7272..0b5048b44 100644 --- a/cypress/integration/rendering/gitGraph.spec.js +++ b/cypress/integration/rendering/gitGraph.spec.js @@ -325,11 +325,11 @@ describe('Git Graph diagram', () => { it('1433: should render a simple gitgraph with a title', () => { imgSnapshotTest( `--- - title: simple gitGraph - --- - gitGraph - commit - `, +title: simple gitGraph +--- +gitGraph + commit +`, {} ); }); diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 7c322c1b3..0eca01873 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -562,12 +562,12 @@ stateDiagram-v2 it('1433: should render a simple state diagram with a title', () => { imgSnapshotTest( `--- - title: simple state diagram - --- - stateDiagram-v2 - [*] --> State1 - State1 --> [*] - `, +title: simple state diagram +--- +stateDiagram-v2 +[*] --> State1 +State1 --> [*] +`, {} ); }); diff --git a/demos/classchart.html b/demos/classchart.html index 3481bbad5..031f3b608 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -17,9 +17,9 @@

Class diagram demos

-    ---
-    title: Demo Class Diagram
-    ---
+---
+title: Demo Class Diagram
+---
 		classDiagram
       accTitle: Demo Class Diagram
       accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
diff --git a/demos/flowchart.html b/demos/flowchart.html
index 60e6160c3..7251e586e 100644
--- a/demos/flowchart.html
+++ b/demos/flowchart.html
@@ -17,9 +17,9 @@
     

Sample 1

graph

-    ---
-    title: This is a complicated flow
-    ---
+---
+title: This is a complicated flow
+---
     graph LR
       accTitle: This is a complicated flow
       accDescr: This is the descriptoin for the complicated flow.
@@ -224,9 +224,9 @@
     

Sample 2

graph

-    ---
-    title: What to buy
-    ---
+---
+title: What to buy
+---
     graph TD
       accTitle: What to buy
       accDescr: Options of what to buy with Christmas money
diff --git a/demos/git.html b/demos/git.html
index 5e683152a..99c53d7d0 100644
--- a/demos/git.html
+++ b/demos/git.html
@@ -16,9 +16,9 @@
   
     

Git diagram demo

-    ---
-    title: Simple Git diagram
-    ---
+---
+title: Simple Git diagram
+---
     gitGraph:
     options
     {
diff --git a/demos/journey.html b/demos/journey.html
index 71eecb584..dadcfb13c 100644
--- a/demos/journey.html
+++ b/demos/journey.html
@@ -16,9 +16,9 @@
   
     

Journey diagram demo

-     ---
-     title: My working day 
-     ---
+---
+title: My working day 
+---
      journey
       accTitle: Very simple journey demo
       accDescr: 2 main sections: work and home, each with just a few tasks
diff --git a/demos/state.html b/demos/state.html
index 9f126cbc2..c13da84d8 100644
--- a/demos/state.html
+++ b/demos/state.html
@@ -17,9 +17,9 @@
     

State diagram demos

Very simple showing change from State1 to State2

-    ---
-    title: Very simple diagram
-    ---
+---
+title: Very simple diagram
+---
 		stateDiagram
 		  accTitle: This is the accessible title
       accDescr:This is an accessible description
@@ -46,9 +46,9 @@
       
     

-    ---
-    title: Very simple diagram
-    ---
+---
+title: Very simple diagram
+---
 		stateDiagram-v2
 		  accTitle: This is the accessible title
       accDescr: This is an accessible description
diff --git a/packages/mermaid/src/diagram-api/frontmatter.spec.ts b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
index 92aa70573..4f8848f25 100644
--- a/packages/mermaid/src/diagram-api/frontmatter.spec.ts
+++ b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
@@ -41,6 +41,13 @@ describe('extractFrontmatter', () => {
     expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar');
   });
 
+  it('handles frontmatter with multi-line string and multiple delimiters', () => {
+    const db = dbMock();
+    const text = `---\ntitle: |\n   multi-line string\n   ---\n---\ndiagram`;
+    expect(extractFrontMatter(text, db)).toEqual('diagram');
+    expect(db.setDiagramTitle).toHaveBeenCalledWith('multi-line string\n---\n');
+  });
+
   it('handles frontmatter with title', () => {
     const db = dbMock();
     const text = `---\ntitle: foo\n---\ndiagram`;
diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts
index 46b161582..b73440a7d 100644
--- a/packages/mermaid/src/diagram-api/frontmatter.ts
+++ b/packages/mermaid/src/diagram-api/frontmatter.ts
@@ -6,7 +6,7 @@ import * as yaml from 'js-yaml';
 // Note that JS doesn't support the "\A" anchor, which means we can't use
 // multiline mode.
 // Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents
-export const frontMatterRegex = /^(?:\s*---\s*[\r\n])(.*?)(?:[\r\n]\s*---\s*[\r\n]+)/s;
+export const frontMatterRegex = /^(?:---\s*[\r\n])(.*?)(?:[\r\n]---\s*[\r\n]+)/s;
 
 type FrontMatterMetadata = {
   title?: string;
diff --git a/packages/mermaid/src/utils.spec.js b/packages/mermaid/src/utils.spec.js
index 04cf9b769..4d3e07e6b 100644
--- a/packages/mermaid/src/utils.spec.js
+++ b/packages/mermaid/src/utils.spec.js
@@ -238,10 +238,9 @@ Alice->Bob: hi`;
     const type = detectType(str);
     expect(type).toBe('gitGraph');
   });
-  it('should handle frontmatter with leading spaces', function () {
+  it('should not allow frontmatter with leading spaces', function () {
     const str = '    ---\ntitle: foo\n---\n  gitGraph TB:\nbfs1:queue';
-    const type = detectType(str);
-    expect(type).toBe('gitGraph');
+    expect(() => detectType(str)).toThrow('No diagram type detected for text');
   });
 });
 describe('when finding substring in array ', function () {

From 3316aa5f4f8c93f3410ca74c2fa5390087f26ef9 Mon Sep 17 00:00:00 2001
From: Mason Malone <651224+MasonM@users.noreply.github.com>
Date: Sat, 19 Nov 2022 12:48:40 -0800
Subject: [PATCH 51/79] Add interface for DiagramDb and other minor changes

---
 packages/mermaid/src/diagram-api/frontmatter.ts | 11 ++++++-----
 packages/mermaid/src/diagram-api/types.ts       | 10 +++++++++-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts
index b73440a7d..800e7399b 100644
--- a/packages/mermaid/src/diagram-api/frontmatter.ts
+++ b/packages/mermaid/src/diagram-api/frontmatter.ts
@@ -1,3 +1,4 @@
+import { DiagramDb } from './types';
 // The "* as yaml" part is necessary for tree-shaking
 import * as yaml from 'js-yaml';
 
@@ -15,11 +16,11 @@ type FrontMatterMetadata = {
 /**
  * Extract and parse frontmatter from text, if present, and sets appropriate
  * properties in the provided db.
- * @param text -
- * @param db -
+ * @param text - The text that may have a YAML frontmatter.
+ * @param db - Diagram database, could be of any diagram.
  * @returns text with frontmatter stripped out
  */
-export function extractFrontMatter(text: string, db: any): string {
+export function extractFrontMatter(text: string, db: DiagramDb): string {
   const matches = text.match(frontMatterRegex);
   if (matches) {
     const parsed: FrontMatterMetadata = yaml.load(matches[1], {
@@ -28,8 +29,8 @@ export function extractFrontMatter(text: string, db: any): string {
       schema: yaml.FAILSAFE_SCHEMA,
     }) as FrontMatterMetadata;
 
-    if (parsed && parsed.title) {
-      db?.setDiagramTitle(parsed.title);
+    if (parsed?.title) {
+      db.setDiagramTitle?.(parsed.title);
     }
 
     return text.slice(matches[0].length);
diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts
index d45eac6aa..23810d133 100644
--- a/packages/mermaid/src/diagram-api/types.ts
+++ b/packages/mermaid/src/diagram-api/types.ts
@@ -8,8 +8,16 @@ export interface InjectUtils {
   _setupGraphViewbox: any;
 }
 
+/**
+ * Generic Diagram DB that may apply to any diagram type.
+ */
+export interface DiagramDb {
+  clear?: () => void;
+  setDiagramTitle?: (title: string) => void;
+}
+
 export interface DiagramDefinition {
-  db: any;
+  db: DiagramDb;
   renderer: any;
   parser: any;
   styles: any;

From 1b201bf462aff405e38001e886e96d0adfb3986c Mon Sep 17 00:00:00 2001
From: Mason Malone <651224+MasonM@users.noreply.github.com>
Date: Sat, 19 Nov 2022 13:01:21 -0800
Subject: [PATCH 52/79] Fix TS errors

---
 packages/mermaid/src/Diagram.ts                      | 2 +-
 packages/mermaid/src/diagram-api/frontmatter.spec.ts | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts
index 574dd0fac..a2349c255 100644
--- a/packages/mermaid/src/Diagram.ts
+++ b/packages/mermaid/src/Diagram.ts
@@ -56,7 +56,7 @@ export class Diagram {
     }
     try {
       text = text + '\n';
-      this.db.clear();
+      this.db.clear?.();
       this.parser.parse(text);
       return true;
     } catch (error) {
diff --git a/packages/mermaid/src/diagram-api/frontmatter.spec.ts b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
index 4f8848f25..4eb9789e2 100644
--- a/packages/mermaid/src/diagram-api/frontmatter.spec.ts
+++ b/packages/mermaid/src/diagram-api/frontmatter.spec.ts
@@ -5,12 +5,12 @@ const dbMock = () => ({ setDiagramTitle: vi.fn() });
 
 describe('extractFrontmatter', () => {
   it('returns text unchanged if no frontmatter', () => {
-    expect(extractFrontMatter('diagram', null)).toEqual('diagram');
+    expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram');
   });
 
   it('returns text unchanged if frontmatter lacks closing delimiter', () => {
     const text = `---\ntitle: foo\ndiagram`;
-    expect(extractFrontMatter(text, null)).toEqual(text);
+    expect(extractFrontMatter(text, dbMock())).toEqual(text);
   });
 
   it('handles empty frontmatter', () => {
@@ -71,7 +71,7 @@ describe('extractFrontmatter', () => {
 
   it('throws exception for invalid YAML syntax', () => {
     const text = `---\n!!!\n---\ndiagram`;
-    expect(() => extractFrontMatter(text, null)).toThrow(
+    expect(() => extractFrontMatter(text, dbMock())).toThrow(
       'tag suffix cannot contain exclamation marks'
     );
   });

From bdf8b01185aee526e1059bc3ca63fa696e734de8 Mon Sep 17 00:00:00 2001
From: Mason Malone <651224+MasonM@users.noreply.github.com>
Date: Sat, 19 Nov 2022 13:20:12 -0800
Subject: [PATCH 53/79] Fix example for Git diagrams

---
 docs/syntax/gitgraph.md                      | 56 ++++++++++----------
 packages/mermaid/src/docs/syntax/gitgraph.md | 28 +++++-----
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/docs/syntax/gitgraph.md b/docs/syntax/gitgraph.md
index 051e7ce39..964fe3886 100644
--- a/docs/syntax/gitgraph.md
+++ b/docs/syntax/gitgraph.md
@@ -13,37 +13,37 @@ These kind of diagram are particularly helpful to developers and devops teams to
 Mermaid can render Git diagrams
 
 ```mermaid-example
-    ---
-    title: Example Git diagram
-    ---
-    gitGraph
-       commit
-       commit
-       branch develop
-       checkout develop
-       commit
-       commit
-       checkout main
-       merge develop
-       commit
-       commit
+---
+title: Example Git diagram
+---
+gitGraph
+   commit
+   commit
+   branch develop
+   checkout develop
+   commit
+   commit
+   checkout main
+   merge develop
+   commit
+   commit
 ```
 
 ```mermaid
-    ---
-    title: Example Git diagram
-    ---
-    gitGraph
-       commit
-       commit
-       branch develop
-       checkout develop
-       commit
-       commit
-       checkout main
-       merge develop
-       commit
-       commit
+---
+title: Example Git diagram
+---
+gitGraph
+   commit
+   commit
+   branch develop
+   checkout develop
+   commit
+   commit
+   checkout main
+   merge develop
+   commit
+   commit
 ```
 
 In Mermaid, we support the basic git operations like:
diff --git a/packages/mermaid/src/docs/syntax/gitgraph.md b/packages/mermaid/src/docs/syntax/gitgraph.md
index c3210af31..f1930bb27 100644
--- a/packages/mermaid/src/docs/syntax/gitgraph.md
+++ b/packages/mermaid/src/docs/syntax/gitgraph.md
@@ -7,20 +7,20 @@ These kind of diagram are particularly helpful to developers and devops teams to
 Mermaid can render Git diagrams
 
 ```mermaid-example
-    ---
-    title: Example Git diagram
-    ---
-    gitGraph
-       commit
-       commit
-       branch develop
-       checkout develop
-       commit
-       commit
-       checkout main
-       merge develop
-       commit
-       commit
+---
+title: Example Git diagram
+---
+gitGraph
+   commit
+   commit
+   branch develop
+   checkout develop
+   commit
+   commit
+   checkout main
+   merge develop
+   commit
+   commit
 ```
 
 In Mermaid, we support the basic git operations like:

From 49a931f7129b8ab5628115808a3ceebe938d728e Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Sun, 20 Nov 2022 12:13:00 +0530
Subject: [PATCH 54/79] feat: Add bundle visualization

---
 .vite/build.ts |  5 +++--
 package.json   |  2 ++
 pnpm-lock.yaml | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/.vite/build.ts b/.vite/build.ts
index 50b7fb1ad..fb5f171e2 100644
--- a/.vite/build.ts
+++ b/.vite/build.ts
@@ -1,8 +1,9 @@
-import { build, InlineConfig } from 'vite';
+import { build, InlineConfig, type PluginOption } from 'vite';
 import { resolve } from 'path';
 import { fileURLToPath } from 'url';
 import jisonPlugin from './jisonPlugin.js';
 import { readFileSync } from 'fs';
+import { visualizer } from 'rollup-plugin-visualizer';
 
 const watch = process.argv.includes('--watch');
 const mermaidOnly = process.argv.includes('--mermaid');
@@ -95,7 +96,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
     resolve: {
       extensions: ['.jison', '.js', '.ts', '.json'],
     },
-    plugins: [jisonPlugin()],
+    plugins: [jisonPlugin(), visualizer({ template: 'network' }) as PluginOption],
   };
 
   if (watch && config.build) {
diff --git a/package.json b/package.json
index 7bd648877..52b756f99 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
     "@types/mdast": "^3.0.10",
     "@types/node": "^18.11.9",
     "@types/prettier": "^2.7.1",
+    "@types/rollup-plugin-visualizer": "^4.2.1",
     "@typescript-eslint/eslint-plugin": "^5.42.1",
     "@typescript-eslint/parser": "^5.42.1",
     "@vitest/coverage-c8": "^0.25.1",
@@ -96,6 +97,7 @@
     "prettier": "^2.7.1",
     "prettier-plugin-jsdoc": "^0.4.2",
     "rimraf": "^3.0.2",
+    "rollup-plugin-visualizer": "^5.8.3",
     "start-server-and-test": "^1.14.0",
     "ts-node": "^10.9.1",
     "typescript": "^4.8.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 85afcb31d..683958bb6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -40,6 +40,9 @@ importers:
       '@types/prettier':
         specifier: ^2.7.1
         version: 2.7.1
+      '@types/rollup-plugin-visualizer':
+        specifier: ^4.2.1
+        version: 4.2.1
       '@typescript-eslint/eslint-plugin':
         specifier: ^5.42.1
         version: 5.42.1_2udltptbznfmezdozpdoa2aemq
@@ -136,6 +139,9 @@ importers:
       rimraf:
         specifier: ^3.0.2
         version: 3.0.2
+      rollup-plugin-visualizer:
+        specifier: ^5.8.3
+        version: 5.8.3_rollup@2.79.1
       start-server-and-test:
         specifier: ^1.14.0
         version: 1.14.0
@@ -2584,6 +2590,13 @@ packages:
     resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
     dev: true
 
+  /@types/rollup-plugin-visualizer/4.2.1:
+    resolution: {integrity: sha512-Fk4y0EgmsSbvbayYhtSI9+cGvgw1rcQ9RlbExkQt4ivXRdiEwFKuRpxNuJCr0JktXIvOPUuPR7GSmtyZu0dujQ==}
+    dependencies:
+      '@types/node': 18.11.9
+      rollup: 2.79.1
+    dev: true
+
   /@types/semver/7.3.12:
     resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==}
     dev: true
@@ -3534,7 +3547,7 @@ packages:
   /axios/0.21.4_debug@4.3.2:
     resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
     dependencies:
-      follow-redirects: 1.15.2
+      follow-redirects: 1.15.2_debug@4.3.2
     transitivePeerDependencies:
       - debug
     dev: true
@@ -6054,6 +6067,18 @@ packages:
         optional: true
     dev: true
 
+  /follow-redirects/1.15.2_debug@4.3.2:
+    resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
+    dependencies:
+      debug: 4.3.2
+    dev: true
+
   /foreground-child/2.0.0:
     resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==}
     engines: {node: '>=8.0.0'}
@@ -9412,6 +9437,22 @@ packages:
     resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==}
     dev: false
 
+  /rollup-plugin-visualizer/5.8.3_rollup@2.79.1:
+    resolution: {integrity: sha512-QGJk4Bqe4AOat5AjipOh8esZH1nck5X2KFpf4VytUdSUuuuSwvIQZjMGgjcxe/zXexltqaXp5Vx1V3LmnQH15Q==}
+    engines: {node: '>=14'}
+    hasBin: true
+    peerDependencies:
+      rollup: 2.x || 3.x
+    peerDependenciesMeta:
+      rollup:
+        optional: true
+    dependencies:
+      open: 8.4.0
+      rollup: 2.79.1
+      source-map: 0.7.4
+      yargs: 17.5.1
+    dev: true
+
   /rollup/2.79.1:
     resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
     engines: {node: '>=10.0.0'}
@@ -9768,6 +9809,11 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /source-map/0.7.4:
+    resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+    engines: {node: '>= 8'}
+    dev: true
+
   /sourcemap-codec/1.4.8:
     resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
     dev: true

From fc859528e4e2845d7952f1a68ee23d181cc95815 Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Sun, 20 Nov 2022 12:10:05 +0530
Subject: [PATCH 55/79] Ignore stats.html

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 8cc09354b..6813b82b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@ tsconfig.tsbuildinfo
 
 knsv*.html
 local*.html
+stats.html

From 4ad99a25d09c698a947ff0234c9899bf89835d55 Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Sun, 20 Nov 2022 14:16:22 +0530
Subject: [PATCH 56/79] feat: Add package visualization

---
 .gitignore     |  2 +-
 .vite/build.ts | 20 ++++++++++++++++++--
 cSpell.json    |  2 ++
 package.json   |  3 ++-
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6813b82b4..f29286825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,4 @@ tsconfig.tsbuildinfo
 
 knsv*.html
 local*.html
-stats.html
+stats/
diff --git a/.vite/build.ts b/.vite/build.ts
index fb5f171e2..c441dc0ab 100644
--- a/.vite/build.ts
+++ b/.vite/build.ts
@@ -4,7 +4,9 @@ import { fileURLToPath } from 'url';
 import jisonPlugin from './jisonPlugin.js';
 import { readFileSync } from 'fs';
 import { visualizer } from 'rollup-plugin-visualizer';
+import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
 
+const visualize = process.argv.includes('--visualize');
 const watch = process.argv.includes('--watch');
 const mermaidOnly = process.argv.includes('--mermaid');
 const __dirname = fileURLToPath(new URL('.', import.meta.url));
@@ -14,6 +16,20 @@ type OutputOptions = Exclude<
   undefined
 >['output'];
 
+const visualizerOptions = (packageName: string): PluginOption[] => {
+  if (packageName !== 'mermaid' || !visualize) {
+    return [];
+  }
+  return ['network', 'treemap', 'sunburst'].map((chartType) =>
+    visualizer({
+      filename: `./stats/${chartType}.html`,
+      template: chartType as TemplateType,
+      gzipSize: true,
+      brotliSize: true,
+    })
+  );
+};
+
 const packageOptions = {
   mermaid: {
     name: 'mermaid',
@@ -96,7 +112,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
     resolve: {
       extensions: ['.jison', '.js', '.ts', '.json'],
     },
-    plugins: [jisonPlugin(), visualizer({ template: 'network' }) as PluginOption],
+    plugins: [jisonPlugin(), ...visualizerOptions(packageName)],
   };
 
   if (watch && config.build) {
@@ -122,7 +138,7 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
 
 const main = async () => {
   const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
-  for (const pkg of packageNames) {
+  for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
     await buildPackage(pkg);
   }
 };
diff --git a/cSpell.json b/cSpell.json
index 3cf8a1e54..03891165f 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -14,6 +14,7 @@
     "bilkent",
     "bisheng",
     "brolin",
+    "brotli",
     "codedoc",
     "colour",
     "cpettitt",
@@ -70,6 +71,7 @@
     "substate",
     "sveidqvist",
     "techn",
+    "treemap",
     "ts-nocheck",
     "tuleap",
     "verdana",
diff --git a/package.json b/package.json
index 52b756f99..10ca11bec 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,9 @@
     "git graph"
   ],
   "scripts": {
-    "build:mermaid": "ts-node-esm --transpileOnly .vite/build.ts --mermaid",
     "build:vite": "ts-node-esm --transpileOnly .vite/build.ts",
+    "build:mermaid": "pnpm build:vite --mermaid",
+    "build:viz": "pnpm build:mermaid --visualize",
     "build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly",
     "build:watch": "pnpm build:vite --watch",
     "build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"",

From 29342ea726aeaa0b77aaf91c766c66d8b2022d6e Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Sun, 20 Nov 2022 17:16:09 +0530
Subject: [PATCH 57/79] fix: Viz build

---
 .vite/build.ts | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/.vite/build.ts b/.vite/build.ts
index c441dc0ab..f2dd7db05 100644
--- a/.vite/build.ts
+++ b/.vite/build.ts
@@ -16,13 +16,13 @@ type OutputOptions = Exclude<
   undefined
 >['output'];
 
-const visualizerOptions = (packageName: string): PluginOption[] => {
+const visualizerOptions = (packageName: string, core = false): PluginOption[] => {
   if (packageName !== 'mermaid' || !visualize) {
     return [];
   }
   return ['network', 'treemap', 'sunburst'].map((chartType) =>
     visualizer({
-      filename: `./stats/${chartType}.html`,
+      filename: `./stats/${chartType}${core ? '.core' : ''}.html`,
       template: chartType as TemplateType,
       gzipSize: true,
       brotliSize: true,
@@ -112,7 +112,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
     resolve: {
       extensions: ['.jison', '.js', '.ts', '.json'],
     },
-    plugins: [jisonPlugin(), ...visualizerOptions(packageName)],
+    plugins: [jisonPlugin(), ...visualizerOptions(packageName, core)],
   };
 
   if (watch && config.build) {
@@ -149,6 +149,9 @@ if (watch) {
     build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
     // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
   }
+} else if (visualize) {
+  await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
+  await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
 } else {
   void main();
 }

From 8a2d3a400c2e9c7c661377cfc40fa9916b80567d Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Sun, 20 Nov 2022 19:12:52 +0530
Subject: [PATCH 58/79] Fix Lodash import

---
 packages/mermaid/src/mermaidAPI.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts
index 0df1da305..25ba03f87 100644
--- a/packages/mermaid/src/mermaidAPI.ts
+++ b/packages/mermaid/src/mermaidAPI.ts
@@ -29,7 +29,7 @@ import utils, { directiveSanitizer } from './utils';
 import DOMPurify from 'dompurify';
 import { MermaidConfig } from './config.type';
 import { evaluate } from './diagrams/common/common';
-import { isEmpty } from 'lodash';
+import isEmpty from 'lodash/isEmpty';
 
 // diagram names that support classDef statements
 const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2'];

From de99cdfb4cc7db05778a19102fd3cca47ae66d50 Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Mon, 21 Nov 2022 08:22:10 +0530
Subject: [PATCH 59/79] chore: Add size shield in readme

Co-authored-by: Alois Klink 
---
 README.md                                | 2 +-
 README.zh-CN.md                          | 2 +-
 docs/intro/index.md                      | 2 +-
 packages/mermaid/README.md               | 2 +-
 packages/mermaid/README.zh-CN.md         | 2 +-
 packages/mermaid/src/docs/intro/index.md | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 4d66d3e6b..d4ed52485 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # mermaid
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 # Whoa, what's going on here?
 
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 62eba5244..4bdbc4ae7 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,6 +1,6 @@
 # mermaid
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 [English](./README.md) | 简体中文
 
diff --git a/docs/intro/index.md b/docs/intro/index.md
index a3ed371ac..b8a27acff 100644
--- a/docs/intro/index.md
+++ b/docs/intro/index.md
@@ -14,7 +14,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
 
 
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 
 
diff --git a/packages/mermaid/README.md b/packages/mermaid/README.md
index 90ae1ad4c..567f522cf 100644
--- a/packages/mermaid/README.md
+++ b/packages/mermaid/README.md
@@ -1,6 +1,6 @@
 # mermaid
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 # Whoa, what's going on here?
 
diff --git a/packages/mermaid/README.zh-CN.md b/packages/mermaid/README.zh-CN.md
index fcaa1f523..0ccef27e4 100644
--- a/packages/mermaid/README.zh-CN.md
+++ b/packages/mermaid/README.zh-CN.md
@@ -1,6 +1,6 @@
 # mermaid
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 [English](./README.md) | 简体中文
 
diff --git a/packages/mermaid/src/docs/intro/index.md b/packages/mermaid/src/docs/intro/index.md
index 80d806730..b58321e75 100644
--- a/packages/mermaid/src/docs/intro/index.md
+++ b/packages/mermaid/src/docs/intro/index.md
@@ -8,7 +8,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
 
 
 
-[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
 
 

From a8c5f6d517a966735fa8c98fba71902c0e657970 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 21 Nov 2022 01:49:48 +0000
Subject: [PATCH 60/79] chore(deps): update lycheeverse/lychee-action action to
 v1.5.4

---
 .github/workflows/link-checker.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml
index 0a499f2d6..fbf03cb39 100644
--- a/.github/workflows/link-checker.yml
+++ b/.github/workflows/link-checker.yml
@@ -36,7 +36,7 @@ jobs:
           restore-keys: cache-lychee-
 
       - name: Link Checker
-        uses: lycheeverse/lychee-action@v1.5.2
+        uses: lycheeverse/lychee-action@v1.5.4
         with:
           args: --verbose --no-progress --cache --max-cache-age 1d packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md
           fail: true

From ed6ad77fd91a33d8c2e723e4199bb41db5edfd8d Mon Sep 17 00:00:00 2001
From: Sidharth Vinod 
Date: Mon, 21 Nov 2022 11:52:57 +0530
Subject: [PATCH 61/79] docs: Remove warning in readme

---
 README.md                  | 17 -----------------
 packages/mermaid/README.md | 17 -----------------
 2 files changed, 34 deletions(-)

diff --git a/README.md b/README.md
index 4d66d3e6b..9d4b44906 100644
--- a/README.md
+++ b/README.md
@@ -2,23 +2,6 @@
 
 [![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
-# Whoa, what's going on here?
-
-We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
-
-- Make it possible to select which diagrams to include on your site
-- Open up for lazy loading
-- Make it possible to add diagrams from outside of the Mermaid repository
-- Separate the release flow between different diagrams and the Mermaid core
-
-As such be aware of some changes..
-
-# We use pnpm now
-
-# The source code has moved
-
-It is now located in the src folder for each respective package located as subfolders in packages.
-
 English | [简体中文](./README.zh-CN.md)
 
 
diff --git a/packages/mermaid/README.md b/packages/mermaid/README.md
index 90ae1ad4c..e8d92350e 100644
--- a/packages/mermaid/README.md
+++ b/packages/mermaid/README.md
@@ -2,23 +2,6 @@
 
 [![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
 
-# Whoa, what's going on here?
-
-We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
-
-- Make it possible to select which diagrams to include on your site
-- Open up for lazy loading
-- Make it possible to add diagrams from outside of the Mermaid repository
-- Separate the release flow between different diagrams and the Mermaid core
-
-As such be aware of some changes..
-
-# We use pnpm now
-
-# The source code has moved
-
-It is now located in the src folder for each respective package located as subfolders in packages.
-
 English | [简体中文](./README.zh-CN.md)
 
 

From b9f0c7c807955fe3fd26155c81f763b18e950084 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 21 Nov 2022 07:10:09 +0000
Subject: [PATCH 62/79] chore(deps): update pnpm to v7.17.0

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 7bd648877..b04c8cf32 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "version": "9.2.2",
   "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
   "type": "module",
-  "packageManager": "pnpm@7.15.0",
+  "packageManager": "pnpm@7.17.0",
   "keywords": [
     "diagram",
     "markdown",

From 564414ecac7f70c7e6b3847c455cf0731e07c3c2 Mon Sep 17 00:00:00 2001
From: Knut Sveidqvist 
Date: Mon, 21 Nov 2022 13:23:25 +0100
Subject: [PATCH 63/79] #3882 fix for issues with mindmaps  with only a single
 node

---
 packages/mermaid-mindmap/src/mindmapRenderer.js | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/packages/mermaid-mindmap/src/mindmapRenderer.js b/packages/mermaid-mindmap/src/mindmapRenderer.js
index c0760e4ac..9fd557e51 100644
--- a/packages/mermaid-mindmap/src/mindmapRenderer.js
+++ b/packages/mermaid-mindmap/src/mindmapRenderer.js
@@ -92,10 +92,6 @@ function addNodes(mindmap, cy, conf, level) {
  */
 function layoutMindmap(node, conf) {
   return new Promise((resolve) => {
-    if (node.children.length === 0) {
-      return node;
-    }
-
     // Add temporary render element
     const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
     const cy = cytoscape({

From 78b7941f2d43a7f8bf62aa056ac84e01f8425e4e Mon Sep 17 00:00:00 2001
From: Knut Sveidqvist 
Date: Mon, 21 Nov 2022 14:06:09 +0100
Subject: [PATCH 64/79] #3835 Adding path to list of elements to be styled

---
 packages/mermaid/src/mermaidAPI.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts
index 0df1da305..50e1c70a8 100644
--- a/packages/mermaid/src/mermaidAPI.ts
+++ b/packages/mermaid/src/mermaidAPI.ts
@@ -194,7 +194,7 @@ export const createCssStyles = (
       const htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config?
 
       const cssHtmlElements = ['> *', 'span']; // TODO make a constant
-      const cssShapeElements = ['rect', 'polygon', 'ellipse', 'circle']; // TODO make a constant
+      const cssShapeElements = ['rect', 'polygon', 'ellipse', 'circle', 'path']; // TODO make a constant
 
       const cssElements = htmlLabels ? cssHtmlElements : cssShapeElements;
 

From f9222a3bf4721d6f60196c34addaede7502e60bd Mon Sep 17 00:00:00 2001
From: Knut Sveidqvist 
Date: Mon, 21 Nov 2022 14:30:06 +0100
Subject: [PATCH 65/79] #3831 Re-enabling themes for er diagrams

---
 .../mermaid/src/diagrams/er/erRenderer.js     | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js
index a08f166c4..d0771fe39 100644
--- a/packages/mermaid/src/diagrams/er/erRenderer.js
+++ b/packages/mermaid/src/diagrams/er/erRenderer.js
@@ -211,9 +211,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
       const typeRect = groupNode
         .insert('rect', '#' + attributeNode.tn.node().id)
         .classed(`er ${attribStyle}`, true)
-        .style('fill', conf.fill)
-        .style('fill-opacity', '100%')
-        .style('stroke', conf.stroke)
         .attr('x', 0)
         .attr('y', heightOffset)
         .attr('width', maxTypeWidth + widthPadding * 2 + spareColumnWidth)
@@ -231,9 +228,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
       const nameRect = groupNode
         .insert('rect', '#' + attributeNode.nn.node().id)
         .classed(`er ${attribStyle}`, true)
-        .style('fill', conf.fill)
-        .style('fill-opacity', '100%')
-        .style('stroke', conf.stroke)
         .attr('x', nameXOffset)
         .attr('y', heightOffset)
         .attr('width', maxNameWidth + widthPadding * 2 + spareColumnWidth)
@@ -253,9 +247,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
         const keyTypeRect = groupNode
           .insert('rect', '#' + attributeNode.kn.node().id)
           .classed(`er ${attribStyle}`, true)
-          .style('fill', conf.fill)
-          .style('fill-opacity', '100%')
-          .style('stroke', conf.stroke)
           .attr('x', keyTypeAndCommentXOffset)
           .attr('y', heightOffset)
           .attr('width', maxKeyWidth + widthPadding * 2 + spareColumnWidth)
@@ -276,9 +267,6 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => {
         groupNode
           .insert('rect', '#' + attributeNode.cn.node().id)
           .classed(`er ${attribStyle}`, 'true')
-          .style('fill', conf.fill)
-          .style('fill-opacity', '100%')
-          .style('stroke', conf.stroke)
           .attr('x', keyTypeAndCommentXOffset)
           .attr('y', heightOffset)
           .attr('width', maxCommentWidth + widthPadding * 2 + spareColumnWidth)
@@ -348,9 +336,6 @@ const drawEntities = function (svgNode, entities, graph) {
     const rectNode = groupNode
       .insert('rect', '#' + textId)
       .classed('er entityBox', true)
-      .style('fill', conf.fill)
-      .style('fill-opacity', '100%')
-      .style('stroke', conf.stroke)
       .attr('x', 0)
       .attr('y', 0)
       .attr('width', entityWidth)
@@ -548,9 +533,7 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) {
     .attr('x', labelPoint.x - labelBBox.width / 2)
     .attr('y', labelPoint.y - labelBBox.height / 2)
     .attr('width', labelBBox.width)
-    .attr('height', labelBBox.height)
-    .style('fill', 'white')
-    .style('fill-opacity', '85%');
+    .attr('height', labelBBox.height);
 };
 
 /**

From 22993e8b6c47b571f2935333f74af650a938b683 Mon Sep 17 00:00:00 2001
From: "Ashley Engelund (weedySeaDragon @ github)" 
Date: Mon, 21 Nov 2022 16:35:02 -0800
Subject: [PATCH 66/79] remove console stmt

---
 packages/mermaid/src/diagrams/pie/pieDetector.ts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/mermaid/src/diagrams/pie/pieDetector.ts b/packages/mermaid/src/diagrams/pie/pieDetector.ts
index 9010f8a96..e267c710a 100644
--- a/packages/mermaid/src/diagrams/pie/pieDetector.ts
+++ b/packages/mermaid/src/diagrams/pie/pieDetector.ts
@@ -2,6 +2,5 @@ import type { DiagramDetector } from '../../diagram-api/types';
 
 export const pieDetector: DiagramDetector = (txt) => {
   const logOutput = txt.match(/^\s*pie/) !== null || txt.match(/^\s*bar/) !== null;
-  console.log(logOutput);
   return logOutput;
 };

From e1c2b1ddb54d00697985620f7b16d1f7cd2c993c Mon Sep 17 00:00:00 2001
From: "Ashley Engelund (weedySeaDragon @ github)" 
Date: Mon, 21 Nov 2022 16:28:47 -0800
Subject: [PATCH 67/79] refine - what is not done yet

---
 docs/syntax/stateDiagram.md                   | 240 ++++++++++++++++--
 .../mermaid/src/docs/syntax/stateDiagram.md   | 190 ++++++++++++--
 2 files changed, 388 insertions(+), 42 deletions(-)

diff --git a/docs/syntax/stateDiagram.md b/docs/syntax/stateDiagram.md
index 1cec5afca..afb1349ef 100644
--- a/docs/syntax/stateDiagram.md
+++ b/docs/syntax/stateDiagram.md
@@ -6,9 +6,12 @@
 
 # State diagrams
 
-> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia
+> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems.
+> State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the
+> case, while at other times this is a reasonable abstraction." Wikipedia
 
-Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
+Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make
+it easier for users to share diagrams between mermaid and plantUml.
 
 ```mermaid-example
 ---
@@ -62,20 +65,23 @@ stateDiagram
     Crash --> [*]
 ```
 
-In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash.
+In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via
+a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the
+**Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to
+the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.)
 
 ## States
 
-A state can be declared in multiple ways. The simplest way is to define a state id as a description.
+A state can be declared in multiple ways. The simplest way is to define a state with just an id:
 
 ```mermaid-example
 stateDiagram-v2
-    s1
+    stateId
 ```
 
 ```mermaid
 stateDiagram-v2
-    s1
+    stateId
 ```
 
 Another way is by using the state keyword with a description as per below:
@@ -106,7 +112,8 @@ stateDiagram-v2
 
 Transitions are path/edges when one state passes into another. This is represented using text arrow, "-->".
 
-When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way.
+When you define a transition between two states and the states are not already defined, the undefined states are defined
+with the id from the transition. You can later add descriptions to states defined this way.
 
 ```mermaid-example
 stateDiagram-v2
@@ -118,7 +125,7 @@ stateDiagram-v2
     s1 --> s2
 ```
 
-It is possible to add text to a transition. To describe what it represents.
+It is possible to add text to a transition to describe what it represents:
 
 ```mermaid-example
 stateDiagram-v2
@@ -132,7 +139,8 @@ stateDiagram-v2
 
 ## Start and End
 
-There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and the direction of the transition to it defines it either as a start or a stop state.
+There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and
+the direction of the transition to it defines it either as a start or a stop state.
 
 ```mermaid-example
 stateDiagram-v2
@@ -148,10 +156,11 @@ stateDiagram-v2
 
 ## Composite states
 
-In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can
+In a real world use of state diagrams you often end up with diagrams that are multidimensional as one state can
 have several internal states. These are called composite states in this terminology.
 
-In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between {}. See the example below:
+In order to define a composite state you need to use the state keyword followed by an id and the body of the composite
+state between {}. See the example below:
 
 ```mermaid-example
 stateDiagram-v2
@@ -311,7 +320,7 @@ It is possible to specify a fork in the diagram using <\> <\>.
 
 ## Notes
 
-Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams.
+Sometimes nothing says it better than a Post-it note. That is also the case in state diagrams.
 
 Here you can choose to put the note to the _right of_ or to the _left of_ a node.
 
@@ -381,7 +390,8 @@ stateDiagram-v2
 
 ## Setting the direction of the diagram
 
-With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example.
+With state diagrams you can use the direction statement to set the direction which the diagram will render like in this
+example.
 
 ```mermaid-example
 stateDiagram
@@ -411,7 +421,9 @@ stateDiagram
 
 ## Comments
 
-Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
+Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their
+own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next
+newline will be treated as a comment, including any diagram syntax
 
 ```mermaid-example
 stateDiagram-v2
@@ -435,22 +447,204 @@ stateDiagram-v2
     Crash --> [*]
 ```
 
-## Styling
+## Styling with classDefs
 
-Styling of the a state diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/state.scss
+As with other diagrams (like flowcharts), you can define a style in the diagram itself and apply that named style to a
+state or states in the diagram.
+
+**These are the current limitations with state diagram classDefs:**
+
+1.  They cannot be applied to start or end states
+2.  The cannot be applied to or within composite states
+
+_These are in development and will be available in a future version._
+
+You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something
+like a _CSS class_)
+followed by _a name for the style,_
+and then one or more _property-value pairs_. Each _property-value pair_ is
+a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by a colon (`:`) and then a _value._
+
+Here is an example of a classDef with just one property-value pair:
+
+        classDef movement font-style:italic;
+
+where
+
+- the _name_ of the style is `movement`
+- the only _property_ is `font-style` and its _value_ is `italic`
+
+If you want to have more than one _property-value pair_ then you put a comma (`,`) between each _property-value pair._
+
+Here is an example with three property-value pairs:
+
+        classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+where
+
+- the _name_ of the style is `badBadEvent`
+- the first _property_ is `fill` and its _value_ is `#f00`
+- the second _property_ is `color` and its _value_ is `white`
+- the third _property_ is `font-weight` and its _value_ is `bold`
+- the fourth _property_ is `stroke-width` and its _value_ is `2px`
+- the fifth _property_ is `stroke` and its _value_ is `yello`
+
+### Apply classDef styles to states
+
+There are two ways to apply a `classDef` style to a state:
+
+1.  use the `class` keyword to apply a classDef style to one or more states in a single statement, or
+2.  use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow
+    to/from another state)
+
+#### 1. `class` statement
+
+A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is:
+
+```text
+    class [one or more state names, separated by commas] [name of a style defined with classDef]
+```
+
+Here is an example applying the `badBadEvent` style to a state named `Crash`:
+
+```text
+class Crash badBadEvent
+```
+
+Here is an example applying the `movement` style to the two states `Moving` and `Crash`:
+
+```text
+class Moving, Crash movement
+```
+
+Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement`
+and `badBadEvent`
+
+```mermaid-example
+   stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*]--> Still
+   Still --> [*]
+   Still --> Moving
+   Moving --> Still
+   Moving --> Crash
+   Crash --> [*]
+
+   class Still notMoving
+   class Moving, Crash movement
+   class Crash badBadEvent
+   class end badBadEvent
+```
+
+```mermaid
+   stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*]--> Still
+   Still --> [*]
+   Still --> Moving
+   Moving --> Still
+   Moving --> Crash
+   Crash --> [*]
+
+   class Still notMoving
+   class Moving, Crash movement
+   class Crash badBadEvent
+   class end badBadEvent
+```
+
+#### 2. `:::` operator to apply a style to a state
+
+You can apply a classDef style to a state using the `:::` (three colons) operator. The syntax is
+
+```text
+[state]:::[style name]
+```
+
+You can use this in a diagram within a statement using a class. This includes the start and end states. For example:
+
+```mermaid-example
+stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic;
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*] --> Still:::notMoving
+   Still --> [*]
+   Still --> Moving:::movement
+   Moving --> Still
+   Moving --> Crash:::movement
+   Crash:::badBadEvent --> [*]
+```
+
+```mermaid
+stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic;
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*] --> Still:::notMoving
+   Still --> [*]
+   Still --> Moving:::movement
+   Moving --> Still
+   Moving --> Crash:::movement
+   Crash:::badBadEvent --> [*]
+```
 
 ## Spaces in state names
 
-Spaces can be added to a state by defining it at the top and referencing the acronym later.
+Spaces can be added to a state by first defining the state with an id and then referencing the id later.
+
+In the following example there is a state with the id **yswsii** and description **Your state with spaces in it**.
+After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`)
+and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`).\
+(**yswsii** has been styled so that it is different from the other states.)
 
 ```mermaid-example
-stateDiagram-v2
-    Yswsii: Your state with spaces in it
-    [*] --> Yswsii
+stateDiagram
+    classDef yourState font-style:italic,font-weight:bold,fill:white
+
+    yswsii: Your state with spaces in it
+    [*] --> yswsii:::yourState
+    [*] --> SomeOtherState
+    SomeOtherState --> YetAnotherState
+    yswsii --> YetAnotherState
+    YetAnotherState --> [*]
 ```
 
 ```mermaid
-stateDiagram-v2
-    Yswsii: Your state with spaces in it
-    [*] --> Yswsii
+stateDiagram
+    classDef yourState font-style:italic,font-weight:bold,fill:white
+
+    yswsii: Your state with spaces in it
+    [*] --> yswsii:::yourState
+    [*] --> SomeOtherState
+    SomeOtherState --> YetAnotherState
+    yswsii --> YetAnotherState
+    YetAnotherState --> [*]
 ```
diff --git a/packages/mermaid/src/docs/syntax/stateDiagram.md b/packages/mermaid/src/docs/syntax/stateDiagram.md
index 9293e1083..3687518b2 100644
--- a/packages/mermaid/src/docs/syntax/stateDiagram.md
+++ b/packages/mermaid/src/docs/syntax/stateDiagram.md
@@ -1,8 +1,11 @@
 # State diagrams
 
-> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia
+> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems.
+> State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the
+> case, while at other times this is a reasonable abstraction." Wikipedia
 
-Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
+Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make
+it easier for users to share diagrams between mermaid and plantUml.
 
 ```mermaid-example
 ---
@@ -31,15 +34,18 @@ stateDiagram
     Crash --> [*]
 ```
 
-In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash.
+In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via
+a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the 
+ **Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to
+the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.)
 
 ## States
 
-A state can be declared in multiple ways. The simplest way is to define a state id as a description.
+A state can be declared in multiple ways. The simplest way is to define a state with just an id:
 
 ```mermaid-example
 stateDiagram-v2
-    s1
+    stateId
 ```
 
 Another way is by using the state keyword with a description as per below:
@@ -60,14 +66,15 @@ stateDiagram-v2
 
 Transitions are path/edges when one state passes into another. This is represented using text arrow, "\-\-\>".
 
-When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way.
+When you define a transition between two states and the states are not already defined, the undefined states are defined
+with the id from the transition. You can later add descriptions to states defined this way.
 
 ```mermaid-example
 stateDiagram-v2
     s1 --> s2
 ```
 
-It is possible to add text to a transition. To describe what it represents.
+It is possible to add text to a transition to describe what it represents:
 
 ```mermaid-example
 stateDiagram-v2
@@ -76,7 +83,8 @@ stateDiagram-v2
 
 ## Start and End
 
-There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and the direction of the transition to it defines it either as a start or a stop state.
+There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and
+the direction of the transition to it defines it either as a start or a stop state.
 
 ```mermaid-example
 stateDiagram-v2
@@ -86,10 +94,11 @@ stateDiagram-v2
 
 ## Composite states
 
-In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can
+In a real world use of state diagrams you often end up with diagrams that are multidimensional as one state can
 have several internal states. These are called composite states in this terminology.
 
-In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between \{\}. See the example below:
+In order to define a composite state you need to use the state keyword followed by an id and the body of the composite
+state between \{\}. See the example below:
 
 ```mermaid-example
 stateDiagram-v2
@@ -178,7 +187,7 @@ It is possible to specify a fork in the diagram using <<fork>> <&
 
 ## Notes
 
-Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams.
+Sometimes nothing says it better than a Post-it note. That is also the case in state diagrams.
 
 Here you can choose to put the note to the _right of_ or to the _left of_ a node.
 
@@ -218,7 +227,8 @@ stateDiagram-v2
 
 ## Setting the direction of the diagram
 
-With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example.
+With state diagrams you can use the direction statement to set the direction which the diagram will render like in this
+example.
 
 ```mermaid-example
 stateDiagram
@@ -235,7 +245,9 @@ stateDiagram
 
 ## Comments
 
-Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
+Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their
+own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next
+newline will be treated as a comment, including any diagram syntax
 
 ```mmd
 stateDiagram-v2
@@ -248,16 +260,156 @@ stateDiagram-v2
     Crash --> [*]
 ```
 
-## Styling
+## Styling with classDefs
+
+As with other diagrams (like flowcharts), you can define a style in the diagram itself and apply that named style to a
+state or states in the diagram.
+
+**These are the current limitations with state diagram classDefs:**
+1. They cannot be applied to start or end states
+2. The cannot be applied to or within composite states
+
+_These are in development and will be available in a future version._
+
+
+You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something
+like a _CSS class_)
+followed by _a name for the style,_
+and then one or more _property-value pairs_. Each _property-value pair_ is
+a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by a colon (`:`) and then a _value._
+
+Here is an example of a classDef with just one property-value pair:
+
+```
+    classDef movement font-style:italic;
+```
+
+where
+
+- the _name_ of the style is `movement`
+- the only _property_ is `font-style` and its _value_ is `italic`
+
+If you want to have more than one _property-value pair_ then you put a comma (`,`) between each _property-value pair._
+
+Here is an example with three property-value pairs:
+
+```
+    classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+```
+
+where
+
+- the _name_ of the style is `badBadEvent`
+- the first _property_ is `fill` and its _value_ is `#f00`
+- the second _property_ is `color` and its _value_ is `white`
+- the third _property_ is `font-weight` and its _value_ is `bold`
+- the fourth _property_ is `stroke-width` and its _value_ is `2px`
+- the fifth _property_ is `stroke` and its _value_ is `yello`
+
+### Apply classDef styles to states
+
+There are two ways to apply a `classDef` style to a state:
+
+1. use the `class` keyword to apply a classDef style to one or more states in a single statement, or
+2. use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow
+   to/from another state)
+
+
+#### 1. `class` statement
+
+A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is:
+
+```text
+    class [one or more state names, separated by commas] [name of a style defined with classDef]
+```
+
+Here is an example applying the `badBadEvent` style to a state named `Crash`:
+
+```text
+class Crash badBadEvent
+```
+
+Here is an example applying the `movement` style to the two states `Moving` and `Crash`:
+
+```text
+class Moving, Crash movement
+```
+
+
+Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement`
+and `badBadEvent`
+
+```mermaid-example
+   stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*]--> Still
+   Still --> [*]
+   Still --> Moving
+   Moving --> Still
+   Moving --> Crash
+   Crash --> [*]
+
+   class Still notMoving
+   class Moving, Crash movement
+   class Crash badBadEvent
+   class end badBadEvent
+```
+
+#### 2. `:::` operator to apply a style to a state
+
+You can apply a classDef style to a state using the `:::` (three colons) operator. The syntax is
+
+```text
+[state]:::[style name]
+```
+
+You can use this in a diagram within a statement using a class. This includes the start and end states. For example:
+
+```mermaid-example
+stateDiagram
+   direction TB
+
+   accTitle: This is the accessible title
+   accDescr: This is an accessible description
+
+   classDef notMoving fill:white
+   classDef movement font-style:italic;
+   classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+   [*] --> Still:::notMoving
+   Still --> [*]
+   Still --> Moving:::movement
+   Moving --> Still
+   Moving --> Crash:::movement
+   Crash:::badBadEvent --> [*]
+```
+
 
-Styling of the a state diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/state.scss
 
 ## Spaces in state names
 
-Spaces can be added to a state by defining it at the top and referencing the acronym later.
+Spaces can be added to a state by first defining the state with an id and then referencing the id later.
 
+In the following example there is a state with the id **yswsii** and description **Your state with spaces in it**.
+After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`)
+and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`).  
+(**yswsii** has been styled so that it is different from the other states.)
 ```mermaid-example
-stateDiagram-v2
-    Yswsii: Your state with spaces in it
-    [*] --> Yswsii
+stateDiagram
+    classDef yourState font-style:italic,font-weight:bold,fill:white
+    
+    yswsii: Your state with spaces in it
+    [*] --> yswsii:::yourState
+    [*] --> SomeOtherState
+    SomeOtherState --> YetAnotherState
+    yswsii --> YetAnotherState
+    YetAnotherState --> [*]
 ```

From 98e4b6f338cb725947bd496403c5d6bec0537b0f Mon Sep 17 00:00:00 2001
From: "Ashley Engelund (weedySeaDragon @ github)" 
Date: Mon, 21 Nov 2022 16:58:59 -0800
Subject: [PATCH 68/79] add 'horz' to cSpell (in pieDetector.ts commented out
 barChart work)

---
 cSpell.json                                      | 1 +
 packages/mermaid/src/diagrams/pie/pieDetector.ts | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/cSpell.json b/cSpell.json
index 03891165f..8e92ffa8a 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -36,6 +36,7 @@
     "graphlib",
     "grav",
     "greywolf",
+    "horz",
     "inkdrop",
     "jaoude",
     "jison",
diff --git a/packages/mermaid/src/diagrams/pie/pieDetector.ts b/packages/mermaid/src/diagrams/pie/pieDetector.ts
index 9010f8a96..e267c710a 100644
--- a/packages/mermaid/src/diagrams/pie/pieDetector.ts
+++ b/packages/mermaid/src/diagrams/pie/pieDetector.ts
@@ -2,6 +2,5 @@ import type { DiagramDetector } from '../../diagram-api/types';
 
 export const pieDetector: DiagramDetector = (txt) => {
   const logOutput = txt.match(/^\s*pie/) !== null || txt.match(/^\s*bar/) !== null;
-  console.log(logOutput);
   return logOutput;
 };

From e2e604a76a9ad0316967d5fac8b304cffe072791 Mon Sep 17 00:00:00 2001
From: "Ashley Engelund (weedySeaDragon @ github)" 
Date: Mon, 21 Nov 2022 16:59:55 -0800
Subject: [PATCH 69/79] update demos/state.html to includ examples; formatting

---
 demos/state.html                              | 82 +++++++++++++++++--
 .../mermaid/src/docs/syntax/stateDiagram.md   | 13 ++-
 2 files changed, 78 insertions(+), 17 deletions(-)

diff --git a/demos/state.html b/demos/state.html
index c13da84d8..3d070f379 100644
--- a/demos/state.html
+++ b/demos/state.html
@@ -1,5 +1,5 @@
 
-
+
   
     
     
@@ -33,8 +33,9 @@ title: Very simple diagram
     

classDef notMoving fill:white
- classDef movement font-style:italic;
- classDef badBadEvent fill:#f00,color:white,font-weight:bold
+ classDef movement font-style:italic
+ classDef badBadEvent + fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow

And these are how they are applied:

@@ -49,15 +50,17 @@ title: Very simple diagram --- title: Very simple diagram --- - stateDiagram-v2 + stateDiagram + direction TB + accTitle: This is the accessible title accDescr: This is an accessible description classDef notMoving fill:white - classDef movement font-style:italic; - classDef badBadEvent fill:#f00,color:white,font-weight:bold + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow - [*] --> Still + [*]--> Still Still --> [*] Still --> Moving Moving --> Still @@ -67,10 +70,57 @@ title: Very simple diagram class Still notMoving class Moving, Crash movement class Crash badBadEvent + class end badBadEvent

+

Here is a diagram that uses the ::: operator to apply styles to states

+

Here are the classDef statements:

+

+ + classDef notMoving fill:white
+ classDef movement font-style:italic
+ classDef badBadEvent + fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+

+

And these are how they are applied:

+

+ + [*] --> Still:::notMoving
+ ...
+ Still --> Moving:::movement
+ ...
+ Moving --> Crash:::movement
+ Crash:::badBadEvent --> [*]
+
+

+

+ Note that both the starting state and the end state have styles applied:
+ The start state has the start classDef style
and the end state has the + stop classDef style applied. +

+
+    stateDiagram
+      direction TB
+
+		  accTitle: This is the accessible title
+      accDescr: This is an accessible description
+
+      classDef notMoving fill:white
+      classDef movement font-style:italic
+      classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
+
+      [*] --> Still:::notMoving
+      Still --> [*]
+      Still --> Moving:::movement
+      Moving --> Still
+      Moving --> Crash:::movement
+      Crash:::badBadEvent --> [*]
+    
+
+
     stateDiagram-v2
       accTitle: very very simple state
@@ -79,6 +129,20 @@ title: Very simple diagram
     

+

States with spaces in them

+
+      stateDiagram
+        classDef yourState font-style:italic,font-weight:bold,fill:white
+
+        yswsii: Your state with spaces in it
+        [*] --> yswsii:::yourState
+        [*] --> SomeOtherState
+        SomeOtherState --> YetAnotherState
+        yswsii --> YetAnotherState
+        YetAnotherState --> [*]
+    
+
+

You can label the relationships

     stateDiagram-v2
@@ -127,7 +191,7 @@ title: Very simple diagram
     
       stateDiagram-v2
       [*] --> S1
-      S1 --> S2: This long line uses a br tag
to create multiple
lines. + S1 --> S2: This long line uses a br tag
to create multiple
lines. S1 --> S3: This transition descripton uses \na newline character\nto create multiple\nlines.
@@ -139,7 +203,7 @@ title: Very simple diagram direction LR State1: A state with a note note right of State1 - Important information!
You can write notes.
And\nthey\ncan\nbe\nmulti-\nline. + Important information!
You can write notes.
And\nthey\ncan\nbe\nmulti-\nline. end note State1 --> State2 note left of State2 : Notes can be to the left of a state\n(like this one). diff --git a/packages/mermaid/src/docs/syntax/stateDiagram.md b/packages/mermaid/src/docs/syntax/stateDiagram.md index 3687518b2..a9cb72948 100644 --- a/packages/mermaid/src/docs/syntax/stateDiagram.md +++ b/packages/mermaid/src/docs/syntax/stateDiagram.md @@ -35,8 +35,8 @@ stateDiagram ``` In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via -a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the - **Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to +a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the +**Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.) ## States @@ -266,12 +266,12 @@ As with other diagrams (like flowcharts), you can define a style in the diagram state or states in the diagram. **These are the current limitations with state diagram classDefs:** + 1. They cannot be applied to start or end states 2. The cannot be applied to or within composite states _These are in development and will be available in a future version._ - You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something like a _CSS class_) followed by _a name for the style,_ @@ -314,7 +314,6 @@ There are two ways to apply a `classDef` style to a state: 2. use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow to/from another state) - #### 1. `class` statement A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is: @@ -335,7 +334,6 @@ Here is an example applying the `movement` style to the two states `Moving` and class Moving, Crash movement ``` - Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement` and `badBadEvent` @@ -392,8 +390,6 @@ stateDiagram Crash:::badBadEvent --> [*] ``` - - ## Spaces in state names Spaces can be added to a state by first defining the state with an id and then referencing the id later. @@ -402,10 +398,11 @@ In the following example there is a state with the id **yswsii** and description After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`) and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`). (**yswsii** has been styled so that it is different from the other states.) + ```mermaid-example stateDiagram classDef yourState font-style:italic,font-weight:bold,fill:white - + yswsii: Your state with spaces in it [*] --> yswsii:::yourState [*] --> SomeOtherState From 31380368e14abdb29803db3dd263ac9b5878ad24 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 22 Nov 2022 10:49:45 +0530 Subject: [PATCH 70/79] chore: Fix cSpell in pieRenderer --- packages/mermaid/src/diagrams/pie/pieRenderer.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.js b/packages/mermaid/src/diagrams/pie/pieRenderer.js index 016afccc4..3faa752fd 100644 --- a/packages/mermaid/src/diagrams/pie/pieRenderer.js +++ b/packages/mermaid/src/diagrams/pie/pieRenderer.js @@ -161,9 +161,9 @@ let conf = configApi.getConfig(); // .attr('transform', function (d, i) { // var height = legendRectSize + legendSpacing; // var offset = (height * color.domain().length) / 2; -// var horz = 12 * legendRectSize; -// var vert = i * height - offset; -// return 'translate(' + horz + ',' + vert + ')'; +// var horizontal = 12 * legendRectSize; +// var vertical = i * height - offset; +// return 'translate(' + horizontal + ',' + vertical + ')'; // }); // legend @@ -337,11 +337,11 @@ export const draw = (txt, id, _version, diagObj) => { .append('g') .attr('class', 'legend') .attr('transform', function (d, i) { - var height = legendRectSize + legendSpacing; - var offset = (height * color.domain().length) / 2; - var horz = 12 * legendRectSize; - var vert = i * height - offset; - return 'translate(' + horz + ',' + vert + ')'; + const height = legendRectSize + legendSpacing; + const offset = (height * color.domain().length) / 2; + const horizontal = 12 * legendRectSize; + const vertical = i * height - offset; + return 'translate(' + horizontal + ',' + vertical + ')'; }); legend From 9eb506f6c53a4ec095e6222ba421baedd61d534d Mon Sep 17 00:00:00 2001 From: Per Brolin Date: Tue, 22 Nov 2022 10:04:28 +0100 Subject: [PATCH 71/79] Revert "Added pie" This reverts commit 1d9fefe7ac65990e4dd06a7e0e29976a873db844. --- cypress/platform/per.html | 46 ++--- demos/pie.html | 2 +- .../mermaid/src/diagrams/pie/parser/pie.jison | 10 +- packages/mermaid/src/diagrams/pie/pieDb.js | 13 -- .../mermaid/src/diagrams/pie/pieDetector.ts | 3 +- .../mermaid/src/diagrams/pie/pieRenderer.js | 187 +----------------- 6 files changed, 23 insertions(+), 238 deletions(-) diff --git a/cypress/platform/per.html b/cypress/platform/per.html index f68a3f50b..4fca4c808 100644 --- a/cypress/platform/per.html +++ b/cypress/platform/per.html @@ -6,10 +6,6 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> -
Security check
-bar title Pets adopted by volunteers
-    "Dogs" : 386
-    "Cats" : 85
-    "Rats" : 15
-    
- - - - - - - +flowchart LR +A-->B +
+
+            mindmap
+          root
+            ch1
+            ch2
+        
+ + +