diff --git a/.esbuild/serve.cjs b/.esbuild/serve.cjs
deleted file mode 100644
index c54ff1e9f1..0000000000
--- a/.esbuild/serve.cjs
+++ /dev/null
@@ -1,53 +0,0 @@
-const esbuild = require('esbuild');
-const http = require('http');
-const path = require('path');
-const { iifeBuild } = require('./util.cjs');
-
-// Start esbuild's server on a random local port
-esbuild
- .serve(
- {
- servedir: path.join(__dirname, '..'),
- },
- iifeBuild({ minify: false })
- )
- .then((result) => {
- // The result tells us where esbuild's local server is
- const { host, port } = result;
-
- // Then start a proxy server on port 3000
- http
- .createServer((req, res) => {
- if (req.url.includes('mermaid.js')) {
- req.url = '/dist/mermaid.js';
- }
- const options = {
- hostname: host,
- port: port,
- path: req.url,
- method: req.method,
- headers: req.headers,
- };
-
- // Forward each incoming request to esbuild
- const proxyReq = http.request(options, (proxyRes) => {
- // If esbuild returns "not found", send a custom 404 page
- console.error('pp', req.url);
- if (proxyRes.statusCode === 404) {
- if (!req.url.endsWith('.html')) {
- res.writeHead(404, { 'Content-Type': 'text/html' });
- res.end('
A custom 404 page
');
- return;
- }
- }
-
- // Otherwise, forward the response from esbuild to the client
- res.writeHead(proxyRes.statusCode, proxyRes.headers);
- proxyRes.pipe(res, { end: true });
- });
-
- // Forward the body of the request to esbuild
- req.pipe(proxyReq, { end: true });
- })
- .listen(3000);
- });
diff --git a/.eslintignore b/.eslintignore
index 60c278861f..04348c4108 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,3 +3,5 @@ dist/**
docs/Setup.md
cypress.config.js
cypress/plugins/index.js
+coverage
+*.json
\ No newline at end of file
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000000..e6f99a8bf9
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,150 @@
+module.exports = {
+ env: {
+ browser: true,
+ es6: true,
+ 'jest/globals': true,
+ node: true,
+ },
+ root: true,
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ ecmaFeatures: {
+ experimentalObjectRestSpread: true,
+ jsx: true,
+ },
+ tsconfigRootDir: __dirname,
+ sourceType: 'module',
+ ecmaVersion: 2020,
+ allowAutomaticSingleRunInference: true,
+ project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
+ parser: '@typescript-eslint/parser',
+ },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:json/recommended',
+ 'plugin:markdown/recommended',
+ 'plugin:@cspell/recommended',
+ 'prettier',
+ ],
+ plugins: [
+ '@typescript-eslint',
+ 'no-only-tests',
+ 'html',
+ 'jest',
+ 'jsdoc',
+ 'json',
+ '@cspell',
+ 'lodash',
+ 'unicorn',
+ ],
+ rules: {
+ curly: 'error',
+ 'no-console': 'error',
+ 'no-prototype-builtins': 'off',
+ 'no-unused-vars': 'off',
+ 'cypress/no-async-tests': 'off',
+ '@typescript-eslint/no-floating-promises': 'error',
+ '@typescript-eslint/no-misused-promises': 'error',
+ '@typescript-eslint/ban-ts-comment': [
+ 'error',
+ {
+ 'ts-expect-error': 'allow-with-description',
+ 'ts-ignore': 'allow-with-description',
+ 'ts-nocheck': 'allow-with-description',
+ 'ts-check': 'allow-with-description',
+ minimumDescriptionLength: 10,
+ },
+ ],
+ 'json/*': ['error', 'allowComments'],
+ '@cspell/spellchecker': [
+ 'error',
+ {
+ checkIdentifiers: false,
+ checkStrings: false,
+ checkStringTemplates: false,
+ },
+ ],
+ 'no-empty': [
+ 'error',
+ {
+ allowEmptyCatch: true,
+ },
+ ],
+ 'no-only-tests/no-only-tests': 'error',
+ 'lodash/import-scope': ['error', 'method'],
+ 'unicorn/better-regex': 'error',
+ 'unicorn/no-abusive-eslint-disable': 'error',
+ 'unicorn/no-array-push-push': 'error',
+ 'unicorn/no-for-loop': 'error',
+ 'unicorn/no-instanceof-array': 'error',
+ 'unicorn/no-typeof-undefined': 'error',
+ 'unicorn/no-unnecessary-await': 'error',
+ 'unicorn/no-unsafe-regex': 'warn',
+ 'unicorn/no-useless-promise-resolve-reject': 'error',
+ 'unicorn/prefer-array-find': 'error',
+ 'unicorn/prefer-array-flat-map': 'error',
+ 'unicorn/prefer-array-index-of': 'error',
+ 'unicorn/prefer-array-some': 'error',
+ 'unicorn/prefer-default-parameters': 'error',
+ 'unicorn/prefer-includes': 'error',
+ 'unicorn/prefer-negative-index': 'error',
+ 'unicorn/prefer-object-from-entries': 'error',
+ 'unicorn/prefer-string-starts-ends-with': 'error',
+ 'unicorn/prefer-string-trim-start-end': 'error',
+ 'unicorn/string-content': 'error',
+ 'unicorn/prefer-spread': 'error',
+ 'unicorn/no-lonely-if': 'error',
+ },
+ overrides: [
+ {
+ files: ['cypress/**', 'demos/**'],
+ rules: {
+ 'no-console': 'off',
+ },
+ },
+ {
+ files: ['*.{js,jsx,mjs,cjs}'],
+ extends: ['plugin:jsdoc/recommended'],
+ rules: {
+ 'jsdoc/check-indentation': 'off',
+ 'jsdoc/check-alignment': 'off',
+ 'jsdoc/check-line-alignment': 'off',
+ 'jsdoc/multiline-blocks': 'off',
+ 'jsdoc/newline-after-description': 'off',
+ 'jsdoc/tag-lines': 'off',
+ 'jsdoc/require-param-description': 'off',
+ 'jsdoc/require-param-type': 'off',
+ 'jsdoc/require-returns': 'off',
+ 'jsdoc/require-returns-description': 'off',
+ },
+ },
+ {
+ files: ['*.{ts,tsx}'],
+ plugins: ['tsdoc'],
+ rules: {
+ 'tsdoc/syntax': 'error',
+ },
+ },
+ {
+ files: ['*.spec.{ts,js}', 'cypress/**', 'demos/**', '**/docs/**'],
+ rules: {
+ 'jsdoc/require-jsdoc': 'off',
+ '@typescript-eslint/no-unused-vars': 'off',
+ },
+ },
+ {
+ files: ['*.html', '*.md', '**/*.md/*'],
+ rules: {
+ 'no-var': 'error',
+ 'no-undef': 'off',
+ '@typescript-eslint/no-unused-vars': 'off',
+ '@typescript-eslint/no-floating-promises': 'off',
+ '@typescript-eslint/no-misused-promises': 'off',
+ },
+ parserOptions: {
+ project: null,
+ },
+ },
+ ],
+};
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 02753280c9..0000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "env": {
- "browser": true,
- "es6": true,
- "jest/globals": true,
- "node": true
- },
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "ecmaFeatures": {
- "experimentalObjectRestSpread": true,
- "jsx": true
- },
- "sourceType": "module"
- },
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/recommended",
- "plugin:jsdoc/recommended",
- "plugin:json/recommended",
- "plugin:markdown/recommended",
- "prettier"
- ],
- "plugins": ["@typescript-eslint", "html", "jest", "jsdoc", "json"],
- "rules": {
- "no-console": "error",
- "no-prototype-builtins": "off",
- "no-unused-vars": "off",
- "jsdoc/check-indentation": "off",
- "jsdoc/check-alignment": "off",
- "jsdoc/check-line-alignment": "off",
- "jsdoc/multiline-blocks": "off",
- "jsdoc/newline-after-description": "off",
- "jsdoc/tag-lines": "off",
- "jsdoc/require-param-description": "off",
- "jsdoc/require-param-type": "off",
- "jsdoc/require-returns": "off",
- "jsdoc/require-returns-description": "off",
- "cypress/no-async-tests": "off",
- "@typescript-eslint/ban-ts-comment": [
- "error",
- {
- "ts-expect-error": "allow-with-description",
- "ts-ignore": "allow-with-description",
- "ts-nocheck": "allow-with-description",
- "ts-check": "allow-with-description",
- "minimumDescriptionLength": 10
- }
- ],
- "json/*": ["error", "allowComments"],
- "no-empty": ["error", { "allowEmptyCatch": true }]
- },
- "overrides": [
- {
- "files": "./**/*.html",
- "rules": {
- "no-undef": "off",
- "jsdoc/require-jsdoc": "off"
- }
- },
- {
- "files": ["./cypress/**", "./demos/**"],
- "rules": {
- "no-console": "off"
- }
- },
- {
- "files": ["./**/*.spec.{ts,js}", "./cypress/**", "./demos/**", "./**/docs/**"],
- "rules": {
- "jsdoc/require-jsdoc": "off",
- "@typescript-eslint/no-unused-vars": "off"
- }
- }
- ]
-}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index a3427c2f43..b7e5d38d9b 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,6 +1,8 @@
# These are supported funding model platforms
-github: [knsv]
+github:
+ - knsv
+ - sidharthv96
#patreon: # Replace with a single Patreon username
#open_collective: # Replace with a single Open Collective username
#ko_fi: # Replace with a single Ko-fi username
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 1ca7dd4c3c..0000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: 'Status: Triage, Type: Bug / Error'
-assignees: ''
----
-
-**Describe the bug**
-A clear and concise description of what the bug is.
-
-**To Reproduce**
-Steps to reproduce the behavior:
-
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Code Sample**
-If applicable, add the code sample or a link to the [live editor](https://mermaid.live).
-
-**Desktop (please complete the following information):**
-
-- OS: [e.g. iOS]
-- Browser [e.g. chrome, safari]
-- Version [e.g. 22]
-
-**Smartphone (please complete the following information):**
-
-- Device: [e.g. iPhone6]
-- OS: [e.g. iOS8.1]
-- Browser [e.g. stock browser, safari]
-- Version [e.g. 22]
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..3ddf86ea5e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,69 @@
+name: Bug Report
+description: Create a report to help us improve
+labels:
+ - 'Status: Triage'
+ - 'Type: Bug / Error'
+
+body:
+ - type: markdown
+ attributes:
+ value: |-
+ ## Security vulnerabilities
+ Please refer our [Security Policy](https://github.com/mermaid-js/.github/blob/main/SECURITY.md) and report to keep vulnerabilities confidential so we can release fixes first.
+
+ ## Before you submit...
+ We like to help you, but in order to do that should you make a few things first:
+
+ - Use a clear and concise title
+ - Fill out the text fields with as much detail as possible.
+ - Never be shy to give us screenshots and/or code samples. It will help!
+ - type: textarea
+ attributes:
+ label: Description
+ description: Give a clear and concise description of what the bug is.
+ placeholder: When I do ... does ... happen.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Steps to reproduce
+ description: Give a step-by-step example on how to reproduce the bug.
+ placeholder: |-
+ 1. Do this
+ 2. Do that
+ 3. ...
+ 4. Bug!
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to help explain your issue.
+ - type: textarea
+ attributes:
+ label: Code Sample
+ description: |-
+ If applicable, add the code sample or a link to the [Live Editor](https://mermaid.live).
+ Any text pasted here will be rendered as a Code block.
+ render: text
+ - type: textarea
+ attributes:
+ label: Setup
+ description: |-
+ Please fill out the below info.
+ Note that you only need to fill out one and not both sections.
+ value: |-
+ **Desktop**
+
+ - OS and Version: [Windows, Linux, Mac, ...]
+ - Browser and Version: [Chrome, Edge, Firefox]
+
+ **Smartphone**
+
+ - Device: [Samsung, iPhone, ...]
+ - OS and Version: [Android, iOS, ...]
+ - Browser and Version: [Chrome, Safari, ...]
+ - type: textarea
+ attributes:
+ label: Additional Context
+ description: Anything else to add?
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..8710d49aa4
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,14 @@
+blank_issues_enabled: false
+contact_links:
+ - name: GitHub Discussions
+ url: https://github.com/mermaid-js/mermaid/discussions
+ about: Ask the Community questions or share your own graphs in our discussions.
+ - name: Slack
+ url: https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE
+ about: Join our Community on Slack for Help and a casual chat.
+ - name: Documentation
+ url: https://mermaid-js.github.io
+ about: Read our documentation for all that Mermaid.js can offer.
+ - name: Live Editor
+ url: https://mermaid.live
+ about: Try the live editor to preview graphs in no time.
diff --git a/.github/ISSUE_TEMPLATE/diagram_proposal.yml b/.github/ISSUE_TEMPLATE/diagram_proposal.yml
new file mode 100644
index 0000000000..67dad5d3a3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/diagram_proposal.yml
@@ -0,0 +1,42 @@
+name: Diagram Proposal
+description: Suggest a new Diagram Type to add to Mermaid.
+labels:
+ - 'Status: Triage'
+ - 'Type: Enhancement'
+
+body:
+ - type: markdown
+ attributes:
+ value: |-
+ ## Before you submit...
+ First of all, thank you for proposing a new Diagram to us.
+ We are always happy about new ideas to improve Mermaid.js wherever possible.
+
+ To get the fastest and best response possible, make sure you do the following:
+
+ - Use a clear and concise title
+ - Fill out the text fields with as much detail as possible.
+ - Never be shy to give us screenshots and/or code samples. It will help!
+ - type: textarea
+ attributes:
+ label: Proposal
+ description: A clear and concise description of what should be added to Mermaid.js.
+ placeholder: Mermaid.js should add ... because ...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Use Cases
+ description: If applicable, give some use cases for where this diagram would be useful.
+ placeholder: The Diagram could be used for ...
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to show possible examples of how the diagram may look like.
+ - type: textarea
+ attributes:
+ label: Code Sample
+ description: |-
+ If applicable, add a code sample for how to implement this new diagram.
+ The text will automatically be rendered as JavaScript code.
+ render: javascript
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index ba38cf9acb..0000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: 'Status: Triage, Type: Enhancement'
-assignees: ''
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
deleted file mode 100644
index 52684fd1d4..0000000000
--- a/.github/ISSUE_TEMPLATE/question.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-name: Question
-about: Get some help from the community.
-title: ''
-labels: 'Help wanted!, Type: Other'
-assignees: ''
----
-
-## Help us help you!
-
-You want an answer. Here are some ways to get it quicker:
-
-- Use a clear and concise title.
-- Try to pose a clear and concise question.
-- Include as much, or as little, code as necessary.
-- Don't be shy to give us some screenshots, if it helps!
diff --git a/.github/ISSUE_TEMPLATE/syntax_proposal.yml b/.github/ISSUE_TEMPLATE/syntax_proposal.yml
new file mode 100644
index 0000000000..99250ba93a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/syntax_proposal.yml
@@ -0,0 +1,34 @@
+name: Syntax Proposal
+description: Suggest a new Syntax to add to Mermaid.js.
+labels:
+ - 'Status: Triage'
+ - 'Type: Enhancement'
+
+body:
+ - type: markdown
+ attributes:
+ value: |-
+ ## Before you submit...
+ First of all, thank you for proposing a new Syntax to us.
+ We are always happy about new ideas to improve Mermaid.js wherever possible.
+
+ To get the fastest and best response possible, make sure you do the following:
+
+ - Use a clear and concise title
+ - Fill out the text fields with as much detail as possible. Examples are always welcome.
+ - Never be shy to give us screenshots and/or code samples. It will help!
+ - type: textarea
+ attributes:
+ label: Proposal
+ description: A clear and concise description of what Syntax should be added to Mermaid.js.
+ placeholder: Mermaid.js should add ... because ...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Example
+ description: If applicable, provide an example of the new Syntax.
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to show possible examples of how the theme may look like.
diff --git a/.github/ISSUE_TEMPLATE/theme_proposal.yml b/.github/ISSUE_TEMPLATE/theme_proposal.yml
new file mode 100644
index 0000000000..da4fddbeca
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/theme_proposal.yml
@@ -0,0 +1,42 @@
+name: Theme Proposal
+description: Suggest a new theme to add to Mermaid.js.
+labels:
+ - 'Status: Triage'
+ - 'Type: Enhancement'
+
+body:
+ - type: markdown
+ attributes:
+ value: |-
+ ## Before you submit...
+ First of all, thank you for proposing a new Theme to us.
+ We are always happy about new ideas to improve Mermaid.js wherever possible.
+
+ To get the fastest and best response possible, make sure you do the following:
+
+ - Use a clear and concise title
+ - Fill out the text fields with as much detail as possible. Examples are always welcome!
+ - Never be shy to give us screenshots and/or code samples. It will help!
+ - type: textarea
+ attributes:
+ label: Proposal
+ description: A clear and concise description of what theme should be added to Mermaid.js.
+ placeholder: Mermaid.js should add ... because ...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Colors
+ description: |-
+ A detailed list of the different colour values to use.
+ A list of currently used variable names can be found [here](https://mermaid-js.github.io/mermaid/#/theming?id=theme-variables-reference-table)
+ placeholder: |-
+ - background: #f4f4f4
+ - primaryColor: #fff4dd
+ - ...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to show possible examples of how the theme may look like.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 5add84f225..0000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: npm
- open-pull-requests-limit: 10
- directory: /
- target-branch: develop
- versioning-strategy: increase
- schedule:
- interval: weekly
- day: monday
- time: '07:00'
- - package-ecosystem: github-actions
- directory: /
- target-branch: develop
- schedule:
- interval: weekly
- day: monday
- time: '07:00'
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 41d9c4cff8..3574c35997 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -14,4 +14,5 @@ Make sure you
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
- [ ] :computer: have added unit/e2e tests (if appropriate)
+- [ ] :notebook: have added documentation (if appropriate)
- [ ] :bookmark: targeted `develop` branch
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e5ca579917..2a70b5901d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -16,30 +16,36 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- node-version: [16.x]
+ node-version: [18.x]
steps:
- uses: actions/checkout@v3
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
- cache: yarn
+ cache: pnpm
node-version: ${{ matrix.node-version }}
- - name: Install Yarn
- run: npm i yarn --global
-
- name: Install Packages
run: |
- yarn install --frozen-lockfile
+ pnpm install --frozen-lockfile
env:
CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Run Build
- run: yarn build
+ run: pnpm run build
+
+ - name: Upload Mermaid Build as Artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: mermaid-build
+ path: packages/mermaid/dist
- - name: Upload Build as Artifact
+ - name: Upload Mermaid Mindmap Build as Artifact
uses: actions/upload-artifact@v3
with:
- name: dist
- path: dist
+ name: mermaid-mindmap-build
+ path: packages/mermaid-mindmap/dist
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index 845c763e8c..34b14c395b 100644
--- a/.github/workflows/dependency-review.yml
+++ b/.github/workflows/dependency-review.yml
@@ -17,4 +17,4 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
- uses: actions/dependency-review-action@v2
+ uses: actions/dependency-review-action@v3
diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml
new file mode 100644
index 0000000000..da6dbdb1f9
--- /dev/null
+++ b/.github/workflows/e2e-applitools.yml
@@ -0,0 +1,72 @@
+name: E2E (Applitools)
+
+on:
+ workflow_dispatch:
+ # Because we want to limit Applitools usage, so we only want to start this
+ # workflow on rare occasions/manually.
+ inputs:
+ parent_branch:
+ required: true
+ type: string
+ default: master
+ description: 'Parent branch to use for PRs'
+
+permissions:
+ contents: read
+
+env:
+ # on PRs from forks, this secret will always be empty, for security reasons
+ USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [18.x]
+ steps:
+ - if: ${{ ! env.USE_APPLI }}
+ name: Warn if not using Applitools
+ run: |
+ echo "::error,title=Not using Applitols::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
+
+ - uses: actions/checkout@v3
+
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
+ - name: Setup Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ cache: pnpm
+ node-version: ${{ matrix.node-version }}
+
+ - name: Install Packages
+ run: |
+ pnpm install --frozen-lockfile
+ env:
+ CYPRESS_CACHE_FOLDER: .cache/Cypress
+
+ - if: ${{ env.USE_APPLI }}
+ name: Notify applitools of new batch
+ # Copied from docs https://applitools.com/docs/topics/integrations/github-integration-ci-setup.html
+ run: curl -L -d '' -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
+ env:
+ # e.g. mermaid-js/mermaid/my-branch
+ APPLITOOLS_BRANCH: ${{ github.repository }}/${{ github.ref_name }}
+ APPLITOOLS_PARENT_BRANCH: ${{ github.inputs.parent_branch }}
+ APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
+ APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
+
+ - name: Run E2E Tests
+ run: pnpm run e2e
+ env:
+ CYPRESS_CACHE_FOLDER: .cache/Cypress
+ # Mermaid applitools.config.js uses this to pick batch name.
+ APPLI_BRANCH: ${{ github.ref_name }}
+ APPLITOOLS_BATCH_ID: ${{ github.sha }}
+ # e.g. mermaid-js/mermaid/my-branch
+ APPLITOOLS_BRANCH: ${{ github.repository }}/${{ github.ref_name }}
+ APPLITOOLS_PARENT_BRANCH: ${{ github.inputs.parent_branch }}
+ APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
+ APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 06a346aeb5..aff5852dbb 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -9,30 +9,46 @@ jobs:
build:
runs-on: ubuntu-latest
strategy:
+ fail-fast: false
matrix:
- node-version: [16.x]
+ node-version: [18.x]
+ containers: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
+ # Need to skip setup if Cypress run is skipped, otherwise an error
+ # is thrown since the pnpm cache step fails
+ if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
with:
- cache: yarn
+ cache: pnpm
node-version: ${{ matrix.node-version }}
- - name: Install Yarn
- run: npm i yarn --global
-
- - name: Install Packages
- run: |
- yarn install --frozen-lockfile
+ # Install NPM dependencies, cache them correctly
+ # and run all Cypress tests
+ - name: Cypress run
+ uses: cypress-io/github-action@v4
+ id: cypress
+ # If CYPRESS_RECORD_KEY is set, run in parallel on all containers
+ # Otherwise (e.g. if running from fork), we run on a single container only
+ if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
+ with:
+ start: pnpm run dev
+ wait-on: 'http://localhost:9000'
+ # 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 != '' }}
+ parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
env:
- CYPRESS_CACHE_FOLDER: .cache/Cypress
+ CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
- - name: Run Build
- run: yarn build
-
- - name: Run E2E Tests
- run: yarn e2e
- env:
- CYPRESS_CACHE_FOLDER: .cache/Cypress
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ if: ${{ failure() && steps.cypress.conclusion == 'failure' }}
+ with:
+ name: error-snapshots
+ path: cypress/snapshots/**/__diff_output__/*
diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml
new file mode 100644
index 0000000000..566548ecfb
--- /dev/null
+++ b/.github/workflows/link-checker.yml
@@ -0,0 +1,44 @@
+# This Link Checker is run on all documentation files once per week.
+
+# references:
+# - https://github.com/lycheeverse/lychee-action
+# - https://github.com/lycheeverse/lychee
+
+name: Link Checker
+
+on:
+ push:
+ branches:
+ - develop
+ - master
+ pull_request:
+ branches:
+ - master
+ schedule:
+ # * is a special character in YAML so you have to quote this string
+ - cron: '30 8 * * *'
+
+jobs:
+ linkChecker:
+ runs-on: ubuntu-latest
+ permissions:
+ # lychee only uses the GITHUB_TOKEN to avoid rate-limiting
+ contents: read
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Restore lychee cache
+ uses: actions/cache@v3
+ with:
+ path: .lycheecache
+ key: cache-lychee-${{ github.sha }}
+ restore-keys: cache-lychee-
+
+ - name: Link Checker
+ 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
+ jobSummary: true
+ env:
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index e567aba899..a21fbc0056 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -7,51 +7,65 @@ on:
- opened
- synchronize
- ready_for_review
+ workflow_dispatch:
permissions:
- contents: read
+ contents: write
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
- node-version: [16.x]
+ node-version: [18.x]
steps:
- uses: actions/checkout@v3
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
- cache: yarn
+ cache: pnpm
node-version: ${{ matrix.node-version }}
- - name: Install Yarn
- run: npm i yarn --global
-
- name: Install Packages
run: |
- yarn install --frozen-lockfile
+ pnpm install --frozen-lockfile
env:
CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Run Linting
- run: yarn lint
+ shell: bash
+ run: |
+ if ! pnpm run lint; then
+ # print a nice error message on lint failure
+ ERROR_MESSAGE='Running `pnpm run lint` failed.'
+ ERROR_MESSAGE+=' Running `pnpm run lint:fix` may fix this issue. '
+ ERROR_MESSAGE+=" If this error doesn't occur on your local machine,"
+ ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.'
+ ERROR_MESSAGE+=' You may also need to delete your prettier cache by running'
+ ERROR_MESSAGE+=' `rm ./node_modules/.cache/prettier/.prettier-cache`.'
+ echo "::error title=Lint failure::${ERROR_MESSAGE}"
+ # make sure to return an error exitcode so that GitHub actions shows a red-cross
+ exit 1
+ fi
- name: Verify Docs
- run: yarn docs:verify
+ id: verifyDocs
+ working-directory: ./packages/mermaid
+ continue-on-error: ${{ github.event_name == 'push' }}
+ run: pnpm run docs:verify
- - name: Check no `console.log()` in .jison files
- # ESLint can't parse .jison files directly
- # In the future, it might be worth making a `eslint-plugin-jison`, so
- # that this will be built into the `yarn lint` command.
- run: |
- shopt -s globstar
- mkdir -p tmp/
- for jison_file in src/**/*.jison; do
- outfile="tmp/$(basename -- "$jison_file" .jison)-jison.js"
- echo "Converting $jison_file to $outfile"
- # default module-type (CJS) always adds a console.log()
- yarn jison "$jison_file" --outfile "$outfile" --module-type "amd"
- done
- yarn eslint --no-eslintrc --rule no-console:error --parser "@babel/eslint-parser" "./tmp/*-jison.js"
+ - name: Rebuild Docs
+ if: ${{ steps.verifyDocs.outcome == 'failure' && github.event_name == 'push' }}
+ working-directory: ./packages/mermaid
+ run: pnpm run docs:build
+
+ - name: Commit changes
+ uses: EndBug/add-and-commit@v9
+ if: ${{ steps.verifyDocs.outcome == 'failure' && github.event_name == 'push' }}
+ with:
+ message: 'Update docs'
+ add: 'docs/*'
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 107743c6a9..0a53c6e424 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -8,6 +8,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Label PR
- uses: TimonVS/pr-labeler-action@v3
+ uses: TimonVS/pr-labeler-action@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml
new file mode 100644
index 0000000000..cdd6167b75
--- /dev/null
+++ b/.github/workflows/publish-docs.yml
@@ -0,0 +1,64 @@
+name: Deploy Vitepress docs to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches:
+ - master
+ pull_request:
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+ group: 'pages'
+ cancel-in-progress: true
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - uses: pnpm/action-setup@v2
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ cache: pnpm
+ node-version: 18
+
+ - name: Install Packages
+ run: pnpm install --frozen-lockfile
+
+ - name: Setup Pages
+ uses: actions/configure-pages@v3
+
+ - name: Run Build
+ run: pnpm --filter mermaid run docs:build:vitepress
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v1
+ with:
+ path: packages/mermaid/src/vitepress/.vitepress/dist
+
+ # Deployment job
+ deploy:
+ if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
+ environment:
+ name: github-pages
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v1
diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml
index ed55c847d0..5f4936ab68 100644
--- a/.github/workflows/release-preview-publish.yml
+++ b/.github/workflows/release-preview-publish.yml
@@ -10,22 +10,30 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - uses: pnpm/action-setup@v2
+
- name: Setup Node.js
uses: actions/setup-node@v3
with:
- node-version: 16.x
- - name: Install Yarn
- run: npm i yarn --global
+ cache: pnpm
+ node-version: 18.x
+
+ - name: Install Packages
+ run: |
+ pnpm install --frozen-lockfile
+ env:
+ CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Install Json
run: npm i json --global
- - name: Install Packages
- run: yarn install --frozen-lockfile
-
- name: Publish
+ working-directory: ./packages/mermaid
run: |
- PREVIEW_VERSION=8
+ PREVIEW_VERSION=$(git log --oneline "origin/$GITHUB_REF_NAME" ^"origin/master" | wc -l)
VERSION=$(echo ${{github.ref}} | tail -c +20)-preview.$PREVIEW_VERSION
echo $VERSION
npm version --no-git-tag-version --allow-same-version $VERSION
diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml
index 9cf49e282b..28094453e4 100644
--- a/.github/workflows/release-publish.yml
+++ b/.github/workflows/release-publish.yml
@@ -11,18 +11,21 @@ jobs:
- uses: actions/checkout@v3
- uses: fregante/setup-git-user@v1
- - name: Setup Node.js
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
+ - name: Setup Node.js v18
uses: actions/setup-node@v3
with:
- node-version: 16.x
- - name: Install Yarn
- run: npm i yarn --global
-
- - name: Install Json
- run: npm i json --global
+ cache: pnpm
+ node-version: 18.x
- name: Install Packages
- run: yarn install --frozen-lockfile
+ run: |
+ pnpm install --frozen-lockfile
+ npm i json --global
+ env:
+ CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Prepare release
run: |
@@ -31,7 +34,7 @@ jobs:
git checkout -t origin/release/$VERSION
npm version --no-git-tag-version --allow-same-version $VERSION
git add package.json
- git commit -m "Bump version $VERSION"
+ git commit -nm "Bump version $VERSION"
git checkout -t origin/master
git merge -m "Release $VERSION" --no-ff release/$VERSION
git push --no-verify
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 08c35befab..6397e53051 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,28 +10,28 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- node-version: [16.x]
+ node-version: [18.x]
steps:
- uses: actions/checkout@v3
+ - uses: pnpm/action-setup@v2
+ # uses version from "packageManager" field in package.json
+
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
- cache: yarn
+ cache: pnpm
node-version: ${{ matrix.node-version }}
- - name: Install Yarn
- run: npm i yarn --global
-
- name: Install Packages
run: |
- yarn install --frozen-lockfile
+ pnpm install --frozen-lockfile
env:
CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Run Unit Tests
run: |
- yarn ci --coverage
+ pnpm run ci --coverage
- name: Upload Coverage to Coveralls
# it feels a bit weird to use @master, but that's what the docs use
diff --git a/.gitignore b/.gitignore
index 9641d25748..f29286825a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,11 @@ token
package-lock.json
-.vscode/
+# ignore files in /.vscode/ except for launch.json and extensions.json
+/.vscode/**
+!/.vscode/launch.json
+!/.vscode/extensions.json
+
cypress/platform/current.html
cypress/platform/experimental.html
local/
@@ -28,3 +32,7 @@ cypress/snapshots/
.eslintcache
.tsbuildinfo
tsconfig.tsbuildinfo
+
+knsv*.html
+local*.html
+stats/
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 025779ed2b..a9e30b9bec 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
-yarn pre-commit
+pnpm run pre-commit
diff --git a/.lintstagedrc.json b/.lintstagedrc.json
deleted file mode 100644
index b88abda4b2..0000000000
--- a/.lintstagedrc.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "src/docs/**": ["yarn docs:build --git"],
- "src/docs.mts": ["yarn docs:build --git"],
- "*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"]
-}
diff --git a/.lintstagedrc.mjs b/.lintstagedrc.mjs
new file mode 100644
index 0000000000..ac26230932
--- /dev/null
+++ b/.lintstagedrc.mjs
@@ -0,0 +1,11 @@
+export default {
+ '!(docs/**/*)*.{ts,js,json,html,md,mts}': [
+ 'eslint --cache --cache-strategy content --fix',
+ // don't cache prettier yet, since we use `prettier-plugin-jsdoc`,
+ // and prettier doesn't invalidate cache on plugin updates"
+ // https://prettier.io/docs/en/cli.html#--cache
+ 'prettier --write',
+ ],
+ 'cSpell.json': ['ts-node-esm scripts/fixCSpell.ts'],
+ '**/*.jison': ['pnpm -w run lint:jison'],
+};
diff --git a/.lycheeignore b/.lycheeignore
new file mode 100644
index 0000000000..79cf4428bd
--- /dev/null
+++ b/.lycheeignore
@@ -0,0 +1,16 @@
+# These links are ignored by our link checker https://github.com/lycheeverse/lychee
+# The file allows you to list multiple regular expressions for exclusion (one pattern per line).
+
+# Network error: Forbidden
+https://codepen.io
+
+# Network error: The certificate was not trusted
+https://mkdocs.org/
+https://osawards.com/javascript/#nominees
+https://osawards.com/javascript/2019
+
+# Timeout error, maybe Twitter has anti-bot defences against GitHub's CI servers?
+https://twitter.com/mermaidjs_
+
+# Don't check files that are generated during the build via `pnpm docs:code`
+packages/mermaid/src/docs/config/setup/*
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..2896843026
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,3 @@
+auto-install-peers=true
+strict-peer-dependencies=false
+use-inline-specifiers-lockfile-format=true
diff --git a/.prettierignore b/.prettierignore
index 2ce673fe9e..b66f97d1ca 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,3 +1,7 @@
dist
cypress/platform/xss3.html
-.cache
\ No newline at end of file
+.cache
+coverage
+# Autogenerated by PNPM
+pnpm-lock.yaml
+stats
\ No newline at end of file
diff --git a/.vite/build.ts b/.vite/build.ts
new file mode 100644
index 0000000000..268db32702
--- /dev/null
+++ b/.vite/build.ts
@@ -0,0 +1,142 @@
+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';
+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));
+
+type OutputOptions = Exclude<
+ Exclude['rollupOptions'],
+ undefined
+>['output'];
+
+const visualizerOptions = (packageName: string, core = false): PluginOption[] => {
+ if (packageName !== 'mermaid' || !visualize) {
+ return [];
+ }
+ return ['network', 'treemap', 'sunburst'].map(
+ (chartType) =>
+ visualizer({
+ filename: `./stats/${chartType}${core ? '.core' : ''}.html`,
+ template: chartType as TemplateType,
+ gzipSize: true,
+ brotliSize: true,
+ }) as PluginOption
+ );
+};
+
+const packageOptions = {
+ mermaid: {
+ name: 'mermaid',
+ packageName: 'mermaid',
+ file: 'mermaid.ts',
+ },
+ 'mermaid-example-diagram': {
+ name: 'mermaid-example-diagram',
+ packageName: 'mermaid-example-diagram',
+ file: 'detector.ts',
+ },
+};
+
+interface BuildOptions {
+ minify: boolean | 'esbuild';
+ core?: boolean;
+ watch?: boolean;
+ entryName: keyof typeof packageOptions;
+}
+
+export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => {
+ const external: (string | RegExp)[] = ['require', 'fs', 'path'];
+ console.log(entryName, packageOptions[entryName]);
+ const { name, file, packageName } = packageOptions[entryName];
+ let output: OutputOptions = [
+ {
+ name,
+ format: 'esm',
+ sourcemap: true,
+ entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
+ },
+ ];
+
+ if (core) {
+ const { dependencies } = JSON.parse(
+ readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
+ );
+ // Core build is used to generate file without bundled dependencies.
+ // This is used by downstream projects to bundle dependencies themselves.
+ // Ignore dependencies and any dependencies of dependencies
+ // Adapted from the RegEx used by `rollup-plugin-node`
+ external.push(new RegExp('^(?:' + Object.keys(dependencies).join('|') + ')(?:/.+)?$'));
+ // This needs to be an array. Otherwise vite will build esm & umd with same name and overwrite esm with umd.
+ output = [
+ {
+ name,
+ format: 'esm',
+ sourcemap: true,
+ entryFileNames: `${name}.core.mjs`,
+ },
+ ];
+ }
+
+ const config: InlineConfig = {
+ configFile: false,
+ build: {
+ emptyOutDir: false,
+ outDir: resolve(__dirname, `../packages/${packageName}/dist`),
+ lib: {
+ entry: resolve(__dirname, `../packages/${packageName}/src/${file}`),
+ name,
+ // the proper extensions will be added
+ fileName: name,
+ },
+ minify,
+ rollupOptions: {
+ external,
+ output,
+ },
+ },
+ resolve: {
+ extensions: ['.jison', '.js', '.ts', '.json'],
+ },
+ plugins: [jisonPlugin(), ...visualizerOptions(packageName, core)],
+ };
+
+ if (watch && config.build) {
+ config.build.watch = {
+ include: ['packages/mermaid-example-diagram/src/**', 'packages/mermaid/src/**'],
+ };
+ }
+
+ return config;
+};
+
+const buildPackage = async (entryName: keyof typeof packageOptions) => {
+ await build(getBuildConfig({ minify: false, entryName }));
+ await build(getBuildConfig({ minify: 'esbuild', entryName }));
+ await build(getBuildConfig({ minify: false, core: true, entryName }));
+};
+
+const main = async () => {
+ const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
+ for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
+ await buildPackage(pkg);
+ }
+};
+
+if (watch) {
+ build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
+ if (!mermaidOnly) {
+ 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();
+}
diff --git a/.vite/jisonPlugin.ts b/.vite/jisonPlugin.ts
new file mode 100644
index 0000000000..c211907841
--- /dev/null
+++ b/.vite/jisonPlugin.ts
@@ -0,0 +1,17 @@
+import { transformJison } from './jisonTransformer.js';
+const fileRegex = /\.(jison)$/;
+
+export default function jison() {
+ return {
+ name: 'jison',
+
+ transform(src: string, id: string) {
+ if (fileRegex.test(id)) {
+ return {
+ code: transformJison(src),
+ map: null, // provide source map if available
+ };
+ }
+ },
+ };
+}
diff --git a/.vite/jisonTransformer.ts b/.vite/jisonTransformer.ts
new file mode 100644
index 0000000000..a5734e1259
--- /dev/null
+++ b/.vite/jisonTransformer.ts
@@ -0,0 +1,17 @@
+// @ts-ignore No typings for jison
+import jison from 'jison';
+
+export const transformJison = (src: string): string => {
+ // @ts-ignore No typings for jison
+ const parser = new jison.Generator(src, {
+ moduleType: 'js',
+ 'token-stack': true,
+ });
+ const source = parser.generate({ moduleMain: '() => {}' });
+ const exporter = `
+ parser.parser = parser;
+ export { parser };
+ export default parser;
+ `;
+ return `${source} ${exporter}`;
+};
diff --git a/.vite/server.ts b/.vite/server.ts
new file mode 100644
index 0000000000..7a65cba005
--- /dev/null
+++ b/.vite/server.ts
@@ -0,0 +1,27 @@
+import express from 'express';
+import cors from 'cors';
+import { createServer as createViteServer } from 'vite';
+
+async function createServer() {
+ const app = express();
+
+ // Create Vite server in middleware mode
+ const vite = await createViteServer({
+ configFile: './vite.config.ts',
+ server: { middlewareMode: true },
+ appType: 'custom', // don't include Vite's default HTML handling middlewares
+ });
+
+ app.use(cors());
+ app.use(express.static('./packages/mermaid/dist'));
+ app.use(express.static('./packages/mermaid-example-diagram/dist'));
+ app.use(vite.middlewares);
+ app.use(express.static('demos'));
+ app.use(express.static('cypress/platform'));
+
+ app.listen(9000, () => {
+ console.log(`Listening on http://localhost:9000`);
+ });
+}
+
+createServer();
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000000..9633bed665
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "dbaeumer.vscode-eslint",
+ "esbenp.prettier-vscode",
+ "zixuanchen.vitest-explorer",
+ "luniclynx.bison"
+ ]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000000..83b80fa403
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,28 @@
+{
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Debug Current Test File",
+ "autoAttachChildProcesses": true,
+ "skipFiles": ["/**", "**/node_modules/**"],
+ "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
+ "args": ["run", "${relativeFile}"],
+ "smartStep": true,
+ "console": "integratedTerminal"
+ },
+ {
+ "name": "Docs generation",
+ "type": "node",
+ "request": "launch",
+ "args": ["src/docs.mts"],
+ "runtimeArgs": ["--loader", "ts-node/esm"],
+ "cwd": "${workspaceRoot}/packages/mermaid",
+ "skipFiles": ["/**", "**/node_modules/**"],
+ "smartStep": true,
+ "internalConsoleOptions": "openOnSessionStart"
+ }
+ ]
+}
diff --git a/.webpack/loaders/jison.js b/.webpack/loaders/jison.js
deleted file mode 100644
index 0d5ebc7e5b..0000000000
--- a/.webpack/loaders/jison.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const { Generator } = require('jison');
-const validate = require('schema-utils');
-
-const schema = {
- title: 'Jison Parser options',
- type: 'object',
- properties: {
- 'token-stack': {
- type: 'boolean',
- },
- debug: {
- type: 'boolean',
- },
- },
- additionalProperties: false,
-};
-
-module.exports = function jisonLoader(source) {
- const options = this.getOptions();
- (validate.validate || validate)(schema, options, {
- name: 'Jison Loader',
- baseDataPath: 'options',
- });
- return new Generator(source, options).generate();
-};
diff --git a/.webpack/webpack.config.babel.js b/.webpack/webpack.config.babel.js
deleted file mode 100644
index 15760b19b8..0000000000
--- a/.webpack/webpack.config.babel.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { merge, mergeWithCustomize, customizeObject } from 'webpack-merge';
-import nodeExternals from 'webpack-node-externals';
-import baseConfig from './webpack.config.base';
-
-export default (_env, args) => {
- return [
- // non-minified
- merge(baseConfig, {
- optimization: {
- minimize: false,
- },
- }),
- // core [To be used by webpack/esbuild/vite etc to bundle mermaid]
- merge(baseConfig, {
- externals: [nodeExternals()],
- output: {
- filename: '[name].core.js',
- },
- optimization: {
- minimize: false,
- },
- }),
- // umd
- merge(baseConfig, {
- output: {
- filename: '[name].min.js',
- },
- }),
- // esm
- mergeWithCustomize({
- customizeObject: customizeObject({
- 'output.library': 'replace',
- }),
- })(baseConfig, {
- experiments: {
- outputModule: true,
- },
- output: {
- library: {
- type: 'module',
- },
- filename: '[name].esm.min.mjs',
- },
- }),
- ];
-};
diff --git a/.webpack/webpack.config.base.js b/.webpack/webpack.config.base.js
deleted file mode 100644
index 3ebd1863d4..0000000000
--- a/.webpack/webpack.config.base.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import path from 'path';
-const esbuild = require('esbuild');
-const { ESBuildMinifyPlugin } = require('esbuild-loader');
-export const resolveRoot = (...relativePath) => path.resolve(__dirname, '..', ...relativePath);
-
-export default {
- amd: false, // https://github.com/lodash/lodash/issues/3052
- target: 'web',
- entry: {
- mermaid: './src/mermaid',
- },
- resolve: {
- extensions: ['.wasm', '.mjs', '.js', '.ts', '.json', '.jison'],
- fallback: {
- fs: false, // jison generated code requires 'fs'
- path: require.resolve('path-browserify'),
- },
- },
- output: {
- path: resolveRoot('./dist'),
- filename: '[name].js',
- library: {
- name: 'mermaid',
- type: 'umd',
- export: 'default',
- },
- globalObject: 'typeof self !== "undefined" ? self : this',
- },
- module: {
- rules: [
- {
- test: /\.ts$/,
- use: 'ts-loader',
- exclude: /node_modules/,
- },
- {
- test: /\.js$/,
- include: [resolveRoot('./src'), resolveRoot('./node_modules/dagre-d3-renderer/lib')],
- use: {
- loader: 'esbuild-loader',
- options: {
- implementation: esbuild,
- target: 'es2015',
- },
- },
- },
- {
- // load scss to string
- test: /\.scss$/,
- use: ['css-to-string-loader', 'css-loader', 'sass-loader'],
- },
- {
- test: /\.jison$/,
- use: {
- loader: path.resolve(__dirname, './loaders/jison.js'),
- options: {
- 'token-stack': true,
- },
- },
- },
- ],
- },
- devtool: 'source-map',
- optimization: {
- minimizer: [
- new ESBuildMinifyPlugin({
- target: 'es2015',
- }),
- ],
- },
-};
diff --git a/.webpack/webpack.config.e2e.babel.js b/.webpack/webpack.config.e2e.babel.js
deleted file mode 100644
index 7f26b8aed7..0000000000
--- a/.webpack/webpack.config.e2e.babel.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import baseConfig, { resolveRoot } from './webpack.config.base';
-import { merge } from 'webpack-merge';
-
-export default merge(baseConfig, {
- mode: 'development',
- entry: {
- mermaid: './src/mermaid',
- e2e: './cypress/platform/viewer.js',
- 'bundle-test': './cypress/platform/bundle-test.js',
- },
- output: {
- globalObject: 'window',
- },
- devServer: {
- compress: true,
- port: 9000,
- static: [
- { directory: resolveRoot('cypress', 'platform') },
- { directory: resolveRoot('dist') },
- { directory: resolveRoot('demos') },
- ],
- },
- externals: {
- mermaid: 'mermaid',
- },
-});
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..0917a17fc7
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+- Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+- The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+- Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at security@mermaid.live
+.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8171aeca99..b0320b36e1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,13 +6,24 @@ So you want to help? That's great!
Here are a few things to know to get you started on the right path.
+Below link will help you making a copy of the repository in your local system.
+
+https://docs.github.com/en/get-started/quickstart/fork-a-repo
+
+## Requirements
+
+- [volta](https://volta.sh/) to manage node versions.
+- [Node.js](https://nodejs.org/en/). `volta install node`
+- [pnpm](https://pnpm.io/) package manager. `volta install pnpm`
+
## Development Installation
```bash
git clone git@github.com:mermaid-js/mermaid.git
cd mermaid
-yarn
-yarn test
+# npx is required for first install as volta support for pnpm is not added yet.
+npx pnpm install
+pnpm test
```
## Committing code
@@ -21,7 +32,7 @@ We make all changes via pull requests. As we have many pull requests from develo
- Large changes reviewed by knsv or other developer asked to review by knsv
- Smaller low-risk changes like dependencies, documentation, etc. can be merged by active collaborators
-- Documentation (updates to the `src/docs` folder is also allowed via direct commits)
+- Documentation (updates to the `package/mermaid/src/docs` folder is also allowed via direct commits)
To commit code, create a branch, let it start with the type like feature or bug followed by the issue number for reference and some describing text.
@@ -39,47 +50,60 @@ Less strict here, it is OK to commit directly in the `develop` branch if you are
The documentation is written in **Markdown**. For more information about Markdown [see the GitHub Markdown help page](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).
-### Documentation source files are in /src/docs
+### Documentation source files are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs)
-The source files for the project documentation are located in the `/src/docs` directory. This is where you should make changes.
-The files under `/src/docs` are processed to generate the published documentation, and the resulting files are put into the `/docs` directory.
+The source files for the project documentation are located in the [`/packages/mermaid/src/docs`](packages/mermaid/src/docs) directory. This is where you should make changes.
+The files under `/packages/mermaid/src/docs` are processed to generate the published documentation, and the resulting files are put into the `/docs` directory.
```mermaid
flowchart LR
classDef default fill:#fff,color:black,stroke:black
- source["files in /src/docs\n(changes should be done here)"] -- automatic processing\nto generate the final documentation--> published["files in /docs\ndisplayed on the official documentation site"]
+ source["files in /packages/mermaid/src/docs\n(changes should be done here)"] -- automatic processing\nto generate the final documentation--> published["files in /docs\ndisplayed on the official documentation site"]
```
-**_DO NOT CHANGE FILES IN `/docs`_**
+You can use `note`, `tip`, `warning` and `danger` in triple backticks to add a note, tip, warning or danger box.
+Do not use vitepress specific markdown syntax `::: warning` as it will not be processed correctly.
-### The official documentation site
+````
+```note
+Note content
+```
-**[The mermaid documentation site](https://mermaid-js.github.io/mermaid/) is powered by [Docsify](https://docsify.js.org), a simple documentation site generator.**
+```tip
+Tip content
+```
-If you want to preview the whole documentation site on your machine, you need to install `docsify-cli`:
+```warning
+Warning content
+```
-```sh
-$ npm i docsify-cli -g
+```danger
+Danger content
```
-If you are more familiar with Yarn, you can use the following command:
+````
-```sh
-$ yarn global add docsify-cli
-```
+**_DO NOT CHANGE FILES IN `/docs`_**
-The above command will install `docsify-cli` globally.
-If the installation is successful, the command `docsify` will be available in your `PATH`.
+### The official documentation site
-You can now run the following command to serve the documentation site:
+**[The mermaid documentation site](https://mermaid-js.github.io/mermaid/) is powered by [Vitepress](https://vitepress.vuejs.org/), a simple documentation site generator.**
+
+If you want to preview the whole documentation site on your machine:
```sh
-$ docsify serve docs
+cd packages/mermaid
+pnpm i
+pnpm docs:dev
```
-Once the local HTTP server is listening, you can point your browser at http://localhost:3000.
+You can now build and serve the documentation site:
+
+```sh
+pnpm docs:serve
+```
## Branching
@@ -103,7 +127,7 @@ This is important so that, if someone else does a change to the grammar that doe
This tests the rendering and visual appearance of the diagram. This ensures that the rendering of that feature in the e2e will be reviewed in the release process going forward. Less chance that it breaks!
-To start working with the e2e tests, run `yarn dev` to start the dev server, after that start cypress by running `cypress open` in the mermaid folder. (Make sure you have path to cypress in order, the binary is located in node_modules/.bin).
+To start working with the e2e tests, run `pnpm run dev` to start the dev server, after that start cypress by running `pnpm exec cypress open` in the mermaid folder.
The rendering tests are very straightforward to create. There is a function imgSnapshotTest. This function takes a diagram in text form, the mermaid options and renders that diagram in cypress.
@@ -137,11 +161,11 @@ it('should render forks and joins', () => {
Finally, if it is not in the documentation, no one will know about it and then **no one will use it**. Wouldn't that be sad? With all the effort that was put into the feature?
-The source files for documentation are in `/src/docs` and are written in markdown. Just pick the right section and start typing. See the [Committing Documentation](#committing-documentation) section for more about how the documentation is generated.
+The source files for documentation are in `/packages/mermaid/src/docs` and are written in markdown. Just pick the right section and start typing. See the [Committing Documentation](#committing-documentation) section for more about how the documentation is generated.
#### Adding to or changing the documentation organization
-If you want to add a new section or change the organization (structure), then you need to make sure to **change the side navigation** in `src/docs/_sidebar.md`.
+If you want to add a new section or change the organization (structure), then you need to make sure to **change the side navigation** in `mermaid/src/docs/.vitepress/config.js`.
When changes are committed and then released, they become part of the `master` branch and become part of the published documentation on https://mermaid-js.github.io/mermaid/
diff --git a/README.md b/README.md
index f42bf348df..f4cf8e105c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,37 @@
-# mermaid [![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![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) [![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)
-
-English | [简体中文](./README.zh-CN.md)
+
+
+
+
+
+[![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/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 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 Downloads](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/badge/Social-mermaidjs__-blue?style=social&logo=twitter)](https://twitter.com/mermaidjs_)
@@ -8,7 +39,7 @@ English | [简体中文](./README.zh-CN.md)
**Thanks to all involved, people committing pull requests, people answering questions! 🙏**
-
+
## About
@@ -24,14 +55,12 @@ Mermaid addresses this problem by enabling users to create easily modifiable dia
Mermaid allows even non-programmers to easily create detailed diagrams through the [Mermaid Live Editor](https://mermaid.live/).
-[Tutorials](./docs/Tutorials.md) has video tutorials.
-Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
-
-You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
+[Tutorials](./docs/config/Tutorials.md) has video tutorials.
+Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/ecosystem/integrations.md).
-For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/n00b-overview.md), [Usage](./docs/usage.md) and [Tutorials](./docs/Tutorials.md).
+You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/ecosystem/integrations.md).
-🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [Changelog](./docs/CHANGELOG.md)
+For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/community/n00b-overview.md), [Usage](./docs/config/usage.md) and [Tutorials](./docs/config/Tutorials.md).
In our release process we rely heavily on visual regression tests using [applitools](https://applitools.com/). Applitools is a great service which has been easy to use and integrate with our tests.
@@ -335,7 +364,11 @@ To report a vulnerability, please e-mail security@mermaid.live with a descriptio
A quick note from Knut Sveidqvist:
-> _Many thanks to the [d3](https://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!_ >_Thanks also to the [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering._ >_Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
+> _Many thanks to the [d3](https://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!_
+>
+> _Thanks also to the [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering._
+>
+> _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!_
diff --git a/README.zh-CN.md b/README.zh-CN.md
index c00c539e04..65cf38645e 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,6 +1,37 @@
-# mermaid [![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![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) [![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)
-
-[English](./README.md) | 简体中文
+