diff --git a/.changeset/angry-bags-brake.md b/.changeset/angry-bags-brake.md
new file mode 100644
index 000000000..472e486ec
--- /dev/null
+++ b/.changeset/angry-bags-brake.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: architecture diagrams no longer grow to extreme heights due to conflicting alignments
diff --git a/.changeset/bright-ads-exist.md b/.changeset/bright-ads-exist.md
new file mode 100644
index 000000000..ef2f76f4c
--- /dev/null
+++ b/.changeset/bright-ads-exist.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+Fixes for consistent edge id creation & handling edge cases for animate edge feature
diff --git a/.changeset/chatty-elephants-warn.md b/.changeset/chatty-elephants-warn.md
new file mode 100644
index 000000000..225047ece
--- /dev/null
+++ b/.changeset/chatty-elephants-warn.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+Fix for issue #6195 - allowing @ signs inside node labels
diff --git a/.changeset/chilly-years-cheat.md b/.changeset/chilly-years-cheat.md
new file mode 100644
index 000000000..e665af75b
--- /dev/null
+++ b/.changeset/chilly-years-cheat.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each class diagram
diff --git a/.changeset/dull-tips-cough.md b/.changeset/dull-tips-cough.md
new file mode 100644
index 000000000..1f5179417
--- /dev/null
+++ b/.changeset/dull-tips-cough.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: revert state db to resolve getData returning empty nodes and edges
diff --git a/.changeset/great-ghosts-rule.md b/.changeset/great-ghosts-rule.md
new file mode 100644
index 000000000..f11c6e2a9
--- /dev/null
+++ b/.changeset/great-ghosts-rule.md
@@ -0,0 +1,8 @@
+---
+'mermaid': minor
+---
+
+Flowchart new syntax for node metadata bugs
+
+- Incorrect label mapping for nodes when using `&`
+- Syntax error when `}` with trailing spaces before new line
diff --git a/.changeset/grumpy-cheetahs-deliver.md b/.changeset/grumpy-cheetahs-deliver.md
new file mode 100644
index 000000000..fa6736d42
--- /dev/null
+++ b/.changeset/grumpy-cheetahs-deliver.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+`mermaidAPI.getDiagramFromText()` now returns a new db instance on each call for state diagrams
diff --git a/.changeset/heavy-moose-mix.md b/.changeset/heavy-moose-mix.md
new file mode 100644
index 000000000..c02d62446
--- /dev/null
+++ b/.changeset/heavy-moose-mix.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+Added versioning to StateDB and updated tests and diagrams to use it.
diff --git a/.changeset/many-brooms-promise.md b/.changeset/many-brooms-promise.md
new file mode 100644
index 000000000..fec442b34
--- /dev/null
+++ b/.changeset/many-brooms-promise.md
@@ -0,0 +1,5 @@
+---
+'mermaid': minor
+---
+
+Adding support for animation of flowchart edges
diff --git a/.changeset/new-kiwis-listen.md b/.changeset/new-kiwis-listen.md
new file mode 100644
index 000000000..24306573c
--- /dev/null
+++ b/.changeset/new-kiwis-listen.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each flowchart
diff --git a/.changeset/poor-masks-change.md b/.changeset/poor-masks-change.md
new file mode 100644
index 000000000..2896e7b90
--- /dev/null
+++ b/.changeset/poor-masks-change.md
@@ -0,0 +1,8 @@
+---
+'mermaid': minor
+---
+
+Upgrade Requirement and ER diagram to use the common renderer flow
+
+- Added support for directions
+- Added support for hand drawn look
diff --git a/.changeset/silver-olives-marry.md b/.changeset/silver-olives-marry.md
new file mode 100644
index 000000000..d709b17ba
--- /dev/null
+++ b/.changeset/silver-olives-marry.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: `mermaidAPI.getDiagramFromText()` now returns a new different db for each sequence diagram. Added unique IDs for messages.
diff --git a/.changeset/stupid-dots-do.md b/.changeset/stupid-dots-do.md
new file mode 100644
index 000000000..594fa9536
--- /dev/null
+++ b/.changeset/stupid-dots-do.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: Gantt, Sankey and User Journey diagram are now able to pick font-family from mermaid config.
diff --git a/.changeset/vast-nails-stay.md b/.changeset/vast-nails-stay.md
new file mode 100644
index 000000000..de2059b32
--- /dev/null
+++ b/.changeset/vast-nails-stay.md
@@ -0,0 +1,5 @@
+---
+'mermaid': minor
+---
+
+The arrowhead color should match the color of the edge. Creates a unique clone of the arrow marker with the appropriate color.
diff --git a/.changeset/weak-trees-perform.md b/.changeset/weak-trees-perform.md
new file mode 100644
index 000000000..17175301d
--- /dev/null
+++ b/.changeset/weak-trees-perform.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+fix: `getDirection` and `setDirection` in `stateDb` refactored to return and set actual direction
diff --git a/.changeset/witty-crews-smell.md b/.changeset/witty-crews-smell.md
new file mode 100644
index 000000000..4213083f2
--- /dev/null
+++ b/.changeset/witty-crews-smell.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+`mermaidAPI.getDiagramFromText()` now returns a new different db for each state diagram
diff --git a/.cspell/libraries.txt b/.cspell/libraries.txt
index 73a2dceeb..185d284f7 100644
--- a/.cspell/libraries.txt
+++ b/.cspell/libraries.txt
@@ -26,6 +26,7 @@ dompurify
 elkjs
 fcose
 fontawesome
+Forgejo
 Foswiki
 Gitea
 graphlib
diff --git a/.github/lychee.toml b/.github/lychee.toml
index 288ab054a..5070c3d50 100644
--- a/.github/lychee.toml
+++ b/.github/lychee.toml
@@ -47,7 +47,10 @@ exclude = [
 "https://(www.)?drupal.org",
 
 # Swimm returns 404, eventhough the link is valid
-"https://docs.swimm.io"
+"https://docs.swimm.io",
+
+# Timeout
+"https://huehive.co"
 ]
 
 # Exclude all private IPs from checking.
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index 13b913c11..5b1066661 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -13,13 +13,13 @@ jobs:
   autofix:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
         # uses version from "packageManager" field in package.json
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
@@ -42,4 +42,4 @@ jobs:
         working-directory: ./packages/mermaid
         run: pnpm run docs:build
 
-      - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c # main
+      - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef # main
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 79e9deea1..79ed53de1 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -18,12 +18,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
diff --git a/.github/workflows/check-readme-in-sync.yml b/.github/workflows/check-readme-in-sync.yml
index 5c940c087..ed5c70208 100644
--- a/.github/workflows/check-readme-in-sync.yml
+++ b/.github/workflows/check-readme-in-sync.yml
@@ -18,7 +18,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
       - name: Check for difference in README.md and docs/README.md
         run: |
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 94ede60ab..a6400a86a 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -32,11 +32,11 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
+        uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
         with:
           config-file: ./.github/codeql/codeql-config.yml
           languages: ${{ matrix.language }}
@@ -48,7 +48,7 @@ jobs:
       # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
       # If this step fails, then you should remove it and run the build manually (see below)
       - name: Autobuild
-        uses: github/codeql-action/autobuild@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
+        uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
 
       # ℹ️ Command-line programs to run using the OS shell.
       # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -62,4 +62,4 @@ jobs:
       #   make release
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
+        uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index 521735e6e..69c435631 100644
--- a/.github/workflows/dependency-review.yml
+++ b/.github/workflows/dependency-review.yml
@@ -15,6 +15,6 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: 'Checkout Repository'
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
       - name: 'Dependency Review'
-        uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
+        uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml
index b1eb70674..9c357a581 100644
--- a/.github/workflows/e2e-applitools.yml
+++ b/.github/workflows/e2e-applitools.yml
@@ -32,13 +32,13 @@ jobs:
         run: |
           echo "::error,title=Not using Applitools::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
 
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
         # uses version from "packageManager" field in package.json
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           node-version-file: '.node-version'
 
@@ -54,7 +54,7 @@ jobs:
           APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
 
       - name: Cypress run
-        uses: cypress-io/github-action@d79d2d530a66e641eb4a5f227e13bc985c60b964 # v4.2.2
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         id: cypress
         with:
           start: pnpm run dev
diff --git a/.github/workflows/e2e-timings.yml b/.github/workflows/e2e-timings.yml
index e3f724d81..b51557b69 100644
--- a/.github/workflows/e2e-timings.yml
+++ b/.github/workflows/e2e-timings.yml
@@ -19,18 +19,18 @@ jobs:
       image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
       options: --user 1001
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           node-version-file: '.node-version'
       - name: Install dependencies
-        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         with:
           runTests: false
       - name: Cypress run
-        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         id: cypress
         with:
           install: false
@@ -51,3 +51,8 @@ jobs:
           author_name: 'github-actions[bot]'
           author_email: '41898282+github-actions[bot]@users.noreply.github.com'
           message: 'chore: update E2E timings'
+      - name: Create Pull Request
+        uses: peter-evans/create-pull-request@v5
+        with:
+          branch: release-promotion
+          title: Update E2E Timings
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index c5bbc6e62..56883b987 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -28,6 +28,8 @@ env:
       ) || 
       github.event.before
     }}
+  RUN_VISUAL_TEST: >-
+    ${{ github.repository == 'mermaid-js/mermaid' && (github.event_name != 'pull_request' || !startsWith(github.head_ref, 'renovate/')) }}
 jobs:
   cache:
     runs-on: ubuntu-latest
@@ -35,30 +37,29 @@ jobs:
       image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
       options: --user 1001
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           node-version-file: '.node-version'
       - name: Cache snapshots
         id: cache-snapshot
-        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
+        uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
         with:
-          save-always: true
           path: ./cypress/snapshots
           key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
 
       # If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
       - name: Switch to base branch
         if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
         with:
           ref: ${{ env.targetHash }}
 
       - name: Install dependencies
         if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
-        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         with:
           # just perform install
           runTests: false
@@ -81,26 +82,26 @@ jobs:
       matrix:
         containers: [1, 2, 3, 4, 5]
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
         # uses version from "packageManager" field in package.json
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           node-version-file: '.node-version'
 
       # These cached snapshots are downloaded, providing the reference snapshots.
       - name: Cache snapshots
         id: cache-snapshot
-        uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
+        uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
         with:
           path: ./cypress/snapshots
           key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
 
       - name: Install dependencies
-        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         with:
           runTests: false
 
@@ -116,7 +117,7 @@ jobs:
       # Install NPM dependencies, cache them correctly
       # and run all Cypress tests
       - name: Cypress run
-        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
+        uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12
         id: cypress
         with:
           install: false
@@ -125,21 +126,20 @@ jobs:
           browser: chrome
           # Disable recording if we don't have an API key
           # e.g. if this action was run from a fork
-          record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
+          record: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY != '' }}
         env:
-          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
-          VITEST_COVERAGE: true
+          ARGOS_PARALLEL: ${{ env.RUN_VISUAL_TEST == 'true' }}
+          ARGOS_PARALLEL_TOTAL: ${{ env.RUN_VISUAL_TEST == 'true' && strategy.job-total || 1 }}
+          ARGOS_PARALLEL_INDEX: ${{ env.RUN_VISUAL_TEST == 'true' && matrix.containers || 1 }}
           CYPRESS_COMMIT: ${{ github.sha }}
-          ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}
-          ARGOS_PARALLEL: true
-          ARGOS_PARALLEL_TOTAL: ${{ strategy.job-total }}
-          ARGOS_PARALLEL_INDEX: ${{ matrix.containers }}
+          CYPRESS_RECORD_KEY: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY || ''}}
           SPLIT: ${{ strategy.job-total }}
           SPLIT_INDEX: ${{ strategy.job-index }}
           SPLIT_FILE: 'cypress/timings.json'
+          VITEST_COVERAGE: true
 
       - name: Upload Coverage to Codecov
-        uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
+        uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
         # Run step only pushes to develop and pull_requests
         if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
         with:
diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml
index 0a2b74dfe..f855ed23b 100644
--- a/.github/workflows/link-checker.yml
+++ b/.github/workflows/link-checker.yml
@@ -29,17 +29,17 @@ jobs:
       # lychee only uses the GITHUB_TOKEN to avoid rate-limiting
       contents: read
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
       - name: Restore lychee cache
-        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
+        uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
         with:
           path: .lycheecache
           key: cache-lychee-${{ github.sha }}
           restore-keys: cache-lychee-
 
       - name: Link Checker
-        uses: lycheeverse/lychee-action@c053181aa0c3d17606addfe97a9075a32723548a # v1.9.3
+        uses: lycheeverse/lychee-action@f613c4a64e50d792e0b31ec34bbcbba12263c6a6 # v2.3.0
         with:
           args: >-
             --config .github/lychee.toml
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 24e7ee35d..50edaa271 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -15,7 +15,7 @@ jobs:
   docker-lint:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
       - uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0
         with:
@@ -23,13 +23,13 @@ jobs:
   lint:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
         # uses version from "packageManager" field in package.json
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index c9faaa062..44860845f 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -22,7 +22,7 @@ jobs:
       pull-requests: write # write permission is required to label PRs
     steps:
       - name: Label PR
-        uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v6.0.0
+        uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
         with:
           config-name: pr-labeler.yml
           disable-autolabeler: false
diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml
index 587ddae08..1a9ccafb6 100644
--- a/.github/workflows/publish-docs.yml
+++ b/.github/workflows/publish-docs.yml
@@ -23,12 +23,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
@@ -37,7 +37,7 @@ jobs:
         run: pnpm install --frozen-lockfile
 
       - name: Setup Pages
-        uses: actions/configure-pages@1f0c5cde4bc74cd7e1254d0cb4de8d49e9068c7d # v4.0.0
+        uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
 
       - name: Run Build
         run: pnpm --filter mermaid run docs:build:vitepress
diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml
index fa48d3659..665222b35 100644
--- a/.github/workflows/release-preview-publish.yml
+++ b/.github/workflows/release-preview-publish.yml
@@ -9,14 +9,14 @@ jobs:
   publish-preview:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
         with:
           fetch-depth: 0
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml
index 7b7dba987..38938dff4 100644
--- a/.github/workflows/release-preview.yml
+++ b/.github/workflows/release-preview.yml
@@ -26,12 +26,12 @@ jobs:
     timeout-minutes: 5
     steps:
       - name: Checkout Repo
-        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4e8e9cd83..649c40034 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,12 +21,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout Repo
-        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
@@ -36,7 +36,7 @@ jobs:
 
       - name: Create Release Pull Request or Publish to npm
         id: changesets
-        uses: changesets/action@3de3850952bec538fde60aac71731376e57b9b57 # v1.4.8
+        uses: changesets/action@c8bada60c408975afd1a20b3db81d6eee6789308 # v1.4.9
         with:
           version: pnpm changeset:version
           publish: pnpm changeset:publish
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 528e94045..4901b3781 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -16,22 +16,22 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout code
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
         with:
           persist-credentials: false
       - name: Run analysis
-        uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
+        uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
         with:
           results_file: results.sarif
           results_format: sarif
           publish_results: true
       - name: Upload artifact
-        uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
+        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
         with:
           name: SARIF file
           path: results.sarif
           retention-days: 5
       - name: Upload to code-scanning
-        uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
+        uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
         with:
           sarif_file: results.sarif
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7323ec027..527ab7401 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,13 +9,13 @@ jobs:
   unit-test:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
         # uses version from "packageManager" field in package.json
 
       - name: Setup Node.js
-        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
+        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
         with:
           cache: pnpm
           node-version-file: '.node-version'
@@ -43,7 +43,7 @@ jobs:
           pnpm test:check:tsc
 
       - name: Upload Coverage to Codecov
-        uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
+        uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
         # Run step only pushes to develop and pull_requests
         if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
         with:
diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml
index 1b26271f7..94de12ad3 100644
--- a/.github/workflows/update-browserlist.yml
+++ b/.github/workflows/update-browserlist.yml
@@ -8,8 +8,8 @@ jobs:
   update-browser-list:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
-      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
       - run: npx update-browserslist-db@latest
       - name: Commit changes
         uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
@@ -19,7 +19,7 @@ jobs:
           message: 'chore: update browsers list'
           push: false
       - name: Create Pull Request
-        uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
+        uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
         with:
           branch: update-browserslist
           title: Update Browserslist
diff --git a/.node-version b/.node-version
index 87834047a..7d41c735d 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-20.12.2
+22.14.0
diff --git a/Dockerfile b/Dockerfile
index 7be53d24e..533604407 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20.12.2-alpine3.19@sha256:7a91aa397f2e2dfbfcdad2e2d72599f374e0b0172be1d86eeb73f1d33f36a4b2
+FROM node:22.12.0-alpine3.19@sha256:40dc4b415c17b85bea9be05314b4a753f45a4e1716bb31c01182e6c53d51a654
 
 USER 0:0
 
diff --git a/README.md b/README.md
index 2345feb8d..2fca46b25 100644
--- a/README.md
+++ b/README.md
@@ -95,6 +95,10 @@ In our release process we rely heavily on visual regression tests using [applito
 
 
 
+## Mermaid AI Bot
+
+[Mermaid](https://codeparrot.ai/oracle?owner=mermaid-js&repo=mermaid) Bot will help you understand this repository better. You can ask for code examples, installation guide, debugging help and much more.
+
 ## Examples
 
 **The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid.js.org/intro/syntax-reference.html).**
@@ -253,6 +257,34 @@ pie
 
 ### Git graph [experimental - live editor]
 
+```
+gitGraph
+  commit
+  commit
+  branch develop
+  checkout develop
+  commit
+  commit
+  checkout main
+  merge develop
+  commit
+  commit
+```
+
+```mermaid
+gitGraph
+  commit
+  commit
+  branch develop
+  checkout develop
+  commit
+  commit
+  checkout main
+  merge develop
+  commit
+  commit
+```
+
 ### Bar chart (using gantt chart) [docs - live editor]
 
 ```
@@ -435,7 +467,7 @@ A quick note from Knut Sveidqvist:
 >
 > _Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
 >
-> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_
+> _Thank you to the ever-growing list of [contributors](https://github.com/mermaid-js/mermaid/graphs/contributors) that brought the project this far!_
 
 ---
 
diff --git a/README.zh-CN.md b/README.zh-CN.md
index fc07bba11..e5b20caed 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -358,7 +358,7 @@ _很不幸的是,鱼与熊掌不可兼得,在这个场景下它意味着在
 
 > _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库!_ > _同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ > _感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
 >
-> _感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!_
+> _感谢越来越多的 [贡献者们](https://github.com/mermaid-js/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!_
 
 ---
 
diff --git a/cypress.config.ts b/cypress.config.ts
index b0257b9b2..d077ba915 100644
--- a/cypress.config.ts
+++ b/cypress.config.ts
@@ -23,12 +23,10 @@ export default eyesPlugin(
         });
         // copy any needed variables from process.env to config.env
         config.env.useAppli = process.env.USE_APPLI ? true : false;
-        config.env.useArgos = !!process.env.CI;
+        config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
 
         if (config.env.useArgos) {
-          registerArgosTask(on, config, {
-            token: 'fc3a35cf5200db928d65b2047861582d9444032b',
-          });
+          registerArgosTask(on, config);
         } else {
           addMatchImageSnapshotPlugin(on, config);
         }
diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts
index 52da4a72e..81b7036af 100644
--- a/cypress/helpers/util.ts
+++ b/cypress/helpers/util.ts
@@ -132,3 +132,10 @@ export const verifyScreenshot = (name: string): void => {
     cy.matchImageSnapshot(name);
   }
 };
+
+export const verifyNumber = (value: number, expected: number, deltaPercent = 10): void => {
+  expect(value).to.be.within(
+    expected * (1 - deltaPercent / 100),
+    expected * (1 + deltaPercent / 100)
+  );
+};
diff --git a/cypress/integration/rendering/architecture.spec.ts b/cypress/integration/rendering/architecture.spec.ts
index bc2276352..25326ff80 100644
--- a/cypress/integration/rendering/architecture.spec.ts
+++ b/cypress/integration/rendering/architecture.spec.ts
@@ -171,6 +171,58 @@ describe.skip('architecture diagram', () => {
             `
     );
   });
+
+  it('should render an architecture diagram with a resonable height', () => {
+    imgSnapshotTest(
+      `architecture-beta
+              group federated(cloud)[Federated Environment]
+                  service server1(server)[System] in federated
+                  service edge(server)[Edge Device] in federated
+                  server1:R -- L:edge
+
+              group on_prem(cloud)[Hub]
+                  service firewall(server)[Firewall Device] in on_prem
+                  service server(server)[Server] in on_prem
+                  firewall:R -- L:server
+
+                  service db1(database)[db1] in on_prem
+                  service db2(database)[db2] in on_prem
+                  service db3(database)[db3] in on_prem
+                  service db4(database)[db4] in on_prem
+                  service db5(database)[db5] in on_prem
+                  service db6(database)[db6] in on_prem
+
+                  junction mid in on_prem
+                  server:B -- T:mid
+
+                  junction 1Leftofmid in on_prem
+                  1Leftofmid:R -- L:mid
+                  1Leftofmid:B -- T:db1
+
+                  junction 2Leftofmid in on_prem
+                  2Leftofmid:R -- L:1Leftofmid
+                  2Leftofmid:B -- T:db2
+
+                  junction 3Leftofmid in on_prem
+                  3Leftofmid:R -- L:2Leftofmid
+                  3Leftofmid:B -- T:db3
+
+                  junction 1RightOfMid in on_prem
+                  mid:R -- L:1RightOfMid
+                  1RightOfMid:B -- T:db4
+                  
+                  junction 2RightOfMid in on_prem
+                  1RightOfMid:R -- L:2RightOfMid
+                  2RightOfMid:B -- T:db5        
+                  
+                  junction 3RightOfMid in on_prem
+                  2RightOfMid:R -- L:3RightOfMid
+                  3RightOfMid:B -- T:db6         
+
+                  edge:R -- L:firewall
+      `
+    );
+  });
 });
 
 // Skipped as the layout is not deterministic, and causes issues in E2E tests.
diff --git a/cypress/integration/rendering/erDiagram-unified.spec.js b/cypress/integration/rendering/erDiagram-unified.spec.js
new file mode 100644
index 000000000..8cecba21d
--- /dev/null
+++ b/cypress/integration/rendering/erDiagram-unified.spec.js
@@ -0,0 +1,652 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
+
+const testOptions = [
+  { description: '', options: { logLevel: 1 } },
+  { description: 'ELK: ', options: { logLevel: 1, layout: 'elk' } },
+  { description: 'HD: ', options: { logLevel: 1, look: 'handDrawn' } },
+];
+
+describe('Entity Relationship Diagram Unified', () => {
+  testOptions.forEach(({ description, options }) => {
+    it(`${description}should render a simple ER diagram`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER ||--o{ ORDER : places
+          ORDER ||--|{ LINE-ITEM : contains
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a simple ER diagram without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER ||--o{ ORDER : places
+          ORDER ||--|{ LINE-ITEM : contains
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render an ER diagram with a recursive relationship`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER ||..o{ CUSTOMER : refers
+          CUSTOMER ||--o{ ORDER : places
+          ORDER ||--|{ LINE-ITEM : contains
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with multiple relationships between the same two entities`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER ||--|{ ADDRESS : "invoiced at"
+          CUSTOMER ||--|{ ADDRESS : "receives goods at"
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a cyclical ER diagram`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          A ||--|{ B : likes
+          B ||--|{ C : likes
+          C ||--|{ A : likes
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a not-so-simple ER diagram`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER }|..|{ DELIVERY-ADDRESS : has
+          CUSTOMER ||--o{ ORDER : places
+          CUSTOMER ||--o{ INVOICE : "liable for"
+          DELIVERY-ADDRESS ||--o{ ORDER : receives
+          INVOICE ||--|{ ORDER : covers
+          ORDER ||--|{ ORDER-ITEM : includes
+          PRODUCT-CATEGORY ||--|{ PRODUCT : contains
+          PRODUCT ||--o{ ORDER-ITEM : "ordered in"
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a not-so-simple ER diagram without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          CUSTOMER }|..|{ DELIVERY-ADDRESS : has
+          CUSTOMER ||--o{ ORDER : places
+          CUSTOMER ||--o{ INVOICE : "liable for"
+          DELIVERY-ADDRESS ||--o{ ORDER : receives
+          INVOICE ||--|{ ORDER : covers
+          ORDER ||--|{ ORDER-ITEM : includes
+          PRODUCT-CATEGORY ||--|{ PRODUCT : contains
+          PRODUCT ||--o{ ORDER-ITEM : "ordered in"
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render multiple ER diagrams`, () => {
+      imgSnapshotTest(
+        [
+          `
+      erDiagram
+          CUSTOMER ||--o{ ORDER : places
+          ORDER ||--|{ LINE-ITEM : contains
+        `,
+          `
+      erDiagram
+          CUSTOMER ||--o{ ORDER : places
+          ORDER ||--|{ LINE-ITEM : contains
+        `,
+        ],
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with blank or empty labels`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          BOOK }|..|{ AUTHOR : ""
+          BOOK }|..|{ GENRE : " "
+          AUTHOR }|..|{ GENRE : "  "
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities that have no relationships`, () => {
+      renderGraph(
+        `
+      erDiagram
+          DEAD_PARROT
+          HERMIT
+          RECLUSE
+          SOCIALITE }o--o{ SOCIALITE : "interacts with"
+          RECLUSE }o--o{ SOCIALITE : avoids
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with and without attributes`, () => {
+      renderGraph(
+        `
+      erDiagram
+          BOOK { string title }
+          AUTHOR }|..|{ BOOK : writes
+          BOOK { float price }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with generic and array attributes`, () => {
+      renderGraph(
+        `
+      erDiagram
+          BOOK {
+            string title
+            string[] authors
+            type~T~ type
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with generic and array attributes without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+          BOOK {
+            string title
+            string[] authors
+            type~T~ type
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with length in attributes type`, () => {
+      renderGraph(
+        `
+      erDiagram
+          CLUSTER {
+            varchar(99) name
+            string(255) description
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with length in attributes type without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+          CLUSTER {
+            varchar(99) name
+            string(255) description
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities and attributes with big and small entity names`, () => {
+      renderGraph(
+        `
+      erDiagram
+          PRIVATE_FINANCIAL_INSTITUTION {
+            string name
+            int    turnover
+          }
+          PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
+          EMPLOYEE { bool officer_of_firm }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities and attributes with big and small entity names without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+          PRIVATE_FINANCIAL_INSTITUTION {
+            string name
+            int    turnover
+          }
+          PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
+          EMPLOYEE { bool officer_of_firm }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with attributes that begin with asterisk`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          BOOK {
+            int         *id
+            string      name
+            varchar(99) summary
+          }
+          BOOK }o..o{ STORE : soldBy
+          STORE {
+            int         *id
+            string      name
+            varchar(50) address
+          }
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with attributes that begin with asterisk without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          BOOK {
+            int         *id
+            string      name
+            varchar(99) summary
+          }
+          BOOK }o..o{ STORE : soldBy
+          STORE {
+            int         *id
+            string      name
+            varchar(50) address
+          }
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with keys`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name PK
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            float price
+            string author FK
+            string title PK
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with keys without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name PK
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            float price
+            string author FK
+            string title PK
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with comments`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name "comment"
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            string author
+            string title "author comment"
+            float price "price comment"
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with comments without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name "comment"
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            string author
+            string title "author comment"
+            float price "price comment"
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with keys and comments`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name PK "comment"
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            string description
+            float price "price comment"
+            string title PK "title comment"
+            string author FK
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with keys and comments without htmlLabels`, () => {
+      renderGraph(
+        `
+      erDiagram
+        AUTHOR_WITH_LONG_ENTITY_NAME {
+          string name PK "comment"
+        }
+        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
+        BOOK {
+            string description
+            float price "price comment"
+            string title PK "title comment"
+            string author FK
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with aliases`, () => {
+      renderGraph(
+        `
+      erDiagram
+        T1 one or zero to one or more T2 : test
+        T2 one or many optionally to zero or one T3 : test
+        T3 zero or more to zero or many T4 : test
+        T4 many(0) to many(1) T5 : test
+        T5 many optionally to one T6 : test
+        T6 only one optionally to only one T1 : test
+        T4 0+ to 1+ T6 : test
+        T1 1 to 1 T3 : test
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a simple ER diagram with a title`, () => {
+      imgSnapshotTest(
+        `---
+  title: simple ER diagram
+  ---
+  erDiagram
+  CUSTOMER ||--o{ ORDER : places
+  ORDER ||--|{ LINE-ITEM : contains
+  `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with entity name aliases`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+        p[Person] {
+          varchar(64) firstName
+          varchar(64) lastName
+        }
+        c["Customer Account"] {
+          varchar(128) email
+        }
+        p ||--o| c : has
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render relationship labels with line breaks`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+        p[Person] {
+            string firstName
+            string lastName
+        }
+        a["Customer Account"] {
+            string email
+        }
+  
+        b["Customer Account Secondary"] {
+          string email
+        }
+        
+        c["Customer Account Tertiary"] {
+          string email
+        }
+        
+        d["Customer Account Nth"] {
+          string email
+        }
+  
+        p ||--o| a : "has
one"
+        p ||--o| b : "has
one
two"
+        p ||--o| c : "has
one
two
three"
+        p ||--o| d : "has
one
two
three
...
Nth"
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with unicode text`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          _**testẽζ➕Ø😀㌕ぼ**_ {
+              *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
+              *string(99)~T~~~~~~* firstName "Only __99__ 
characters are a
llowed dsfsdfsdfsdfs"
+              string last*Name*
+              string __phone__ UK
+              int _age_
+          }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with unicode text without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+      erDiagram
+          _**testẽζ➕Ø😀㌕ぼ**_ {
+              *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
+              *string(99)~T~~~~~~* firstName "Only __99__ 
characters are a
llowed dsfsdfsdfsdfs"
+              string last*Name*
+              string __phone__ UK
+              int _age_
+          }
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render an ER diagram with relationships with unicode text`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+            person[😀] {
+                string *first*Name
+                string _**last**Name_
+            }
+            a["*Customer Account*"] {
+                **string** ema*i*l
+            }
+            person ||--o| a : __hẽ😀__
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with relationships with unicode text without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+            person[😀] {
+                string *first*Name
+                string _**last**Name_
+            }
+            a["*Customer Account*"] {
+                **string** ema*i*l
+            }
+            person ||--o| a : __hẽ😀__
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render an ER diagram with TB direction`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+          direction TB
+          CAR ||--|{ NAMED-DRIVER : allows
+          PERSON ||..o{ NAMED-DRIVER : is
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with BT direction`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+          direction BT
+          CAR ||--|{ NAMED-DRIVER : allows
+          PERSON ||..o{ NAMED-DRIVER : is
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with LR direction`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+          direction LR
+          CAR ||--|{ NAMED-DRIVER : allows
+          PERSON ||..o{ NAMED-DRIVER : is
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render an ER diagram with RL direction`, () => {
+      imgSnapshotTest(
+        `
+          erDiagram
+          direction RL
+          CAR ||--|{ NAMED-DRIVER : allows
+          PERSON ||..o{ NAMED-DRIVER : is
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with styles applied from style statement`, () => {
+      imgSnapshotTest(
+        `
+            erDiagram
+              c[CUSTOMER]
+              p[PERSON]
+              style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with styles applied from style statement without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+            erDiagram
+              c[CUSTOMER]
+              p[PERSON]
+              style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with styles applied from class statement`, () => {
+      imgSnapshotTest(
+        `
+            erDiagram
+              c[CUSTOMER]
+              p[PERSON]:::blue
+              classDef bold font-size:24px, font-weight: bold
+              classDef blue stroke:lightblue, color: #0000FF
+              class c,p bold
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render entities with styles applied from class statement without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+            erDiagram
+              c[CUSTOMER]
+              p[PERSON]:::blue
+              classDef bold font-size:24px, font-weight: bold
+              classDef blue stroke:lightblue, color: #0000FF
+              class c,p bold
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render entities with styles applied from the default class and other styles`, () => {
+      imgSnapshotTest(
+        `
+            erDiagram
+              c[CUSTOMER]
+              p[PERSON]:::blue
+              classDef blue stroke:lightblue, color: #0000FF
+              classDef default fill:pink
+              style c color:green
+        `,
+        { ...options }
+      );
+    });
+  });
+});
diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js
index aad9b1cf7..cbfec8218 100644
--- a/cypress/integration/rendering/erDiagram.spec.js
+++ b/cypress/integration/rendering/erDiagram.spec.js
@@ -109,8 +109,8 @@ describe('Entity Relationship Diagram', () => {
       const style = svg.attr('style');
       expect(style).to.match(/^max-width: [\d.]+px;$/);
       const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
-      // use within because the absolute value can be slightly different depending on the environment ±5%
-      expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
+      // use within because the absolute value can be slightly different depending on the environment ±6%
+      expect(maxWidthValue).to.be.within(140 * 0.96, 140 * 1.06);
     });
   });
 
@@ -125,8 +125,8 @@ describe('Entity Relationship Diagram', () => {
     );
     cy.get('svg').should((svg) => {
       const width = parseFloat(svg.attr('width'));
-      // use within because the absolute value can be slightly different depending on the environment ±5%
-      expect(width).to.be.within(140 * 0.95, 140 * 1.05);
+      // use within because the absolute value can be slightly different depending on the environment ±6%
+      expect(width).to.be.within(140 * 0.96, 140 * 1.06);
       // expect(svg).to.have.attr('height', '465');
       expect(svg).to.not.have.attr('style');
     });
diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js
index 38bfe6440..c31df1181 100644
--- a/cypress/integration/rendering/flowchart-elk.spec.js
+++ b/cypress/integration/rendering/flowchart-elk.spec.js
@@ -1,4 +1,4 @@
-import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
+import { imgSnapshotTest, renderGraph, verifyNumber } from '../../helpers/util.ts';
 
 describe('Flowchart ELK', () => {
   it('1-elk: should render a simple flowchart', () => {
@@ -109,7 +109,7 @@ describe('Flowchart ELK', () => {
       const style = svg.attr('style');
       expect(style).to.match(/^max-width: [\d.]+px;$/);
       const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
-      expect(maxWidthValue).to.be.within(230 * 0.95, 230 * 1.05);
+      verifyNumber(maxWidthValue, 380);
     });
   });
   it('8-elk: should render a flowchart when useMaxWidth is false', () => {
@@ -128,7 +128,7 @@ describe('Flowchart ELK', () => {
       const width = parseFloat(svg.attr('width'));
       // use within because the absolute value can be slightly different depending on the environment ±5%
       // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
-      expect(width).to.be.within(230 * 0.95, 230 * 1.05);
+      verifyNumber(width, 380);
       expect(svg).to.not.have.attr('style');
     });
   });
@@ -692,7 +692,7 @@ A --> B
       {}
     );
     cy.get('svg').should((svg) => {
-      const edges = svg.querySelectorAll('.edges > path');
+      const edges = svg[0].querySelectorAll('.edges > path');
       edges.forEach((edge) => {
         expect(edge).to.have.class('flowchart-link');
       });
@@ -739,7 +739,7 @@ NL\`") --"\`1o **bold**\`"--> c
           { flowchart: { titleTopMargin: 0 } }
         );
       });
-      it('Wrapping long text with a new line', () => {
+      it.skip('Wrapping long text with a new line', () => {
         imgSnapshotTest(
           `%%{init: {"flowchart": {"htmlLabels": true}} }%%
 flowchart-elk LR
@@ -841,7 +841,7 @@ end
           { flowchart: { titleTopMargin: 0 } }
         );
       });
-      it('Sub graphs and markdown strings', () => {
+      it('Sub graphs', () => {
         imgSnapshotTest(
           `---
 config:
diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js
index 66452f4b2..4322500df 100644
--- a/cypress/integration/rendering/flowchart-v2.spec.js
+++ b/cypress/integration/rendering/flowchart-v2.spec.js
@@ -1076,4 +1076,41 @@ end
       );
     });
   });
+  describe('New @ sytax for node metadata edge cases', () => {
+    it('should be possible to use @  syntax to add labels on multi nodes', () => {
+      imgSnapshotTest(
+        `flowchart TB
+       n2["label for n2"] &   n4@{ label: "labe for n4"}   & n5@{ label: "labe for n5"}
+        `,
+        {}
+      );
+    });
+    it('should be possible to use @  syntax to add labels with trail spaces and &', () => {
+      imgSnapshotTest(
+        `flowchart TB
+       n2["label for n2"] &   n4@{ label: "labe for n4"}   & n5@{ label: "labe for n5"}   
+        `,
+        {}
+      );
+    });
+    it('should be possible to use @  syntax to add labels with trail spaces', () => {
+      imgSnapshotTest(
+        `flowchart TB
+       n2["label for n2"]
+       n4@{ label: "labe for n4"}
+       n5@{ label: "labe for n5"}  
+        `,
+        {}
+      );
+    });
+    it('should be possible to use @  syntax to add labels with trail spaces and edge/link', () => {
+      imgSnapshotTest(
+        `flowchart TD
+    A["A"] --> B["for B"] &    C@{ label: "for c"} & E@{label : "for E"}  
+    D@{label: "for D"}     
+        `,
+        {}
+      );
+    });
+  });
 });
diff --git a/cypress/integration/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js
index d3a83ae5f..7b986cd2f 100644
--- a/cypress/integration/rendering/flowchart.spec.js
+++ b/cypress/integration/rendering/flowchart.spec.js
@@ -895,7 +895,7 @@ graph TD
     imgSnapshotTest(
       `
       graph TD
-        classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff 
+        classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff
         hello --> default
       `,
       { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
@@ -917,4 +917,21 @@ graph TD
       }
     );
   });
+  it('#6369: edge color should affect arrow head', () => {
+    imgSnapshotTest(
+      `
+    flowchart LR
+        A --> B
+        A --> C
+        C --> D
+
+        linkStyle 0 stroke:#D50000
+        linkStyle 2 stroke:#D50000
+    `,
+      {
+        flowchart: { htmlLabels: true },
+        securityLevel: 'loose',
+      }
+    );
+  });
 });
diff --git a/cypress/integration/rendering/requirementDiagram-unified.spec.js b/cypress/integration/rendering/requirementDiagram-unified.spec.js
new file mode 100644
index 000000000..48b1a0d61
--- /dev/null
+++ b/cypress/integration/rendering/requirementDiagram-unified.spec.js
@@ -0,0 +1,703 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
+
+const testOptions = [
+  { description: '', options: { logLevel: 1 } },
+  { description: 'ELK: ', options: { logLevel: 1, layout: 'elk' } },
+  { description: 'HD: ', options: { logLevel: 1, look: 'handDrawn' } },
+];
+
+describe('Requirement Diagram Unified', () => {
+  testOptions.forEach(({ description, options }) => {
+    it(`${description}should render a simple Requirement diagram`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+        requirement test_req {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+
+        element test_entity {
+        type: simulation
+        }
+
+        test_entity - satisfies -> test_req
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a simple Requirement diagram without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+        requirement test_req {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+
+        element test_entity {
+        type: simulation
+        }
+
+        test_entity - satisfies -> test_req
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render a not-so-simple Requirement diagram`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+
+        requirement test_req {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+
+        functionalRequirement test_req2 {
+        id: 1.1
+        text: the second test text.
+        risk: low
+        verifymethod: inspection
+        }
+
+        performanceRequirement test_req3 {
+        id: 1.2
+        text: the third test text.
+        risk: medium
+        verifymethod: demonstration
+        }
+
+        interfaceRequirement test_req4 {
+        id: 1.2.1
+        text: the fourth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        physicalRequirement test_req5 {
+        id: 1.2.2
+        text: the fifth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        designConstraint test_req6 {
+        id: 1.2.3
+        text: the sixth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        element test_entity {
+        type: simulation
+        }
+
+        element test_entity2 {
+        type: word doc
+        docRef: reqs/test_entity
+        }
+
+        element test_entity3 {
+        type: "test suite"
+        docRef: github.com/all_the_tests
+        }
+
+
+        test_entity - satisfies -> test_req2
+        test_req - traces -> test_req2
+        test_req - contains -> test_req3
+        test_req3 - contains -> test_req4
+        test_req4 - derives -> test_req5
+        test_req5 - refines -> test_req6
+        test_entity3 - verifies -> test_req5
+        test_req <- copies - test_entity2
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a not-so-simple Requirement diagram without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+
+        requirement test_req {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+
+        functionalRequirement test_req2 {
+        id: 1.1
+        text: the second test text.
+        risk: low
+        verifymethod: inspection
+        }
+
+        performanceRequirement test_req3 {
+        id: 1.2
+        text: the third test text.
+        risk: medium
+        verifymethod: demonstration
+        }
+
+        interfaceRequirement test_req4 {
+        id: 1.2.1
+        text: the fourth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        physicalRequirement test_req5 {
+        id: 1.2.2
+        text: the fifth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        designConstraint test_req6 {
+        id: 1.2.3
+        text: the sixth test text.
+        risk: medium
+        verifymethod: analysis
+        }
+
+        element test_entity {
+        type: simulation
+        }
+
+        element test_entity2 {
+        type: word doc
+        docRef: reqs/test_entity
+        }
+
+        element test_entity3 {
+        type: "test suite"
+        docRef: github.com/all_the_tests
+        }
+
+
+        test_entity - satisfies -> test_req2
+        test_req - traces -> test_req2
+        test_req - contains -> test_req3
+        test_req3 - contains -> test_req4
+        test_req4 - derives -> test_req5
+        test_req5 - refines -> test_req6
+        test_entity3 - verifies -> test_req5
+        test_req <- copies - test_entity2
+        `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render multiple Requirement diagrams`, () => {
+      imgSnapshotTest(
+        [
+          `
+    requirementDiagram
+
+    requirement test_req {
+    id: 1
+    text: the test text.
+    risk: high
+    verifymethod: test
+    }
+
+    element test_entity {
+    type: simulation
+    }
+
+    test_entity - satisfies -> test_req
+    `,
+          `
+    requirementDiagram
+
+    requirement test_req {
+    id: 1
+    text: the test text.
+    risk: high
+    verifymethod: test
+    }
+
+    element test_entity {
+    type: simulation
+    }
+
+    test_entity - satisfies -> test_req
+    `,
+        ],
+        options
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with empty information`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+        requirement test_req {
+        }
+        element test_entity {
+        }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with and without information`, () => {
+      renderGraph(
+        `
+    requirementDiagram
+        requirement test_req {
+            id: 1
+            text: the test text.
+            risk: high
+            verifymethod: test
+        }
+        element test_entity {
+        }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with long and short text`, () => {
+      renderGraph(
+        `
+    requirementDiagram
+        requirement test_req {
+            id: 1
+            text: the test text that is long and takes up a lot of space.
+            risk: high
+            verifymethod: test
+        }
+        element test_entity_name_that_is_extra_long {
+        }
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with long and short text without htmlLabels`, () => {
+      renderGraph(
+        `
+      requirementDiagram
+          requirement test_req {
+              id: 1
+              text: the test text that is long and takes up a lot of space.
+              risk: high
+              verifymethod: test
+          }
+          element test_entity_name_that_is_extra_long {
+          }
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render requirements and elements with quoted text for spaces`, () => {
+      renderGraph(
+        `
+      requirementDiagram
+          requirement "test req name with spaces" {
+              id: 1
+              text: the test text that is long and takes up a lot of space.
+              risk: high
+              verifymethod: test
+          }
+          element "test entity name that is extra long with spaces" {
+          }
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with markdown text`, () => {
+      renderGraph(
+        `
+      requirementDiagram
+          requirement "__my bolded name__" {
+              id: 1
+              text: "**Bolded text** _italicized text_"
+              risk: high
+              verifymethod: test
+          }
+          element "*my italicized name*" {
+            type: "**Bolded type** _italicized type_"
+            docref: "*Italicized* __Bolded__"
+          }
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with markdown text without htmlLabels`, () => {
+      renderGraph(
+        `
+      requirementDiagram
+          requirement "__my bolded name__" {
+              id: 1
+              text: "**Bolded text** _italicized text_"
+              risk: high
+              verifymethod: test
+          }
+          element "*my italicized name*" {
+            type: "**Bolded type** _italicized type_"
+            docref: "*Italicized* __Bolded__"
+          }
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render a simple Requirement diagram with a title`, () => {
+      imgSnapshotTest(
+        `---
+  title: simple Requirement diagram
+  ---
+    requirementDiagram
+
+    requirement test_req {
+    id: 1
+    text: the test text.
+    risk: high
+    verifymethod: test
+    }
+
+    element test_entity {
+    type: simulation
+    }
+
+    test_entity - satisfies -> test_req
+  `,
+        options
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with TB direction`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+    direction TB
+
+    requirement test_req {
+    id: 1
+    text: the test text.
+    risk: high
+    verifymethod: test
+    }
+
+    element test_entity {
+    type: simulation
+    }
+
+    test_entity - satisfies -> test_req
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with BT direction`, () => {
+      imgSnapshotTest(
+        `
+      requirementDiagram
+      direction BT
+  
+      requirement test_req {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with LR direction`, () => {
+      imgSnapshotTest(
+        `
+      requirementDiagram
+      direction LR
+  
+      requirement test_req {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with RL direction`, () => {
+      imgSnapshotTest(
+        `
+      requirementDiagram
+      direction RL
+  
+      requirement test_req {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from style statement`, () => {
+      imgSnapshotTest(
+        `
+    requirementDiagram
+
+    requirement test_req {
+    id: 1
+    text: the test text.
+    risk: high
+    verifymethod: test
+    }
+
+    element test_entity {
+    type: simulation
+    }
+
+    test_entity - satisfies -> test_req
+
+    style test_req,test_entity fill:#f9f,stroke:blue, color:grey, font-weight:bold
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from style statement without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+      requirementDiagram
+  
+      requirement test_req {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+  
+      style test_req,test_entity fill:#f9f,stroke:blue, color:grey, font-weight:bold
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from class statement`, () => {
+      imgSnapshotTest(
+        `
+requirementDiagram
+  
+      requirement test_req {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+      classDef bold font-weight: bold
+      classDef blue stroke:lightblue, color: #0000FF
+      class test_entity bold
+      class test_req blue, bold
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from class statement without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+  requirementDiagram
+    
+        requirement test_req {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+    
+        element test_entity {
+        type: simulation
+        }
+    
+        test_entity - satisfies -> test_req
+        classDef bold font-weight: bold
+        classDef blue stroke:lightblue, color: #0000FF
+        class test_entity bold
+        class test_req blue, bold
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from classes with shorthand syntax`, () => {
+      imgSnapshotTest(
+        `
+  requirementDiagram
+    
+        requirement test_req:::blue {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+    
+        element test_entity {
+        type: simulation
+        }
+    
+        test_entity - satisfies -> test_req
+        classDef bold font-weight: bold
+        classDef blue stroke:lightblue, color: #0000FF
+        test_entity:::bold
+          `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from classes with shorthand syntax without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+  requirementDiagram
+    
+        requirement test_req:::blue {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+    
+        element test_entity {
+        type: simulation
+        }
+    
+        test_entity - satisfies -> test_req
+        classDef bold font-weight: bold
+        classDef blue stroke:lightblue, color: #0000FF
+        test_entity:::bold
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from the default class and other styles`, () => {
+      imgSnapshotTest(
+        `
+requirementDiagram
+  
+      requirement test_req:::blue {
+      id: 1
+      text: the test text.
+      risk: high
+      verifymethod: test
+      }
+  
+      element test_entity {
+      type: simulation
+      }
+  
+      test_entity - satisfies -> test_req
+      classDef blue stroke:lightblue, color:blue
+      classDef default fill:pink
+      style test_entity color:green
+        `,
+        options
+      );
+    });
+
+    it(`${description}should render requirements and elements with styles applied from the default class and other styles without htmlLabels`, () => {
+      imgSnapshotTest(
+        `
+  requirementDiagram
+    
+        requirement test_req:::blue {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+    
+        element test_entity {
+        type: simulation
+        }
+    
+        test_entity - satisfies -> test_req
+        classDef blue stroke:lightblue, color:blue
+        classDef default fill:pink
+        style test_entity color:green
+          `,
+        { ...options, htmlLabels: false }
+      );
+    });
+
+    it(`${description}should render a Requirement diagram with a theme`, () => {
+      imgSnapshotTest(
+        `
+---
+  theme: forest
+---
+  requirementDiagram
+    
+        requirement test_req:::blue {
+        id: 1
+        text: the test text.
+        risk: high
+        verifymethod: test
+        }
+    
+        element test_entity {
+        type: simulation
+        }
+    
+        test_entity - satisfies -> test_req
+          `,
+        options
+      );
+    });
+  });
+});
diff --git a/cypress/platform/ashish2.html b/cypress/platform/ashish2.html
index f9132d2e2..351dcabc2 100644
--- a/cypress/platform/ashish2.html
+++ b/cypress/platform/ashish2.html
@@ -4,7 +4,7 @@
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
   
 
   
----
-config:
-  layout: elk
----
       flowchart LR
-      subgraph S2
-      subgraph s1["APA"]
-      D{"Use the editor"}
-      end
-
-
-      D -- Mermaid js --> I{"fa:fa-code Text"}
-            D --> I
-            D --> I
-
-      end
+        AB["apa@apa@"] --> B(("`apa@apa`"))
     
     
+      flowchart
+        D(("for D"))
+    
+    
+      flowchart LR
+        A e1@==> B
+        e1@{ animate: true}
+    
+    +flowchart LR + A e1@--> B + classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round + class e1 animate ++
+flowchart LR + A e1@--> B + classDef animate stroke-dasharray: 9\,5,stroke-dashoffset: 900,animation: dash 25s linear infinite; + class e1 animate ++
+flowchart LR
+  A e1@--> B
+e1@{ animation: fast}
+    
+    +flowchart LR + A e1@--> B + classDef animate stroke-dasharray: 1000,stroke-dashoffset: 1000,animation: dash 10s linear; + class e1 edge-animation-fast ++ +
+ +info+
 ---
 config:
   layout: elk
@@ -131,7 +174,7 @@ config:
       end
       end
     
-    +--- config: layout: elk @@ -144,7 +187,7 @@ config: D-->I D-->I-+--- config: layout: elk @@ -183,7 +226,7 @@ flowchart LR n8@{ shape: rect}-+--- config: layout: elk @@ -199,7 +242,7 @@ flowchart LR-+--- config: layout: elk @@ -208,7 +251,7 @@ flowchart LR A{A} --> B & C-+--- config: layout: elk @@ -220,7 +263,7 @@ flowchart LR end-+--- config: layout: elk @@ -391,7 +434,10 @@ kanban window.callback = function () { alert('A callback was triggered'); }; - mermaid.initialize({ + function callback() { + alert('It worked'); + } + await mermaid.initialize({ // theme: 'base', // theme: 'default', // theme: 'forest', @@ -403,9 +449,11 @@ kanban // layout: 'fixed', // htmlLabels: false, flowchart: { titleTopMargin: 10 }, + // fontFamily: 'Caveat', // fontFamily: 'Kalam', // fontFamily: 'courier', + fontFamily: 'arial', sequence: { actorFontFamily: 'courier', noteFontFamily: 'courier', @@ -417,10 +465,9 @@ kanban fontSize: 12, logLevel: 0, securityLevel: 'loose', + callback, }); - function callback() { - alert('It worked'); - } + mermaid.parseError = function (err, hash) { console.error('In parse error:'); console.error(err); diff --git a/cypress/platform/per.html b/cypress/platform/per.html index e84cea2d0..6d3d198b6 100644 --- a/cypress/platform/per.html +++ b/cypress/platform/per.html @@ -4,7 +4,7 @@- flowchart LR - A@{ icon: "fa:window-minimize", form: circle } - E@{ icon: "fa:window-minimize", form: circle } - B@{ icon: "fa:bell", form: circle } - B2@{ icon: "fa:bell", form: circle } - C@{ icon: "fa:address-book", form: square } - D@{ icon: "fa:star-half", form: square } - A --> E - B --> B2 - + flowchart + A --> A + subgraph B + B1 --> B1 + end + subgraph C + subgraph C1 + C2 --> C2 + subgraph D + D1 --> D1 + end + D --> D + end + C1 --> C1 + end-- flowchart TB - A --test2--> B2@{ icon: "fa:bell", form: "rounded", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" } - B2 --test--> C - D --> B2 --> E - style B2 fill:#f9f,stroke:#333,stroke-width:4px --- flowchart BT - A --test2--> B2@{ icon: "fa:bell", form: "square", label: "B2", pos: "t", h: 40, w: 30 } - B2 --test--> C - D --> B2 --> E --- flowchart BT - A --test2--> B2@{ icon: "fa:bell", label: "B2 awiugdawu uydgayuiwd wuydguy", pos: "b", h: 40, w: 30 } - B2 --test--> C --- flowchart BT - A --test2--> B2@{ icon: "fa:bell", label: "B2 dawuygd ayuwgd uy", pos: "t", h: 40, w: 30 } - B2 --test--> C --- flowchart TB - A --> B2@{ icon: "fa:bell", form: "circle", label: "test augfuyfavf ydvaubfuac", pos: "t", w: 200, h: 100 } --> C --- flowchart TB - A --> B2@{ icon: "fa:bell", form: "circle", label: "test augfuyfavf ydvaubfuac", pos: "b", w: 200, h: 100 } --> C - D --> B2 --> E -+ + +