diff --git a/.eslintrc.json b/.eslintrc.json index 02753280c..9d7eacecd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,26 +16,27 @@ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", - "plugin:jsdoc/recommended", "plugin:json/recommended", "plugin:markdown/recommended", + "plugin:@cspell/recommended", "prettier" ], - "plugins": ["@typescript-eslint", "html", "jest", "jsdoc", "json"], + "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", - "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", @@ -48,28 +49,89 @@ } ], "json/*": ["error", "allowComments"], - "no-empty": ["error", { "allowEmptyCatch": true }] + "@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": "./**/*.html", - "rules": { - "no-undef": "off", - "jsdoc/require-jsdoc": "off" - } - }, - { - "files": ["./cypress/**", "./demos/**"], + "files": ["cypress/**", "demos/**"], "rules": { "no-console": "off" } }, { - "files": ["./**/*.spec.{ts,js}", "./cypress/**", "./demos/**", "./**/docs/**"], + "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" + } } ] } diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 1ca7dd4c3..000000000 --- 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 000000000..3ddf86ea5 --- /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 000000000..8710d49aa --- /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 000000000..67dad5d3a --- /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 ba38cf9ac..000000000 --- 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 52684fd1d..000000000 --- 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 000000000..99250ba93 --- /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 000000000..da4fddbec --- /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 5add84f22..000000000 --- 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/workflows/build.yml b/.github/workflows/build.yml index a8bafc91a..2a70b5901 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml index 5c515b433..da6dbdb1f 100644 --- a/.github/workflows/e2e-applitools.yml +++ b/.github/workflows/e2e-applitools.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - if: ${{ ! env.USE_APPLI }} name: Warn if not using Applitools diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 8925a828d..55e06f46d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [16.x] + node-version: [18.x] containers: [1, 2, 3, 4] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml new file mode 100644 index 000000000..fbf03cb39 --- /dev/null +++ b/.github/workflows/link-checker.yml @@ -0,0 +1,45 @@ +# 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: + - develop + - master + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '30 8 * * 5' + +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 dd2f7aa3b..8ba06989d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - uses: actions/checkout@v3 @@ -39,4 +39,5 @@ jobs: run: pnpm run lint - name: Verify Docs + working-directory: ./packages/mermaid run: pnpm run docs:verify diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 000000000..85bc79f6e --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,62 @@ +name: Deploy Vitepress docs to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + - master + + # 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@v2 + + - 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: + 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 ed55c847d..5f4936ab6 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 9cf49e282..6f0806de1 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -14,7 +14,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 16.x + node-version: 18.x - name: Install Yarn run: npm i yarn --global diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd058406d..6397e5305 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index 6e4fe723a..f29286825 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ cypress/snapshots/ .eslintcache .tsbuildinfo tsconfig.tsbuildinfo + +knsv*.html +local*.html +stats/ diff --git a/.lintstagedrc.json b/.lintstagedrc.json deleted file mode 100644 index be6e92770..000000000 --- a/.lintstagedrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "packages/mermaid/src/docs/**": ["pnpm run docs:build --git"], - "packages/mermaid/src/docs.mts": ["pnpm run docs:build --git"], - "*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"], - "*.jison": ["pnpm run lint:jison"] -} diff --git a/.lintstagedrc.mjs b/.lintstagedrc.mjs new file mode 100644 index 000000000..ff1d8c107 --- /dev/null +++ b/.lintstagedrc.mjs @@ -0,0 +1,5 @@ +export default { + '!(docs/**/*)*.{ts,js,json,html,md,mts}': ['eslint --fix', '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 000000000..767906b16 --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,13 @@ +# 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 + +# 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 000000000..289684302 --- /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 fe2c55574..b66f97d1c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,5 @@ cypress/platform/xss3.html .cache coverage # Autogenerated by PNPM -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml +stats \ No newline at end of file diff --git a/.vite/build.ts b/.vite/build.ts index 6855d3e48..1be46ad5a 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -1,11 +1,14 @@ -import { build, InlineConfig } from 'vite'; +import { build, InlineConfig, type PluginOption } from 'vite'; import { resolve } from 'path'; import { fileURLToPath } from 'url'; import jisonPlugin from './jisonPlugin.js'; -import pkg from '../package.json' assert { type: 'json' }; +import { readFileSync } from 'fs'; +import { visualizer } from 'rollup-plugin-visualizer'; +import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js'; -const { dependencies } = pkg; +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< @@ -13,6 +16,20 @@ type OutputOptions = Exclude< 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, + }) + ); +}; + const packageOptions = { mermaid: { name: 'mermaid', @@ -22,23 +39,13 @@ const packageOptions = { 'mermaid-mindmap': { name: 'mermaid-mindmap', packageName: 'mermaid-mindmap', - file: 'add-diagram.ts', - }, - 'mermaid-mindmap-detector': { - name: 'mermaid-mindmap-detector', - packageName: 'mermaid-mindmap', - file: 'registry.ts', - }, - 'mermaid-example-diagram': { - name: 'mermaid-example-diagram', - packageName: 'mermaid-example-diagram', - file: 'add-diagram.ts', - }, - 'mermaid-example-diagram-detector': { - name: 'mermaid-example-diagram-detector', - packageName: 'mermaid-example-diagram', - file: 'registry.ts', + file: 'detector.ts', }, + // 'mermaid-example-diagram-detector': { + // name: 'mermaid-example-diagram-detector', + // packageName: 'mermaid-example-diagram', + // file: 'detector.ts', + // }, }; interface BuildOptions { @@ -49,7 +56,7 @@ interface BuildOptions { } export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => { - const external = ['require', 'fs', 'path']; + const external: (string | RegExp)[] = ['require', 'fs', 'path']; console.log(entryName, packageOptions[entryName]); const { name, file, packageName } = packageOptions[entryName]; let output: OutputOptions = [ @@ -68,9 +75,14 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) ]; 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. - external.push(...Object.keys(dependencies)); + // 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 = [ { @@ -102,7 +114,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) resolve: { extensions: ['.jison', '.js', '.ts', '.json'], }, - plugins: [jisonPlugin()], + plugins: [jisonPlugin(), ...visualizerOptions(packageName, core)], }; if (watch && config.build) { @@ -110,7 +122,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) include: [ 'packages/mermaid-mindmap/src/**', 'packages/mermaid/src/**', - 'packages/mermaid-example-diagram/src/**', + // 'packages/mermaid-example-diagram/src/**', ], }; } @@ -128,15 +140,20 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { const main = async () => { const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; - for (const pkg of packageNames) { + for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) { await buildPackage(pkg); } }; if (watch) { - build(getBuildConfig({ minify: false, watch, entryName: 'mermaid' })); - build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); - build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); + build(getBuildConfig({ minify: false, watch, core: true, entryName: 'mermaid' })); + if (!mermaidOnly) { + build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); + // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); + } +} else if (visualize) { + await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' })); + await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })); } else { void main(); } diff --git a/.vite/server.ts b/.vite/server.ts index 3cfea7cf4..334398dd8 100644 --- a/.vite/server.ts +++ b/.vite/server.ts @@ -1,7 +1,15 @@ -import express from 'express'; +import express, { NextFunction, Request, Response } from 'express'; import { createServer as createViteServer } from 'vite'; // import { getBuildConfig } from './build'; +const cors = (req: Request, res: Response, next: NextFunction) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); + res.header('Access-Control-Allow-Headers', 'Content-Type'); + + next(); +}; + async function createServer() { const app = express(); @@ -12,8 +20,11 @@ async function createServer() { appType: 'custom', // don't include Vite's default HTML handling middlewares }); - app.use(vite.middlewares); + app.use(cors); app.use(express.static('./packages/mermaid/dist')); + app.use(express.static('./packages/mermaid-example-diagram/dist')); + app.use(express.static('./packages/mermaid-mindmap/dist')); + app.use(vite.middlewares); app.use(express.static('demos')); app.use(express.static('cypress/platform')); diff --git a/.vite/tsconfig.json b/.vite/tsconfig.json deleted file mode 100644 index 915436da1..000000000 --- a/.vite/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "module": "ES2022" - } -} diff --git a/.vscode/launch.json b/.vscode/launch.json index 92df7056e..83b80fa40 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,17 @@ "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/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0917a17fc --- /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 d7efa8e41..cf199c39b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,12 +6,23 @@ 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 -pnpm install +# npx is required for first install as volta support for pnpm is not added yet. +npx pnpm install pnpm test ``` @@ -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,16 +50,16 @@ 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"] ``` @@ -56,31 +67,22 @@ flowchart LR ### The official documentation site -**[The mermaid documentation site](https://mermaid-js.github.io/mermaid/) is powered by [Docsify](https://docsify.js.org), a simple documentation site generator.** +**[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, you need to install `docsify-cli`: +If you want to preview the whole documentation site on your machine: ```sh -$ npm i docsify-cli -g +cd packages/mermaid +pnpm i +pnpm docs:dev ``` -If you are more familiar with Yarn, you can use the following command: +You can now build and serve the documentation site: ```sh -$ yarn global add docsify-cli +pnpm docs:serve ``` -The above command will install `docsify-cli` globally. -If the installation is successful, the command `docsify` will be available in your `PATH`. - -You can now run the following command to serve the documentation site: - -```sh -$ docsify serve docs -``` - -Once the local HTTP server is listening, you can point your browser at http://localhost:3000. - ## Branching Going forward we will use a git flow inspired approach to branching. So development is done in develop, to do the development in the develop. @@ -137,11 +139,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 b30d8d438..059940a02 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,6 @@ -# 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) +# mermaid -# Whoa, whats going on here? - -We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will: - -- Make it possible to select which diagrams to include on your site -- Open up for lazy loading -- Make it possible to add diagrams from outside of the Mermaid repository -- Separate the release flow between different diagrams and the Mermaid core - -As such be aware of some changes.. - -# We use pnpm now - -# The source code has moved - -It is now located in the src folder for each respective package located as subfolders in packages. +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) English | [简体中文](./README.zh-CN.md) @@ -41,12 +26,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). +[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/misc/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). +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/misc/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). +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). 🌐 [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) @@ -352,7 +337,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 c00c539e0..4bdbc4ae7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,4 +1,6 @@ -# 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) +# mermaid + +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) [English](./README.md) | 简体中文 @@ -22,9 +24,9 @@ Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markd Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。

Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。
-你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。 +你可以访问 [教程](./docs/config/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/misc/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。 -如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md), [用法](./docs/usage.md) 和 [教程](./docs/Tutorials.md). +如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/community/n00b-overview.md), [用法](./docs/config/usage.md) 和 [教程](./docs/config/Tutorials.md). 🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md) @@ -37,7 +39,7 @@ Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://merma -### 流程图 [文档 - live editor] +### 流程图 [文档 - live editor] ``` flowchart LR @@ -55,7 +57,7 @@ C -->|One| D[Result 1] C -->|Two| E[Result 2] ``` -### 时序图 [文档 - live editor] +### 时序图 [文档 - live editor] ``` sequenceDiagram @@ -81,7 +83,7 @@ John->>Bob: How about you? Bob-->>John: Jolly good! ``` -### 甘特图 [文档 - live editor] +### 甘特图 [文档 - live editor] ``` gantt @@ -105,7 +107,7 @@ gantt Parallel 4 : des6, after des4, 1d ``` -### 类图 [文档 - live editor] +### 类图 [文档 - live editor] ``` classDiagram @@ -145,7 +147,7 @@ class Class10 { } ``` -### 状态图 [[docs - live editor] +### 状态图 [[docs - live editor] ``` stateDiagram-v2 @@ -167,7 +169,7 @@ Moving --> Crash Crash --> [*] ``` -### 饼图 [文档 - live editor] +### 饼图 [文档 - live editor] ``` pie @@ -183,9 +185,9 @@ pie "Rats" : 15 ``` -### Git 图 [实验特性 - live editor] +### Git 图 [实验特性 - live editor] -### 用户体验旅程图 [文档 - live editor] +### 用户体验旅程图 [文档 - live editor] ``` journey diff --git a/V10-BreakingChanges.md b/V10-BreakingChanges.md new file mode 100644 index 000000000..bd9110d1a --- /dev/null +++ b/V10-BreakingChanges.md @@ -0,0 +1,5 @@ +# A collection of updates that change the behaviour + +## Lazy loading and asynchronisity + +- Invalid dates are rendered as syntax error instead of returning best guess or the current date diff --git a/__mocks__/d3.ts b/__mocks__/d3.ts index 67f09b6f4..f90d93557 100644 --- a/__mocks__/d3.ts +++ b/__mocks__/d3.ts @@ -53,6 +53,18 @@ export const MockD3 = (name, parent) => { get __parent() { return parent; }, + node() { + return { + getBBox() { + return { + x: 5, + y: 10, + height: 15, + width: 20, + }; + }, + }; + }, }; elem.append = (name) => { const mockElem = MockD3(name, elem); diff --git a/__mocks__/dagre-d3.ts b/__mocks__/dagre-d3.ts index a1a677591..bf6d341dc 100644 --- a/__mocks__/dagre-d3.ts +++ b/__mocks__/dagre-d3.ts @@ -1,3 +1 @@ -import { vi } from 'vitest'; - -// export const render = vi.fn(); +// DO NOT delete this file. It is used by vitest to mock the dagre-d3 module. diff --git a/applitools.config.js b/applitools.config.js index 1c0607868..4cf02220a 100644 --- a/applitools.config.js +++ b/applitools.config.js @@ -15,5 +15,5 @@ module.exports = defineConfig({ // { deviceName: 'Pixel 2', screenOrientation: 'portrait' }, ], // set batch name to the configuration - batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`, + // batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`, }); diff --git a/cSpell.json b/cSpell.json new file mode 100644 index 000000000..64187e1ca --- /dev/null +++ b/cSpell.json @@ -0,0 +1,132 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + "acyclicer", + "adamiecki", + "alois", + "antiscript", + "applitools", + "asciidoctor", + "ashish", + "astah", + "bbox", + "bilkent", + "bisheng", + "braintree", + "brolin", + "brotli", + "classdef", + "codedoc", + "colour", + "cpettitt", + "customizability", + "cuzon", + "cytoscape", + "dagre", + "descr", + "docsify", + "docsy", + "doku", + "dompurify", + "edgechromium", + "faber", + "flatmap", + "ftplugin", + "gantt", + "gitea", + "gitgraph", + "globby", + "graphlib", + "grav", + "greywolf", + "inkdrop", + "jaoude", + "jison", + "kaufmann", + "khroma", + "klemm", + "klink", + "knsv", + "knut", + "laganeckas", + "lintstagedrc", + "lucida", + "matthieu", + "mdbook", + "mermerd", + "mindaugas", + "mindmap", + "mindmaps", + "mitigations", + "mkdocs", + "orlandoni", + "phpbb", + "plantuml", + "playfair", + "podlite", + "ranksep", + "redmine", + "sandboxed", + "setupgraphviewbox", + "shiki", + "sidharth", + "sphinxcontrib", + "statediagram", + "stylis", + "substate", + "sveidqvist", + "techn", + "treemap", + "ts-nocheck", + "tuleap", + "unist", + "verdana", + "viewports", + "vinod", + "visio", + "vitepress", + "xlink", + "yash" + ], + "patterns": [ + { "name": "Markdown links", "pattern": "\\((.*)\\)", "description": "" }, + { + "name": "Markdown code blocks", + "pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx", + "description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions" + }, + { + "name": "Inline code blocks", + "pattern": "\\`([^\\`\\r\\n]+?)\\`", + "description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex" + }, + { "name": "Link contents", "pattern": "\\", "description": "" }, + { "name": "Snippet references", "pattern": "-- snippet:(.*)", "description": "" }, + { + "name": "Snippet references 2", + "pattern": "\\<\\[sample:(.*)", + "description": "another kind of snippet reference" + }, + { "name": "Multi-line code blocks", "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" }, + { + "name": "HTML Tags", + "pattern": "<[^>]*>", + "description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string" + } + ], + "ignoreRegExpList": [ + "Markdown links", + "Markdown code blocks", + "Inline code blocks", + "Link contents", + "Snippet references", + "Snippet references 2", + "Multi-line code blocks", + "HTML Tags" + ], + "ignorePaths": [ + "packages/mermaid/src/docs/CHANGELOG.md", + "packages/mermaid/src/docs/.vitepress/redirect.ts" + ] +} diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js index bee9a59f0..5213f634a 100644 --- a/cypress/helpers/util.js +++ b/cypress/helpers/util.js @@ -2,6 +2,8 @@ const utf8ToB64 = (str) => { return window.btoa(unescape(encodeURIComponent(str))); }; +const batchId = 'mermid-batch' + new Date().getTime(); + export const mermaidUrl = (graphStr, options, api) => { const obj = { code: graphStr, @@ -45,26 +47,32 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) => options.fontSize = '16px'; } const useAppli = Cypress.env('useAppli'); - //const useAppli = false; cy.log('Hello ' + useAppli ? 'Appli' : 'image-snapshot'); const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); if (useAppli) { + cy.log('Opening eyes ' + Cypress.spec.name + ' --- ' + name); cy.eyesOpen({ appName: 'Mermaid', testName: name, + batchName: Cypress.spec.name, + batchId: batchId + Cypress.spec.name, }); } const url = mermaidUrl(graphStr, options, api); cy.visit(url); - if (validation) cy.get('svg').should(validation); + if (validation) { + cy.get('svg').should(validation); + } cy.get('svg'); // Default name to test title if (useAppli) { + cy.log('Check eyes' + Cypress.spec.name); cy.eyesCheckWindow('Click!'); + cy.log('Closing eyes: ' + Cypress.spec.name); cy.eyesClose(); } else { cy.matchImageSnapshot(name); @@ -100,19 +108,26 @@ export const urlSnapshotTest = (url, _options, api = false, validation) => { const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); if (useAppli) { + cy.log('Opening eyes 2' + Cypress.spec.name); cy.eyesOpen({ appName: 'Mermaid', testName: name, + batchName: Cypress.spec.name, + batchId: batchId + Cypress.spec.name, }); } cy.visit(url); - if (validation) cy.get('svg').should(validation); + if (validation) { + cy.get('svg').should(validation); + } cy.get('body'); // Default name to test title if (useAppli) { + cy.log('Check eyes 2' + Cypress.spec.name); cy.eyesCheckWindow('Click!'); + cy.log('Closing eyes 2' + Cypress.spec.name); cy.eyesClose(); } else { cy.matchImageSnapshot(name); diff --git a/cypress/integration/other/external-diagrams.spec.js b/cypress/integration/other/external-diagrams.spec.js new file mode 100644 index 000000000..3a6c37e88 --- /dev/null +++ b/cypress/integration/other/external-diagrams.spec.js @@ -0,0 +1,13 @@ +describe('mermaid', () => { + describe('registerDiagram', () => { + it('should work on @mermaid-js/mermaid-mindmap and mermaid-example-diagram', () => { + const url = 'http://localhost:9000/external-diagrams-mindmap.html'; + cy.visit(url); + + cy.get('svg', { + // may be a bit slower than normal, since vite might need to re-compile mermaid/mermaid-mindmap/mermaid-example-diagram + timeout: 10000, + }).matchImageSnapshot(); + }); + }); +}); diff --git a/cypress/integration/other/interaction.spec.js b/cypress/integration/other/interaction.spec.js index b253d0389..857141b5b 100644 --- a/cypress/integration/other/interaction.spec.js +++ b/cypress/integration/other/interaction.spec.js @@ -1,266 +1,180 @@ describe('Interaction', () => { - describe('Interaction - security level loose', () => { - it('Graph: should handle a click on a node with a bound function', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-Function-4').click(); + describe('Security level loose', () => { + beforeEach(() => { + cy.visit('http://localhost:9000/click_security_loose.html'); + }); + it('Graph: should handle a click on a node with a bound function', () => { + cy.contains('FunctionTest1').parents('.node').click(); cy.get('.created-by-click').should('have.text', 'Clicked By Flow'); }); + it('Graph: should handle a click on a node with a bound function with args', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-FunctionArg-28').click(); - + cy.contains('FunctionArgTest2').parents('.node').click(); cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT'); }); + it('Flowchart: should handle a click on a node with a bound function where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-FunctionArg-34"]').click(); - + cy.contains('2FunctionArg').parents('.node').click(); cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT'); }); - it('Graph: should handle a click on a node with a bound url', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('#flowchart-URL-5').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('Graph: should handle a click on a node with a bound url', () => { + // When there is a URL, cy.contains selects the a tag instead of the span. The .node is a child of a, so we have to use find instead of parent. + cy.contains('URLTest1').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); - it('Graph: should handle a click on a node with a bound url where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-2URL-11"]').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('Graph: should handle a click on a node with a bound url where the node starts with a number', () => { + cy.contains('2URL').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); it('Flowchart-v2: should handle a click on a node with a bound function', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-Function-16').click(); - + cy.contains('FunctionTest2').parents('.node').click(); cy.get('.created-by-click').should('have.text', 'Clicked By Flow'); }); + it('Flowchart-v2: should handle a click on a node with a bound function where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-1Function-22"]').click(); - + cy.contains('10Function').parents('.node').click(); cy.get('.created-by-click').should('have.text', 'Clicked By Flow'); }); - it('Flowchart-v2: should handle a click on a node with a bound url', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('#flowchart-URL-17').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('Flowchart-v2: should handle a click on a node with a bound url', () => { + cy.contains('URLTest2').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); - it('Flowchart-v2: should handle a click on a node with a bound url where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-2URL-23"]').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('Flowchart-v2: should handle a click on a node with a bound url where the node starts with a number', () => { + cy.contains('20URL').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); it('should handle a click on a task with a bound URL clicking on the rect', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl1').click({ force: true }); - - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + cy.get('rect#cl1').click({ force: true }); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); + it('should handle a click on a task with a bound URL clicking on the text', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl1-text').click({ force: true }); - - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + cy.get('text#cl1-text').click({ force: true }); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); - it('should handle a click on a task with a bound function without args', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl2').click({ force: true }); + it('should handle a click on a task with a bound function without args', () => { + cy.get('rect#cl2').click({ force: true }); cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2'); }); - it('should handle a click on a task with a bound function with args', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl3').click({ force: true }); + it('should handle a click on a task with a bound function with args', () => { + cy.get('rect#cl3').click({ force: true }); cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3'); }); it('should handle a click on a task with a bound function without args', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl2-text').click({ force: true }); - + cy.get('text#cl2-text').click({ force: true }); cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2'); }); - it('should handle a click on a task with a bound function with args ', () => { - const url = 'http://localhost:9000/click_security_loose.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl3-text').click({ force: true }); + it('should handle a click on a task with a bound function with args ', () => { + cy.get('text#cl3-text').click({ force: true }); cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3'); }); }); describe('Interaction - security level tight', () => { + beforeEach(() => { + cy.visit('http://localhost:9000/click_security_strict.html'); + }); it('should handle a click on a node without a bound function', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-Function-4').click(); - + cy.contains('Function1').parents('.node').click(); cy.get('.created-by-click').should('not.exist'); - // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow'); }); + it('should handle a click on a node with a bound function where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-1Function-10"]').click(); - - // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow'); + cy.contains('1Function').parents('.node').click(); cy.get('.created-by-click').should('not.exist'); }); - it('should handle a click on a node with a bound url', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-URL-5').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('should handle a click on a node with a bound url', () => { + cy.contains('URL1').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); - it('should handle a click on a node with a bound url where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-2URL-11"]').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('should handle a click on a node with a bound url where the node starts with a number', () => { + cy.contains('2URL').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); it('should handle a click on a task with a bound URL clicking on the rect', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl1').click({ force: true }); - - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + cy.get('rect#cl1').click({ force: true }); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); + it('should handle a click on a task with a bound URL clicking on the text', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl1-text').click({ force: true }); - - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + cy.get('text#cl1-text').click({ force: true }); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); - it('should handle a click on a task with a bound function', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl2').click({ force: true }); - // cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2'); + it('should handle a click on a task with a bound function', () => { + cy.get('rect#cl2').click({ force: true }); cy.get('.created-by-gant-click').should('not.exist'); }); - it('should handle a click on a task with a bound function', () => { - const url = 'http://localhost:9000/click_security_strict.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl2-text').click({ force: true }); - // cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2'); + it('should handle a click on a task with a bound function', () => { + cy.get('text#cl2-text').click({ force: true }); cy.get('.created-by-gant-click').should('not.exist'); }); }); describe('Interaction - security level other, missspelling', () => { + beforeEach(() => { + cy.visit('http://localhost:9000/click_security_other.html'); + }); + it('should handle a click on a node with a bound function', () => { - const url = 'http://localhost:9000/click_security_other.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-Function-4').click(); - - // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow'); + cy.contains('Function1').parents('.node').click(); cy.get('.created-by-click').should('not.exist'); }); + it('should handle a click on a node with a bound function where the node starts with a number', () => { - const url = 'http://localhost:9000/click_security_other.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g[id="flowchart-1Function-10"]').click(); - - cy.get('.created-by-click').should('not.exist'); + cy.contains('1Function').parents('.node').click(); cy.get('.created-by-click').should('not.exist'); }); - it('should handle a click on a node with a bound url', () => { - const url = 'http://localhost:9000/click_security_other.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('g#flowchart-URL-5').click(); - cy.location().should((location) => { - expect(location.href).to.eq('http://localhost:9000/webpackUsage.html'); + it('should handle a click on a node with a bound url', () => { + cy.contains('URL1').find('.node').click(); + cy.location().should(({ href }) => { + expect(href).to.eq('http://localhost:9000/empty.html'); }); }); it('should handle a click on a task with a bound function', () => { - const url = 'http://localhost:9000/click_security_other.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('rect#cl2').click({ force: true }); - + cy.get('rect#cl2').click({ force: true }); cy.get('.created-by-gant-click').should('not.exist'); }); - it('should handle a click on a task with a bound function', () => { - const url = 'http://localhost:9000/click_security_other.html'; - cy.viewport(1440, 1024); - cy.visit(url); - cy.get('body').find('text#cl2-text').click({ force: true }); + it('should handle a click on a task with a bound function', () => { + cy.get('text#cl2-text').click({ force: true }); cy.get('.created-by-gant-click').should('not.exist'); }); }); diff --git a/cypress/integration/rendering/appli.spec.js b/cypress/integration/rendering/appli.spec.js index d6a83eb8b..462fe869c 100644 --- a/cypress/integration/rendering/appli.spec.js +++ b/cypress/integration/rendering/appli.spec.js @@ -21,7 +21,7 @@ describe('Git Graph diagram', () => { // // Call Open on eyes to initialize a test session // cy.eyesOpen({ // appName: 'Demo App', - // testName: 'Ultrafast grid demo', + // testName: 'UltraFast grid demo', // }); // // check the login page with fluent api, see more info here diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index d285a9237..f97458857 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -478,4 +478,34 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); + + it('18: should render a simple class diagram with notes', () => { + imgSnapshotTest( + ` + classDiagram-v2 + note "I love this diagram!\nDo you love it?" + class Class10 { + <> + int id + size() + } + note for Class10 "Cool class\nI said it's very cool class!" + + `, + { logLevel: 1, flowchart: { htmlLabels: false } } + ); + cy.get('svg'); + }); + + it('1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- +title: simple class diagram +--- +classDiagram-v2 +class Class10 +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index 8cf410d05..16601652d 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -407,4 +407,21 @@ describe('Class diagram', () => { // // expect(svg).to.not.have.attr('style'); // }); // }); + + it('19: should render a simple class diagram with notes', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + class Class10 { + <> + int id + size() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1 } + ); + cy.get('svg'); + }); }); diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 0f9084e7c..8e8946170 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -167,7 +167,7 @@ describe('Entity Relationship Diagram', () => { cy.get('svg'); }); - it.only('should render entities with generic and array attributes', () => { + it('should render entities with generic and array attributes', () => { renderGraph( ` erDiagram @@ -255,4 +255,35 @@ describe('Entity Relationship Diagram', () => { ); cy.get('svg'); }); + + it('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 + `, + { logLevel: 1 } + ); + cy.get('svg'); + }); + + it('1433: should render a simple ER diagram with a title', () => { + imgSnapshotTest( + `--- +title: simple ER diagram +--- +erDiagram +CUSTOMER ||--o{ ORDER : places +ORDER ||--|{ LINE-ITEM : contains +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 61dccfb84..30ae4f0d2 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -663,4 +663,15 @@ flowchart RL { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); + it('1433: should render a titled flowchart with titleTopMargin set to 0', () => { + imgSnapshotTest( + `--- +title: Simple flowchart +--- +flowchart TD +A --> B +`, + { titleTopMargin: 0 } + ); + }); }); diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 438b80267..325cca065 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -92,7 +92,7 @@ describe('Gantt diagram', () => { {} ); }); - it('should render a gantt chart for issue #1060', () => { + it('should FAIL redering a gantt chart for issue #1060 with invalid date', () => { imgSnapshotTest( ` gantt @@ -326,7 +326,7 @@ describe('Gantt diagram', () => { ); cy.get('svg').should((svg) => { const el = svg.get(0); - const children = Array.from(el.children); + const children = [...el.children]; const titleEl = children.find(function (node) { return node.tagName === 'title'; @@ -341,4 +341,130 @@ describe('Gantt diagram', () => { expect(descriptionEl.textContent).to.equal(expectedAccDescription); }); }); + + it('should render a gantt diagram with tick is 15 minutes', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %H:%M + tickInterval 15minute + excludes weekends + + section Section + A task : a1, 2022-10-03, 6h + Another task : after a1, 6h + section Another + Task in sec : 2022-10-03, 3h + another task : 3h + `, + {} + ); + }); + + it('should render a gantt diagram with tick is 6 hours', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %d %H:%M + tickInterval 6hour + excludes weekends + + section Section + A task : a1, 2022-10-03, 1d + Another task : after a1, 2d + section Another + Task in sec : 2022-10-04, 2d + another task : 2d + `, + {} + ); + }); + + it('should render a gantt diagram with tick is 1 day', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %m-%d + tickInterval 1day + excludes weekends + + section Section + A task : a1, 2022-10-01, 30d + Another task : after a1, 20d + section Another + Task in sec : 2022-10-20, 12d + another task : 24d + `, + {} + ); + }); + + it('should render a gantt diagram with tick is 1 week', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %m-%d + tickInterval 1week + excludes weekends + + section Section + A task : a1, 2022-10-01, 30d + Another task : after a1, 20d + section Another + Task in sec : 2022-10-20, 12d + another task : 24d + `, + {} + ); + }); + + it('should render a gantt diagram with tick is 1 month', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %m-%d + tickInterval 1month + excludes weekends + + section Section + A task : a1, 2022-10-01, 30d + Another task : after a1, 20d + section Another + Task in sec : 2022-10-20, 12d + another task : 24d + `, + {} + ); + }); + + it('should render a gantt diagram with tick is 1 day and topAxis is true', () => { + imgSnapshotTest( + ` + gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + axisFormat %m-%d + tickInterval 1day + excludes weekends + + section Section + A task : a1, 2022-10-01, 30d + Another task : after a1, 20d + section Another + Task in sec : 2022-10-20, 12d + another task : 24d + `, + { gantt: { topAxis: true } } + ); + }); }); diff --git a/cypress/integration/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js index afb39b62e..43f91a983 100644 --- a/cypress/integration/rendering/gitGraph.spec.js +++ b/cypress/integration/rendering/gitGraph.spec.js @@ -322,4 +322,15 @@ describe('Git Graph diagram', () => { {} ); }); + it('1433: should render a simple gitgraph with a title', () => { + imgSnapshotTest( + `--- +title: simple gitGraph +--- +gitGraph + commit id: "1-abcdefg" +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/mermaid.spec.js b/cypress/integration/rendering/mermaid.spec.js deleted file mode 100644 index 4b7de3027..000000000 --- a/cypress/integration/rendering/mermaid.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; - -describe('Mindmap', () => { - it('square shape', () => { - imgSnapshotTest( - ` -mindmap - root[ - The root - ] - `, - {} - ); - cy.get('svg'); - }); - it('rounded rect shape', () => { - imgSnapshotTest( - ` -mindmap - root(( - The root - )) - `, - {} - ); - cy.get('svg'); - }); - it('circle shape', () => { - imgSnapshotTest( - ` -mindmap - root( - The root - ) - `, - {} - ); - cy.get('svg'); - }); - it('default shape', () => { - imgSnapshotTest( - ` -mindmap - The root - `, - {} - ); - cy.get('svg'); - }); - it('adding children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - `, - {} - ); - cy.get('svg'); - }); - it('adding grand children', () => { - imgSnapshotTest( - ` -mindmap - The root - child1 - child2 - child3 - `, - {} - ); - cy.get('svg'); - }); -}); diff --git a/cypress/integration/rendering/mindmap.spec.js b/cypress/integration/rendering/mindmap.spec.js deleted file mode 100644 index f0cc2bc3f..000000000 --- a/cypress/integration/rendering/mindmap.spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; - -describe('Mindmaps', () => { - it('Only a root', () => { - imgSnapshotTest( - `mindmap -root - `, - {} - ); - }); - - it('a root with a shape', () => { - imgSnapshotTest( - `mindmap -root[root] - `, - {} - ); - }); - - it('a root with wrapping text and a shape', () => { - imgSnapshotTest( - `mindmap -root[A root with a long text that wraps to keep the node size in check] - `, - {} - ); - }); - - it('a root with an icon', () => { - imgSnapshotTest( - `mindmap -root[root] -::icon(mdi mdi-fire) - `, - {} - ); - }); - - it('Blang and cloud shape', () => { - imgSnapshotTest( - `mindmap -root))bang(( - ::icon(mdi mdi-fire) - a))Another bang(( - ::icon(mdi mdi-fire) - a)A cloud( - ::icon(mdi mdi-fire) - `, - {} - ); - }); - - it('Blang and cloud shape with icons', () => { - imgSnapshotTest( - `mindmap -root))bang(( - - a))Another bang(( - a)A cloud( - `, - {} - ); - }); - - it('braches', () => { - imgSnapshotTest( - `mindmap -root - child1 - grandchild 1 - grandchild 2 - child2 - grandchild 3 - grandchild 4 - child3 - grandchild 5 - grandchild 6 - `, - {} - ); - }); - - it('braches with shapes and labels', () => { - imgSnapshotTest( - `mindmap -root - child1((Circle)) - grandchild 1 - grandchild 2 - child2(Round rectangle) - grandchild 3 - grandchild 4 - child3[Square] - grandchild 5 - ::icon(mdi mdi-fire) - gc6((grand
child 6)) - ::icon(mdi mdi-fire) - `, - {} - ); - }); - it('text shouhld wrap with icon', () => { - imgSnapshotTest( - `mindmap -root - Child3(A node with an icon and with a long text that wraps to keep the node size in check) - `, - {} - ); - }); - - /* The end */ -}); diff --git a/cypress/integration/rendering/mindmap.spec.ts b/cypress/integration/rendering/mindmap.spec.ts new file mode 100644 index 000000000..62c7e785b --- /dev/null +++ b/cypress/integration/rendering/mindmap.spec.ts @@ -0,0 +1,233 @@ +import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; + +/** + * Check whether the SVG Element has a Mindmap root + * + * Sometimes, Cypress takes a snapshot before the mermaid mindmap has finished + * generating the SVG. + * + * @param $p - The element to check. + */ +function shouldHaveRoot($p: JQuery) { + // get HTML Element from jquery element + const svgElement = $p[0]; + expect(svgElement.nodeName).equal('svg'); + + const sectionRoots = svgElement.getElementsByClassName('mindmap-node section-root'); + // mindmap should have at least one root section + expect(sectionRoots).to.have.lengthOf.at.least(1); +} + +describe('Mindmaps', () => { + it('Only a root', () => { + imgSnapshotTest( + `mindmap +root + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with a shape', () => { + imgSnapshotTest( + `mindmap +root[root] + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with wrapping text and a shape', () => { + imgSnapshotTest( + `mindmap +root[A root with a long text that wraps to keep the node size in check] + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('a root with an icon', () => { + imgSnapshotTest( + `mindmap +root[root] +::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('Blang and cloud shape', () => { + imgSnapshotTest( + `mindmap +root))bang(( + ::icon(mdi mdi-fire) + a))Another bang(( + ::icon(mdi mdi-fire) + a)A cloud( + ::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('Blang and cloud shape with icons', () => { + imgSnapshotTest( + `mindmap +root))bang(( + + a))Another bang(( + a)A cloud( + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('braches', () => { + imgSnapshotTest( + `mindmap +root + child1 + grandchild 1 + grandchild 2 + child2 + grandchild 3 + grandchild 4 + child3 + grandchild 5 + grandchild 6 + `, + {}, + undefined, + shouldHaveRoot + ); + }); + + it('braches with shapes and labels', () => { + imgSnapshotTest( + `mindmap +root + child1((Circle)) + grandchild 1 + grandchild 2 + child2(Round rectangle) + grandchild 3 + grandchild 4 + child3[Square] + grandchild 5 + ::icon(mdi mdi-fire) + gc6((grand
child 6)) + ::icon(mdi mdi-fire) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + it('text shouhld wrap with icon', () => { + imgSnapshotTest( + `mindmap +root + Child3(A node with an icon and with a long text that wraps to keep the node size in check) + `, + {}, + undefined, + shouldHaveRoot + ); + }); + it('square shape', () => { + imgSnapshotTest( + ` +mindmap + root[ + The root + ] + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('rounded rect shape', () => { + imgSnapshotTest( + ` +mindmap + root(( + The root + )) + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('circle shape', () => { + imgSnapshotTest( + ` +mindmap + root( + The root + ) + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('default shape', () => { + imgSnapshotTest( + ` +mindmap + The root + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('adding children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + it('adding grand children', () => { + imgSnapshotTest( + ` +mindmap + The root + child1 + child2 + child3 + `, + {}, + undefined, + shouldHaveRoot + ); + cy.get('svg'); + }); + /* The end */ +}); diff --git a/cypress/integration/rendering/requirement.spec.js b/cypress/integration/rendering/requirement.spec.js index be27f39fa..8a8d188ff 100644 --- a/cypress/integration/rendering/requirement.spec.js +++ b/cypress/integration/rendering/requirement.spec.js @@ -96,7 +96,7 @@ describe('Requirement diagram', () => { ); cy.get('svg').should((svg) => { const el = svg.get(0); - const children = Array.from(el.children); + const children = [...el.children]; const titleEl = children.find(function (node) { return node.tagName === 'title'; diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index aa2bc06ef..0eca01873 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -521,4 +521,54 @@ stateDiagram-v2 { logLevel: 0, fontFamily: 'courier' } ); }); + + describe('classDefs and applying classes', () => { + it('v2 states can have a class applied', () => { + imgSnapshotTest( + ` + stateDiagram-v2 + [*] --> A + A --> B: test({ foo#colon; 'far' }) + B --> [*] + classDef badBadEvent fill:#f00,color:white,font-weight:bold + class B badBadEvent + `, + { logLevel: 0, fontFamily: 'courier' } + ); + }); + it('v2 can have multiple classes applied to multiple states', () => { + imgSnapshotTest( + ` + stateDiagram-v2 + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold + + [*] --> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + `, + { logLevel: 0, fontFamily: 'courier' } + ); + }); + }); + it('1433: should render a simple state diagram with a title', () => { + imgSnapshotTest( + `--- +title: simple state diagram +--- +stateDiagram-v2 +[*] --> State1 +State1 --> [*] +`, + {} + ); + }); }); diff --git a/cypress/integration/rendering/theme.spec.js b/cypress/integration/rendering/theme.spec.js index 0eb8d111b..ef3bd9a4b 100644 --- a/cypress/integration/rendering/theme.spec.js +++ b/cypress/integration/rendering/theme.spec.js @@ -25,6 +25,7 @@ describe('themeCSS balancing, it', () => { }); }); +// TODO: Delete/Rename this describe, keeping the inner contents. describe('Pie Chart', () => { // beforeEach(()=>{ // cy.clock((new Date('2014-06-09')).getTime()); diff --git a/cypress/platform/click_security_loose.html b/cypress/platform/click_security_loose.html index 6c77e90af..459c14e85 100644 --- a/cypress/platform/click_security_loose.html +++ b/cypress/platform/click_security_loose.html @@ -13,42 +13,42 @@
-
+      
     graph TB
-      Function-->URL
-      click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+      FunctionTest1-->URLTest1
+      click FunctionTest1 clickByFlow "Add a div"
+      click URLTest1 "http://localhost:9000/empty.html" "Visit mermaid docs"
       
-
+      
   graph TB
     1Function--->2URL
     click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+    click 2URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
-
+      
     flowchart TB
-      Function-->URL
-      click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs" _self
+      FunctionTest2-->URLTest2
+      click FunctionTest2 clickByFlow "Add a div"
+      click URLTest2 "http://localhost:9000/empty.html" "Visit mermaid docs" _self
       
-
+      
   flowchart TB
-    1Function--->2URL
-    click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs" _self
+    10Function--->20URL
+    click 10Function clickByFlow "Add a div"
+    click 20URL "http://localhost:9000/empty.html" "Visit mermaid docs" _self
       
-
+      
   classDiagram
     class ShapeLink
-    link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+    link ShapeLink "http://localhost:9000/empty.html" "This is a tooltip for a link"
     class ShapeCallback
     callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
       
-
+      
   classDiagram-v2
     class ShapeLink2
-    link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+    link ShapeLink2 "http://localhost:9000/empty.html" "This is a tooltip for a link"
     class ShapeCallback2
     callback ShapeCallback2 "clickByClass" "This is a tooltip for a callback"
       
@@ -85,7 +85,7 @@ Calling a Callback (look at the console log) :cl2, after cl1, 3d Calling a Callback with args :cl3, after cl1, 3d - click cl1 href "http://localhost:9000/webpackUsage.html" + click cl1 href "http://localhost:9000/empty.html" click cl2 call clickByGantt() click cl3 call clickByGantt("test1", test2, test3) @@ -95,31 +95,31 @@ Add another diagram to demo page : 48h
-
+      
       graph TB
-        FunctionArg-->URL
-        click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
-        click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+        FunctionArgTest2-->URL
+        click FunctionArgTest2 call clickByFlowArg(ARGUMENT) "Add a div"
+        click URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
-
+      
       flowchart TB
-        FunctionArg-->URL
-        click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
-        click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+        2FunctionArg-->URL
+        click 2FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
+        click URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
-
+      
       classDiagram
       class ShapeLink
-      link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+      link ShapeLink "http://localhost:9000/empty.html" "This is a tooltip for a link"
       class ShapeCallback
       click ShapeCallback call clickByClass(123) "This is a tooltip for a callback"
       
-
+      
       classDiagram-v2
         class ShapeLink2
-        link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+        link ShapeLink2 "http://localhost:9000/empty.html" "This is a tooltip for a link"
         class ShapeCallback2
         click ShapeCallback2 call clickByClass(123) "This is a tooltip for a callback"
       
diff --git a/cypress/platform/click_security_other.html b/cypress/platform/click_security_other.html index 20bfd5293..5338cac06 100644 --- a/cypress/platform/click_security_other.html +++ b/cypress/platform/click_security_other.html @@ -9,15 +9,15 @@
     graph TB
-      Function-->URL
-      click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+      Function1-->URL1
+      click Function1 clickByFlow "Add a div"
+      click URL1 "http://localhost:9000/empty.html" "Visit mermaid docs"
     
   graph TB
     1Function-->2URL
     click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+    click 2URL "http://localhost:9000/empty.html" "Visit mermaid docs"
     
@@ -50,7 +50,7 @@
     Visit mermaidjs               :active, cl1, 2014-01-07,2014-01-10
     Calling a Callback (look at the console log) :cl2, after cl1, 3d
 
-    click cl1 href "http://localhost:9000/webpackUsage.html"
+    click cl1 href "http://localhost:9000/empty.html"
     click cl2 call clickByGantt("test", test, test)
 
     section Last section
diff --git a/cypress/platform/click_security_sandbox.html b/cypress/platform/click_security_sandbox.html
index 94229500c..49c5d71c0 100644
--- a/cypress/platform/click_security_sandbox.html
+++ b/cypress/platform/click_security_sandbox.html
@@ -17,38 +17,38 @@
     graph TB
       Function-->URL
       click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+      click URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
   graph TB
     1Function--->2URL
     click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+    click 2URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
     flowchart TB
       Function-->URL
       click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs" _self
+      click URL "http://localhost:9000/empty.html" "Visit mermaid docs" _self
       
   flowchart TB
     1Function--->2URL
     click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs" _self
+    click 2URL "http://localhost:9000/empty.html" "Visit mermaid docs" _self
       
   classDiagram
     class ShapeLink
-    link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+    link ShapeLink "http://localhost:9000/empty.html" "This is a tooltip for a link"
     class ShapeCallback
     callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
       
   classDiagram-v2
     class ShapeLink2
-    link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+    link ShapeLink2 "http://localhost:9000/empty.html" "This is a tooltip for a link"
     class ShapeCallback2
     callback ShapeCallback2 "clickByClass" "This is a tooltip for a callback"
       
@@ -85,7 +85,7 @@ Calling a Callback (look at the console log) :cl2, after cl1, 3d Calling a Callback with args :cl3, after cl1, 3d - click cl1 href "http://localhost:9000/webpackUsage.html" + click cl1 href "http://localhost:9000/empty.html" click cl2 call clickByGantt() click cl3 call clickByGantt("test1", test2, test3) @@ -99,19 +99,19 @@ graph TB FunctionArg-->URL click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div" - click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs" + click URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       flowchart TB
         FunctionArg-->URL
         click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
-        click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+        click URL "http://localhost:9000/empty.html" "Visit mermaid docs"
       
       classDiagram
       class ShapeLink
-      link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+      link ShapeLink "http://localhost:9000/empty.html" "This is a tooltip for a link"
       class ShapeCallback
       click ShapeCallback call clickByClass(123) "This is a tooltip for a callback"
       
@@ -119,7 +119,7 @@
       classDiagram-v2
         class ShapeLink2
-        link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
+        link ShapeLink2 "http://localhost:9000/empty.html" "This is a tooltip for a link"
         class ShapeCallback2
         click ShapeCallback2 call clickByClass(123) "This is a tooltip for a callback"
       
diff --git a/cypress/platform/click_security_strict.html b/cypress/platform/click_security_strict.html index 00c6d9c6a..26605ddf9 100644 --- a/cypress/platform/click_security_strict.html +++ b/cypress/platform/click_security_strict.html @@ -9,15 +9,15 @@
     graph TB
-      Function-->URL
-      click Function clickByFlow "Add a div"
-      click URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+      Function1-->URL1
+      click Function1 clickByFlow "Add a div"
+      click URL1 "http://localhost:9000/empty.html" "Visit mermaid docs"
     
   graph TB
     1Function-->2URL
     click 1Function clickByFlow "Add a div"
-    click 2URL "http://localhost:9000/webpackUsage.html" "Visit mermaid docs"
+    click 2URL "http://localhost:9000/empty.html" "Visit mermaid docs"
     
@@ -51,7 +51,7 @@
     Calling a Callback (look at the console log) :cl2, after cl1, 3d
     Calling a Callback with args :cl3, after cl1, 3d
 
-    click cl1 href "http://localhost:9000/webpackUsage.html"
+    click cl1 href "http://localhost:9000/empty.html"
     click cl2 call clickByGantt()
     click cl3 call clickByGantt("test1", test2, test3)
 
diff --git a/cypress/platform/empty.html b/cypress/platform/empty.html
new file mode 100644
index 000000000..2961644d6
--- /dev/null
+++ b/cypress/platform/empty.html
@@ -0,0 +1,10 @@
+
+
+  
+    
+    
+    
+    Empty
+  
+  
+
diff --git a/cypress/platform/external-diagrams-mindmap.html b/cypress/platform/external-diagrams-mindmap.html
new file mode 100644
index 000000000..e5eded4ba
--- /dev/null
+++ b/cypress/platform/external-diagrams-mindmap.html
@@ -0,0 +1,49 @@
+
+  
+    

Should correctly load a third-party diagram using registerDiagram

+
+mindmap
+  root
+    A
+    B
+    C
+    D
+    E
+    A2
+    B2
+    C2
+    D2
+    E2
+    child1((Circle))
+        grandchild 1
+        grandchild 2
+    child2(Round rectangle)
+        grandchild 3
+        grandchild 4
+    child3[Square]
+        grandchild 5
+        ::icon(mdi mdi-fire)
+        gc6((grand
child 6)) + ::icon(mdi mdi-fire) + gc7((grand
grand
child 8)) +
+ + + + + + + + + + diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index 1a58420ef..f6ee1ef03 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -6,6 +6,10 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> + -
+    
 flowchart LR
   subgraph one
     direction LR
@@ -364,8 +368,7 @@ flowchart TD
     
- - + - - - diff --git a/cypress/platform/render-after-error.html b/cypress/platform/render-after-error.html index 267ffade1..f5165e0ee 100644 --- a/cypress/platform/render-after-error.html +++ b/cypress/platform/render-after-error.html @@ -14,7 +14,6 @@ mermaid.init({ startOnLoad: false }); mermaid.mermaidAPI.initialize({ securityLevel: 'strict' }); - try { console.log('rendering'); mermaid.mermaidAPI.render('graphDiv', `>`); diff --git a/cypress/platform/rerender.html b/cypress/platform/rerender.html index 9b6cb130e..ab1b8e009 100644 --- a/cypress/platform/rerender.html +++ b/cypress/platform/rerender.html @@ -17,9 +17,9 @@ rerender('XMas'); function rerender(text) { - var graphText = `graph TD + const graphText = `graph TD A[${text}] -->|Get money| B(Go shopping)`; - var graph = mermaid.mermaidAPI.render('id', graphText); + const graph = mermaid.mermaidAPI.render('id', graphText); console.log('\x1b[35m%s\x1b[0m', '>> graph', graph); document.getElementById('graph').innerHTML = graph; } diff --git a/cypress/platform/sidv.html b/cypress/platform/sidv.html new file mode 100644 index 000000000..c9bf56b7d --- /dev/null +++ b/cypress/platform/sidv.html @@ -0,0 +1,14 @@ + + +
+    none
+    hello world
+    
+ + + + diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js index 8f1ccfdab..c06976e97 100644 --- a/cypress/platform/viewer.js +++ b/cypress/platform/viewer.js @@ -1,4 +1,5 @@ import mermaid2 from '../../packages/mermaid/src/mermaid'; +import mindmap from '../../packages/mermaid-mindmap/src/detector'; function b64ToUtf8(str) { return decodeURIComponent(escape(window.atob(str))); @@ -9,7 +10,7 @@ function b64ToUtf8(str) { * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the * page. */ -const contentLoaded = function () { +const contentLoaded = async function () { let pos = document.location.href.indexOf('?graph='); if (pos > 0) { pos = pos + 7; @@ -36,6 +37,7 @@ const contentLoaded = function () { document.getElementsByTagName('body')[0].appendChild(div); } + await mermaid2.registerExternalDiagrams([mindmap]); mermaid2.initialize(graphObj.mermaid); mermaid2.init(); } @@ -52,7 +54,7 @@ function merge(current, update) { if ( current.hasOwnProperty(key) && typeof current[key] === 'object' && - !(current[key] instanceof Array) + !Array.isArray(current[key]) ) { merge(current[key], update[key]); @@ -118,7 +120,9 @@ const contentLoadedApi = function () { (svgCode, bindFunctions) => { div.innerHTML = svgCode; - if (bindFunctions) bindFunctions(div); + if (bindFunctions) { + bindFunctions(div); + } }, div ); diff --git a/cypress/platform/xss10.html b/cypress/platform/xss10.html index 6a027f514..b39728c84 100644 --- a/cypress/platform/xss10.html +++ b/cypress/platform/xss10.html @@ -93,7 +93,7 @@ throw new Error('XSS Succeeded'); } - var diagram = 'classDiagram\n'; + let diagram = 'classDiagram\n'; diagram += 'class Square~" <--> "" C2: Cool label`; // // var diagram = "stateDiagram-v2\n"; diff --git a/cypress/platform/xss19.html b/cypress/platform/xss19.html index 590a195aa..ca747b39e 100644 --- a/cypress/platform/xss19.html +++ b/cypress/platform/xss19.html @@ -93,7 +93,7 @@ throw new Error('XSS Succeeded'); } - var diagram = `classDiagram + let diagram = `classDiagram class Shape{ << { + let cnt = 0; + let a; + const handler = setInterval(() => { cnt++; a = {}; if (typeof a.polluted !== 'undefined') { diff --git a/cypress/platform/xss20.html b/cypress/platform/xss20.html index 7b8aa9f85..9efd17215 100644 --- a/cypress/platform/xss20.html +++ b/cypress/platform/xss20.html @@ -96,7 +96,7 @@ // var diagram = ` graph TD // A --> B["<a href='javasc`; // diagram += `ript#colon;xssAttack()'>AAA</a>"]`; - var diagram = ` graph TD + let diagram = ` graph TD A --> B["AAA"]`; // diagram += '//via.placeholder.com/64\' width=64 />"]'; diff --git a/cypress/platform/xss21.html b/cypress/platform/xss21.html index e65a357ee..b2f67cd93 100644 --- a/cypress/platform/xss21.html +++ b/cypress/platform/xss21.html @@ -94,9 +94,9 @@ } // var diagram = ` graph TD - // A --> B["<a href='javasc`; + // A --> B["<a href='javascript`; // diagram += `ript#colon;xssAttack()'>AAA</a>"]`; - var diagram = ` graph TD + let diagram = ` graph TD A --> B["AAA"]`; // diagram += '//via.placeholder.com/64\' width=64 />"]'; diff --git a/cypress/platform/xss3.html b/cypress/platform/xss3.html index b72e8743c..78fabc4aa 100644 --- a/cypress/platform/xss3.html +++ b/cypress/platform/xss3.html @@ -42,9 +42,9 @@ startOnLoad: true, useMaxWidth: true, }); - var cnt = 0; - var a; - var handler = setInterval(() => { + let cnt = 0; + let a; + const handler = setInterval(() => { cnt++; a = {}; if (typeof a.polluted !== 'undefined') { diff --git a/cypress/platform/xss4.html b/cypress/platform/xss4.html index b6e36edcd..924a65e08 100644 --- a/cypress/platform/xss4.html +++ b/cypress/platform/xss4.html @@ -85,7 +85,7 @@ alert('It worked'); } - var diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n'; + let diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n'; diagram += 'flowchart\n'; diagram += 'A[" - + @@ -14,6 +14,7 @@ +

C4 context diagram demos

     C4Context
       accTitle: C4 context demo
@@ -62,6 +63,7 @@
       
       UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
     
+
     C4Container
@@ -101,6 +103,7 @@
     Rel(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")
     UpdateRelStyle(backend_api, banking_system, $offsetY="-50", $offsetX="-140")
     
+
     C4Component
@@ -140,6 +143,7 @@
         UpdateRelStyle(security, db, $offsetY="-40")
         UpdateRelStyle(mbsfacade, mbs, $offsetY="-40")
     
+
     C4Dynamic
@@ -159,6 +163,7 @@
     UpdateRelStyle(c2, c3, $textColor="red", $offsetX="-40", $offsetY="60")
     UpdateRelStyle(c3, c4, $textColor="red", $offsetY="-40", $offsetX="10")
     
+
     C4Deployment
@@ -210,7 +215,6 @@
     UpdateRelStyle(api, db2, $offsetX="-40", $offsetY="-20")
     UpdateRelStyle(db, db2, $offsetY="-10")
      
-
@@ -273,7 +277,7 @@ + - - - diff --git a/demos/journey.html b/demos/journey.html index dc1c379d3..dadcfb13c 100644 --- a/demos/journey.html +++ b/demos/journey.html @@ -1,5 +1,5 @@ - + @@ -14,9 +14,12 @@ +

Journey diagram demo

-         journey
-    title My working day
+---
+title: My working day 
+---
+     journey
       accTitle: Very simple journey demo
       accDescr: 2 main sections: work and home, each with just a few tasks
 
diff --git a/demos/mindmap.html b/demos/mindmap.html
new file mode 100644
index 000000000..a5b554a1a
--- /dev/null
+++ b/demos/mindmap.html
@@ -0,0 +1,108 @@
+
+
+  
+    
+    
+    Mindmap Mermaid Quick Test Page
+    
+    
+  
+
+  
+    

Mindmap diagram demo

+
+        mindmap
+        root
+            child1((Circle))
+                grandchild 1
+                grandchild 2
+            child2(Round rectangle)
+                grandchild 3
+                grandchild 4
+            child3[Square]
+                grandchild 5
+                ::icon(mdi mdi-fire)
+                gc6((grand
child 6)) + ::icon(mdi mdi-fire) + gc7((grand
grand
child 8)) +
+ +

Mindmap with root wrapping text and a shape

+
+        mindmap
+            root[A root with a long text that wraps to keep the node size in check]
+    
+ + + + diff --git a/demos/pie.html b/demos/pie.html index 3232d2534..333ef9491 100644 --- a/demos/pie.html +++ b/demos/pie.html @@ -1,5 +1,5 @@ - + @@ -14,6 +14,7 @@ +

Pie chart demos

       pie title Pets adopted by volunteers
       accTitle: simple pie char demo
@@ -23,6 +24,7 @@
     "Rats" : 15
     
+
     pie
       title Key elements in Product X
@@ -35,7 +37,7 @@
     
- -A summary of all options and their defaults is found [here][3]. -A description of each option follows below. - -## theme - -Theme , the CSS style sheet - -| Parameter | Description | Type | Required | Values | -| --------- | --------------- | ------ | -------- | ---------------------------------------------- | -| theme | Built in Themes | string | Optional | 'default', 'forest', 'dark', 'neutral', 'null' | - -**Notes:** To disable any pre-defined mermaid theme, use "null".
 "theme": "forest",
-"themeCSS": ".node rect { fill: red; }" 
- -## fontFamily - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------------------------------------------ | ------ | -------- | --------------------------- | -| fontFamily | specifies the font to be used in the rendered diagrams | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: '"trebuchet ms", verdana, arial, sans-serif;'. - -## logLevel - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------------------------- | ------ | -------- | -------- | --------------------------------------------- | -| logLevel | This option decides the amount of logging to be used. | string | number | Required | 'trace','debug','info','warn','error','fatal' | - -**Notes:** - -- Trace: 0 -- Debug: 1 -- Info: 2 -- Warn: 3 -- Error: 4 -- Fatal: 5 (default) - -## securityLevel - -| Parameter | Description | Type | Required | Values | -| ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ | -| securityLevel | Level of trust for parsed diagram | string | Required | 'sandbox', 'strict', 'loose', 'antiscript' | - -**Notes**: - -- **strict**: (**default**) tags in text are encoded, click functionality is disabled -- **loose**: tags in text are allowed, click functionality is enabled -- **antiscript**: html tags in text are allowed, (only script element is removed), click - functionality is enabled -- **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This - prevent any JavaScript from running in the context. This may hinder interactive functionality - of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc. - -## startOnLoad - -| Parameter | Description | Type | Required | Values | -| ----------- | -------------------------------------------- | ------- | -------- | ----------- | -| startOnLoad | Dictates whether mermaid starts on Page load | boolean | Required | true, false | - -**Notes:** Default value: true - -## arrowMarkerAbsolute - -| Parameter | Description | Type | Required | Values | -| ------------------- | ---------------------------------------------------------------------------- | ------- | -------- | ----------- | -| arrowMarkerAbsolute | Controls whether or arrow markers in html code are absolute paths or anchors | boolean | Required | true, false | - -**Notes**: - -This matters if you are using base tag settings. - -Default value: false - -## secure - -This option controls which currentConfig keys are considered _secure_ and can only be changed -via call to mermaidAPI.initialize. Calls to mermaidAPI.reinitialize cannot make changes to the -`secure` keys in the current currentConfig. This prevents malicious graph directives from -overriding a site's default security. - -**Notes**: - -Default value: \['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'] - -## deterministicIds - -This option controls if the generated ids of nodes in the SVG are generated randomly or based -on a seed. If set to false, the IDs are generated based on the current date and thus are not -deterministic. This is the default behaviour. - -**Notes**: - -This matters if your files are checked into sourcecontrol e.g. git and should not change unless -content is changed. - -Default value: false - -## deterministicIDSeed - -This option is the optional seed for deterministic ids. if set to undefined but -deterministicIds is true, a simple number iterator is used. You can set this attribute to base -the seed on a static string. - -## flowchart - -The object containing configurations specific for flowcharts - -### diagramPadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | -| diagramPadding | Amount of padding around the diagram as a whole | Integer | Required | Any Positive Value | - -**Notes:** - -The amount of padding around the diagram as a whole so that embedded diagrams have margins, -expressed in pixels - -Default value: 8 - -### htmlLabels - -| Parameter | Description | Type | Required | Values | -| ---------- | -------------------------------------------------------------------------------------------- | ------- | -------- | ----------- | -| htmlLabels | Flag for setting whether or not a html tag should be used for rendering labels on the edges. | boolean | Required | true, false | - -**Notes:** Default value: true. - -### nodeSpacing - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------------------------------------- | ------- | -------- | ------------------- | -| nodeSpacing | Defines the spacing between nodes on the same level | Integer | Required | Any positive Number | - -**Notes:** - -Pertains to horizontal spacing for TB (top to bottom) or BT (bottom to top) graphs, and the -vertical spacing for LR as well as RL graphs.\*\* - -Default value: 50 - -### rankSpacing - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------------------------------------------------- | ------- | -------- | ------------------- | -| rankSpacing | Defines the spacing between nodes on different levels | Integer | Required | Any Positive Number | - -**Notes**: - -Pertains to vertical spacing for TB (top to bottom) or BT (bottom to top), and the horizontal -spacing for LR as well as RL graphs. - -Default value 50 - -### curve - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------------------------------- | ------ | -------- | ----------------------------- | -| curve | Defines how mermaid renders curves for flowcharts. | string | Required | 'basis', 'linear', 'cardinal' | - -**Notes:** - -Default Value: 'basis' - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes:** - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-wrapper' - -## sequence - -The object containing configurations specific for sequence diagrams - -### activationWidth - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------- | ------- | -------- | ------------------ | -| activationWidth | Width of the activation rect | Integer | Required | Any Positive Value | - -**Notes:** Default value :10 - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | ------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### actorMargin - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------- | ------- | -------- | ------------------ | -| actorMargin | Margin between actors | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------- | ------- | -------- | ------------------ | -| width | Width of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 150 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| height | Height of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 65 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------------ | ------- | -------- | ------------------ | -| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### boxTextMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| boxTextMargin | Margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 5 - -### noteMargin - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------- | ------- | -------- | ------------------ | -| noteMargin | margin around notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### messageMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | ---------------------- | ------- | -------- | ------------------ | -| messageMargin | Space between messages | Integer | Required | Any Positive Value | - -**Notes:** Default value: 35 - -### messageAlign - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ------ | -------- | ------------------------- | -| messageAlign | Multiline message alignment | string | Required | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### mirrorActors - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ------- | -------- | ----------- | -| mirrorActors | Mirror actors under diagram | boolean | Required | true, false | - -**Notes:** Default value: true - -### forceMenus - -| Parameter | Description | Type | Required | Values | -| ---------- | ----------------------------------------------------------------------- | ------- | -------- | ----------- | -| forceMenus | forces actor popup menus to always be visible (to support E2E testing). | Boolean | Required | True, False | - -**Notes:** - -Default value: false. - -### bottomMarginAdj - -| Parameter | Description | Type | Required | Values | -| --------------- | ------------------------------------------ | ------- | -------- | ------------------ | -| bottomMarginAdj | Prolongs the edge of the diagram downwards | Integer | Required | Any Positive Value | - -**Notes:** - -Depending on css styling this might need adjustment. - -Default value: 1 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** When this flag is set to true, the height and width is set to 100% and is then -scaling with the available space. If set to false, the absolute space required is used. - -Default value: true - -### rightAngles - -| Parameter | Description | Type | Required | Values | -| ----------- | ------------------------------------ | ------- | -------- | ----------- | -| rightAngles | display curve arrows as right angles | boolean | Required | true, false | - -**Notes:** - -This will display arrows that start and begin at the same node as right angles, rather than a -curve - -Default value: false - -### showSequenceNumbers - -| Parameter | Description | Type | Required | Values | -| ------------------- | ------------------------------- | ------- | -------- | ----------- | -| showSequenceNumbers | This will show the node numbers | boolean | Required | true, false | - -**Notes:** Default value: false - -### actorFontSize - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------------- | ------- | -------- | ------------------ | -| actorFontSize | This sets the font size of the actor's description | Integer | Require | Any Positive Value | - -**Notes:** **Default value 14**.. - -### actorFontFamily - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------------------------------- | ------ | -------- | --------------------------- | -| actorFontFamily | This sets the font family of the actor's description | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: "'Open Sans", sans-serif' - -### actorFontWeight - -This sets the font weight of the actor's description - -**Notes:** Default value: 400. - -### noteFontSize - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------------------------------------------- | ------- | -------- | ------------------ | -| noteFontSize | This sets the font size of actor-attached notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 14 - -### noteFontFamily - -| Parameter | Description | Type | Required | Values | -| -------------- | -------------------------------------------------- | ------ | -------- | --------------------------- | -| noteFontFamily | This sets the font family of actor-attached notes. | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: ''"trebuchet ms", verdana, arial, sans-serif' - -### noteFontWeight - -This sets the font weight of the note's description - -**Notes:** Default value: 400 - -### noteAlign - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------------------------------------- | ------ | -------- | ------------------------- | -| noteAlign | This sets the text alignment of actor-attached notes | string | required | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### messageFontSize - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------------------------------------- | ------- | -------- | ------------------- | -| messageFontSize | This sets the font size of actor messages | Integer | Required | Any Positive Number | - -**Notes:** Default value: 16 - -### messageFontFamily - -| Parameter | Description | Type | Required | Values | -| ----------------- | ------------------------------------------- | ------ | -------- | --------------------------- | -| messageFontFamily | This sets the font family of actor messages | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: '"trebuchet ms", verdana, arial, sans-serif' - -### messageFontWeight - -This sets the font weight of the message's description - -**Notes:** Default value: 400. - -### wrap - -This sets the auto-wrap state for the diagram - -**Notes:** Default value: false. - -### wrapPadding - -This sets the auto-wrap padding for the diagram (sides only) - -**Notes:** Default value: 0. - -### labelBoxWidth - -This sets the width of the loop-box (loop, alt, opt, par) - -**Notes:** Default value: 50. - -### labelBoxHeight - -This sets the height of the loop-box (loop, alt, opt, par) - -**Notes:** Default value: 20. - -## gantt - -The object containing configurations specific for gantt diagrams - -### titleTopMargin - -### titleTopMargin - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | -| titleTopMargin | Margin top for the text over the gantt diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 25 - -### barHeight - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------- | ------- | -------- | ------------------ | -| barHeight | The height of the bars in the graph | Integer | Required | Any Positive Value | - -**Notes:** Default value: 20 - -### barGap - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------------------------------------------------- | ------- | -------- | ------------------ | -| barGap | The margin between the different activities in the gantt diagram | Integer | Optional | Any Positive Value | - -**Notes:** Default value: 4 - -### topPadding - -| Parameter | Description | Type | Required | Values | -| ---------- | -------------------------------------------------------------------------- | ------- | -------- | ------------------ | -| topPadding | Margin between title and gantt diagram and between axis and gantt diagram. | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### rightPadding - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------------------------------------------------------------------- | ------- | -------- | ------------------ | -| rightPadding | The space allocated for the section name to the right of the activities | Integer | Required | Any Positive Value | - -**Notes:** Default value: 75 - -### leftPadding - -| Parameter | Description | Type | Required | Values | -| ----------- | ---------------------------------------------------------------------- | ------- | -------- | ------------------ | -| leftPadding | The space allocated for the section name to the left of the activities | Integer | Required | Any Positive Value | - -**Notes:** Default value: 75 - -### gridLineStartPadding - -| Parameter | Description | Type | Required | Values | -| -------------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| gridLineStartPadding | Vertical starting position of the grid lines | Integer | Required | Any Positive Value | - -**Notes:** Default value: 35 - -### fontSize - -| Parameter | Description | Type | Required | Values | -| --------- | ----------- | ------- | -------- | ------------------ | -| fontSize | Font size | Integer | Required | Any Positive Value | - -**Notes:** Default value: 11 - -### sectionFontSize - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------- | ------- | -------- | ------------------ | -| sectionFontSize | Font size for sections | Integer | Required | Any Positive Value | - -**Notes:** Default value: 11 - -### numberSectionStyles - -| Parameter | Description | Type | Required | Values | -| ------------------- | ---------------------------------------- | ------- | -------- | ------------------ | -| numberSectionStyles | The number of alternating section styles | Integer | 4 | Any Positive Value | - -**Notes:** Default value: 4 - -### axisFormat - -| Parameter | Description | Type | Required | Values | -| ---------- | --------------------------- | ---- | -------- | ---------------- | -| axisFormat | Datetime format of the axis | 3 | Required | Date in yy-mm-dd | - -**Notes:** - -This might need adjustment to match your locale and preferences - -Default value: '%Y-%m-%d'. - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### topAxis - -| Parameter | Description | Type | Required | Values | -| --------- | ----------- | ------- | -------- | ----------- | -| topAxis | See notes | Boolean | 4 | True, False | - -**Notes:** when this flag is set date labels will be added to the top of the chart - -**Default value false**. - -## journey - -The object containing configurations specific for journey diagrams - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | -------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the sequence diagram. | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### leftMargin - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------- | ------- | -------- | ------------------ | -| actorMargin | Margin between actors | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------- | ------- | -------- | ------------------ | -| width | Width of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 150 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| height | Height of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 65 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------------ | ------- | -------- | ------------------ | -| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### boxTextMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| boxTextMargin | Margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 5 - -### noteMargin - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------- | ------- | -------- | ------------------ | -| noteMargin | Margin around notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### messageMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | ----------------------- | ------- | -------- | ------------------ | -| messageMargin | Space between messages. | Integer | Required | Any Positive Value | - -**Notes:** - -Space between messages. - -Default value: 35 - -### messageAlign - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ---- | -------- | ------------------------- | -| messageAlign | Multiline message alignment | 3 | 4 | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### bottomMarginAdj - -| Parameter | Description | Type | Required | Values | -| --------------- | ------------------------------------------ | ------- | -------- | ------------------ | -| bottomMarginAdj | Prolongs the edge of the diagram downwards | Integer | 4 | Any Positive Value | - -**Notes:** - -Depending on css styling this might need adjustment. - -Default value: 1 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### rightAngles - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------------------- | ---- | -------- | ----------- | -| rightAngles | Curved Arrows become Right Angles | 3 | 4 | true, false | - -**Notes:** - -This will display arrows that start and begin at the same node as right angles, rather than a -curves - -Default value: false - -## useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -## defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes**: - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-d3' - -## useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -## defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes:** - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-d3' - -## er - -The object containing configurations specific for entity relationship diagrams - -### diagramPadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | -| diagramPadding | Amount of padding around the diagram as a whole | Integer | Required | Any Positive Value | - -**Notes:** - -The amount of padding around the diagram as a whole so that embedded diagrams have margins, -expressed in pixels - -Default value: 20 - -### layoutDirection - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------------------- | ------ | -------- | ---------------------- | -| layoutDirection | Directional bias for layout of entities. | string | Required | "TB", "BT", "LR", "RL" | - -**Notes:** - -'TB' for Top-Bottom, 'BT'for Bottom-Top, 'LR' for Left-Right, or 'RL' for Right to Left. - -T = top, B = bottom, L = left, and R = right. - -Default value: 'TB' - -### minEntityWidth - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------- | ------- | -------- | ------------------ | -| minEntityWidth | The minimum width of an entity box | Integer | Required | Any Positive Value | - -**Notes:** Expressed in pixels. Default value: 100 - -### minEntityHeight - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------------------------------- | ------- | -------- | ------------------ | -| minEntityHeight | The minimum height of an entity box | Integer | 4 | Any Positive Value | - -**Notes:** Expressed in pixels Default value: 75 - -### entityPadding - -| Parameter | Description | Type | Required | Values | -| ------------- | ------------------------------------------------------------ | ------- | -------- | ------------------ | -| entityPadding | Minimum internal padding between text in box and box borders | Integer | 4 | Any Positive Value | - -**Notes:** - -The minimum internal padding between text in an entity box and the enclosing box borders, -expressed in pixels. - -Default value: 15 - -### stroke - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------- | ------ | -------- | -------------------- | -| stroke | Stroke color of box edges and lines | string | 4 | Any recognized color | - -**Notes:** Default value: 'gray' - -### fill - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------- | ------ | -------- | -------------------- | -| fill | Fill color of entity boxes | string | 4 | Any recognized color | - -**Notes:** Default value: 'honeydew' - -### fontSize - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------- | ------- | -------- | ------------------ | -| fontSize | Font Size in pixels | Integer | | Any Positive Value | - -**Notes:** - -Font size (expressed as an integer representing a number of pixels) Default value: 12 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## pie - -The object containing configurations specific for pie diagrams - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## requirement - -The object containing configurations specific for req diagrams - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## c4 - -The object containing configurations specific for c4 diagrams - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the c4 diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | ------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the c4 diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### c4ShapeMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | --------------------- | ------- | -------- | ------------------ | -| c4ShapeMargin | Margin between shapes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### c4ShapePadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------- | ------- | -------- | ------------------ | -| c4ShapePadding | Padding between shapes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 20 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| width | Width of person boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 216 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------- | ------- | -------- | ------------------ | -| height | Height of person boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 60 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------- | ------- | -------- | ------------------ | -| boxMargin | Margin around boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** When this flag is set to true, the height and width is set to 100% and is then -scaling with the available space. If set to false, the absolute space required is used. - -Default value: true - -### c4ShapeInRow - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------- | ------- | -------- | ------------------ | -| c4ShapeInRow | See Notes | Integer | Required | Any Positive Value | - -**Notes:** How many shapes to place in each row. - -Default value: 4 - -### c4BoundaryInRow - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ------------------ | -| c4BoundaryInRow | See Notes | Integer | Required | Any Positive Value | - -**Notes:** How many boundarys to place in each row. - -Default value: 2 - -### personFontSize - -This sets the font size of Person shape for the diagram - -**Notes:** Default value: 14. - -### personFontFamily - -This sets the font family of Person shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### personFontWeight - -This sets the font weight of Person shape for the diagram - -**Notes:** Default value: normal. - -### external_personFontSize - -This sets the font size of External Person shape for the diagram - -**Notes:** Default value: 14. - -### external_personFontFamily - -This sets the font family of External Person shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_personFontWeight - -This sets the font weight of External Person shape for the diagram - -**Notes:** Default value: normal. - -### systemFontSize - -This sets the font size of System shape for the diagram - -**Notes:** Default value: 14. - -### systemFontFamily - -This sets the font family of System shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### systemFontWeight - -This sets the font weight of System shape for the diagram - -**Notes:** Default value: normal. - -### external_systemFontSize - -This sets the font size of External System shape for the diagram - -**Notes:** Default value: 14. - -### external_systemFontFamily - -This sets the font family of External System shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_systemFontWeight - -This sets the font weight of External System shape for the diagram - -**Notes:** Default value: normal. - -### system_dbFontSize - -This sets the font size of System DB shape for the diagram - -**Notes:** Default value: 14. - -### system_dbFontFamily - -This sets the font family of System DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### system_dbFontWeight - -This sets the font weight of System DB shape for the diagram - -**Notes:** Default value: normal. - -### external_system_dbFontSize - -This sets the font size of External System DB shape for the diagram - -**Notes:** Default value: 14. - -### external_system_dbFontFamily - -This sets the font family of External System DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_system_dbFontWeight - -This sets the font weight of External System DB shape for the diagram - -**Notes:** Default value: normal. - -### system_queueFontSize - -This sets the font size of System Queue shape for the diagram - -**Notes:** Default value: 14. - -### system_queueFontFamily - -This sets the font family of System Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### system_queueFontWeight - -This sets the font weight of System Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_system_queueFontSize - -This sets the font size of External System Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_system_queueFontFamily - -This sets the font family of External System Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_system_queueFontWeight - -This sets the font weight of External System Queue shape for the diagram - -**Notes:** Default value: normal. - -### boundaryFontSize - -This sets the font size of Boundary shape for the diagram - -**Notes:** Default value: 14. - -### boundaryFontFamily - -This sets the font family of Boundary shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### boundaryFontWeight - -This sets the font weight of Boundary shape for the diagram - -**Notes:** Default value: normal. - -### messageFontSize - -This sets the font size of Message shape for the diagram - -**Notes:** Default value: 12. - -### messageFontFamily - -This sets the font family of Message shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### messageFontWeight - -This sets the font weight of Message shape for the diagram - -**Notes:** Default value: normal. - -### containerFontSize - -This sets the font size of Container shape for the diagram - -**Notes:** Default value: 14. - -### containerFontFamily - -This sets the font family of Container shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### containerFontWeight - -This sets the font weight of Container shape for the diagram - -**Notes:** Default value: normal. - -### external_containerFontSize - -This sets the font size of External Container shape for the diagram - -**Notes:** Default value: 14. - -### external_containerFontFamily - -This sets the font family of External Container shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_containerFontWeight - -This sets the font weight of External Container shape for the diagram - -**Notes:** Default value: normal. - -### container_dbFontSize - -This sets the font size of Container DB shape for the diagram - -**Notes:** Default value: 14. - -### container_dbFontFamily - -This sets the font family of Container DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### container_dbFontWeight - -This sets the font weight of Container DB shape for the diagram - -**Notes:** Default value: normal. - -### external_container_dbFontSize - -This sets the font size of External Container DB shape for the diagram - -**Notes:** Default value: 14. - -### external_container_dbFontFamily - -This sets the font family of External Container DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_container_dbFontWeight - -This sets the font weight of External Container DB shape for the diagram - -**Notes:** Default value: normal. - -### container_queueFontSize - -This sets the font size of Container Queue shape for the diagram - -**Notes:** Default value: 14. - -### container_queueFontFamily - -This sets the font family of Container Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### container_queueFontWeight - -This sets the font weight of Container Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_container_queueFontSize - -This sets the font size of External Container Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_container_queueFontFamily - -This sets the font family of External Container Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_container_queueFontWeight - -This sets the font weight of External Container Queue shape for the diagram - -**Notes:** Default value: normal. - -### componentFontSize - -This sets the font size of Component shape for the diagram - -**Notes:** Default value: 14. - -### componentFontFamily - -This sets the font family of Component shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### componentFontWeight - -This sets the font weight of Component shape for the diagram - -**Notes:** Default value: normal. - -### external_componentFontSize - -This sets the font size of External Component shape for the diagram - -**Notes:** Default value: 14. - -### external_componentFontFamily - -This sets the font family of External Component shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_componentFontWeight - -This sets the font weight of External Component shape for the diagram - -**Notes:** Default value: normal. - -### component_dbFontSize - -This sets the font size of Component DB shape for the diagram - -**Notes:** Default value: 14. - -### component_dbFontFamily - -This sets the font family of Component DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### component_dbFontWeight - -This sets the font weight of Component DB shape for the diagram - -**Notes:** Default value: normal. - -### external_component_dbFontSize - -This sets the font size of External Component DB shape for the diagram - -**Notes:** Default value: 14. - -### external_component_dbFontFamily - -This sets the font family of External Component DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_component_dbFontWeight - -This sets the font weight of External Component DB shape for the diagram - -**Notes:** Default value: normal. - -### component_queueFontSize - -This sets the font size of Component Queue shape for the diagram - -**Notes:** Default value: 14. - -### component_queueFontFamily - -This sets the font family of Component Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### component_queueFontWeight - -This sets the font weight of Component Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_component_queueFontSize - -This sets the font size of External Component Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_component_queueFontFamily - -This sets the font family of External Component Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_component_queueFontWeight - -This sets the font weight of External Component Queue shape for the diagram - -**Notes:** Default value: normal. - -### wrap - -This sets the auto-wrap state for the diagram - -**Notes:** Default value: true. - -### wrapPadding - -This sets the auto-wrap padding for the diagram (sides only) - -**Notes:** Default value: 0. - -## parse - -### Parameters - -- `text` **[string][4]** -- `parseError` **[Function][5]?** - -Returns **[boolean][6]** - -## setSiteConfig - -## setSiteConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------- | ----------- | --------------------------------------- | -| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | - -**Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls -to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) -will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this -function _Default value: At default, will mirror Global Config_ - -### Parameters - -- `conf` **MermaidConfig** The base currentConfig to use as siteConfig - -Returns **[object][7]** The siteConfig - -## getSiteConfig - -## getSiteConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------------------- | ----------- | -------------------------------- | -| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig | - -**Notes**: Returns **any** values in siteConfig. - -Returns **[object][7]** The siteConfig - -## setConfig - -## setConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------- | ----------- | --------------------------------------- | -| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | - -**Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure -keys. Any values found in conf with key found in siteConfig.secure will be replaced with the -corresponding siteConfig value. - -### Parameters - -- `conf` **any** The potential currentConfig - -Returns **any** The currentConfig merged with the sanitized conf - -## render - -Function that renders an svg with a graph from a chart definition. Usage example below. - -```javascript -mermaidAPI.initialize({ - startOnLoad: true, -}); -$(function () { - const graphDefinition = 'graph TB\na-->b'; - const cb = function (svgGraph) { - console.log(svgGraph); - }; - mermaidAPI.render('id1', graphDefinition, cb); -}); -``` - -### Parameters - -- `id` **[string][4]** The id of the element to be rendered -- `text` **[string][4]** The graph definition -- `cb` **function (svgCode: [string][4], bindFunctions: function (element: [Element][8]): void): void** -- `container` **[Element][8]** Selector to element in which a div with the graph temporarily will be - inserted. If one is provided a hidden div will be inserted in the body of the page instead. The - element will be removed when rendering is completed. - -Returns **void** - -## getConfig - -## getConfig - -| Function | Description | Type | Return Values | -| --------- | ------------------------- | ----------- | ------------------------------ | -| getConfig | Obtains the currentConfig | Get Request | Any Values from current Config | - -**Notes**: Returns **any** the currentConfig - -Returns **any** The currentConfig - -## sanitize - -## sanitize - -| Function | Description | Type | Values | -| -------- | -------------------------------------- | ----------- | ------ | -| sanitize | Sets the siteConfig to desired values. | Put Request | None | - -Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies -options in-place - -### Parameters - -- `options` **any** The potential setConfig parameter - -## addDirective - -Pushes in a directive to the configuration - -### Parameters - -- `directive` **[object][7]** The directive to push in - -## reset - -## reset - -| Function | Description | Type | Required | Values | -| -------- | ---------------------------- | ----------- | -------- | ------ | -| reset | Resets currentConfig to conf | Put Request | Required | None | - -## conf - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- | -| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array | - -**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) - -### Parameters - -- `config` (optional, default `siteConfig`) - -Returns **void** - -## initialize - -### Parameters - -- `options` **MermaidConfig** - -## - -## mermaidAPI configuration defaults - -```html - -``` - -[1]: Setup.md?id=render -[2]: 8.6.0_docs.md -[3]: #mermaidapi-configuration-defaults -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object -[8]: https://developer.mozilla.org/docs/Web/API/Element diff --git a/docs/_navbar.md b/docs/_navbar.md deleted file mode 100644 index 7f9f495a7..000000000 --- a/docs/_navbar.md +++ /dev/null @@ -1,15 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -- Getting started - - - [Quick start](quickstart.md) - - [Writing more pages](more-pages.md) - - [Custom navbar](custom-navbar.md) - - [Cover page](cover.md) - -- Configuration - - [Configuration](configuration.md) - - [Themes](themes.md) - - [Using plugins](plugins.md) - - [Markdown configuration](markdown.md) - - [Language highlight](language-highlight.md) diff --git a/docs/_sidebar.md b/docs/_sidebar.md deleted file mode 100644 index 17cde68c9..000000000 --- a/docs/_sidebar.md +++ /dev/null @@ -1,46 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -- 📔 Introduction - - - [About Mermaid](README.md) - - [Deployment](n00b-gettingStarted.md) - - [Syntax and Configuration](n00b-syntaxReference.md) - -- 📊 Diagram Syntax - - - [Flowchart](flowchart.md) - - [Sequence Diagram](sequenceDiagram.md) - - [Class Diagram](classDiagram.md) - - [State Diagram](stateDiagram.md) - - [Entity Relationship Diagram](entityRelationshipDiagram.md) - - [User Journey](user-journey.md) - - [Gantt](gantt.md) - - [Pie Chart](pie.md) - - [Requirement Diagram](requirementDiagram.md) - - [Gitgraph (Git) Diagram 🔥](gitgraph.md) - - [C4C Diagram (Context) Diagram 🦺⚠️](c4c.md) - - [Mindmaps 🦺⚠️](mindmap.md) - - [Other Examples](examples.md) - -- ⚙️ Deployment and Configuration - - - [Tutorials](Tutorials.md) - - [API-Usage](usage.md) - - [Mermaid API Configuration](Setup.md) - - [Directives](directives.md) - - [Theming](theming.md) - - [Accessibility](accessibility.md) - - [Mermaid CLI](mermaidCLI.md) - - [Advanced usage](n00b-advanced.md) - -- 📚 Misc - - - [Use-Cases and Integrations](integrations.md) - - [FAQ](faq.md) - -- 🙌 Contributions and Community - - [Overview for Beginners](n00b-overview.md) - - [Development and Contribution ](development.md) - - [Changelog](CHANGELOG.md) - - [Adding Diagrams ](newDiagram.md) - - [Security ](security.md) diff --git a/docs/breakingChanges.md b/docs/breakingChanges.md deleted file mode 100644 index 964d89e4f..000000000 --- a/docs/breakingChanges.md +++ /dev/null @@ -1,51 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -# Breaking changes - -### Breaking changes from history version to latest version: - -## #1 - -```javascript -mermaid.initialize({ - sequenceDiagram:{ - ... - } -}) -``` - -has been changed to - -```javascript -mermaid.initialize({ - sequence:{ - ... - } -}) -``` - -## #2 - -In old versions you needed to reference a CSS file in your HTML: - -```html - -``` - -or - -```html - -``` - -Now it is not needed, and there are no more CSS files in the distribution files. - -You just: - -```javascript -mermaid.initialize({ - theme: 'forest', -}); -``` - -and it works like a charm because now the CSS is inline with the SVG to allow simpler portability. diff --git a/docs/development.md b/docs/community/development.md similarity index 82% rename from docs/development.md rename to docs/community/development.md index 3f2033d61..58ca4670b 100644 --- a/docs/development.md +++ b/docs/community/development.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/development.md](../../packages/mermaid/src/docs/community/development.md). # Development and Contribution 🙌 @@ -8,7 +12,7 @@ So you want to help? That's great! Here are a few things to get you started on the right path. -**The Docs Structure is dictated by [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)** +**The Docs Structure is dictated by [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. **Note: Commits and Pull Requests should be directed to the develop branch.** @@ -28,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 (we encourage updates to the `src/docs` folder; you can submit them via direct commits) +- Documentation (we encourage updates to the `/packages/mermaid/src/docs` folder; you can submit them via direct commits) When you commit code, create a branch with the following naming convention: @@ -46,9 +50,9 @@ Start with the type, such as **feature** or **bug**, followed by the issue numbe If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature? -The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via the **[sidebar](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via **[.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. -> **All the documents displayed in the GitHub.io page are listed in [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +> **All the documents displayed in the GitHub.io page are listed in [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. The contents of are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid-js.github.io/mermaid/) once released. @@ -60,7 +64,7 @@ The documentation is located in the `src/docs` directory and organized according The `docs` folder will be automatically generated when committing to `src/docs` and should not be edited manually. -We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) +We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) ### Add Unit Tests for Parsing @@ -113,7 +117,7 @@ Markdown is used to format the text, for more information about Markdown [see th To edit Docs on your computer: -1. Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs) directory in the `develop` branch. +1. Find the Markdown file (.md) to edit in the [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) directory in the `develop` branch. 2. Create a fork of the develop branch. 3. Make changes or add new documentation. 4. Commit changes to your fork and push it to GitHub. @@ -122,7 +126,7 @@ To edit Docs on your computer: To edit Docs on GitHub: 1. Login to [GitHub.com](https://www.github.com). -2. Navigate to [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). +2. Navigate to [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). 3. To edit a file, click the pencil icon at the top-right of the file contents panel. 4. Describe what you changed in the **Propose file change** section, located at the bottom of the page. 5. Submit your changes by clicking the button **Propose file change** at the bottom (by automatic creation of a fork and a new branch). diff --git a/docs/community/img/er.png b/docs/community/img/er.png new file mode 100644 index 000000000..21c44c257 Binary files /dev/null and b/docs/community/img/er.png differ diff --git a/docs/n00b-overview.md b/docs/community/n00b-overview.md similarity index 85% rename from docs/n00b-overview.md rename to docs/community/n00b-overview.md index df400e4bb..e0056d912 100644 --- a/docs/n00b-overview.md +++ b/docs/community/n00b-overview.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/n00b-overview.md](../../packages/mermaid/src/docs/community/n00b-overview.md). # Overview for Beginners @@ -41,7 +45,7 @@ It is a relatively straightforward solution to a significant hurdle with the sof **Nodes** -> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](./n00b-syntaxReference) +> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference.md) ## Advantages of using Mermaid @@ -65,6 +69,6 @@ In fact one can pick up the syntax for it quite easily from the examples given a ## Mermaid is for everyone. -Video [Tutorials](https://mermaid-js.github.io/mermaid/#/./Tutorials) are also available for the mermaid [live editor](https://mermaid.live/). +Video [Tutorials](https://mermaid-js.github.io/mermaid/#/../config/Tutorials) are also available for the mermaid [live editor](https://mermaid.live/). Alternatively you can use Mermaid [Plug-Ins](https://mermaid-js.github.io/mermaid/#/./integrations), with tools you already use, like Google Docs. diff --git a/docs/newDiagram.md b/docs/community/newDiagram.md similarity index 93% rename from docs/newDiagram.md rename to docs/community/newDiagram.md index 070865702..da86f9838 100644 --- a/docs/newDiagram.md +++ b/docs/community/newDiagram.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/newDiagram.md](../../packages/mermaid/src/docs/community/newDiagram.md). # Adding a New Diagram/Chart 📊 @@ -28,9 +32,8 @@ statement In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered. -```tip -Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user. -``` +> **Note** +> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user. For more info look in the example diagram type: @@ -45,8 +48,7 @@ exports.parseError = function (err, hash) { when parsing the `yy` object is initialized as per below: ```javascript -var parser; -parser = exampleParser.parser; +const parser = exampleParser.parser; parser.yy = db; ``` @@ -69,8 +71,8 @@ At this point when mermaid is trying to render the diagram, it will detect it as ### Setup ```javascript -var graph = require('./graphDb'); -var flow = require('./parser/flow'); +const graph = require('./graphDb'); +const flow = require('./parser/flow'); flow.parser.yy = graph; ``` @@ -91,7 +93,7 @@ graph.getEdges(); The parser is also exposed in the mermaid api by calling: ```javascript -var parser = mermaid.getParser(); +const parser = mermaid.getParser(); ``` Note that the parse needs a graph object to store the data as per: @@ -117,13 +119,12 @@ There are a few features that are common between the different types of diagrams Here some pointers on how to handle these different areas. -#### [Directives](./directives.md) +#### [Directives](../config/directives.md) Here is example handling from flowcharts: Jison: ```jison - /* lexical grammar */ %lex %x open_directive @@ -180,6 +181,7 @@ The syntax for adding title and description looks like this: In a similar way to the directives the jison syntax are quite similar between the diagrams. ```jison + * lexical grammar */ %lex %x acc_title @@ -199,6 +201,7 @@ statement : acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } + ``` The functions for setting title and description are provided by a common module. This is the import from flowDb.js: @@ -226,7 +229,7 @@ addSVGAccessibilityFields(parser.yy, svg, id); ## Theming -Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](./theming.md). +Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](../config/theming.md). When adding themes to a diagram it comes down to a few important locations in the code. diff --git a/docs/security.md b/docs/community/security.md similarity index 64% rename from docs/security.md rename to docs/community/security.md index cac6d8da2..07adbfbf8 100644 --- a/docs/security.md +++ b/docs/community/security.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/community/security.md](../../packages/mermaid/src/docs/community/security.md). # Security @@ -6,13 +10,13 @@ The Mermaid team takes the security of Mermaid and the applications that use Mer ## Reporting vulnerabilities -To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. +To report a vulnerability, please e-mail with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. We aim to reply within three working days, probably much sooner. -You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates. +You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to again if you do not receive prompt attention and regular updates. -You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. +You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. ## Best practices diff --git a/docs/8.6.0_docs.md b/docs/config/8.6.0_docs.md similarity index 76% rename from docs/8.6.0_docs.md rename to docs/config/8.6.0_docs.md index cc812901e..abd158712 100644 --- a/docs/8.6.0_docs.md +++ b/docs/config/8.6.0_docs.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/8.6.0_docs.md](../../packages/mermaid/src/docs/config/8.6.0_docs.md). # Version 8.6.0 Changes @@ -8,8 +12,8 @@ With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation. -`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](./Setup.md). -This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. +`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration.md). +This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives.md), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. **A likely application for this is in the creation of diagrams/charts inside company/organizational webpages, that rely on mermaid for diagram and chart rendering.** @@ -48,9 +52,8 @@ Implementors can only modify configurations using directives, and cannot change The Two types of directives: are `init` (or `initialize`) and `wrap`. -```note -All directives are enclosed in `%%{ }%%` -``` +> **Note** +> All directives are enclosed in `%%{ }%%` Older versions of mermaid will not parse directives because `%%` will comment out the directive. This makes the update backwards-compatible. @@ -62,18 +65,17 @@ Older versions of mermaid will not parse directives because `%%` will comment ou | --------- | ----------------------- | --------- | -------- | ----------------------------------------------- | | init | modifies configurations | Directive | Optional | Any parameters not included in the secure array | -```note -init would be an argument-directive: `%%{init: { **insert argument here**}}%%` - -The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored. - **for example**: - -`%%{init: {"theme": "default", "logLevel": 1 }}%%` - -Configurations that are passed through init cannot change the parameters in a secure array at a higher level. In the event of a collision, mermaid will give priority to secure arrays and parse the request without changing the values of those parameters in conflict. - -When deployed within code, init is called before the graph/diagram description. -``` +> **Note** +> init would be an argument-directive: `%%{init: { **insert argument here**}}%%` +> +> The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored. +> **for example**: +> +> `%%{init: {"theme": "default", "logLevel": 1 }}%%` +> +> Configurations that are passed through init cannot change the parameters in a secure array at a higher level. In the event of a collision, mermaid will give priority to secure arrays and parse the request without changing the values of those parameters in conflict. +> +> When deployed within code, init is called before the graph/diagram description. **for example**: @@ -107,19 +109,18 @@ When deployed within code, init is called before the graph/diagram description. | --------- | ----------------------------- | --------- | -------- | ---------- | | wrap | a callable text-wrap function | Directive | Optional | %%{wrap}%% | -```note -Wrap is a function that is currently only deployable for sequence diagrams. - -Wrap respects a manually added , so if the user wants to break up their text, they have full control over line breaks by adding tags. - -It is a non-argument directive and can be executed thusly: - -`%%{wrap}%%` . -``` +> **Note** +> Wrap is a function that is currently only deployable for sequence diagrams. +> +> `Wrap respects a manually added
, so if the user wants to break up their text, they have full control over line breaks by adding
tags.` +> +> It is a non-argument directive and can be executed thusly: +> +> `%%{wrap}%%` . **An example of text wrapping in a sequence diagram**: -![Image showing wrapped text](img/wrapped%20text.png) +!\[Image showing wrapped text]\(img/wrapped text.png) # Resetting Configurations: @@ -143,7 +144,7 @@ Example of **assignWithDepth**: Example of **object.Assign**: -![Image showing object.assign without depth](img/object.assign%20without%20depth.png) +!\[Image showing object.assign without depth]\(img/object.assign without depth.png) • **calculateTextDimensions**, **calculateTextWidth**, and **calculateTextHeight** - for measuring text dimensions, width and height. @@ -157,13 +158,12 @@ Example of **object.Assign**: | --------------- | ------------------------------------- | ----------- | --------------------------------------- | ---------- | ---------- | | `setSiteConfig` | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | conf | siteConfig | -```note -Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset -the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig -to the defaultConfig -Note: currentConfig is set in this function。 -Default value: will mirror Global Config -``` +> **Note** +> Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls to reset() will reset +> the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) will reset siteConfig and currentConfig +> to the defaultConfig +> Note: currentConfig is set in this function。 +> Default value: will mirror Global Config ## getSiteConfig @@ -171,9 +171,8 @@ Default value: will mirror Global Config | --------------- | --------------------------------------------------- | ----------- | ---------------------------------- | | `getSiteConfig` | Returns the current `siteConfig` base configuration | Get Request | Returns Any Values in `siteConfig` | -```note -Returns any values in siteConfig. -``` +> **Note** +> Returns any values in siteConfig. ## setConfig @@ -181,11 +180,10 @@ Returns any values in siteConfig. | ----------- | ------------------------------------------ | ----------- | --------------------------------- | ---------- | ---------------------------------------------- | | `setConfig` | Sets the `currentConfig` to desired values | Put Request | Any Values, those in secure array | conf | `currentConfig` merged with the sanitized conf | -```note -Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any -values found in conf with key found in siteConfig.secure will be replaced with the corresponding -siteConfig value. -``` +> **Note** +> Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure keys. Any +> values found in conf with key found in siteConfig.secure will be replaced with the corresponding +> siteConfig value. ## getConfig @@ -193,9 +191,8 @@ siteConfig value. | ----------- | --------------------------- | ----------- | ------------------------------- | | `getConfig` | Obtains the `currentConfig` | Get Request | Any Values from `currentConfig` | -```note -Returns any values in currentConfig. -``` +> **Note** +> Returns any values in currentConfig. ## sanitize @@ -203,10 +200,9 @@ Returns any values in currentConfig. | ---------- | ---------------------------------------- | -------------- | ------ | | `sanitize` | Sets the `siteConfig` to desired values. | Put Request(?) | None | -```note -modifies options in-place -Ensures options parameter does not attempt to override siteConfig secure keys. -``` +> **Note** +> modifies options in-place +> Ensures options parameter does not attempt to override siteConfig secure keys. ## reset @@ -220,8 +216,7 @@ Ensures options parameter does not attempt to override siteConfig secure keys. | --------- | ------------------------------------------------------------ | ---------- | -------- | -------------------------------------------- | | `conf` | base set of values, which `currentConfig` could be reset to. | Dictionary | Required | Any Values, with respect to the secure Array | -```note -default: current siteConfig (optional, default `getSiteConfig()`) -``` +> **Note** +> default: current siteConfig (optional, default `getSiteConfig()`) -## For more information, read [Setup](Setup.md). +## For more information, read [Setup](./setup/README.md). diff --git a/docs/Tutorials.md b/docs/config/Tutorials.md similarity index 87% rename from docs/Tutorials.md rename to docs/config/Tutorials.md index 0f9465a35..41e0508cb 100644 --- a/docs/Tutorials.md +++ b/docs/config/Tutorials.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/Tutorials.md](../../packages/mermaid/src/docs/config/Tutorials.md). # Tutorials @@ -6,7 +10,7 @@ This is list of publicly available Tutorials for using Mermaid.JS . This is inte **Note that these tutorials might display an older interface, but the usage of the live-editor will largely be the same.** -For most purposes, you can use the [Live Editor](https://mermaid-js.github.io/mermaid-live-editor), to quickly and easily render a diagram. +For most purposes, you can use the [Live Editor](https://mermaid.live), to quickly and easily render a diagram. ## Live-Editor Tutorials @@ -24,7 +28,7 @@ The definitions that can be generated the Live-Editor are also backwards-compati ## Mermaid with HTML -Examples are provided in [Getting Started](n00b-gettingStarted.md) +Examples are provided in [Getting Started](../intro/n00b-gettingStarted.md) **CodePen Examples:** diff --git a/docs/accessibility.md b/docs/config/accessibility.md similarity index 96% rename from docs/accessibility.md rename to docs/config/accessibility.md index bce3da25d..8fa4aa3ac 100644 --- a/docs/accessibility.md +++ b/docs/config/accessibility.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/accessibility.md](../../packages/mermaid/src/docs/config/accessibility.md). # Accessibility Options @@ -19,7 +23,7 @@ The diagram authors can now add the accessibility options in the diagram definit - `accTitle: "Your Accessibility Title"` or - `accDescr: "Your Accessibility Description"` -**When these two options are defined, they will add a coressponding `` and `<desc>` tag in the SVG.** +**When these two options are defined, they will add a corresponding `<title>` and `<desc>` tag in the SVG.** Let us take a look at the following example with a flowchart diagram: diff --git a/docs/developer-docs/configuration.md b/docs/config/configuration.md similarity index 85% rename from docs/developer-docs/configuration.md rename to docs/config/configuration.md index ba3422f6d..c7b780143 100644 --- a/docs/developer-docs/configuration.md +++ b/docs/config/configuration.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/configuration.md](../../packages/mermaid/src/docs/config/configuration.md). # Configuration diff --git a/docs/directives.md b/docs/config/directives.md similarity index 92% rename from docs/directives.md rename to docs/config/directives.md index f814782f0..550707080 100644 --- a/docs/directives.md +++ b/docs/config/directives.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/directives.md](../../packages/mermaid/src/docs/config/directives.md). # Directives @@ -26,7 +30,7 @@ Mermaid basically supports two types of configuration options to be overridden b 2. _Diagram specific configurations_ : These are the configurations that are available and applied to a specific diagram. For each diagram there are specific configuration that will alter how that particular diagram looks and behaves. For example, `mirrorActors` is a configuration that is specific to the `SequenceDiagram` and alter whether the actors are mirrored or not. So this config is available only for the `SequenceDiagram` type. -**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code. +**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code. Soon we plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs @@ -84,7 +88,13 @@ Here the directive declaration will set the `logLevel` to `debug` and the `theme Note: You can use 'init' or 'initialize' as both acceptable as init directives. Also note that `%%init%%` and `%%initialize%%` directives will be grouped together after they are parsed. This means: -```mmd2 +```mermaid-example +%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% +%%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%% +... +``` + +```mermaid %%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% %%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%% ... @@ -92,11 +102,11 @@ Note: You can use 'init' or 'initialize' as both acceptable as init directives. parsing the above generates a single `%%init%%` JSON object below, combining the two directives and carrying over the last value given for `loglevel`: -```json5 +```json { - logLevel: 'fatal', - theme: 'dark', - startOnLoad: true, + "logLevel": "fatal", + "theme": "dark", + "startOnLoad": true } ``` @@ -223,7 +233,7 @@ Some common flowchart configurations are: - _diagramPadding_: number - _useMaxWidth_: number -For complete list of flowchart configurations, see [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code. +For complete list of flowchart configurations, see [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code. _Soon we plan to publish a complete list all diagram specific configurations updated in the docs_ The following code snippet changes flowchart config: @@ -267,7 +277,7 @@ Some common sequence configurations are: - _showSequenceNumbers_: boolean - _wrap_: boolean -For complete list of sequence diagram configurations, see _defaultConfig.js_ in the source code. +For complete list of sequence diagram configurations, see _defaultConfig.ts_ in the source code. _Soon we plan to publish a complete list all diagram specific configurations updated in the docs_ So, `wrap` by default has a value of `false` for sequence diagrams. diff --git a/docs/img/accessibility-div-example-2.png b/docs/config/img/accessibility-div-example-2.png similarity index 100% rename from docs/img/accessibility-div-example-2.png rename to docs/config/img/accessibility-div-example-2.png diff --git a/docs/img/accessibility-div-example.png b/docs/config/img/accessibility-div-example.png similarity index 100% rename from docs/img/accessibility-div-example.png rename to docs/config/img/accessibility-div-example.png diff --git a/docs/img/assignWithDepth.png b/docs/config/img/assignWithDepth.png similarity index 100% rename from docs/img/assignWithDepth.png rename to docs/config/img/assignWithDepth.png diff --git a/docs/img/object.assign without depth.png b/docs/config/img/object.assign without depth.png similarity index 100% rename from docs/img/object.assign without depth.png rename to docs/config/img/object.assign without depth.png diff --git a/docs/img/python-mermaid-integration.png b/docs/config/img/python-mermaid-integration.png similarity index 100% rename from docs/img/python-mermaid-integration.png rename to docs/config/img/python-mermaid-integration.png diff --git a/docs/img/wrapped text.png b/docs/config/img/wrapped text.png similarity index 100% rename from docs/img/wrapped text.png rename to docs/config/img/wrapped text.png diff --git a/docs/config/mermaidCLI.md b/docs/config/mermaidCLI.md new file mode 100644 index 000000000..530ac93ab --- /dev/null +++ b/docs/config/mermaidCLI.md @@ -0,0 +1,9 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/mermaidCLI.md](../../packages/mermaid/src/docs/config/mermaidCLI.md). + +# mermaid CLI + +mermaid CLI has been moved to [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). Please read its documentation instead. diff --git a/docs/n00b-advanced.md b/docs/config/n00b-advanced.md similarity index 63% rename from docs/n00b-advanced.md rename to docs/config/n00b-advanced.md index e6a6adcc3..5dd907429 100644 --- a/docs/n00b-advanced.md +++ b/docs/config/n00b-advanced.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/n00b-advanced.md](../../packages/mermaid/src/docs/config/n00b-advanced.md). # Advanced n00b mermaid (Coming soon..) diff --git a/docs/config/setup/README.md b/docs/config/setup/README.md new file mode 100644 index 000000000..1cf82797d --- /dev/null +++ b/docs/config/setup/README.md @@ -0,0 +1,13 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/README.md](../../../packages/mermaid/src/docs/config/setup/README.md). + +# mermaid + +## Modules + +- [config](modules/config.md) +- [defaultConfig](modules/defaultConfig.md) +- [mermaidAPI](modules/mermaidAPI.md) diff --git a/docs/config/setup/modules/config.md b/docs/config/setup/modules/config.md new file mode 100644 index 000000000..8381dc8c7 --- /dev/null +++ b/docs/config/setup/modules/config.md @@ -0,0 +1,276 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/modules/config.md](../../../../packages/mermaid/src/docs/config/setup/modules/config.md). + +# Module: config + +## Variables + +### defaultConfig + +• `Const` **defaultConfig**: `MermaidConfig` + +#### Defined in + +[config.ts:7](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L7) + +## Functions + +### addDirective + +▸ **addDirective**(`directive`): `void` + +Pushes in a directive to the configuration + +#### Parameters + +| Name | Type | Description | +| :---------- | :---- | :----------------------- | +| `directive` | `any` | The directive to push in | + +#### Returns + +`void` + +#### Defined in + +[config.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L191) + +--- + +### getConfig + +▸ **getConfig**(): `MermaidConfig` + +## getConfig + +| Function | Description | Type | Return Values | +| --------- | ------------------------- | ----------- | ------------------------------ | +| getConfig | Obtains the currentConfig | Get Request | Any Values from current Config | + +**Notes**: Returns **any** the currentConfig + +#### Returns + +`MermaidConfig` + +The currentConfig + +#### Defined in + +[config.ts:137](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L137) + +--- + +### getSiteConfig + +▸ **getSiteConfig**(): `MermaidConfig` + +## getSiteConfig + +| Function | Description | Type | Values | +| ------------- | ------------------------------------------------- | ----------- | -------------------------------- | +| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig | + +**Notes**: Returns **any** values in siteConfig. + +#### Returns + +`MermaidConfig` + +The siteConfig + +#### Defined in + +[config.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L96) + +--- + +### reset + +▸ **reset**(`config?`): `void` + +## reset + +| Function | Description | Type | Required | Values | +| -------- | ---------------------------- | ----------- | -------- | ------ | +| reset | Resets currentConfig to conf | Put Request | Required | None | + +## conf + +| Parameter | Description | Type | Required | Values | +| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- | +| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array | + +**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) + +#### Parameters + +| Name | Type | Default value | Description | +| :------- | :-------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `config` | `MermaidConfig` | `siteConfig` | base set of values, which currentConfig could be **reset** to. Defaults to the current siteConfig (e.g returned by [getSiteConfig](config.md#getsiteconfig)). | + +#### Returns + +`void` + +#### Defined in + +[config.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L223) + +--- + +### sanitize + +▸ **sanitize**(`options`): `void` + +## sanitize + +| Function | Description | Type | Values | +| -------- | -------------------------------------- | ----------- | ------ | +| sanitize | Sets the siteConfig to desired values. | Put Request | None | + +Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies +options in-place + +#### Parameters + +| Name | Type | Description | +| :-------- | :---- | :-------------------------------- | +| `options` | `any` | The potential setConfig parameter | + +#### Returns + +`void` + +#### Defined in + +[config.ts:152](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L152) + +--- + +### saveConfigFromInitialize + +▸ **saveConfigFromInitialize**(`conf`): `void` + +#### Parameters + +| Name | Type | +| :----- | :-------------- | +| `conf` | `MermaidConfig` | + +#### Returns + +`void` + +#### Defined in + +[config.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L75) + +--- + +### setConfig + +▸ **setConfig**(`conf`): `MermaidConfig` + +## setConfig + +| Function | Description | Type | Values | +| ------------- | ------------------------------------- | ----------- | --------------------------------------- | +| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | + +**Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure +keys. Any values found in conf with key found in siteConfig.secure will be replaced with the +corresponding siteConfig value. + +#### Parameters + +| Name | Type | Description | +| :----- | :-------------- | :-------------------------- | +| `conf` | `MermaidConfig` | The potential currentConfig | + +#### Returns + +`MermaidConfig` + +The currentConfig merged with the sanitized conf + +#### Defined in + +[config.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L113) + +--- + +### setSiteConfig + +▸ **setSiteConfig**(`conf`): `MermaidConfig` + +## setSiteConfig + +| Function | Description | Type | Values | +| ------------- | ------------------------------------- | ----------- | --------------------------------------- | +| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | + +**Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls +to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) +will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this +function _Default value: At default, will mirror Global Config_ + +#### Parameters + +| Name | Type | Description | +| :----- | :-------------- | :------------------------------------------ | +| `conf` | `MermaidConfig` | The base currentConfig to use as siteConfig | + +#### Returns + +`MermaidConfig` + +The new siteConfig + +#### Defined in + +[config.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L61) + +--- + +### updateCurrentConfig + +▸ **updateCurrentConfig**(`siteCfg`, `_directives`): `MermaidConfig` + +#### Parameters + +| Name | Type | +| :------------ | :-------------- | +| `siteCfg` | `MermaidConfig` | +| `_directives` | `any`\[] | + +#### Returns + +`MermaidConfig` + +#### Defined in + +[config.ts:14](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L14) + +--- + +### updateSiteConfig + +▸ **updateSiteConfig**(`conf`): `MermaidConfig` + +#### Parameters + +| Name | Type | +| :----- | :-------------- | +| `conf` | `MermaidConfig` | + +#### Returns + +`MermaidConfig` + +#### Defined in + +[config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79) diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md new file mode 100644 index 000000000..05f6f8a2c --- /dev/null +++ b/docs/config/setup/modules/defaultConfig.md @@ -0,0 +1,56 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/modules/defaultConfig.md](../../../../packages/mermaid/src/docs/config/setup/modules/defaultConfig.md). + +# Module: defaultConfig + +## Variables + +### configKeys + +• `Const` **configKeys**: `string`\[] + +#### Defined in + +[defaultConfig.ts:1933](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L1933) + +--- + +### default + +• `Const` **default**: `Partial`<`MermaidConfig`> + +**Configuration methods in Mermaid version 8.6.0 have been updated, to learn more\[[click +here](8.6.0_docs.md)].** + +## **What follows are config instructions for older versions** + +These are the default options which can be overridden with the initialization call like so: + +**Example 1:** + +```js +mermaid.initialize({ flowchart: { htmlLabels: false } }); +``` + +**Example 2:** + +```html +<script> + const config = { + startOnLoad: true, + flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, + securityLevel: 'loose', + }; + mermaid.initialize(config); +</script> +``` + +A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults). +A description of each option follows below. + +#### Defined in + +[defaultConfig.ts:33](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L33) diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md new file mode 100644 index 000000000..d24369c3c --- /dev/null +++ b/docs/config/setup/modules/mermaidAPI.md @@ -0,0 +1,308 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/modules/mermaidAPI.md](../../../../packages/mermaid/src/docs/config/setup/modules/mermaidAPI.md). + +# Module: mermaidAPI + +## References + +### default + +Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) + +## Variables + +### mermaidAPI + +• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `boolean` ; `parseAsync`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `Promise`<`boolean`> ; `parseDirective`: (`p`: `any`, `statement`: `string`, `context`: `string`, `type`: `string`) => `void` ; `render`: (`id`: `string`, `text`: `string`, `cb?`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `string` ; `renderAsync`: (`id`: `string`, `text`: `string`, `cb?`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `Promise`<`string`> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }> + +## mermaidAPI configuration defaults + +```ts +const config = { + theme: 'default', + logLevel: 'fatal', + securityLevel: 'strict', + startOnLoad: true, + arrowMarkerAbsolute: false, + + er: { + diagramPadding: 20, + layoutDirection: 'TB', + minEntityWidth: 100, + minEntityHeight: 75, + entityPadding: 15, + stroke: 'gray', + fill: 'honeydew', + fontSize: 12, + useMaxWidth: true, + }, + flowchart: { + diagramPadding: 8, + htmlLabels: true, + curve: 'basis', + }, + sequence: { + diagramMarginX: 50, + diagramMarginY: 10, + actorMargin: 50, + width: 150, + height: 65, + boxMargin: 10, + boxTextMargin: 5, + noteMargin: 10, + messageMargin: 35, + messageAlign: 'center', + mirrorActors: true, + bottomMarginAdj: 1, + useMaxWidth: true, + rightAngles: false, + showSequenceNumbers: false, + }, + gantt: { + titleTopMargin: 25, + barHeight: 20, + barGap: 4, + topPadding: 50, + leftPadding: 75, + gridLineStartPadding: 35, + fontSize: 11, + fontFamily: '"Open Sans", sans-serif', + numberSectionStyles: 4, + axisFormat: '%Y-%m-%d', + topAxis: false, + }, +}; +mermaid.initialize(config); +``` + +#### Defined in + +[mermaidAPI.ts:939](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L939) + +## Functions + +### appendDivSvgG + +▸ **appendDivSvgG**(`parentRoot`, `id`, `enclosingDivId`, `divStyle?`, `svgXlink?`): `any` + +Append an enclosing div, then svg, then g (group) to the d3 parentRoot. Set attributes. +Only set the style attribute on the enclosing div if divStyle is given. +Only set the xmlns:xlink attribute on svg if svgXlink is given. +Return the last node appended + +#### Parameters + +| Name | Type | Description | +| :--------------- | :------- | :----------------------------------------------- | +| `parentRoot` | `any` | the d3 node to append things to | +| `id` | `string` | the value to set the id attr to | +| `enclosingDivId` | `string` | the id to set the enclosing div to | +| `divStyle?` | `string` | if given, the style to set the enclosing div to | +| `svgXlink?` | `string` | if given, the link to set the new svg element to | + +#### Returns + +`any` + +- returns the parentRoot that had nodes appended + +#### Defined in + +[mermaidAPI.ts:284](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L284) + +--- + +### cleanUpSvgCode + +▸ **cleanUpSvgCode**(`svgCode?`, `inSandboxMode`, `useArrowMarkerUrls`): `string` + +Clean up svgCode. Do replacements needed + +#### Parameters + +| Name | Type | Default value | Description | +| :------------------- | :-------- | :------------ | :---------------------------------------------------------- | +| `svgCode` | `string` | `''` | the code to clean up | +| `inSandboxMode` | `boolean` | `undefined` | security level | +| `useArrowMarkerUrls` | `boolean` | `undefined` | should arrow marker's use full urls? (vs. just the anchors) | + +#### Returns + +`string` + +the cleaned up svgCode + +#### Defined in + +[mermaidAPI.ts:235](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L235) + +--- + +### createCssStyles + +▸ **createCssStyles**(`config`, `graphType`, `classDefs?`): `string` + +Create the user styles + +#### Parameters + +| Name | Type | Description | +| :---------- | :-------------- | :----------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `config` | `MermaidConfig` | configuration that has style and theme settings to use | +| `graphType` | `string` | used for checking if classDefs should be applied | +| `classDefs` | `undefined` | `null` | `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) | + +#### Returns + +`string` + +the string with all the user styles + +#### Defined in + +[mermaidAPI.ts:164](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L164) + +--- + +### createUserStyles + +▸ **createUserStyles**(`config`, `graphType`, `classDefs`, `svgId`): `string` + +#### Parameters + +| Name | Type | +| :---------- | :----------------------------------------- | +| `config` | `MermaidConfig` | +| `graphType` | `string` | +| `classDefs` | `Record`<`string`, `DiagramStyleClassDef`> | +| `svgId` | `string` | + +#### Returns + +`string` + +#### Defined in + +[mermaidAPI.ts:212](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L212) + +--- + +### cssImportantStyles + +▸ **cssImportantStyles**(`cssClass`, `element`, `cssClasses?`): `string` + +Create a CSS style that starts with the given class name, then the element, +with an enclosing block that has each of the cssClasses followed by !important; + +#### Parameters + +| Name | Type | Default value | Description | +| :----------- | :---------- | :------------ | :--------------------------------------------- | +| `cssClass` | `string` | `undefined` | CSS class name | +| `element` | `string` | `undefined` | CSS element | +| `cssClasses` | `string`\[] | `[]` | list of CSS styles to append after the element | + +#### Returns + +`string` + +- the constructed string + +#### Defined in + +[mermaidAPI.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L148) + +--- + +### decodeEntities + +▸ **decodeEntities**(`text`): `string` + +#### Parameters + +| Name | Type | Description | +| :----- | :------- | :----------------- | +| `text` | `string` | text to be decoded | + +#### Returns + +`string` + +#### Defined in + +[mermaidAPI.ts:128](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L128) + +--- + +### encodeEntities + +▸ **encodeEntities**(`text`): `string` + +#### Parameters + +| Name | Type | Description | +| :----- | :------- | :----------------- | +| `text` | `string` | text to be encoded | + +#### Returns + +`string` + +#### Defined in + +[mermaidAPI.ts:99](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L99) + +--- + +### putIntoIFrame + +▸ **putIntoIFrame**(`svgCode?`, `svgElement?`): `string` + +Put the svgCode into an iFrame. Return the iFrame code + +#### Parameters + +| Name | Type | Default value | Description | +| :------------ | :------- | :------------ | :--------------------------------------------------------------------------- | +| `svgCode` | `string` | `''` | the svg code to put inside the iFrame | +| `svgElement?` | `any` | `undefined` | the d3 node that has the current svgElement so we can get the height from it | + +#### Returns + +`string` + +- the code with the iFrame that now contains the svgCode + TODO replace btoa(). Replace with buf.toString('base64')? + +#### Defined in + +[mermaidAPI.ts:263](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L263) + +--- + +### removeExistingElements + +▸ **removeExistingElements**(`doc`, `isSandboxed`, `id`, `divSelector`, `iFrameSelector`): `void` + +Remove any existing elements from the given document + +#### Parameters + +| Name | Type | Description | +| :--------------- | :--------- | :---------------------------------------------- | +| `doc` | `Document` | the document to removed elements from | +| `isSandboxed` | `boolean` | whether or not we are in sandboxed mode | +| `id` | `string` | id for any existing SVG element | +| `divSelector` | `string` | selector for any existing enclosing div element | +| `iFrameSelector` | `string` | selector for any existing iFrame element | + +#### Returns + +`void` + +#### Defined in + +[mermaidAPI.ts:335](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L335) diff --git a/docs/theming.md b/docs/config/theming.md similarity index 96% rename from docs/theming.md rename to docs/config/theming.md index c2dd3f2ae..cfd86caa0 100644 --- a/docs/theming.md +++ b/docs/config/theming.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/theming.md](../../packages/mermaid/src/docs/config/theming.md). # Theme Configuration @@ -152,9 +156,8 @@ You can create your own themes, by changing any of the given variables below. If ## Theme Variables Reference Table -```note -Variables that are unique to some diagrams can be affected by changes in Theme Variables -``` +> **Note** +> Variables that are unique to some diagrams can be affected by changes in Theme Variables | Variable | Default/Base/Factor value | Calc | Description | | -------------------- | ------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------- | @@ -371,42 +374,6 @@ In the following examples, the directive `init` is used, with the `theme` being end ``` -```mermaid-example -%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% - graph TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - B --> G[/Another/] - C ==>|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car] - subgraph section - C - D - E - F - G - end -``` - -```mermaid -%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% - graph TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - B --> G[/Another/] - C ==>|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car] - subgraph section - C - D - E - F - G - end -``` - ### Flowchart (beta) ```mermaid-example diff --git a/docs/usage.md b/docs/config/usage.md similarity index 80% rename from docs/usage.md rename to docs/config/usage.md index be986a56b..476806d8f 100644 --- a/docs/usage.md +++ b/docs/config/usage.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/usage.md](../../packages/mermaid/src/docs/config/usage.md). # Usage @@ -14,7 +18,7 @@ Please note that you can switch versions through the dropdown box at the top rig ## Using mermaid -For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./Setup.md). +For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./setup/README.md). We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor. @@ -37,25 +41,11 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai **Hosting mermaid on a web page.** -> Note:This topic explored in greater depth in the [User Guide for Beginners](./n00b-gettingStarted.md) +> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md) -The easiest way to integrate mermaid on a web page requires three elements: +The easiest way to integrate mermaid on a web page requires two elements: -1. Inclusion of the mermaid address in the html page using a `script` tag, in the `src` section.Example: - - ```html - <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> - ``` - -2. The `mermaidAPI` call, in a separate `script` tag. Example: - - ```html - <script> - mermaid.initialize({ startOnLoad: true }); - </script> - ``` - -3. A graph definition, inside `<div>` tags labeled `class=mermaid`. Example: +- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example: ```html <pre class="mermaid"> @@ -66,8 +56,18 @@ The easiest way to integrate mermaid on a web page requires three elements: </pre> ``` -**Following these directions, mermaid starts at page load and (when the page has loaded) it will -locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.** +- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call. + +Example: + +```html +<script type="module"> + import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs'; + mermaid.initialize({ startOnLoad: true }); +</script> +``` + +**Following these directions, mermaid starts at page load and (when the page has loaded) it will locate the graph definitions inside the `pre` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.** ## Simple full example: @@ -84,8 +84,8 @@ locate the graph definitions inside the `div` tags with `class="mermaid"` and re B-->C[fa:fa-ban forbidden] B-->D(fa:fa-spinner); </pre> - <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> - <script> + <script type="module"> + import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: true }); </script> </body> @@ -119,10 +119,9 @@ Values: - **antiscript**: html tags in text are allowed, (only script element is removed), click functionality is enabled - **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This prevent any JavaScript running in the context. This may hinder interactive functionality of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc. -```note -This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled. -**sandbox** security level is still in the beta version. -``` +> **Note** +> This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled. +> **sandbox** security level is still in the beta version. **If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.** @@ -187,9 +186,8 @@ Or with no config object, and a jQuery selection: mermaid.init(undefined, $('#someId .yetAnotherClass')); ``` -```warning -This type of integration is deprecated. Instead the preferred way of handling more complex integration is to use the mermaidAPI instead. -``` +> **Warning** +> This type of integration is deprecated. Instead the preferred way of handling more complex integration is to use the mermaidAPI instead. ## Usage with webpack @@ -204,18 +202,17 @@ fetch the graph definition from the site (perhaps from a textarea), render it an The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console. ```html -<script src="mermaid.js"></script> - -<script> +<script type="module"> + import mermaid from './mermaid.mjs'; mermaid.mermaidAPI.initialize({ startOnLoad: false }); - $(function () { + $(async function () { // Example of using the API var element = document.querySelector('#graphDiv'); - var insertSvg = function (svgCode, bindFunctions) { + const insertSvg = function (svgCode, bindFunctions) { element.innerHTML = svgCode; }; - var graphDefinition = 'graph TB\na-->b'; - var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg); + const graphDefinition = 'graph TB\na-->b'; + const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg); }); </script> ``` @@ -229,7 +226,7 @@ The example code below is an extract of what mermaid does when using the API. Th bind events to an SVG when using the API for rendering. ```javascript -var insertSvg = function (svgCode, bindFunctions) { +const insertSvg = function (svgCode, bindFunctions) { element.innerHTML = svgCode; if (typeof callback !== 'undefined') { callback(id); @@ -237,7 +234,7 @@ var insertSvg = function (svgCode, bindFunctions) { bindFunctions(element); }; -var id = 'theGraph'; +const id = 'theGraph'; mermaidAPI.render(id, txt, insertSvg, element); ``` @@ -253,7 +250,7 @@ mermaidAPI.render(id, txt, insertSvg, element); This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html. ```javascript -var renderer = new marked.Renderer(); +const renderer = new marked.Renderer(); renderer.code = function (code, language) { if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) { return '<pre class="mermaid">' + code + '</pre>'; @@ -304,8 +301,8 @@ mermaid.parseError = function (err, hash) { displayErrorInGui(err); }; -var textFieldUpdated = function () { - var textStr = getTextFromFormField('code'); +const textFieldUpdated = function () { + const textStr = getTextFromFormField('code'); if (mermaid.parse(textStr)) { reRender(textStr); @@ -329,7 +326,7 @@ setting the options in mermaid. 4. Instantiation of the configuration using the **mermaid.init** call- **Deprecated** The list above has two ways too many of doing this. Three are deprecated and will eventually be removed. The list of -configuration objects are described [in the mermaidAPI documentation](Setup.md). +configuration objects are described [in the mermaidAPI documentation](./setup/README.md). ## Using the `mermaidAPI.initialize`/`mermaid.initialize` call @@ -339,20 +336,19 @@ on what kind of integration you use. ```html <script src="../dist/mermaid.js"></script> <script> - var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; + let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; mermaid.initialize(config); </script> ``` -```tip -This is the preferred way of configuring mermaid. -``` +> **Note** +> This is the preferred way of configuring mermaid. ### The following methods are deprecated and are kept only for backwards compatibility. ## Using the mermaid object -Is it possible to set some configuration via the mermaid object. The two parameters that are supported using this +It is possible to set some configuration via the mermaid object. The two parameters that are supported using this approach are: - mermaid.startOnLoad @@ -362,9 +358,8 @@ approach are: mermaid.startOnLoad = true; ``` -```warning -This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. -``` +> **Warning** +> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. ## Using the mermaid_config @@ -378,9 +373,8 @@ approach are: mermaid_config.startOnLoad = true; ``` -```warning -This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. -``` +> **Warning** +> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. ## Using the mermaid.init call @@ -393,6 +387,5 @@ To set some configuration via the mermaid object. The two parameters that are su mermaid_config.startOnLoad = true; ``` -```warning -This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. -``` +> **Warning** +> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility. diff --git a/docs/diagrams-and-syntax-and-examples/flowchart.md b/docs/diagrams-and-syntax-and-examples/flowchart.md deleted file mode 100644 index a55c6292a..000000000 --- a/docs/diagrams-and-syntax-and-examples/flowchart.md +++ /dev/null @@ -1,927 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - ---- - -sort: 3 -title: Flowchart - ---- - -# Flowcharts - Basic Syntax - -## Graph - -This statement declares the direction of the flowchart, either from top to bottom (`TD` or `TB`): - -```mermaid-example -graph TD - Start --> Stop -``` - -```mermaid -graph TD - Start --> Stop -``` - -or left to right (`LR`): - -```mermaid-example -graph LR - Start --> Stop -``` - -```mermaid -graph LR - Start --> Stop -``` - -## Flowchart Orientation - -Possible FlowChart orientations are: - -- TB - top to bottom -- TD - top-down (same as top to bottom) -- BT - bottom to top -- RL - right to left -- LR - left to right - -## Flowcharts - -This renders a flowchart that allows for features such as: more arrow types, multi directional arrows, and linking to and from subgraphs. - -Apart from the graph type, the syntax is the same. This is currently experimental. When the beta period is over, both the graph and flowchart keywords will render in this new way. At this point it is OK to start beta testing flowcharts. - -> **Important note** Do not type the word "end" as a Flowchart node. Capitalize all or any one the letters to keep the flowchart from breaking, i.e, "End" or "END". Or you can apply this [workaround](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897).\*\* - -## Nodes and shapes - -### A node (default) - -```mermaid-example -graph LR - id -``` - -```mermaid -graph LR - id -``` - -> **Note** The id is what is displayed in the box. - -### A node with text - -It is also possible to set text in the box that differs from the id. If this is done several times, only the last text -found for the node will be rendered. Also if you define edges for the node later on, you can omit text definitions. The -text previously defined will be used when rendering the box. - -```mermaid-example -graph LR - id1[This is the text in the box] -``` - -```mermaid -graph LR - id1[This is the text in the box] -``` - -## Node Shapes - -### A node with round edges - -```mermaid-example -graph LR - id1(This is the text in the box) -``` - -```mermaid -graph LR - id1(This is the text in the box) -``` - -### A stadium-shaped node - -```mermaid-example -graph LR - id1([This is the text in the box]) -``` - -```mermaid -graph LR - id1([This is the text in the box]) -``` - -### A node in a subroutine shape - -```mermaid-example -graph LR - id1[[This is the text in the box]] -``` - -```mermaid -graph LR - id1[[This is the text in the box]] -``` - -### A node in a cylindrical shape - -```mermaid-example -graph LR - id1[(Database)] -``` - -```mermaid -graph LR - id1[(Database)] -``` - -### A node in the form of a circle - -```mermaid-example -graph LR - id1((This is the text in the circle)) -``` - -```mermaid -graph LR - id1((This is the text in the circle)) -``` - -### A node in an asymmetric shape - -```mermaid-example -graph LR - id1>This is the text in the box] -``` - -```mermaid -graph LR - id1>This is the text in the box] -``` - -Currently it is only possible to render the shape above, and not its mirror. _This might change with future releases._ - -### A node (rhombus) - -```mermaid-example -graph LR - id1{This is the text in the box} -``` - -```mermaid -graph LR - id1{This is the text in the box} -``` - -### A hexagonal node - -```mermaid-example -graph LR - id1{{This is the text in the box}} -``` - -```mermaid -graph LR - id1{{This is the text in the box}} -``` - -### Parallelogram - -```mermaid-example -graph TD - id1[/This is the text in the box/] -``` - -```mermaid -graph TD - id1[/This is the text in the box/] -``` - -### Parallelogram alt - -```mermaid-example -graph TD - id1[\This is the text in the box\] -``` - -```mermaid -graph TD - id1[\This is the text in the box\] -``` - -### Trapezoid - -```mermaid-example -graph TD - A[/Christmas\] -``` - -```mermaid -graph TD - A[/Christmas\] -``` - -### Trapezoid alt - -```mermaid-example -graph TD - B[\Go shopping/] -``` - -```mermaid -graph TD - B[\Go shopping/] -``` - -## Links between nodes - -Nodes can be connected with links/edges. It is possible to have different types of links, or attach a text string on a link. - -### Link with arrow head - -```mermaid-example -graph LR - A-->B -``` - -```mermaid -graph LR - A-->B -``` - -### Open link - -```mermaid-example -graph LR - A --- B -``` - -```mermaid -graph LR - A --- B -``` - -### Text on links - -```mermaid-example -graph LR - A-- This is the text! ---B -``` - -```mermaid -graph LR - A-- This is the text! ---B -``` - -or - -```mermaid-example -graph LR - A---|This is the text|B -``` - -```mermaid -graph LR - A---|This is the text|B -``` - -### Link with arrow head and text - -```mermaid-example -graph LR - A-->|text|B -``` - -```mermaid -graph LR - A-->|text|B -``` - -or - -```mermaid-example -graph LR - A-- text -->B -``` - -```mermaid -graph LR - A-- text -->B -``` - -### Dotted link - -```mermaid-example -graph LR; - A-.->B; -``` - -```mermaid -graph LR; - A-.->B; -``` - -### Dotted link with text - -```mermaid-example -graph LR - A-. text .-> B -``` - -```mermaid -graph LR - A-. text .-> B -``` - -### Thick link - -```mermaid-example -graph LR - A ==> B -``` - -```mermaid -graph LR - A ==> B -``` - -### Thick link with text - -```mermaid-example -graph LR - A == text ==> B -``` - -```mermaid -graph LR - A == text ==> B -``` - -### Chaining of links - -It is possible to declare many links on the same line as per below: - -```mermaid-example -graph LR - A -- text --> B -- text2 --> C -``` - -```mermaid -graph LR - A -- text --> B -- text2 --> C -``` - -It is also possible to declare multiple nodes links in the same line as per below: - -```mermaid-example -graph LR - a --> b & c--> d -``` - -```mermaid -graph LR - a --> b & c--> d -``` - -You can then describe dependencies in a very expressive way. Like the one-liner below: - -```mermaid-example -graph TB - A & B--> C & D -``` - -```mermaid -graph TB - A & B--> C & D -``` - -If you describe the same diagram using the the basic syntax, it will take four lines: - -```mermaid-example -graph TB - A --> C - A --> D - B --> C - B --> D -``` - -```mermaid -graph TB - A --> C - A --> D - B --> C - B --> D -``` - -A word of warning, one could go overboard with this, making the graph harder to read in -markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little. -This goes for expressive syntaxes as well. - -### New arrow types - -When using flowchart instead of graph there are new types of arrows supported as per below: - -```mermaid-example -flowchart LR - A --o B - B --x C -``` - -```mermaid -flowchart LR - A --o B - B --x C -``` - -### Multi directional arrows - -When using flowchart instead of graph there is the possibility to use multidirectional arrows. - -```mermaid-example -flowchart LR - A o--o B - B <--> C - C x--x D -``` - -```mermaid -flowchart LR - A o--o B - B <--> C - C x--x D -``` - -### Minimum length of a link - -Each node in the flowchart is ultimately assigned to a rank in the rendered -graph, i.e. to a vertical or horizontal level (depending on the flowchart -orientation), based on the nodes to which it is linked. By default, links -can span any number of ranks, but you can ask for any link to be longer -than the others by adding extra dashes in the link definition. - -In the following example, two extra dashes are added in the link from node _B_ -to node _E_, so that it spans two more ranks than regular links: - -```mermaid-example -graph TD - A[Start] --> B{Is it?}; - B -->|Yes| C[OK]; - C --> D[Rethink]; - D --> B; - B ---->|No| E[End]; -``` - -```mermaid -graph TD - A[Start] --> B{Is it?}; - B -->|Yes| C[OK]; - C --> D[Rethink]; - D --> B; - B ---->|No| E[End]; -``` - -> **Note** The rendering engine may cause some links to be longer than -> the number of ranks requested in order to accommodate the overall topology. - -When the link label is written in the middle of the link, the extra dashes must -be added on the right side of the link. The following example is equivalent to -the previous one: - -```mermaid-example -graph TD - A[Start] --> B{Is it?}; - B -- Yes --> C[OK]; - C --> D[Rethink]; - D --> B; - B -- No ----> E[End]; -``` - -```mermaid -graph TD - A[Start] --> B{Is it?}; - B -- Yes --> C[OK]; - C --> D[Rethink]; - D --> B; - B -- No ----> E[End]; -``` - -For dotted or thick links, the characters to add are equals signs or dots, -as summed up in the following table: - -| Length | 1 | 2 | 3 | -| ----------------- | :----: | :-----: | :------: | -| Normal | `---` | `----` | `-----` | -| Normal with arrow | `-->` | `--->` | `---->` | -| Thick | `===` | `====` | `=====` | -| Thick with arrow | `==>` | `===>` | `====>` | -| Dotted | `-.-` | `-..-` | `-...-` | -| Dotted with arrow | `-.->` | `-..->` | `-...->` | - -## Special characters that break syntax - -Use quotes around text in order to render more troublesome characters, as in the example below: - -```mermaid-example -graph LR - id1["This is the (text) in the box"] -``` - -```mermaid -graph LR - id1["This is the (text) in the box"] -``` - -### Entity codes to escape characters - -Special characters (including Unicode) can be included by using HTML escaping syntax: - -```mermaid-example - graph LR - A["A double quote:#quot;"] -->B["A dec char:#9829;"] -``` - -```mermaid - graph LR - A["A double quote:#quot;"] -->B["A dec char:#9829;"] -``` - -## Subgraphs - - subgraph title - graph definition - end - -An example: - -```mermaid-example -graph TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end -``` - -```mermaid -graph TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end -``` - -You can also set an explicit id for the subgraph: - -```mermaid-example -graph TB - c1-->a2 - subgraph ide1 [one] - a1-->a2 - end -``` - -```mermaid -graph TB - c1-->a2 - subgraph ide1 [one] - a1-->a2 - end -``` - -## Flowcharts - -With the graphtype `flowchart` it is also possible to set edges to and from subgraphs: - -```mermaid-example -flowchart TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end - one --> two - three --> two - two --> c2 -``` - -```mermaid -flowchart TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end - one --> two - three --> two - two --> c2 -``` - -## Interaction - -A node can have click events bound that lead to either a JavaScript callback or to open a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. - - click nodeId callback - click nodeId call callback() - -- nodeId is the id of the node -- `callback` is the name of a JavaScript function defined on the page displaying the graph. The function will be called with the nodeId as an incoming parameter. - -```html -<script> - var callback = function (nodeId) { - alert('A callback was triggered on ' + nodeId); - }; -</script> -``` - -Examples of tooltip usage: - -The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class .mermaidTooltip. - -```mermaid-example -graph LR; - A-->B; - B-->C; - C-->D; - click A callback "Tooltip for a callback" - click B "https://www.github.com" "This is a tooltip for a link" - click A call callback() "Tooltip for a callback" - click B href "https://www.github.com" "This is a tooltip for a link" -``` - -```mermaid -graph LR; - A-->B; - B-->C; - C-->D; - click A callback "Tooltip for a callback" - click B "https://www.github.com" "This is a tooltip for a link" - click A call callback() "Tooltip for a callback" - click B href "https://www.github.com" "This is a tooltip for a link" -``` - -> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. - -?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). - -Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): - -```mermaid-example -graph LR; - A-->B; - B-->C; - C-->D; - D-->E; - click A "https://www.github.com" _blank - click B "https://www.github.com" "Open this in a new tab" _blank - click C href "https://www.github.com" _blank - click D href "https://www.github.com" "Open this in a new tab" _blank -``` - -```mermaid -graph LR; - A-->B; - B-->C; - C-->D; - D-->E; - click A "https://www.github.com" _blank - click B "https://www.github.com" "Open this in a new tab" _blank - click C href "https://www.github.com" _blank - click D href "https://www.github.com" "Open this in a new tab" _blank -``` - -Beginner's tip—here's a full example of using interactive links in HTML: - -```html -<body> - <pre class="mermaid"> - graph LR; - A-->B; - B-->C; - C-->D; - click A callback "Tooltip" - click B "https://www.github.com" "This is a link" - click C call callback() "Tooltip" - click D href "https://www.github.com" "This is a link" - </pre> - - <script> - var callback = function () { - alert('A callback was triggered'); - }; - var config = { - startOnLoad: true, - flowchart: { - useMaxWidth: true, - htmlLabels: true, - curve: 'cardinal', - }, - securityLevel: 'loose', - }; - mermaid.initialize(config); - </script> -</body> -``` - -### Comments - -Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including all punctuation and any flow syntax. - -```mermaid-example -graph LR -%% this is a comment A -- text --> B{node} - A -- text --> B -- text2 --> C -``` - -```mermaid -graph LR -%% this is a comment A -- text --> B{node} - A -- text --> B -- text2 --> C -``` - -## Styling and classes - -### Styling links - -It is possible to style links. For instance, you might want to style a link that is going backwards in the flow. As links -have no ids in the same way as nodes, some other way of attaching style is required. -So instead of ids, the order number of when the link was defined in the graph is used, starting with zero. Here's a linkStyle statement that would apply style to the fourth link in the graph: - - linkStyle 3 stroke:#ff3,stroke-width:4px,color:red; - -You can specify a `default` to apply to all links, or you can give a comma-separated list of link order numbers. - -Instead of giving a styles option, you can also use custom d3 curve types with the following syntax: - - linkStyle default|numList|num interpolate curveType - -If you want to add both D3 and style options, instead of writing: - - linkStyle default interpolate cardinal - linkStyle default stroke:#ff3,stroke-width:4px,color:red; - -You can combine them: - - linkStyle default interpolate cardinal stroke:#ff3,stroke-width:4px,color:red; - -### Styling a node - -It is possible to apply specific styles such as a thicker border or a different background color to a node. - -```mermaid-example -graph LR - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px - style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 -``` - -```mermaid -graph LR - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px - style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 -``` - -#### Classes - -More convenient than defining the style every time is to define a class of styles and attach this class reference to multiple nodes. - -here's a class definition: - - classDef className fill:#f9f,stroke:#333,stroke-width:4px; - -and then attaching this class to a node is simply: - - class nodeId1 className; - -It is also possible to attach a class to multiple nodes in one statement: - - class nodeId1,nodeId2 className; - -An even shorter form of adding a class is to attach the classname to the node using the `:::`operator: - -```mermaid-example -graph LR - A:::someclass --> B - classDef someclass fill:#f96; -``` - -```mermaid -graph LR - A:::someclass --> B - classDef someclass fill:#f96; -``` - -### Css classes - -It is also possible to predefine classes in css styles that can be applied from the graph definition: - -**Example style** - -```css -.cssClass > rect { - fill: #ff0000; - stroke: #ffff00; - stroke-width: 4px; -} -``` - -**Example definition** - -```mermaid-example -graph LR; - A-->B[AAA<span>BBB</span>]; - B-->D; - class A cssClass; -``` - -```mermaid -graph LR; - A-->B[AAA<span>BBB</span>]; - B-->D; - class A cssClass; -``` - -### Default class - -If a class is named `default` it will be assigned to all nodes that do not have a specific class definition. - - classDef default fill:#f9f,stroke:#333,stroke-width:4px; - -## Basic support for fontawesome - -It is possible to add icons from fontawesome. These are accessed via the syntax fa:#icon-class-name#. - -```mermaid-example -graph TD - B["fa:fa-twitter for peace"] - B-->C[fa:fa-ban forbidden] - B-->D(fa:fa-spinner); - B-->E(A fa:fa-camera-retro perhaps?); -``` - -```mermaid -graph TD - B["fa:fa-twitter for peace"] - B-->C[fa:fa-ban forbidden] - B-->D(fa:fa-spinner); - B-->E(A fa:fa-camera-retro perhaps?); -``` - -## Graph declarations with spaces between vertices and link and without semicolon - -- After release 0.2.16, graph declaration statements do not need to end with a semicolon. (And they can continue to have the ending semicolon—it has now just become optional.) So the below graph declaration is valid along with the old declarations. - -- A single space is allowed between vertices and the link, however there should not be any space between a vertex and its text, or a link and its text. The old syntax of graph declarations will also work, so this new feature is optional and is introduced to improve readability. - -Below is an example of the new way to declare graph edges. This is valid alongside any old-style declarations of graph edges. - -```mermaid-example -graph LR - A[Hard edge] -->|Link text| B(Round edge) - B --> C{Decision} - C -->|One| D[Result one] - C -->|Two| E[Result two] -``` - -```mermaid -graph LR - A[Hard edge] -->|Link text| B(Round edge) - B --> C{Decision} - C -->|One| D[Result one] - C -->|Two| E[Result two] -``` - -## Configuration... - -Is it possible to adjust the width of the rendered flowchart. - -This is done by defining **mermaid.flowchartConfig**, or by the CLI to use a json file with the configuration (which is described in the mermaidCLI page). -In Javascript config parameters can be set by using `mermaid.flowchartConfig`: - -```javascript -mermaid.flowchartConfig = { - width: '100%', -}; -``` diff --git a/docs/img/Configuration.png b/docs/img/Configuration.png deleted file mode 100644 index 60a808f2c..000000000 Binary files a/docs/img/Configuration.png and /dev/null differ diff --git a/docs/img/Editing-process.png b/docs/img/Editing-process.png deleted file mode 100644 index a49b35224..000000000 Binary files a/docs/img/Editing-process.png and /dev/null differ diff --git a/docs/img/EditingHistory+Links.png b/docs/img/EditingHistory+Links.png deleted file mode 100644 index 3891f39c1..000000000 Binary files a/docs/img/EditingHistory+Links.png and /dev/null differ diff --git a/docs/img/GitHub-Mark-32px.png b/docs/img/GitHub-Mark-32px.png deleted file mode 100644 index 790fa7710..000000000 Binary files a/docs/img/GitHub-Mark-32px.png and /dev/null differ diff --git a/docs/img/Live-Editor-Usage.png b/docs/img/Live-Editor-Usage.png deleted file mode 100644 index 04df642dc..000000000 Binary files a/docs/img/Live-Editor-Usage.png and /dev/null differ diff --git a/docs/img/book-banner-post-release.jpeg b/docs/img/book-banner-post-release.jpeg deleted file mode 100644 index 005a3282b..000000000 Binary files a/docs/img/book-banner-post-release.jpeg and /dev/null differ diff --git a/docs/img/book-banner-post-release.png b/docs/img/book-banner-post-release.png deleted file mode 100644 index 7db35ea7a..000000000 Binary files a/docs/img/book-banner-post-release.png and /dev/null differ diff --git a/docs/img/book-banner-pre-release.jpg b/docs/img/book-banner-pre-release.jpg deleted file mode 100644 index 6dc996fd9..000000000 Binary files a/docs/img/book-banner-pre-release.jpg and /dev/null differ diff --git a/docs/img/book-banner-pre-release.png b/docs/img/book-banner-pre-release.png deleted file mode 100644 index b85b165db..000000000 Binary files a/docs/img/book-banner-pre-release.png and /dev/null differ diff --git a/docs/img/class.png b/docs/img/class.png deleted file mode 100644 index fde265f63..000000000 Binary files a/docs/img/class.png and /dev/null differ diff --git a/docs/img/flow.png b/docs/img/flow.png deleted file mode 100644 index 37537c18f..000000000 Binary files a/docs/img/flow.png and /dev/null differ diff --git a/docs/img/gantt.png b/docs/img/gantt.png deleted file mode 100644 index 304b598b8..000000000 Binary files a/docs/img/gantt.png and /dev/null differ diff --git a/docs/img/git.png b/docs/img/git.png deleted file mode 100644 index 2da331a1e..000000000 Binary files a/docs/img/git.png and /dev/null differ diff --git a/docs/img/n00b-firstFlow.png b/docs/img/n00b-firstFlow.png deleted file mode 100644 index 5d3c7738d..000000000 Binary files a/docs/img/n00b-firstFlow.png and /dev/null differ diff --git a/docs/img/new-diagrams.png b/docs/img/new-diagrams.png deleted file mode 100644 index bd9c8c97a..000000000 Binary files a/docs/img/new-diagrams.png and /dev/null differ diff --git a/docs/img/sequence.png b/docs/img/sequence.png deleted file mode 100644 index f37d523f8..000000000 Binary files a/docs/img/sequence.png and /dev/null differ diff --git a/docs/img/simple-er.png b/docs/img/simple-er.png deleted file mode 100644 index 6ebf41352..000000000 Binary files a/docs/img/simple-er.png and /dev/null differ diff --git a/docs/img/user-journey.png b/docs/img/user-journey.png deleted file mode 100644 index 825d467d8..000000000 Binary files a/docs/img/user-journey.png and /dev/null differ diff --git a/docs/img/without wrap.png b/docs/img/without wrap.png deleted file mode 100644 index 038408d2b..000000000 Binary files a/docs/img/without wrap.png and /dev/null differ diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index c4eb48af8..000000000 --- a/docs/index.html +++ /dev/null @@ -1,163 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <!--# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs.--><head> - <meta charset="UTF-8" /> - <title> - mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, - gantt charts and git graphs. - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - diff --git a/docs/img/Code-Preview-Config.png b/docs/intro/img/Code-Preview-Config.png similarity index 100% rename from docs/img/Code-Preview-Config.png rename to docs/intro/img/Code-Preview-Config.png diff --git a/docs/img/Live-Editor-Choices.png b/docs/intro/img/Live-Editor-Choices.png similarity index 100% rename from docs/img/Live-Editor-Choices.png rename to docs/intro/img/Live-Editor-Choices.png diff --git a/docs/img/book-banner-post-release.jpg b/docs/intro/img/book-banner-post-release.jpg similarity index 100% rename from docs/img/book-banner-post-release.jpg rename to docs/intro/img/book-banner-post-release.jpg diff --git a/docs/README.md b/docs/intro/index.md similarity index 77% rename from docs/README.md rename to docs/intro/index.md index 00e03c76d..5aa068e27 100644 --- a/docs/README.md +++ b/docs/intro/index.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/intro/index.md](../../packages/mermaid/src/docs/intro/index.md). # About Mermaid @@ -6,11 +10,11 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. -> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](./n00b-syntaxReference.md). +> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference.md). - + -[![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) +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) @@ -26,12 +30,12 @@ Diagramming and documentation costs precious developer time and gets outdated qu But not having diagrams or docs ruins productivity and hurts organizational learning.
Mermaid addresses this problem by enabling users to create easily modifiable diagrams, it can also be made part of production scripts (and other pieces of code).

Mermaid allows even non-programmers to easily create detailed and diagrams through the [Mermaid Live Editor](https://mermaid.live/).
-[Tutorials](./Tutorials.md) has video tutorials. -Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./integrations.md). +[Tutorials](../config/Tutorials.md) has video tutorials. +Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](../misc/integrations.md). -For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./n00b-overview.md) and [Usage](./usage.md). +For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](../community/n00b-overview.md) and [Usage](../config/usage.md). -🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/docs/development.md) | 📜 [Version Log](./CHANGELOG.md) | 🔌 [Plug-Ins](./integrations.md) +🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](../community/development.md) | 🔌 [Plug-Ins](../misc/integrations.md) > 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/knsv/mermaid/issues/866). @@ -47,7 +51,7 @@ In our release process we rely heavily on visual regression tests using [applito ## Diagram Types -### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax) +### [Flowchart](../syntax/flowchart.md?id=flowcharts-basic-syntax) ```mermaid-example graph TD; @@ -65,9 +69,7 @@ graph TD; C-->D; ``` -![Flowchart](img/flow.png) - -### [Sequence diagram](./sequenceDiagram.md) +### [Sequence diagram](../syntax/sequenceDiagram.md) ```mermaid-example sequenceDiagram @@ -97,9 +99,7 @@ sequenceDiagram Bob-->>John: Jolly good! ``` -![Sequence diagram](img/sequence.png) - -### [Gantt diagram](./gantt.md) +### [Gantt diagram](../syntax/gantt.md) ```mermaid-example gantt @@ -127,9 +127,7 @@ Future task : des3, after des2, 5d Future task2 : des4, after des3, 5d ``` -![Gantt diagram](img/gantt.png) - -### [Class diagram](./classDiagram.md) +### [Class diagram](../syntax/classDiagram.md) ```mermaid-example classDiagram @@ -165,9 +163,7 @@ Class01 : int gorilla Class08 <--> C2: Cool label ``` -![Class diagram](img/class.png) - -### Git graph +### [Git graph](../syntax/gitgraph.md) ```mermaid-example gitGraph @@ -195,7 +191,7 @@ Class08 <--> C2: Cool label commit ``` -### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md) +### [Entity Relationship Diagram - :exclamation: experimental](../syntax/entityRelationshipDiagram.md) ```mermaid-example erDiagram @@ -213,9 +209,7 @@ erDiagram ``` -![ER diagram](img/simple-er.png) - -### [User Journey Diagram](./user-journey.md) +### [User Journey Diagram](../syntax/userJourney.md) ```mermaid-example journey @@ -241,13 +235,11 @@ journey Sit down: 5: Me ``` -![Journey diagram](img/user-journey.png) - ## Installation -**In depth guides and examples can be found at [Getting Started](/n00b-gettingStarted) and [Usage](/usage).** +**In depth guides and examples can be found at [Getting Started](./n00b-gettingStarted.md) and [Usage](../config/usage.md).** -**It would also be helpful to learn more about mermaid's [Syntax](/n00b-syntaxReference).** +**It would also be helpful to learn more about mermaid's [Syntax](./n00b-syntaxReference.md).** ### CDN @@ -264,25 +256,25 @@ Latest Version: To Deploy Mermaid: 1. You will need to install node v16, which would have npm -2. Download yarn using npm -3. Enter the following command: `yarn add mermaid` -4. You can then add mermaid as a dev dependency using this command: - `yarn add --dev mermaid` +2. Install mermaid + - NPM: `npm i mermaid` + - Yarn: `yarn add mermaid` + - Pnpm: `pnpm add mermaid` -### [Mermaid API](./Setup.md): +### [Mermaid API](../config/setup/README.md): -**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:** +**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:** ```html - - ``` -**Doing so will command the mermaid parser to look for the `
` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.** +**Doing so will command the mermaid parser to look for the `
` or `
` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
 
-**Examples can be found at** [Other examples](/examples)
+**Examples can be found at** [Other examples](../syntax/examples.md)
 
 ## Sibling projects
 
@@ -308,22 +300,26 @@ Don't hesitate to contact me if you want to get involved!
 
 ## For contributors
 
-### Setup
+### Requirements
 
-```sh
-yarn install
-```
+- [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`
 
-### Build
+## Development Installation
 
-```sh
-yarn build:watch
+```bash
+git clone git@github.com:mermaid-js/mermaid.git
+cd mermaid
+# npx is required for first install as volta support for pnpm is not added yet.
+npx pnpm install
+pnpm test
 ```
 
 ### Lint
 
 ```sh
-yarn lint
+pnpm lint
 ```
 
 We use [eslint](https://eslint.org/).
@@ -332,7 +328,7 @@ We recommend you to install [editor plugins](https://eslint.org/docs/user-guide/
 ### Test
 
 ```sh
-yarn test
+pnpm test
 ```
 
 Manual test in browser: open `dist/index.html`
@@ -347,7 +343,7 @@ Update version number in `package.json`.
 npm publish
 ```
 
-The above command generates files into the `dist` folder and publishes them to npmjs.org.
+The above command generates files into the `dist` folder and publishes them to \.
 
 ## Related projects
 
@@ -359,11 +355,11 @@ The above command generates files into the `dist` folder and publishes them to n
 
 Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
 
-Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
+Detailed information about how to contribute can be found in the [contribution guide](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
 
 ## Security and safe diagrams
 
-For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
+For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitize the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
 
 As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing JavaScript in the code from being executed. This is a great step forward for better security.
 
@@ -377,10 +373,33 @@ 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!_
 
 ---
 
 _Mermaid was created by Knut Sveidqvist for easier documentation._
+
+
diff --git a/docs/n00b-gettingStarted.md b/docs/intro/n00b-gettingStarted.md
similarity index 69%
rename from docs/n00b-gettingStarted.md
rename to docs/intro/n00b-gettingStarted.md
index b82e2ff01..2a05a1fdd 100644
--- a/docs/n00b-gettingStarted.md
+++ b/docs/intro/n00b-gettingStarted.md
@@ -1,35 +1,59 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs.
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/intro/n00b-gettingStarted.md](../../packages/mermaid/src/docs/intro/n00b-gettingStarted.md).
 
 # A Mermaid User-Guide for Beginners
 
 Mermaid is composed of three parts: Deployment, Syntax and Configuration.
 
-This section talks about the different ways to deploy Mermaid. Learning the [Syntax](./n00b-syntaxReference.md) would be of great help to the beginner.
+This section talks about the different ways to deploy Mermaid. Learning the [Syntax](n00b-syntaxReference.md) would be of great help to the beginner.
 
 > Generally the live editor is enough for most general uses of mermaid, and is a good place to start learning.
 
-**Absolute beginners are advised to view the Video [Tutorials](./Tutorials.md) on the Live Editor, to gain a better understanding of mermaid.**
+**Absolute beginners are advised to view the Video [Tutorials](../config/Tutorials.md) on the Live Editor, to gain a better understanding of mermaid.**
 
 ## Four ways of using mermaid:
 
 1.  Using the Mermaid Live Editor at [mermaid.live](https://mermaid.live).
-2.  Using [mermaid plugins](./integrations.md) with programs you are familiar with.
+2.  Using [mermaid plugins](../misc/integrations.md) with programs you are familiar with.
 3.  Calling the Mermaid JavaScript API.
 4.  Deploying Mermaid as a dependency.
 
 **Note: It is our recommendation that you review all approaches, and choose the one that is best for your project.**
 
-> More in depth information can be found at [Usage](./usage.md).
+> More in depth information can be found at [Usage](../config/usage.md).
 
 ## 1. Using the Live Editor
 
 Available at [mermaid.live](https://mermaid.live)
 
-![EditingProcess](./img/Editing-process.png)
+```mermaid-example
+graph TD
+    A[Enter Chart Definition] --> B(Preview)
+    B --> C{decide}
+    C --> D[Keep]
+    C --> E[Edit Definition]
+    E --> B
+    D --> F[Save Image and Code]
+    F --> B
+```
+
+```mermaid
+graph TD
+    A[Enter Chart Definition] --> B(Preview)
+    B --> C{decide}
+    C --> D[Keep]
+    C --> E[Edit Definition]
+    E --> B
+    D --> F[Save Image and Code]
+    F --> B
+```
 
 In the `Code` section one can write or edit raw mermaid code, and instantly `Preview` the rendered result on the panel beside it.
 
-The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](./n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](Setup.md) page.
+The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README.md) page.
 
 ![Code,Config and Preview](./img/Code-Preview-Config.png)
 
@@ -61,9 +85,9 @@ and to View, https://mermaid.live/view?gist=https://gist.github.com/sidharthv96/
 
 ## 2. Using Mermaid Plugins:
 
-You can generate mermaid diagrams from within popular applications using plug-ins. It can be done in the same way, you would use the Live Editor. Here's a list of [Mermaid Plugins](./integrations.md).
+You can generate mermaid diagrams from within popular applications using plug-ins. It can be done in the same way, you would use the Live Editor. Here's a list of [Mermaid Plugins](../misc/integrations.md).
 
-**This is covered in greater detail in the [Usage section](usage.md)**
+**This is covered in greater detail in the [Usage section](../config/usage.md)**
 
 ## 3. Calling the JavaScript API
 
@@ -75,23 +99,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
 
 ### Requirements for the Mermaid API.
 
-When writing the .html file, we give three instructions inside the html code to the web browser:
+When writing the .html file, we give two instructions inside the html code to the web browser:
 
-a. A reference for fetching the online mermaid renderer, through the `mermaid.js` or `mermaid.min.js`.
+a. The mermaid code for the diagram we want to create.
 
-b. The mermaid code for the diagram we want to create.
+b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
 
-c. The `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
-
-**a. A reference to the external CDN in a `
-
-```
-
-**b. The embedded mermaid diagram definition inside a `
`:**
+**a. The embedded mermaid diagram definition inside a `
`:**
 
 ```html
 
@@ -107,13 +121,14 @@ c. The `mermaid.initialize()` call, which dictates the appearance of diagrams an
 
 **Notes**: Every Mermaid chart/graph/diagram definition, should have separate `
` tags.
 
-**c. The `mermaid.initialize()` call.**
+**b. The import of mermaid and the `mermaid.initialize()` call.**
 
 `mermaid.initialize()` call takes all the definitions contained in all the `
` tags that it finds in the html body and renders them into diagrams. Example:
 
 ```html
 
-  
 
@@ -128,6 +143,10 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
 | ----------- | --------------------------------- | ------- | ----------- |
 | startOnLoad | Toggle for Rendering upon loading | Boolean | true, false |
 
+### Adding external diagrams to mermaid
+
+Please refer to the [Mindmap](../syntax/mindmap.md?id=integrating-with-your-librarywebsite) section for more information.
+
 ### Working Examples
 
 **Here is a full working example of the mermaidAPI being called through the CDN:**
@@ -135,11 +154,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
 ```html
 
   
-    
-    
-
     Here is one mermaid diagram:
     
             graph TD 
@@ -156,6 +170,11 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
             B -->|tcp_456| C[Server1] 
             B -->|tcp_456| D[Server2]
     
+ + ``` @@ -181,8 +200,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file, B --> C[Server1] B --> D[Server2]
- - @@ -206,4 +225,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file, **Comments from Knut Sveidqvist, creator of mermaid:** -- In early versions of mermaid, the ` - - - - - - -
-
- -
-
-
-

MermaidPress

-

- The Official Guide to Mermaid.js -

-

- Learn to create complex diagrams and beautiful flowcharts easily using text and code - using Mermaid.js. -

- - - -
-
-
- -
- -
-
-
-
- - - - - - - - - - - - -
-
-
-

- Get up to speed with using Mermaid diagrams along with real-world examples and expert tips - from the authors to facilitate a seamless development workflow -

-
-
-
-
-
-

- Flowcharts is a diagram type that visualizes a process or an algorithm by showing the - steps in order, as well as the different paths the execution can take. -

-
-
- -
-
-
-
- -
-
-
-

- Sequence diagrams lets you model and visualize interactions between different actors - or objects in a system, as well as the order of those interactions -

-
-
-
-
-
-

- A class diagram is a graphical representation that is used to visualize and describe - an object-oriented system. -

-
-
- -
-
-
-
- -
-
-
-

- An entity-relationship diagram is a graphical representation that is used to - visualize the different types of entities that exist within a system. -

-
-
-
-
-
-

- Use State diagrams to model and document state machines, an abstract way of - representing a system or an algorithm. -

-
-
- -
-
-
-
- -
-
-
-

- A Gantt chart is a graphical representation that is used to visualize and describe - tasks (events or activities) over time. -

-
-
-
-
-

- These were a few of the diagrams supported by Mermaid. -

-
- -
-
-

- Book description -

-
-

- Mermaid lets you represent diagrams using text and code which simplifies the maintenance - of complex diagrams. This is a great option for developers as they’re more familiar with - code, rather than special tools for generating diagrams. Besides, diagrams in code - simplify maintenance and ensure that the code is supported by version control systems. - In some cases, Mermaid makes refactoring support for name changes possible while also - enabling team collaboration for review distribution and updates. -

-

- Developers working with any system will be able to put their knowledge to work with this - practical guide to using Mermaid for documentation. The book is also a great reference - for looking up the syntax for specific diagrams when authoring diagrams. -

-

- You’ll start by getting up to speed with the importance of accurate and visual - documentation. Next, the book introduces Mermaid and establishes how to use it to create - effective documentation. By using different tools, editors, or a custom documentation - platform, you’ll also learn how to use Mermaid syntax for various diagrams. Later - chapters cover advanced configuration settings and theme options to manipulate your - diagram as per your needs. -

-

- By the end of this Mermaid book, you’ll have become well-versed with the different types - of Mermaid diagrams and how they can be used in your workflows. -

-
-
-
-
-
-

- What you will learn -

-
-
-
-
-
-
-
    -
  • - Understand good and bad documentation, and the art of effective documentation -
  • -
  • - Become well-versed with maintaining complex diagrams with ease -
  • -
  • - Learn how to set up a custom documentation system -
  • -
  • - Learn how to implement Mermaid diagrams in your workflows -
  • -
  • - Understand how to set up themes for a Mermaid diagram for an entire site -
  • -
  • - Discover how to draw different types of diagrams such as flowcharts, class - diagrams, Gantt charts, and more -
  • -
-
-
-
-
-
- - - - - - - - - - - - - - - - - -
-

- Purchase The Official Guide to Mermaid.js -

-
-
-
-

-

Written by Knut Sveidqvist and Ashish Jain.

-

- Knut is the creator of Mermaid and both authors are active core team members of the - Mermaid open-source project. -

-

- - - -
- - - diff --git a/docs/landing/sequence-diagram.png b/docs/landing/sequence-diagram.png deleted file mode 100644 index 8c51ac1c5..000000000 Binary files a/docs/landing/sequence-diagram.png and /dev/null differ diff --git a/docs/landing/state.png b/docs/landing/state.png deleted file mode 100644 index 2ef66ea2f..000000000 Binary files a/docs/landing/state.png and /dev/null differ diff --git a/docs/mermaidCLI.md b/docs/mermaidCLI.md deleted file mode 100644 index 01860cab2..000000000 --- a/docs/mermaidCLI.md +++ /dev/null @@ -1,5 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -# mermaid CLI - -mermaid CLI has been moved to [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). Please read its documentation instead. diff --git a/docs/faq.md b/docs/misc/faq.md similarity index 83% rename from docs/faq.md rename to docs/misc/faq.md index a24b436b6..c7155a5b0 100644 --- a/docs/faq.md +++ b/docs/misc/faq.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/misc/faq.md](../../packages/mermaid/src/docs/misc/faq.md). # Frequently Asked Questions diff --git a/packages/mermaid/src/docs/integrations.md b/docs/misc/integrations.md similarity index 96% rename from packages/mermaid/src/docs/integrations.md rename to docs/misc/integrations.md index 2b25cb600..007b9e778 100644 --- a/packages/mermaid/src/docs/integrations.md +++ b/docs/misc/integrations.md @@ -1,3 +1,9 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/misc/integrations.md](../../packages/mermaid/src/docs/misc/integrations.md). + # Integrations The following list is a compilation of different integrations and plugins that allow the rendering of mermaid definitions within other applications. @@ -31,8 +37,9 @@ They also serve as proof of concept, for the variety of things that can be built - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro) - [redmine-mermaid](https://github.com/styz/redmine_mermaid) - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin) -- [Jetsbrain IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) +- [JetBrains IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) - [mermerd](https://github.com/KarnerTh/mermerd) +- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive) ## CRM/ERP/Similar @@ -115,6 +122,7 @@ They also serve as proof of concept, for the variety of things that can be built - [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin) - [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid) - [Vim](https://www.vim.org) + - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid) - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram) - [GNU Emacs](https://www.gnu.org/software/emacs/) - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode) @@ -161,7 +169,6 @@ They also serve as proof of concept, for the variety of things that can be built | Extensions for Mermaid | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) | | Chrome Diagrammer | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - | | Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - | -| Mermaid Markdown | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg) | - | - | - | - | | Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - | | Mermaid Previewer | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-previewer/oidjnlhbegipkcklbdfnbkikplpghfdl) | - | - | - | - | diff --git a/docs/.nojekyll b/docs/public/.nojekyll similarity index 100% rename from docs/.nojekyll rename to docs/public/.nojekyll diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico new file mode 100644 index 000000000..d41818c5b Binary files /dev/null and b/docs/public/favicon.ico differ diff --git a/docs/public/favicon.png b/docs/public/favicon.png new file mode 100644 index 000000000..05d8a737b Binary files /dev/null and b/docs/public/favicon.png differ diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg new file mode 100644 index 000000000..993c56b94 --- /dev/null +++ b/docs/public/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/img/header.png b/docs/public/header.png similarity index 100% rename from docs/img/header.png rename to docs/public/header.png diff --git a/docs/public/manifest.json b/docs/public/manifest.json new file mode 100644 index 000000000..85c11395c --- /dev/null +++ b/docs/public/manifest.json @@ -0,0 +1,14 @@ +{ + "short_name": "Mermaid", + "name": "Mermaid JS", + "icons": [ + { + "src": "/favicon.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "background_color": "#6366F1", + "display": "standalone", + "theme_color": "#6366F1" +} diff --git a/docs/public/mermaid-logo.svg b/docs/public/mermaid-logo.svg new file mode 100644 index 000000000..5ac259968 --- /dev/null +++ b/docs/public/mermaid-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/stateDiagram.md b/docs/stateDiagram.md deleted file mode 100644 index ecea7cf5d..000000000 --- a/docs/stateDiagram.md +++ /dev/null @@ -1,446 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -# State diagrams - -> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia - -Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml. - -```mermaid-example -stateDiagram-v2 - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -```mermaid -stateDiagram-v2 - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -Older renderer: - -```mermaid-example -stateDiagram - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -```mermaid -stateDiagram - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash. - -## States - -A state can be declared in multiple ways. The simplest way is to define a state id as a description. - -```mermaid-example -stateDiagram-v2 - s1 -``` - -```mermaid -stateDiagram-v2 - s1 -``` - -Another way is by using the state keyword with a description as per below: - -```mermaid-example -stateDiagram-v2 - state "This is a state description" as s2 -``` - -```mermaid -stateDiagram-v2 - state "This is a state description" as s2 -``` - -Another way to define a state with a description is to define the state id followed by a colon and the description: - -```mermaid-example -stateDiagram-v2 - s2 : This is a state description -``` - -```mermaid -stateDiagram-v2 - s2 : This is a state description -``` - -## Transitions - -Transitions are path/edges when one state passes into another. This is represented using text arrow, "-->". - -When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way. - -```mermaid-example -stateDiagram-v2 - s1 --> s2 -``` - -```mermaid -stateDiagram-v2 - s1 --> s2 -``` - -It is possible to add text to a transition. To describe what it represents. - -```mermaid-example -stateDiagram-v2 - s1 --> s2: A transition -``` - -```mermaid -stateDiagram-v2 - s1 --> s2: A transition -``` - -## Start and End - -There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and the direction of the transition to it defines it either as a start or a stop state. - -```mermaid-example -stateDiagram-v2 - [*] --> s1 - s1 --> [*] -``` - -```mermaid -stateDiagram-v2 - [*] --> s1 - s1 --> [*] -``` - -## Composite states - -In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can -have several internal states. These are called composite states in this terminology. - -In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between {}. See the example below: - -```mermaid-example -stateDiagram-v2 - [*] --> First - state First { - [*] --> second - second --> [*] - } -``` - -```mermaid -stateDiagram-v2 - [*] --> First - state First { - [*] --> second - second --> [*] - } -``` - -You can do this in several layers: - -```mermaid-example -stateDiagram-v2 - [*] --> First - - state First { - [*] --> Second - - state Second { - [*] --> second - second --> Third - - state Third { - [*] --> third - third --> [*] - } - } - } -``` - -```mermaid -stateDiagram-v2 - [*] --> First - - state First { - [*] --> Second - - state Second { - [*] --> second - second --> Third - - state Third { - [*] --> third - third --> [*] - } - } - } -``` - -You can also define transitions also between composite states: - -```mermaid-example -stateDiagram-v2 - [*] --> First - First --> Second - First --> Third - - state First { - [*] --> fir - fir --> [*] - } - state Second { - [*] --> sec - sec --> [*] - } - state Third { - [*] --> thi - thi --> [*] - } -``` - -```mermaid -stateDiagram-v2 - [*] --> First - First --> Second - First --> Third - - state First { - [*] --> fir - fir --> [*] - } - state Second { - [*] --> sec - sec --> [*] - } - state Third { - [*] --> thi - thi --> [*] - } -``` - -_You can not define transitions between internal states belonging to different composite states_ - -## Choice - -Sometimes you need to model a choice between two or more paths, you can do so using <\>. - -```mermaid-example -stateDiagram-v2 - state if_state <> - [*] --> IsPositive - IsPositive --> if_state - if_state --> False: if n < 0 - if_state --> True : if n >= 0 -``` - -```mermaid -stateDiagram-v2 - state if_state <> - [*] --> IsPositive - IsPositive --> if_state - if_state --> False: if n < 0 - if_state --> True : if n >= 0 -``` - -## Forks - -It is possible to specify a fork in the diagram using <\> <\>. - -```mermaid-example - stateDiagram-v2 - state fork_state <> - [*] --> fork_state - fork_state --> State2 - fork_state --> State3 - - state join_state <> - State2 --> join_state - State3 --> join_state - join_state --> State4 - State4 --> [*] -``` - -```mermaid - stateDiagram-v2 - state fork_state <> - [*] --> fork_state - fork_state --> State2 - fork_state --> State3 - - state join_state <> - State2 --> join_state - State3 --> join_state - join_state --> State4 - State4 --> [*] -``` - -## Notes - -Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams. - -Here you can choose to put the note to the _right of_ or to the _left of_ a node. - -```mermaid-example - stateDiagram-v2 - State1: The state with a note - note right of State1 - Important information! You can write - notes. - end note - State1 --> State2 - note left of State2 : This is the note to the left. -``` - -```mermaid - stateDiagram-v2 - State1: The state with a note - note right of State1 - Important information! You can write - notes. - end note - State1 --> State2 - note left of State2 : This is the note to the left. -``` - -## Concurrency - -As in plantUml you can specify concurrency using the -- symbol. - -```mermaid-example -stateDiagram-v2 - [*] --> Active - - state Active { - [*] --> NumLockOff - NumLockOff --> NumLockOn : EvNumLockPressed - NumLockOn --> NumLockOff : EvNumLockPressed - -- - [*] --> CapsLockOff - CapsLockOff --> CapsLockOn : EvCapsLockPressed - CapsLockOn --> CapsLockOff : EvCapsLockPressed - -- - [*] --> ScrollLockOff - ScrollLockOff --> ScrollLockOn : EvScrollLockPressed - ScrollLockOn --> ScrollLockOff : EvScrollLockPressed - } -``` - -```mermaid -stateDiagram-v2 - [*] --> Active - - state Active { - [*] --> NumLockOff - NumLockOff --> NumLockOn : EvNumLockPressed - NumLockOn --> NumLockOff : EvNumLockPressed - -- - [*] --> CapsLockOff - CapsLockOff --> CapsLockOn : EvCapsLockPressed - CapsLockOn --> CapsLockOff : EvCapsLockPressed - -- - [*] --> ScrollLockOff - ScrollLockOff --> ScrollLockOn : EvScrollLockPressed - ScrollLockOn --> ScrollLockOff : EvScrollLockPressed - } -``` - -## Setting the direction of the diagram - -With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example. - -```mermaid-example -stateDiagram - direction LR - [*] --> A - A --> B - B --> C - state B { - direction LR - a --> b - } - B --> D -``` - -```mermaid -stateDiagram - direction LR - [*] --> A - A --> B - B --> C - state B { - direction LR - a --> b - } - B --> D -``` - -## Comments - -Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax - -```mermaid-example -stateDiagram-v2 - [*] --> Still - Still --> [*] -%% this is a comment - Still --> Moving - Moving --> Still %% another comment - Moving --> Crash - Crash --> [*] -``` - -```mermaid -stateDiagram-v2 - [*] --> Still - Still --> [*] -%% this is a comment - Still --> Moving - Moving --> Still %% another comment - Moving --> Crash - Crash --> [*] -``` - -## Styling - -Styling of the a state diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/state.scss - -## Spaces in state names - -Spaces can be added to a state by defining it at the top and referencing the acronym later. - -```mermaid-example -stateDiagram-v2 - Yswsii: Your state with spaces in it - [*] --> Yswsii -``` - -```mermaid -stateDiagram-v2 - Yswsii: Your state with spaces in it - [*] --> Yswsii -``` diff --git a/docs/c4c.md b/docs/syntax/c4c.md similarity index 98% rename from docs/c4c.md rename to docs/syntax/c4c.md index 40dbb6fe6..e946aedb6 100644 --- a/docs/c4c.md +++ b/docs/syntax/c4c.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/c4c.md](../../packages/mermaid/src/docs/syntax/c4c.md). # C4 Diagrams @@ -220,7 +224,7 @@ The following unfinished features are not supported in the short term. - - \[x] RelIndex \* Compatible with C4-Plantuml syntax, but ignores the index parameter. The sequence number is determined by the order in which the rel statements are written. -- \[ ] Custom tags/stereotypes support and skinparam updates +- \[ ] Custom tags/stereotypes support and skin param updates - - \[ ] AddElementTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new element tag. The styles of the tagged elements are updated and the tag is displayed in the calculated legend. @@ -563,7 +567,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60") Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.") } - Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){ + Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){ Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } @@ -615,7 +619,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60") Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.") } - Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){ + Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){ Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } diff --git a/docs/classDiagram.md b/docs/syntax/classDiagram.md similarity index 94% rename from docs/classDiagram.md rename to docs/syntax/classDiagram.md index 529933b98..5870d0743 100644 --- a/docs/classDiagram.md +++ b/docs/syntax/classDiagram.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/classDiagram.md](../../packages/mermaid/src/docs/syntax/classDiagram.md). # Class diagrams @@ -10,8 +14,13 @@ The class diagram is the main building block of object-oriented modeling. It is Mermaid can render class diagrams. ```mermaid-example +--- +title: Animal example +--- classDiagram + note "From Duck till Zebra" Animal <|-- Duck + note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging" Animal <|-- Fish Animal <|-- Zebra Animal : +int age @@ -34,8 +43,13 @@ classDiagram ``` ```mermaid +--- +title: Animal example +--- classDiagram + note "From Duck till Zebra" Animal <|-- Duck + note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging" Animal <|-- Fish Animal <|-- Zebra Animal : +int age @@ -69,6 +83,9 @@ A single instance of a class in the diagram contains three compartments: - The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase. ```mermaid-example +--- +title: Bank example +--- classDiagram class BankAccount BankAccount : +String owner @@ -79,6 +96,9 @@ classDiagram ``` ```mermaid +--- +title: Bank example +--- classDiagram class BankAccount BankAccount : +String owner @@ -247,16 +267,16 @@ A relationship is a general term covering the specific types of logical connecti There are eight different types of relations defined for classes under UML which are currently supported: -| Type | Description | -| ---- | ------------- | ----------- | -| < | -- | Inheritance | -| \*-- | Composition | -| o-- | Aggregation | -| --> | Association | -| -- | Link (Solid) | -| ..> | Dependency | -| .. | > | Realization | -| .. | Link (Dashed) | +| Type | Description | +| ------- | ------------- | +| `<\|--` | Inheritance | +| `\*--` | Composition | +| `o--` | Aggregation | +| `-->` | Association | +| `--` | Link (Solid) | +| `..>` | Dependency | +| `..\|>` | Realization | +| `..` | Link (Dashed) | ```mermaid-example classDiagram @@ -352,14 +372,14 @@ Here is the syntax: Where `Relation Type` can be one of: -| Type | Description | -| ---- | ----------- | ----------- | -| < | | Inheritance | -| \* | Composition | -| o | Aggregation | -| > | Association | -| < | Association | -| | > | Realization | +| Type | Description | +| ----- | ----------- | +| `<\|` | Inheritance | +| `\*` | Composition | +| `o` | Aggregation | +| `>` | Association | +| `<` | Association | +| `\|>` | Realization | And `Link` can be one of: @@ -549,6 +569,10 @@ You would define these actions on a separate line after all classes have been de - (_optional_) tooltip is a string to be displayed when hovering over element (note: The styles of the tooltip are set by the class .mermaidTooltip.) - note: callback function will be called with the nodeId as parameter. +## Notes + +It is possible to add notes on diagram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` + ### Examples _URL Link:_ @@ -589,7 +613,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback" ```html @@ -653,10 +677,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
@@ -771,10 +799,10 @@ Beginner's tip—a full example using interactive links in a html context:
+``` + +You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done. diff --git a/docs/pie.md b/docs/syntax/pie.md similarity index 81% rename from docs/pie.md rename to docs/syntax/pie.md index f59efd93a..63f371e87 100644 --- a/docs/pie.md +++ b/docs/syntax/pie.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/pie.md](../../packages/mermaid/src/docs/syntax/pie.md). # Pie chart diagrams @@ -28,10 +32,10 @@ Drawing a pie chart is really simple in mermaid. - Start with `pie` keyword to begin the diagram - `showData` to render the actual data values after the legend text. This is **_OPTIONAL_** - Followed by `title` keyword and its value in string to give a title to the pie-chart. This is **_OPTIONAL_** -- Followed by dataSet +- Followed by dataSet. Pie slices will be ordered clockwise in the same order as the labels. - `label` for a section in the pie diagram within `" "` quotes. - Followed by `:` colon as separator - - Followed by `positive numeric value` (supported upto two decimal places) + - Followed by `positive numeric value` (supported up to two decimal places) \[pie] \[showData] (OPTIONAL) \[title] \[titlevalue] (OPTIONAL) diff --git a/docs/requirementDiagram.md b/docs/syntax/requirementDiagram.md similarity index 96% rename from docs/requirementDiagram.md rename to docs/syntax/requirementDiagram.md index cf4c4bdc6..f8a0cafa9 100644 --- a/docs/requirementDiagram.md +++ b/docs/syntax/requirementDiagram.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/requirementDiagram.md](../../packages/mermaid/src/docs/syntax/requirementDiagram.md). # Requirement Diagram diff --git a/docs/sequenceDiagram.md b/docs/syntax/sequenceDiagram.md similarity index 96% rename from docs/sequenceDiagram.md rename to docs/syntax/sequenceDiagram.md index 619f33243..ad88249be 100644 --- a/docs/sequenceDiagram.md +++ b/docs/syntax/sequenceDiagram.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/sequenceDiagram.md](../../packages/mermaid/src/docs/syntax/sequenceDiagram.md). # Sequence diagrams @@ -20,11 +24,10 @@ sequenceDiagram Alice-)John: See you later! ``` -```note -A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted. - -If unavoidable, one must use parentheses(), quotation marks "", or brackets {},[], to enclose the word "end". i.e : (end), [end], {end}. -``` +> **Note** +> A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted. +> +> If unavoidable, one must use parentheses(), quotation marks "", or brackets {},\[], to enclose the word "end". i.e : (end), \[end], {end}. ## Syntax @@ -724,10 +727,10 @@ text.actor { ## Configuration -Is it possible to adjust the margins for rendering the sequence diagram. +It is possible to adjust the margins for rendering the sequence diagram. This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration. -How to use the CLI is described in the [mermaidCLI](mermaidCLI) page. +How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page. `mermaid.sequenceConfig` can be set to a JSON string with config parameters or the corresponding object. ```javascript diff --git a/docs/syntax/stateDiagram.md b/docs/syntax/stateDiagram.md new file mode 100644 index 000000000..72d7ec63b --- /dev/null +++ b/docs/syntax/stateDiagram.md @@ -0,0 +1,650 @@ +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/stateDiagram.md](../../packages/mermaid/src/docs/syntax/stateDiagram.md). + +# State diagrams + +> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. +> State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the +> case, while at other times this is a reasonable abstraction." Wikipedia + +Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make +it easier for users to share diagrams between mermaid and plantUml. + +```mermaid-example +--- +title: Simple sample +--- +stateDiagram-v2 + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +```mermaid +--- +title: Simple sample +--- +stateDiagram-v2 + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +Older renderer: + +```mermaid-example +stateDiagram + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +```mermaid +stateDiagram + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via +a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the +**Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to +the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.) + +## States + +A state can be declared in multiple ways. The simplest way is to define a state with just an id: + +```mermaid-example +stateDiagram-v2 + stateId +``` + +```mermaid +stateDiagram-v2 + stateId +``` + +Another way is by using the state keyword with a description as per below: + +```mermaid-example +stateDiagram-v2 + state "This is a state description" as s2 +``` + +```mermaid +stateDiagram-v2 + state "This is a state description" as s2 +``` + +Another way to define a state with a description is to define the state id followed by a colon and the description: + +```mermaid-example +stateDiagram-v2 + s2 : This is a state description +``` + +```mermaid +stateDiagram-v2 + s2 : This is a state description +``` + +## Transitions + +Transitions are path/edges when one state passes into another. This is represented using text arrow, "-->". + +When you define a transition between two states and the states are not already defined, the undefined states are defined +with the id from the transition. You can later add descriptions to states defined this way. + +```mermaid-example +stateDiagram-v2 + s1 --> s2 +``` + +```mermaid +stateDiagram-v2 + s1 --> s2 +``` + +It is possible to add text to a transition to describe what it represents: + +```mermaid-example +stateDiagram-v2 + s1 --> s2: A transition +``` + +```mermaid +stateDiagram-v2 + s1 --> s2: A transition +``` + +## Start and End + +There are two special states indicating the start and stop of the diagram. These are written with the \[\*] syntax and +the direction of the transition to it defines it either as a start or a stop state. + +```mermaid-example +stateDiagram-v2 + [*] --> s1 + s1 --> [*] +``` + +```mermaid +stateDiagram-v2 + [*] --> s1 + s1 --> [*] +``` + +## Composite states + +In a real world use of state diagrams you often end up with diagrams that are multidimensional as one state can +have several internal states. These are called composite states in this terminology. + +In order to define a composite state you need to use the state keyword followed by an id and the body of the composite +state between {}. See the example below: + +```mermaid-example +stateDiagram-v2 + [*] --> First + state First { + [*] --> second + second --> [*] + } +``` + +```mermaid +stateDiagram-v2 + [*] --> First + state First { + [*] --> second + second --> [*] + } +``` + +You can do this in several layers: + +```mermaid-example +stateDiagram-v2 + [*] --> First + + state First { + [*] --> Second + + state Second { + [*] --> second + second --> Third + + state Third { + [*] --> third + third --> [*] + } + } + } +``` + +```mermaid +stateDiagram-v2 + [*] --> First + + state First { + [*] --> Second + + state Second { + [*] --> second + second --> Third + + state Third { + [*] --> third + third --> [*] + } + } + } +``` + +You can also define transitions also between composite states: + +```mermaid-example +stateDiagram-v2 + [*] --> First + First --> Second + First --> Third + + state First { + [*] --> fir + fir --> [*] + } + state Second { + [*] --> sec + sec --> [*] + } + state Third { + [*] --> thi + thi --> [*] + } +``` + +```mermaid +stateDiagram-v2 + [*] --> First + First --> Second + First --> Third + + state First { + [*] --> fir + fir --> [*] + } + state Second { + [*] --> sec + sec --> [*] + } + state Third { + [*] --> thi + thi --> [*] + } +``` + +_You can not define transitions between internal states belonging to different composite states_ + +## Choice + +Sometimes you need to model a choice between two or more paths, you can do so using <\>. + +```mermaid-example +stateDiagram-v2 + state if_state <> + [*] --> IsPositive + IsPositive --> if_state + if_state --> False: if n < 0 + if_state --> True : if n >= 0 +``` + +```mermaid +stateDiagram-v2 + state if_state <> + [*] --> IsPositive + IsPositive --> if_state + if_state --> False: if n < 0 + if_state --> True : if n >= 0 +``` + +## Forks + +It is possible to specify a fork in the diagram using <\> <\>. + +```mermaid-example + stateDiagram-v2 + state fork_state <> + [*] --> fork_state + fork_state --> State2 + fork_state --> State3 + + state join_state <> + State2 --> join_state + State3 --> join_state + join_state --> State4 + State4 --> [*] +``` + +```mermaid + stateDiagram-v2 + state fork_state <> + [*] --> fork_state + fork_state --> State2 + fork_state --> State3 + + state join_state <> + State2 --> join_state + State3 --> join_state + join_state --> State4 + State4 --> [*] +``` + +## Notes + +Sometimes nothing says it better than a Post-it note. That is also the case in state diagrams. + +Here you can choose to put the note to the _right of_ or to the _left of_ a node. + +```mermaid-example + stateDiagram-v2 + State1: The state with a note + note right of State1 + Important information! You can write + notes. + end note + State1 --> State2 + note left of State2 : This is the note to the left. +``` + +```mermaid + stateDiagram-v2 + State1: The state with a note + note right of State1 + Important information! You can write + notes. + end note + State1 --> State2 + note left of State2 : This is the note to the left. +``` + +## Concurrency + +As in plantUml you can specify concurrency using the -- symbol. + +```mermaid-example +stateDiagram-v2 + [*] --> Active + + state Active { + [*] --> NumLockOff + NumLockOff --> NumLockOn : EvNumLockPressed + NumLockOn --> NumLockOff : EvNumLockPressed + -- + [*] --> CapsLockOff + CapsLockOff --> CapsLockOn : EvCapsLockPressed + CapsLockOn --> CapsLockOff : EvCapsLockPressed + -- + [*] --> ScrollLockOff + ScrollLockOff --> ScrollLockOn : EvScrollLockPressed + ScrollLockOn --> ScrollLockOff : EvScrollLockPressed + } +``` + +```mermaid +stateDiagram-v2 + [*] --> Active + + state Active { + [*] --> NumLockOff + NumLockOff --> NumLockOn : EvNumLockPressed + NumLockOn --> NumLockOff : EvNumLockPressed + -- + [*] --> CapsLockOff + CapsLockOff --> CapsLockOn : EvCapsLockPressed + CapsLockOn --> CapsLockOff : EvCapsLockPressed + -- + [*] --> ScrollLockOff + ScrollLockOff --> ScrollLockOn : EvScrollLockPressed + ScrollLockOn --> ScrollLockOff : EvScrollLockPressed + } +``` + +## Setting the direction of the diagram + +With state diagrams you can use the direction statement to set the direction which the diagram will render like in this +example. + +```mermaid-example +stateDiagram + direction LR + [*] --> A + A --> B + B --> C + state B { + direction LR + a --> b + } + B --> D +``` + +```mermaid +stateDiagram + direction LR + [*] --> A + A --> B + B --> C + state B { + direction LR + a --> b + } + B --> D +``` + +## Comments + +Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their +own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next +newline will be treated as a comment, including any diagram syntax + +```mermaid-example +stateDiagram-v2 + [*] --> Still + Still --> [*] +%% this is a comment + Still --> Moving + Moving --> Still %% another comment + Moving --> Crash + Crash --> [*] +``` + +```mermaid +stateDiagram-v2 + [*] --> Still + Still --> [*] +%% this is a comment + Still --> Moving + Moving --> Still %% another comment + Moving --> Crash + Crash --> [*] +``` + +## Styling with classDefs + +As with other diagrams (like flowcharts), you can define a style in the diagram itself and apply that named style to a +state or states in the diagram. + +**These are the current limitations with state diagram classDefs:** + +1. Cannot be applied to start or end states +2. Cannot be applied to or within composite states + +_These are in development and will be available in a future version._ + +You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something +like a _CSS class_) +followed by _a name for the style,_ +and then one or more _property-value pairs_. Each _property-value pair_ is +a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by a colon (`:`) and then a _value._ + +Here is an example of a classDef with just one property-value pair: + + classDef movement font-style:italic; + +where + +- the _name_ of the style is `movement` +- the only _property_ is `font-style` and its _value_ is `italic` + +If you want to have more than one _property-value pair_ then you put a comma (`,`) between each _property-value pair._ + +Here is an example with three property-value pairs: + + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + +where + +- the _name_ of the style is `badBadEvent` +- the first _property_ is `fill` and its _value_ is `#f00` +- the second _property_ is `color` and its _value_ is `white` +- the third _property_ is `font-weight` and its _value_ is `bold` +- the fourth _property_ is `stroke-width` and its _value_ is `2px` +- the fifth _property_ is `stroke` and its _value_ is `yello` + +### Apply classDef styles to states + +There are two ways to apply a `classDef` style to a state: + +1. use the `class` keyword to apply a classDef style to one or more states in a single statement, or +2. use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow + to/from another state) + +#### 1. `class` statement + +A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is: + +```text + class [one or more state names, separated by commas] [name of a style defined with classDef] +``` + +Here is an example applying the `badBadEvent` style to a state named `Crash`: + +```text +class Crash badBadEvent +``` + +Here is an example applying the `movement` style to the two states `Moving` and `Crash`: + +```text +class Moving, Crash movement +``` + +Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement` +and `badBadEvent` + +```mermaid-example + stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*]--> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + class end badBadEvent +``` + +```mermaid + stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*]--> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + class end badBadEvent +``` + +#### 2. `:::` operator to apply a style to a state + +You can apply a classDef style to a state using the `:::` (three colons) operator. The syntax is + +```text +[state]:::[style name] +``` + +You can use this in a diagram within a statement using a class. This includes the start and end states. For example: + +```mermaid-example +stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*] --> Still:::notMoving + Still --> [*] + Still --> Moving:::movement + Moving --> Still + Moving --> Crash:::movement + Crash:::badBadEvent --> [*] +``` + +```mermaid +stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*] --> Still:::notMoving + Still --> [*] + Still --> Moving:::movement + Moving --> Still + Moving --> Crash:::movement + Crash:::badBadEvent --> [*] +``` + +## Spaces in state names + +Spaces can be added to a state by first defining the state with an id and then referencing the id later. + +In the following example there is a state with the id **yswsii** and description **Your state with spaces in it**. +After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`) +and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`).\ +(**yswsii** has been styled so that it is different from the other states.) + +```mermaid-example +stateDiagram + classDef yourState font-style:italic,font-weight:bold,fill:white + + yswsii: Your state with spaces in it + [*] --> yswsii:::yourState + [*] --> SomeOtherState + SomeOtherState --> YetAnotherState + yswsii --> YetAnotherState + YetAnotherState --> [*] +``` + +```mermaid +stateDiagram + classDef yourState font-style:italic,font-weight:bold,fill:white + + yswsii: Your state with spaces in it + [*] --> yswsii:::yourState + [*] --> SomeOtherState + SomeOtherState --> YetAnotherState + yswsii --> YetAnotherState + YetAnotherState --> [*] +``` diff --git a/docs/user-journey.md b/docs/syntax/userJourney.md similarity index 81% rename from docs/user-journey.md rename to docs/syntax/userJourney.md index e40efc5a9..73fcb7468 100644 --- a/docs/user-journey.md +++ b/docs/syntax/userJourney.md @@ -1,4 +1,8 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. +> **Warning** +> +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> +> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/userJourney.md](../../packages/mermaid/src/docs/syntax/userJourney.md). # User Journey Diagram diff --git a/docs/theme.css b/docs/theme.css deleted file mode 100644 index 28dbc0ab5..000000000 --- a/docs/theme.css +++ /dev/null @@ -1,827 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600'); -* { - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-text-size-adjust: none; - -webkit-touch-callout: none; - box-sizing: border-box; -} - -body:not(.ready) { - overflow: hidden; -} -body:not(.ready) .app-nav, -body:not(.ready) > nav, -body:not(.ready) [data-cloak] { - display: none; -} -div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; -} -div#app:empty:before { - content: 'Loading...'; -} -.emoji { - height: 1.2rem; - vertical-align: middle; -} -.progress { - background-color: var(--theme-color, #42b983); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; -} -.search .search-keyword, -.search a:hover { - color: var(--theme-color, #42b983); -} -.search .search-keyword { - font-style: normal; - font-weight: 700; -} -body, -html { - height: 100%; -} -body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #34495e; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; -} -img { - max-width: 100%; -} -a[disabled] { - cursor: not-allowed; - opacity: 0.6; -} -kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; -} -li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; -} -.app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; -} -.app-nav.no-badge { - margin-right: 25px; -} -.app-nav p { - margin: 0; -} -.app-nav > a { - margin: 0 1rem; - padding: 5px 0; -} -.app-nav li, -.app-nav ul { - display: inline-block; - list-style: none; - margin: 0; -} -.app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; -} -.app-nav a.active, -.app-nav a:hover { - color: var(--theme-color, #42b983); -} -.app-nav a.active { - border-bottom: 2px solid var(--theme-color, #42b983); -} -.app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; -} -.app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; -} -.app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; -} -.app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; -} -.app-nav li ul a.active { - border-bottom: 0; -} -.app-nav li:hover ul { - display: block; -} -.github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; -} -.github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; -} -.github-corner svg { - color: #fff; - fill: var(--theme-color, #42b983); - height: 80px; - width: 80px; -} -main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; -} -main.hidden { - display: none; -} -.anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; -} -.anchor span { - color: #34495e; -} -.anchor:hover { - text-decoration: underline; -} -.sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; -} -.sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; -} -.sidebar > h1 a { - color: inherit; - text-decoration: none; -} -.sidebar > h1 .app-nav { - display: block; - position: static; -} -.sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; -} -.sidebar li.collapse .app-sub-sidebar { - display: none; -} -.sidebar ul { - margin: 0 0 0 15px; - padding: 0; -} -.sidebar li > p { - font-weight: 700; - margin: 0; -} -.sidebar ul, -.sidebar ul li { - list-style: none; -} -.sidebar ul li a { - border-bottom: none; - display: block; -} -.sidebar ul li ul { - padding-left: 20px; -} -.sidebar::-webkit-scrollbar { - width: 4px; -} -.sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; -} -.sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); -} -.sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); -} -.sidebar-toggle { - background-color: transparent; - background-color: hsla(0, 0%, 100%, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; -} -.sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; -} -.sidebar-toggle span { - background-color: var(--theme-color, #42b983); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; -} -body.sticky .sidebar, -body.sticky .sidebar-toggle { - position: fixed; -} -.content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; -} -.markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; -} -.markdown-section > * { - box-sizing: border-box; - font-size: inherit; -} -.markdown-section > :first-child { - margin-top: 0 !important; -} -.markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; -} -.markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; -} -.markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; -} -.markdown-section th { - font-weight: 700; -} -.markdown-section td, -.markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; -} -.markdown-section tr { - border-top: 1px solid #ccc; -} -.markdown-section p.tip, -.markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; -} -.markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; -} -.markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #fff; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; -} -.markdown-section p.tip code { - background-color: #efefef; -} -.markdown-section p.tip em { - color: #34495e; -} -.markdown-section p.warn { - background: rgba(66, 185, 131, 0.1); - border-radius: 2px; - padding: 1rem; -} -.markdown-section ul.task-list > li { - list-style-type: none; -} -body.close .sidebar { - transform: translateX(-300px); -} -body.close .sidebar-toggle { - width: auto; -} -body.close .content { - left: 0; -} -@media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } -} -@media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: hsla(0, 0%, 100%, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } -} -@-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } -} -@keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } -} -section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; -} -section.cover.show { - display: flex; -} -section.cover.has-mask .mask { - background-color: #fff; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; -} -section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; -} -section.cover a { - color: inherit; -} -section.cover a, -section.cover a:hover { - text-decoration: none; -} -section.cover p { - line-height: 1.5rem; - margin: 1em 0; -} -section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; -} -section.cover h1 a { - display: block; -} -section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; -} -section.cover blockquote { - font-size: 1.5rem; - text-align: center; -} -section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; -} -section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #42b983); - box-sizing: border-box; - color: var(--theme-color, #42b983); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; -} -section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #42b983); - color: #fff; -} -section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; -} -section.cover .cover-main > p:last-child a:hover { - color: inherit; -} -section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #42b983); - transition: color 0.3s; -} -section.cover blockquote > p > a:hover { - color: var(--theme-color, #42b983); -} -.sidebar, -body { - background-color: #fff; -} -.sidebar { - color: #364149; -} -.sidebar li { - margin: 6px 0; -} -.sidebar ul li a { - color: #505d6b; - font-size: 14px; - font-weight: 400; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; -} -.sidebar ul li a:hover { - text-decoration: underline; -} -.sidebar ul li ul { - padding: 0; -} -.sidebar ul li.active > a { - border-right: 2px solid; - color: var(--theme-color, #42b983); - font-weight: 600; -} -.app-sub-sidebar li:before { - content: '-'; - padding-right: 4px; - float: left; -} -.markdown-section h1, -.markdown-section h2, -.markdown-section h3, -.markdown-section h4, -.markdown-section strong { - color: #2c3e50; - font-weight: 600; -} -.markdown-section a { - color: var(--theme-color, #42b983); - font-weight: 600; -} -.markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; -} -.markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; -} -.markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; -} -.markdown-section h4 { - font-size: 1.25rem; -} -.markdown-section h5 { - font-size: 1rem; -} -.markdown-section h6 { - color: #777; - font-size: 1rem; -} -.markdown-section figure, -.markdown-section p { - margin: 1.2em 0; -} -.markdown-section ol, -.markdown-section p, -.markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; -} -.markdown-section ol, -.markdown-section ul { - padding-left: 1.5rem; -} -.markdown-section blockquote { - border-left: 4px solid var(--theme-color, #42b983); - color: #858585; - margin: 2em 0; - padding-left: 20px; -} -.markdown-section blockquote p { - font-weight: 600; - margin-left: 0; -} -.markdown-section iframe { - margin: 1em 0; -} -.markdown-section em { - color: #7f8c8d; -} -.markdown-section code { - border-radius: 2px; - color: #e96900; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; -} -.markdown-section code, -.markdown-section pre { - background-color: #f8f8f8; - font-family: Roboto Mono, Monaco, courier, monospace; -} -.markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; -} -.token.cdata, -.token.comment, -.token.doctype, -.token.prolog { - color: #8e908c; -} -.token.namespace { - opacity: 0.7; -} -.token.boolean, -.token.number { - color: #c76b29; -} -.token.punctuation { - color: #525252; -} -.token.property { - color: #c08b30; -} -.token.tag { - color: #2973b7; -} -.token.string { - color: var(--theme-color, #42b983); -} -.token.selector { - color: #6679cc; -} -.token.attr-name { - color: #2973b7; -} -.language-css .token.string, -.style .token.string, -.token.entity, -.token.url { - color: #22a2c9; -} -.token.attr-value, -.token.control, -.token.directive, -.token.unit { - color: var(--theme-color, #42b983); -} -.token.function, -.token.keyword { - color: #e96900; -} -.token.atrule, -.token.regex, -.token.statement { - color: #22a2c9; -} -.token.placeholder, -.token.variable { - color: #3d8fd1; -} -.token.deleted { - text-decoration: line-through; -} -.token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; -} -.token.italic { - font-style: italic; -} -.token.bold, -.token.important { - font-weight: 700; -} -.token.important { - color: #c94922; -} -.token.entity { - cursor: help; -} -.markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #f8f8f8; - border-radius: 2px; - color: #525252; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; -} -.markdown-section code:after, -.markdown-section code:before { - letter-spacing: 0.05rem; -} -code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; -} -pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; -} diff --git a/docs/theme_themed.css b/docs/theme_themed.css deleted file mode 100644 index 9cb520ed7..000000000 --- a/docs/theme_themed.css +++ /dev/null @@ -1,1653 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600'); -* { - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-text-size-adjust: none; - -webkit-touch-callout: none; - box-sizing: border-box; -} - -@media (prefers-color-scheme: dark2) { - body:not(.ready) { - overflow: hidden; - } - body:not(.ready) .app-nav, - body:not(.ready) > nav, - body:not(.ready) [data-cloak] { - display: none; - } - div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; - } - div#app:empty:before { - content: 'Loading...'; - } - .emoji { - height: 1.2rem; - vertical-align: middle; - } - .progress { - background-color: var(--theme-color, #ea6f5a); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; - } - .search .search-keyword, - .search a:hover { - color: var(--theme-color, #ea6f5a); - } - .search .search-keyword { - font-style: normal; - font-weight: 700; - } - body, - html { - height: 100%; - } - body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #c8c8c8; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; - } - img { - max-width: 100%; - } - a[disabled] { - cursor: not-allowed; - opacity: 0.6; - } - kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; - } - li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; - } - .app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; - } - .app-nav.no-badge { - margin-right: 25px; - } - .app-nav p { - margin: 0; - } - .app-nav > a { - margin: 0 1rem; - padding: 5px 0; - } - .app-nav li, - .app-nav ul { - display: inline-block; - list-style: none; - margin: 0; - } - .app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; - } - .app-nav a.active, - .app-nav a:hover { - color: var(--theme-color, #ea6f5a); - } - .app-nav a.active { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - } - .app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; - } - .app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; - } - .app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; - } - .app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; - } - .app-nav li ul a.active { - border-bottom: 0; - } - .app-nav li:hover ul { - display: block; - } - .github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; - } - .github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - .github-corner svg { - color: #3f3f3f; - fill: var(--theme-color, #ea6f5a); - height: 80px; - width: 80px; - } - main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; - } - main.hidden { - display: none; - } - .anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; - } - .anchor span { - color: #c8c8c8; - } - .anchor:hover { - text-decoration: underline; - } - .sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; - } - .sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; - } - .sidebar > h1 a { - color: inherit; - text-decoration: none; - } - .sidebar > h1 .app-nav { - display: block; - position: static; - } - .sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; - } - .sidebar li.collapse .app-sub-sidebar { - display: none; - } - .sidebar ul { - margin: 0 0 0 15px; - padding: 0; - } - .sidebar li > p { - font-weight: 700; - margin: 0; - } - .sidebar ul, - .sidebar ul li { - list-style: none; - } - .sidebar ul li a { - border-bottom: none; - display: block; - } - .sidebar ul li ul { - padding-left: 20px; - } - .sidebar::-webkit-scrollbar { - width: 4px; - } - .sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; - } - .sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); - } - .sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); - } - .sidebar-toggle { - background-color: transparent; - background-color: rgba(63, 63, 63, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; - } - .sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; - } - .sidebar-toggle span { - background-color: var(--theme-color, #ea6f5a); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; - } - body.sticky .sidebar, - body.sticky .sidebar-toggle { - position: fixed; - } - .content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; - } - .markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; - } - .markdown-section > * { - box-sizing: border-box; - font-size: inherit; - } - .markdown-section > :first-child { - margin-top: 0 !important; - } - .markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; - } - .markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; - } - .markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; - } - .markdown-section th { - font-weight: 700; - } - .markdown-section td, - .markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; - } - .markdown-section tr { - border-top: 1px solid #ccc; - } - .markdown-section p.tip, - .markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; - } - .markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; - } - .markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #3f3f3f; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; - } - .markdown-section p.tip code { - background-color: #efefef; - } - .markdown-section p.tip em { - color: #c8c8c8; - } - .markdown-section p.warn { - background: rgba(234, 111, 90, 0.1); - border-radius: 2px; - padding: 1rem; - } - .markdown-section ul.task-list > li { - list-style-type: none; - } - body.close .sidebar { - transform: translateX(-300px); - } - body.close .sidebar-toggle { - width: auto; - } - body.close .content { - left: 0; - } - @media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } - } - @media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: rgba(63, 63, 63, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - } - @-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - @keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; - } - section.cover.show { - display: flex; - } - section.cover.has-mask .mask { - background-color: #3f3f3f; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; - } - section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; - } - section.cover a { - color: inherit; - } - section.cover a, - section.cover a:hover { - text-decoration: none; - } - section.cover p { - line-height: 1.5rem; - margin: 1em 0; - } - section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; - } - section.cover h1 a { - display: block; - } - section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; - } - section.cover blockquote { - font-size: 1.5rem; - text-align: center; - } - section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; - } - section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #ea6f5a); - box-sizing: border-box; - color: var(--theme-color, #ea6f5a); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; - } - section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #ea6f5a); - color: #fff; - } - section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; - } - section.cover .cover-main > p:last-child a:hover { - color: inherit; - } - section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - transition: color 0.3s; - } - section.cover blockquote > p > a:hover { - color: var(--theme-color, #ea6f5a); - } - .sidebar, - body { - background-color: #3f3f3f; - } - .sidebar { - color: #c8c8c8; - } - .sidebar li { - margin: 6px 15px 6px 0; - } - .sidebar ul li a { - color: #c8c8c8; - font-size: 14px; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; - } - .sidebar ul li a:hover { - text-decoration: underline; - } - .sidebar ul li ul { - padding: 0; - } - .sidebar ul li.active > a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; - } - .markdown-section h1, - .markdown-section h2, - .markdown-section h3, - .markdown-section h4, - .markdown-section strong { - color: #657b83; - font-weight: 600; - } - .markdown-section a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; - } - .markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; - } - .markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; - } - .markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; - } - .markdown-section h4 { - font-size: 1.25rem; - } - .markdown-section h5 { - font-size: 1rem; - } - .markdown-section h6 { - color: #777; - font-size: 1rem; - } - .markdown-section figure, - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - margin: 1.2em 0; - } - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; - } - .markdown-section ol, - .markdown-section ul { - padding-left: 1.5rem; - } - .markdown-section blockquote { - border-left: 4px solid var(--theme-color, #ea6f5a); - color: #858585; - margin: 2em 0; - padding-left: 20px; - } - .markdown-section blockquote p { - font-weight: 600; - margin-left: 0; - } - .markdown-section iframe { - margin: 1em 0; - } - .markdown-section em { - color: #7f8c8d; - } - .markdown-section code { - border-radius: 2px; - color: #657b83; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; - } - .markdown-section code, - .markdown-section pre { - background-color: #282828; - font-family: Roboto Mono, Monaco, courier, monospace; - } - .markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; - } - .token.cdata, - .token.comment, - .token.doctype, - .token.prolog { - color: #8e908c; - } - .token.namespace { - opacity: 0.7; - } - .token.boolean, - .token.number { - color: #c76b29; - } - .token.punctuation { - color: #525252; - } - .token.property { - color: #c08b30; - } - .token.tag { - color: #2973b7; - } - .token.string { - color: var(--theme-color, #ea6f5a); - } - .token.selector { - color: #6679cc; - } - .token.attr-name { - color: #2973b7; - } - .language-css .token.string, - .style .token.string, - .token.entity, - .token.url { - color: #22a2c9; - } - .token.attr-value, - .token.control, - .token.directive, - .token.unit { - color: var(--theme-color, #ea6f5a); - } - .token.keyword { - color: #e96900; - } - .token.atrule, - .token.regex, - .token.statement { - color: #22a2c9; - } - .token.placeholder, - .token.variable { - color: #3d8fd1; - } - .token.deleted { - text-decoration: line-through; - } - .token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; - } - .token.italic { - font-style: italic; - } - .token.bold, - .token.important { - font-weight: 700; - } - .token.important { - color: #c94922; - } - .token.entity { - cursor: help; - } - .markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #282828; - border-radius: 2px; - color: #657b83; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; - } - .markdown-section code:after, - .markdown-section code:before { - letter-spacing: 0.05rem; - } - code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; - } - pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; - } - .markdown-section p.tip { - background-color: #282828; - color: #657b83; - } - input[type='search'] { - background: #4f4f4f; - border-color: #4f4f4f; - color: #c8c8c8; - } -} - -@media (prefers-color-scheme: light or prefers-color-scheme: dark) { - /* @media (screen) { */ - body:not(.ready) { - overflow: hidden; - } - body:not(.ready) .app-nav, - body:not(.ready) > nav, - body:not(.ready) [data-cloak] { - display: none; - } - div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; - } - div#app:empty:before { - content: 'Loading...'; - } - .emoji { - height: 1.2rem; - vertical-align: middle; - } - .progress { - background-color: var(--theme-color, #42b983); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; - } - .search .search-keyword, - .search a:hover { - color: var(--theme-color, #42b983); - } - .search .search-keyword { - font-style: normal; - font-weight: 700; - } - body, - html { - height: 100%; - } - body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #34495e; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; - } - img { - max-width: 100%; - } - a[disabled] { - cursor: not-allowed; - opacity: 0.6; - } - kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; - } - li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; - } - .app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; - } - .app-nav.no-badge { - margin-right: 25px; - } - .app-nav p { - margin: 0; - } - .app-nav > a { - margin: 0 1rem; - padding: 5px 0; - } - .app-nav li, - .app-nav ul { - display: inline-block; - list-style: none; - margin: 0; - } - .app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; - } - .app-nav a.active, - .app-nav a:hover { - color: var(--theme-color, #42b983); - } - .app-nav a.active { - border-bottom: 2px solid var(--theme-color, #42b983); - } - .app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; - } - .app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; - } - .app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; - } - .app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; - } - .app-nav li ul a.active { - border-bottom: 0; - } - .app-nav li:hover ul { - display: block; - } - .github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; - } - .github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - .github-corner svg { - color: #fff; - fill: var(--theme-color, #42b983); - height: 80px; - width: 80px; - } - main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; - } - main.hidden { - display: none; - } - .anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; - } - .anchor span { - color: #34495e; - } - .anchor:hover { - text-decoration: underline; - } - .sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; - } - .sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; - } - .sidebar > h1 a { - color: inherit; - text-decoration: none; - } - .sidebar > h1 .app-nav { - display: block; - position: static; - } - .sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; - } - .sidebar li.collapse .app-sub-sidebar { - display: none; - } - .sidebar ul { - margin: 0 0 0 15px; - padding: 0; - } - .sidebar li > p { - font-weight: 700; - margin: 0; - } - .sidebar ul, - .sidebar ul li { - list-style: none; - } - .sidebar ul li a { - border-bottom: none; - display: block; - } - .sidebar ul li ul { - padding-left: 20px; - } - .sidebar::-webkit-scrollbar { - width: 4px; - } - .sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; - } - .sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); - } - .sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); - } - .sidebar-toggle { - background-color: transparent; - background-color: hsla(0, 0%, 100%, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; - } - .sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; - } - .sidebar-toggle span { - background-color: var(--theme-color, #42b983); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; - } - body.sticky .sidebar, - body.sticky .sidebar-toggle { - position: fixed; - } - .content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; - } - .markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; - } - .markdown-section > * { - box-sizing: border-box; - font-size: inherit; - } - .markdown-section > :first-child { - margin-top: 0 !important; - } - .markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; - } - .markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; - } - .markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; - } - .markdown-section th { - font-weight: 700; - } - .markdown-section td, - .markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; - } - .markdown-section tr { - border-top: 1px solid #ccc; - } - .markdown-section p.tip, - .markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; - } - .markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; - } - .markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #fff; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; - } - .markdown-section p.tip code { - background-color: #efefef; - } - .markdown-section p.tip em { - color: #34495e; - } - .markdown-section p.warn { - background: rgba(66, 185, 131, 0.1); - border-radius: 2px; - padding: 1rem; - } - .markdown-section ul.task-list > li { - list-style-type: none; - } - body.close .sidebar { - transform: translateX(-300px); - } - body.close .sidebar-toggle { - width: auto; - } - body.close .content { - left: 0; - } - @media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } - } - @media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: hsla(0, 0%, 100%, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - } - @-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - @keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; - } - section.cover.show { - display: flex; - } - section.cover.has-mask .mask { - background-color: #fff; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; - } - section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; - } - section.cover a { - color: inherit; - } - section.cover a, - section.cover a:hover { - text-decoration: none; - } - section.cover p { - line-height: 1.5rem; - margin: 1em 0; - } - section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; - } - section.cover h1 a { - display: block; - } - section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; - } - section.cover blockquote { - font-size: 1.5rem; - text-align: center; - } - section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; - } - section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #42b983); - box-sizing: border-box; - color: var(--theme-color, #42b983); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; - } - section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #42b983); - color: #fff; - } - section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; - } - section.cover .cover-main > p:last-child a:hover { - color: inherit; - } - section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #42b983); - transition: color 0.3s; - } - section.cover blockquote > p > a:hover { - color: var(--theme-color, #42b983); - } - .sidebar, - body { - background-color: #fff; - } - .sidebar { - color: #364149; - } - .sidebar li { - margin: 6px 0; - } - .sidebar ul li a { - color: #505d6b; - font-size: 14px; - font-weight: 400; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; - } - .sidebar ul li a:hover { - text-decoration: underline; - } - .sidebar ul li ul { - padding: 0; - } - .sidebar ul li.active > a { - border-right: 2px solid; - color: var(--theme-color, #42b983); - font-weight: 600; - } - .app-sub-sidebar li:before { - content: '-'; - padding-right: 4px; - float: left; - } - .markdown-section h1, - .markdown-section h2, - .markdown-section h3, - .markdown-section h4, - .markdown-section strong { - color: #2c3e50; - font-weight: 600; - } - .markdown-section a { - color: var(--theme-color, #42b983); - font-weight: 600; - } - .markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; - } - .markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; - } - .markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; - } - .markdown-section h4 { - font-size: 1.25rem; - } - .markdown-section h5 { - font-size: 1rem; - } - .markdown-section h6 { - color: #777; - font-size: 1rem; - } - .markdown-section figure, - .markdown-section p { - margin: 1.2em 0; - } - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; - } - .markdown-section ol, - .markdown-section ul { - padding-left: 1.5rem; - } - .markdown-section blockquote { - border-left: 4px solid var(--theme-color, #42b983); - color: #858585; - margin: 2em 0; - padding-left: 20px; - } - .markdown-section blockquote p { - font-weight: 600; - margin-left: 0; - } - .markdown-section iframe { - margin: 1em 0; - } - .markdown-section em { - color: #7f8c8d; - } - .markdown-section code { - border-radius: 2px; - color: #e96900; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; - } - .markdown-section code, - .markdown-section pre { - background-color: #f8f8f8; - font-family: Roboto Mono, Monaco, courier, monospace; - } - .markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; - } - .token.cdata, - .token.comment, - .token.doctype, - .token.prolog { - color: #8e908c; - } - .token.namespace { - opacity: 0.7; - } - .token.boolean, - .token.number { - color: #c76b29; - } - .token.punctuation { - color: #525252; - } - .token.property { - color: #c08b30; - } - .token.tag { - color: #2973b7; - } - .token.string { - color: var(--theme-color, #42b983); - } - .token.selector { - color: #6679cc; - } - .token.attr-name { - color: #2973b7; - } - .language-css .token.string, - .style .token.string, - .token.entity, - .token.url { - color: #22a2c9; - } - .token.attr-value, - .token.control, - .token.directive, - .token.unit { - color: var(--theme-color, #42b983); - } - .token.function, - .token.keyword { - color: #e96900; - } - .token.atrule, - .token.regex, - .token.statement { - color: #22a2c9; - } - .token.placeholder, - .token.variable { - color: #3d8fd1; - } - .token.deleted { - text-decoration: line-through; - } - .token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; - } - .token.italic { - font-style: italic; - } - .token.bold, - .token.important { - font-weight: 700; - } - .token.important { - color: #c94922; - } - .token.entity { - cursor: help; - } - .markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #f8f8f8; - border-radius: 2px; - color: #525252; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; - } - .markdown-section code:after, - .markdown-section code:before { - letter-spacing: 0.05rem; - } - code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; - } - pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; - } -} diff --git a/docs/upgrading.md b/docs/upgrading.md deleted file mode 100644 index 884326fb7..000000000 --- a/docs/upgrading.md +++ /dev/null @@ -1,27 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - -# Upgrading - -Some of the interfaces has been upgraded. - -## From version 0.4.0 to 0.5.0 - -### Initialization - -`mermaid_config` is no longer used. Instead a call to mermaid initialize is done as in the example below: - -#### version 0.4.0 - -```javascript -mermaid_config = { - startOnLoad: true, -}; -``` - -#### version 0.5.0 - -```javascript -mermaid.initialize({ - startOnLoad: true, -}); -``` diff --git a/package.json b/package.json index e58109b32..1faa1628d 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,10 @@ { "name": "mermaid-monorepo", "private": true, - "version": "9.2.0-rc2", + "version": "9.2.2", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", - "main": "dist/mermaid.core.mjs", - "module": "dist/mermaid.core.mjs", - "types": "dist/mermaid.d.ts", "type": "module", - "packageManager": "pnpm@7.12.2", - "exports": { - ".": { - "require": "./dist/mermaid.min.js", - "import": "./dist/mermaid.core.mjs", - "types": "./dist/mermaid.d.ts" - }, - "./*": "./*" - }, + "packageManager": "pnpm@7.17.1", "keywords": [ "diagram", "markdown", @@ -26,25 +15,24 @@ "git graph" ], "scripts": { - "clean": "rimraf dist", - "build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts", - "build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"", + "build:vite": "ts-node-esm --transpileOnly .vite/build.ts", + "build:mermaid": "pnpm build:vite --mermaid", + "build:viz": "pnpm build:mermaid --visualize", + "build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly", "build:watch": "pnpm build:vite --watch", - "build": "pnpm clean; concurrently \"pnpm build:vite\" \"pnpm build:types\"", - "dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server\"", - "docs:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts", - "docs:verify": "pnpm docs:build --verify", - "todo-postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md", + "build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"", + "dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"", "release": "pnpm build", "lint": "eslint --cache --ignore-path .gitignore . && pnpm lint:jison && prettier --check .", - "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .", - "lint:jison": "ts-node-esm --transpileOnly packages/mermaid/src/jison/lint.mts", + "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write . && ts-node-esm scripts/fixCSpell.ts", + "lint:jison": "ts-node-esm ./scripts/jison/lint.mts", "cypress": "cypress run", "cypress:open": "cypress open", "e2e": "start-server-and-test dev http://localhost:9000/ cypress", "ci": "vitest run", "test": "pnpm lint && vitest run", - "test:watch": "vitest --coverage --watch", + "test:watch": "vitest --watch", + "test:coverage": "vitest --coverage", "prepublishOnly": "pnpm build && pnpm test", "prepare": "concurrently \"husky install\" \"pnpm build\"", "pre-commit": "lint-staged" @@ -65,82 +53,62 @@ "page" ] }, - "dependencies": { - "@braintree/sanitize-url": "^6.0.0", - "@types/uuid": "^8.3.4", - "@types/node": "^18.7.21", - "d3": "^7.0.0", - "dagre": "^0.8.5", - "dagre-d3": "^0.6.4", - "dompurify": "2.4.0", - "fast-clone": "^1.5.13", - "graphlib": "^2.1.8", - "khroma": "^2.0.0", - "lodash": "^4.17.21", - "moment-mini": "^2.24.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "rollup": "^2.79.1", - "stylis": "^4.1.2", - "uuid": "^9.0.0" - }, "devDependencies": { - "@applitools/eyes-cypress": "^3.25.7", - "@commitlint/cli": "^17.1.2", - "@commitlint/config-conventional": "^17.0.0", - "@types/d3": "^7.4.0", - "@types/dompurify": "^2.3.4", - "@types/eslint": "^8.4.6", - "@types/express": "^4.17.13", - "@types/jsdom": "^20.0.0", - "@types/lodash": "^4.14.185", + "@applitools/eyes-cypress": "^3.27.6", + "@commitlint/cli": "^17.2.0", + "@commitlint/config-conventional": "^17.2.0", + "@cspell/eslint-plugin": "^6.14.2", + "@types/eslint": "^8.4.10", + "@types/express": "^4.17.14", + "@types/js-yaml": "^4.0.5", + "@types/jsdom": "^20.0.1", + "@types/lodash": "^4.14.188", + "@types/mdast": "^3.0.10", + "@types/node": "^18.11.9", "@types/prettier": "^2.7.1", - "@types/stylis": "^4.0.2", - "@typescript-eslint/eslint-plugin": "^5.37.0", - "@typescript-eslint/parser": "^5.37.0", - "@vitest/coverage-c8": "^0.23.2", - "@vitest/ui": "^0.23.2", - "concurrently": "^7.4.0", + "@types/rollup-plugin-visualizer": "^4.2.1", + "@typescript-eslint/eslint-plugin": "^5.42.1", + "@typescript-eslint/parser": "^5.42.1", + "@vitest/coverage-c8": "^0.25.1", + "@vitest/ui": "^0.25.1", + "concurrently": "^7.5.0", "coveralls": "^3.1.1", - "cypress": "^10.0.0", + "cypress": "^10.11.0", "cypress-image-snapshot": "^4.0.1", - "documentation": "13.2.0", - "eslint": "^8.24.0", + "esbuild": "^0.15.13", + "eslint": "^8.27.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-cypress": "^2.12.1", "eslint-plugin-html": "^7.1.0", - "eslint-plugin-jest": "^27.0.4", - "eslint-plugin-jsdoc": "^39.3.6", + "eslint-plugin-jest": "^27.1.5", + "eslint-plugin-jsdoc": "^39.6.2", "eslint-plugin-json": "^3.1.0", + "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-markdown": "^3.0.0", - "express": "^4.18.1", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-tsdoc": "^0.2.17", + "eslint-plugin-unicorn": "^45.0.0", + "express": "^4.18.2", "globby": "^13.1.2", - "husky": "^8.0.0", - "identity-obj-proxy": "^3.0.0", - "jest": "29.x", + "husky": "^8.0.2", + "jest": "^29.3.1", "jison": "^0.4.18", - "jsdom": "^20.0.0", - "lint-staged": "^13.0.0", - "moment": "^2.23.0", + "js-yaml": "^4.1.0", + "jsdom": "^20.0.2", + "lint-staged": "^13.0.3", "path-browserify": "^1.0.1", + "pnpm": "^7.15.0", "prettier": "^2.7.1", "prettier-plugin-jsdoc": "^0.4.2", - "remark": "^14.0.2", "rimraf": "^3.0.2", - "start-server-and-test": "^1.12.6", + "rollup-plugin-visualizer": "^5.8.3", + "start-server-and-test": "^1.14.0", "ts-node": "^10.9.1", - "typescript": "^4.8.3", - "unist-util-flatmap": "^1.0.0", - "vite": "^3.0.9", - "vitest": "^0.23.1" + "typescript": "^4.8.4", + "vite": "^3.2.3", + "vitest": "^0.25.3" }, - "resolutions": { - "d3": "^7.0.0" - }, - "files": [ - "dist" - ], - "sideEffects": [ - "**/*.css", - "**/*.scss" - ] + "volta": { + "node": "18.12.1" + } } diff --git a/packages/mermaid-example-diagram/Readme.md b/packages/mermaid-example-diagram/Readme.md new file mode 100644 index 000000000..38056e3c7 --- /dev/null +++ b/packages/mermaid-example-diagram/Readme.md @@ -0,0 +1,3 @@ +### Do not refer this package. It is not ready. + +### Refer mermaid-mindmap instead. diff --git a/packages/mermaid-example-diagram/package.json b/packages/mermaid-example-diagram/package.json index fa3c570b6..8e958806a 100644 --- a/packages/mermaid-example-diagram/package.json +++ b/packages/mermaid-example-diagram/package.json @@ -29,10 +29,6 @@ "lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .", "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .", "lint:jison": "ts-node-esm src/jison/lint.mts", - "ci": "vitest run", - "test": "yarn lint && vitest run", - "test:watch": "vitest --coverage --watch", - "todo-prepublishOnly": "yarn build && yarn test", "todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"", "todo-pre-commit": "lint-staged" }, @@ -54,7 +50,7 @@ }, "dependencies": {}, "devDependencies": { - "concurrently": "^7.4.0", + "concurrently": "^7.5.0", "rimraf": "^3.0.2" }, "resolutions": { diff --git a/packages/mermaid-example-diagram/src/detector.ts b/packages/mermaid-example-diagram/src/detector.ts new file mode 100644 index 000000000..d30b99fba --- /dev/null +++ b/packages/mermaid-example-diagram/src/detector.ts @@ -0,0 +1,18 @@ +// @ts-ignore: TODO Fix ts errors +export const id = 'example-diagram'; + +/** + * Detector function that will be called by mermaid to determine if the diagram is this type of diagram. + * + * @param txt - The diagram text will be passed to the detector + * @returns True if the diagram text matches a diagram of this type + */ + +export const detector = (txt: string) => { + return txt.match(/^\s*example-diagram/) !== null; +}; + +export const loadDiagram = async () => { + const { diagram } = await import('./diagram-definition'); + return { id, diagram }; +}; diff --git a/packages/mermaid-example-diagram/src/add-diagram.ts b/packages/mermaid-example-diagram/src/diagram-definition.ts similarity index 66% rename from packages/mermaid-example-diagram/src/add-diagram.ts rename to packages/mermaid-example-diagram/src/diagram-definition.ts index ec32ed838..95f7cc11d 100644 --- a/packages/mermaid-example-diagram/src/add-diagram.ts +++ b/packages/mermaid-example-diagram/src/diagram-definition.ts @@ -5,13 +5,12 @@ import renderer from './exampleDiagramRenderer'; import styles from './styles'; import { injectUtils } from './mermaidUtils'; -window.mermaid.connectDiagram( - 'example-diagram', - { - db, - renderer, - parser, - styles, - }, - injectUtils -); +export const diagram = { + db, + renderer, + parser, + styles, + injectUtils, +}; + +export { detector, id } from './detector'; diff --git a/packages/mermaid-example-diagram/src/exampleDetector.ts b/packages/mermaid-example-diagram/src/exampleDetector.ts deleted file mode 100644 index 2c71b1e07..000000000 --- a/packages/mermaid-example-diagram/src/exampleDetector.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const detector = (txt: string) => { - return txt.match(/^\s*example-diagram/) !== null; -}; diff --git a/packages/mermaid-example-diagram/src/exampleDiagram.spec.js b/packages/mermaid-example-diagram/src/exampleDiagram.spec.js index 6e231e22d..db539aac0 100644 --- a/packages/mermaid-example-diagram/src/exampleDiagram.spec.js +++ b/packages/mermaid-example-diagram/src/exampleDiagram.spec.js @@ -7,8 +7,8 @@ describe('when parsing an info graph it', function () { ex.yy = db; }); - it('should handle an info definition', function () { - let str = `info + it('should handle an example-diagram definition', function () { + let str = `example-diagram showInfo`; ex.parse(str); diff --git a/packages/mermaid-example-diagram/src/exampleDiagramDb.js b/packages/mermaid-example-diagram/src/exampleDiagramDb.js index a65d2c839..8429ec5d6 100644 --- a/packages/mermaid-example-diagram/src/exampleDiagramDb.js +++ b/packages/mermaid-example-diagram/src/exampleDiagramDb.js @@ -13,21 +13,29 @@ export const getMessage = () => { return message; }; +/** + * Sets the info flag + * + * @param {boolean} inf + */ export const setInfo = (inf) => { info = inf; }; +/** @returns Returns the info flag */ export const getInfo = () => { return info; }; +export const clear = () => { + message = ''; + info = false; +}; + export default { setMessage, getMessage, setInfo, getInfo, - clear: () => { - message = ''; - info = false; - }, + clear, }; diff --git a/packages/mermaid-example-diagram/src/exampleDiagramRenderer.js b/packages/mermaid-example-diagram/src/exampleDiagramRenderer.js index 1bb7a9de9..0d7340677 100644 --- a/packages/mermaid-example-diagram/src/exampleDiagramRenderer.js +++ b/packages/mermaid-example-diagram/src/exampleDiagramRenderer.js @@ -1,6 +1,6 @@ /** Created by knut on 14-12-11. */ import { select } from 'd3'; -import { log, getConfig } from './mermaidUtils'; +import { log, getConfig, setupGraphViewbox } from './mermaidUtils'; /** * Draws a an info picture in the tag with id: id based on the graph definition in text. @@ -10,12 +10,13 @@ import { log, getConfig } from './mermaidUtils'; * @param {any} version * @param diagObj */ -export const draw = (text, id, version, diagObj) => { +export const draw = (text, id, version) => { try { - log.debug('Rendering info diagram\n' + text); - + const conf = getConfig(); + log.debug('Rendering example diagram\n' + text, 'Conf: '); + const THEME_COLOR_LIMIT = getConfig().themeVariables.THEME_COLOR_LIMIT; const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -25,14 +26,34 @@ export const draw = (text, id, version, diagObj) => { ? select(sandboxElement.nodes()[0].contentDocument.body) : select('body'); - // Parse the graph definition - // parser.parse(text); - // log.debug('Parsed info diagram'); - // Fetch the default direction, use TD if none was found const svg = root.select('#' + id); const g = svg.append('g'); + let i; + for (i = 0; i < THEME_COLOR_LIMIT; i++) { + const section = g.append('g').attr('class', 'section-' + i); + section + .append('rect') + .attr('x', (i % 5) * 110) + .attr('y', Math.floor(i / 5) * 90 + 60) + .attr('width', 100) + .attr('height', 60); + section + .append('rect') + .attr('x', (i % 5) * 110) + .attr('y', Math.floor(i / 5) * 90 + 120) + .attr('class', 'inverted') + .attr('width', 100) + .attr('height', 20); + section + .append('text', 'section-' + i) + .text('Section ' + i) + .attr('x', (i % 5) * 110 + 15) + .attr('y', Math.floor(i / 5) * 90 + 95) + .attr('class', 'section-text-' + i); + } + g.append('text') // text label for the x axis .attr('x', 100) .attr('y', 40) @@ -41,9 +62,8 @@ export const draw = (text, id, version, diagObj) => { .style('text-anchor', 'middle') .text('v ' + version); - svg.attr('height', 100); - svg.attr('width', 400); - // svg.attr('viewBox', '0 0 300 150'); + // Setup the view box and size of the svg element + setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth); } catch (e) { log.error('Error while rendering info diagram'); log.error(e.message); diff --git a/packages/mermaid-example-diagram/src/mermaidUtils.ts b/packages/mermaid-example-diagram/src/mermaidUtils.ts index 7d8a459e6..8894abdff 100644 --- a/packages/mermaid-example-diagram/src/mermaidUtils.ts +++ b/packages/mermaid-example-diagram/src/mermaidUtils.ts @@ -19,7 +19,6 @@ export const log: Record = { error: warning, fatal: warning, }; - export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void; export let getConfig: () => object; export let sanitizeText: (str: string) => string; @@ -36,18 +35,19 @@ export let setupGraphViewbox: ( /** * Function called by mermaid that injects utility functions that help the diagram to be a good citizen. - * @param _log - * @param _setLogLevel - * @param _getConfig - * @param _sanitizeText - * @param _setupGraphViewbox + * + * @param _log - log from mermaid/src/diagramAPI.ts + * @param _setLogLevel - setLogLevel from mermaid/src/diagramAPI.ts + * @param _getConfig - getConfig from mermaid/src/diagramAPI.ts + * @param _sanitizeText - sanitizeText from mermaid/src/diagramAPI.ts + * @param _setupGraphViewbox - setupGraphViewbox from mermaid/src/diagramAPI.ts */ export const injectUtils = ( _log: Record, - _setLogLevel: any, - _getConfig: any, - _sanitizeText: any, - _setupGraphViewbox: any + _setLogLevel: typeof setLogLevel, + _getConfig: typeof getConfig, + _sanitizeText: typeof sanitizeText, + _setupGraphViewbox: typeof setupGraphViewbox ) => { _log.debug('Mermaid utils injected into example-diagram'); log.trace = _log.trace; diff --git a/packages/mermaid-example-diagram/src/parser/exampleDiagram.jison b/packages/mermaid-example-diagram/src/parser/exampleDiagram.jison index 47480b591..731fcf18f 100644 --- a/packages/mermaid-example-diagram/src/parser/exampleDiagram.jison +++ b/packages/mermaid-example-diagram/src/parser/exampleDiagram.jison @@ -8,7 +8,7 @@ %% -"info" return 'info' ; +"example-diagram" return 'example-diagram' ; [\s\n\r]+ return 'NL' ; [\s]+ return 'space'; "showInfo" return 'showInfo'; @@ -22,8 +22,8 @@ %% /* language grammar */ start -// %{ : info document 'EOF' { return yy; } } - : info document 'EOF' { return yy; } +// %{ : example-diagram document 'EOF' { return yy; } } + : example-diagram document 'EOF' { return yy; } ; document diff --git a/packages/mermaid-example-diagram/src/registry.ts b/packages/mermaid-example-diagram/src/registry.ts deleted file mode 100644 index 92ff3bd00..000000000 --- a/packages/mermaid-example-diagram/src/registry.ts +++ /dev/null @@ -1,33 +0,0 @@ -// @ts-ignore: TODO Fix ts errors -import { detector } from './exampleDetector'; - -const scriptElement = document.currentScript as HTMLScriptElement; -const path = scriptElement.src; -const lastSlash = path.lastIndexOf('/'); -const baseFolder = lastSlash < 0 ? path : path.substring(0, lastSlash + 1); - -if (typeof document !== 'undefined') { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - window.mermaid.detectors.push({ id: 'example-diagram', detector }); - } else { - window.mermaid = {}; - window.mermaid.detectors = [{ id: 'example-diagram', detector }]; - } - - /* - * Wait for document loaded before starting the execution. - */ - window.addEventListener( - 'load', - () => { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - window.mermaid.detectors.push({ - id: 'example-diagram', - detector, - path: baseFolder, - }); - } - }, - false - ); -} diff --git a/packages/mermaid-example-diagram/src/styles.js b/packages/mermaid-example-diagram/src/styles.js index 0b0729813..02dc4db4e 100644 --- a/packages/mermaid-example-diagram/src/styles.js +++ b/packages/mermaid-example-diagram/src/styles.js @@ -1,3 +1,27 @@ -const getStyles = () => ``; +const genSections = (options) => { + let sections = ''; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + sections += ` + .section-${i} rect { + fill: ${options['cScale' + i]}; + stroke: ${options['cScalePeer' + i]}; + stroke-width: 4; + } + .section-${i} rect.inverted { + fill: ${options['cScaleInv' + i]}; + } + .section-${i} text { + fill: ${options['cScaleLabel' + i]}; + } + + `; + } + return sections; +}; + +const getStyles = (options) => + ` + ${genSections(options)} +`; export default getStyles; diff --git a/packages/mermaid-mindmap/package.json b/packages/mermaid-mindmap/package.json index 10ad34835..852c0871b 100644 --- a/packages/mermaid-mindmap/package.json +++ b/packages/mermaid-mindmap/package.json @@ -1,14 +1,14 @@ { "name": "@mermaid-js/mermaid-mindmap", - "version": "9.2.0-rc2", + "version": "9.2.2", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", - "main": "dist/mermaid-mindmap.core.mjs", "module": "dist/mermaid-mindmap.core.mjs", + "types": "dist/detector.d.ts", "type": "module", "exports": { ".": { - "require": "./dist/mermaid-mindmap.min.js", - "import": "./dist/mermaid-mindmap.core.mjs" + "import": "./dist/mermaid-mindmap.core.mjs", + "types": "./dist/detector.d.ts" }, "./*": "./*" }, @@ -19,22 +19,7 @@ "mermaid" ], "scripts": { - "clean": "rimraf dist", - "build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly", - "build:watch": "yarn build:code --watch", - "build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"", - "build": "yarn clean; yarn build:esbuild", - "dev": "node .esbuild/serve.cjs", - "release": "yarn build", - "lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .", - "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .", - "lint:jison": "ts-node-esm src/jison/lint.mts", - "ci": "vitest run", - "test": "yarn lint && vitest run", - "test:watch": "vitest --coverage --watch", - "todo-prepublishOnly": "yarn build && yarn test", - "todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"", - "todo-pre-commit": "lint-staged" + "prepublishOnly": "pnpm -w run build" }, "repository": { "type": "git", @@ -54,12 +39,16 @@ }, "dependencies": { "@braintree/sanitize-url": "^6.0.0", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", "d3": "^7.0.0", - "mermaid": "workspace:*", + "khroma": "^2.0.0", "non-layered-tidy-tree-layout": "^2.0.2" }, "devDependencies": { - "concurrently": "^7.4.0", + "concurrently": "^7.5.0", + "mermaid": "workspace:*", "rimraf": "^3.0.2" }, "resolutions": { diff --git a/packages/mermaid-mindmap/src/add-diagram.ts b/packages/mermaid-mindmap/src/add-diagram.ts deleted file mode 100644 index 1fe950b14..000000000 --- a/packages/mermaid-mindmap/src/add-diagram.ts +++ /dev/null @@ -1,23 +0,0 @@ -// @ts-ignore: TODO Fix ts errors -import mindmapParser from './parser/mindmap'; -import * as mindmapDb from './mindmapDb'; -import mindmapRenderer from './mindmapRenderer'; -import mindmapStyles from './styles'; -import { injectUtils } from './mermaidUtils'; - -// const getBaseFolder = (path: string) => { -// const parts = path.split('/'); -// parts.pop(); -// return parts.join('/'); -// }; - -window.mermaid.connectDiagram( - 'mindmap', - { - db: mindmapDb, - renderer: mindmapRenderer, - parser: mindmapParser, - styles: mindmapStyles, - }, - injectUtils -); diff --git a/packages/mermaid-mindmap/src/detector.ts b/packages/mermaid-mindmap/src/detector.ts new file mode 100644 index 000000000..da3caf51e --- /dev/null +++ b/packages/mermaid-mindmap/src/detector.ts @@ -0,0 +1,20 @@ +import type { ExternalDiagramDefinition } from 'mermaid'; + +const id = 'mindmap'; + +const detector = (txt: string) => { + return txt.match(/^\s*mindmap/) !== null; +}; + +const loader = async () => { + const { diagram } = await import('./diagram-definition'); + return { id, diagram }; +}; + +const plugin: ExternalDiagramDefinition = { + id, + detector, + loader, +}; + +export default plugin; diff --git a/packages/mermaid-mindmap/src/diagram-definition.ts b/packages/mermaid-mindmap/src/diagram-definition.ts new file mode 100644 index 000000000..e7856289d --- /dev/null +++ b/packages/mermaid-mindmap/src/diagram-definition.ts @@ -0,0 +1,14 @@ +// @ts-ignore: TODO Fix ts errors +import mindmapParser from './parser/mindmap'; +import * as mindmapDb from './mindmapDb'; +import mindmapRenderer from './mindmapRenderer'; +import mindmapStyles from './styles'; +import { injectUtils } from './mermaidUtils'; + +export const diagram = { + db: mindmapDb, + renderer: mindmapRenderer, + parser: mindmapParser, + styles: mindmapStyles, + injectUtils, +}; diff --git a/packages/mermaid-mindmap/src/mermaidUtils.ts b/packages/mermaid-mindmap/src/mermaidUtils.ts index a65523f0c..b575c201b 100644 --- a/packages/mermaid-mindmap/src/mermaidUtils.ts +++ b/packages/mermaid-mindmap/src/mermaidUtils.ts @@ -1,6 +1,7 @@ const warning = (s: string) => { // Todo remove debug code - console.error('Log function was called before initialization', s); // eslint-disable-line + // eslint-disable-next-line no-console + console.error('Log function was called before initialization', s); }; export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; @@ -53,29 +54,3 @@ export const injectUtils = ( sanitizeText = _sanitizeText; setupGraphViewbox = _setupGraphViewbox; }; - -/* -const warning = (..._args: any[]) => { - console.error('Log function was called before initialization'); -}; - -export let log = { - trace: warning, - debug: warning, - info: warning, - warn: warning, - error: warning, - fatal: warning, -}; -export let setLogLevel; -export let getConfig; -export let sanitizeText; -export let setupGraphViewbox; -export const injectUtils = (_log, _setLogLevel, _getConfig, _sanitizeText, _setupGraphViewbox) => { - log = _log; - setLogLevel = _setLogLevel; - getConfig = _getConfig; - sanitizeText = _sanitizeText; - setupGraphViewbox = _setupGraphViewbox; -}; -*/ diff --git a/packages/mermaid-mindmap/src/mindmap.spec.js b/packages/mermaid-mindmap/src/mindmap.spec.js index b9e9abf6e..e3f018350 100644 --- a/packages/mermaid-mindmap/src/mindmap.spec.js +++ b/packages/mermaid-mindmap/src/mindmap.spec.js @@ -172,6 +172,18 @@ root expect(mm.children.length).toEqual(0); expect(mm.type).toEqual(mindmap.yy.nodeType.BANG); }); + + it('MMP-12-a mutiple types (hexagon)', function () { + let str = `mindmap + root{{the root}} +`; + + mindmap.parse(str); + const mm = mindmap.yy.getMindmap(); + expect(mm.type).toEqual(mindmap.yy.nodeType.HEXAGON); + expect(mm.descr).toEqual('the root'); + expect(mm.children.length).toEqual(0); + }); }); describe('decorations', function () { it('MMP-13 should be possible to set an icon for the node', function () { diff --git a/packages/mermaid-mindmap/src/mindmapDb.js b/packages/mermaid-mindmap/src/mindmapDb.js index cbe4d0286..16861cd23 100644 --- a/packages/mermaid-mindmap/src/mindmapDb.js +++ b/packages/mermaid-mindmap/src/mindmapDb.js @@ -42,6 +42,9 @@ export const addNode = (level, id, descr, type) => { case nodeType.RECT: node.padding = 2 * conf.mindmap.padding; break; + case nodeType.HEXAGON: + node.padding = 2 * conf.mindmap.padding; + break; default: node.padding = conf.mindmap.padding; } @@ -79,6 +82,7 @@ export const nodeType = { CIRCLE: 3, CLOUD: 4, BANG: 5, + HEXAGON: 6, }; export const getType = (startStr, endStr) => { @@ -94,6 +98,8 @@ export const getType = (startStr, endStr) => { return nodeType.CLOUD; case '))': return nodeType.BANG; + case '{{': + return nodeType.HEXAGON; default: return nodeType.DEFAULT; } @@ -127,16 +133,14 @@ export const type2Str = (type) => { return 'cloud'; case nodeType.BANG: return 'bang'; + case nodeType.HEXAGON: + return 'hexgon'; default: return 'no-border'; } }; -export let parseError; // = (str, hash) -// => { -// const error = { str, hash }; -// throw error; -// }; +export let parseError; export const setErrorHandler = (handler) => { parseError = handler; }; @@ -146,17 +150,3 @@ export const getLogger = () => log; export const getNodeById = (id) => nodes[id]; export const getElementById = (id) => elements[id]; -// export default { -// // getMindmap, -// // addNode, -// // clear, -// // nodeType, -// // getType, -// // decorateNode, -// // setElementForId, -// getElementById: (id) => elements[id], -// // getNodeById: (id) => nodes.find((node) => node.id === id), -// getNodeById: (id) => nodes[id], -// // type2Str, -// // parseError -// }; diff --git a/packages/mermaid-mindmap/src/mindmapDetector.old b/packages/mermaid-mindmap/src/mindmapDetector.old deleted file mode 100644 index 4fe85af03..000000000 --- a/packages/mermaid-mindmap/src/mindmapDetector.old +++ /dev/null @@ -1,8 +0,0 @@ -const detector = function detect(txt) { - if (txt.match(/^\s*mindmap/)) { - return 'mindmap'; - } - return null; -}; - -export default detector; diff --git a/packages/mermaid-mindmap/src/mindmapDetector.ts b/packages/mermaid-mindmap/src/mindmapDetector.ts deleted file mode 100644 index 9a3f6f426..000000000 --- a/packages/mermaid-mindmap/src/mindmapDetector.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const mindmapDetector = (txt: string) => { - return txt.match(/^\s*mindmap/) !== null; -}; diff --git a/packages/mermaid-mindmap/src/mindmapRenderer.js b/packages/mermaid-mindmap/src/mindmapRenderer.js index aab12a157..9fd557e51 100644 --- a/packages/mermaid-mindmap/src/mindmapRenderer.js +++ b/packages/mermaid-mindmap/src/mindmapRenderer.js @@ -2,13 +2,16 @@ import { select } from 'd3'; import { log, getConfig, setupGraphViewbox } from './mermaidUtils'; import svgDraw from './svgDraw'; -import { BoundingBox, Layout } from 'non-layered-tidy-tree-layout'; -import clone from 'fast-clone'; +import cytoscape from 'cytoscape'; +import coseBilkent from 'cytoscape-cose-bilkent'; import * as db from './mindmapDb'; +// Inject the layout algorithm into cytoscape +cytoscape.use(coseBilkent); + /** * @param {any} svg The svg element to draw the diagram onto - * @param {object} mindmap The maindmap data and hierarchy + * @param {object} mindmap The mindmap data and hierarchy * @param section * @param {object} conf The configuration object */ @@ -22,189 +25,128 @@ function drawNodes(svg, mindmap, section, conf) { } /** - * @param edgesElem - * @param mindmap - * @param parent - * @param depth - * @param section - * @param conf + * @param edgesEl + * @param cy */ -function drawEdges(edgesElem, mindmap, parent, depth, section, conf) { - if (parent) { - svgDraw.drawEdge(edgesElem, mindmap, parent, depth, section, conf); - } - if (mindmap.children) { - mindmap.children.forEach((child, index) => { - drawEdges(edgesElem, child, mindmap, depth + 1, section < 0 ? index : section, conf); - }); - } +function drawEdges(edgesEl, cy) { + cy.edges().map((edge, id) => { + const data = edge.data(); + if (edge[0]._private.bodyBounds) { + const bounds = edge[0]._private.rscratch; + log.trace('Edge: ', id, data); + edgesEl + .insert('path') + .attr( + 'd', + `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} ` + ) + .attr('class', 'edge section-edge-' + data.section + ' edge-depth-' + data.depth); + } + }); } /** - * @param mindmap - * @param callback + * @param mindmap The mindmap data and hierarchy + * @param cy + * @param conf The configuration object + * @param level */ -function eachNode(mindmap, callback) { - callback(mindmap); +function addNodes(mindmap, cy, conf, level) { + cy.add({ + group: 'nodes', + data: { + id: mindmap.id, + labelText: mindmap.descr, + height: mindmap.height, + width: mindmap.width, + level: level, + nodeId: mindmap.id, + padding: mindmap.padding, + type: mindmap.type, + }, + position: { + x: mindmap.x, + y: mindmap.y, + }, + }); if (mindmap.children) { mindmap.children.forEach((child) => { - eachNode(child, callback); - }); - } -} -/** @param {object} mindmap */ -function transpose(mindmap) { - eachNode(mindmap, (node) => { - const orgWidth = node.width; - const orgX = node.x; - node.width = node.height; - node.height = orgWidth; - node.x = node.y; - node.y = orgX; - }); - return mindmap; -} -/** @param {object} mindmap */ -function bottomToUp(mindmap) { - log.debug('bottomToUp', mindmap); - eachNode(mindmap.result, (node) => { - // node.y = node.y - (node.y - bb.top) * 2 - node.height; - node.y = node.y - (node.y - 0) * 2 - node.height; - }); - return mindmap; -} -/** @param {object} mindmap The mindmap hierarchy */ -function rightToLeft(mindmap) { - eachNode(mindmap.result, (node) => { - // node.y = node.y - (node.y - bb.top) * 2 - node.height; - node.x = node.x - (node.x - 0) * 2 - node.width; - }); - return mindmap; -} - -/** - * @param mindmap - * @param dir - */ -function layout(mindmap, dir) { - const bb = new BoundingBox(30, 60); - - const layout = new Layout(bb); - switch (dir) { - case 'TB': - return layout.layout(mindmap); - case 'BT': - return bottomToUp(layout.layout(mindmap)); - case 'RL': { - transpose(mindmap); - let newRes = layout.layout(mindmap); - transpose(newRes.result); - return rightToLeft(newRes); - } - case 'LR': { - transpose(mindmap); - let newRes = layout.layout(mindmap); - transpose(newRes.result); - return newRes; - } - default: - } -} -const dirFromIndex = (index) => { - const dirNum = (index + 2) % 4; - switch (dirNum) { - case 0: - return 'LR'; - case 1: - return 'RL'; - case 2: - return 'TB'; - case 3: - return 'BT'; - default: - return 'TB'; - } -}; - -const mergeTrees = (node, trees) => { - node.x = trees[0].result.x; - node.y = trees[0].result.y; - trees.forEach((tree) => { - tree.result.children.forEach((child) => { - const dx = node.x - tree.result.x; - const dy = node.y - tree.result.y; - eachNode(child, (childNode) => { - const orgNode = db.getNodeById(childNode.id); - if (orgNode) { - orgNode.x = childNode.x + dx; - orgNode.y = childNode.y + dy; - } + addNodes(child, cy, conf, level + 1); + cy.add({ + group: 'edges', + data: { + id: `${mindmap.id}_${child.id}`, + source: mindmap.id, + target: child.id, + depth: level, + section: child.section, + }, }); }); - }); - return node; -}; + } +} /** * @param node * @param conf */ function layoutMindmap(node, conf) { - // BoundingBox(gap, bottomPadding) - // const bb = new BoundingBox(10, 10); - // const layout = new Layout(bb); - // // const layout = new HorizontalLayout(bb); - if (node.children.length === 0) { - return node; - } - const trees = []; - // node.children.forEach((child, index) => { - // const tree = clone(node); - // tree.children = [tree.children[index]]; - // trees.push(layout(tree, dirFromIndex(index), conf)); - // }); + return new Promise((resolve) => { + // Add temporary render element + const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none'); + const cy = cytoscape({ + container: document.getElementById('cy'), // container to render in + style: [ + { + selector: 'edge', + style: { + 'curve-style': 'bezier', + }, + }, + ], + }); + // Remove element after layout + renderEl.remove(); + addNodes(node, cy, conf, 0); - let cnt = 0; - // For each direction, create a new tree with the same root, and add a ubset of the children to it. - for (let i = 0; i < 4; i++) { - // Calculate the number of the children of the root node that will be used in this direction - const numChildren = - Math.floor(node.children.length / 4) + (node.children.length % 4 > i ? 1 : 0); - // Copy the original root node - const tree = clone(node); - // Setup the new copy with the children to be rendered in this direction - tree.children = []; - for (let j = 0; j < numChildren; j++) { - tree.children.push(node.children[cnt]); - cnt++; - } - if (tree.children.length > 0) { - trees.push(layout(tree, dirFromIndex(i), conf)); - } - } - // Let each node know the direct of its tree for when we draw the branches. - trees.forEach((tree, index) => { - tree.result.direction = dirFromIndex(index); - eachNode(tree.result, (node) => { - node.direction = dirFromIndex(index); + // Make cytoscape care about the dimensions of the nodes + cy.nodes().forEach(function (n) { + n.layoutDimensions = () => { + const data = n.data(); + return { w: data.width, h: data.height }; + }; + }); + + cy.layout({ + name: 'cose-bilkent', + quality: 'proof', + // headless: true, + styleEnabled: false, + animate: false, + }).run(); + cy.ready((e) => { + log.info('Ready', e); + resolve(cy); }); }); - - // Merge the trees into a single tree - mergeTrees(node, trees); - return node; } /** - * @param node - * @param conf + * @param cy */ -function positionNodes(node, conf) { - svgDraw.positionNode(node, conf); - if (node.children) { - node.children.forEach((child) => { - positionNodes(child, conf); - }); - } +function positionNodes(cy) { + cy.nodes().map((node, id) => { + const data = node.data(); + data.x = node.position().x; + data.y = node.position().y; + svgDraw.positionNode(data); + const el = db.getElementById(data.nodeId); + log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data); + el.attr( + 'transform', + `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})` + ); + el.attr('attr', `apa-${id})`); + }); } /** @@ -216,7 +158,7 @@ function positionNodes(node, conf) { * @param diagObj */ -export const draw = (text, id, version, diagObj) => { +export const draw = async (text, id, version, diagObj) => { const conf = getConfig(); // This is done only for throwing the error if the text is not valid. @@ -227,7 +169,7 @@ export const draw = (text, id, version, diagObj) => { log.debug('Renering info diagram\n' + text); const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -254,11 +196,11 @@ export const draw = (text, id, version, diagObj) => { // Next step is to layout the mindmap, giving each node a position - const positionedMindmap = layoutMindmap(mm, conf); + const cy = await layoutMindmap(mm, conf); - // After this we can draw, first the edges and the then nodes with the correct position - drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf); - positionNodes(positionedMindmap, conf); + // // After this we can draw, first the edges and the then nodes with the correct position + drawEdges(edgesElem, cy, conf); + positionNodes(cy, conf); // Setup the view box and size of the svg element setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth); diff --git a/packages/mermaid-mindmap/src/parser/mindmap.jison b/packages/mermaid-mindmap/src/parser/mindmap.jison index bd008db7f..a96ee6261 100644 --- a/packages/mermaid-mindmap/src/parser/mindmap.jison +++ b/packages/mermaid-mindmap/src/parser/mindmap.jison @@ -33,11 +33,12 @@ "))" { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; } ")" { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; } "((" { this.begin('NODE');return 'NODE_DSTART'; } +"{{" { this.begin('NODE');return 'NODE_DSTART'; } "(" { this.begin('NODE');return 'NODE_DSTART'; } "[" { this.begin('NODE');return 'NODE_DSTART'; } [\s]+ return 'SPACELIST' /* skip all whitespace */ ; // !(-\() return 'NODE_ID'; -[^\(\[\n\-\)]+ return 'NODE_ID'; +[^\(\[\n\-\)\{\}]+ return 'NODE_ID'; <> return 'EOF'; ["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");} [^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";} @@ -45,11 +46,12 @@ [\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";} [\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";} [\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";} +"}}" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} "(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} "-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} "((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} -"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} -[^\)\]\(]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} +"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} +[^\)\]\(\}]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} .+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} // [\[] return 'NODE_START'; // .+ return 'TXT' ; diff --git a/packages/mermaid-mindmap/src/registry.ts b/packages/mermaid-mindmap/src/registry.ts deleted file mode 100644 index 8252bc78e..000000000 --- a/packages/mermaid-mindmap/src/registry.ts +++ /dev/null @@ -1,41 +0,0 @@ -// @ts-ignore: TODO Fix ts errors -import { mindmapDetector } from './mindmapDetector'; - -// const getBaseFolder = () => { -const scriptElement = document.currentScript as HTMLScriptElement; -const path = scriptElement.src; -const lastSlash = path.lastIndexOf('/'); -const baseFolder = lastSlash < 0 ? path : path.substring(0, lastSlash + 1); - -// }; - -// console.log('Current script', getBaseFolder(scriptElement !== null ? scriptElement.src : '')); // eslint-disable-line no-console - -if (typeof document !== 'undefined') { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector }); - } else { - // console.error('window.mermaid.detectors was not found!'); // eslint-disable-line no-console - window.mermaid = {}; - window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }]; - // console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console - } - - /*! - * Wait for document loaded before starting the execution. - */ - window.addEventListener( - 'load', - () => { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - window.mermaid.detectors.push({ - id: 'mindmap', - detector: mindmapDetector, - path: baseFolder, - }); - // console.error(window.mermaid.detectors); // eslint-disable-line no-console - } - }, - false - ); -} diff --git a/packages/mermaid-mindmap/src/styles.js b/packages/mermaid-mindmap/src/styles.js index f6afaa612..986a04514 100644 --- a/packages/mermaid-mindmap/src/styles.js +++ b/packages/mermaid-mindmap/src/styles.js @@ -3,8 +3,8 @@ import { darken, lighten, isDark } from 'khroma'; const genSections = (options) => { let sections = ''; - for (let i = 0; i < 8; i++) { - options['lineColor' + i] = options['lineColor' + i] || options['gitInv' + i]; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options['lineColor' + i] = options['lineColor' + i] || options['cScaleInv' + i]; if (isDark(options['lineColor' + i])) { options['lineColor' + i] = lighten(options['lineColor' + i], 20); } else { @@ -12,31 +12,29 @@ const genSections = (options) => { } } - for (let i = 0; i < 8; i++) { + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { const sw = '' + (17 - 3 * i); sections += ` .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${ i - 1 - } path { - fill: ${options['git' + i]}; + } polygon, .section-${i - 1} path { + fill: ${options['cScale' + i]}; } .section-${i - 1} text { - fill: ${options['gitBranchLabel' + i]}; - // fill: ${options['gitInv' + i]}; + fill: ${options['cScaleLabel' + i]}; } .node-icon-${i - 1} { font-size: 40px; - color: ${options['gitBranchLabel' + i]}; - // color: ${options['gitInv' + i]}; + color: ${options['cScaleLabel' + i]}; } .section-edge-${i - 1}{ - stroke: ${options['git' + i]}; + stroke: ${options['cScale' + i]}; } .edge-depth-${i - 1}{ stroke-width: ${sw}; } .section-${i - 1} line { - stroke: ${options['lineColor' + i]} ; + stroke: ${options['cScaleInv' + i]} ; stroke-width: 3; } @@ -57,7 +55,7 @@ const getStyles = (options) => stroke-width: 3; } ${genSections(options)} - .section-root rect, .section-root path, .section-root circle { + .section-root rect, .section-root path, .section-root circle, .section-root polygon { fill: ${options.git0}; } .section-root text { diff --git a/packages/mermaid-mindmap/src/svgDraw.js b/packages/mermaid-mindmap/src/svgDraw.js index 7d6804f24..d4f57f1f1 100644 --- a/packages/mermaid-mindmap/src/svgDraw.js +++ b/packages/mermaid-mindmap/src/svgDraw.js @@ -1,5 +1,6 @@ import { select } from 'd3'; import * as db from './mindmapDb'; +const MAX_SECTIONS = 12; /** * @param {string} text The text to be wrapped @@ -144,6 +145,45 @@ const circleBkg = function (elem, node) { .attr('class', 'node-bkg node-' + db.type2Str(node.type)) .attr('r', node.width / 2); }; + +/** + * + * @param parent + * @param w + * @param h + * @param points + * @param node + */ +function insertPolygonShape(parent, w, h, points, node) { + return parent + .insert('polygon', ':first-child') + .attr( + 'points', + points + .map(function (d) { + return d.x + ',' + d.y; + }) + .join(' ') + ) + .attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')'); +} + +const hexagonBkg = function (elem, node) { + const h = node.height; + const f = 4; + const m = h / f; + const w = node.width - node.padding + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 }, + ]; + const shapeSvg = insertPolygonShape(elem, w, h, points, node); +}; + const roundedRectBkg = function (elem, node) { elem .append('rect') @@ -158,17 +198,19 @@ const roundedRectBkg = function (elem, node) { /** * @param {object} elem The D3 dom element in which the node is to be added * @param {object} node The node to be added - * @param section + * @param fullSection * @param {object} conf The configuration object * @returns {number} The height nodes dom element */ -export const drawNode = function (elem, node, section, conf) { +export const drawNode = function (elem, node, fullSection, conf) { + const section = (fullSection % MAX_SECTIONS) - 1; const nodeElem = elem.append('g'); + node.section = section; nodeElem.attr( 'class', (node.class ? node.class + ' ' : '') + 'mindmap-node ' + - (section === -1 ? 'section-root' : 'section-' + section) + (section < 0 ? 'section-root' : 'section-' + section) ); const bkgElem = nodeElem.append('g'); @@ -249,17 +291,21 @@ export const drawNode = function (elem, node, section, conf) { case db.nodeType.BANG: bangBkg(bkgElem, node, section, conf); break; + case db.nodeType.HEXAGON: + hexagonBkg(bkgElem, node, section, conf); + break; } // Position the node to its coordinate - if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') { - nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')'); - } + // if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') { + // nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')'); + // } db.setElementForId(node.id, nodeElem); return node.height; }; -export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, section) { +export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) { + const section = (fullSection % MAX_SECTIONS) - 1; const sx = parent.x + parent.width / 2; const sy = parent.y + parent.height / 2; const ex = mindmap.x + mindmap.width / 2; diff --git a/packages/mermaid-mindmap/tsconfig.json b/packages/mermaid-mindmap/tsconfig.json index 45076b7b5..310137cc0 100644 --- a/packages/mermaid-mindmap/tsconfig.json +++ b/packages/mermaid-mindmap/tsconfig.json @@ -1,5 +1,6 @@ { "extends": "../../tsconfig.json", + "module": "esnext", "compilerOptions": { "rootDir": "./src", "outDir": "./dist" diff --git a/packages/mermaid/.gitignore b/packages/mermaid/.gitignore new file mode 100644 index 000000000..1a961ffe0 --- /dev/null +++ b/packages/mermaid/.gitignore @@ -0,0 +1,2 @@ +src/vitepress +src/docs/config/setup \ No newline at end of file diff --git a/packages/mermaid/.lintstagedrc.mjs b/packages/mermaid/.lintstagedrc.mjs new file mode 100644 index 000000000..fe79ad254 --- /dev/null +++ b/packages/mermaid/.lintstagedrc.mjs @@ -0,0 +1,7 @@ +import baseConfig from '../../.lintstagedrc.mjs'; +export default { + ...baseConfig, + 'src/docs/**': ['pnpm --filter mermaid run docs:build --git'], + 'src/docs.mts': ['pnpm --filter mermaid run docs:build --git'], + 'src/(defaultConfig|config|mermaidAPI).ts': ['pnpm --filter mermaid run docs:build --git'], +}; diff --git a/packages/mermaid/README.md b/packages/mermaid/README.md new file mode 100644 index 000000000..91c2d1640 --- /dev/null +++ b/packages/mermaid/README.md @@ -0,0 +1,346 @@ +# mermaid + +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) + +English | [简体中文](./README.zh-CN.md) + + + +:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) in the category "The most exciting use of technology"!!!** + +**Thanks to all involved, people committing pull requests, people answering questions! 🙏** + +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! + +## About + + + +Mermaid is a JavaScript-based diagramming and charting tool that uses Markdown-inspired text definitions and a renderer to create and modify complex diagrams. The main purpose of Mermaid is to help documentation catch up with development. + +> Doc-Rot is a Catch-22 that Mermaid helps to solve. + +Diagramming and documentation costs precious developer time and gets outdated quickly. +But not having diagrams or docs ruins productivity and hurts organizational learning.
+Mermaid addresses this problem by enabling users to create easily modifiable diagrams. It can also be made part of production scripts (and other pieces of code).
+
+ +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). + +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). + +🌐 [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) + +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. + + + + + + + +## 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.github.io/mermaid/#/n00b-syntaxReference).** + + + +### Flowchart [docs - live editor] + +``` +flowchart LR + +A[Hard] -->|Text| B(Round) +B --> C{Decision} +C -->|One| D[Result 1] +C -->|Two| E[Result 2] +``` + +```mermaid +flowchart LR + +A[Hard] -->|Text| B(Round) +B --> C{Decision} +C -->|One| D[Result 1] +C -->|Two| E[Result 2] +``` + +### Sequence diagram [docs - live editor] + +``` +sequenceDiagram +Alice->>John: Hello John, how are you? +loop Healthcheck + John->>John: Fight against hypochondria +end +Note right of John: Rational thoughts! +John-->>Alice: Great! +John->>Bob: How about you? +Bob-->>John: Jolly good! +``` + +```mermaid +sequenceDiagram +Alice->>John: Hello John, how are you? +loop Healthcheck + John->>John: Fight against hypochondria +end +Note right of John: Rational thoughts! +John-->>Alice: Great! +John->>Bob: How about you? +Bob-->>John: Jolly good! +``` + +### Gantt chart [docs - live editor] + +``` +gantt + section Section + Completed :done, des1, 2014-01-06,2014-01-08 + Active :active, des2, 2014-01-07, 3d + Parallel 1 : des3, after des1, 1d + Parallel 2 : des4, after des1, 1d + Parallel 3 : des5, after des3, 1d + Parallel 4 : des6, after des4, 1d +``` + +```mermaid +gantt + section Section + Completed :done, des1, 2014-01-06,2014-01-08 + Active :active, des2, 2014-01-07, 3d + Parallel 1 : des3, after des1, 1d + Parallel 2 : des4, after des1, 1d + Parallel 3 : des5, after des3, 1d + Parallel 4 : des6, after des4, 1d +``` + +### Class diagram [docs - live editor] + +``` +classDiagram +Class01 <|-- AveryLongClass : Cool +<> Class01 +Class09 --> C2 : Where am I? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +class Class10 { + <> + int id + size() +} +``` + +```mermaid +classDiagram +Class01 <|-- AveryLongClass : Cool +<> Class01 +Class09 --> C2 : Where am I? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +class Class10 { + <> + int id + size() +} +``` + +### State diagram [docs - live editor] + +``` +stateDiagram-v2 +[*] --> Still +Still --> [*] +Still --> Moving +Moving --> Still +Moving --> Crash +Crash --> [*] +``` + +```mermaid +stateDiagram-v2 +[*] --> Still +Still --> [*] +Still --> Moving +Moving --> Still +Moving --> Crash +Crash --> [*] +``` + +### Pie chart [docs - live editor] + +``` +pie +"Dogs" : 386 +"Cats" : 85.9 +"Rats" : 15 +``` + +```mermaid +pie +"Dogs" : 386 +"Cats" : 85.9 +"Rats" : 15 +``` + +### Git graph [experimental - live editor] + +### User Journey diagram [docs - live editor] + +``` + journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 3: Me +``` + +```mermaid + journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 3: Me +``` + +### C4 diagram [docs] + +``` +C4Context +title System Context diagram for Internet Banking System + +Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") +Person(customerB, "Banking Customer B") +Person_Ext(customerC, "Banking Customer C") +System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") + +Person(customerD, "Banking Customer D", "A customer of the bank,
with personal bank accounts.") + +Enterprise_Boundary(b1, "BankBoundary") { + + SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") + + System_Boundary(b2, "BankBoundary2") { + System(SystemA, "Banking System A") + System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.") + } + + System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") + SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") + + Boundary(b3, "BankBoundary3", "boundary") { + SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.") + SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") + } +} + +BiRel(customerA, SystemAA, "Uses") +BiRel(SystemAA, SystemE, "Uses") +Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") +Rel(SystemC, customerA, "Sends e-mails to") +``` + +```mermaid +C4Context +title System Context diagram for Internet Banking System + +Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") +Person(customerB, "Banking Customer B") +Person_Ext(customerC, "Banking Customer C") +System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") + +Person(customerD, "Banking Customer D", "A customer of the bank,
with personal bank accounts.") + +Enterprise_Boundary(b1, "BankBoundary") { + + SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") + + System_Boundary(b2, "BankBoundary2") { + System(SystemA, "Banking System A") + System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.") + } + + System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") + SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") + + Boundary(b3, "BankBoundary3", "boundary") { + SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.") + SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") + } +} + +BiRel(customerA, SystemAA, "Uses") +BiRel(SystemAA, SystemE, "Uses") +Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") +Rel(SystemC, customerA, "Sends e-mails to") +``` + +## Release + +For those who have the permission to do so: + +Update version number in `package.json`. + +```sh +npm publish +``` + +The above command generates files into the `dist` folder and publishes them to npmjs.org. + +## Related projects + +- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli) +- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor) +- [HTTP Server](https://github.com/TomWright/mermaid-server) + +## Contributors [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) + +Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out. + +Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md) + +## Security and safe diagrams + +For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes. + +As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing javascript in the code from being executed. This is a great step forward for better security. + +_Unfortunately you can not have a cake and eat it at the same time which in this case means that some of the interactive functionality gets blocked along with the possible malicious code._ + +## Reporting vulnerabilities + +To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. + +## Appreciation + +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._ +> +> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_ + +--- + +_Mermaid was created by Knut Sveidqvist for easier documentation._ diff --git a/packages/mermaid/README.zh-CN.md b/packages/mermaid/README.zh-CN.md new file mode 100644 index 000000000..0ccef27e4 --- /dev/null +++ b/packages/mermaid/README.zh-CN.md @@ -0,0 +1,334 @@ +# mermaid + +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) + +[English](./README.md) | 简体中文 + + + +:trophy: **Mermaid 被提名并获得了 [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) 的 "The most exciting use of technology" 奖项!!!** + +**感谢所有参与进来提交 PR,解答疑问的人们! 🙏** + +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! + +## 关于 Mermaid + + + +Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。 + +> Doc-Rot 是 Mermaid 致力于解决的一个难题。 + +绘图和编写文档花费了开发者宝贵的开发时间,而且随着业务的变更,它很快就会过期。 但是如果缺少了图表或文档,对于生产力和团队新人的业务学习都会产生巨大的阻碍。
+Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。
+
+Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。
+你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。 + +如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md), [用法](./docs/usage.md) 和 [教程](./docs/Tutorials.md). + +🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md) + + + +## 示例 + +**下面是一些可以使用 Mermaid 创建的图表示例。点击 [语法](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference) 查看详情。** + +
+ + +### 流程图 [文档 - live editor] + +``` +flowchart LR +A[Hard] -->|Text| B(Round) +B --> C{Decision} +C -->|One| D[Result 1] +C -->|Two| E[Result 2] +``` + +```mermaid +flowchart LR +A[Hard] -->|Text| B(Round) +B --> C{Decision} +C -->|One| D[Result 1] +C -->|Two| E[Result 2] +``` + +### 时序图 [文档 - live editor] + +``` +sequenceDiagram +Alice->>John: Hello John, how are you? +loop Healthcheck + John->>John: Fight against hypochondria +end +Note right of John: Rational thoughts! +John-->>Alice: Great! +John->>Bob: How about you? +Bob-->>John: Jolly good! +``` + +```mermaid +sequenceDiagram +Alice->>John: Hello John, how are you? +loop Healthcheck + John->>John: Fight against hypochondria +end +Note right of John: Rational thoughts! +John-->>Alice: Great! +John->>Bob: How about you? +Bob-->>John: Jolly good! +``` + +### 甘特图 [文档 - live editor] + +``` +gantt + section Section + Completed :done, des1, 2014-01-06,2014-01-08 + Active :active, des2, 2014-01-07, 3d + Parallel 1 : des3, after des1, 1d + Parallel 2 : des4, after des1, 1d + Parallel 3 : des5, after des3, 1d + Parallel 4 : des6, after des4, 1d +``` + +```mermaid +gantt + section Section + Completed :done, des1, 2014-01-06,2014-01-08 + Active :active, des2, 2014-01-07, 3d + Parallel 1 : des3, after des1, 1d + Parallel 2 : des4, after des1, 1d + Parallel 3 : des5, after des3, 1d + Parallel 4 : des6, after des4, 1d +``` + +### 类图 [文档 - live editor] + +``` +classDiagram +Class01 <|-- AveryLongClass : Cool +<> Class01 +Class09 --> C2 : Where am I? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +class Class10 { + <> + int id + size() +} +``` + +```mermaid +classDiagram +Class01 <|-- AveryLongClass : Cool +<> Class01 +Class09 --> C2 : Where am I? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +class Class10 { + <> + int id + size() +} +``` + +### 状态图 [[docs - live editor] + +``` +stateDiagram-v2 +[*] --> Still +Still --> [*] +Still --> Moving +Moving --> Still +Moving --> Crash +Crash --> [*] +``` + +```mermaid +stateDiagram-v2 +[*] --> Still +Still --> [*] +Still --> Moving +Moving --> Still +Moving --> Crash +Crash --> [*] +``` + +### 饼图 [文档 - live editor] + +``` +pie +"Dogs" : 386 +"Cats" : 85 +"Rats" : 15 +``` + +```mermaid +pie +"Dogs" : 386 +"Cats" : 85 +"Rats" : 15 +``` + +### Git 图 [实验特性 - live editor] + +### 用户体验旅程图 [文档 - live editor] + +``` + journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 3: Me +``` + +```mermaid + journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 3: Me +``` + +### C4 图 [文档] + +``` +C4Context +title System Context diagram for Internet Banking System + +Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") +Person(customerB, "Banking Customer B") +Person_Ext(customerC, "Banking Customer C") +System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") + +Person(customerD, "Banking Customer D", "A customer of the bank,
with personal bank accounts.") + +Enterprise_Boundary(b1, "BankBoundary") { + + SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") + + System_Boundary(b2, "BankBoundary2") { + System(SystemA, "Banking System A") + System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.") + } + + System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") + SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") + + Boundary(b3, "BankBoundary3", "boundary") { + SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.") + SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") + } +} + +BiRel(customerA, SystemAA, "Uses") +BiRel(SystemAA, SystemE, "Uses") +Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") +Rel(SystemC, customerA, "Sends e-mails to") +``` + +```mermaid +C4Context +title System Context diagram for Internet Banking System + +Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") +Person(customerB, "Banking Customer B") +Person_Ext(customerC, "Banking Customer C") +System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") + +Person(customerD, "Banking Customer D", "A customer of the bank,
with personal bank accounts.") + +Enterprise_Boundary(b1, "BankBoundary") { + + SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.") + + System_Boundary(b2, "BankBoundary2") { + System(SystemA, "Banking System A") + System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.") + } + + System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") + SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.") + + Boundary(b3, "BankBoundary3", "boundary") { + SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.") + SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.") + } +} + +BiRel(customerA, SystemAA, "Uses") +BiRel(SystemAA, SystemE, "Uses") +Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") +Rel(SystemC, customerA, "Sends e-mails to") +``` + +## 发布 + +对于有权限的同学来说,你可以通过以下步骤来完成发布操作: + +更新 `package.json` 中的版本号,然后执行如下命令: + +```sh +npm publish +``` + +以上的命令会将文件打包到 `dist` 目录并发布至 npmjs.org. + +## 相关项目 + +- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli) +- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor) +- [HTTP Server](https://github.com/TomWright/mermaid-server) + +## 贡献者 [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) + +Mermaid 是一个不断发展中的社区,并且还在接收新的贡献者。有很多不同的方式可以参与进来,而且我们还在寻找额外的帮助。如果你想知道如何开始贡献,请查看 [这个 issue](https://github.com/mermaid-js/mermaid/issues/866)。 + +关于如何贡献的详细信息可以在 [贡献指南](CONTRIBUTING.md) 中找到。 + +## 安全 + +对于公开网站来说,从互联网上的用户处检索文本、存储供后续在浏览器中展示的内容可能是不安全的,理由是用户的内容可能嵌入一些数据加载完成之后就会运行的恶意脚本,这些对于 Mermaid 来说毫无疑问是一个风险,尤其是 mermaid 图表还包含了许多在 html 中使用的字符,这意味着我们难以使用常规的手段来过滤不安全代码,因为这些常规手段会造成图表损坏。我们仍然在努力对获取到的代码进行安全过滤并不断完善我们的程序,但很难保证没有漏洞。 + +作为拥有外部用户的网站的额外安全级别,我们很高兴推出一个新的安全级别,其中的图表在沙盒 iframe 中渲染,防止代码中的 javascript 被执行,这是在安全性方面迈出的一大步。 + +_很不幸的是,鱼与熊掌不可兼得,在这个场景下它意味着在可能的恶意代码被阻止时,也会损失部分交互能力_。 + +## 报告漏洞 + +如果想要报告漏洞,请发送邮件到 security@mermaid.live, 并附上问题的描述、复现问题的步骤、受影响的版本,以及解决问题的方案(如果有的话)。 + +## 鸣谢 + +来自 Knut Sveidqvist: + +> _特别感谢 [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),没有你们,就没有这个项目的今天!_ + +--- + +_Mermaid 是由 Knut Sveidqvist 创建,它为了更简单的文档编写而生。_ diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 0c42dc3b9..66fa4f224 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,11 +1,10 @@ { "name": "mermaid", - "version": "9.2.0-rc2", - "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", - "main": "./dist/mermaid.core.mjs", + "version": "9.2.3-rc.1", + "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", + "main": "./dist/mermaid.min.js", "module": "./dist/mermaid.core.mjs", "types": "./dist/mermaid.d.ts", - "type": "module", "exports": { ".": { "require": "./dist/mermaid.min.js", @@ -25,28 +24,16 @@ ], "scripts": { "clean": "rimraf dist", - "build:code": "node .esbuild/esbuild.cjs", - "build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly", - "build:watch": "yarn build:code --watch", - "build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"", - "build": "yarn clean; yarn build:esbuild", - "dev": "node .esbuild/serve.cjs", - "docs:build": "ts-node-esm src/docs.mts", - "docs:verify": "yarn docs:build --verify", - "todo-postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md", - "release": "yarn build", - "lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .", - "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .", - "lint:jison": "ts-node-esm src/jison/lint.mts", - "cypress": "cypress run", - "cypress:open": "cypress open", - "e2e": "start-server-and-test dev http://localhost:9000/ cypress", - "ci": "vitest run", - "test": "yarn lint && vitest run", - "test:watch": "vitest --coverage --watch", - "prepublishOnly": "yarn build && yarn test", - "todo-prepare": "concurrently \"husky install\" \"yarn build\"", - "pre-commit": "lint-staged" + "docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaidAPI.ts && prettier --write ./src/docs/config/setup", + "docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts", + "docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts --verify", + "docs:pre:vitepress": "rimraf src/vitepress && pnpm docs:code && ts-node-esm src/docs.mts --vitepress", + "docs:build:vitepress": "pnpm docs:pre:vitepress && vitepress build src/vitepress", + "docs:dev": "pnpm docs:pre:vitepress && concurrently \"vitepress dev src/vitepress\" \"ts-node-esm src/docs.mts --watch --vitepress\"", + "docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress", + "docs:spellcheck": "cspell --config ../../cSpell.json \"src/docs/**/*.md\"", + "release": "pnpm build", + "prepublishOnly": "pnpm -w run build" }, "repository": { "type": "git", @@ -67,72 +54,51 @@ "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", - "dagre": "^0.8.5", - "dagre-d3": "^0.6.4", - "dompurify": "2.4.0", - "fast-clone": "^1.5.13", - "graphlib": "^2.1.8", + "dagre-d3-es": "7.0.4", + "dompurify": "2.4.1", "khroma": "^2.0.0", - "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "moment-mini": "^2.24.0", "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.2" + "stylis": "^4.1.2", + "uuid": "^9.0.0" }, "devDependencies": { - "@applitools/eyes-cypress": "^3.25.7", - "@commitlint/cli": "^17.1.2", - "@commitlint/config-conventional": "^17.0.0", "@types/d3": "^7.4.0", - "@types/dompurify": "^2.3.4", - "@types/eslint": "^8.4.6", - "@types/express": "^4.17.13", - "@types/jsdom": "^20.0.0", - "@types/lodash": "^4.14.185", - "@types/prettier": "^2.7.0", + "@types/dompurify": "^2.4.0", + "@types/jsdom": "^20.0.1", + "@types/lodash-es": "^4.17.6", + "@types/micromatch": "^4.0.2", + "@types/prettier": "^2.7.1", "@types/stylis": "^4.0.2", - "@typescript-eslint/eslint-plugin": "^5.37.0", - "@typescript-eslint/parser": "^5.37.0", - "@vitest/coverage-c8": "^0.23.2", - "@vitest/ui": "^0.23.2", - "concurrently": "^7.4.0", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^5.42.1", + "@typescript-eslint/parser": "^5.42.1", + "chokidar": "^3.5.3", + "concurrently": "^7.5.0", "coveralls": "^3.1.1", - "cypress": "^10.0.0", - "cypress-image-snapshot": "^4.0.1", - "documentation": "13.2.0", - "esbuild": "^0.15.8", - "eslint": "^8.23.1", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-cypress": "^2.12.1", - "eslint-plugin-html": "^7.1.0", - "eslint-plugin-jest": "^27.0.4", - "eslint-plugin-jsdoc": "^39.3.6", - "eslint-plugin-json": "^3.1.0", - "eslint-plugin-markdown": "^3.0.0", - "express": "^4.18.1", + "cspell": "^6.14.3", "globby": "^13.1.2", - "husky": "^8.0.0", - "identity-obj-proxy": "^3.0.0", "jison": "^0.4.18", - "js-base64": "3.7.2", - "jsdom": "^20.0.0", - "lint-staged": "^13.0.0", - "moment": "^2.23.0", + "js-base64": "^3.7.2", + "jsdom": "^20.0.2", + "micromatch": "^4.0.5", + "moment": "^2.29.4", "path-browserify": "^1.0.1", "prettier": "^2.7.1", - "prettier-plugin-jsdoc": "^0.4.2", "remark": "^14.0.2", "rimraf": "^3.0.2", - "start-server-and-test": "^1.12.6", - "ts-node": "^10.9.1", - "typescript": "^4.8.3", + "start-server-and-test": "^1.14.0", + "typedoc": "^0.23.18", + "typedoc-plugin-markdown": "^3.13.6", + "typescript": "^4.8.4", "unist-util-flatmap": "^1.0.0", - "vitest": "^0.23.1" - }, - "resolutions": { - "d3": "^7.0.0" + "vitepress": "^1.0.0-alpha.28", + "vitepress-plugin-search": "^1.0.4-alpha.15" }, "files": [ - "dist" + "dist", + "README.md" ], "sideEffects": [ "**/*.css", diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts index 231a78af6..a2349c255 100644 --- a/packages/mermaid/src/Diagram.ts +++ b/packages/mermaid/src/Diagram.ts @@ -1,18 +1,28 @@ import * as configApi from './config'; import { log } from './logger'; -import { getDiagram, loadDiagram } from './diagram-api/diagramAPI'; -import { detectType, getPathForDiagram } from './diagram-api/detectType'; -import { isDetailedError } from './utils'; +import { getDiagram, registerDiagram } from './diagram-api/diagramAPI'; +import { detectType, getDiagramLoader } from './diagram-api/detectType'; +import { extractFrontMatter } from './diagram-api/frontmatter'; +import { isDetailedError, type DetailedError } from './utils'; + +export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void; + export class Diagram { type = 'graph'; parser; renderer; db; - // eslint-disable-next-line @typescript-eslint/ban-types - constructor(public txt: string, parseError?: Function) { + private detectTypeFailed = false; + constructor(public txt: string, parseError?: ParseErrorFunction) { const cnf = configApi.getConfig(); this.txt = txt; - this.type = detectType(txt, cnf); + try { + this.type = detectType(txt, cnf); + } catch (e) { + this.handleError(e, parseError); + this.type = 'error'; + this.detectTypeFailed = true; + } const diagram = getDiagram(this.type); log.debug('Type ' + this.type); // Setup diagram @@ -20,6 +30,16 @@ export class Diagram { this.db.clear?.(); this.renderer = diagram.renderer; this.parser = diagram.parser; + const originalParse = this.parser.parse.bind(this.parser); + // Wrap the jison parse() method to handle extracting frontmatter. + // + // This can't be done in this.parse() because some code + // directly calls diagram.parser.parse(), bypassing this.parse(). + // + // Similarly, we can't do this in getDiagramFromText() because some code + // calls diagram.db.clear(), which would reset anything set by + // extractFrontMatter(). + this.parser.parse = (text: string) => originalParse(extractFrontMatter(text, this.db)); this.parser.parser.yy = this.db; if (diagram.init) { diagram.init(cnf); @@ -30,33 +50,41 @@ export class Diagram { this.parse(this.txt, parseError); } - // eslint-disable-next-line @typescript-eslint/ban-types - parse(text: string, parseError?: Function): boolean { + parse(text: string, parseError?: ParseErrorFunction): boolean { + if (this.detectTypeFailed) { + return false; + } try { text = text + '\n'; - this.db.clear(); + this.db.clear?.(); this.parser.parse(text); return true; } catch (error) { - // Is this the correct way to access mermiad's parseError() - // method ? (or global.mermaid.parseError()) ? - if (parseError) { - if (isDetailedError(error)) { - // handle case where error string and hash were - // wrapped in object like`const error = { str, hash };` - parseError(error.str, error.hash); - } else { - // assume it is just error string and pass it on - parseError(error); - } - } else { - // No mermaid.parseError() handler defined, so re-throw it - throw error; - } + this.handleError(error, parseError); } return false; } + handleError(error: unknown, parseError?: ParseErrorFunction) { + // Is this the correct way to access mermaid's parseError() + // method ? (or global.mermaid.parseError()) ? + + if (parseError === undefined) { + // No mermaid.parseError() handler defined, so re-throw it + throw error; + } + + if (isDetailedError(error)) { + // Handle case where error string and hash were + // wrapped in object like`const error = { str, hash };` + parseError(error.str, error.hash); + return; + } + + // Otherwise, assume it is just an error string and pass it on + parseError(error as string); + } + getParser() { return this.parser; } @@ -66,22 +94,30 @@ export class Diagram { } } -export default Diagram; - -// eslint-disable-next-line @typescript-eslint/ban-types -export const getDiagramFromText = async (txt: string, parseError?: Function) => { +export const getDiagramFromText = ( + txt: string, + parseError?: ParseErrorFunction +): Diagram | Promise => { const type = detectType(txt, configApi.getConfig()); try { // Trying to find the diagram getDiagram(type); + return new Diagram(txt, parseError); } catch (error) { - // Diagram not avaiable, loading it - const path = getPathForDiagram(type); - // await loadDiagram('./packages/mermaid-mindmap/dist/mermaid-mindmap.js'); - await loadDiagram(path + 'mermaid-' + type + '.js'); - // new diagram will try getDiagram again and if fails then it is a valid throw + const loader = getDiagramLoader(type); + if (!loader) { + throw new Error(`Diagram ${type} not found.`); + } + // TODO: Uncomment for v10 + // // Diagram not available, loading it + // const { diagram } = await loader(); + // registerDiagram(type, diagram, undefined, diagram.injectUtils); + // // new diagram will try getDiagram again and if fails then it is a valid throw + return loader().then(({ diagram }) => { + registerDiagram(type, diagram, undefined); + return new Diagram(txt, parseError); + }); } - // If either of the above worked, we have the diagram - // logic and can continue - return new Diagram(txt, parseError); }; + +export default Diagram; diff --git a/packages/mermaid/src/__mocks__/mermaidAPI.ts b/packages/mermaid/src/__mocks__/mermaidAPI.ts index f15db139f..12c1652bc 100644 --- a/packages/mermaid/src/__mocks__/mermaidAPI.ts +++ b/packages/mermaid/src/__mocks__/mermaidAPI.ts @@ -6,22 +6,14 @@ import * as configApi from '../config'; import { vi } from 'vitest'; import { addDiagrams } from '../diagram-api/diagram-orchestration'; -import Diagram from '../Diagram'; +import Diagram, { type ParseErrorFunction } from '../Diagram'; // Normally, we could just do the following to get the original `parse()` // implementation, however, requireActual returns a promise and it's not documented how to use withing mock file. -let hasLoadedDiagrams = false; -/** - * @param text - * @param parseError - */ -// eslint-disable-next-line @typescript-eslint/ban-types -function parse(text: string, parseError?: Function): boolean { - if (!hasLoadedDiagrams) { - addDiagrams(); - hasLoadedDiagrams = true; - } +/** {@inheritDoc mermaidAPI.parse} */ +function parse(text: string, parseError?: ParseErrorFunction): boolean { + addDiagrams(); const diagram = new Diagram(text, parseError); return diagram.parse(text, parseError); } @@ -29,6 +21,7 @@ function parse(text: string, parseError?: Function): boolean { // original version cannot be modified since it was frozen with `Object.freeze()` export const mermaidAPI = { render: vi.fn(), + renderAsync: vi.fn(), parse, parseDirective: vi.fn(), initialize: vi.fn(), diff --git a/packages/mermaid/src/accessibility.js b/packages/mermaid/src/accessibility.js index c59ba270c..4d4837fff 100644 --- a/packages/mermaid/src/accessibility.js +++ b/packages/mermaid/src/accessibility.js @@ -11,7 +11,7 @@ * @param id */ export default function addSVGAccessibilityFields(yy_parser, svg, id) { - if (typeof svg.insert === 'undefined') { + if (svg.insert === undefined) { return; } diff --git a/packages/mermaid/src/assignWithDepth.js b/packages/mermaid/src/assignWithDepth.js index eff568d3e..898481c30 100644 --- a/packages/mermaid/src/assignWithDepth.js +++ b/packages/mermaid/src/assignWithDepth.js @@ -32,20 +32,20 @@ const assignWithDepth = function (dst, src, config) { return dst; } else if (Array.isArray(src) && Array.isArray(dst)) { src.forEach((s) => { - if (dst.indexOf(s) === -1) { + if (!dst.includes(s)) { dst.push(s); } }); return dst; } - if (typeof dst === 'undefined' || depth <= 0) { + if (dst === undefined || depth <= 0) { if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') { return Object.assign(dst, src); } else { return src; } } - if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') { + if (src !== undefined && typeof dst === 'object' && typeof src === 'object') { Object.keys(src).forEach((key) => { if ( typeof src[key] === 'object' && diff --git a/packages/mermaid/src/config.ts b/packages/mermaid/src/config.ts index 44dcf8bd1..8750c8fa5 100644 --- a/packages/mermaid/src/config.ts +++ b/packages/mermaid/src/config.ts @@ -18,8 +18,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[]) // Join directives let sumOfDirectives: MermaidConfig = {}; - for (let i = 0; i < _directives.length; i++) { - const d = _directives[i]; + for (const d of _directives) { sanitize(d); // Apply the data from the directive where the the overrides the themeVariables @@ -40,7 +39,8 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[]) } currentConfig = cfg; - return cfg; + checkConfig(currentConfig); + return currentConfig; }; /** @@ -56,7 +56,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[]) * function _Default value: At default, will mirror Global Config_ * * @param conf - The base currentConfig to use as siteConfig - * @returns {object} - The siteConfig + * @returns The new siteConfig */ export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => { siteConfig = assignWithDepth({}, defaultConfig); @@ -68,7 +68,7 @@ export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => { siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables); } - currentConfig = updateCurrentConfig(siteConfig, directives); + updateCurrentConfig(siteConfig, directives); return siteConfig; }; @@ -91,7 +91,7 @@ export const updateSiteConfig = (conf: MermaidConfig): MermaidConfig => { * * **Notes**: Returns **any** values in siteConfig. * - * @returns {object} - The siteConfig + * @returns The siteConfig */ export const getSiteConfig = (): MermaidConfig => { return assignWithDepth({}, siteConfig); @@ -107,8 +107,8 @@ export const getSiteConfig = (): MermaidConfig => { * keys. Any values found in conf with key found in siteConfig.secure will be replaced with the * corresponding siteConfig value. * - * @param {any} conf - The potential currentConfig - * @returns {any} - The currentConfig merged with the sanitized conf + * @param conf - The potential currentConfig + * @returns The currentConfig merged with the sanitized conf */ export const setConfig = (conf: MermaidConfig): MermaidConfig => { // sanitize(conf); @@ -117,6 +117,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => { // conf[key] = manipulator ? manipulator(conf[key]) : conf[key]; // }); + checkConfig(conf); assignWithDepth(currentConfig, conf); return getConfig(); @@ -131,7 +132,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => { * * **Notes**: Returns **any** the currentConfig * - * @returns {any} - The currentConfig + * @returns The currentConfig */ export const getConfig = (): MermaidConfig => { return assignWithDepth({}, currentConfig); @@ -146,12 +147,12 @@ export const getConfig = (): MermaidConfig => { * Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies * options in-place * - * @param {any} options - The potential setConfig parameter + * @param options - The potential setConfig parameter */ export const sanitize = (options: any) => { // Checking that options are not in the list of excluded options ['secure', ...(siteConfig.secure ?? [])].forEach((key) => { - if (typeof options[key] !== 'undefined') { + if (options[key] !== undefined) { // DO NOT attempt to print options[key] within `${}` as a malicious script // can exploit the logger's attempt to stringify the value and execute arbitrary code log.debug(`Denied attempt to modify a secure key ${key}`, options[key]); @@ -166,16 +167,15 @@ export const sanitize = (options: any) => { } }); // Check that there no attempts of xss, there should be no tags at all in the directive - // blocking data urls as base64 urls can contain svgs with inline script tags + // blocking data urls as base64 urls can contain svg's with inline script tags Object.keys(options).forEach((key) => { - if (typeof options[key] === 'string') { - if ( - options[key].indexOf('<') > -1 || - options[key].indexOf('>') > -1 || - options[key].indexOf('url(data:') > -1 - ) { - delete options[key]; - } + if ( + typeof options[key] === 'string' && + (options[key].includes('<') || + options[key].includes('>') || + options[key].includes('url(data:')) + ) { + delete options[key]; } if (typeof options[key] === 'object') { sanitize(options[key]); @@ -186,7 +186,7 @@ export const sanitize = (options: any) => { /** * Pushes in a directive to the configuration * - * @param {object} directive The directive to push in + * @param directive - The directive to push in */ export const addDirective = (directive: any) => { if (directive.fontFamily) { @@ -217,10 +217,33 @@ export const addDirective = (directive: any) => { * * **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) * - * @param config + * @param config - base set of values, which currentConfig could be **reset** to. + * Defaults to the current siteConfig (e.g returned by {@link getSiteConfig}). */ export const reset = (config = siteConfig): void => { // Replace current config with siteConfig directives = []; updateCurrentConfig(config, directives); }; + +enum ConfigWarning { + 'LAZY_LOAD_DEPRECATED' = 'The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.', +} +type ConfigWarningStrings = keyof typeof ConfigWarning; +const issuedWarnings: { [key in ConfigWarningStrings]?: boolean } = {}; +const issueWarning = (warning: ConfigWarningStrings) => { + if (issuedWarnings[warning]) { + return; + } + log.warn(ConfigWarning[warning]); + issuedWarnings[warning] = true; +}; + +const checkConfig = (config: MermaidConfig) => { + if (!config) { + return; + } + if (config.lazyLoadedDiagrams || config.loadExternalDiagramsAtStartup) { + issueWarning('LAZY_LOAD_DEPRECATED'); + } +}; diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index d9d94226f..ff199ca8b 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -3,6 +3,10 @@ import DOMPurify from 'dompurify'; export interface MermaidConfig { + /** @deprecated use mermaid.registerLazyDiagrams instead */ + lazyLoadedDiagrams?: string[]; + /** @deprecated use mermaid.registerLazyDiagrams instead */ + loadExternalDiagramsAtStartup?: boolean; theme?: string; themeVariables?: any; themeCSS?: string; @@ -185,6 +189,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig { } export interface GitGraphDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; diagramPadding?: number; nodeLabel?: NodeLabel; mainBranchName?: string; @@ -223,6 +228,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig { export type PieDiagramConfig = BaseDiagramConfig; export interface ErDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; diagramPadding?: number; layoutDirection?: string; minEntityWidth?: number; @@ -234,6 +240,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig { } export interface StateDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; dividerMargin?: number; sizeUnit?: number; @@ -254,6 +261,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig { } export interface ClassDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; dividerMargin?: number; padding?: number; @@ -296,6 +304,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig { sectionFontSize?: string | number; numberSectionStyles?: number; axisFormat?: string; + tickInterval?: string; topAxis?: boolean; } @@ -338,6 +347,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig { } export interface FlowchartDiagramConfig extends BaseDiagramConfig { + titleTopMargin?: number; arrowMarkerAbsolute?: boolean; diagramPadding?: number; htmlLabels?: boolean; diff --git a/packages/mermaid/src/dagre-wrapper/clusters.js b/packages/mermaid/src/dagre-wrapper/clusters.js index 40729dead..57c3ff513 100644 --- a/packages/mermaid/src/dagre-wrapper/clusters.js +++ b/packages/mermaid/src/dagre-wrapper/clusters.js @@ -59,11 +59,9 @@ const rect = (parent, node) => { // Center the label label.attr( 'transform', - 'translate(' + - (node.x - bbox.width / 2) + - ', ' + - (node.y - node.height / 2 + node.padding / 3) + - ')' + // This puts the labal on top of the box instead of inside it + // 'translate(' + (node.x - bbox.width / 2) + ', ' + (node.y - node.height / 2 - bbox.height) + ')' + 'translate(' + (node.x - bbox.width / 2) + ', ' + (node.y - node.height / 2) + ')' ); const rectBox = rect.node().getBBox(); diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js index ba0ce4a5d..af5032096 100644 --- a/packages/mermaid/src/dagre-wrapper/createLabel.js +++ b/packages/mermaid/src/dagre-wrapper/createLabel.js @@ -44,7 +44,9 @@ function addHtmlLabel(node) { const createLabel = (_vertexText, style, isTitle, isNode) => { let vertexText = _vertexText || ''; - if (typeof vertexText === 'object') vertexText = vertexText[0]; + if (typeof vertexText === 'object') { + vertexText = vertexText[0]; + } if (evaluate(getConfig().flowchart.htmlLabels)) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? vertexText = vertexText.replace(/\\n|\n/g, '
'); @@ -52,7 +54,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { const node = { isNode, label: decodeEntities(vertexText).replace( - /fa[lrsb]?:fa-[\w-]+/g, + /fa[blrs]?:fa-[\w-]+/g, (s) => `` ), labelStyle: style.replace('fill:', 'color:'), @@ -72,7 +74,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { rows = []; } - for (let j = 0; j < rows.length; j++) { + for (const row of rows) { const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); tspan.setAttribute('dy', '1em'); @@ -82,7 +84,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { } else { tspan.setAttribute('class', 'row'); } - tspan.textContent = rows[j].trim(); + tspan.textContent = row.trim(); svgLabel.appendChild(tspan); } return svgLabel; diff --git a/packages/mermaid/src/dagre-wrapper/edges.js b/packages/mermaid/src/dagre-wrapper/edges.js index 6ed08e924..bb22cee83 100644 --- a/packages/mermaid/src/dagre-wrapper/edges.js +++ b/packages/mermaid/src/dagre-wrapper/edges.js @@ -130,9 +130,21 @@ export const positionEdgeLabel = (edge, paths) => { if (path) { // // debugger; const pos = utils.calcLabelPosition(path); - log.info('Moving label from (', x, ',', y, ') to (', pos.x, ',', pos.y, ') abc78'); - // x = pos.x; - // y = pos.y; + log.info( + 'Moving label ' + edge.label + ' from (', + x, + ',', + y, + ') to (', + pos.x, + ',', + pos.y, + ') abc78' + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } } el.attr('transform', 'translate(' + x + ', ' + y + ')'); } @@ -310,7 +322,7 @@ const cutPathAtIntersect = (_points, boundryNode) => { // const node = clusterDb[edge.toCluster].node; log.info('abc88 checking point', point, boundryNode); - // check if point is inside the boundry rect + // check if point is inside the boundary rect if (!outsideNode(boundryNode, point) && !isInside) { // First point inside the rect found // Calc the intersection coord between the point anf the last point outside the rect @@ -324,7 +336,7 @@ const cutPathAtIntersect = (_points, boundryNode) => { pointPresent = pointPresent || (p.x === inter.x && p.y === inter.y); }); // // if (!pointPresent) { - if (!points.find((e) => e.x === inter.x && e.y === inter.y)) { + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { points.push(inter); } else { log.warn('abc88 no intersect', inter, points); @@ -336,7 +348,9 @@ const cutPathAtIntersect = (_points, boundryNode) => { log.warn('abc88 outside', point, lastPointOutside); lastPointOutside = point; // points.push(point); - if (!isInside) points.push(point); + if (!isInside) { + points.push(point); + } } }); log.warn('abc88 returning points', points); @@ -429,7 +443,7 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph }) .curve(curve); - // Contruct stroke classes based on properties + // Construct stroke classes based on properties let strokeClasses; switch (edge.thickness) { case 'normal': @@ -461,7 +475,7 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph .attr('style', edge.style); // DEBUG code, adds a red circle at each edge coordinate - // edge.points.forEach(point => { + // edge.points.forEach((point) => { // elem // .append('circle') // .style('stroke', 'red') diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js index 72652ff8c..e2d7d51f4 100644 --- a/packages/mermaid/src/dagre-wrapper/index.js +++ b/packages/mermaid/src/dagre-wrapper/index.js @@ -1,5 +1,5 @@ -import dagre from 'dagre'; -import graphlib from 'graphlib'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; import insertMarkers from './markers'; import { updateNodeBounds } from './shapes/util'; import { @@ -15,7 +15,7 @@ import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } f import { log } from '../logger'; const recursiveRender = (_elem, graph, diagramtype, parentCluster) => { - log.info('Graph in recursive render: XXX', graphlib.json.write(graph), parentCluster); + log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster); const dir = graph.graph().rankdir; log.trace('Dir in recursive render - dir:', dir); @@ -37,7 +37,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => { // to the abstract node and is later used by dagre for the layout graph.nodes().forEach(function (v) { const node = graph.node(v); - if (typeof parentCluster !== 'undefined') { + if (parentCluster !== undefined) { const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); // data.clusterPositioning = true; log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster); @@ -95,8 +95,8 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => { log.info('### Layout ###'); log.info('#############################################'); log.info(graph); - dagre.layout(graph); - log.info('Graph after layout:', graphlib.json.write(graph)); + dagreLayout(graph); + log.info('Graph after layout:', graphlibJson.write(graph)); // Move the nodes to the correct place let diff = 0; sortNodesByHierarchy(graph).forEach(function (v) { @@ -153,10 +153,10 @@ export const render = (elem, graph, markers, diagramtype, id) => { clearClusters(); clearGraphlib(); - log.warn('Graph at first:', graphlib.json.write(graph)); + log.warn('Graph at first:', graphlibJson.write(graph)); adjustClustersAndEdges(graph); - log.warn('Graph after:', graphlib.json.write(graph)); - // log.warn('Graph ever after:', graphlib.json.write(graph.node('A').graph)); + log.warn('Graph after:', graphlibJson.write(graph)); + // log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph)); recursiveRender(elem, graph, diagramtype); }; diff --git a/packages/mermaid/src/dagre-wrapper/intersect/index.js b/packages/mermaid/src/dagre-wrapper/intersect/index.js index 9acff666c..e33b6dd51 100644 --- a/packages/mermaid/src/dagre-wrapper/intersect/index.js +++ b/packages/mermaid/src/dagre-wrapper/intersect/index.js @@ -1,5 +1,5 @@ /* - * Borrowed with love from from dagrge-d3. Many thanks to cpettitt! + * Borrowed with love from from dagre-d3. Many thanks to cpettitt! */ import node from './intersect-node.js'; diff --git a/packages/mermaid/src/dagre-wrapper/intersect/intersect-line.js b/packages/mermaid/src/dagre-wrapper/intersect/intersect-line.js index f9ef0b15f..e97ae6f0d 100644 --- a/packages/mermaid/src/dagre-wrapper/intersect/intersect-line.js +++ b/packages/mermaid/src/dagre-wrapper/intersect/intersect-line.js @@ -28,7 +28,7 @@ function intersectLine(p1, p2, q1, q2) { // Check signs of r3 and r4. If both point 3 and point 4 lie on // same side of line 1, the line segments do not intersect. if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { - return /*DONT_INTERSECT*/; + return /*DON'T_INTERSECT*/; } // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0 @@ -44,7 +44,7 @@ function intersectLine(p1, p2, q1, q2) { // on same side of second line segment, the line segments do // not intersect. if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { - return /*DONT_INTERSECT*/; + return /*DON'T_INTERSECT*/; } // Line segments intersect: compute intersection point. diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js index 4c283b12f..5722f7cc0 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js @@ -1,50 +1,50 @@ /** Decorates with functions required by mermaids dagre-wrapper. */ import { log } from '../logger'; -import graphlib from 'graphlib'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; export let clusterDb = {}; -let decendants = {}; +let descendants = {}; let parents = {}; export const clear = () => { - decendants = {}; + descendants = {}; parents = {}; clusterDb = {}; }; -const isDecendant = (id, ancenstorId) => { +const isDescendant = (id, ancenstorId) => { // if (id === ancenstorId) return true; - log.trace( - 'In isDecendant', - ancenstorId, - ' ', - id, - ' = ', - decendants[ancenstorId].indexOf(id) >= 0 - ); - if (decendants[ancenstorId].indexOf(id) >= 0) return true; + log.trace('In isDecendant', ancenstorId, ' ', id, ' = ', descendants[ancenstorId].includes(id)); + if (descendants[ancenstorId].includes(id)) { + return true; + } return false; }; const edgeInCluster = (edge, clusterId) => { - log.info('Decendants of ', clusterId, ' is ', decendants[clusterId]); + log.info('Decendants of ', clusterId, ' is ', descendants[clusterId]); log.info('Edge is ', edge); // Edges to/from the cluster is not in the cluster, they are in the parent - if (edge.v === clusterId) return false; - if (edge.w === clusterId) return false; + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } - if (!decendants[clusterId]) { + if (!descendants[clusterId]) { log.debug('Tilt, ', clusterId, ',not in decendants'); return false; } - if (decendants[clusterId].indexOf(edge.v) >= 0) return true; - if (isDecendant(edge.v, clusterId)) return true; - if (isDecendant(edge.w, clusterId)) return true; - if (decendants[clusterId].indexOf(edge.w) >= 0) return true; - - return false; + return ( + descendants[clusterId].includes(edge.v) || + isDescendant(edge.v, clusterId) || + isDescendant(edge.w, clusterId) || + descendants[clusterId].includes(edge.w) + ); }; const copy = (clusterId, graph, newGraph, rootId) => { @@ -125,14 +125,14 @@ const copy = (clusterId, graph, newGraph, rootId) => { graph.removeNode(node); }); }; -export const extractDecendants = (id, graph) => { +export const extractDescendants = (id, graph) => { // log.debug('Extracting ', id); const children = graph.children(id); - let res = [].concat(children); + let res = [...children]; - for (let i = 0; i < children.length; i++) { - parents[children[i]] = id; - res = res.concat(extractDecendants(children[i], graph)); + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; } return res; @@ -147,13 +147,13 @@ export const extractDecendants = (id, graph) => { export const validate = (graph) => { const edges = graph.edges(); log.trace('Edges: ', edges); - for (let i = 0; i < edges.length; i++) { - if (graph.children(edges[i].v).length > 0) { - log.trace('The node ', edges[i].v, ' is part of and edge even though it has children'); + for (const edge of edges) { + if (graph.children(edge.v).length > 0) { + log.trace('The node ', edge.v, ' is part of and edge even though it has children'); return false; } - if (graph.children(edges[i].w).length > 0) { - log.trace('The node ', edges[i].w, ' is part of and edge even though it has children'); + if (graph.children(edge.w).length > 0) { + log.trace('The node ', edge.w, ' is part of and edge even though it has children'); return false; } } @@ -176,8 +176,8 @@ export const findNonClusterChild = (id, graph) => { log.trace('This is a valid node', id); return id; } - for (let i = 0; i < children.length; i++) { - const _id = findNonClusterChild(children[i], graph); + for (const child of children) { + const _id = findNonClusterChild(child, graph); if (_id) { log.trace('Found replacement for', id, ' => ', _id); return _id; @@ -219,7 +219,7 @@ export const adjustClustersAndEdges = (graph, depth) => { ' Replacement id in edges: ', findNonClusterChild(id, graph) ); - decendants[id] = extractDecendants(id, graph); + descendants[id] = extractDescendants(id, graph); clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; } }); @@ -229,28 +229,28 @@ export const adjustClustersAndEdges = (graph, depth) => { const children = graph.children(id); const edges = graph.edges(); if (children.length > 0) { - log.debug('Cluster identified', id, decendants); + log.debug('Cluster identified', id, descendants); edges.forEach((edge) => { // log.debug('Edge, decendants: ', edge, decendants[id]); // Check if any edge leaves the cluster (not the actual cluster, that's a link from the box) if (edge.v !== id && edge.w !== id) { - // Any edge where either the one of the nodes is decending to the cluster but not the other + // Any edge where either the one of the nodes is descending to the cluster but not the other // if (decendants[id].indexOf(edge.v) < 0 && decendants[id].indexOf(edge.w) < 0) { - const d1 = isDecendant(edge.v, id); - const d2 = isDecendant(edge.w, id); + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); // d1 xor d2 - if either d1 is true and d2 is false or the other way around if (d1 ^ d2) { log.warn('Edge: ', edge, ' leaves cluster ', id); - log.warn('Decendants of XXX ', id, ': ', decendants[id]); + log.warn('Decendants of XXX ', id, ': ', descendants[id]); clusterDb[id].externalConnections = true; } } }); } else { - log.debug('Not a cluster ', id, decendants); + log.debug('Not a cluster ', id, descendants); } }); @@ -270,7 +270,7 @@ export const adjustClustersAndEdges = (graph, depth) => { 'ids:', e.v, e.w, - 'Translateing: ', + 'Translating: ', clusterDb[e.v], ' --- ', clusterDb[e.w] @@ -306,13 +306,17 @@ export const adjustClustersAndEdges = (graph, depth) => { v = getAnchorId(e.v); w = getAnchorId(e.w); graph.removeEdge(e.v, e.w, e.name); - if (v !== e.v) edge.fromCluster = e.v; - if (w !== e.w) edge.toCluster = e.w; + if (v !== e.v) { + edge.fromCluster = e.v; + } + if (w !== e.w) { + edge.toCluster = e.w; + } log.warn('Fix Replacing with XXX', v, w, e.name); graph.setEdge(v, w, edge, e.name); } }); - log.warn('Adjusted Graph', graphlib.json.write(graph)); + log.warn('Adjusted Graph', graphlibJson.write(graph)); extractor(graph, 0); log.trace(clusterDb); @@ -326,7 +330,7 @@ export const adjustClustersAndEdges = (graph, depth) => { }; export const extractor = (graph, depth) => { - log.warn('extractor - ', depth, graphlib.json.write(graph), graph.children('D')); + log.warn('extractor - ', depth, graphlibJson.write(graph), graph.children('D')); if (depth > 10) { log.error('Bailing out'); return; @@ -336,8 +340,7 @@ export const extractor = (graph, depth) => { // for (let i = 0;) let nodes = graph.nodes(); let hasChildren = false; - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]; + for (const node of nodes) { const children = graph.children(node); hasChildren = hasChildren || children.length > 0; } @@ -349,9 +352,7 @@ export const extractor = (graph, depth) => { // const clusters = Object.keys(clusterDb); // clusters.forEach(clusterId => { log.debug('Nodes = ', nodes, depth); - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]; - + for (const node of nodes) { log.debug( 'Extracting node', node, @@ -383,11 +384,9 @@ export const extractor = (graph, depth) => { const graphSettings = graph.graph(); let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB'; - if (clusterDb[node]) { - if (clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { - dir = clusterDb[node].clusterData.dir; - log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir); - } + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir); } const clusterGraph = new graphlib.Graph({ @@ -405,7 +404,7 @@ export const extractor = (graph, depth) => { return {}; }); - log.warn('Old graph before copy', graphlib.json.write(graph)); + log.warn('Old graph before copy', graphlibJson.write(graph)); copy(node, graph, clusterGraph, node); graph.setNode(node, { clusterNode: true, @@ -414,8 +413,8 @@ export const extractor = (graph, depth) => { labelText: clusterDb[node].labelText, graph: clusterGraph, }); - log.warn('New graph after copy node: (', node, ')', graphlib.json.write(clusterGraph)); - log.debug('Old graph after copy', graphlib.json.write(graph)); + log.warn('New graph after copy node: (', node, ')', graphlibJson.write(clusterGraph)); + log.debug('Old graph after copy', graphlibJson.write(graph)); } else { log.warn( 'Cluster ** ', @@ -435,8 +434,7 @@ export const extractor = (graph, depth) => { nodes = graph.nodes(); log.warn('New list of nodes', nodes); - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]; + for (const node of nodes) { const data = graph.node(node); log.warn(' Now next level', node, data); if (data.clusterNode) { @@ -446,12 +444,14 @@ export const extractor = (graph, depth) => { }; const sorter = (graph, nodes) => { - if (nodes.length === 0) return []; + if (nodes.length === 0) { + return []; + } let result = Object.assign(nodes); nodes.forEach((node) => { const children = graph.children(node); const sorted = sorter(graph, children); - result = result.concat(sorted); + result = [...result, ...sorted]; }); return result; diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js index 8155bbf70..f594e3430 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js @@ -1,9 +1,9 @@ -import graphlib from 'graphlib'; -import dagre from 'dagre'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { validate, adjustClustersAndEdges, - extractDecendants, + extractDescendants, sortNodesByHierarchy, } from './mermaid-graphlib'; import { setLogLevel, log } from '../logger'; @@ -233,9 +233,9 @@ describe('Graphlib decorations', () => { g.setParent('D', 'C'); // log.info('Graph before', g.node('D')) - // log.info('Graph before', graphlib.json.write(g)) + // log.info('Graph before', graphlibJson.write(g)) adjustClustersAndEdges(g); - // log.info('Graph after', graphlib.json.write(g), g.node('C').graph) + // log.info('Graph after', graphlibJson.write(g), g.node('C').graph) const CGraph = g.node('C').graph; const DGraph = CGraph.node('D').graph; @@ -279,9 +279,9 @@ describe('Graphlib decorations', () => { g.setEdge('A', 'C', { data: 'link2' }, '2'); log.info('Graph before', g.node('D')); - log.info('Graph before', graphlib.json.write(g)); + log.info('Graph before', graphlibJson.write(g)); adjustClustersAndEdges(g); - log.trace('Graph after', graphlib.json.write(g)); + log.trace('Graph after', graphlibJson.write(g)); expect(g.nodes()).toEqual(['C', 'B', 'A']); expect(g.nodes().length).toBe(3); expect(g.edges().length).toBe(2); @@ -334,11 +334,11 @@ describe('Graphlib decorations', () => { g.setEdge('c', 'd', { data: 'link2' }, '2'); g.setEdge('d', 'e', { data: 'link2' }, '2'); - log.info('Graph before', graphlib.json.write(g)); + log.info('Graph before', graphlibJson.write(g)); adjustClustersAndEdges(g); const bGraph = g.node('b').graph; - // log.trace('Graph after', graphlib.json.write(g)) - log.info('Graph after', graphlib.json.write(bGraph)); + // log.trace('Graph after', graphlibJson.write(g)) + log.info('Graph after', graphlibJson.write(bGraph)); expect(bGraph.nodes().length).toBe(3); expect(bGraph.edges().length).toBe(2); }); @@ -360,13 +360,13 @@ describe('Graphlib decorations', () => { g.setParent('c', 'b'); g.setParent('e', 'c'); - log.info('Graph before', graphlib.json.write(g)); + log.info('Graph before', graphlibJson.write(g)); adjustClustersAndEdges(g); const aGraph = g.node('a').graph; const bGraph = aGraph.node('b').graph; - log.info('Graph after', graphlib.json.write(aGraph)); + log.info('Graph after', graphlibJson.write(aGraph)); const cGraph = bGraph.node('c').graph; - // log.trace('Graph after', graphlib.json.write(g)) + // log.trace('Graph after', graphlibJson.write(g)) expect(aGraph.nodes().length).toBe(1); expect(bGraph.nodes().length).toBe(1); expect(cGraph.nodes().length).toBe(1); @@ -388,19 +388,19 @@ flowchart TB const exportedGraph = JSON.parse( '{"options":{"directed":true,"multigraph":true,"compound":true},"nodes":[{"v":"A","value":{"labelStyle":"","shape":"rect","labelText":"A","rx":0,"ry":0,"class":"default","style":"","id":"A","width":500,"type":"group","padding":15}},{"v":"B","value":{"labelStyle":"","shape":"rect","labelText":"B","rx":0,"ry":0,"class":"default","style":"","id":"B","width":500,"type":"group","padding":15},"parent":"A"},{"v":"b","value":{"labelStyle":"","shape":"rect","labelText":"b","rx":0,"ry":0,"class":"default","style":"","id":"b","padding":15},"parent":"A"},{"v":"c","value":{"labelStyle":"","shape":"rect","labelText":"c","rx":0,"ry":0,"class":"default","style":"","id":"c","padding":15},"parent":"B"},{"v":"a","value":{"labelStyle":"","shape":"rect","labelText":"a","rx":0,"ry":0,"class":"default","style":"","id":"a","padding":15},"parent":"A"}],"edges":[{"v":"b","w":"B","name":"1","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-b-B","classes":"flowchart-link LS-b LE-B"}},{"v":"a","w":"c","name":"2","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-a-c","classes":"flowchart-link LS-a LE-c"}}],"value":{"rankdir":"TB","nodesep":50,"ranksep":50,"marginx":8,"marginy":8}}' ); - const gr = graphlib.json.read(exportedGraph); + const gr = graphlibJson.read(exportedGraph); - log.info('Graph before', graphlib.json.write(gr)); + log.info('Graph before', graphlibJson.write(gr)); adjustClustersAndEdges(gr); const aGraph = gr.node('A').graph; const bGraph = aGraph.node('B').graph; - log.info('Graph after', graphlib.json.write(aGraph)); - // log.trace('Graph after', graphlib.json.write(g)) + log.info('Graph after', graphlibJson.write(aGraph)); + // log.trace('Graph after', graphlibJson.write(g)) expect(aGraph.parent('c')).toBe('B'); expect(aGraph.parent('B')).toBe(undefined); }); }); -describe('extractDecendants', function () { +describe('extractDescendants', function () { let g; beforeEach(function () { setLogLevel(1); @@ -443,9 +443,9 @@ describe('extractDecendants', function () { g.setEdge('A', 'C', { data: 'link2' }, '2'); // log.info(g.edges()) - const d1 = extractDecendants('A', g); - const d2 = extractDecendants('B', g); - const d3 = extractDecendants('C', g); + const d1 = extractDescendants('A', g); + const d2 = extractDescendants('B', g); + const d3 = extractDescendants('C', g); expect(d1).toEqual(['a']); expect(d2).toEqual(['b']); diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js index f25eb2e86..fda789323 100644 --- a/packages/mermaid/src/dagre-wrapper/nodes.js +++ b/packages/mermaid/src/dagre-wrapper/nodes.js @@ -291,11 +291,15 @@ const cylinder = (parent, node) => { (Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) ) { // ellipsis equation: x*x / a*a + y*y / b*b = 1 - // solve for y to get adjustion value for pos.y + // solve for y to get adjusted value for pos.y let y = ry * ry * (1 - (x * x) / (rx * rx)); - if (y != 0) y = Math.sqrt(y); + if (y != 0) { + y = Math.sqrt(y); + } y = ry - y; - if (point.y - node.y > 0) y = -y; + if (point.y - node.y > 0) { + y = -y; + } pos.y += y; } @@ -387,12 +391,10 @@ const labelRect = (parent, node) => { function applyNodePropertyBorders(rect, borders, totalWidth, totalHeight) { const strokeDashArray = []; const addBorder = (length) => { - strokeDashArray.push(length); - strokeDashArray.push(0); + strokeDashArray.push(length, 0); }; const skipBorder = (length) => { - strokeDashArray.push(0); - strokeDashArray.push(length); + strokeDashArray.push(0, length); }; if (borders.includes('t')) { log.debug('add top border'); diff --git a/packages/mermaid/src/dagre-wrapper/shapes/util.js b/packages/mermaid/src/dagre-wrapper/shapes/util.js index 1655d2e91..6de0da638 100644 --- a/packages/mermaid/src/dagre-wrapper/shapes/util.js +++ b/packages/mermaid/src/dagre-wrapper/shapes/util.js @@ -19,7 +19,13 @@ export const labelHelper = (parent, node, _classes, isNode) => { // Create the label and insert it after the rect const label = shapeSvg.insert('g').attr('class', 'label').attr('style', node.labelStyle); - const labelText = typeof node.labelText === 'string' ? node.labelText : node.labelText[0]; + // Replace labelText with default value if undefined + let labelText; + if (node.labelText === undefined) { + labelText = ''; + } else { + labelText = typeof node.labelText === 'string' ? node.labelText : node.labelText[0]; + } const text = label .node() diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 681fda60c..37d4f71ff 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -8,19 +8,27 @@ import { MermaidConfig } from './config.type'; * * These are the default options which can be overridden with the initialization call like so: * - * **Example 1:**
 mermaid.initialize({ flowchart:{ htmlLabels: false } }); 
+ * **Example 1:** * - * **Example 2:**
  
+ * ```html + * + * ``` * * A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults). * A description of each option follows below. - * - * @name Configuration */ const config: Partial = { /** @@ -30,8 +38,16 @@ const config: Partial = { * | --------- | --------------- | ------ | -------- | ---------------------------------------------- | * | theme | Built in Themes | string | Optional | 'default', 'forest', 'dark', 'neutral', 'null' | * - * **Notes:** To disable any pre-defined mermaid theme, use "null".
 "theme": "forest",
-   * "themeCSS": ".node rect { fill: red; }" 
+ * **Notes:** To disable any pre-defined mermaid theme, use "null". + * + * @example + * + * ```js + * { + * "theme": "forest", + * "themeCSS": ".node rect { fill: red; }" + * } + * ``` */ theme: 'default', themeVariables: theme['default'].getThemeVariables(), @@ -115,15 +131,14 @@ const config: Partial = { * Default value: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'] */ secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], - /** * This option controls if the generated ids of nodes in the SVG are generated randomly or based * on a seed. If set to false, the IDs are generated based on the current date and thus are not - * deterministic. This is the default behaviour. + * deterministic. This is the default behavior. * * **Notes**: * - * This matters if your files are checked into sourcecontrol e.g. git and should not change unless + * This matters if your files are checked into source control e.g. git and should not change unless * content is changed. * * Default value: false @@ -139,6 +154,17 @@ const config: Partial = { /** The object containing configurations specific for flowcharts */ flowchart: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the flowchart | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, + /** * | Parameter | Description | Type | Required | Values | * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | @@ -633,9 +659,9 @@ const config: Partial = { numberSectionStyles: 4, /** - * | Parameter | Description | Type | Required | Values | - * | ---------- | --------------------------- | ---- | -------- | ---------------- | - * | axisFormat | Datetime format of the axis | 3 | Required | Date in yy-mm-dd | + * | Parameter | Description | Type | Required | Values | + * | ---------- | ---------------------------- | ---- | -------- | ---------------- | + * | axisFormat | Date/time format of the axis | 3 | Required | Date in yy-mm-dd | * * **Notes:** * @@ -645,6 +671,19 @@ const config: Partial = { */ axisFormat: '%Y-%m-%d', + /** + * | Parameter | Description | Type | Required | Values | + * | ------------ | ------------| ------ | -------- | ------- | + * | tickInterval | axis ticks | string | Optional | string | + * + * **Notes:** + * + * Pattern is /^([1-9][0-9]*)(minute|hour|day|week|month)$/ + * + * Default value: undefined + */ + tickInterval: undefined, + /** * | Parameter | Description | Type | Required | Values | * | ----------- | ----------- | ------- | -------- | ----------- | @@ -823,6 +862,16 @@ const config: Partial = { sectionColours: ['#fff'], }, class: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the class diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, arrowMarkerAbsolute: false, dividerMargin: 10, padding: 5, @@ -856,6 +905,16 @@ const config: Partial = { defaultRenderer: 'dagre-wrapper', }, state: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the state diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, dividerMargin: 10, sizeUnit: 5, padding: 8, @@ -904,6 +963,17 @@ const config: Partial = { /** The object containing configurations specific for entity relationship diagrams */ er: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, + /** * | Parameter | Description | Type | Required | Values | * | -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | @@ -1057,6 +1127,16 @@ const config: Partial = { line_height: 20, }, gitGraph: { + /** + * ### titleTopMargin + * + * | Parameter | Description | Type | Required | Values | + * | -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | + * | titleTopMargin | Margin top for the text over the Git diagram | Integer | Required | Any Positive Value | + * + * **Notes:** Default value: 25 + */ + titleTopMargin: 25, diagramPadding: 8, nodeLabel: { width: 75, @@ -1168,7 +1248,7 @@ const config: Partial = { * | --------------- | ----------- | ------- | -------- | ------------------ | * | c4BoundaryInRow | See Notes | Integer | Required | Any Positive Value | * - * **Notes:** How many boundarys to place in each row. + * **Notes:** How many boundaries to place in each row. * * Default value: 2 */ @@ -1833,8 +1913,12 @@ const config: Partial = { fontSize: 16, }; -if (config.class) config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; -if (config.gitGraph) config.gitGraph.arrowMarkerAbsolute = config.arrowMarkerAbsolute; +if (config.class) { + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; +} +if (config.gitGraph) { + config.gitGraph.arrowMarkerAbsolute = config.arrowMarkerAbsolute; +} const keyify = (obj: any, prefix = ''): string[] => Object.keys(obj).reduce((res: string[], el): string[] => { diff --git a/packages/mermaid/src/diagram-api/detectType.ts b/packages/mermaid/src/diagram-api/detectType.ts index afb9a9078..2ff0b5532 100644 --- a/packages/mermaid/src/diagram-api/detectType.ts +++ b/packages/mermaid/src/diagram-api/detectType.ts @@ -1,19 +1,21 @@ import { MermaidConfig } from '../config.type'; +import { log } from '../logger'; +import { DetectorRecord, DiagramDetector, DiagramLoader } from './types'; +import { frontMatterRegex } from './frontmatter'; -export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean; -export type DetectorRecord = { detector: DiagramDetector; path: string }; - -const directive = - /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; +const directive = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi; const anyComment = /\s*%%.*\n/gm; const detectors: Record = {}; /** - * @function detectType Detects the type of the graph text. Takes into consideration the possible - * existence of an %%init directive + * Detects the type of the graph text. * - * ```mermaid + * Takes into consideration the possible existence of an `%%init` directive + * + * @param text - The text defining the graph. For example: + * + * ```mermaid * %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%% * graph LR * a-->b @@ -24,36 +26,28 @@ const detectors: Record = {}; * f-->g * g-->h * ``` - * @param {string} text The text defining the graph - * @param {{ - * class: { defaultRenderer: string } | undefined; - * state: { defaultRenderer: string } | undefined; - * flowchart: { defaultRenderer: string } | undefined; - * }} [config] - * @returns {string} A graph definition key + * + * @param config - The mermaid config. + * @returns A graph definition key */ export const detectType = function (text: string, config?: MermaidConfig): string { - text = text.replace(directive, '').replace(anyComment, '\n'); - - // console.log(detectors); - - for (const [key, detectorRecord] of Object.entries(detectors)) { - if (detectorRecord.detector(text, config)) { + text = text.replace(frontMatterRegex, '').replace(directive, '').replace(anyComment, '\n'); + for (const [key, { detector }] of Object.entries(detectors)) { + const diagram = detector(text, config); + if (diagram) { return key; } } - // TODO: #3391 - // throw new Error(`No diagram type detected for text: ${text}`); - return 'flowchart'; + + throw new Error(`No diagram type detected for text: ${text}`); }; -export const addDetector = (key: string, detector: DiagramDetector, path: string) => { - detectors[key] = { detector, path }; -}; - -export const getPathForDiagram = (id: string) => { - const detectorRecord = detectors[id]; - if (detectorRecord) { - return detectorRecord.path; +export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => { + if (detectors[key]) { + throw new Error(`Detector with key ${key} already exists`); } + detectors[key] = { detector, loader }; + log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`); }; + +export const getDiagramLoader = (key: string) => detectors[key].loader; diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 912559c90..a26edb303 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -1,16 +1,4 @@ -import { - registerDiagram, - registerDetector, - DiagramDefinition, - DiagramDetector, -} from './diagramAPI'; - -// // @ts-ignore: TODO Fix ts errors -// import mindmapParser from '../diagrams/mindmap/parser/mindmap'; -// import * as mindmapDb from '../diagrams/mindmap/mindmapDb'; -// import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector'; -// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer'; -// import mindmapStyles from '../diagrams/mindmap/styles'; +import { registerDiagram } from './diagramAPI'; // @ts-ignore: TODO Fix ts errors import gitGraphParser from '../diagrams/git/parser/gitGraph'; @@ -106,17 +94,15 @@ import { setConfig } from '../config'; import errorRenderer from '../diagrams/error/errorRenderer'; import errorStyles from '../diagrams/error/styles'; -const registerDiagramAndDetector = ( - id: string, - diagram: DiagramDefinition, - detector: DiagramDetector -) => { - registerDiagram(id, diagram); - registerDetector(id, detector, ''); -}; - +let hasLoadedDiagrams = false; export const addDiagrams = () => { - registerDiagramAndDetector( + if (hasLoadedDiagrams) { + return; + } + // This is added here to avoid race-conditions. + // We could optimize the loading logic somehow. + hasLoadedDiagrams = true; + registerDiagram( 'error', // Special diagram with error messages but setup as a regular diagram { @@ -140,7 +126,7 @@ export const addDiagrams = () => { (text) => text.toLowerCase().trim() === 'error' ); - registerDiagramAndDetector( + registerDiagram( 'c4', { parser: c4Parser, @@ -153,7 +139,7 @@ export const addDiagrams = () => { }, c4Detector ); - registerDiagramAndDetector( + registerDiagram( 'class', { parser: classParser, @@ -170,7 +156,7 @@ export const addDiagrams = () => { }, classDetector ); - registerDiagramAndDetector( + registerDiagram( 'classDiagram', { parser: classParser, @@ -187,7 +173,7 @@ export const addDiagrams = () => { }, classDetectorV2 ); - registerDiagramAndDetector( + registerDiagram( 'er', { parser: erParser, @@ -197,7 +183,7 @@ export const addDiagrams = () => { }, erDetector ); - registerDiagramAndDetector( + registerDiagram( 'gantt', { parser: ganttParser, @@ -207,7 +193,7 @@ export const addDiagrams = () => { }, ganttDetector ); - registerDiagramAndDetector( + registerDiagram( 'info', { parser: infoParser, @@ -217,7 +203,7 @@ export const addDiagrams = () => { }, infoDetector ); - registerDiagramAndDetector( + registerDiagram( 'pie', { parser: pieParser, @@ -227,7 +213,7 @@ export const addDiagrams = () => { }, pieDetector ); - registerDiagramAndDetector( + registerDiagram( 'requirement', { parser: requirementParser, @@ -237,7 +223,7 @@ export const addDiagrams = () => { }, requirementDetector ); - registerDiagramAndDetector( + registerDiagram( 'sequence', { parser: sequenceParser, @@ -260,7 +246,7 @@ export const addDiagrams = () => { }, sequenceDetector ); - registerDiagramAndDetector( + registerDiagram( 'state', { parser: stateParser, @@ -277,7 +263,7 @@ export const addDiagrams = () => { }, stateDetector ); - registerDiagramAndDetector( + registerDiagram( 'stateDiagram', { parser: stateParser, @@ -294,7 +280,7 @@ export const addDiagrams = () => { }, stateDetectorV2 ); - registerDiagramAndDetector( + registerDiagram( 'journey', { parser: journeyParser, @@ -309,7 +295,7 @@ export const addDiagrams = () => { journeyDetector ); - registerDiagramAndDetector( + registerDiagram( 'flowchart', { parser: flowParser, @@ -329,7 +315,7 @@ export const addDiagrams = () => { }, flowDetector ); - registerDiagramAndDetector( + registerDiagram( 'flowchart-v2', { parser: flowParser, @@ -350,14 +336,9 @@ export const addDiagrams = () => { }, flowDetectorV2 ); - registerDiagramAndDetector( + registerDiagram( 'gitGraph', { parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles }, gitGraphDetector ); - // registerDiagram( - // 'mindmap', - // { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles }, - // mindmapDetector - // ); }; diff --git a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts index 018e72bd4..ea546fbb6 100644 --- a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts +++ b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts @@ -1,6 +1,7 @@ -import { detectType, DiagramDetector } from './detectType'; -import { getDiagram, registerDiagram, registerDetector } from './diagramAPI'; +import { detectType } from './detectType'; +import { getDiagram, registerDiagram } from './diagramAPI'; import { addDiagrams } from './diagram-orchestration'; +import { DiagramDetector } from './types'; addDiagrams(); @@ -15,11 +16,12 @@ describe('DiagramAPI', () => { it('should handle diagram registrations', () => { expect(() => getDiagram('loki')).toThrow(); - expect(() => detectType('loki diagram')).not.toThrow(); // TODO: #3391 + expect(() => detectType('loki diagram')).toThrow( + 'No diagram type detected for text: loki diagram' + ); const detector: DiagramDetector = (str: string) => { return str.match('loki') !== null; }; - registerDetector('loki', detector, ''); registerDiagram( 'loki', { @@ -28,7 +30,7 @@ describe('DiagramAPI', () => { renderer: {}, styles: {}, }, - (text: string) => text.includes('loki') + detector ); expect(getDiagram('loki')).not.toBeNull(); expect(detectType('loki diagram')).toBe('loki'); diff --git a/packages/mermaid/src/diagram-api/diagramAPI.ts b/packages/mermaid/src/diagram-api/diagramAPI.ts index beb770f31..748cc5f96 100644 --- a/packages/mermaid/src/diagram-api/diagramAPI.ts +++ b/packages/mermaid/src/diagram-api/diagramAPI.ts @@ -1,58 +1,53 @@ -import { addDetector, DiagramDetector as _DiagramDetector } from './detectType'; +import { addDetector } from './detectType'; import { log as _log, setLogLevel as _setLogLevel } from '../logger'; import { getConfig as _getConfig } from '../config'; import { sanitizeText as _sanitizeText } from '../diagrams/common/common'; -import { MermaidConfig } from '../config.type'; import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox'; import { addStylesForDiagram } from '../styles'; +import { DiagramDefinition, DiagramDetector } from './types'; /* - Packaging and exposing resources for externa diagrams so that they can import - diagramAPI and have access to selct parts of mermaid common code reqiored to - create diagrams worling like the internal diagrams. + Packaging and exposing resources for external diagrams so that they can import + diagramAPI and have access to select parts of mermaid common code required to + create diagrams working like the internal diagrams. */ export const log = _log; export const setLogLevel = _setLogLevel; -export type DiagramDetector = _DiagramDetector; export const getConfig = _getConfig; export const sanitizeText = (text: string) => _sanitizeText(text, getConfig()); export const setupGraphViewbox = _setupGraphViewbox; -export interface DiagramDefinition { - db: any; - renderer: any; - parser: any; - styles: any; - init?: (config: MermaidConfig) => void; -} - const diagrams: Record = {}; -const connectCallbacks: Record = {}; // TODO fix, eslint-disable-line @typescript-eslint/no-explicit-any export interface Detectors { [key: string]: DiagramDetector; } -export const registerDetector = (id: string, detector: DiagramDetector, path: string) => { - addDetector(id, detector, path); -}; - +/** + * Registers the given diagram with Mermaid. + * + * Can be used for third-party custom diagrams. + * + * @param id - A unique ID for the given diagram. + * @param diagram - The diagram definition. + * @param detector - Function that returns `true` if a given mermaid text is this diagram definition. + */ export const registerDiagram = ( id: string, diagram: DiagramDefinition, - callback?: ( - _log: any, - _setLogLevel: any, - _getConfig: any, - _sanitizeText: any, - _setupGraphViewbox: any - ) => void + detector?: DiagramDetector ) => { if (diagrams[id]) { - log.warn(`Diagram ${id} already registered.`); + throw new Error(`Diagram ${id} already registered.`); } diagrams[id] = diagram; + if (detector) { + addDetector(id, detector); + } addStylesForDiagram(id, diagram.styles); - connectCallbacks[id] = callback; + + if (diagram.injectUtils) { + diagram.injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox); + } }; export const getDiagram = (name: string): DiagramDefinition => { @@ -61,19 +56,3 @@ export const getDiagram = (name: string): DiagramDefinition => { } throw new Error(`Diagram ${name} not found.`); }; - -/** - * - * @param sScriptSrc - */ -export const loadDiagram = (sScriptSrc: string) => - new Promise((resolve) => { - const oHead = document.getElementsByTagName('HEAD')[0]; - const oScript = document.createElement('script'); - oScript.type = 'text/javascript'; - oScript.src = sScriptSrc; - oHead.appendChild(oScript); - oScript.onload = () => { - resolve(true); - }; - }); diff --git a/packages/mermaid/src/diagram-api/frontmatter.spec.ts b/packages/mermaid/src/diagram-api/frontmatter.spec.ts new file mode 100644 index 000000000..4eb9789e2 --- /dev/null +++ b/packages/mermaid/src/diagram-api/frontmatter.spec.ts @@ -0,0 +1,78 @@ +import { vi } from 'vitest'; +import { extractFrontMatter } from './frontmatter'; + +const dbMock = () => ({ setDiagramTitle: vi.fn() }); + +describe('extractFrontmatter', () => { + it('returns text unchanged if no frontmatter', () => { + expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram'); + }); + + it('returns text unchanged if frontmatter lacks closing delimiter', () => { + const text = `---\ntitle: foo\ndiagram`; + expect(extractFrontMatter(text, dbMock())).toEqual(text); + }); + + it('handles empty frontmatter', () => { + const db = dbMock(); + const text = `---\n\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('handles frontmatter without mappings', () => { + const db = dbMock(); + const text = `---\n1\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('does not try to parse frontmatter at the end', () => { + const db = dbMock(); + const text = `diagram\n---\ntitle: foo\n---\n`; + expect(extractFrontMatter(text, db)).toEqual(text); + expect(db.setDiagramTitle).not.toHaveBeenCalled(); + }); + + it('handles frontmatter with multiple delimiters', () => { + const db = dbMock(); + const text = `---\ntitle: foo---bar\n---\ndiagram\n---\ntest`; + expect(extractFrontMatter(text, db)).toEqual('diagram\n---\ntest'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo---bar'); + }); + + it('handles frontmatter with multi-line string and multiple delimiters', () => { + const db = dbMock(); + const text = `---\ntitle: |\n multi-line string\n ---\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('multi-line string\n---\n'); + }); + + it('handles frontmatter with title', () => { + const db = dbMock(); + const text = `---\ntitle: foo\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo'); + }); + + it('handles booleans in frontmatter properly', () => { + const db = dbMock(); + const text = `---\ntitle: true\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('true'); + }); + + it('ignores unspecified frontmatter keys', () => { + const db = dbMock(); + const text = `---\ninvalid: true\ntitle: foo\ntest: bar\n---\ndiagram`; + expect(extractFrontMatter(text, db)).toEqual('diagram'); + expect(db.setDiagramTitle).toHaveBeenCalledWith('foo'); + }); + + it('throws exception for invalid YAML syntax', () => { + const text = `---\n!!!\n---\ndiagram`; + expect(() => extractFrontMatter(text, dbMock())).toThrow( + 'tag suffix cannot contain exclamation marks' + ); + }); +}); diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts new file mode 100644 index 000000000..d6811388c --- /dev/null +++ b/packages/mermaid/src/diagram-api/frontmatter.ts @@ -0,0 +1,40 @@ +import { DiagramDb } from './types'; +// The "* as yaml" part is necessary for tree-shaking +import * as yaml from 'js-yaml'; + +// Match Jekyll-style front matter blocks (https://jekyllrb.com/docs/front-matter/). +// Based on regex used by Jekyll: https://github.com/jekyll/jekyll/blob/6dd3cc21c40b98054851846425af06c64f9fb466/lib/jekyll/document.rb#L10 +// Note that JS doesn't support the "\A" anchor, which means we can't use +// multiline mode. +// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents +export const frontMatterRegex = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s; + +type FrontMatterMetadata = { + title?: string; +}; + +/** + * Extract and parse frontmatter from text, if present, and sets appropriate + * properties in the provided db. + * @param text - The text that may have a YAML frontmatter. + * @param db - Diagram database, could be of any diagram. + * @returns text with frontmatter stripped out + */ +export function extractFrontMatter(text: string, db: DiagramDb): string { + const matches = text.match(frontMatterRegex); + if (matches) { + const parsed: FrontMatterMetadata = yaml.load(matches[1], { + // To keep things simple, only allow strings, arrays, and plain objects. + // https://www.yaml.org/spec/1.2/spec.html#id2802346 + schema: yaml.FAILSAFE_SCHEMA, + }) as FrontMatterMetadata; + + if (parsed?.title) { + db.setDiagramTitle?.(parsed.title); + } + + return text.slice(matches[0].length); + } else { + return text; + } +} diff --git a/packages/mermaid/src/diagram-api/text-wrap b/packages/mermaid/src/diagram-api/text-wrap deleted file mode 100644 index 173baecec..000000000 --- a/packages/mermaid/src/diagram-api/text-wrap +++ /dev/null @@ -1,227 +0,0 @@ -export const lineBreakRegex = //gi; - -/** - * Caches results of functions based on input - * - * @param {Function} fn Function to run - * @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes - * @returns {Function} An optimized caching function - */ -const memoize = (fn, resolver) => { - let cache = {}; - return (...args) => { - let n = resolver ? resolver.apply(this, args) : args[0]; - if (n in cache) { - return cache[n]; - } else { - let result = fn(...args); - cache[n] = result; - return result; - } - }; -}; -/** - * This calculates the width of the given text, font size and family. - * - * @param {any} text - The text to calculate the width of - * @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size - * @returns {any} - The width for the given text - */ -export const calculateTextWidth = function (text, config) { - config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); - return calculateTextDimensions(text, config).width; -}; - -export const getTextObj = function () { - return { - x: 0, - y: 0, - fill: undefined, - anchor: 'start', - style: '#666', - width: 100, - height: 100, - textMargin: 0, - rx: 0, - ry: 0, - valign: undefined, - }; -}; - -/** - * Adds text to an element - * - * @param {SVGElement} elem Element to add text to - * @param {{ - * text: string; - * x: number; - * y: number; - * anchor: 'start' | 'middle' | 'end'; - * fontFamily: string; - * fontSize: string | number; - * fontWeight: string | number; - * fill: string; - * class: string | undefined; - * textMargin: number; - * }} textData - * @returns {SVGTextElement} Text element with given styling and content - */ -export const drawSimpleText = function (elem, textData) { - // Remove and ignore br:s - const nText = textData.text.replace(lineBreakRegex, ' '); - - const textElem = elem.append('text'); - textElem.attr('x', textData.x); - textElem.attr('y', textData.y); - textElem.style('text-anchor', textData.anchor); - textElem.style('font-family', textData.fontFamily); - textElem.style('font-size', textData.fontSize); - textElem.style('font-weight', textData.fontWeight); - textElem.attr('fill', textData.fill); - if (typeof textData.class !== 'undefined') { - textElem.attr('class', textData.class); - } - - const span = textElem.append('tspan'); - span.attr('x', textData.x + textData.textMargin * 2); - span.attr('fill', textData.fill); - span.text(nText); - - return textElem; -}; - -/** - * This calculates the dimensions of the given text, font size, font family, font weight, and margins. - * - * @param {any} text - The text to calculate the width of - * @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting - * the resulting size - * @returns - The width for the given text - */ -export const calculateTextDimensions = memoize( - function (text, config) { - config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); - const { fontSize, fontFamily, fontWeight } = config; - if (!text) { - return { width: 0, height: 0 }; - } - - // We can't really know if the user supplied font family will render on the user agent; - // thus, we'll take the max width between the user supplied font family, and a default - // of sans-serif. - const fontFamilies = ['sans-serif', fontFamily]; - const lines = text.split(common.lineBreakRegex); - let dims = []; - - const body = select('body'); - // We don't want to leak DOM elements - if a removal operation isn't available - // for any reason, do not continue. - if (!body.remove) { - return { width: 0, height: 0, lineHeight: 0 }; - } - - const g = body.append('svg'); - - for (let fontFamily of fontFamilies) { - let cheight = 0; - let dim = { width: 0, height: 0, lineHeight: 0 }; - for (let line of lines) { - const textObj = getTextObj(); - textObj.text = line; - const textElem = drawSimpleText(g, textObj) - .style('font-size', fontSize) - .style('font-weight', fontWeight) - .style('font-family', fontFamily); - - let bBox = (textElem._groups || textElem)[0][0].getBBox(); - dim.width = Math.round(Math.max(dim.width, bBox.width)); - cheight = Math.round(bBox.height); - dim.height += cheight; - dim.lineHeight = Math.round(Math.max(dim.lineHeight, cheight)); - } - dims.push(dim); - } - - g.remove(); - - let index = - isNaN(dims[1].height) || - isNaN(dims[1].width) || - isNaN(dims[1].lineHeight) || - (dims[0].height > dims[1].height && - dims[0].width > dims[1].width && - dims[0].lineHeight > dims[1].lineHeight) - ? 0 - : 1; - return dims[index]; - }, - (text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}` -); - -const breakString = memoize( - (word, maxWidth, hyphenCharacter = '-', config) => { - config = Object.assign( - { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0 }, - config - ); - const characters = word.split(''); - const lines = []; - let currentLine = ''; - characters.forEach((character, index) => { - const nextLine = `${currentLine}${character}`; - const lineWidth = calculateTextWidth(nextLine, config); - if (lineWidth >= maxWidth) { - const currentCharacter = index + 1; - const isLastLine = characters.length === currentCharacter; - const hyphenatedNextLine = `${nextLine}${hyphenCharacter}`; - lines.push(isLastLine ? nextLine : hyphenatedNextLine); - currentLine = ''; - } else { - currentLine = nextLine; - } - }); - return { hyphenatedStrings: lines, remainingWord: currentLine }; - }, - (word, maxWidth, hyphenCharacter = '-', config) => - `${word}-${maxWidth}-${hyphenCharacter}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}` -); - -export const wrapLabel = memoize( - (label, maxWidth, config) => { - if (!label) { - return label; - } - config = Object.assign( - { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', joinWith: '
' }, - config - ); - if (lineBreakRegex.test(label)) { - return label; - } - const words = label.split(' '); - const completedLines = []; - let nextLine = ''; - words.forEach((word, index) => { - const wordLength = calculateTextWidth(`${word} `, config); - const nextLineLength = calculateTextWidth(nextLine, config); - if (wordLength > maxWidth) { - const { hyphenatedStrings, remainingWord } = breakString(word, maxWidth, '-', config); - completedLines.push(nextLine, ...hyphenatedStrings); - nextLine = remainingWord; - } else if (nextLineLength + wordLength >= maxWidth) { - completedLines.push(nextLine); - nextLine = word; - } else { - nextLine = [nextLine, word].filter(Boolean).join(' '); - } - const currentWord = index + 1; - const isLastWord = currentWord === words.length; - if (isLastWord) { - completedLines.push(nextLine); - } - }); - return completedLines.filter((line) => line !== '').join(config.joinWith); - }, - (label, maxWidth, config) => - `${label}-${maxWidth}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}-${config.joinWith}` -); diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts new file mode 100644 index 000000000..23810d133 --- /dev/null +++ b/packages/mermaid/src/diagram-api/types.ts @@ -0,0 +1,46 @@ +import { MermaidConfig } from '../config.type'; + +export interface InjectUtils { + _log: any; + _setLogLevel: any; + _getConfig: any; + _sanitizeText: any; + _setupGraphViewbox: any; +} + +/** + * Generic Diagram DB that may apply to any diagram type. + */ +export interface DiagramDb { + clear?: () => void; + setDiagramTitle?: (title: string) => void; +} + +export interface DiagramDefinition { + db: DiagramDb; + renderer: any; + parser: any; + styles: any; + init?: (config: MermaidConfig) => void; + injectUtils?: ( + _log: InjectUtils['_log'], + _setLogLevel: InjectUtils['_setLogLevel'], + _getConfig: InjectUtils['_getConfig'], + _sanitizeText: InjectUtils['_sanitizeText'], + _setupGraphViewbox: InjectUtils['_setupGraphViewbox'] + ) => void; +} + +export interface DetectorRecord { + detector: DiagramDetector; + loader?: DiagramLoader; +} + +export interface ExternalDiagramDefinition { + id: string; + detector: DiagramDetector; + loader: DiagramLoader; +} + +export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean; +export type DiagramLoader = () => Promise<{ id: string; diagram: DiagramDefinition }>; diff --git a/packages/mermaid/src/diagrams/c4/c4Db.js b/packages/mermaid/src/diagrams/c4/c4Db.js index 79028a0c5..d337b15c0 100644 --- a/packages/mermaid/src/diagrams/c4/c4Db.js +++ b/packages/mermaid/src/diagrams/c4/c4Db.js @@ -49,8 +49,9 @@ export const addRel = function (type, from, to, label, techn, descr, sprite, tag to === null || label === undefined || label === null - ) + ) { return; + } let rel = {}; const old = rels.find((rel) => rel.from === from && rel.to === to); @@ -111,7 +112,9 @@ export const addRel = function (type, from, to, label, techn, descr, sprite, tag //type, alias, label, ?descr, ?sprite, ?tags, $link export const addPersonOrSystem = function (typeC4Shape, alias, label, descr, sprite, tags, link) { // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let personOrSystem = {}; const old = c4ShapeArray.find((personOrSystem) => personOrSystem.alias === alias); @@ -166,7 +169,9 @@ export const addPersonOrSystem = function (typeC4Shape, alias, label, descr, spr //type, alias, label, ?techn, ?descr ?sprite, ?tags, $link export const addContainer = function (typeC4Shape, alias, label, techn, descr, sprite, tags, link) { // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let container = {}; const old = c4ShapeArray.find((container) => container.alias === alias); @@ -232,7 +237,9 @@ export const addContainer = function (typeC4Shape, alias, label, techn, descr, s //type, alias, label, ?techn, ?descr ?sprite, ?tags, $link export const addComponent = function (typeC4Shape, alias, label, techn, descr, sprite, tags, link) { // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let component = {}; const old = c4ShapeArray.find((component) => component.alias === alias); @@ -300,7 +307,9 @@ export const addPersonOrSystemBoundary = function (alias, label, type, tags, lin // if (parentBoundary === null) return; // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let boundary = {}; const old = boundarys.find((boundary) => boundary.alias === alias); @@ -354,7 +363,9 @@ export const addContainerBoundary = function (alias, label, type, tags, link) { // if (parentBoundary === null) return; // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let boundary = {}; const old = boundarys.find((boundary) => boundary.alias === alias); @@ -417,7 +428,9 @@ export const addDeploymentNode = function ( // if (parentBoundary === null) return; // Don't allow label nulling - if (alias === null || label === null) return; + if (alias === null || label === null) { + return; + } let boundary = {}; const old = boundarys.find((boundary) => boundary.alias === alias); @@ -646,8 +659,12 @@ export const updateLayoutConfig = function (typeC4Shape, c4ShapeInRowParam, c4Bo c4BoundaryInRowValue = parseInt(c4BoundaryInRowParam); } - if (c4ShapeInRowValue >= 1) c4ShapeInRow = c4ShapeInRowValue; - if (c4BoundaryInRowValue >= 1) c4BoundaryInRow = c4BoundaryInRowValue; + if (c4ShapeInRowValue >= 1) { + c4ShapeInRow = c4ShapeInRowValue; + } + if (c4BoundaryInRowValue >= 1) { + c4BoundaryInRow = c4BoundaryInRowValue; + } }; export const getC4ShapeInRow = function () { @@ -665,11 +682,13 @@ export const getParentBoundaryParse = function () { }; export const getC4ShapeArray = function (parentBoundary) { - if (parentBoundary === undefined || parentBoundary === null) return c4ShapeArray; - else + if (parentBoundary === undefined || parentBoundary === null) { + return c4ShapeArray; + } else { return c4ShapeArray.filter((personOrSystem) => { return personOrSystem.parentBoundary === parentBoundary; }); + } }; export const getC4Shape = function (alias) { return c4ShapeArray.find((personOrSystem) => personOrSystem.alias === alias); @@ -679,8 +698,11 @@ export const getC4ShapeKeys = function (parentBoundary) { }; export const getBoundarys = function (parentBoundary) { - if (parentBoundary === undefined || parentBoundary === null) return boundarys; - else return boundarys.filter((boundary) => boundary.parentBoundary === parentBoundary); + if (parentBoundary === undefined || parentBoundary === null) { + return boundarys; + } else { + return boundarys.filter((boundary) => boundary.parentBoundary === parentBoundary); + } }; export const getRels = function () { diff --git a/packages/mermaid/src/diagrams/c4/c4Detector.ts b/packages/mermaid/src/diagrams/c4/c4Detector.ts index 2be62bff1..49ba95b8e 100644 --- a/packages/mermaid/src/diagrams/c4/c4Detector.ts +++ b/packages/mermaid/src/diagrams/c4/c4Detector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const c4Detector: DiagramDetector = (txt) => { return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null; diff --git a/packages/mermaid/src/diagrams/c4/c4Renderer.js b/packages/mermaid/src/diagrams/c4/c4Renderer.js index dceca2887..6490a8e19 100644 --- a/packages/mermaid/src/diagrams/c4/c4Renderer.js +++ b/packages/mermaid/src/diagrams/c4/c4Renderer.js @@ -48,7 +48,7 @@ class Bounds { } updateVal(obj, key, val, fun) { - if (typeof obj[key] === 'undefined') { + if (obj[key] === undefined) { obj[key] = val; } else { obj[key] = fun(val, obj[key]); @@ -177,12 +177,12 @@ function calcC4ShapeTextWH(textType, c4Shape, c4ShapeTextWrap, textConf, textLim let lineHeight = 0; c4Shape[textType].height = 0; c4Shape[textType].width = 0; - for (let i = 0; i < lines.length; i++) { + for (const line of lines) { c4Shape[textType].width = Math.max( - calculateTextWidth(lines[i], textConf), + calculateTextWidth(line, textConf), c4Shape[textType].width ); - lineHeight = calculateTextHeight(lines[i], textConf); + lineHeight = calculateTextHeight(line, textConf); c4Shape[textType].height = c4Shape[textType].height + lineHeight; } // c4Shapes[textType].height = c4Shapes[textType].textLines * textConf.fontSize; @@ -212,9 +212,9 @@ export const drawC4ShapeArray = function (currentBounds, diagram, c4ShapeArray, // Upper Y is relative point let Y = 0; // Draw the c4ShapeArray - for (let i = 0; i < c4ShapeKeys.length; i++) { + for (const c4ShapeKey of c4ShapeKeys) { Y = 0; - const c4Shape = c4ShapeArray[c4ShapeKeys[i]]; + const c4Shape = c4ShapeArray[c4ShapeKey]; // calc c4 shape type width and height @@ -414,7 +414,9 @@ export const drawRels = function (diagram, rels, getC4ShapeObj, diagObj) { let relTextWrap = rel.wrap && conf.wrap; let relConf = messageFont(conf); let diagramType = diagObj.db.getC4Type(); - if (diagramType === 'C4Dynamic') rel.label.text = i + ': ' + rel.label.text; + if (diagramType === 'C4Dynamic') { + rel.label.text = i + ': ' + rel.label.text; + } let textLimitWidth = calculateTextWidth(rel.label.text, relConf); calcC4ShapeTextWH('label', rel, relTextWrap, relConf, textLimitWidth); @@ -441,20 +443,25 @@ export const drawRels = function (diagram, rels, getC4ShapeObj, diagObj) { * @param diagram * @param parentBoundaryAlias * @param parentBounds - * @param currentBoundarys + * @param currentBoundaries * @param diagObj */ -function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentBoundarys, diagObj) { +function drawInsideBoundary( + diagram, + parentBoundaryAlias, + parentBounds, + currentBoundaries, + diagObj +) { let currentBounds = new Bounds(diagObj); - // Calculate the width limit of the boundar. label/type 的长度, + // Calculate the width limit of the boundary. label/type 的长度, currentBounds.data.widthLimit = - parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundarys.length); + parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundaries.length); // Math.min( // conf.width * conf.c4ShapeInRow + conf.c4ShapeMargin * conf.c4ShapeInRow * 2, - // parentBounds.data.widthLimit / Math.min(conf.c4BoundaryInRow, currentBoundarys.length) + // parentBounds.data.widthLimit / Math.min(conf.c4BoundaryInRow, currentBoundaries.length) // ); - for (let i = 0; i < currentBoundarys.length; i++) { - let currentBoundary = currentBoundarys[i]; + for (let [i, currentBoundary] of currentBoundaries.entries()) { let Y = 0; currentBoundary.image = { width: 0, height: 0, Y: 0 }; if (currentBoundary.sprite) { @@ -508,13 +515,13 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB } if (i == 0 || i % c4BoundaryInRow === 0) { - // Calculate the drawing start point of the currentBoundarys. + // Calculate the drawing start point of the currentBoundaries. let _x = parentBounds.data.startx + conf.diagramMarginX; let _y = parentBounds.data.stopy + conf.diagramMarginY + Y; currentBounds.setData(_x, _x, _y, _y); } else { - // Calculate the drawing start point of the currentBoundarys. + // Calculate the drawing start point of the currentBoundaries. let _x = currentBounds.data.stopx !== currentBounds.data.startx ? currentBounds.data.stopx + conf.diagramMarginX @@ -540,8 +547,6 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB if (nextCurrentBoundarys.length > 0) { // draw boundary inside currentBoundary - // bounds.init(); - // parentBoundaryWidthLimit = bounds.data.stopx - bounds.startx; drawInsideBoundary( diagram, parentBoundaryAlias, @@ -551,7 +556,9 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB ); } // draw boundary - if (currentBoundary.alias !== 'global') drawBoundary(diagram, currentBoundary, currentBounds); + if (currentBoundary.alias !== 'global') { + drawBoundary(diagram, currentBoundary, currentBounds); + } parentBounds.data.stopy = Math.max( currentBounds.data.stopy + conf.c4ShapeMargin, parentBounds.data.stopy @@ -576,7 +583,7 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB export const draw = function (_text, id, _version, diagObj) { conf = configApi.getConfig().c4; const securityLevel = configApi.getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -616,10 +623,10 @@ export const draw = function (_text, id, _version, diagObj) { globalBoundaryMaxY = conf.diagramMarginY; const title = diagObj.db.getTitle(); - let currentBoundarys = diagObj.db.getBoundarys(''); + let currentBoundaries = diagObj.db.getBoundarys(''); // switch (c4type) { // case 'C4Context': - drawInsideBoundary(diagram, '', screenBounds, currentBoundarys, diagObj); + drawInsideBoundary(diagram, '', screenBounds, currentBoundaries, diagObj); // break; // } diff --git a/packages/mermaid/src/diagrams/c4/svgDraw.js b/packages/mermaid/src/diagrams/c4/svgDraw.js index 5666d9f84..d3d66a80d 100644 --- a/packages/mermaid/src/diagrams/c4/svgDraw.js +++ b/packages/mermaid/src/diagrams/c4/svgDraw.js @@ -13,7 +13,9 @@ export const drawRect = function (elem, rectData) { rectElem.attr('ry', rectData.ry); if (rectData.attrs !== 'undefined' && rectData.attrs !== null) { - for (let attrKey in rectData.attrs) rectElem.attr(attrKey, rectData.attrs[attrKey]); + for (let attrKey in rectData.attrs) { + rectElem.attr(attrKey, rectData.attrs[attrKey]); + } } if (rectData.class !== 'undefined') { @@ -33,184 +35,6 @@ export const drawImage = function (elem, width, height, x, y, link) { imageElem.attr('xlink:href', sanitizedLink); }; -export const drawEmbeddedImage = function (elem, x, y, link) { - const imageElem = elem.append('use'); - imageElem.attr('x', x); - imageElem.attr('y', y); - var sanitizedLink = sanitizeUrl(link); - imageElem.attr('xlink:href', '#' + sanitizedLink); -}; - -export const drawText = function (elem, textData) { - let prevTextHeight = 0, - textHeight = 0; - const lines = textData.text.split(common.lineBreakRegex); - - let textElems = []; - let dy = 0; - let yfunc = () => textData.y; - if ( - typeof textData.valign !== 'undefined' && - typeof textData.textMargin !== 'undefined' && - textData.textMargin > 0 - ) { - switch (textData.valign) { - case 'top': - case 'start': - yfunc = () => Math.round(textData.y + textData.textMargin); - break; - case 'middle': - case 'center': - yfunc = () => - Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2); - break; - case 'bottom': - case 'end': - yfunc = () => - Math.round( - textData.y + - (prevTextHeight + textHeight + 2 * textData.textMargin) - - textData.textMargin - ); - break; - } - } - if ( - typeof textData.anchor !== 'undefined' && - typeof textData.textMargin !== 'undefined' && - typeof textData.width !== 'undefined' - ) { - switch (textData.anchor) { - case 'left': - case 'start': - textData.x = Math.round(textData.x + textData.textMargin); - textData.anchor = 'start'; - textData.dominantBaseline = 'text-after-edge'; - textData.alignmentBaseline = 'middle'; - break; - case 'middle': - case 'center': - textData.x = Math.round(textData.x + textData.width / 2); - textData.anchor = 'middle'; - textData.dominantBaseline = 'middle'; - textData.alignmentBaseline = 'middle'; - break; - case 'right': - case 'end': - textData.x = Math.round(textData.x + textData.width - textData.textMargin); - textData.anchor = 'end'; - textData.dominantBaseline = 'text-before-edge'; - textData.alignmentBaseline = 'middle'; - break; - } - } - for (let i = 0; i < lines.length; i++) { - let line = lines[i]; - if ( - typeof textData.textMargin !== 'undefined' && - textData.textMargin === 0 && - typeof textData.fontSize !== 'undefined' - ) { - dy = i * textData.fontSize; - } - - const textElem = elem.append('text'); - textElem.attr('x', textData.x); - textElem.attr('y', yfunc()); - if (typeof textData.anchor !== 'undefined') { - textElem - .attr('text-anchor', textData.anchor) - .attr('dominant-baseline', textData.dominantBaseline) - .attr('alignment-baseline', textData.alignmentBaseline); - } - if (typeof textData.fontFamily !== 'undefined') { - textElem.style('font-family', textData.fontFamily); - } - if (typeof textData.fontSize !== 'undefined') { - textElem.style('font-size', textData.fontSize); - } - if (typeof textData.fontWeight !== 'undefined') { - textElem.style('font-weight', textData.fontWeight); - } - if (typeof textData.fill !== 'undefined') { - textElem.attr('fill', textData.fill); - } - if (typeof textData.class !== 'undefined') { - textElem.attr('class', textData.class); - } - if (typeof textData.dy !== 'undefined') { - textElem.attr('dy', textData.dy); - } else if (dy !== 0) { - textElem.attr('dy', dy); - } - - if (textData.tspan) { - const span = textElem.append('tspan'); - span.attr('x', textData.x); - if (typeof textData.fill !== 'undefined') { - span.attr('fill', textData.fill); - } - span.text(line); - } else { - textElem.text(line); - } - if ( - typeof textData.valign !== 'undefined' && - typeof textData.textMargin !== 'undefined' && - textData.textMargin > 0 - ) { - textHeight += (textElem._groups || textElem)[0][0].getBBox().height; - prevTextHeight = textHeight; - } - - textElems.push(textElem); - } - - return textElems; -}; - -export const drawLabel = function (elem, txtObject) { - /** - * @param {any} x - * @param {any} y - * @param {any} width - * @param {any} height - * @param {any} cut - * @returns {any} - */ - function genPoints(x, y, width, height, cut) { - return ( - x + - ',' + - y + - ' ' + - (x + width) + - ',' + - y + - ' ' + - (x + width) + - ',' + - (y + height - cut) + - ' ' + - (x + width - cut * 1.2) + - ',' + - (y + height) + - ' ' + - x + - ',' + - (y + height) - ); - } - const polygon = elem.append('polygon'); - polygon.attr('points', genPoints(txtObject.x, txtObject.y, txtObject.width, txtObject.height, 7)); - polygon.attr('class', 'labelBox'); - - txtObject.y = txtObject.y + txtObject.height / 2; - - drawText(elem, txtObject); - return polygon; -}; - export const drawRels = (elem, rels, conf) => { const relsElem = elem.append('g'); let i = 0; @@ -231,9 +55,12 @@ export const drawRels = (elem, rels, conf) => { line.attr('stroke-width', '1'); line.attr('stroke', strokeColor); line.style('fill', 'none'); - if (rel.type !== 'rel_b') line.attr('marker-end', 'url(' + url + '#arrowhead)'); - if (rel.type === 'birel' || rel.type === 'rel_b') + if (rel.type !== 'rel_b') { + line.attr('marker-end', 'url(' + url + '#arrowhead)'); + } + if (rel.type === 'birel' || rel.type === 'rel_b') { line.attr('marker-start', 'url(' + url + '#arrowend)'); + } i = -1; } else { let line = relsElem.append('path'); @@ -256,9 +83,12 @@ export const drawRels = (elem, rels, conf) => { .replaceAll('stopx', rel.endPoint.x) .replaceAll('stopy', rel.endPoint.y) ); - if (rel.type !== 'rel_b') line.attr('marker-end', 'url(' + url + '#arrowhead)'); - if (rel.type === 'birel' || rel.type === 'rel_b') + if (rel.type !== 'rel_b') { + line.attr('marker-end', 'url(' + url + '#arrowhead)'); + } + if (rel.type === 'birel' || rel.type === 'rel_b') { line.attr('marker-start', 'url(' + url + '#arrowend)'); + } } let messageConf = conf.messageFont(); @@ -314,7 +144,9 @@ const drawBoundary = function (elem, boundary, conf) { let fontColor = boundary.fontColor ? boundary.fontColor : 'black'; let attrsValue = { 'stroke-width': 1.0, 'stroke-dasharray': '7.0,7.0' }; - if (boundary.nodeType) attrsValue = { 'stroke-width': 1.0 }; + if (boundary.nodeType) { + attrsValue = { 'stroke-width': 1.0 }; + } let rectData = { x: boundary.x, y: boundary.y, @@ -735,23 +567,6 @@ export const insertArrowCrossHead = function (elem) { // this is actual shape for arrowhead }; -export const getTextObj = function () { - return { - x: 0, - y: 0, - fill: undefined, - anchor: undefined, - style: '#666', - width: undefined, - height: undefined, - textMargin: 0, - rx: 0, - ry: 0, - tspan: true, - valign: undefined, - }; -}; - export const getNoteRect = function () { return { x: 0, @@ -886,13 +701,10 @@ const _drawTextCandidateFunc = (function () { export default { drawRect, - drawText, - drawLabel, drawBoundary, drawC4Shape, drawRels, drawImage, - drawEmbeddedImage, insertArrowHead, insertArrowEnd, insertArrowFilledHead, @@ -901,7 +713,6 @@ export default { insertDatabaseIcon, insertComputerIcon, insertClockIcon, - getTextObj, getNoteRect, - sanitizeUrl, + sanitizeUrl, // TODO why is this exported? }; diff --git a/packages/mermaid/src/diagrams/class/classDb.js b/packages/mermaid/src/diagrams/class/classDb.js index 223bfe067..2c6690e39 100644 --- a/packages/mermaid/src/diagrams/class/classDb.js +++ b/packages/mermaid/src/diagrams/class/classDb.js @@ -10,12 +10,15 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; const MERMAID_DOM_ID_PREFIX = 'classid-'; let relations = []; let classes = {}; +let notes = []; let classCounter = 0; let funs = []; @@ -49,7 +52,9 @@ const splitClassNameAndType = function (id) { export const addClass = function (id) { let classId = splitClassNameAndType(id); // Only add class if not exists - if (typeof classes[classId.className] !== 'undefined') return; + if (classes[classId.className] !== undefined) { + return; + } classes[classId.className] = { id: classId.className, @@ -72,9 +77,9 @@ export const addClass = function (id) { */ export const lookUpDomId = function (id) { const classKeys = Object.keys(classes); - for (let i = 0; i < classKeys.length; i++) { - if (classes[classKeys[i]].id === id) { - return classes[classKeys[i]].domId; + for (const classKey of classKeys) { + if (classes[classKey].id === id) { + return classes[classKey].domId; } } }; @@ -82,6 +87,7 @@ export const lookUpDomId = function (id) { export const clear = function () { relations = []; classes = {}; + notes = []; funs = []; funs.push(setupToolTips); commonClear(); @@ -98,6 +104,10 @@ export const getRelations = function () { return relations; }; +export const getNotes = function () { + return notes; +}; + export const addRelation = function (relation) { log.debug('Adding relation: ' + JSON.stringify(relation)); addClass(relation.id1); @@ -168,6 +178,15 @@ export const addMembers = function (className, members) { } }; +export const addNote = function (text, className) { + const note = { + id: `note${notes.length}`, + class: className, + text: text, + }; + notes.push(note); +}; + export const cleanupLabel = function (label) { if (label.substring(0, 1) === ':') { return common.sanitizeText(label.substr(1).trim(), configApi.getConfig()); @@ -185,8 +204,10 @@ export const cleanupLabel = function (label) { export const setCssClass = function (ids, className) { ids.split(',').forEach(function (_id) { let id = _id; - if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; - if (typeof classes[id] !== 'undefined') { + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== undefined) { classes[id].cssClasses.push(className); } }); @@ -201,7 +222,7 @@ export const setCssClass = function (ids, className) { const setTooltip = function (ids, tooltip) { const config = configApi.getConfig(); ids.split(',').forEach(function (id) { - if (typeof tooltip !== 'undefined') { + if (tooltip !== undefined) { classes[id].tooltip = common.sanitizeText(tooltip, config); } }); @@ -220,8 +241,10 @@ export const setLink = function (ids, linkStr, target) { const config = configApi.getConfig(); ids.split(',').forEach(function (_id) { let id = _id; - if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; - if (typeof classes[id] !== 'undefined') { + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== undefined) { classes[id].link = utils.formatUrl(linkStr, config); if (config.securityLevel === 'sandbox') { classes[id].linkTarget = '_top'; @@ -258,10 +281,10 @@ const setClickFunc = function (domId, functionName, functionArgs) { if (config.securityLevel !== 'loose') { return; } - if (typeof functionName === 'undefined') { + if (functionName === undefined) { return; } - if (typeof classes[id] !== 'undefined') { + if (classes[id] !== undefined) { let argList = []; if (typeof functionArgs === 'string') { /* Splits functionArgs by ',', ignoring all ',' in double quoted strings */ @@ -369,7 +392,9 @@ export default { clear, getClass, getClasses, + getNotes, addAnnotation, + addNote, getRelations, addRelation, getDirection, @@ -385,4 +410,6 @@ export default { getTooltip, setTooltip, lookUpDomId, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/class/classDetector-V2.ts b/packages/mermaid/src/diagrams/class/classDetector-V2.ts index a0e270100..7100f6c66 100644 --- a/packages/mermaid/src/diagrams/class/classDetector-V2.ts +++ b/packages/mermaid/src/diagrams/class/classDetector-V2.ts @@ -1,9 +1,13 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const classDetectorV2: DiagramDetector = (txt, config) => { - // If we have confgured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram - if (txt.match(/^\s*classDiagram/) !== null && config?.class?.defaultRenderer === 'dagre-wrapper') + // If we have configured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram + if ( + txt.match(/^\s*classDiagram/) !== null && + config?.class?.defaultRenderer === 'dagre-wrapper' + ) { return true; + } // We have not opted to use the new renderer so we should return true if we detect a class diagram return txt.match(/^\s*classDiagram-v2/) !== null; }; diff --git a/packages/mermaid/src/diagrams/class/classDetector.ts b/packages/mermaid/src/diagrams/class/classDetector.ts index 19d8bd2f5..c3833ed28 100644 --- a/packages/mermaid/src/diagrams/class/classDetector.ts +++ b/packages/mermaid/src/diagrams/class/classDetector.ts @@ -1,8 +1,10 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const classDetector: DiagramDetector = (txt, config) => { - // If we have confgured to use dagre-wrapper then we should never return true in this function - if (config?.class?.defaultRenderer === 'dagre-wrapper') return false; + // If we have configured to use dagre-wrapper then we should never return true in this function + if (config?.class?.defaultRenderer === 'dagre-wrapper') { + return false; + } // We have not opted to use the new renderer so we should return true if we detect a class diagram return txt.match(/^\s*classDiagram/) !== null; }; diff --git a/packages/mermaid/src/diagrams/class/classDiagram.spec.js b/packages/mermaid/src/diagrams/class/classDiagram.spec.js index 3f47701e6..04a8e9bf3 100644 --- a/packages/mermaid/src/diagrams/class/classDiagram.spec.js +++ b/packages/mermaid/src/diagrams/class/classDiagram.spec.js @@ -529,6 +529,16 @@ foo() parser.parse(str); }); + + it('should handle "note for"', function () { + const str = 'classDiagram\n' + 'Class11 <|.. Class12\n' + 'note for Class11 "test"\n'; + parser.parse(str); + }); + + it('should handle "note"', function () { + const str = 'classDiagram\n' + 'note "test"\n'; + parser.parse(str); + }); }); describe('when fetching data from a classDiagram graph it', function () { diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.js b/packages/mermaid/src/diagrams/class/classRenderer-v2.js index 20722e6d0..c4e7e0291 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer-v2.js +++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.js @@ -1,16 +1,15 @@ import { select } from 'd3'; -import graphlib from 'graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { log } from '../../logger'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; +import utils from '../../utils'; import { curveLinear } from 'd3'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; import { setupGraphViewbox } from '../../setupGraphViewbox'; import common from '../common/common'; import addSVGAccessibilityFields from '../../accessibility'; -let idCache = {}; - const sanitizeText = (txt) => common.sanitizeText(txt, getConfig()); let conf = { @@ -64,6 +63,7 @@ export const addClasses = function (classes, g, _id, diagObj) { // if (evaluate(getConfig().flowchart.htmlLabels)) { // const node = { // label: vertexText.replace( + // eslint-disable-next-line @cspell/spellchecker // /fa[lrsb]?:fa-[\w-]+/g, // s => `` // ) @@ -133,6 +133,99 @@ export const addClasses = function (classes, g, _id, diagObj) { }); }; +/** + * Function that adds the additional vertices (notes) found during parsing to the graph to be rendered. + * + * @param {{text: string; class: string; placement: number}[]} notes + * Object containing the additional vertices (notes). + * @param {SVGGElement} g The graph that is to be drawn. + * @param {number} startEdgeId starting index for note edge + * @param classes + */ +export const addNotes = function (notes, g, startEdgeId, classes) { + log.info(notes); + + // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition + notes.forEach(function (note, i) { + const vertex = note; + + /** + * Variable for storing the classes for the vertex + * + * @type {string} + */ + let cssNoteStr = ''; + + const styles = { labelStyle: '', style: '' }; + + // Use vertex id as text in the box if no text is provided by the graph definition + let vertexText = vertex.text; + + let radious = 0; + let _shape = 'note'; + // Add the node + g.setNode(vertex.id, { + labelStyle: styles.labelStyle, + shape: _shape, + labelText: sanitizeText(vertexText), + noteData: vertex, + rx: radious, + ry: radious, + class: cssNoteStr, + style: styles.style, + id: vertex.id, + domId: vertex.id, + tooltip: '', + type: 'note', + padding: getConfig().flowchart.padding, + }); + + log.info('setNode', { + labelStyle: styles.labelStyle, + shape: _shape, + labelText: vertexText, + rx: radious, + ry: radious, + style: styles.style, + id: vertex.id, + type: 'note', + padding: getConfig().flowchart.padding, + }); + + if (!vertex.class || !(vertex.class in classes)) { + return; + } + const edgeId = startEdgeId + i; + const edgeData = {}; + //Set relationship style and line type + edgeData.classes = 'relation'; + edgeData.pattern = 'dotted'; + + edgeData.id = `edgeNote${edgeId}`; + // Set link type for rendering + edgeData.arrowhead = 'none'; + + log.info(`Note edge: ${JSON.stringify(edgeData)}, ${JSON.stringify(vertex)}`); + //Set edge extra labels + edgeData.startLabelRight = ''; + edgeData.endLabelLeft = ''; + + //Set relation arrow types + edgeData.arrowTypeStart = 'none'; + edgeData.arrowTypeEnd = 'none'; + let style = 'fill:none'; + let labelStyle = ''; + + edgeData.style = style; + edgeData.labelStyle = labelStyle; + + edgeData.curve = interpolateToCurve(conf.curve, curveLinear); + + // Add the edge to the graph + g.setEdge(vertex.id, vertex.class, edgeData, edgeId); + }); +}; + /** * Add edges to graph based on parsed graph definition * @@ -180,16 +273,16 @@ export const addRelations = function (relations, g) { let style = ''; let labelStyle = ''; - if (typeof edge.style !== 'undefined') { + if (edge.style !== undefined) { const styles = getStylesFromArray(edge.style); style = styles.style; labelStyle = styles.labelStyle; } else { style = 'fill:none'; - if (typeof defaultStyle !== 'undefined') { + if (defaultStyle !== undefined) { style = defaultStyle; } - if (typeof defaultLabelStyle !== 'undefined') { + if (defaultLabelStyle !== undefined) { labelStyle = defaultLabelStyle; } } @@ -197,17 +290,17 @@ export const addRelations = function (relations, g) { edgeData.style = style; edgeData.labelStyle = labelStyle; - if (typeof edge.interpolate !== 'undefined') { + if (edge.interpolate !== undefined) { edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear); - } else if (typeof relations.defaultInterpolate !== 'undefined') { + } else if (relations.defaultInterpolate !== undefined) { edgeData.curve = interpolateToCurve(relations.defaultInterpolate, curveLinear); } else { edgeData.curve = interpolateToCurve(conf.curve, curveLinear); } edge.text = edge.title; - if (typeof edge.text === 'undefined') { - if (typeof edge.style !== 'undefined') { + if (edge.text === undefined) { + if (edge.style !== undefined) { edgeData.arrowheadStyle = 'fill: #333'; } } else { @@ -221,7 +314,7 @@ export const addRelations = function (relations, g) { edgeData.labelType = 'text'; edgeData.label = edge.text.replace(common.lineBreakRegex, '\n'); - if (typeof edge.style === 'undefined') { + if (edge.style === undefined) { edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none'; } @@ -304,10 +397,12 @@ export const draw = function (text, id, _version, diagObj) { // Fetch the vertices/nodes and edges/links from the parsed graph definition const classes = diagObj.db.getClasses(); const relations = diagObj.db.getRelations(); + const notes = diagObj.db.getNotes(); log.info(relations); addClasses(classes, g, id, diagObj); addRelations(relations, g); + addNotes(notes, g, relations.length + 1, classes); // Add custom shapes // flowChartShapes.addToRenderV2(addShape); @@ -333,15 +428,15 @@ export const draw = function (text, id, _version, diagObj) { id ); + utils.insertTitle(svg, 'classTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth); // Add label rects for non html labels if (!conf.htmlLabels) { const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); - for (let k = 0; k < labels.length; k++) { - const label = labels[k]; - + for (const label of labels) { // Get dimensions of label const dim = label.getBBox(); diff --git a/packages/mermaid/src/diagrams/class/classRenderer.js b/packages/mermaid/src/diagrams/class/classRenderer.js index c1236afea..c500a73a7 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer.js +++ b/packages/mermaid/src/diagrams/class/classRenderer.js @@ -1,6 +1,6 @@ import { select } from 'd3'; -import dagre from 'dagre'; -import graphlib from 'graphlib'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { log } from '../../logger'; import svgDraw from './svgDraw'; import { configureSvgSize } from '../../setupGraphViewbox'; @@ -148,7 +148,7 @@ export const draw = function (text, id, _version, diagObj) { log.info('Rendering diagram ' + text); const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -180,8 +180,8 @@ export const draw = function (text, id, _version, diagObj) { const classes = diagObj.db.getClasses(); const keys = Object.keys(classes); - for (let i = 0; i < keys.length; i++) { - const classDef = classes[keys[i]]; + for (const key of keys) { + const classDef = classes[key]; const node = svgDraw.drawClass(diagram, classDef, conf, diagObj); idCache[node.id] = node; @@ -208,12 +208,42 @@ export const draw = function (text, id, _version, diagObj) { ); }); - dagre.layout(g); + const notes = diagObj.db.getNotes(); + notes.forEach(function (note) { + log.debug(`Adding note: ${JSON.stringify(note)}`); + const node = svgDraw.drawNote(diagram, note, conf, diagObj); + idCache[node.id] = node; + + // Add nodes to the graph. The first argument is the node id. The second is + // metadata about the node. In this case we're going to add labels to each of + // our nodes. + g.setNode(node.id, node); + if (note.class && note.class in classes) { + g.setEdge( + note.id, + getGraphId(note.class), + { + relation: { + id1: note.id, + id2: note.class, + relation: { + type1: 'none', + type2: 'none', + lineType: 10, + }, + }, + }, + 'DEFAULT' + ); + } + }); + + dagreLayout(g); g.nodes().forEach(function (v) { - if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') { + if (v !== undefined && g.node(v) !== undefined) { log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); root - .select('#' + diagObj.db.lookUpDomId(v)) + .select('#' + (diagObj.db.lookUpDomId(v) || v)) .attr( 'transform', 'translate(' + @@ -226,7 +256,7 @@ export const draw = function (text, id, _version, diagObj) { }); g.edges().forEach(function (e) { - if (typeof e !== 'undefined' && typeof g.edge(e) !== 'undefined') { + if (e !== undefined && g.edge(e) !== undefined) { log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))); svgDraw.drawEdge(diagram, g.edge(e), g.edge(e).relation, conf, diagObj); } diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison index ba0e69fba..157e3d7d8 100644 --- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison +++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison @@ -56,6 +56,8 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili "callback" return 'CALLBACK'; "link" return 'LINK'; "click" return 'CLICK'; +"note for" return 'NOTE_FOR'; +"note" return 'NOTE'; "<<" return 'ANNOTATION_START'; ">>" return 'ANNOTATION_END'; [~] this.begin("generic"); @@ -263,6 +265,7 @@ statement | annotationStatement | clickStatement | cssClassStatement + | noteStatement | directive | direction | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } @@ -300,6 +303,11 @@ relationStatement | className STR relation STR className { $$ = {id1:$1, id2:$5, relation:$3, relationTitle1:$2, relationTitle2:$4} } ; +noteStatement + : NOTE_FOR className noteText { yy.addNote($3, $2); } + | NOTE noteText { yy.addNote($2); } + ; + relation : relationType lineType relationType { $$={type1:$1,type2:$3,lineType:$2}; } | lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; } @@ -351,4 +359,6 @@ alphaNumToken : UNICODE_TEXT | NUM | ALPHA; classLiteralName : BQUOTE_STR; +noteText : STR; + %% diff --git a/packages/mermaid/src/diagrams/class/styles.js b/packages/mermaid/src/diagrams/class/styles.js index 9e7665c58..981cd7b73 100644 --- a/packages/mermaid/src/diagrams/class/styles.js +++ b/packages/mermaid/src/diagrams/class/styles.js @@ -80,6 +80,10 @@ g.classGroup line { stroke-dasharray: 3; } +.dotted-line{ + stroke-dasharray: 1 2; +} + #compositionStart, .composition { fill: ${options.lineColor} !important; stroke: ${options.lineColor} !important; @@ -105,13 +109,13 @@ g.classGroup line { } #extensionStart, .extension { - fill: ${options.lineColor} !important; + fill: ${options.mainBkg} !important; stroke: ${options.lineColor} !important; stroke-width: 1; } #extensionEnd, .extension { - fill: ${options.lineColor} !important; + fill: ${options.mainBkg} !important; stroke: ${options.lineColor} !important; stroke-width: 1; } @@ -144,6 +148,11 @@ g.classGroup line { font-size: 11px; } +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/class/svgDraw.js b/packages/mermaid/src/diagrams/class/svgDraw.js index 3d44e94b4..cc6909280 100644 --- a/packages/mermaid/src/diagrams/class/svgDraw.js +++ b/packages/mermaid/src/diagrams/class/svgDraw.js @@ -9,13 +9,13 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { switch (type) { case diagObj.db.relationType.AGGREGATION: return 'aggregation'; - case diagObj.db.EXTENSION: + case diagObj.db.relationType.EXTENSION: return 'extension'; - case diagObj.db.COMPOSITION: + case diagObj.db.relationType.COMPOSITION: return 'composition'; - case diagObj.db.DEPENDENCY: + case diagObj.db.relationType.DEPENDENCY: return 'dependency'; - case diagObj.db.LOLLIPOP: + case diagObj.db.relationType.LOLLIPOP: return 'lollipop'; } }; @@ -55,6 +55,9 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { if (relation.relation.lineType == 1) { svgPath.attr('class', 'relation dashed-line'); } + if (relation.relation.lineType == 10) { + svgPath.attr('class', 'relation dotted-line'); + } if (relation.relation.type1 !== 'none') { svgPath.attr( 'marker-start', @@ -99,7 +102,7 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { p2_card_y = cardinality_2_point.y; } - if (typeof relation.title !== 'undefined') { + if (relation.title !== undefined) { const g = elem.append('g').attr('class', 'classLabel'); const label = g .append('text') @@ -122,7 +125,7 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { } log.info('Rendering relation ' + JSON.stringify(relation)); - if (typeof relation.relationTitle1 !== 'undefined' && relation.relationTitle1 !== 'none') { + if (relation.relationTitle1 !== undefined && relation.relationTitle1 !== 'none') { const g = elem.append('g').attr('class', 'cardinality'); g.append('text') .attr('class', 'type1') @@ -132,7 +135,7 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { .attr('font-size', '6') .text(relation.relationTitle1); } - if (typeof relation.relationTitle2 !== 'undefined' && relation.relationTitle2 !== 'none') { + if (relation.relationTitle2 !== undefined && relation.relationTitle2 !== 'none') { const g = elem.append('g').attr('class', 'cardinality'); g.append('text') .attr('class', 'type2') @@ -190,7 +193,9 @@ export const drawClass = function (elem, classDef, conf, diagObj) { let isFirst = true; classDef.annotations.forEach(function (member) { const titleText2 = title.append('tspan').text('«' + member + '»'); - if (!isFirst) titleText2.attr('dy', conf.textHeight); + if (!isFirst) { + titleText2.attr('dy', conf.textHeight); + } isFirst = false; }); @@ -203,7 +208,9 @@ export const drawClass = function (elem, classDef, conf, diagObj) { const classTitle = title.append('tspan').text(classTitleString).attr('class', 'title'); // If class has annotations the title needs to have an offset of the text height - if (!isFirst) classTitle.attr('dy', conf.textHeight); + if (!isFirst) { + classTitle.attr('dy', conf.textHeight); + } const titleHeight = title.node().getBBox().height; @@ -284,9 +291,72 @@ export const drawClass = function (elem, classDef, conf, diagObj) { return classInfo; }; +/** + * Renders a note diagram + * + * @param {SVGSVGElement} elem The element to draw it into + * @param {{id: string; text: string; class: string;}} note + * @param conf + * @param diagObj + * @todo Add more information in the JSDOC here + */ +export const drawNote = function (elem, note, conf, diagObj) { + log.debug('Rendering note ', note, conf); + + const id = note.id; + const noteInfo = { + id: id, + text: note.text, + width: 0, + height: 0, + }; + + // add class group + const g = elem.append('g').attr('id', id).attr('class', 'classGroup'); + + // add text + let text = g + .append('text') + .attr('y', conf.textHeight + conf.padding) + .attr('x', 0); + + const lines = JSON.parse(`"${note.text}"`).split('\n'); + + lines.forEach(function (line) { + log.debug(`Adding line: ${line}`); + text.append('tspan').text(line).attr('class', 'title').attr('dy', conf.textHeight); + }); + + const noteBox = g.node().getBBox(); + + const rect = g + .insert('rect', ':first-child') + .attr('x', 0) + .attr('y', 0) + .attr('width', noteBox.width + 2 * conf.padding) + .attr( + 'height', + noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin + ); + + const rectWidth = rect.node().getBBox().width; + + // Center title + // We subtract the width of each text element from the class box width and divide it by 2 + text.node().childNodes.forEach(function (x) { + x.setAttribute('x', (rectWidth - x.getBBox().width) / 2); + }); + + noteInfo.width = rectWidth; + noteInfo.height = + noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin; + + return noteInfo; +}; + export const parseMember = function (text) { - const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+) *(\*|\$)?$/; - const methodRegEx = /^([+|\-|~|#])?(\w+) *\( *(.*)\) *(\*|\$)? *(\w*[~|[\]]*\s*\w*~?)$/; + const fieldRegEx = /^([#+~-])?(\w+)(~\w+~|\[])?\s+(\w+) *([$*])?$/; + const methodRegEx = /^([#+|~-])?(\w+) *\( *(.*)\) *([$*])? *(\w*[[\]|~]*\s*\w*~?)$/; let fieldMatch = text.match(fieldRegEx); let methodMatch = text.match(methodRegEx); @@ -362,7 +432,7 @@ const buildLegacyDisplay = function (text) { if (firstChar.match(/\w/)) { methodName = text.substring(0, methodStart).trim(); } else { - if (firstChar.match(/\+|-|~|#/)) { + if (firstChar.match(/[#+~-]/)) { visibility = firstChar; } @@ -370,21 +440,21 @@ const buildLegacyDisplay = function (text) { } const parameters = text.substring(methodStart + 1, methodEnd); - const classifier = text.substring(methodEnd + 1, methodEnd + 2); - cssStyle = parseClassifier(classifier); + const classifier = text.substring(methodEnd + 1, 1); + cssStyle = parseClassifier(text.substring(methodEnd + 1, methodEnd + 2)); displayText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')'; - if (methodEnd <= text.length) { + if (methodEnd < text.length) { returnType = text.substring(methodEnd + 2).trim(); if (returnType !== '') { returnType = ' : ' + parseGenericTypes(returnType); displayText += returnType; } - } else { - // finally - if all else fails, just send the text back as written (other than parsing for generic types) - displayText = parseGenericTypes(text); } + } else { + // finally - if all else fails, just send the text back as written (other than parsing for generic types) + displayText = parseGenericTypes(text); } return { @@ -392,7 +462,6 @@ const buildLegacyDisplay = function (text) { cssStyle, }; }; - /** * Adds a for a member in a diagram * @@ -435,5 +504,6 @@ const parseClassifier = function (classifier) { export default { drawClass, drawEdge, + drawNote, parseMember, }; diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 9f6ae2cdb..194a9a4c0 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -4,11 +4,13 @@ import { MermaidConfig } from '../../config.type'; /** * Gets the rows of lines in a string * - * @param {string | undefined} s The string to check the lines for - * @returns {string[]} The rows in that string + * @param s - The string to check the lines for + * @returns The rows in that string */ export const getRows = (s?: string): string[] => { - if (!s) return ['']; + if (!s) { + return ['']; + } const str = breakToPlaceholder(s).replace(/\\n/g, '#br#'); return str.split('#br#'); }; @@ -16,8 +18,8 @@ export const getRows = (s?: string): string[] => { /** * Removes script tags from a text * - * @param {string} txt The text to sanitize - * @returns {string} The safer text + * @param txt - The text to sanitize + * @returns The safer text */ export const removeScript = (txt: string): string => { return DOMPurify.sanitize(txt); @@ -39,7 +41,9 @@ const sanitizeMore = (text: string, config: MermaidConfig) => { }; export const sanitizeText = (text: string, config: MermaidConfig): string => { - if (!text) return text; + if (!text) { + return text; + } if (config.dompurifyConfig) { text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString(); } else { @@ -52,7 +56,9 @@ export const sanitizeTextOrArray = ( a: string | string[] | string[][], config: MermaidConfig ): string | string[] => { - if (typeof a === 'string') return sanitizeText(a, config); + if (typeof a === 'string') { + return sanitizeText(a, config); + } // TODO: Refactor to avoid flat. return a.flat().map((x: string) => sanitizeText(x, config)); }; @@ -60,10 +66,10 @@ export const sanitizeTextOrArray = ( export const lineBreakRegex = //gi; /** - * Whether or not a text has any linebreaks + * Whether or not a text has any line breaks * - * @param {string} text The text to test - * @returns {boolean} Whether or not the text has breaks + * @param text - The text to test + * @returns Whether or not the text has breaks */ export const hasBreaks = (text: string): boolean => { return lineBreakRegex.test(text); @@ -72,18 +78,18 @@ export const hasBreaks = (text: string): boolean => { /** * Splits on
tags * - * @param {string} text Text to split - * @returns {string[]} List of lines as strings + * @param text - Text to split + * @returns List of lines as strings */ export const splitBreaks = (text: string): string[] => { return text.split(lineBreakRegex); }; /** - * Converts placeholders to linebreaks in HTML + * Converts placeholders to line breaks in HTML * - * @param {string} s HTML with placeholders - * @returns {string} HTML with breaks instead of placeholders + * @param s - HTML with placeholders + * @returns HTML with breaks instead of placeholders */ const placeholderToBreak = (s: string): string => { return s.replace(/#br#/g, '
'); @@ -92,8 +98,8 @@ const placeholderToBreak = (s: string): string => { /** * Opposite of `placeholderToBreak`, converts breaks to placeholders * - * @param {string} s HTML string - * @returns {string} String with placeholders + * @param s - HTML string + * @returns String with placeholders */ const breakToPlaceholder = (s: string): string => { return s.replace(lineBreakRegex, '#br#'); @@ -102,8 +108,8 @@ const breakToPlaceholder = (s: string): string => { /** * Gets the current URL * - * @param {boolean} useAbsolute Whether to return the absolute URL or not - * @returns {string} The current URL + * @param useAbsolute - Whether to return the absolute URL or not + * @returns The current URL */ const getUrl = (useAbsolute: boolean): string => { let url = ''; @@ -124,8 +130,8 @@ const getUrl = (useAbsolute: boolean): string => { /** * Converts a string/boolean into a boolean * - * @param {string | boolean} val String or boolean to convert - * @returns {boolean} The result from the input + * @param val - String or boolean to convert + * @returns The result from the input */ export const evaluate = (val?: string | boolean): boolean => val === false || ['false', 'null', '0'].includes(String(val).trim().toLowerCase()) ? false : true; @@ -133,17 +139,20 @@ export const evaluate = (val?: string | boolean): boolean => /** * Makes generics in typescript syntax * - * @example
- * // returns "Array>" - * parseGenericTypes('Array~Array~string~~'); + * @example + * Array of array of strings in typescript syntax * - * @param {string} text The text to convert - * @returns {string} The converted string + * ```js + * // returns "Array>" + * parseGenericTypes('Array~Array~string~~'); + * ``` + * @param text - The text to convert + * @returns The converted string */ export const parseGenericTypes = function (text: string): string { let cleanedText = text; - if (text.indexOf('~') !== -1) { + if (text.includes('~')) { cleanedText = cleanedText.replace(/~([^~].*)/, '<$1'); cleanedText = cleanedText.replace(/~([^~]*)$/, '>$1'); diff --git a/packages/mermaid/src/diagrams/er/erDb.js b/packages/mermaid/src/diagrams/er/erDb.js index ad3454f84..026e08420 100644 --- a/packages/mermaid/src/diagrams/er/erDb.js +++ b/packages/mermaid/src/diagrams/er/erDb.js @@ -8,6 +8,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; let entities = {}; @@ -30,7 +32,7 @@ export const parseDirective = function (statement, context, type) { }; const addEntity = function (name) { - if (typeof entities[name] === 'undefined') { + if (entities[name] === undefined) { entities[name] = { attributes: [] }; log.info('Added new entity :', name); } @@ -94,4 +96,6 @@ export default { getAccTitle, setAccDescription, getAccDescription, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/er/erDetector.ts b/packages/mermaid/src/diagrams/er/erDetector.ts index a17eafb81..5a87a949e 100644 --- a/packages/mermaid/src/diagrams/er/erDetector.ts +++ b/packages/mermaid/src/diagrams/er/erDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const erDetector: DiagramDetector = (txt) => { return txt.match(/^\s*erDiagram/) !== null; diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index a6277f27d..101beebb9 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -1,8 +1,9 @@ -import graphlib from 'graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { line, curveBasis, select } from 'd3'; -import dagre from 'dagre'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import { getConfig } from '../../config'; import { log } from '../../logger'; +import utils from '../../utils'; import erMarkers from './erMarkers'; import { configureSvgSize } from '../../setupGraphViewbox'; import addSVGAccessibilityFields from '../../accessibility'; @@ -10,7 +11,7 @@ import { parseGenericTypes } from '../common/common'; import { v4 as uuid4 } from 'uuid'; /** Regex used to remove chars from the entity name so the result can be used in an id */ -const BAD_ID_CHARS_REGEXP = /[^A-Za-z0-9]([\W])*/g; +const BAD_ID_CHARS_REGEXP = /[^\dA-Za-z](\W)*/g; // Configuration let conf = {}; @@ -27,8 +28,8 @@ let entityNameIds = new Map(); */ export const setConf = function (cnf) { const keys = Object.keys(cnf); - for (let i = 0; i < keys.length; i++) { - conf[keys[i]] = cnf[keys[i]]; + for (const key of keys) { + conf[key] = cnf[key]; } }; @@ -77,31 +78,27 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { // Add a text node for the attribute type const typeNode = groupNode .append('text') - .attr('class', 'er entityLabel') + .classed('er entityLabel', true) .attr('id', `${attrPrefix}-type`) .attr('x', 0) .attr('y', 0) - .attr('dominant-baseline', 'middle') - .attr('text-anchor', 'left') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + attrFontSize + 'px' - ) + .style('dominant-baseline', 'middle') + .style('text-anchor', 'left') + .style('font-family', getConfig().fontFamily) + .style('font-size', attrFontSize + 'px') .text(attributeType); // Add a text node for the attribute name const nameNode = groupNode .append('text') - .attr('class', 'er entityLabel') + .classed('er entityLabel', true) .attr('id', `${attrPrefix}-name`) .attr('x', 0) .attr('y', 0) - .attr('dominant-baseline', 'middle') - .attr('text-anchor', 'left') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + attrFontSize + 'px' - ) + .style('dominant-baseline', 'middle') + .style('text-anchor', 'left') + .style('font-family', getConfig().fontFamily) + .style('font-size', attrFontSize + 'px') .text(item.attributeName); const attributeNode = {}; @@ -118,16 +115,14 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { if (hasKeyType) { const keyTypeNode = groupNode .append('text') - .attr('class', 'er entityLabel') + .classed('er entityLabel', true) .attr('id', `${attrPrefix}-key`) .attr('x', 0) .attr('y', 0) - .attr('dominant-baseline', 'middle') - .attr('text-anchor', 'left') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + attrFontSize + 'px' - ) + .style('dominant-baseline', 'middle') + .style('text-anchor', 'left') + .style('font-family', getConfig().fontFamily) + .style('font-size', attrFontSize + 'px') .text(item.attributeKeyType || ''); attributeNode.kn = keyTypeNode; @@ -139,16 +134,14 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { if (hasComment) { const commentNode = groupNode .append('text') - .attr('class', 'er entityLabel') + .classed('er entityLabel', true) .attr('id', `${attrPrefix}-comment`) .attr('x', 0) .attr('y', 0) - .attr('dominant-baseline', 'middle') - .attr('text-anchor', 'left') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + attrFontSize + 'px' - ) + .style('dominant-baseline', 'middle') + .style('text-anchor', 'left') + .style('font-family', getConfig().fontFamily) + .style('font-size', attrFontSize + 'px') .text(item.attributeComment || ''); attributeNode.cn = commentNode; @@ -217,10 +210,7 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { // Insert a rectangle for the type const typeRect = groupNode .insert('rect', '#' + attributeNode.tn.node().id) - .attr('class', `er ${attribStyle}`) - .attr('fill', conf.fill) - .attr('fill-opacity', '100%') - .attr('stroke', conf.stroke) + .classed(`er ${attribStyle}`, true) .attr('x', 0) .attr('y', heightOffset) .attr('width', maxTypeWidth + widthPadding * 2 + spareColumnWidth) @@ -237,10 +227,7 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { // Insert a rectangle for the name const nameRect = groupNode .insert('rect', '#' + attributeNode.nn.node().id) - .attr('class', `er ${attribStyle}`) - .attr('fill', conf.fill) - .attr('fill-opacity', '100%') - .attr('stroke', conf.stroke) + .classed(`er ${attribStyle}`, true) .attr('x', nameXOffset) .attr('y', heightOffset) .attr('width', maxNameWidth + widthPadding * 2 + spareColumnWidth) @@ -259,10 +246,7 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { // Insert a rectangle for the key type const keyTypeRect = groupNode .insert('rect', '#' + attributeNode.kn.node().id) - .attr('class', `er ${attribStyle}`) - .attr('fill', conf.fill) - .attr('fill-opacity', '100%') - .attr('stroke', conf.stroke) + .classed(`er ${attribStyle}`, true) .attr('x', keyTypeAndCommentXOffset) .attr('y', heightOffset) .attr('width', maxKeyWidth + widthPadding * 2 + spareColumnWidth) @@ -282,10 +266,7 @@ const drawAttributes = (groupNode, entityTextNode, attributes) => { // Insert a rectangle for the comment groupNode .insert('rect', '#' + attributeNode.cn.node().id) - .attr('class', `er ${attribStyle}`) - .attr('fill', conf.fill) - .attr('fill-opacity', '100%') - .attr('stroke', conf.stroke) + .classed(`er ${attribStyle}`, 'true') .attr('x', keyTypeAndCommentXOffset) .attr('y', heightOffset) .attr('width', maxCommentWidth + widthPadding * 2 + spareColumnWidth) @@ -335,16 +316,14 @@ const drawEntities = function (svgNode, entities, graph) { const textId = 'text-' + entityId; const textNode = groupNode .append('text') - .attr('class', 'er entityLabel') + .classed('er entityLabel', true) .attr('id', textId) .attr('x', 0) .attr('y', 0) - .attr('dominant-baseline', 'middle') - .attr('text-anchor', 'middle') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px' - ) + .style('dominant-baseline', 'middle') + .style('text-anchor', 'middle') + .style('font-family', getConfig().fontFamily) + .style('font-size', conf.fontSize + 'px') .text(entityName); const { width: entityWidth, height: entityHeight } = drawAttributes( @@ -356,10 +335,7 @@ const drawEntities = function (svgNode, entities, graph) { // Draw the rectangle - insert it before the text so that the text is not obscured const rectNode = groupNode .insert('rect', '#' + textId) - .attr('class', 'er entityBox') - .attr('fill', conf.fill) - .attr('fill-opacity', '100%') - .attr('stroke', conf.stroke) + .classed('er entityBox', true) .attr('x', 0) .attr('y', 0) .attr('width', entityWidth) @@ -380,7 +356,7 @@ const drawEntities = function (svgNode, entities, graph) { const adjustEntities = function (svgNode, graph) { graph.nodes().forEach(function (v) { - if (typeof v !== 'undefined' && typeof graph.node(v) !== 'undefined') { + if (v !== undefined && graph.node(v) !== undefined) { svgNode .select('#' + v) .attr( @@ -411,7 +387,7 @@ const getEdgeName = function (rel) { * Add each relationship to the graph * * @param relationships The relationships to be added - * @param {Graph} g The graph + * @param g The graph * @returns {Array} The array of relationships */ const addRelationships = function (relationships, g) { @@ -460,10 +436,10 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { // Insert the line at the right place const svgPath = svg .insert('path', '#' + insert) - .attr('class', 'er relationshipLine') + .classed('er relationshipLine', true) .attr('d', lineFunction(edge.points)) - .attr('stroke', conf.stroke) - .attr('fill', 'none'); + .style('stroke', conf.stroke) + .style('fill', 'none'); // ...and with dashes if necessary if (rel.relSpec.relType === diagObj.db.Identification.NON_IDENTIFYING) { @@ -537,16 +513,14 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { const labelNode = svg .append('text') - .attr('class', 'er relationshipLabel') + .classed('er relationshipLabel', true) .attr('id', labelId) .attr('x', labelPoint.x) .attr('y', labelPoint.y) - .attr('text-anchor', 'middle') - .attr('dominant-baseline', 'middle') - .attr( - 'style', - 'font-family: ' + getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px' - ) + .style('text-anchor', 'middle') + .style('dominant-baseline', 'middle') + .style('font-family', getConfig().fontFamily) + .style('font-size', conf.fontSize + 'px') .text(rel.roleA); // Figure out how big the opaque 'container' rectangle needs to be @@ -555,13 +529,11 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { // Insert the opaque rectangle before the text label svg .insert('rect', '#' + labelId) - .attr('class', 'er relationshipLabelBox') + .classed('er relationshipLabelBox', true) .attr('x', labelPoint.x - labelBBox.width / 2) .attr('y', labelPoint.y - labelBBox.height / 2) .attr('width', labelBBox.width) - .attr('height', labelBBox.height) - .attr('fill', 'white') - .attr('fill-opacity', '85%'); + .attr('height', labelBBox.height); }; /** @@ -644,12 +616,12 @@ export const draw = function (text, id, _version, diagObj) { // inserted - this represents the insertion point for relationship paths const firstEntity = drawEntities(svg, diagObj.db.getEntities(), g); - // TODO: externalise the addition of entities to the graph - it's a bit 'buried' in the above + // TODO: externalize the addition of entities to the graph - it's a bit 'buried' in the above // Add all the relationships to the graph const relationships = addRelationships(diagObj.db.getRelationships(), g); - dagre.layout(g); // Node and edge positions will be updated + dagreLayout(g); // Node and edge positions will be updated // Adjust the positions of the entities so that they adhere to the layout adjustEntities(svg, g); @@ -661,6 +633,8 @@ export const draw = function (text, id, _version, diagObj) { const padding = conf.diagramPadding; + utils.insertTitle(svg, 'entityTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + const svgBounds = svg.node().getBBox(); const width = svgBounds.width + padding * 2; const height = svgBounds.height + padding * 2; @@ -678,10 +652,8 @@ export const draw = function (text, id, _version, diagObj) { * Although the official XML standard for ids says that many more characters are valid in the id, * this keeps things simple by accepting only A-Za-z0-9. * - * @param {string} [str?=''] Given string to use as the basis for the id. Default is `''` - * @param {string} [prefix?=''] String to put at the start, followed by '-'. Default is `''` - * @param str - * @param prefix + * @param {string} str Given string to use as the basis for the id. Default is `''` + * @param {string} prefix String to put at the start, followed by '-'. Default is `''` * @returns {string} * @see https://www.w3.org/TR/xml/#NT-Name */ diff --git a/packages/mermaid/src/diagrams/er/parser/erDiagram.jison b/packages/mermaid/src/diagrams/er/parser/erDiagram.jison index 6294599b5..f0411fd72 100644 --- a/packages/mermaid/src/diagrams/er/parser/erDiagram.jison +++ b/packages/mermaid/src/diagrams/er/parser/erDiagram.jison @@ -36,15 +36,32 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [\n]+ /* nothing */ "}" { this.popState(); return 'BLOCK_STOP'; } . return yytext[0]; + +"one or zero" return 'ZERO_OR_ONE'; +"one or more" return 'ONE_OR_MORE'; +"one or many" return 'ONE_OR_MORE'; +"1+" return 'ONE_OR_MORE'; \|o return 'ZERO_OR_ONE'; +"zero or one" return 'ZERO_OR_ONE'; +"zero or more" return 'ZERO_OR_MORE'; +"zero or many" return 'ZERO_OR_MORE'; +"0+" return 'ZERO_OR_MORE'; \}o return 'ZERO_OR_MORE'; +"many(0)" return 'ZERO_OR_MORE'; +"many(1)" return 'ONE_OR_MORE'; +"many" return 'ZERO_OR_MORE'; \}\| return 'ONE_OR_MORE'; +"one" return 'ONLY_ONE'; +"only one" return 'ONLY_ONE'; +"1" return 'ONLY_ONE'; \|\| return 'ONLY_ONE'; o\| return 'ZERO_OR_ONE'; o\{ return 'ZERO_OR_MORE'; \|\{ return 'ONE_OR_MORE'; \.\. return 'NON_IDENTIFYING'; \-\- return 'IDENTIFYING'; +"to" return 'IDENTIFYING'; +"optionally to" return 'NON_IDENTIFYING'; \.\- return 'NON_IDENTIFYING'; \-\. return 'NON_IDENTIFYING'; [A-Za-z][A-Za-z0-9\-_]* return 'ALPHANUM'; diff --git a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js index 1d891ffea..eb738fe4b 100644 --- a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js +++ b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js @@ -532,18 +532,100 @@ describe('when parsing ER diagram it...', function () { expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE); }); + it('should handle zero-or-one-to-zero-or-more relationships (aliases "one or zero" and "zero or many")', function () { + erDiagram.parser.parse('erDiagram\nA one or zero to many B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_MORE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_ONE); + }); + + it('should handle one-or-more-to-zero-or-one relationships (aliases "one or many" and "zero or one")', function () { + erDiagram.parser.parse('erDiagram\nA one or many optionally to zero or one B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_ONE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONE_OR_MORE); + }); + + it('should handle zero-or-more-to-zero-or-more relationships (aliases "zero or more" and "zero or many")', function () { + erDiagram.parser.parse('erDiagram\nA zero or more to zero or many B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_MORE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE); + }); + + it('should handle zero-or-more-to-one-or-more relationships (aliases "many(0)" and "many(1)")', function () { + erDiagram.parser.parse('erDiagram\nA many(0) to many(1) B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ONE_OR_MORE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE); + }); + + it('should handle zero-or-more-to-only-one relationships (aliases "many(0)" and "many(1)")', function () { + erDiagram.parser.parse('erDiagram\nA many optionally to one B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ONLY_ONE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE); + }); + + it('should handle only-one-to-only-one relationships (aliases "only one" and "1+")', function () { + erDiagram.parser.parse('erDiagram\nA only one optionally to 1+ B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ONE_OR_MORE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONLY_ONE); + }); + + it('should handle zero-or-more-to-only-one relationships (aliases "0+" and "1")', function () { + erDiagram.parser.parse('erDiagram\nA 0+ optionally to 1 B : has'); + const rels = erDb.getRelationships(); + + expect(Object.keys(erDb.getEntities()).length).toBe(2); + expect(rels.length).toBe(1); + expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ONLY_ONE); + expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ZERO_OR_MORE); + }); + it('should represent identifying relationships properly', function () { erDiagram.parser.parse('erDiagram\nHOUSE ||--|{ ROOM : contains'); const rels = erDb.getRelationships(); expect(rels[0].relSpec.relType).toBe(erDb.Identification.IDENTIFYING); }); + it('should represent identifying relationships properly (alias "to")', function () { + erDiagram.parser.parse('erDiagram\nHOUSE one to one ROOM : contains'); + const rels = erDb.getRelationships(); + expect(rels[0].relSpec.relType).toBe(erDb.Identification.IDENTIFYING); + }); + it('should represent non-identifying relationships properly', function () { erDiagram.parser.parse('erDiagram\n PERSON ||..o{ POSSESSION : owns'); const rels = erDb.getRelationships(); expect(rels[0].relSpec.relType).toBe(erDb.Identification.NON_IDENTIFYING); }); + it('should represent non-identifying relationships properly (alias "optionally to")', function () { + erDiagram.parser.parse('erDiagram\n PERSON many optionally to many POSSESSION : owns'); + const rels = erDb.getRelationships(); + expect(rels[0].relSpec.relType).toBe(erDb.Identification.NON_IDENTIFYING); + }); + it('should not accept a syntax error', function () { const doc = 'erDiagram\nA xxx B : has'; expect(() => { diff --git a/packages/mermaid/src/diagrams/er/styles.js b/packages/mermaid/src/diagrams/er/styles.js index 907d813b6..42dbcebde 100644 --- a/packages/mermaid/src/diagrams/er/styles.js +++ b/packages/mermaid/src/diagrams/er/styles.js @@ -27,6 +27,12 @@ const getStyles = (options) => .relationshipLine { stroke: ${options.lineColor}; } + + .entityTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/error/errorRenderer.ts b/packages/mermaid/src/diagrams/error/errorRenderer.ts index df9ce2c6e..b4e267684 100644 --- a/packages/mermaid/src/diagrams/error/errorRenderer.ts +++ b/packages/mermaid/src/diagrams/error/errorRenderer.ts @@ -8,7 +8,7 @@ let conf = {}; /** * Merges the value of `conf` with the passed `cnf` * - * @param {object} cnf Config to merge + * @param cnf - Config to merge */ export const setConf = function (cnf: any) { conf = { ...conf, ...cnf }; @@ -17,11 +17,11 @@ export const setConf = function (cnf: any) { /** * Draws a an info picture in the tag with id: id based on the graph definition in text. * - * @param text - * @param {string} id The text for the error - * @param {string} mermaidVersion The version + * @param _text - Mermaid graph definition. + * @param id - The text for the error + * @param mermaidVersion - The version */ -export const draw = (text: string, id: string, mermaidVersion: string) => { +export const draw = (_text: string, id: string, mermaidVersion: string) => { try { log.debug('Renering svg for syntax error\n'); diff --git a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js index 083c52a03..d02d484c4 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js +++ b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.js @@ -1,4 +1,5 @@ -import dagreD3 from 'dagre-d3'; +import { intersectPolygon } from 'dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js'; +import { intersectRect } from 'dagre-d3-es/src/dagre-js/intersect/intersect-rect.js'; /** * @param parent @@ -17,7 +18,7 @@ function question(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, s, s, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -42,7 +43,7 @@ function hexagon(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -64,7 +65,7 @@ function rect_left_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -85,7 +86,7 @@ function lean_right(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -106,7 +107,7 @@ function lean_left(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -127,7 +128,7 @@ function trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -148,7 +149,7 @@ function inv_trapezoid(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -170,7 +171,7 @@ function rect_right_inv_arrow(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -194,7 +195,7 @@ function stadium(parent, bbox, node) { .attr('height', h); node.intersect = function (point) { - return dagreD3.intersect.rect(node, point); + return intersectRect(node, point); }; return shapeSvg; } @@ -221,7 +222,7 @@ function subroutine(parent, bbox, node) { ]; const shapeSvg = insertPolygonShape(parent, w, h, points); node.intersect = function (point) { - return dagreD3.intersect.polygon(node, points, point); + return intersectPolygon(node, points, point); }; return shapeSvg; } @@ -270,7 +271,7 @@ function cylinder(parent, bbox, node) { .attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')'); node.intersect = function (point) { - const pos = dagreD3.intersect.rect(node, point); + const pos = intersectRect(node, point); const x = pos.x - node.x; if ( @@ -279,11 +280,15 @@ function cylinder(parent, bbox, node) { (Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) ) { // ellipsis equation: x*x / a*a + y*y / b*b = 1 - // solve for y to get adjustion value for pos.y + // solve for y to get adjusted value for pos.y let y = ry * ry * (1 - (x * x) / (rx * rx)); - if (y != 0) y = Math.sqrt(y); + if (y != 0) { + y = Math.sqrt(y); + } y = ry - y; - if (point.y - node.y > 0) y = -y; + if (point.y - node.y > 0) { + y = -y; + } pos.y += y; } diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.js b/packages/mermaid/src/diagrams/flowchart/flowDb.js index 192da23d3..9181ab9cc 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.js +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.js @@ -10,6 +10,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; const MERMAID_DOM_ID_PREFIX = 'flowchart-'; @@ -17,7 +19,7 @@ let vertexCounter = 0; let config = configApi.getConfig(); let vertices = {}; let edges = []; -let classes = []; +let classes = {}; let subGraphs = []; let subGraphLookup = {}; let tooltips = {}; @@ -44,9 +46,9 @@ export const parseDirective = function (statement, context, type) { */ export const lookUpDomId = function (id) { const veritceKeys = Object.keys(vertices); - for (let i = 0; i < veritceKeys.length; i++) { - if (vertices[veritceKeys[i]].id === id) { - return vertices[veritceKeys[i]].domId; + for (const veritceKey of veritceKeys) { + if (vertices[veritceKey].id === id) { + return vertices[veritceKey].domId; } } return id; @@ -66,7 +68,7 @@ export const lookUpDomId = function (id) { export const addVertex = function (_id, text, type, style, classes, dir, props = {}) { let txt; let id = _id; - if (typeof id === 'undefined') { + if (id === undefined) { return; } if (id.trim().length === 0) { @@ -75,7 +77,7 @@ export const addVertex = function (_id, text, type, style, classes, dir, props = // if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; - if (typeof vertices[id] === 'undefined') { + if (vertices[id] === undefined) { vertices[id] = { id: id, domId: MERMAID_DOM_ID_PREFIX + id + '-' + vertexCounter, @@ -84,7 +86,7 @@ export const addVertex = function (_id, text, type, style, classes, dir, props = }; } vertexCounter++; - if (typeof text !== 'undefined') { + if (text !== undefined) { config = configApi.getConfig(); txt = sanitizeText(text.trim()); @@ -95,31 +97,31 @@ export const addVertex = function (_id, text, type, style, classes, dir, props = vertices[id].text = txt; } else { - if (typeof vertices[id].text === 'undefined') { + if (vertices[id].text === undefined) { vertices[id].text = _id; } } - if (typeof type !== 'undefined') { + if (type !== undefined) { vertices[id].type = type; } - if (typeof style !== 'undefined') { - if (style !== null) { - style.forEach(function (s) { - vertices[id].styles.push(s); - }); - } + if (style !== undefined && style !== null) { + style.forEach(function (s) { + vertices[id].styles.push(s); + }); } - if (typeof classes !== 'undefined') { - if (classes !== null) { - classes.forEach(function (s) { - vertices[id].classes.push(s); - }); - } + if (classes !== undefined && classes !== null) { + classes.forEach(function (s) { + vertices[id].classes.push(s); + }); } - if (typeof dir !== 'undefined') { + if (dir !== undefined) { vertices[id].dir = dir; } - vertices[id].props = props; + if (vertices[id].props === undefined) { + vertices[id].props = props; + } else if (props !== undefined) { + Object.assign(vertices[id].props, props); + } }; /** @@ -128,9 +130,9 @@ export const addVertex = function (_id, text, type, style, classes, dir, props = * @param _start * @param _end * @param type - * @param linktext + * @param linkText */ -export const addSingleLink = function (_start, _end, type, linktext) { +export const addSingleLink = function (_start, _end, type, linkText) { let start = _start; let end = _end; // if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start; @@ -138,18 +140,18 @@ export const addSingleLink = function (_start, _end, type, linktext) { // log.info('Got edge...', start, end); const edge = { start: start, end: end, type: undefined, text: '' }; - linktext = type.text; + linkText = type.text; - if (typeof linktext !== 'undefined') { - edge.text = sanitizeText(linktext.trim()); + if (linkText !== undefined) { + edge.text = sanitizeText(linkText.trim()); - // strip quotes if string starts and exnds with a quote + // strip quotes if string starts and ends with a quote if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { edge.text = edge.text.substring(1, edge.text.length - 1); } } - if (typeof type !== 'undefined') { + if (type !== undefined) { edge.type = type.type; edge.stroke = type.stroke; edge.length = type.length; @@ -201,21 +203,19 @@ export const updateLink = function (positions, style) { }; export const addClass = function (id, style) { - if (typeof classes[id] === 'undefined') { + if (classes[id] === undefined) { classes[id] = { id: id, styles: [], textStyles: [] }; } - if (typeof style !== 'undefined') { - if (style !== null) { - style.forEach(function (s) { - if (s.match('color')) { - const newStyle1 = s.replace('fill', 'bgFill'); - const newStyle2 = newStyle1.replace('color', 'fill'); - classes[id].textStyles.push(newStyle2); - } - classes[id].styles.push(s); - }); - } + if (style !== undefined && style !== null) { + style.forEach(function (s) { + if (s.match('color')) { + const newStyle1 = s.replace('fill', 'bgFill'); + const newStyle2 = newStyle1.replace('color', 'fill'); + classes[id].textStyles.push(newStyle2); + } + classes[id].styles.push(s); + }); } }; @@ -251,11 +251,11 @@ export const setClass = function (ids, className) { // let id = version === 'gen-2' ? lookUpDomId(_id) : _id; let id = _id; // if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; - if (typeof vertices[id] !== 'undefined') { + if (vertices[id] !== undefined) { vertices[id].classes.push(className); } - if (typeof subGraphLookup[id] !== 'undefined') { + if (subGraphLookup[id] !== undefined) { subGraphLookup[id].classes.push(className); } }); @@ -263,7 +263,7 @@ export const setClass = function (ids, className) { const setTooltip = function (ids, tooltip) { ids.split(',').forEach(function (id) { - if (typeof tooltip !== 'undefined') { + if (tooltip !== undefined) { tooltips[version === 'gen-1' ? lookUpDomId(id) : id] = sanitizeText(tooltip); } }); @@ -275,7 +275,7 @@ const setClickFun = function (id, functionName, functionArgs) { if (configApi.getConfig().securityLevel !== 'loose') { return; } - if (typeof functionName === 'undefined') { + if (functionName === undefined) { return; } let argList = []; @@ -298,7 +298,7 @@ const setClickFun = function (id, functionName, functionArgs) { argList.push(id); } - if (typeof vertices[id] !== 'undefined') { + if (vertices[id] !== undefined) { vertices[id].haveCallback = true; funs.push(function () { const elem = document.querySelector(`[id="${domId}"]`); @@ -324,7 +324,7 @@ const setClickFun = function (id, functionName, functionArgs) { */ export const setLink = function (ids, linkStr, target) { ids.split(',').forEach(function (id) { - if (typeof vertices[id] !== 'undefined') { + if (vertices[id] !== undefined) { vertices[id].link = utils.formatUrl(linkStr, config); vertices[id].linkTarget = target; } @@ -429,8 +429,7 @@ export const clear = function (ver = 'gen-1') { vertices = {}; classes = {}; edges = []; - funs = []; - funs.push(setupToolTips); + funs = [setupToolTips]; subGraphs = []; subGraphLookup = {}; subCount = 0; @@ -479,7 +478,7 @@ export const addSubGraph = function (_id, list, _title) { if (type in prims) { return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true); } else { - return objs.indexOf(item) >= 0 ? false : objs.push(item); + return objs.includes(item) ? false : objs.push(item); } }); return { nodeList, dir }; @@ -525,8 +524,8 @@ export const addSubGraph = function (_id, list, _title) { }; const getPosForId = function (id) { - for (let i = 0; i < subGraphs.length; i++) { - if (subGraphs[i].id === id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { return i; } } @@ -617,11 +616,11 @@ const destructStartLink = (_str) => { let stroke = 'normal'; - if (str.indexOf('=') !== -1) { + if (str.includes('=')) { stroke = 'thick'; } - if (str.indexOf('.') !== -1) { + if (str.includes('.')) { stroke = 'dotted'; } @@ -700,7 +699,9 @@ const destructLink = (_str, _startStr) => { startInfo.type = info.type; } else { // x-- xyz --> - not supported - if (startInfo.type !== info.type) return { type: 'INVALID', stroke: 'INVALID' }; + if (startInfo.type !== info.type) { + return { type: 'INVALID', stroke: 'INVALID' }; + } startInfo.type = 'double_' + startInfo.type; } @@ -780,4 +781,6 @@ export default { }, exists, makeUniq, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts b/packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts index f73748c79..c88a63fa6 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts @@ -1,8 +1,9 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const flowDetectorV2: DiagramDetector = (txt, config) => { - // If we have confgured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram - if (config?.flowchart?.defaultRenderer === 'dagre-wrapper' && txt.match(/^\s*graph/) !== null) + // If we have configured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram + if (config?.flowchart?.defaultRenderer === 'dagre-wrapper' && txt.match(/^\s*graph/) !== null) { return true; + } return txt.match(/^\s*flowchart/) !== null; }; diff --git a/packages/mermaid/src/diagrams/flowchart/flowDetector.ts b/packages/mermaid/src/diagrams/flowchart/flowDetector.ts index edc9096c0..02ef63f99 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDetector.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDetector.ts @@ -1,8 +1,10 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const flowDetector: DiagramDetector = (txt, config) => { - // If we have confired to only use new flow charts this function shohuld always return false + // If we have conferred to only use new flow charts this function should always return false // as in not signalling true for a legacy flowchart - if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') return false; + if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') { + return false; + } return txt.match(/^\s*graph/) !== null; }; diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js index 6b7c4c1bf..be3fffa0c 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js @@ -1,11 +1,12 @@ -import graphlib from 'graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { select, curveLinear, selectAll } from 'd3'; import flowDb from './flowDb'; import { getConfig } from '../../config'; +import utils from '../../utils'; import { render } from '../../dagre-wrapper/index.js'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; @@ -15,8 +16,8 @@ import addSVGAccessibilityFields from '../../accessibility'; const conf = {}; export const setConf = function (cnf) { const keys = Object.keys(cnf); - for (let i = 0; i < keys.length; i++) { - conf[keys[i]] = cnf[keys[i]]; + for (const key of keys) { + conf[key] = cnf[key]; } }; @@ -59,7 +60,7 @@ export const addVertices = function (vert, g, svgId, root, doc, diagObj) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? const node = { label: vertexText.replace( - /fa[lrsb]?:fa-[\w-]+/g, + /fa[blrs]?:fa-[\w-]+/g, (s) => `` ), }; @@ -71,12 +72,12 @@ export const addVertices = function (vert, g, svgId, root, doc, diagObj) { const rows = vertexText.split(common.lineBreakRegex); - for (let j = 0; j < rows.length; j++) { + for (const row of rows) { const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan'); tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); tspan.setAttribute('dy', '1em'); tspan.setAttribute('x', '1'); - tspan.textContent = rows[j]; + tspan.textContent = row; svgLabel.appendChild(tspan); } vertexNode = svgLabel; @@ -197,7 +198,7 @@ export const addEdges = function (edges, g, diagObj) { let defaultStyle; let defaultLabelStyle; - if (typeof edges.defaultStyle !== 'undefined') { + if (edges.defaultStyle !== undefined) { const defaultStyles = getStylesFromArray(edges.defaultStyle); defaultStyle = defaultStyles.style; defaultLabelStyle = defaultStyles.labelStyle; @@ -209,7 +210,7 @@ export const addEdges = function (edges, g, diagObj) { // Identify Link var linkIdBase = 'L-' + edge.start + '-' + edge.end; // count the links from+to the same node to give unique id - if (typeof linkIdCnt[linkIdBase] === 'undefined') { + if (linkIdCnt[linkIdBase] === undefined) { linkIdCnt[linkIdBase] = 0; log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]); } else { @@ -261,10 +262,10 @@ export const addEdges = function (edges, g, diagObj) { switch (edge.stroke) { case 'normal': style = 'fill:none;'; - if (typeof defaultStyle !== 'undefined') { + if (defaultStyle !== undefined) { style = defaultStyle; } - if (typeof defaultLabelStyle !== 'undefined') { + if (defaultLabelStyle !== undefined) { labelStyle = defaultLabelStyle; } edgeData.thickness = 'normal'; @@ -281,7 +282,7 @@ export const addEdges = function (edges, g, diagObj) { edgeData.style = 'stroke-width: 3.5px;fill:none;'; break; } - if (typeof edge.style !== 'undefined') { + if (edge.style !== undefined) { const styles = getStylesFromArray(edge.style); style = styles.style; labelStyle = styles.labelStyle; @@ -290,16 +291,16 @@ export const addEdges = function (edges, g, diagObj) { edgeData.style = edgeData.style += style; edgeData.labelStyle = edgeData.labelStyle += labelStyle; - if (typeof edge.interpolate !== 'undefined') { + if (edge.interpolate !== undefined) { edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear); - } else if (typeof edges.defaultInterpolate !== 'undefined') { + } else if (edges.defaultInterpolate !== undefined) { edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear); } else { edgeData.curve = interpolateToCurve(conf.curve, curveLinear); } - if (typeof edge.text === 'undefined') { - if (typeof edge.style !== 'undefined') { + if (edge.text === undefined) { + if (edge.style !== undefined) { edgeData.arrowheadStyle = 'fill: #333'; } } else { @@ -310,7 +311,7 @@ export const addEdges = function (edges, g, diagObj) { edgeData.labelType = 'text'; edgeData.label = edge.text.replace(common.lineBreakRegex, '\n'); - if (typeof edge.style === 'undefined') { + if (edge.style === undefined) { edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none;'; } @@ -359,7 +360,7 @@ export const draw = function (text, id, _version, diagObj) { // Fetch the default direction, use TD if none was found let dir = diagObj.db.getDirection(); - if (typeof dir === 'undefined') { + if (dir === undefined) { dir = 'TD'; } @@ -437,6 +438,8 @@ export const draw = function (text, id, _version, diagObj) { const element = root.select('#' + id + ' g'); render(element, g, ['point', 'circle', 'cross'], 'flowchart', id); + utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); + setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth); // Index nodes @@ -445,9 +448,7 @@ export const draw = function (text, id, _version, diagObj) { // Add label rects for non html labels if (!conf.htmlLabels) { const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); - for (let k = 0; k < labels.length; k++) { - const label = labels[k]; - + for (const label of labels) { // Get dimensions of label const dim = label.getBBox(); diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index 0c3aa3623..4b3232189 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -1,8 +1,9 @@ -import graphlib from 'graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { select, curveLinear, selectAll } from 'd3'; import { getConfig } from '../../config'; -import dagreD3 from 'dagre-d3'; -import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; +import { render as Render } from 'dagre-d3-es'; +import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js'; +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { log } from '../../logger'; import common, { evaluate } from '../common/common'; import { interpolateToCurve, getStylesFromArray } from '../../utils'; @@ -13,8 +14,8 @@ import addSVGAccessibilityFields from '../../accessibility'; const conf = {}; export const setConf = function (cnf) { const keys = Object.keys(cnf); - for (let i = 0; i < keys.length; i++) { - conf[keys[i]] = cnf[keys[i]]; + for (const key of keys) { + conf[key] = cnf[key]; } }; @@ -58,7 +59,7 @@ export const addVertices = function (vert, g, svgId, root, _doc, diagObj) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? const node = { label: vertexText.replace( - /fa[lrsb]?:fa-[\w-]+/g, + /fa[blrs]?:fa-[\w-]+/g, (s) => `` ), }; @@ -70,12 +71,12 @@ export const addVertices = function (vert, g, svgId, root, _doc, diagObj) { const rows = vertexText.split(common.lineBreakRegex); - for (let j = 0; j < rows.length; j++) { + for (const row of rows) { const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan'); tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); tspan.setAttribute('dy', '1em'); tspan.setAttribute('x', '1'); - tspan.textContent = rows[j]; + tspan.textContent = row; svgLabel.appendChild(tspan); } vertexNode = svgLabel; @@ -166,7 +167,7 @@ export const addEdges = function (edges, g, diagObj) { let defaultStyle; let defaultLabelStyle; - if (typeof edges.defaultStyle !== 'undefined') { + if (edges.defaultStyle !== undefined) { const defaultStyles = getStylesFromArray(edges.defaultStyle); defaultStyle = defaultStyles.style; defaultLabelStyle = defaultStyles.labelStyle; @@ -192,7 +193,7 @@ export const addEdges = function (edges, g, diagObj) { let style = ''; let labelStyle = ''; - if (typeof edge.style !== 'undefined') { + if (edge.style !== undefined) { const styles = getStylesFromArray(edge.style); style = styles.style; labelStyle = styles.labelStyle; @@ -200,10 +201,10 @@ export const addEdges = function (edges, g, diagObj) { switch (edge.stroke) { case 'normal': style = 'fill:none'; - if (typeof defaultStyle !== 'undefined') { + if (defaultStyle !== undefined) { style = defaultStyle; } - if (typeof defaultLabelStyle !== 'undefined') { + if (defaultLabelStyle !== undefined) { labelStyle = defaultLabelStyle; } break; @@ -219,16 +220,16 @@ export const addEdges = function (edges, g, diagObj) { edgeData.style = style; edgeData.labelStyle = labelStyle; - if (typeof edge.interpolate !== 'undefined') { + if (edge.interpolate !== undefined) { edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear); - } else if (typeof edges.defaultInterpolate !== 'undefined') { + } else if (edges.defaultInterpolate !== undefined) { edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear); } else { edgeData.curve = interpolateToCurve(conf.curve, curveLinear); } - if (typeof edge.text === 'undefined') { - if (typeof edge.style !== 'undefined') { + if (edge.text === undefined) { + if (edge.style !== undefined) { edgeData.arrowheadStyle = 'fill: #333'; } } else { @@ -240,14 +241,14 @@ export const addEdges = function (edges, g, diagObj) { edgeData.label = `${edge.text.replace( - /fa[lrsb]?:fa-[\w-]+/g, + /fa[blrs]?:fa-[\w-]+/g, (s) => `` )}`; } else { edgeData.labelType = 'text'; edgeData.label = edge.text.replace(common.lineBreakRegex, '\n'); - if (typeof edge.style === 'undefined') { + if (edge.style === undefined) { edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none'; } @@ -279,7 +280,8 @@ export const getClasses = function (text, diagObj) { diagObj.parse(text); return diagObj.db.getClasses(); } catch (e) { - return; + log.error(e); + return {}; } }; @@ -314,7 +316,7 @@ export const draw = function (text, id, _version, diagObj) { // Fetch the default direction, use TD if none was found let dir = diagObj.db.getDirection(); - if (typeof dir === 'undefined') { + if (dir === undefined) { dir = 'TD'; } const nodeSpacing = conf.nodeSpacing || 50; @@ -369,7 +371,6 @@ export const draw = function (text, id, _version, diagObj) { addEdges(edges, g, diagObj); // Create the renderer - const Render = dagreD3.render; const render = new Render(); // Add custom shapes @@ -389,7 +390,7 @@ export const draw = function (text, id, _version, diagObj) { .attr('orient', 'auto'); const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z'); - dagreD3.util.applyStyle(path, edge[type + 'Style']); + applyStyle(path, edge[type + 'Style']); }; // Override normal arrowhead defined in d3. Remove style & add class to allow css styling. @@ -458,9 +459,7 @@ export const draw = function (text, id, _version, diagObj) { // Add label rects for non html labels if (!conf.htmlLabels) { const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); - for (let k = 0; k < labels.length; k++) { - const label = labels[k]; - + for (const label of labels) { // Get dimensions of label const dim = label.getBBox(); diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js index a56184f11..5c2094737 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js @@ -1,12 +1,8 @@ import flowDb from '../flowDb'; import flow from './flow'; -import filter from 'lodash/filter'; +import filter from 'lodash-es/filter'; import { setConfig } from '../../../config'; -// import DOMPurify from 'dompurify'; -// const domPurify = DOMPurify.createDOMPurify(window); - -// const clean = DOMPurify.sanitize(dirty); setConfig({ securityLevel: 'strict', }); @@ -83,8 +79,8 @@ describe('when parsing directions', function () { const subgraphs = flow.parser.yy.getSubGraphs(); expect(subgraphs.length).toBe(2); - const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0]; - const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0]; + const subgraphA = subgraphs.find((o) => o.id === 'A'); + const subgraphB = subgraphs.find((o) => o.id === 'B'); expect(subgraphB.nodes[0]).toBe('c'); expect(subgraphB.dir).toBe('LR'); diff --git a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js index aa8e9217f..5ba6a5361 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js @@ -1,6 +1,6 @@ import flowDb from '../flowDb'; import flow from './flow'; -import filter from 'lodash/filter'; +import filter from 'lodash-es/filter'; import { setConfig } from '../../../config'; setConfig({ @@ -254,8 +254,8 @@ describe('when parsing subgraphs', function () { const subgraphs = flow.parser.yy.getSubGraphs(); expect(subgraphs.length).toBe(2); - const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0]; - const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0]; + const subgraphA = subgraphs.find((o) => o.id === 'A'); + const subgraphB = subgraphs.find((o) => o.id === 'B'); expect(subgraphB.nodes[0]).toBe('c'); expect(subgraphA.nodes).toContain('B'); @@ -279,8 +279,8 @@ describe('when parsing subgraphs', function () { const subgraphs = flow.parser.yy.getSubGraphs(); expect(subgraphs.length).toBe(2); - const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0]; - const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0]; + const subgraphA = subgraphs.find((o) => o.id === 'A'); + const subgraphB = subgraphs.find((o) => o.id === 'B'); expect(subgraphB.nodes[0]).toBe('c'); expect(subgraphA.nodes).toContain('B'); @@ -302,8 +302,8 @@ describe('when parsing subgraphs', function () { const subgraphs = flow.parser.yy.getSubGraphs(); expect(subgraphs.length).toBe(2); - const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0]; - const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0]; + const subgraphA = subgraphs.find((o) => o.id === 'A'); + const subgraphB = subgraphs.find((o) => o.id === 'B'); expect(subgraphB.nodes[0]).toBe('c'); expect(subgraphA.nodes).toContain('B'); expect(subgraphA.nodes).toContain('b'); diff --git a/packages/mermaid/src/diagrams/flowchart/styles.ts b/packages/mermaid/src/diagrams/flowchart/styles.ts index 82fb1f875..a89d33d3d 100644 --- a/packages/mermaid/src/diagrams/flowchart/styles.ts +++ b/packages/mermaid/src/diagrams/flowchart/styles.ts @@ -103,6 +103,12 @@ const getStyles = (options: FlowChartStyleOptions) => pointer-events: none; z-index: 100; } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.js b/packages/mermaid/src/diagrams/gantt/ganttDb.js index 5d072b903..a1c74dd62 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDb.js +++ b/packages/mermaid/src/diagrams/gantt/ganttDb.js @@ -17,6 +17,7 @@ import { let dateFormat = ''; let axisFormat = ''; +let tickInterval = undefined; let todayMarker = ''; let includes = []; let excludes = []; @@ -47,6 +48,7 @@ export const clear = function () { rawTasks = []; dateFormat = ''; axisFormat = ''; + tickInterval = undefined; todayMarker = ''; includes = []; excludes = []; @@ -65,6 +67,14 @@ export const getAxisFormat = function () { return axisFormat; }; +export const setTickInterval = function (txt) { + tickInterval = txt; +}; + +export const getTickInterval = function () { + return tickInterval; +}; + export const setTodayMarker = function (txt) { todayMarker = txt; }; @@ -140,20 +150,22 @@ export const getTasks = function () { }; export const isInvalidDate = function (date, dateFormat, excludes, includes) { - if (includes.indexOf(date.format(dateFormat.trim())) >= 0) { + if (includes.includes(date.format(dateFormat.trim()))) { return false; } - if (date.isoWeekday() >= 6 && excludes.indexOf('weekends') >= 0) { + if (date.isoWeekday() >= 6 && excludes.includes('weekends')) { return true; } - if (excludes.indexOf(date.format('dddd').toLowerCase()) >= 0) { + if (excludes.includes(date.format('dddd').toLowerCase())) { return true; } - return excludes.indexOf(date.format(dateFormat.trim())) >= 0; + return excludes.includes(date.format(dateFormat.trim())); }; const checkTaskDates = function (task, dateFormat, excludes, includes) { - if (!excludes.length || task.manualEndTime) return; + if (!excludes.length || task.manualEndTime) { + return; + } let startTime = moment(task.startTime, dateFormat, true); startTime.add(1, 'd'); let endTime = moment(task.endTime, dateFormat, true); @@ -190,7 +202,7 @@ const getStartDate = function (prevTime, dateFormat, str) { let latestEndingTask = null; afterStatement[1].split(' ').forEach(function (id) { let task = findTaskById(id); - if (typeof task !== 'undefined') { + if (task !== undefined) { if (!latestEndingTask) { latestEndingTask = task; } else { @@ -217,17 +229,19 @@ const getStartDate = function (prevTime, dateFormat, str) { } else { log.debug('Invalid date:' + str); log.debug('With date format:' + dateFormat.trim()); + const d = new Date(str); + if (d === undefined || isNaN(d.getTime())) { + throw new Error('Invalid date:' + str); + } + return d; } - - // Default date - now - return new Date(); }; /** * Parse a string as a moment duration. * * The string have to be compound by a value and a shorthand duration unit. For example `5d` - * representes 5 days. + * represents 5 days. * * Shorthand unit supported are: * @@ -244,15 +258,14 @@ const getStartDate = function (prevTime, dateFormat, str) { * string. */ const parseDuration = function (str) { - const statement = /^(\d+(?:\.\d+)?)([yMwdhms]|ms)$/.exec(str.trim()); + const statement = /^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(str.trim()); if (statement !== null) { return moment.duration(Number.parseFloat(statement[1]), statement[2]); } return moment.duration.invalid(); }; -const getEndDate = function (prevTime, dateFormat, str, inclusive) { - inclusive = inclusive || false; +const getEndDate = function (prevTime, dateFormat, str, inclusive = false) { str = str.trim(); // Check for actual date @@ -274,7 +287,7 @@ const getEndDate = function (prevTime, dateFormat, str, inclusive) { let taskCnt = 0; const parseId = function (idStr) { - if (typeof idStr === 'undefined') { + if (idStr === undefined) { taskCnt = taskCnt + 1; return 'task' + taskCnt; } @@ -496,10 +509,10 @@ const compileTasks = function () { }; let allProcessed = true; - for (let i = 0; i < rawTasks.length; i++) { + for (const [i, rawTask] of rawTasks.entries()) { compileTask(i); - allProcessed = allProcessed && rawTasks[i].processed; + allProcessed = allProcessed && rawTask.processed; } return allProcessed; }; @@ -517,7 +530,7 @@ export const setLink = function (ids, _linkStr) { } ids.split(',').forEach(function (id) { let rawTask = findTaskById(id); - if (typeof rawTask !== 'undefined') { + if (rawTask !== undefined) { pushFun(id, () => { window.open(linkStr, '_self'); }); @@ -536,7 +549,7 @@ export const setLink = function (ids, _linkStr) { export const setClass = function (ids, className) { ids.split(',').forEach(function (id) { let rawTask = findTaskById(id); - if (typeof rawTask !== 'undefined') { + if (rawTask !== undefined) { rawTask.classes.push(className); } }); @@ -546,7 +559,7 @@ const setClickFun = function (id, functionName, functionArgs) { if (configApi.getConfig().securityLevel !== 'loose') { return; } - if (typeof functionName === 'undefined') { + if (functionName === undefined) { return; } @@ -571,7 +584,7 @@ const setClickFun = function (id, functionName, functionArgs) { } let rawTask = findTaskById(id); - if (typeof rawTask !== 'undefined') { + if (rawTask !== undefined) { pushFun(id, () => { utils.runFunc(functionName, ...argList); }); @@ -586,24 +599,26 @@ const setClickFun = function (id, functionName, functionArgs) { * @param callbackFunction A function to be executed when clicked on the task or the task's text */ const pushFun = function (id, callbackFunction) { - funs.push(function () { - // const elem = d3.select(element).select(`[id="${id}"]`) - const elem = document.querySelector(`[id="${id}"]`); - if (elem !== null) { - elem.addEventListener('click', function () { - callbackFunction(); - }); + funs.push( + function () { + // const elem = d3.select(element).select(`[id="${id}"]`) + const elem = document.querySelector(`[id="${id}"]`); + if (elem !== null) { + elem.addEventListener('click', function () { + callbackFunction(); + }); + } + }, + function () { + // const elem = d3.select(element).select(`[id="${id}-text"]`) + const elem = document.querySelector(`[id="${id}-text"]`); + if (elem !== null) { + elem.addEventListener('click', function () { + callbackFunction(); + }); + } } - }); - funs.push(function () { - // const elem = d3.select(element).select(`[id="${id}-text"]`) - const elem = document.querySelector(`[id="${id}-text"]`); - if (elem !== null) { - elem.addEventListener('click', function () { - callbackFunction(); - }); - } - }); + ); }; /** @@ -643,6 +658,8 @@ export default { topAxisEnabled, setAxisFormat, getAxisFormat, + setTickInterval, + getTickInterval, setTodayMarker, getTodayMarker, setAccTitle, diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts b/packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts index 28b64d4f5..09df96f12 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts +++ b/packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts @@ -1,7 +1,6 @@ // @ts-nocheck TODO: Fix TS import moment from 'moment-mini'; import ganttDb from './ganttDb'; -import { it, describe } from 'vitest'; import { convert } from '../../tests/util'; describe('when using the ganttDb', function () { diff --git a/packages/mermaid/src/diagrams/gantt/ganttDetector.ts b/packages/mermaid/src/diagrams/gantt/ganttDetector.ts index 926792dcf..5de167010 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDetector.ts +++ b/packages/mermaid/src/diagrams/gantt/ganttDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const ganttDetector: DiagramDetector = (txt) => { return txt.match(/^\s*gantt/) !== null; diff --git a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js index 3b12bc191..ab2407ecd 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js +++ b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js @@ -10,6 +10,11 @@ import { axisBottom, axisTop, timeFormat, + timeMinute, + timeHour, + timeDay, + timeWeek, + timeMonth, } from 'd3'; import common from '../common/common'; import { getConfig } from '../../config'; @@ -27,7 +32,7 @@ export const draw = function (text, id, version, diagObj) { // parser.parse(text); const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -41,11 +46,11 @@ export const draw = function (text, id, version, diagObj) { const elem = doc.getElementById(id); w = elem.parentElement.offsetWidth; - if (typeof w === 'undefined') { + if (w === undefined) { w = 1200; } - if (typeof conf.useWidth !== 'undefined') { + if (conf.useWidth !== undefined) { w = conf.useWidth; } @@ -72,8 +77,8 @@ export const draw = function (text, id, version, diagObj) { let categories = []; - for (let i = 0; i < taskArray.length; i++) { - categories.push(taskArray[i].type); + for (const element of taskArray) { + categories.push(element.type); } const catsUnfiltered = categories; // for vert labels @@ -173,8 +178,8 @@ export const draw = function (text, id, version, diagObj) { }) .attr('height', theGap) .attr('class', function (d) { - for (let i = 0; i < categories.length; i++) { - if (d.type === categories[i]) { + for (const [i, category] of categories.entries()) { + if (d.type === category) { return 'section section' + (i % conf.numberSectionStyles); } } @@ -242,8 +247,8 @@ export const draw = function (text, id, version, diagObj) { } let secNum = 0; - for (let i = 0; i < categories.length; i++) { - if (d.type === categories[i]) { + for (const [i, category] of categories.entries()) { + if (d.type === category) { secNum = i % conf.numberSectionStyles; } } @@ -334,8 +339,8 @@ export const draw = function (text, id, version, diagObj) { } let secNum = 0; - for (let i = 0; i < categories.length; i++) { - if (d.type === categories[i]) { + for (const [i, category] of categories.entries()) { + if (d.type === category) { secNum = i % conf.numberSectionStyles; } } @@ -395,7 +400,7 @@ export const draw = function (text, id, version, diagObj) { rectangles .filter(function (d) { - return typeof links[d.id] !== 'undefined'; + return links[d.id] !== undefined; }) .each(function (o) { var taskRect = doc.querySelector('#' + o.id); @@ -427,7 +432,9 @@ export const draw = function (text, id, version, diagObj) { ); const maxTime = tasks.reduce((max, { endTime }) => (max ? Math.max(max, endTime) : endTime), 0); const dateFormat = diagObj.db.getDateFormat(); - if (!minTime || !maxTime) return; + if (!minTime || !maxTime) { + return; + } const excludeRanges = []; let range = null; @@ -493,6 +500,33 @@ export const draw = function (text, id, version, diagObj) { .tickSize(-h + theTopPad + conf.gridLineStartPadding) .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); + const reTickInterval = /^([1-9]\d*)(minute|hour|day|week|month)$/; + const resultTickInterval = reTickInterval.exec( + diagObj.db.getTickInterval() || conf.tickInterval + ); + + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + switch (interval) { + case 'minute': + bottomXAxis.ticks(timeMinute.every(every)); + break; + case 'hour': + bottomXAxis.ticks(timeHour.every(every)); + break; + case 'day': + bottomXAxis.ticks(timeDay.every(every)); + break; + case 'week': + bottomXAxis.ticks(timeWeek.every(every)); + break; + case 'month': + bottomXAxis.ticks(timeMonth.every(every)); + break; + } + } + svg .append('g') .attr('class', 'grid') @@ -510,6 +544,28 @@ export const draw = function (text, id, version, diagObj) { .tickSize(-h + theTopPad + conf.gridLineStartPadding) .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + switch (interval) { + case 'minute': + topXAxis.ticks(timeMinute.every(every)); + break; + case 'hour': + topXAxis.ticks(timeHour.every(every)); + break; + case 'day': + topXAxis.ticks(timeDay.every(every)); + break; + case 'week': + topXAxis.ticks(timeWeek.every(every)); + break; + case 'month': + topXAxis.ticks(timeMonth.every(every)); + break; + } + } + svg .append('g') .attr('class', 'grid') @@ -532,8 +588,8 @@ export const draw = function (text, id, version, diagObj) { const numOccurances = []; let prevGap = 0; - for (let i = 0; i < categories.length; i++) { - numOccurances[i] = [categories[i], getCount(categories[i], catsUnfiltered)]; + for (const [i, category] of categories.entries()) { + numOccurances[i] = [category, getCount(category, catsUnfiltered)]; } svg @@ -548,12 +604,14 @@ export const draw = function (text, id, version, diagObj) { const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text'); svgLabel.setAttribute('dy', dy + 'em'); - for (let j = 0; j < rows.length; j++) { + for (const [j, row] of rows.entries()) { const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan'); tspan.setAttribute('alignment-baseline', 'central'); tspan.setAttribute('x', '10'); - if (j > 0) tspan.setAttribute('dy', '1em'); - tspan.textContent = rows[j]; + if (j > 0) { + tspan.setAttribute('dy', '1em'); + } + tspan.textContent = row; svgLabel.appendChild(tspan); } return svgLabel; @@ -572,8 +630,8 @@ export const draw = function (text, id, version, diagObj) { .attr('font-size', conf.sectionFontSize) .attr('font-size', conf.sectionFontSize) .attr('class', function (d) { - for (let i = 0; i < categories.length; i++) { - if (d[0] === categories[i]) { + for (const [i, category] of categories.entries()) { + if (d[0] === category) { return 'sectionTitle sectionTitle' + (i % conf.numberSectionStyles); } } @@ -610,7 +668,7 @@ export const draw = function (text, id, version, diagObj) { } /** - * From this stackexchange question: + * From this stack exchange question: * http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript * * @param arr @@ -629,7 +687,7 @@ export const draw = function (text, id, version, diagObj) { } /** - * From this stackexchange question: + * From this stack exchange question: * http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array * * @param arr diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison index f25656453..2223aa378 100644 --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison @@ -82,6 +82,7 @@ that id. "inclusiveEndDates" return 'inclusiveEndDates'; "topAxis" return 'topAxis'; "axisFormat"\s[^#\n;]+ return 'axisFormat'; +"tickInterval"\s[^#\n;]+ return 'tickInterval'; "includes"\s[^#\n;]+ return 'includes'; "excludes"\s[^#\n;]+ return 'excludes'; "todayMarker"\s[^\n;]+ return 'todayMarker'; @@ -125,6 +126,7 @@ statement | inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);} | topAxis {yy.TopAxis();$$=$1.substr(8);} | axisFormat {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);} + | tickInterval {yy.setTickInterval($1.substr(13));$$=$1.substr(13);} | excludes {yy.setExcludes($1.substr(9));$$=$1.substr(9);} | includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);} | todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);} diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js index 9e5675249..9a1401cad 100644 --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js @@ -65,17 +65,6 @@ describe('when parsing a gantt diagram it', function () { expect(parserFnConstructor(str)).not.toThrow(); }); - /** - * Beslutsflöde inligt nedan. Obs bla bla bla - * - * graph TD - * A[Hard pledge] -- text on link -->B(Round edge) - * B --> C{to do or not to do} - * C -->|Too| D[Result one] - * C -->|Doo| E[Result two] - * - * Params bapa - a unique bapap - */ it('should handle a task definition', function () { const str = 'gantt\n' + diff --git a/packages/mermaid/src/diagrams/git/gitGraphAst.js b/packages/mermaid/src/diagrams/git/gitGraphAst.js index 41130c780..dded48efa 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphAst.js +++ b/packages/mermaid/src/diagrams/git/gitGraphAst.js @@ -10,6 +10,8 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; let mainBranchName = getConfig().gitGraph.mainBranchName; @@ -39,6 +41,7 @@ export const parseDirective = function (statement, context, type) { // * @param currentCommit // * @param otherCommit // */ +// eslint-disable-next-line @cspell/spellchecker // function isfastforwardable(currentCommit, otherCommit) { // log.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id); // let cnt = 0; @@ -128,7 +131,7 @@ export const commit = function (msg, id, type, tag) { export const branch = function (name, order) { name = common.sanitizeText(name, configApi.getConfig()); - if (typeof branches[name] === 'undefined') { + if (branches[name] === undefined) { branches[name] = head != null ? head.id : null; branchesConfig[name] = { name, order: order ? parseInt(order, 10) : null }; checkout(name); @@ -166,7 +169,7 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag expected: ['branch abc'], }; throw error; - } else if (typeof currentCommit === 'undefined' || !currentCommit) { + } else if (currentCommit === undefined || !currentCommit) { let error = new Error( 'Incorrect usage of "merge". Current branch (' + curBranch + ')has no commits' ); @@ -178,7 +181,7 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag expected: ['commit'], }; throw error; - } else if (typeof branches[otherBranch] === 'undefined') { + } else if (branches[otherBranch] === undefined) { let error = new Error( 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ') does not exist' ); @@ -190,7 +193,7 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag expected: ['branch ' + otherBranch], }; throw error; - } else if (typeof otherCommit === 'undefined' || !otherCommit) { + } else if (otherCommit === undefined || !otherCommit) { let error = new Error( 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ') has no commits' ); @@ -212,7 +215,7 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag expected: ['branch abc'], }; throw error; - } else if (custom_id && typeof commits[custom_id] !== 'undefined') { + } else if (custom_id && commits[custom_id] !== undefined) { let error = new Error( 'Incorrect usage of "merge". Commit with id:' + custom_id + @@ -264,7 +267,7 @@ export const cherryPick = function (sourceId, targetId, tag) { targetId = common.sanitizeText(targetId, configApi.getConfig()); tag = common.sanitizeText(tag, configApi.getConfig()); - if (!sourceId || typeof commits[sourceId] === 'undefined') { + if (!sourceId || commits[sourceId] === undefined) { let error = new Error( 'Incorrect usage of "cherryPick". Source commit id should exist and provided' ); @@ -293,7 +296,7 @@ export const cherryPick = function (sourceId, targetId, tag) { }; throw error; } - if (!targetId || typeof commits[targetId] === 'undefined') { + if (!targetId || commits[targetId] === undefined) { // cherry-pick source commit to current branch if (sourceCommitBranch === curBranch) { @@ -310,7 +313,7 @@ export const cherryPick = function (sourceId, targetId, tag) { throw error; } const currentCommit = commits[branches[curBranch]]; - if (typeof currentCommit === 'undefined' || !currentCommit) { + if (currentCommit === undefined || !currentCommit) { let error = new Error( 'Incorrect usage of "cherry-pick". Current branch (' + curBranch + ')has no commits' ); @@ -341,7 +344,7 @@ export const cherryPick = function (sourceId, targetId, tag) { }; export const checkout = function (branch) { branch = common.sanitizeText(branch, configApi.getConfig()); - if (typeof branches[branch] === 'undefined') { + if (branches[branch] === undefined) { let error = new Error( 'Trying to checkout branch which is not yet created. (Help try using "branch ' + branch + '")' ); @@ -384,21 +387,23 @@ export const checkout = function (branch) { /** * @param arr * @param key - * @param newval + * @param newVal */ -function upsert(arr, key, newval) { +function upsert(arr, key, newVal) { const index = arr.indexOf(key); if (index === -1) { - arr.push(newval); + arr.push(newVal); } else { - arr.splice(index, 1, newval); + arr.splice(index, 1, newVal); } } /** @param commitArr */ function prettyPrintCommitHistory(commitArr) { const commit = commitArr.reduce((out, commit) => { - if (out.seq > commit.seq) return out; + if (out.seq > commit.seq) { + return out; + } return commit; }, commitArr[0]); let line = ''; @@ -411,7 +416,9 @@ function prettyPrintCommitHistory(commitArr) { }); const label = [line, commit.id, commit.seq]; for (let branch in branches) { - if (branches[branch] === commit.id) label.push(branch); + if (branches[branch] === commit.id) { + label.push(branch); + } } log.debug(label.join(' ')); if (commit.parents && commit.parents.length == 2) { @@ -451,7 +458,9 @@ export const clear = function () { export const getBranchesAsObjArray = function () { const branchesArray = Object.values(branchesConfig) .map((branchConfig, i) => { - if (branchConfig.order !== null) return branchConfig; + if (branchConfig.order !== null) { + return branchConfig; + } return { ...branchConfig, order: parseFloat(`0.${i}`, 10), @@ -522,5 +531,7 @@ export default { getAccTitle, getAccDescription, setAccDescription, + setDiagramTitle, + getDiagramTitle, commitType, }; diff --git a/packages/mermaid/src/diagrams/git/gitGraphDetector.ts b/packages/mermaid/src/diagrams/git/gitGraphDetector.ts index 1c0a015e7..f890501a5 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphDetector.ts +++ b/packages/mermaid/src/diagrams/git/gitGraphDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const gitGraphDetector: DiagramDetector = (txt) => { return txt.match(/^\s*gitGraph/) !== null; diff --git a/packages/mermaid/src/diagrams/git/gitGraphParserV2.spec.js b/packages/mermaid/src/diagrams/git/gitGraphParserV2.spec.js index 7aab8fc7c..cad44ea1f 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphParserV2.spec.js +++ b/packages/mermaid/src/diagrams/git/gitGraphParserV2.spec.js @@ -334,6 +334,31 @@ describe('when parsing a gitGraph', function () { expect(Object.keys(parser.yy.getBranches()).length).toBe(2); }); + it('should allow quoted branch names', function () { + const str = `gitGraph: + commit + branch "branch" + checkout "branch" + commit + checkout main + merge "branch" + `; + + parser.parse(str); + const commits = parser.yy.getCommits(); + expect(Object.keys(commits).length).toBe(3); + expect(parser.yy.getCurrentBranch()).toBe('main'); + expect(parser.yy.getDirection()).toBe('LR'); + expect(Object.keys(parser.yy.getBranches()).length).toBe(2); + const commit1 = Object.keys(commits)[0]; + const commit2 = Object.keys(commits)[1]; + const commit3 = Object.keys(commits)[2]; + expect(commits[commit1].branch).toBe('main'); + expect(commits[commit2].branch).toBe('branch'); + expect(commits[commit3].branch).toBe('main'); + expect(parser.yy.getBranchesAsObjArray()).toStrictEqual([{ name: 'main' }, { name: 'branch' }]); + }); + it('should allow _-./ characters in branch names', function () { const str = `gitGraph: commit diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer-old.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer-old.js index eefaf5ad8..ca288bfae 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer-old.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer-old.js @@ -218,18 +218,18 @@ function cloneNode(svg, selector) { /** * @param svg - * @param commitid + * @param commitId * @param branches * @param direction */ -function renderCommitHistory(svg, commitid, branches, direction) { +function renderCommitHistory(svg, commitId, branches, direction) { let commit; const numCommits = Object.keys(allCommitsDict).length; - if (typeof commitid === 'string') { + if (typeof commitId === 'string') { do { - commit = allCommitsDict[commitid]; + commit = allCommitsDict[commitId]; logger.debug('in renderCommitHistory', commit.id, commit.seq); - if (svg.select('#node-' + commitid).size() > 0) { + if (svg.select('#node-' + commitId).size() > 0) { return; } svg @@ -291,15 +291,15 @@ function renderCommitHistory(svg, commitid, branches, direction) { .attr('class', 'commit-msg') .text(', ' + commit.message); } - commitid = commit.parent; - } while (commitid && allCommitsDict[commitid]); + commitId = commit.parent; + } while (commitId && allCommitsDict[commitId]); } - if (Array.isArray(commitid)) { - logger.debug('found merge commmit', commitid); - renderCommitHistory(svg, commitid[0], branches, direction); + if (Array.isArray(commitId)) { + logger.debug('found merge commmit', commitId); + renderCommitHistory(svg, commitId[0], branches, direction); branchNum++; - renderCommitHistory(svg, commitid[1], branches, direction); + renderCommitHistory(svg, commitId[1], branches, direction); branchNum--; } } @@ -310,8 +310,7 @@ function renderCommitHistory(svg, commitid, branches, direction) { * @param direction * @param branchColor */ -function renderLines(svg, commit, direction, branchColor) { - branchColor = branchColor || 0; +function renderLines(svg, commit, direction, branchColor = 0) { while (commit.seq > 0 && !commit.lineDrawn) { if (typeof commit.parent === 'string') { svgDrawLineForCommits(svg, commit.id, commit.parent, direction, branchColor); @@ -357,7 +356,9 @@ export const draw = function (txt, id, ver) { branchNum++; } svg.attr('height', function () { - if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing; + if (direction === 'BT') { + return Object.keys(allCommitsDict).length * config.nodeSpacing; + } return (branches.length + 1) * config.branchOffset; }); } catch (e) { diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js index e15e43ac3..6874363ad 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js @@ -1,6 +1,7 @@ import { select } from 'd3'; import { getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI'; import { log } from '../../logger'; +import utils from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; let allCommitsDict = {}; @@ -46,13 +47,13 @@ const drawText = (txt) => { rows = []; } - for (let j = 0; j < rows.length; j++) { + for (const row of rows) { const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve'); tspan.setAttribute('dy', '1em'); tspan.setAttribute('x', '0'); tspan.setAttribute('class', 'row'); - tspan.textContent = rows[j].trim(); + tspan.textContent = row.trim(); svgLabel.appendChild(tspan); } /** @@ -90,7 +91,7 @@ const drawCommits = (svg, commits, modifyGraph) => { if (modifyGraph) { let typeClass; let commitSymbolType = - typeof commit.customType !== 'undefined' && commit.customType !== '' + commit.customType !== undefined && commit.customType !== '' ? commit.customType : commit.type; switch (commitSymbolType) { @@ -318,23 +319,16 @@ const hasOverlappingCommits = (commit1, commit2, allCommits) => { * * @param {any} y1 * @param {any} y2 - * @param {any} _depth + * @param {any} depth * @returns {number} Y value between y1 and y2 */ -const findLane = (y1, y2, _depth) => { - const depth = _depth || 0; - +const findLane = (y1, y2, depth = 0) => { const candidate = y1 + Math.abs(y1 - y2) / 2; if (depth > 5) { return candidate; } - let ok = true; - for (let i = 0; i < lanes.length; i++) { - if (Math.abs(lanes[i] - candidate) < 10) { - ok = false; - } - } + let ok = lanes.every((lane) => Math.abs(lane - candidate) >= 10); if (ok) { lanes.push(candidate); return candidate; @@ -496,7 +490,7 @@ const drawBranches = (svg, branches) => { export const draw = function (txt, id, ver, diagObj) { clear(); const conf = getConfig(); - const gitGraphConfig = getConfig().gitGraph; + const gitGraphConfig = conf.gitGraph; // try { log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver); @@ -521,9 +515,20 @@ export const draw = function (txt, id, ver, diagObj) { } drawArrows(diagram, allCommitsDict); drawCommits(diagram, allCommitsDict, true); + utils.insertTitle( + diagram, + 'gitTitleText', + gitGraphConfig.titleTopMargin, + diagObj.db.getDiagramTitle() + ); // Setup the view box and size of the svg element - setupGraphViewbox(undefined, diagram, gitGraphConfig.diagramPadding, conf.useMaxWidth); + setupGraphViewbox( + undefined, + diagram, + gitGraphConfig.diagramPadding, + gitGraphConfig.useMaxWidth ?? conf.useMaxWidth + ); }; export default { diff --git a/packages/mermaid/src/diagrams/git/layout.js b/packages/mermaid/src/diagrams/git/layout.js index 5714c2b96..de866a72b 100644 --- a/packages/mermaid/src/diagrams/git/layout.js +++ b/packages/mermaid/src/diagrams/git/layout.js @@ -1,12 +1,12 @@ import { getConfig } from '../../config'; -export default (dir, _branches, _commits) => { +export default (dir, _branches) => { const config = getConfig().gitGraph; const branches = []; const commits = []; - for (let i = 0; i < _branches.length; i++) { - const branch = Object.assign({}, _branches[i]); + for (const [i, _branch] of _branches.entries()) { + const branch = Object.assign({}, _branch); if (dir === 'TB' || dir === 'BT') { branch.x = config.branchOffset * i; branch.y = -1; diff --git a/packages/mermaid/src/diagrams/git/parser/gitGraph.jison b/packages/mermaid/src/diagrams/git/parser/gitGraph.jison index dbe220e15..1c87f3bf3 100644 --- a/packages/mermaid/src/diagrams/git/parser/gitGraph.jison +++ b/packages/mermaid/src/diagrams/git/parser/gitGraph.jison @@ -109,12 +109,12 @@ statement | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);} | branchStatement - | CHECKOUT ID {yy.checkout($2)} + | CHECKOUT ref {yy.checkout($2)} // | RESET reset_arg {yy.reset($2)} ; branchStatement - : BRANCH ID {yy.branch($2)} - | BRANCH ID ORDER NUM {yy.branch($2, $4)} + : BRANCH ref {yy.branch($2)} + | BRANCH ref ORDER NUM {yy.branch($2, $4)} ; cherryPickStatement @@ -126,22 +126,22 @@ cherryPickStatement ; mergeStatement - : MERGE ID {yy.merge($2,'','','')} - | MERGE ID COMMIT_ID STR {yy.merge($2, $4,'','')} - | MERGE ID COMMIT_TYPE commitType {yy.merge($2,'', $4,'')} - | MERGE ID COMMIT_TAG STR {yy.merge($2, '','',$4)} - | MERGE ID COMMIT_TAG STR COMMIT_ID STR {yy.merge($2, $6,'', $4)} - | MERGE ID COMMIT_TAG STR COMMIT_TYPE commitType {yy.merge($2, '',$6, $4)} - | MERGE ID COMMIT_TYPE commitType COMMIT_TAG STR {yy.merge($2, '',$4, $6)} - | MERGE ID COMMIT_ID STR COMMIT_TYPE commitType {yy.merge($2, $4, $6, '')} - | MERGE ID COMMIT_ID STR COMMIT_TAG STR {yy.merge($2, $4, '', $6)} - | MERGE ID COMMIT_TYPE commitType COMMIT_ID STR {yy.merge($2, $6,$4, '')} - | MERGE ID COMMIT_ID STR COMMIT_TYPE commitType COMMIT_TAG STR {yy.merge($2, $4, $6, $8)} - | MERGE ID COMMIT_TYPE commitType COMMIT_TAG STR COMMIT_ID STR {yy.merge($2, $8, $4, $6)} - | MERGE ID COMMIT_ID STR COMMIT_TAG STR COMMIT_TYPE commitType {yy.merge($2, $4, $8, $6)} - | MERGE ID COMMIT_TYPE commitType COMMIT_ID STR COMMIT_TAG STR {yy.merge($2, $6, $4, $8)} - | MERGE ID COMMIT_TAG STR COMMIT_TYPE commitType COMMIT_ID STR {yy.merge($2, $8, $6, $4)} - | MERGE ID COMMIT_TAG STR COMMIT_ID STR COMMIT_TYPE commitType {yy.merge($2, $6, $8, $4)} + : MERGE ref {yy.merge($2,'','','')} + | MERGE ref COMMIT_ID STR {yy.merge($2, $4,'','')} + | MERGE ref COMMIT_TYPE commitType {yy.merge($2,'', $4,'')} + | MERGE ref COMMIT_TAG STR {yy.merge($2, '','',$4)} + | MERGE ref COMMIT_TAG STR COMMIT_ID STR {yy.merge($2, $6,'', $4)} + | MERGE ref COMMIT_TAG STR COMMIT_TYPE commitType {yy.merge($2, '',$6, $4)} + | MERGE ref COMMIT_TYPE commitType COMMIT_TAG STR {yy.merge($2, '',$4, $6)} + | MERGE ref COMMIT_ID STR COMMIT_TYPE commitType {yy.merge($2, $4, $6, '')} + | MERGE ref COMMIT_ID STR COMMIT_TAG STR {yy.merge($2, $4, '', $6)} + | MERGE ref COMMIT_TYPE commitType COMMIT_ID STR {yy.merge($2, $6,$4, '')} + | MERGE ref COMMIT_ID STR COMMIT_TYPE commitType COMMIT_TAG STR {yy.merge($2, $4, $6, $8)} + | MERGE ref COMMIT_TYPE commitType COMMIT_TAG STR COMMIT_ID STR {yy.merge($2, $8, $4, $6)} + | MERGE ref COMMIT_ID STR COMMIT_TAG STR COMMIT_TYPE commitType {yy.merge($2, $4, $8, $6)} + | MERGE ref COMMIT_TYPE commitType COMMIT_ID STR COMMIT_TAG STR {yy.merge($2, $6, $4, $8)} + | MERGE ref COMMIT_TAG STR COMMIT_TYPE commitType COMMIT_ID STR {yy.merge($2, $8, $6, $4)} + | MERGE ref COMMIT_TAG STR COMMIT_ID STR COMMIT_TYPE commitType {yy.merge($2, $6, $8, $4)} ; commitStatement @@ -261,6 +261,11 @@ closeDirective : close_directive { yy.parseDirective('}%%', 'close_directive', 'gitGraph'); } ; +ref + : ID + | STR + ; + eol : NL | ';' diff --git a/packages/mermaid/src/diagrams/git/styles.js b/packages/mermaid/src/diagrams/git/styles.js index 7e09ff7e0..741760235 100644 --- a/packages/mermaid/src/diagrams/git/styles.js +++ b/packages/mermaid/src/diagrams/git/styles.js @@ -51,6 +51,11 @@ const getStyles = (options) => } .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } } `; diff --git a/packages/mermaid/src/diagrams/info/infoDetector.ts b/packages/mermaid/src/diagrams/info/infoDetector.ts index 68f2ac794..8bccb578f 100644 --- a/packages/mermaid/src/diagrams/info/infoDetector.ts +++ b/packages/mermaid/src/diagrams/info/infoDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const infoDetector: DiagramDetector = (txt) => { return txt.match(/^\s*info/) !== null; diff --git a/packages/mermaid/src/diagrams/info/infoRenderer.js b/packages/mermaid/src/diagrams/info/infoRenderer.js index b50178481..1caa7222c 100644 --- a/packages/mermaid/src/diagrams/info/infoRenderer.js +++ b/packages/mermaid/src/diagrams/info/infoRenderer.js @@ -9,16 +9,15 @@ import { getConfig } from '../../config'; * @param {any} text * @param {any} id * @param {any} version - * @param diagObj */ -export const draw = (text, id, version, diagObj) => { +export const draw = (text, id, version) => { try { // const parser = infoParser.parser; // parser.yy = db; log.debug('Rendering info diagram\n' + text); const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); diff --git a/packages/mermaid/src/diagrams/pie/pieDb.js b/packages/mermaid/src/diagrams/pie/pieDb.js index 8ef4d9efc..5ccf6d29e 100644 --- a/packages/mermaid/src/diagrams/pie/pieDb.js +++ b/packages/mermaid/src/diagrams/pie/pieDb.js @@ -21,7 +21,7 @@ export const parseDirective = function (statement, context, type) { const addSection = function (id, value) { id = common.sanitizeText(id, configApi.getConfig()); - if (typeof sections[id] === 'undefined') { + if (sections[id] === undefined) { sections[id] = value; log.debug('Added new section :', id); } diff --git a/packages/mermaid/src/diagrams/pie/pieDetector.ts b/packages/mermaid/src/diagrams/pie/pieDetector.ts index 1e122b0e0..e267c710a 100644 --- a/packages/mermaid/src/diagrams/pie/pieDetector.ts +++ b/packages/mermaid/src/diagrams/pie/pieDetector.ts @@ -1,5 +1,6 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const pieDetector: DiagramDetector = (txt) => { - return txt.match(/^\s*pie/) !== null; + const logOutput = txt.match(/^\s*pie/) !== null || txt.match(/^\s*bar/) !== null; + return logOutput; }; diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.js b/packages/mermaid/src/diagrams/pie/pieRenderer.js index f8e21bc9d..c5d86ad65 100644 --- a/packages/mermaid/src/diagrams/pie/pieRenderer.js +++ b/packages/mermaid/src/diagrams/pie/pieRenderer.js @@ -21,7 +21,7 @@ export const draw = (txt, id, _version, diagObj) => { log.debug('Rendering info diagram\n' + txt); const securityLevel = configApi.getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -39,14 +39,14 @@ export const draw = (txt, id, _version, diagObj) => { const elem = doc.getElementById(id); width = elem.parentElement.offsetWidth; - if (typeof width === 'undefined') { + if (width === undefined) { width = 1200; } - if (typeof conf.useWidth !== 'undefined') { + if (conf.useWidth !== undefined) { width = conf.useWidth; } - if (typeof conf.pie.useWidth !== 'undefined') { + if (conf.pie.useWidth !== undefined) { width = conf.pie.useWidth; } @@ -94,10 +94,22 @@ export const draw = (txt, id, _version, diagObj) => { var color = scaleOrdinal().range(myGeneratedColors); // Compute the position of each group on the pie: - var pie = d3pie().value(function (d) { - return d[1]; + var pieData = Object.entries(data).map(function (el, idx) { + return { + order: idx, + name: el[0], + value: el[1], + }; }); - var dataReady = pie(Object.entries(data)); + var pie = d3pie() + .value(function (d) { + return d.value; + }) + .sort(function (a, b) { + // Sort slices in clockwise direction + return a.order - b.order; + }); + var dataReady = pie(pieData); // Shape helper to build arcs: var arcGenerator = arc().innerRadius(0).outerRadius(radius); @@ -110,7 +122,7 @@ export const draw = (txt, id, _version, diagObj) => { .append('path') .attr('d', arcGenerator) .attr('fill', function (d) { - return color(d.data[0]); + return color(d.data.name); }) .attr('class', 'pieCircle'); @@ -122,7 +134,7 @@ export const draw = (txt, id, _version, diagObj) => { .enter() .append('text') .text(function (d) { - return ((d.data[1] / sum) * 100).toFixed(0) + '%'; + return ((d.data.value / sum) * 100).toFixed(0) + '%'; }) .attr('transform', function (d) { return 'translate(' + arcGenerator.centroid(d) + ')'; @@ -145,11 +157,11 @@ export const draw = (txt, id, _version, diagObj) => { .append('g') .attr('class', 'legend') .attr('transform', function (d, i) { - var height = legendRectSize + legendSpacing; - var offset = (height * color.domain().length) / 2; - var horz = 12 * legendRectSize; - var vert = i * height - offset; - return 'translate(' + horz + ',' + vert + ')'; + const height = legendRectSize + legendSpacing; + const offset = (height * color.domain().length) / 2; + const horizontal = 12 * legendRectSize; + const vertical = i * height - offset; + return 'translate(' + horizontal + ',' + vertical + ')'; }); legend @@ -166,9 +178,9 @@ export const draw = (txt, id, _version, diagObj) => { .attr('y', legendRectSize - legendSpacing) .text(function (d) { if (diagObj.db.getShowData() || conf.showData || conf.pie.showData) { - return d.data[0] + ' [' + d.data[1] + ']'; + return d.data.name + ' [' + d.data.value + ']'; } else { - return d.data[0]; + return d.data.name; } }); } catch (e) { diff --git a/packages/mermaid/src/diagrams/requirement/requirementDb.js b/packages/mermaid/src/diagrams/requirement/requirementDb.js index 9d48f0b2d..df5eb0ab9 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementDb.js +++ b/packages/mermaid/src/diagrams/requirement/requirementDb.js @@ -53,7 +53,7 @@ export const parseDirective = function (statement, context, type) { }; const addRequirement = (name, type) => { - if (typeof requirements[name] === 'undefined') { + if (requirements[name] === undefined) { requirements[name] = { name, type, @@ -72,31 +72,31 @@ const addRequirement = (name, type) => { const getRequirements = () => requirements; const setNewReqId = (id) => { - if (typeof latestRequirement != 'undefined') { + if (latestRequirement !== undefined) { latestRequirement.id = id; } }; const setNewReqText = (text) => { - if (typeof latestRequirement != 'undefined') { + if (latestRequirement !== undefined) { latestRequirement.text = text; } }; const setNewReqRisk = (risk) => { - if (typeof latestRequirement != 'undefined') { + if (latestRequirement !== undefined) { latestRequirement.risk = risk; } }; const setNewReqVerifyMethod = (verifyMethod) => { - if (typeof latestRequirement != 'undefined') { + if (latestRequirement !== undefined) { latestRequirement.verifyMethod = verifyMethod; } }; const addElement = (name) => { - if (typeof elements[name] === 'undefined') { + if (elements[name] === undefined) { elements[name] = { name, @@ -113,13 +113,13 @@ const addElement = (name) => { const getElements = () => elements; const setNewElementType = (type) => { - if (typeof latestElement != 'undefined') { + if (latestElement !== undefined) { latestElement.type = type; } }; const setNewElementDocRef = (docRef) => { - if (typeof latestElement != 'undefined') { + if (latestElement !== undefined) { latestElement.docRef = docRef; } }; diff --git a/packages/mermaid/src/diagrams/requirement/requirementDetector.ts b/packages/mermaid/src/diagrams/requirement/requirementDetector.ts index 2e1aa93ae..164da6c1a 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementDetector.ts +++ b/packages/mermaid/src/diagrams/requirement/requirementDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const requirementDetector: DiagramDetector = (txt) => { return txt.match(/^\s*requirement(Diagram)?/) !== null; diff --git a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js index d10c43066..a0019f46b 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js +++ b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js @@ -1,6 +1,6 @@ import { line, select } from 'd3'; -import dagre from 'dagre'; -import graphlib from 'graphlib'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { log } from '../../logger'; import { configureSvgSize } from '../../setupGraphViewbox'; import common from '../common/common'; @@ -284,7 +284,7 @@ const addRelationships = (relationships, g) => { const adjustEntities = function (svgNode, graph) { graph.nodes().forEach(function (v) { - if (typeof v !== 'undefined' && typeof graph.node(v) !== 'undefined') { + if (v !== undefined && graph.node(v) !== undefined) { svgNode.select('#' + v); svgNode .select('#' + v) @@ -311,7 +311,7 @@ export const draw = (text, id, _version, diagObj) => { diagObj.parser.parse(text); const securityLevel = conf.securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -348,7 +348,7 @@ export const draw = (text, id, _version, diagObj) => { drawReqs(requirements, g, svg); drawElements(elements, g, svg); addRelationships(relationships, g); - dagre.layout(g); + dagreLayout(g); adjustEntities(svg, g); relationships.forEach(function (rel) { diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDb.js b/packages/mermaid/src/diagrams/sequence/sequenceDb.js index 6c863e204..fadd9f391 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDb.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDb.js @@ -26,7 +26,9 @@ export const parseDirective = function (statement, context, type) { export const addActor = function (id, name, description, type) { // Don't allow description nulling const old = actors[id]; - if (old && name === old.name && description == null) return; + if (old && name === old.name && description == null) { + return; + } // Don't allow null descriptions, either if (description == null || description.text == null) { @@ -58,15 +60,11 @@ const activationCount = (part) => { let i; let count = 0; for (i = 0; i < messages.length; i++) { - if (messages[i].type === LINETYPE.ACTIVE_START) { - if (messages[i].from.actor === part) { - count++; - } + if (messages[i].type === LINETYPE.ACTIVE_START && messages[i].from.actor === part) { + count++; } - if (messages[i].type === LINETYPE.ACTIVE_END) { - if (messages[i].from.actor === part) { - count--; - } + if (messages[i].type === LINETYPE.ACTIVE_END && messages[i].from.actor === part) { + count--; } } return count; @@ -141,7 +139,7 @@ export const setWrap = function (wrapSetting) { export const autoWrap = () => { // if setWrap has been called, use that value, otherwise use the value from the config // TODO: refactor, always use the config value let setWrap update the config value - if (typeof wrapEnabled !== 'undefined') { + if (wrapEnabled !== undefined) { return wrapEnabled; } return configApi.getConfig().sequence.wrap; @@ -157,11 +155,11 @@ export const clear = function () { export const parseMessage = function (str) { const _str = str.trim(); const message = { - text: _str.replace(/^[:]?(?:no)?wrap:/, '').trim(), + text: _str.replace(/^:?(?:no)?wrap:/, '').trim(), wrap: - _str.match(/^[:]?wrap:/) !== null + _str.match(/^:?wrap:/) !== null ? true - : _str.match(/^[:]?nowrap:/) !== null + : _str.match(/^:?nowrap:/) !== null ? false : undefined, }; @@ -221,6 +219,7 @@ export const addNote = function (actor, placement, message) { }; // Coerce actor into a [to, from, ...] array + // eslint-disable-next-line unicorn/prefer-spread const actors = [].concat(actor, actor); notes.push(note); @@ -335,7 +334,7 @@ export const addDetails = function (actorId, text) { }; export const getActorProperty = function (actor, key) { - if (typeof actor !== 'undefined' && typeof actor.properties !== 'undefined') { + if (actor !== undefined && actor.properties !== undefined) { return actor.properties[key]; } @@ -343,7 +342,7 @@ export const getActorProperty = function (actor, key) { }; export const apply = function (param) { - if (param instanceof Array) { + if (Array.isArray(param)) { param.forEach(function (item) { apply(item); }); diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDetector.ts b/packages/mermaid/src/diagrams/sequence/sequenceDetector.ts index e68433255..52640b134 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDetector.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const sequenceDetector: DiagramDetector = (txt) => { return txt.match(/^\s*sequenceDiagram/) !== null; diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js index 5aebd1e3a..9422a5f37 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js @@ -130,7 +130,7 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility auto numbers expect(diagram.db.showSequenceNumbers()).toBe(false); }); it('should show sequence numbers when autonumber is enabled', function () { @@ -142,7 +142,7 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility auto numbers expect(diagram.db.showSequenceNumbers()).toBe(true); }); it('should handle a sequenceDiagram definition with a title:', function () { @@ -1871,7 +1871,7 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str1, diagram); - diagram.renderer.draw(str1, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + diagram.renderer.draw(str1, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility auto numbers expect(diagram.db.showSequenceNumbers()).toBe(true); const str2 = ` diff --git a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts index 19352ca72..738b86540 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts @@ -10,6 +10,7 @@ import assignWithDepth from '../../assignWithDepth'; import utils from '../../utils'; import { configureSvgSize } from '../../setupGraphViewbox'; import addSVGAccessibilityFields from '../../accessibility'; +import Diagram from '../../Diagram'; let conf = {}; @@ -90,7 +91,7 @@ export const bounds = { setConf(configApi.getConfig()); }, updateVal: function (obj, key, val, fun) { - if (typeof obj[key] === 'undefined') { + if (obj[key] === undefined) { obj[key] = val; } else { obj[key] = fun(val, obj[key]); @@ -100,8 +101,8 @@ export const bounds = { // eslint-disable-next-line @typescript-eslint/no-this-alias const _self = this; let cnt = 0; - /** @param {any} type */ - function updateFn(type) { + /** @param type - Either `activation` or `undefined` */ + function updateFn(type?: 'activation') { return function updateItemBounds(item) { cnt++; // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems @@ -200,15 +201,25 @@ export const bounds = { }, }; +/** Options for drawing a note in {@link drawNote} */ +interface NoteModel { + /** x axis start position */ + startx: number; + /** y axis position */ + starty: number; + /** the message to be shown */ + message: string; + /** Set this with a custom width to override the default configured width. */ + width: number; +} + /** * Draws an note in the diagram with the attached line * - * @param {any} elem - The diagram to draw to. - * @param {{ x: number; y: number; message: string; width: number }} noteModel - Startx: x axis - * start position, verticalPos: y axis position, messsage: the message to be shown, width: Set - * this with a custom width to override the default configured width. + * @param elem - The diagram to draw to. + * @param noteModel - Note model options. */ -const drawNote = function (elem, noteModel) { +const drawNote = function (elem: any, noteModel: NoteModel) { bounds.bumpVerticalPos(conf.boxMargin); noteModel.height = conf.boxMargin; noteModel.starty = bounds.getVerticalPos(); @@ -278,11 +289,11 @@ const actorFont = (cnf) => { * message so it can be drawn later. We do not draw the message at this point so the arrowhead can * be on top of the activation box. * - * @param {any} diagram - The parent of the message element - * @param {any} msgModel - The model containing fields describing a message - * @returns {number} LineStarty - The Y coordinate at which the message line starts + * @param _diagram - The parent of the message element. + * @param msgModel - The model containing fields describing a message + * @returns `lineStartY` - The Y coordinate at which the message line starts */ -const boundMessage = function (diagram, msgModel) { +function boundMessage(_diagram, msgModel): number { bounds.bumpVerticalPos(10); const { startx, stopx, message } = msgModel; const lines = common.splitBreaks(message).length; @@ -292,15 +303,15 @@ const boundMessage = function (diagram, msgModel) { bounds.bumpVerticalPos(lineHeight); - let lineStarty; + let lineStartY; let totalOffset = textDims.height - 10; const textWidth = textDims.width; if (startx === stopx) { - lineStarty = bounds.getVerticalPos() + totalOffset; + lineStartY = bounds.getVerticalPos() + totalOffset; if (!conf.rightAngles) { totalOffset += conf.boxMargin; - lineStarty = bounds.getVerticalPos() + totalOffset; + lineStartY = bounds.getVerticalPos() + totalOffset; } totalOffset += 30; const dx = Math.max(textWidth / 2, conf.width / 2); @@ -312,26 +323,26 @@ const boundMessage = function (diagram, msgModel) { ); } else { totalOffset += conf.boxMargin; - lineStarty = bounds.getVerticalPos() + totalOffset; - bounds.insert(startx, lineStarty - 10, stopx, lineStarty); + lineStartY = bounds.getVerticalPos() + totalOffset; + bounds.insert(startx, lineStartY - 10, stopx, lineStartY); } bounds.bumpVerticalPos(totalOffset); msgModel.height += totalOffset; msgModel.stopy = msgModel.starty + msgModel.height; bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy); - return lineStarty; -}; + return lineStartY; +} /** * Draws a message. Note that the bounds have previously been updated by boundMessage. * - * @param {any} diagram - The parent of the message element - * @param {any} msgModel - The model containing fields describing a message - * @param {number} lineStarty - The Y coordinate at which the message line starts - * @param diagObj + * @param diagram - The parent of the message element + * @param msgModel - The model containing fields describing a message + * @param lineStartY - The Y coordinate at which the message line starts + * @param diagObj - The diagram object. */ -const drawMessage = function (diagram, msgModel, lineStarty, diagObj) { +const drawMessage = function (diagram, msgModel, lineStartY: number, diagObj: Diagram) { const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel; const textDims = utils.calculateTextDimensions(message, messageFont(conf)); const textObj = svgDraw.getTextObj(); @@ -360,8 +371,8 @@ const drawMessage = function (diagram, msgModel, lineStarty, diagObj) { .append('path') .attr( 'd', - `M ${startx},${lineStarty} H ${startx + Math.max(conf.width / 2, textWidth / 2)} V ${ - lineStarty + 25 + `M ${startx},${lineStartY} H ${startx + Math.max(conf.width / 2, textWidth / 2)} V ${ + lineStartY + 25 } H ${startx}` ); } else { @@ -372,27 +383,27 @@ const drawMessage = function (diagram, msgModel, lineStarty, diagObj) { 'M ' + startx + ',' + - lineStarty + + lineStartY + ' C ' + (startx + 60) + ',' + - (lineStarty - 10) + + (lineStartY - 10) + ' ' + (startx + 60) + ',' + - (lineStarty + 30) + + (lineStartY + 30) + ' ' + startx + ',' + - (lineStarty + 20) + (lineStartY + 20) ); } } else { line = diagram.append('line'); line.attr('x1', startx); - line.attr('y1', lineStarty); + line.attr('y1', lineStartY); line.attr('x2', stopx); - line.attr('y2', lineStarty); + line.attr('y2', lineStartY); } // Make an SVG Container // Draw the line @@ -440,7 +451,7 @@ const drawMessage = function (diagram, msgModel, lineStarty, diagObj) { diagram .append('text') .attr('x', startx) - .attr('y', lineStarty + 4) + .attr('y', lineStartY + 4) .attr('font-family', 'sans-serif') .attr('font-size', '12px') .attr('text-anchor', 'middle') @@ -470,8 +481,8 @@ export const drawActors = function ( let prevWidth = 0; let prevMargin = 0; let maxHeight = 0; - for (let i = 0; i < actorKeys.length; i++) { - const actor = actors[actorKeys[i]]; + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; // Add some rendering data to the object actor.width = actor.width || conf.width; @@ -498,8 +509,8 @@ export const drawActors = function ( export const drawActorsPopup = function (diagram, actors, actorKeys, doc) { let maxHeight = 0; let maxWidth = 0; - for (let i = 0; i < actorKeys.length; i++) { - const actor = actors[actorKeys[i]]; + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; const minMenuWidth = getRequiredPopupWidth(actor); const menuDimensions = svgDraw.drawPopup( diagram, @@ -554,13 +565,6 @@ const activationBounds = function (actor, actors) { return [left, right]; }; -/** - * @param {any} loopWidths - * @param {any} msg - * @param {any} preMargin - * @param {any} postMargin - * @param {any} addLoopFn - */ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) { bounds.bumpVerticalPos(preMargin); let heightAdjust = postMargin; @@ -584,15 +588,15 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop /** * Draws a sequenceDiagram in the tag with id: id based on the graph definition in text. * - * @param {any} _text The text of the diagram - * @param {any} id The id of the diagram which will be used as a DOM element id¨ - * @param {any} _version Mermaid version from package.json - * @param {any} diagObj A stanard diagram containing the db and the text and type etc of the diagram + * @param _text - The text of the diagram + * @param id - The id of the diagram which will be used as a DOM element id¨ + * @param _version - Mermaid version from package.json + * @param diagObj - A standard diagram containing the db and the text and type etc of the diagram */ -export const draw = function (_text, id, _version, diagObj) { +export const draw = function (_text: string, id: string, _version: string, diagObj: Diagram) { const { securityLevel, sequence } = configApi.getConfig(); conf = sequence; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -632,10 +636,10 @@ export const draw = function (_text, id, _version, diagObj) { svgDraw.insertSequenceNumber(diagram); /** - * @param {any} msg - * @param {any} verticalPos + * @param msg - The message to draw. + * @param verticalPos - The vertical position of the message. */ - function activeEnd(msg, verticalPos) { + function activeEnd(msg: any, verticalPos: number) { const activationData = bounds.endActivation(msg); if (activationData.starty + 18 > verticalPos) { activationData.starty = verticalPos - 6; @@ -762,8 +766,11 @@ export const draw = function (_text, id, _version, diagObj) { case diagObj.db.LINETYPE.AUTONUMBER: sequenceIndex = msg.message.start || sequenceIndex; sequenceIndexStep = msg.message.step || sequenceIndexStep; - if (msg.message.visible) diagObj.db.enableSequenceNumbers(); - else diagObj.db.disableSequenceNumbers(); + if (msg.message.visible) { + diagObj.db.enableSequenceNumbers(); + } else { + diagObj.db.disableSequenceNumbers(); + } break; case diagObj.db.LINETYPE.CRITICAL_START: adjustLoopHeightForWrap( @@ -811,8 +818,8 @@ export const draw = function (_text, id, _version, diagObj) { msgModel.starty = bounds.getVerticalPos(); msgModel.sequenceIndex = sequenceIndex; msgModel.sequenceVisible = diagObj.db.showSequenceNumbers(); - const lineStarty = boundMessage(diagram, msgModel); - messagesToDraw.push({ messageModel: msgModel, lineStarty: lineStarty }); + const lineStartY = boundMessage(diagram, msgModel); + messagesToDraw.push({ messageModel: msgModel, lineStartY: lineStartY }); bounds.models.addMessage(msgModel); } catch (e) { log.error('error while drawing message', e); @@ -836,7 +843,7 @@ export const draw = function (_text, id, _version, diagObj) { } }); - messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStarty, diagObj)); + messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStartY, diagObj)); if (conf.mirrorActors) { // Draw actors below diagram @@ -907,12 +914,16 @@ export const draw = function (_text, id, _version, diagObj) { * It will enumerate each given message, and will determine its text width, in relation to the actor * it originates from, and destined to. * - * @param {any} actors - The actors map - * @param {Array} messages - A list of message objects to iterate - * @param diagObj - * @returns {any} + * @param actors - The actors map + * @param messages - A list of message objects to iterate + * @param diagObj - The diagram object. + * @returns The max message width of each actor. */ -const getMaxMessageWidthPerActor = function (actors, messages, diagObj) { +function getMaxMessageWidthPerActor( + actors: { [id: string]: any }, + messages: any[], + diagObj: Diagram +): { [id: string]: number } { const maxMessageWidthPerActor = {}; messages.forEach(function (msg) { @@ -1005,7 +1016,7 @@ const getMaxMessageWidthPerActor = function (actors, messages, diagObj) { log.debug('maxMessageWidthPerActor:', maxMessageWidthPerActor); return maxMessageWidthPerActor; -}; +} const getRequiredPopupWidth = function (actor) { let requiredPopupWidth = 0; @@ -1022,15 +1033,19 @@ const getRequiredPopupWidth = function (actor) { }; /** - * This will calculate the optimal margin for each given actor, for a given actor->messageWidth map. + * This will calculate the optimal margin for each given actor, + * for a given actor → messageWidth map. * * An actor's margin is determined by the width of the actor, the width of the largest message that * originates from it, and the configured conf.actorMargin. * - * @param {any} actors - The actors map to calculate margins for - * @param {any} actorToMessageWidth - A map of actor key -> max message width it holds + * @param actors - The actors map to calculate margins for + * @param actorToMessageWidth - A map of actor key → max message width it holds */ -const calculateActorMargins = function (actors, actorToMessageWidth) { +function calculateActorMargins( + actors: { [id: string]: any }, + actorToMessageWidth: ReturnType +) { let maxHeight = 0; Object.keys(actors).forEach((prop) => { const actor = actors[prop]; @@ -1071,7 +1086,7 @@ const calculateActorMargins = function (actors, actorToMessageWidth) { } return Math.max(maxHeight, conf.height); -}; +} const buildNoteModel = function (msg, actors, diagObj) { const startx = actors[msg.from].x; @@ -1165,7 +1180,7 @@ const buildMessageModel = function (msg, actors, diagObj) { const toBounds = activationBounds(msg.to, actors); const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0; const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1; - const allBounds = fromBounds.concat(toBounds); + const allBounds = [...fromBounds, ...toBounds]; const boundedWidth = Math.abs(toBounds[toIdx] - fromBounds[fromIdx]); if (msg.wrap && msg.message) { msg.message = utils.wrapLabel( diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index fd70871e0..ce1caea69 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -13,7 +13,7 @@ export const drawRect = function (elem, rectData) { rectElem.attr('rx', rectData.rx); rectElem.attr('ry', rectData.ry); - if (typeof rectData.class !== 'undefined') { + if (rectData.class !== undefined) { rectElem.attr('class', rectData.class); } @@ -31,7 +31,9 @@ const addPopupInteraction = (id, actorCnt) => { addFunction(() => { const arr = document.querySelectorAll(id); // This will be the case when running in sandboxed mode - if (arr.length === 0) return; + if (arr.length === 0) { + return; + } arr[0].addEventListener('mouseover', function () { popupMenuUpFunc('actor' + actorCnt + '_popup'); }); @@ -60,7 +62,7 @@ export const drawPopup = function (elem, actor, minMenuWidth, textAttrs, forceMe g.attr('display', displayValue); addPopupInteraction('#actor' + actorCnt + '_popup', actorCnt); var actorClass = ''; - if (typeof rectData.class !== 'undefined') { + if (rectData.class !== undefined) { actorClass = ' ' + rectData.class; } @@ -158,8 +160,8 @@ export const drawText = function (elem, textData) { let dy = 0; let yfunc = () => textData.y; if ( - typeof textData.valign !== 'undefined' && - typeof textData.textMargin !== 'undefined' && + textData.valign !== undefined && + textData.textMargin !== undefined && textData.textMargin > 0 ) { switch (textData.valign) { @@ -184,9 +186,9 @@ export const drawText = function (elem, textData) { } } if ( - typeof textData.anchor !== 'undefined' && - typeof textData.textMargin !== 'undefined' && - typeof textData.width !== 'undefined' + textData.anchor !== undefined && + textData.textMargin !== undefined && + textData.width !== undefined ) { switch (textData.anchor) { case 'left': @@ -212,12 +214,11 @@ export const drawText = function (elem, textData) { break; } } - for (let i = 0; i < lines.length; i++) { - let line = lines[i]; + for (let [i, line] of lines.entries()) { if ( - typeof textData.textMargin !== 'undefined' && + textData.textMargin !== undefined && textData.textMargin === 0 && - typeof textData.fontSize !== 'undefined' + textData.fontSize !== undefined ) { dy = i * textData.fontSize; } @@ -225,28 +226,28 @@ export const drawText = function (elem, textData) { const textElem = elem.append('text'); textElem.attr('x', textData.x); textElem.attr('y', yfunc()); - if (typeof textData.anchor !== 'undefined') { + if (textData.anchor !== undefined) { textElem .attr('text-anchor', textData.anchor) .attr('dominant-baseline', textData.dominantBaseline) .attr('alignment-baseline', textData.alignmentBaseline); } - if (typeof textData.fontFamily !== 'undefined') { + if (textData.fontFamily !== undefined) { textElem.style('font-family', textData.fontFamily); } - if (typeof textData.fontSize !== 'undefined') { + if (textData.fontSize !== undefined) { textElem.style('font-size', textData.fontSize); } - if (typeof textData.fontWeight !== 'undefined') { + if (textData.fontWeight !== undefined) { textElem.style('font-weight', textData.fontWeight); } - if (typeof textData.fill !== 'undefined') { + if (textData.fill !== undefined) { textElem.attr('fill', textData.fill); } - if (typeof textData.class !== 'undefined') { + if (textData.class !== undefined) { textElem.attr('class', textData.class); } - if (typeof textData.dy !== 'undefined') { + if (textData.dy !== undefined) { textElem.attr('dy', textData.dy); } else if (dy !== 0) { textElem.attr('dy', dy); @@ -255,7 +256,7 @@ export const drawText = function (elem, textData) { if (textData.tspan) { const span = textElem.append('tspan'); span.attr('x', textData.x); - if (typeof textData.fill !== 'undefined') { + if (textData.fill !== undefined) { span.attr('fill', textData.fill); } span.text(line); @@ -263,8 +264,8 @@ export const drawText = function (elem, textData) { textElem.text(line); } if ( - typeof textData.valign !== 'undefined' && - typeof textData.textMargin !== 'undefined' && + textData.valign !== undefined && + textData.textMargin !== undefined && textData.textMargin > 0 ) { textHeight += (textElem._groups || textElem)[0][0].getBBox().height; @@ -322,7 +323,9 @@ export const drawLabel = function (elem, txtObject) { let actorCnt = -1; export const fixLifeLineHeights = (diagram, bounds) => { - if (!diagram.selectAll) return; + if (!diagram.selectAll) { + return; + } diagram .selectAll('.actor-line') .attr('class', '200') @@ -509,7 +512,7 @@ export const anchorElement = function (elem) { * * @param {any} elem - Element to append activation rect. * @param {any} bounds - Activation box bounds. - * @param {any} verticalPos - Precise y cooridnate of bottom activation box edge. + * @param {any} verticalPos - Precise y coordinate of bottom activation box edge. * @param {any} conf - Sequence diagram config object. * @param {any} actorActivations - Number of activations on the actor. */ @@ -527,10 +530,10 @@ export const drawActivation = function (elem, bounds, verticalPos, conf, actorAc /** * Draws a loop in the diagram * - * @param {any} elem - Elemenet to append the loop to. + * @param {any} elem - Element to append the loop to. * @param {any} loopModel - LoopModel of the given loop. * @param {any} labelText - Text within the loop. - * @param {any} conf - Diagrom configuration + * @param {any} conf - Diagram configuration * @returns {any} */ export const drawLoop = function (elem, loopModel, labelText, conf) { @@ -557,7 +560,7 @@ export const drawLoop = function (elem, loopModel, labelText, conf) { drawLoopLine(loopModel.stopx, loopModel.starty, loopModel.stopx, loopModel.stopy); drawLoopLine(loopModel.startx, loopModel.stopy, loopModel.stopx, loopModel.stopy); drawLoopLine(loopModel.startx, loopModel.starty, loopModel.startx, loopModel.stopy); - if (typeof loopModel.sections !== 'undefined') { + if (loopModel.sections !== undefined) { loopModel.sections.forEach(function (item) { drawLoopLine(loopModel.startx, item.y, loopModel.stopx, item.y).style( 'stroke-dasharray', @@ -597,7 +600,7 @@ export const drawLoop = function (elem, loopModel, labelText, conf) { let textElem = drawText(g, txt); - if (typeof loopModel.sectionTitles !== 'undefined') { + if (loopModel.sectionTitles !== undefined) { loopModel.sectionTitles.forEach(function (item, idx) { if (item.message) { txt.text = item.message; @@ -748,7 +751,7 @@ export const insertSequenceNumber = function (elem) { // .style("fill", '#f00'); }; /** - * Setup arrow head and define the marker. The result is appended to the svg. + * Setup cross head and define the marker. The result is appended to the svg. * * @param {any} elem */ @@ -760,26 +763,16 @@ export const insertArrowCrossHead = function (elem) { .attr('markerWidth', 15) .attr('markerHeight', 8) .attr('orient', 'auto') - .attr('refX', 16) - .attr('refY', 4); - - // The arrow - marker - .append('path') - .attr('fill', 'black') - .attr('stroke', '#000000') - .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 9,2 V 6 L16,4 Z'); - + .attr('refX', 4) + .attr('refY', 5); // The cross marker .append('path') .attr('fill', 'none') .attr('stroke', '#000000') .style('stroke-dasharray', '0, 0') - .attr('stroke-width', '1px') - .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7'); + .attr('stroke-width', '1pt') + .attr('d', 'M 1,2 L 6,7 M 6,2 L 1,7'); // this is actual shape for arrowhead }; diff --git a/packages/mermaid/src/diagrams/state/parser/state-style.spec.js b/packages/mermaid/src/diagrams/state/parser/state-style.spec.js new file mode 100644 index 000000000..75ecb4b13 --- /dev/null +++ b/packages/mermaid/src/diagrams/state/parser/state-style.spec.js @@ -0,0 +1,210 @@ +import stateDb from '../stateDb'; +import stateDiagram from './stateDiagram'; +import { setConfig } from '../../../config'; + +setConfig({ + securityLevel: 'strict', +}); + +describe('ClassDefs and classes when parsing a State diagram', () => { + beforeEach(function () { + stateDiagram.parser.yy = stateDb; + stateDiagram.parser.yy.clear(); + }); + + describe('class for a state (classDef)', () => { + describe('defining (classDef)', () => { + it('has "classDef" as a keyword, an id, and can set a css style attribute', function () { + stateDiagram.parser.parse('stateDiagram-v2\n classDef exampleClass background:#bbb;'); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const styleClasses = stateDb.getClasses(); + expect(styleClasses['exampleClass'].styles.length).toEqual(1); + expect(styleClasses['exampleClass'].styles[0]).toEqual('background:#bbb'); + }); + + it('can define multiple attributes separated by commas', function () { + stateDiagram.parser.parse( + 'stateDiagram-v2\n classDef exampleClass background:#bbb, font-weight:bold, font-style:italic;' + ); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const styleClasses = stateDb.getClasses(); + expect(styleClasses['exampleClass'].styles.length).toEqual(3); + expect(styleClasses['exampleClass'].styles[0]).toEqual('background:#bbb'); + expect(styleClasses['exampleClass'].styles[1]).toEqual('font-weight:bold'); + expect(styleClasses['exampleClass'].styles[2]).toEqual('font-style:italic'); + }); + + // need to look at what the lexer is doing + it('an attribute can have a dot in the style', function () { + stateDiagram.parser.parse( + 'stateDiagram-v2\n classDef exampleStyleClass background:#bbb,border:1.5px solid red;' + ); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const classes = stateDiagram.parser.yy.getClasses(); + expect(classes['exampleStyleClass'].styles.length).toBe(2); + expect(classes['exampleStyleClass'].styles[0]).toBe('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toBe('border:1.5px solid red'); + }); + + it('an attribute can have a space in the style', function () { + stateDiagram.parser.parse( + 'stateDiagram-v2\n classDef exampleStyleClass background: #bbb,border:1.5px solid red;' + ); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const classes = stateDiagram.parser.yy.getClasses(); + expect(classes['exampleStyleClass'].styles.length).toBe(2); + expect(classes['exampleStyleClass'].styles[0]).toBe('background: #bbb'); + expect(classes['exampleStyleClass'].styles[1]).toBe('border:1.5px solid red'); + }); + }); + + describe('applying to states in the diagram', () => { + it('can apply a class to a state', function () { + let diagram = ''; + diagram += 'stateDiagram-v2\n' + '\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;\n'; + diagram += 'a --> b '; + diagram += 'class a exampleStyleClass'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const classes = stateDb.getClasses(); + expect(classes['exampleStyleClass'].styles.length).toEqual(2); + expect(classes['exampleStyleClass'].styles[0]).toEqual('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toEqual('border:1px solid red'); + + const state_a = stateDb.getState('a'); + expect(state_a.classes.length).toEqual(1); + expect(state_a.classes[0]).toEqual('exampleStyleClass'); + }); + + it('can be applied to a state with an id containing _', function () { + let diagram = ''; + + diagram += 'stateDiagram-v2\n' + '\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;\n'; + diagram += 'a_a --> b_b' + '\n'; + diagram += 'class a_a exampleStyleClass'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const classes = stateDiagram.parser.yy.getClasses(); + expect(classes['exampleStyleClass'].styles.length).toBe(2); + expect(classes['exampleStyleClass'].styles[0]).toBe('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toBe('border:1px solid red'); + + const state_a_a = stateDiagram.parser.yy.getState('a_a'); + expect(state_a_a.classes.length).toEqual(1); + expect(state_a_a.classes[0]).toEqual('exampleStyleClass'); + }); + + describe('::: syntax', () => { + it('can be applied to a state using ::: syntax', () => { + let diagram = ''; + diagram += 'stateDiagram-v2\n' + '\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;' + '\n'; + diagram += 'a --> b:::exampleStyleClass' + '\n'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const states = stateDiagram.parser.yy.getStates(); + const classes = stateDiagram.parser.yy.getClasses(); + + expect(classes['exampleStyleClass'].styles.length).toEqual(2); + expect(classes['exampleStyleClass'].styles[0]).toEqual('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toEqual('border:1px solid red'); + + expect(states['b'].classes[0]).toEqual('exampleStyleClass'); + }); + + it('can be applied to a [*] state', () => { + let diagram = ''; + diagram += 'stateDiagram-v2\n\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;\n'; + diagram += '[*]:::exampleStyleClass --> b\n'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const states = stateDiagram.parser.yy.getStates(); + const classes = stateDiagram.parser.yy.getClasses(); + + expect(classes['exampleStyleClass'].styles.length).toEqual(2); + expect(classes['exampleStyleClass'].styles[0]).toEqual('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toEqual('border:1px solid red'); + + expect(states['root_start'].classes[0]).toEqual('exampleStyleClass'); + }); + + it('can be applied to a comma separated list of states', function () { + let diagram = ''; + diagram += 'stateDiagram-v2\n\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;\n'; + diagram += 'a-->b\n'; + diagram += 'class a,b exampleStyleClass'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + let classes = stateDiagram.parser.yy.getClasses(); + let states = stateDiagram.parser.yy.getStates(); + + expect(classes['exampleStyleClass'].styles.length).toEqual(2); + expect(classes['exampleStyleClass'].styles[0]).toEqual('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toEqual('border:1px solid red'); + expect(states['a'].classes[0]).toEqual('exampleStyleClass'); + expect(states['b'].classes[0]).toEqual('exampleStyleClass'); + }); + + it('a comma separated list of states may or may not have spaces after commas', function () { + let diagram = ''; + diagram += 'stateDiagram-v2\n\n'; + diagram += 'classDef exampleStyleClass background:#bbb,border:1px solid red;\n'; + diagram += 'a-->b\n'; + diagram += 'class a,b,c, d, e exampleStyleClass'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + const classes = stateDiagram.parser.yy.getClasses(); + const states = stateDiagram.parser.yy.getStates(); + + expect(classes['exampleStyleClass'].styles.length).toEqual(2); + expect(classes['exampleStyleClass'].styles[0]).toEqual('background:#bbb'); + expect(classes['exampleStyleClass'].styles[1]).toEqual('border:1px solid red'); + + const statesList = ['a', 'b', 'c', 'd', 'e']; + statesList.forEach((stateId) => { + expect(states[stateId].classes[0]).toEqual('exampleStyleClass'); + }); + }); + }); + + describe('comments parsing', () => { + it('working inside states', function () { + let diagram = ''; + diagram += 'stateDiagram-v2\n\n'; + diagram += '[*] --> Moving\n'; + diagram += 'Moving --> Still\n'; + diagram += 'Moving --> Crash\n'; + diagram += 'state Moving {\n'; + diagram += '%% comment inside state\n'; + diagram += 'slow --> fast\n'; + diagram += '}\n'; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const states = stateDiagram.parser.yy.getStates(); + + expect(states['Moving'].doc.length).toEqual(1); + }); + }); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison index e2a984ca1..67073210b 100644 --- a/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison +++ b/packages/mermaid/src/diagrams/state/parser/stateDiagram.jison @@ -23,6 +23,10 @@ %x acc_title %x acc_descr %x acc_descr_multiline +%x CLASSDEF +%x CLASSDEFID +%x CLASS +%x CLASS_STYLE %x NOTE %x NOTE_ID %x NOTE_TEXT @@ -39,6 +43,8 @@ %% +"default" return 'DEFAULT'; + .*direction\s+TB[^\n]* return 'direction_tb'; .*direction\s+BT[^\n]* return 'direction_bt'; .*direction\s+RL[^\n]* return 'direction_rl'; @@ -69,6 +75,20 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [\}] { this.popState(); } [^\}]* return "acc_descr_multiline_value"; +"classDef"\s+ { this.pushState('CLASSDEF'); return 'classDef'; } +DEFAULT\s+ { this.popState(); this.pushState('CLASSDEFID'); return 'DEFAULT_CLASSDEF_ID' } +\w+\s+ { this.popState(); this.pushState('CLASSDEFID'); return 'CLASSDEF_ID' } +[^\n]* { this.popState(); return 'CLASSDEF_STYLEOPTS' } + +"class"\s+ { this.pushState('CLASS'); return 'class'; } +(\w+)+((","\s*\w+)*) { this.popState(); this.pushState('CLASS_STYLE'); return 'CLASSENTITY_IDS' } +[^\n]* { this.popState(); return 'STYLECLASS' } + +"scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; } +\d+ return 'WIDTH'; +\s+"width" {this.popState();} + + "state"\s+ { /*console.log('Starting STATE zxzx'+yy.getDirection());*/this.pushState('STATE'); } .*"<>" {this.popState();yytext=yytext.slice(0,-8).trim(); /*console.warn('Fork Fork: ',yytext);*/return 'FORK';} .*"<>" {this.popState();yytext=yytext.slice(0,-8).trim();/*console.warn('Fork Join: ',yytext);*/return 'JOIN';} @@ -89,6 +109,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [^\n\s\{]+ {/*console.log('COMPOSIT_STATE', yytext);*/return 'COMPOSIT_STATE';} \n {this.popState();} \{ {this.popState();this.pushState('struct'); /*console.log('begin struct', yytext);*/return 'STRUCT_START';} +\%\%(?!\{)[^\n]* /* skip comments inside state*/ \} { /*console.log('Ending struct');*/ this.popState(); return 'STRUCT_STOP';}} [\n] /* nothing */ @@ -111,10 +132,12 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili [^:\n\s\-\{]+ { /*console.log('=>ID=',yytext);*/ return 'ID';} // \s*":"[^\+\->:\n;]+ { yytext = yytext.trim(); /*console.log('Descr = ', yytext);*/ return 'DESCR'; } \s*":"[^:\n;]+ { yytext = yytext.trim(); /*console.log('Descr = ', yytext);*/ return 'DESCR'; } + "-->" return '-->'; -"--" return 'CONCURRENT'; -<> return 'NL'; -. return 'INVALID'; +"--" return 'CONCURRENT'; +":::" return 'STYLE_SEPARATOR'; +<> return 'NL'; +. return 'INVALID'; /lex @@ -124,20 +147,23 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili %% /* language grammar */ +/* $$ is the value of the symbol being evaluated (= what is to the left of the : in the rule */ + start : SPACE start | NL start | directive start - | SD document { /*console.warn('Root document', $2);*/ yy.setRootDoc($2);return $2; } + | SD document { /* console.log('--> Root document', $2); */ yy.setRootDoc($2); return $2; } ; document - : /* empty */ { $$ = [] } + : /* empty */ { /*console.log('empty document'); */ $$ = [] } | document line { - if($2!='nl'){ - $1.push($2);$$ = $1 + if($2 !='nl'){ + /* console.log(' document: 1: ', $1, ' pushing 2: ', $2); */ + $1.push($2); $$ = $1 } - // console.warn('Got document',$1, $2); + /* console.log('Got document',$1, $2); */ } ; @@ -148,24 +174,34 @@ line ; statement - : idStatement { /*console.warn('got id and descr', $1);*/$$={ stmt: 'state', id: $1, type: 'default', description: ''};} - | idStatement DESCR { /*console.warn('got id and descr', $1, $2.trim());*/$$={ stmt: 'state', id: $1, type: 'default', description: yy.trimColon($2)};} + : classDefStatement + | cssClassStatement + | idStatement { /* console.log('got id', $1); */ + $$=$1; + } + | idStatement DESCR { + const stateStmt = $1; + stateStmt.description = yy.trimColon($2); + $$ = stateStmt; + } | idStatement '-->' idStatement - { - /*console.warn('got id', $1);yy.addRelation($1, $3);*/ - $$={ stmt: 'relation', state1: { stmt: 'state', id: $1, type: 'default', description: '' }, state2:{ stmt: 'state', id: $3 ,type: 'default', description: ''}}; - } + { + /* console.info('got ids: 1: ', $1, ' 2:', $2,' 3: ', $3); */ + // console.log(' idStatement --> idStatement : state1 =', $1, ' state2 =', $3); + $$={ stmt: 'relation', state1: $1, state2: $3}; + } | idStatement '-->' idStatement DESCR - { - /*yy.addRelation($1, $3, $4.substr(1).trim());*/ - $$={ stmt: 'relation', state1: { stmt: 'state', id: $1, type: 'default', description: '' }, state2:{ stmt: 'state', id: $3 ,type: 'default', description: ''}, description: $4.substr(1).trim()}; - } + { + const relDescription = yy.trimColon($4); + /* console.log(' idStatement --> idStatement DESCR : state1 =', $1, ' state2stmt =', $3, ' description: ', relDescription); */ + $$={ stmt: 'relation', state1: $1, state2: $3, description: relDescription}; + } | HIDE_EMPTY | scale WIDTH | COMPOSIT_STATE | COMPOSIT_STATE STRUCT_START document STRUCT_STOP { - /* console.warn('Adding document for state without id ', $1);*/ + /* console.log('Adding document for state without id ', $1); */ $$={ stmt: 'state', id: $1, type: 'default', description: '', doc: $3 } } | STATE_DESCR AS ID { @@ -181,7 +217,7 @@ statement } | STATE_DESCR AS ID STRUCT_START document STRUCT_STOP { - // console.warn('Adding document for state with id zxzx', $3, $4, yy.getDirection()); yy.addDocument($3); + /* console.log('Adding document for state with id zxzx', $3, $4, yy.getDirection()); yy.addDocument($3);*/ $$={ stmt: 'state', id: $3, type: 'default', description: $1, doc: $5 } } | FORK { @@ -208,6 +244,23 @@ statement | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } ; + +classDefStatement + : classDef CLASSDEF_ID CLASSDEF_STYLEOPTS { + $$ = { stmt: 'classDef', id: $2.trim(), classes: $3.trim() }; + } + | classDef DEFAULT CLASSDEF_STYLEOPTS { + $$ = { stmt: 'classDef', id: $2.trim(), classes: $3.trim() }; + } + ; + +cssClassStatement + : class CLASSENTITY_IDS STYLECLASS { + //console.log('apply class: id(s): ',$2, ' style class: ', $3); + $$={ stmt: 'applyClass', id: $2.trim(), styleClass: $3.trim() }; + } + ; + directive : openDirective typeDirective closeDirective | openDirective typeDirective ':' argDirective closeDirective @@ -229,8 +282,22 @@ eol ; idStatement - : ID {$$=$1;} - | EDGE_STATE {$$=$1;} + : ID + { /* console.log('idStatement id: ', $1); */ + $$={ stmt: 'state', id: $1.trim(), type: 'default', description: '' }; + } + | EDGE_STATE + { /* console.log('idStatement id: ', $1); */ + $$={ stmt: 'state', id: $1.trim(), type: 'default', description: '' }; + } + | ID STYLE_SEPARATOR ID + { /*console.log('idStatement ID STYLE_SEPARATOR ID'); */ + $$={ stmt: 'state', id: $1.trim(), classes: [$3.trim()], type: 'default', description: '' }; + } + | EDGE_STATE STYLE_SEPARATOR ID + { /*console.log('idStatement EDGE_STATE STYLE_SEPARATOR ID'); */ + $$={ stmt: 'state', id: $1.trim(), classes: [$3.trim()], type: 'default', description: '' }; + } ; notePosition diff --git a/packages/mermaid/src/diagrams/state/shapes.js b/packages/mermaid/src/diagrams/state/shapes.js index e2286bb51..0a495e56c 100644 --- a/packages/mermaid/src/diagrams/state/shapes.js +++ b/packages/mermaid/src/diagrams/state/shapes.js @@ -137,7 +137,7 @@ export const drawDescrState = (g, stateDef) => { /** Adds the creates a box around the existing content and adds a panel for the id on top of the content. */ /** - * Function that creates an title row and a frame around a substate for a composit state diagram. + * Function that creates an title row and a frame around a substate for a composite state diagram. * The function returns a new d3 svg object with updated width and height properties; * * @param {any} g The d3 svg object for the substate to framed @@ -178,7 +178,7 @@ export const addTitleAndBox = (g, stateDef, altBkg) => { // descrLine.attr('x2', graphBox.width + getConfig().state.padding); if (stateDef.doc) { - // cnsole.warn( + // console.warn( // stateDef.id, // 'orgX: ', // orgX, @@ -197,10 +197,8 @@ export const addTitleAndBox = (g, stateDef, altBkg) => { if (titleWidth > orgWidth) { startX = (orgWidth - width) / 2 + pad; } - if (Math.abs(orgX - graphBox.x) < pad) { - if (titleWidth > orgWidth) { - startX = orgX - (titleWidth - orgWidth) / 2; - } + if (Math.abs(orgX - graphBox.x) < pad && titleWidth > orgWidth) { + startX = orgX - (titleWidth - orgWidth) / 2; } const lineY = 1 - getConfig().state.textHeight; @@ -217,7 +215,9 @@ export const addTitleAndBox = (g, stateDef, altBkg) => { .attr('rx', '0'); title.attr('x', startX + pad); - if (titleWidth <= orgWidth) title.attr('x', orgX + (width - dblPad) / 2 - titleWidth / 2 + pad); + if (titleWidth <= orgWidth) { + title.attr('x', orgX + (width - dblPad) / 2 - titleWidth / 2 + pad); + } // Title background g.insert('rect', ':first-child') @@ -299,7 +299,7 @@ export const drawText = function (elem, textData) { textElem.attr('y', textData.y); textElem.style('text-anchor', textData.anchor); textElem.attr('fill', textData.fill); - if (typeof textData.class !== 'undefined') { + if (textData.class !== undefined) { textElem.attr('class', textData.class); } @@ -379,14 +379,27 @@ export const drawState = function (elem, stateDef) { const g = elem.append('g').attr('id', id).attr('class', 'stateGroup'); - if (stateDef.type === 'start') drawStartState(g); - if (stateDef.type === 'end') drawEndState(g); - if (stateDef.type === 'fork' || stateDef.type === 'join') drawForkJoinState(g, stateDef); - if (stateDef.type === 'note') drawNote(stateDef.note.text, g); - if (stateDef.type === 'divider') drawDivider(g); - if (stateDef.type === 'default' && stateDef.descriptions.length === 0) + if (stateDef.type === 'start') { + drawStartState(g); + } + if (stateDef.type === 'end') { + drawEndState(g); + } + if (stateDef.type === 'fork' || stateDef.type === 'join') { + drawForkJoinState(g, stateDef); + } + if (stateDef.type === 'note') { + drawNote(stateDef.note.text, g); + } + if (stateDef.type === 'divider') { + drawDivider(g); + } + if (stateDef.type === 'default' && stateDef.descriptions.length === 0) { drawSimpleState(g, stateDef); - if (stateDef.type === 'default' && stateDef.descriptions.length > 0) drawDescrState(g, stateDef); + } + if (stateDef.type === 'default' && stateDef.descriptions.length > 0) { + drawDescrState(g, stateDef); + } const stateBox = g.node().getBBox(); stateInfo.width = stateBox.width + 2 * getConfig().state.padding; @@ -449,7 +462,7 @@ export const drawEdge = function (elem, path, relation) { 'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')' ); - if (typeof relation.title !== 'undefined') { + if (relation.title !== undefined) { const label = elem.append('g').attr('class', 'stateLabel'); const { x, y } = utils.calcLabelPosition(path.points); diff --git a/packages/mermaid/src/diagrams/state/stateCommon.ts b/packages/mermaid/src/diagrams/state/stateCommon.ts new file mode 100644 index 000000000..2df19eee8 --- /dev/null +++ b/packages/mermaid/src/diagrams/state/stateCommon.ts @@ -0,0 +1,32 @@ +/** + * Constants common to all State Diagram code + */ + +// default diagram direction +export const DEFAULT_DIAGRAM_DIRECTION = 'LR'; + +// default direction for any nested documents (composites) +export const DEFAULT_NESTED_DOC_DIR = 'TB'; + +// parsed statement type for a state +export const STMT_STATE = 'state'; +// parsed statement type for a relation +export const STMT_RELATION = 'relation'; +// parsed statement type for a classDef +export const STMT_CLASSDEF = 'classDef'; +// parsed statement type for applyClass +export const STMT_APPLYCLASS = 'applyClass'; + +export const DEFAULT_STATE_TYPE = 'default'; +export const DIVIDER_TYPE = 'divider'; + +export default { + DEFAULT_DIAGRAM_DIRECTION, + DEFAULT_NESTED_DOC_DIR, + STMT_STATE, + STMT_RELATION, + STMT_CLASSDEF, + STMT_APPLYCLASS, + DEFAULT_STATE_TYPE, + DIVIDER_TYPE, +}; diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index 96f92af8a..991aba078 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -9,10 +9,73 @@ import { getAccDescription, setAccDescription, clear as commonClear, + setDiagramTitle, + getDiagramTitle, } from '../../commonDb'; -const clone = (o) => JSON.parse(JSON.stringify(o)); +import { + DEFAULT_DIAGRAM_DIRECTION, + STMT_STATE, + STMT_RELATION, + STMT_CLASSDEF, + STMT_APPLYCLASS, + DEFAULT_STATE_TYPE, + DIVIDER_TYPE, +} from './stateCommon'; + +const START_NODE = '[*]'; +const START_TYPE = 'start'; +const END_NODE = START_NODE; +const END_TYPE = 'end'; + +const COLOR_KEYWORD = 'color'; +const FILL_KEYWORD = 'fill'; +const BG_FILL = 'bgFill'; +const STYLECLASS_SEP = ','; + +/** + * Returns a new list of classes. + * In the future, this can be replaced with a class common to all diagrams. + * ClassDef information = { id: id, styles: [], textStyles: [] } + * + * @returns {{}} + */ +function newClassesList() { + return {}; +} + +let direction = DEFAULT_DIAGRAM_DIRECTION; let rootDoc = []; +let classes = newClassesList(); // style classes defined by a classDef + +const newDoc = () => { + return { + relations: [], + states: {}, + documents: {}, + }; +}; +let documents = { + root: newDoc(), +}; + +let currentDocument = documents.root; +let startEndCount = 0; +let dividerCnt = 0; + +export const lineType = { + LINE: 0, + DOTTED_LINE: 1, +}; + +export const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3, +}; + +const clone = (o) => JSON.parse(JSON.stringify(o)); export const parseDirective = function (statement, context, type) { mermaidAPI.parseDirective(this, statement, context, type); @@ -27,24 +90,22 @@ const setRootDoc = (o) => { const getRootDoc = () => rootDoc; const docTranslator = (parent, node, first) => { - if (node.stmt === 'relation') { + if (node.stmt === STMT_RELATION) { docTranslator(parent, node.state1, true); docTranslator(parent, node.state2, false); } else { - if (node.stmt === 'state') { - if (node.id === '[*]') { - node.id = first ? parent.id + '_start' : parent.id + '_end'; - node.start = first; - } + if (node.stmt === STMT_STATE && node.id === '[*]') { + node.id = first ? parent.id + '_start' : parent.id + '_end'; + node.start = first; } if (node.doc) { const doc = []; // Check for concurrency - let i = 0; let currentDoc = []; + let i; for (i = 0; i < node.doc.length; i++) { - if (node.doc[i].type === 'divider') { + if (node.doc[i].type === DIVIDER_TYPE) { // debugger; const newNode = clone(node.doc[i]); newNode.doc = clone(currentDoc); @@ -58,7 +119,7 @@ const docTranslator = (parent, node, first) => { // If any divider was encountered if (doc.length > 0 && currentDoc.length > 0) { const newNode = { - stmt: 'state', + stmt: STMT_STATE, id: generateId(), type: 'divider', doc: clone(currentDoc), @@ -77,6 +138,17 @@ const getRootDocV2 = () => { // Here }; +/** + * Convert all of the statements (stmts) that were parsed into states and relationships. + * This is done because a state diagram may have nested sections, + * where each section is a 'document' and has its own set of statements. + * Ex: the section within a fork has its own statements, and incoming and outgoing statements + * refer to the fork as a whole (document). + * See the parser grammar: the definition of a document is a document then a 'line', where a line can be a statement. + * This will push the statement into the the list of statements for the current document. + * + * @param _doc + */ const extract = (_doc) => { // const res = { states: [], relations: [] }; let doc; @@ -95,48 +167,66 @@ const extract = (_doc) => { log.info('Extract', doc); doc.forEach((item) => { - if (item.stmt === 'state') { - addState(item.id, item.type, item.doc, item.description, item.note); - } - if (item.stmt === 'relation') { - addRelation(item.state1.id, item.state2.id, item.description); + switch (item.stmt) { + case STMT_STATE: + addState( + item.id, + item.type, + item.doc, + item.description, + item.note, + item.classes, + item.styles, + item.textStyles + ); + break; + case STMT_RELATION: + addRelation(item.state1, item.state2, item.description); + break; + case STMT_CLASSDEF: + addStyleClass(item.id, item.classes); + break; + case STMT_APPLYCLASS: + setCssClass(item.id, item.styleClass); + break; } }); }; -const newDoc = () => { - return { - relations: [], - states: {}, - documents: {}, - }; -}; - -let documents = { - root: newDoc(), -}; - -let currentDocument = documents.root; - -let startCnt = 0; - /** * Function called by parser when a node definition has been found. * - * @param {any} id - * @param {any} type - * @param {any} doc - * @param {any} descr - * @param {any} note + * @param {null | string} id + * @param {null | string} type + * @param {null | string} doc + * @param {null | string | string[]} descr - description for the state. Can be a string or a list or strings + * @param {null | string} note + * @param {null | string | string[]} classes - class styles to apply to this state. Can be a string (1 style) or an array of styles. If it's just 1 class, convert it to an array of that 1 class. + * @param {null | string | string[]} styles - styles to apply to this state. Can be a string (1 style) or an array of styles. If it's just 1 style, convert it to an array of that 1 style. + * @param {null | string | string[]} textStyles - text styles to apply to this state. Can be a string (1 text test) or an array of text styles. If it's just 1 text style, convert it to an array of that 1 text style. */ -export const addState = function (id, type, doc, descr, note) { - if (typeof currentDocument.states[id] === 'undefined') { +export const addState = function ( + id, + type = DEFAULT_STATE_TYPE, + doc = null, + descr = null, + note = null, + classes = null, + styles = null, + textStyles = null +) { + // add the state if needed + if (currentDocument.states[id] === undefined) { + log.info('Adding state ', id, descr); currentDocument.states[id] = { id: id, descriptions: [], type, doc, note, + classes: [], + styles: [], + textStyles: [], }; } else { if (!currentDocument.states[id].doc) { @@ -146,9 +236,12 @@ export const addState = function (id, type, doc, descr, note) { currentDocument.states[id].type = type; } } + if (descr) { - log.info('Adding state ', id, descr); - if (typeof descr === 'string') addDescription(id, descr.trim()); + log.info('Setting state description', id, descr); + if (typeof descr === 'string') { + addDescription(id, descr.trim()); + } if (typeof descr === 'object') { descr.forEach((des) => addDescription(id, des.trim())); @@ -162,6 +255,24 @@ export const addState = function (id, type, doc, descr, note) { configApi.getConfig() ); } + + if (classes) { + log.info('Setting state classes', id, classes); + const classesList = typeof classes === 'string' ? [classes] : classes; + classesList.forEach((klass) => setCssClass(id, klass.trim())); + } + + if (styles) { + log.info('Setting state styles', id, styles); + const stylesList = typeof styles === 'string' ? [styles] : styles; + stylesList.forEach((style) => setStyle(id, style.trim())); + } + + if (textStyles) { + log.info('Setting state styles', id, styles); + const textStylesList = typeof textStyles === 'string' ? [textStyles] : textStyles; + textStylesList.forEach((textStyle) => setTextStyle(id, textStyle.trim())); + } }; export const clear = function (saveCommon) { @@ -170,10 +281,9 @@ export const clear = function (saveCommon) { }; currentDocument = documents.root; - currentDocument = documents.root; - - startCnt = 0; - classes = []; + // number of start and end nodes; used to construct ids + startEndCount = 0; + classes = newClassesList(); if (!saveCommon) { commonClear(); } @@ -193,36 +303,134 @@ export const getRelations = function () { return currentDocument.relations; }; -export const addRelation = function (_id1, _id2, title) { - let id1 = _id1; - let id2 = _id2; - let type1 = 'default'; - let type2 = 'default'; - if (_id1 === '[*]') { - startCnt++; - id1 = 'start' + startCnt; - type1 = 'start'; +/** + * If the id is a start node ( [*] ), then return a new id constructed from + * the start node name and the current start node count. + * else return the given id + * + * @param {string} id + * @returns {string} - the id (original or constructed) + */ +function startIdIfNeeded(id = '') { + let fixedId = id; + if (id === START_NODE) { + startEndCount++; + fixedId = `${START_TYPE}${startEndCount}`; } - if (_id2 === '[*]') { - id2 = 'end' + startCnt; - type2 = 'end'; + return fixedId; +} + +/** + * If the id is a start node ( [*] ), then return the start type ('start') + * else return the given type + * + * @param {string} id + * @param {string} type + * @returns {string} - the type that should be used + */ +function startTypeIfNeeded(id = '', type = DEFAULT_STATE_TYPE) { + return id === START_NODE ? START_TYPE : type; +} + +/** + * If the id is an end node ( [*] ), then return a new id constructed from + * the end node name and the current start_end node count. + * else return the given id + * + * @param {string} id + * @returns {string} - the id (original or constructed) + */ +function endIdIfNeeded(id = '') { + let fixedId = id; + if (id === END_NODE) { + startEndCount++; + fixedId = `${END_TYPE}${startEndCount}`; } - addState(id1, type1); - addState(id2, type2); + return fixedId; +} + +/** + * If the id is an end node ( [*] ), then return the end type + * else return the given type + * + * @param {string} id + * @param {string} type + * @returns {string} - the type that should be used + */ +function endTypeIfNeeded(id = '', type = DEFAULT_STATE_TYPE) { + return id === END_NODE ? END_TYPE : type; +} + +/** + * + * @param item1 + * @param item2 + * @param relationTitle + */ +export function addRelationObjs(item1, item2, relationTitle) { + let id1 = startIdIfNeeded(item1.id); + let type1 = startTypeIfNeeded(item1.id, item1.type); + let id2 = startIdIfNeeded(item2.id); + let type2 = startTypeIfNeeded(item2.id, item2.type); + + addState( + id1, + type1, + item1.doc, + item1.description, + item1.note, + item1.classes, + item1.styles, + item1.textStyles + ); + addState( + id2, + type2, + item2.doc, + item2.description, + item2.note, + item2.classes, + item2.styles, + item2.textStyles + ); + currentDocument.relations.push({ id1, id2, - title: common.sanitizeText(title, configApi.getConfig()), + relationTitle: common.sanitizeText(relationTitle, configApi.getConfig()), }); +} + +/** + * Add a relation between two items. The items may be full objects or just the string id of a state. + * + * @param {string | object} item1 + * @param {string | object} item2 + * @param {string} title + */ +export const addRelation = function (item1, item2, title) { + if (typeof item1 === 'object') { + addRelationObjs(item1, item2, title); + } else { + const id1 = startIdIfNeeded(item1); + const type1 = startTypeIfNeeded(item1); + const id2 = endIdIfNeeded(item2); + const type2 = endTypeIfNeeded(item2); + + addState(id1, type1); + addState(id2, type2); + currentDocument.relations.push({ + id1, + id2, + title: common.sanitizeText(title, configApi.getConfig()), + }); + } }; -const addDescription = function (id, _descr) { +export const addDescription = function (id, descr) { const theState = currentDocument.states[id]; - let descr = _descr; - if (descr[0] === ':') { - descr = descr.substr(1).trim(); - } - theState.descriptions.push(common.sanitizeText(descr, configApi.getConfig())); + const _descr = descr.startsWith(':') ? descr.replace(':', '').trim() : descr; + theState.descriptions.push(common.sanitizeText(_descr, configApi.getConfig())); }; export const cleanupLabel = function (label) { @@ -233,34 +441,103 @@ export const cleanupLabel = function (label) { } }; -export const lineType = { - LINE: 0, - DOTTED_LINE: 1, -}; - -let dividerCnt = 0; const getDividerId = () => { dividerCnt++; return 'divider-id-' + dividerCnt; }; -let classes = []; +/** + * Called when the parser comes across a (style) class definition + * @example classDef my-style fill:#f96; + * + * @param {string} id - the id of this (style) class + * @param {string | null} styleAttributes - the string with 1 or more style attributes (each separated by a comma) + */ +export const addStyleClass = function (id, styleAttributes = '') { + // create a new style class object with this id + if (classes[id] === undefined) { + classes[id] = { id: id, styles: [], textStyles: [] }; // This is a classDef + } + const foundClass = classes[id]; + if (styleAttributes !== undefined && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + // remove any trailing ; + const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim(); -const getClasses = () => classes; + // replace some style keywords + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; + +/** + * Return all of the style classes + * @returns {{} | any | classes} + */ +export const getClasses = function () { + return classes; +}; + +/** + * Add a (style) class or css class to a state with the given id. + * If the state isn't already in the list of known states, add it. + * Might be called by parser when a style class or CSS class should be applied to a state + * + * @param {string | string[]} itemIds The id or a list of ids of the item(s) to apply the css class to + * @param {string} cssClassName CSS class name + */ +export const setCssClass = function (itemIds, cssClassName) { + itemIds.split(',').forEach(function (id) { + let foundState = getState(id); + if (foundState === undefined) { + const trimmedId = id.trim(); + addState(trimmedId); + foundState = getState(trimmedId); + } + foundState.classes.push(cssClassName); + }); +}; + +/** + * Add a style to a state with the given id. + * @example style stateId fill:#f9f,stroke:#333,stroke-width:4px + * where 'style' is the keyword + * stateId is the id of a state + * the rest of the string is the styleText (all of the attributes to be applied to the state) + * + * @param itemId The id of item to apply the style to + * @param styleText - the text of the attributes for the style + */ +export const setStyle = function (itemId, styleText) { + const item = getState(itemId); + if (item !== undefined) { + item.textStyles.push(styleText); + } +}; + +/** + * Add a text style to a state with the given id + * + * @param itemId The id of item to apply the css class to + * @param cssClassName CSS class name + */ +export const setTextStyle = function (itemId, cssClassName) { + const item = getState(itemId); + if (item !== undefined) { + item.textStyles.push(cssClassName); + } +}; -let direction = 'TB'; const getDirection = () => direction; const setDirection = (dir) => { direction = dir; }; -export const relationType = { - AGGREGATION: 0, - EXTENSION: 1, - COMPOSITION: 2, - DEPENDENCY: 3, -}; - const trimColon = (str) => (str && str[0] === ':' ? str.substr(1).trim() : str.trim()); export default { @@ -289,4 +566,9 @@ export default { setAccTitle, getAccDescription, setAccDescription, + addStyleClass, + setCssClass, + addDescription, + setDiagramTitle, + getDiagramTitle, }; diff --git a/packages/mermaid/src/diagrams/state/stateDb.spec.js b/packages/mermaid/src/diagrams/state/stateDb.spec.js new file mode 100644 index 000000000..d51d919c3 --- /dev/null +++ b/packages/mermaid/src/diagrams/state/stateDb.spec.js @@ -0,0 +1,75 @@ +import stateDb from './stateDb'; + +describe('State Diagram stateDb', () => { + beforeEach(() => { + stateDb.clear(); + }); + + describe('addStyleClass', () => { + it('is added to the list of style classes', () => { + const newStyleClassId = 'newStyleClass'; + const newStyleClassAttribs = 'font-weight:bold, border:blue;'; + + stateDb.addStyleClass(newStyleClassId, newStyleClassAttribs); + const styleClasses = stateDb.getClasses(); + expect(styleClasses[newStyleClassId].id).toEqual(newStyleClassId); + expect(styleClasses[newStyleClassId].styles.length).toEqual(2); + expect(styleClasses[newStyleClassId].styles[0]).toEqual('font-weight:bold'); + expect(styleClasses[newStyleClassId].styles[1]).toEqual('border:blue'); + }); + }); + + describe('addDescription to a state', () => { + beforeEach(() => { + stateDb.clear(); + stateDb.addState('state1'); + }); + + const testStateId = 'state1'; + + it('removes only the first leading :', () => { + const restOfTheDescription = 'rest of the description'; + const oneLeadingColon = `:${restOfTheDescription}`; + const twoLeadingColons = `::${restOfTheDescription}`; + + stateDb.addDescription(testStateId, restOfTheDescription); + let states = stateDb.getStates(); + expect(states[testStateId].descriptions[0]).toEqual(restOfTheDescription); + + stateDb.addDescription(testStateId, oneLeadingColon); + states = stateDb.getStates(); + expect(states[testStateId].descriptions[1]).toEqual(restOfTheDescription); + + stateDb.addDescription(testStateId, twoLeadingColons); + states = stateDb.getStates(); + expect(states[testStateId].descriptions[2]).toEqual(`:${restOfTheDescription}`); + }); + + it('adds each description to the array of descriptions', () => { + stateDb.addDescription(testStateId, 'description 0'); + stateDb.addDescription(testStateId, 'description 1'); + stateDb.addDescription(testStateId, 'description 2'); + + let states = stateDb.getStates(); + expect(states[testStateId].descriptions.length).toEqual(3); + expect(states[testStateId].descriptions[0]).toEqual('description 0'); + expect(states[testStateId].descriptions[1]).toEqual('description 1'); + expect(states[testStateId].descriptions[2]).toEqual('description 2'); + }); + + it('sanitizes on the description', () => { + stateDb.addDescription( + testStateId, + 'desc outside the script ' + ); + let states = stateDb.getStates(); + expect(states[testStateId].descriptions[0]).toEqual('desc outside the script '); + }); + + it('adds the description to the state with the given id', () => { + stateDb.addDescription(testStateId, 'the description'); + let states = stateDb.getStates(); + expect(states[testStateId].descriptions[0]).toEqual('the description'); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/state/stateDetector-V2.ts b/packages/mermaid/src/diagrams/state/stateDetector-V2.ts index 8082a47bd..9e59c4a04 100644 --- a/packages/mermaid/src/diagrams/state/stateDetector-V2.ts +++ b/packages/mermaid/src/diagrams/state/stateDetector-V2.ts @@ -1,8 +1,11 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const stateDetectorV2: DiagramDetector = (text, config) => { - if (text.match(/^\s*stateDiagram-v2/) !== null) return true; - if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') + if (text.match(/^\s*stateDiagram-v2/) !== null) { return true; + } + if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') { + return true; + } return false; }; diff --git a/packages/mermaid/src/diagrams/state/stateDetector.ts b/packages/mermaid/src/diagrams/state/stateDetector.ts index 79dd6586b..85338c6df 100644 --- a/packages/mermaid/src/diagrams/state/stateDetector.ts +++ b/packages/mermaid/src/diagrams/state/stateDetector.ts @@ -1,8 +1,10 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const stateDetector: DiagramDetector = (txt, config) => { - // If we have confired to only use new state diagrams this function should always return false + // If we have confirmed to only use new state diagrams this function should always return false // as in not signalling true for a legacy state diagram - if (config?.state?.defaultRenderer === 'dagre-wrapper') return false; + if (config?.state?.defaultRenderer === 'dagre-wrapper') { + return false; + } return txt.match(/^\s*stateDiagram/) !== null; }; diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index ad224f14d..7ed5555db 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -1,10 +1,14 @@ import { parser } from './parser/stateDiagram'; import stateDb from './stateDb'; +import stateDiagram from './parser/stateDiagram.jison'; -describe('state diagram, ', function () { +describe('state diagram V2, ', function () { + // TODO - these examples should be put into ./parser/stateDiagram.spec.js describe('when parsing an info graph it', function () { beforeEach(function () { parser.yy = stateDb; + stateDiagram.parser.yy = stateDb; + stateDiagram.parser.yy.clear(); }); it('super simple', function () { @@ -121,6 +125,30 @@ describe('state diagram, ', function () { parser.parse(str); }); + describe('relationship labels', () => { + it('simple states with : labels', () => { + const diagram = ` + stateDiagram-v2 + [*] --> State1 + State1 --> State2 : Transition 1 + State1 --> State3 : Transition 2 + State1 --> State4 : Transition 3 + State1 --> [*] + `; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const rels = stateDb.getRelations(); + const rel_1_2 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State2'); + expect(rel_1_2.relationTitle).toEqual('Transition 1'); + const rel_1_3 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State3'); + expect(rel_1_3.relationTitle).toEqual('Transition 2'); + const rel_1_4 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State4'); + expect(rel_1_4.relationTitle).toEqual('Transition 3'); + }); + }); + it('scale', function () { const str = `stateDiagram-v2\n scale 350 width @@ -355,7 +383,7 @@ describe('state diagram, ', function () { parser.parse(str); }); - it('should handle notes for composit states', function () { + it('should handle notes for composite (nested) states', function () { const str = `stateDiagram-v2\n [*] --> NotShooting @@ -372,5 +400,28 @@ describe('state diagram, ', function () { parser.parse(str); }); + + it('A composite state should be able to link to itself', () => { + const diagram = ` + stateDiagram-v2 + state Active { + Idle + } + Inactive --> Idle: ACT + Active --> Active: LOG + `; + + stateDiagram.parser.parse(diagram); + stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); + + const states = stateDb.getStates(); + expect(states['Active'].doc[0].id).toEqual('Idle'); + + const rels = stateDb.getRelations(); + const rel_Inactive_Idle = rels.find((rel) => rel.id1 === 'Inactive' && rel.id2 === 'Idle'); + expect(rel_Inactive_Idle.relationTitle).toEqual('ACT'); + const rel_Active_Active = rels.find((rel) => rel.id1 === 'Active' && rel.id2 === 'Active'); + expect(rel_Active_Active.relationTitle).toEqual('LOG'); + }); }); }); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 13c474b5e..78e38726e 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -1,237 +1,377 @@ -import graphlib from 'graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib'; import { select } from 'd3'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; import { log } from '../../logger'; import { configureSvgSize } from '../../setupGraphViewbox'; import common from '../common/common'; +import utils from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; +import { + DEFAULT_DIAGRAM_DIRECTION, + DEFAULT_NESTED_DOC_DIR, + STMT_STATE, + STMT_RELATION, + DEFAULT_STATE_TYPE, + DIVIDER_TYPE, +} from './stateCommon'; +// -------------------------------------- +// Shapes +const SHAPE_STATE = 'rect'; +const SHAPE_STATE_WITH_DESC = 'rectWithTitle'; +const SHAPE_START = 'start'; +const SHAPE_END = 'end'; +const SHAPE_DIVIDER = 'divider'; +const SHAPE_GROUP = 'roundedWithTitle'; +const SHAPE_NOTE = 'note'; +const SHAPE_NOTEGROUP = 'noteGroup'; + +// -------------------------------------- +// CSS classes +const CSS_DIAGRAM = 'statediagram'; +const CSS_STATE = 'state'; +const CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`; +const CSS_EDGE = 'transition'; +const CSS_NOTE = 'note'; +const CSS_NOTE_EDGE = 'note-edge'; +const CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`; +const CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`; +const CSS_CLUSTER = 'cluster'; +const CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`; +const CSS_CLUSTER_ALT = 'cluster-alt'; +const CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`; + +// -------------------------------------- +// DOM and element IDs +const PARENT = 'parent'; +const NOTE = 'note'; +const DOMID_STATE = 'state'; +const DOMID_TYPE_SPACER = '----'; +const NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`; +const PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`; +// -------------------------------------- +// Graph edge settings +const G_EDGE_STYLE = 'fill:none'; +const G_EDGE_ARROWHEADSTYLE = 'fill: #333'; +const G_EDGE_LABELPOS = 'c'; +const G_EDGE_LABELTYPE = 'text'; +const G_EDGE_THICKNESS = 'normal'; + +// -------------------------------------- +// List of nodes created from the parsed diagram statement items +let nodeDb = {}; + +let graphItemCount = 0; // used to construct ids, etc. + +// Configuration const conf = {}; + +// ----------------------------------------------------------------------- + export const setConf = function (cnf) { const keys = Object.keys(cnf); - for (let i = 0; i < keys.length; i++) { - conf[keys[i]] = cnf[keys[i]]; + for (const key of keys) { + conf[key] = cnf[key]; } }; -let nodeDb = {}; - /** - * Returns the all the styles from classDef statements in the graph definition. + * Returns the all the classdef styles (a.k.a. classes) from classDef statements in the graph definition. * - * @param {any} text - * @param diag - * @returns {object} ClassDef styles + * @param {string} text - the diagram text to be parsed + * @param diagramObj + * @returns {object} ClassDef styles (a Map with keys = strings, values = ) */ -export const getClasses = function (text, diag) { +export const getClasses = function (text, diagramObj) { log.trace('Extracting classes'); - diag.sb.clear(); - - // Parse the graph definition - diag.parser.parse(text); - return diag.sb.getClasses(); + diagramObj.db.clear(); + try { + // Parse the graph definition + diagramObj.parser.parse(text); + // must run extract() to turn the parsed statements into states, relationships, classes, etc. + diagramObj.db.extract(diagramObj.db.getRootDocV2()); + return diagramObj.db.getClasses(); + } catch (e) { + return e; + } }; -const setupNode = (g, parent, node, altFlag) => { - // Add the node - if (node.id !== 'root') { - let shape = 'rect'; - if (node.start === true) { - shape = 'start'; +/** + * Get classes from the db for the info item. + * If there aren't any or if dbInfoItem isn't defined, return an empty string. + * Else create 1 string from the list of classes found + * + * @param {undefined | null | object} dbInfoItem + * @returns {string} + */ +function getClassesFromDbInfo(dbInfoItem) { + if (dbInfoItem === undefined || dbInfoItem === null) { + return ''; + } else { + if (dbInfoItem.classes) { + return dbInfoItem.classes.join(' '); + } else { + return ''; } - if (node.start === false) { - shape = 'end'; + } +} + +/** + * Create a standard string for the dom ID of an item. + * If a type is given, insert that before the counter, preceded by the type spacer + * + * @param itemId + * @param counter + * @param {string | null} type + * @param typeSpacer + * @returns {string} + */ +export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOMID_TYPE_SPACER) { + const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : ''; + return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`; +} + +/** + * Create a graph node based on the statement information + * + * @param g - graph + * @param {object} parent + * @param {object} parsedItem - parsed statement item + * @param {object[]} diagramStates - the list of all known states for the diagram + * @param {object} diagramDb + * @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class + */ +const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { + const itemId = parsedItem.id; + const classStr = getClassesFromDbInfo(diagramStates[itemId]); + + if (itemId !== 'root') { + let shape = SHAPE_STATE; + if (parsedItem.start === true) { + shape = SHAPE_START; } - if (node.type !== 'default') { - shape = node.type; + if (parsedItem.start === false) { + shape = SHAPE_END; + } + if (parsedItem.type !== DEFAULT_STATE_TYPE) { + shape = parsedItem.type; } - if (!nodeDb[node.id]) { - nodeDb[node.id] = { - id: node.id, + // Add the node to our list (nodeDb) + if (!nodeDb[itemId]) { + nodeDb[itemId] = { + id: itemId, shape, - description: common.sanitizeText(node.id, getConfig()), - classes: 'statediagram-state', + description: common.sanitizeText(itemId, getConfig()), + classes: `${classStr} ${CSS_DIAGRAM_STATE}`, }; } - // Build of the array of description strings accordinging - if (node.description) { - if (Array.isArray(nodeDb[node.id].description)) { - // There already is an array of strings,add to it - nodeDb[node.id].shape = 'rectWithTitle'; - nodeDb[node.id].description.push(node.description); - } else { - if (nodeDb[node.id].description.length > 0) { - // if there is a description already transformit to an array - nodeDb[node.id].shape = 'rectWithTitle'; - if (nodeDb[node.id].description === node.id) { - // If the previous description was the is, remove it - nodeDb[node.id].description = [node.description]; - } else { - nodeDb[node.id].description = [nodeDb[node.id].description, node.description]; - } - } else { - nodeDb[node.id].shape = 'rect'; - nodeDb[node.id].description = node.description; - } - } - nodeDb[node.id].description = common.sanitizeTextOrArray( - nodeDb[node.id].description, - getConfig() - ); - } - - // - if (nodeDb[node.id].description.length === 1 && nodeDb[node.id].shape === 'rectWithTitle') { - nodeDb[node.id].shape = 'rect'; - } + const newNode = nodeDb[itemId]; // Save data for description and group so that for instance a statement without description overwrites - // one with description + // one with description @todo TODO What does this mean? If important, add a test for it - // group - if (!nodeDb[node.id].type && node.doc) { - log.info('Setting cluster for ', node.id, getDir(node)); - nodeDb[node.id].type = 'group'; - nodeDb[node.id].dir = getDir(node); - nodeDb[node.id].shape = node.type === 'divider' ? 'divider' : 'roundedWithTitle'; - nodeDb[node.id].classes = - nodeDb[node.id].classes + - ' ' + - (altFlag ? 'statediagram-cluster statediagram-cluster-alt' : 'statediagram-cluster'); + // Build of the array of description strings + if (parsedItem.description) { + if (Array.isArray(newNode.description)) { + // There already is an array of strings,add to it + newNode.shape = SHAPE_STATE_WITH_DESC; + newNode.description.push(parsedItem.description); + } else { + if (newNode.description.length > 0) { + // if there is a description already transform it to an array + newNode.shape = SHAPE_STATE_WITH_DESC; + if (newNode.description === itemId) { + // If the previous description was this, remove it + newNode.description = [parsedItem.description]; + } else { + newNode.description = [newNode.description, parsedItem.description]; + } + } else { + newNode.shape = SHAPE_STATE; + newNode.description = parsedItem.description; + } + } + newNode.description = common.sanitizeTextOrArray(newNode.description, getConfig()); } + // If there's only 1 description entry, just use a regular state shape + if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) { + newNode.shape = SHAPE_STATE; + } + + // group + if (!newNode.type && parsedItem.doc) { + log.info('Setting cluster for ', itemId, getDir(parsedItem)); + newNode.type = 'group'; + newNode.dir = getDir(parsedItem); + newNode.shape = parsedItem.type === DIVIDER_TYPE ? SHAPE_DIVIDER : SHAPE_GROUP; + newNode.classes = + newNode.classes + + ' ' + + CSS_DIAGRAM_CLUSTER + + ' ' + + (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : ''); + } + + // This is what will be added to the graph const nodeData = { labelStyle: '', - shape: nodeDb[node.id].shape, - labelText: nodeDb[node.id].description, - // typeof nodeDb[node.id].description === 'object' - // ? nodeDb[node.id].description[0] - // : nodeDb[node.id].description, - classes: nodeDb[node.id].classes, //classStr, + shape: newNode.shape, + labelText: newNode.description, + // typeof newNode.description === 'object' + // ? newNode.description[0] + // : newNode.description, + classes: newNode.classes, style: '', //styles.style, - id: node.id, - dir: nodeDb[node.id].dir, - domId: 'state-' + node.id + '-' + cnt, - type: nodeDb[node.id].type, + id: itemId, + dir: newNode.dir, + domId: stateDomId(itemId, graphItemCount), + type: newNode.type, padding: 15, //getConfig().flowchart.padding }; - if (node.note) { + if (parsedItem.note) { // Todo: set random id const noteData = { labelStyle: '', - shape: 'note', - labelText: node.note.text, - classes: 'statediagram-note', //classStr, - style: '', //styles.style, - id: node.id + '----note-' + cnt, - domId: 'state-' + node.id + '----note-' + cnt, - type: nodeDb[node.id].type, + shape: SHAPE_NOTE, + labelText: parsedItem.note.text, + classes: CSS_DIAGRAM_NOTE, + style: '', // styles.style, + id: itemId + NOTE_ID + '-' + graphItemCount, + domId: stateDomId(itemId, graphItemCount, NOTE), + type: newNode.type, padding: 15, //getConfig().flowchart.padding }; const groupData = { labelStyle: '', - shape: 'noteGroup', - labelText: node.note.text, - classes: nodeDb[node.id].classes, //classStr, - style: '', //styles.style, - id: node.id + '----parent', - domId: 'state-' + node.id + '----parent-' + cnt, + shape: SHAPE_NOTEGROUP, + labelText: parsedItem.note.text, + classes: newNode.classes, + style: '', // styles.style, + id: itemId + PARENT_ID, + domId: stateDomId(itemId, graphItemCount, PARENT), type: 'group', padding: 0, //getConfig().flowchart.padding }; - cnt++; + graphItemCount++; - g.setNode(node.id + '----parent', groupData); + const parentNodeId = itemId + PARENT_ID; + g.setNode(parentNodeId, groupData); g.setNode(noteData.id, noteData); - g.setNode(node.id, nodeData); + g.setNode(itemId, nodeData); - g.setParent(node.id, node.id + '----parent'); - g.setParent(noteData.id, node.id + '----parent'); + g.setParent(itemId, parentNodeId); + g.setParent(noteData.id, parentNodeId); - let from = node.id; + let from = itemId; let to = noteData.id; - if (node.note.position === 'left of') { + if (parsedItem.note.position === 'left of') { from = noteData.id; - to = node.id; + to = itemId; } g.setEdge(from, to, { arrowhead: 'none', arrowType: '', - style: 'fill:none', + style: G_EDGE_STYLE, labelStyle: '', - classes: 'transition note-edge', - arrowheadStyle: 'fill: #333', - labelpos: 'c', - labelType: 'text', - thickness: 'normal', + classes: CSS_EDGE_NOTE_EDGE, + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS, }); } else { - g.setNode(node.id, nodeData); + g.setNode(itemId, nodeData); } } - if (parent) { - if (parent.id !== 'root') { - log.trace('Setting node ', node.id, ' to be child of its parent ', parent.id); - g.setParent(node.id, parent.id); - } + if (parent && parent.id !== 'root') { + log.trace('Setting node ', itemId, ' to be child of its parent ', parent.id); + g.setParent(itemId, parent.id); } - if (node.doc) { + if (parsedItem.doc) { log.trace('Adding nodes children '); - setupDoc(g, node, node.doc, !altFlag); + setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); } }; -let cnt = 0; -const setupDoc = (g, parent, doc, altFlag) => { - // cnt = 0; + +/** + * Turn parsed statements (item.stmt) into nodes, relationships, etc. for a document. + * (A document may be nested within others.) + * + * @param g + * @param parentParsedItem - parsed Item that is the parent of this document (doc) + * @param doc - the document to set up + * @param {object} diagramStates - the list of all known states for the diagram + * @param diagramDb + * @param {boolean} altFlag + * @todo This duplicates some of what is done in stateDb.js extract method + */ +const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { + // graphItemCount = 0; log.trace('items', doc); doc.forEach((item) => { - if (item.stmt === 'state' || item.stmt === 'default') { - setupNode(g, parent, item, altFlag); - } else if (item.stmt === 'relation') { - setupNode(g, parent, item.state1, altFlag); - setupNode(g, parent, item.state2, altFlag); - const edgeData = { - id: 'edge' + cnt, - arrowhead: 'normal', - arrowTypeEnd: 'arrow_barb', - style: 'fill:none', - labelStyle: '', - label: common.sanitizeText(item.description, getConfig()), - arrowheadStyle: 'fill: #333', - labelpos: 'c', - labelType: 'text', - thickness: 'normal', - classes: 'transition', - }; - let startId = item.state1.id; - let endId = item.state2.id; - - g.setEdge(startId, endId, edgeData, cnt); - cnt++; + switch (item.stmt) { + case STMT_STATE: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case DEFAULT_STATE_TYPE: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case STMT_RELATION: + { + setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); + const edgeData = { + id: 'edge' + graphItemCount, + arrowhead: 'normal', + arrowTypeEnd: 'arrow_barb', + style: G_EDGE_STYLE, + labelStyle: '', + label: common.sanitizeText(item.description, getConfig()), + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS, + classes: CSS_EDGE, + }; + g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount); + graphItemCount++; + } + break; } }); }; -const getDir = (nodes, defaultDir) => { - let dir = defaultDir || 'TB'; - if (nodes.doc) { - for (let i = 0; i < nodes.doc.length; i++) { - const node = nodes.doc[i]; - if (node.stmt === 'dir') { - dir = node.value; + +/** + * Get the direction from the statement items. + * Look through all of the documents (docs) in the parsedItems + * Because is a _document_ direction, the default direction is not necessarily the same as the overall default _diagram_ direction. + * @param {object[]} parsedItem - the parsed statement item to look through + * @param [defaultDir=DEFAULT_NESTED_DOC_DIR] - the direction to use if none is found + * @returns {string} + */ +const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => { + let dir = defaultDir; + if (parsedItem.doc) { + for (let i = 0; i < parsedItem.doc.length; i++) { + const parsedItemDoc = parsedItem.doc[i]; + if (parsedItemDoc.stmt === 'dir') { + dir = parsedItemDoc.value; } } } return dir; }; + /** - * Draws a flowchart in the tag with id: id based on the graph definition in text. + * Draws a state diagram in the tag with id: id based on the graph definition in text. * * @param {any} text * @param {any} id @@ -244,8 +384,8 @@ export const draw = function (text, id, _version, diag) { nodeDb = {}; // Fetch the default direction, use TD if none was found let dir = diag.db.getDirection(); - if (typeof dir === 'undefined') { - dir = 'LR'; + if (dir === undefined) { + dir = DEFAULT_DIAGRAM_DIRECTION; } const { securityLevel, state: conf } = getConfig(); @@ -253,9 +393,13 @@ export const draw = function (text, id, _version, diag) { const rankSpacing = conf.rankSpacing || 50; log.info(diag.db.getRootDocV2()); + + // This parses the diagram text and sets the classes, relations, styles, classDefs, etc. diag.db.extract(diag.db.getRootDocV2()); log.info(diag.db.getRootDocV2()); + const diagramStates = diag.db.getStates(); + // Create the input mermaid.graph const g = new graphlib.Graph({ multigraph: true, @@ -272,7 +416,7 @@ export const draw = function (text, id, _version, diag) { return {}; }); - setupNode(g, undefined, diag.db.getRootDocV2(), true); + setupNode(g, undefined, diag.db.getRootDocV2(), diagramStates, diag.db, true); // Set up an SVG group so that we can translate the final graph. let sandboxElement; @@ -288,17 +432,18 @@ export const draw = function (text, id, _version, diag) { // Run the renderer. This is what draws the final graph. const element = root.select('#' + id + ' g'); - render(element, g, ['barb'], 'statediagram', id); + render(element, g, ['barb'], CSS_DIAGRAM, id); const padding = 8; - const bounds = svg.node().getBBox(); + utils.insertTitle(svg, 'statediagramTitleText', conf.titleTopMargin, diag.db.getDiagramTitle()); + const bounds = svg.node().getBBox(); const width = bounds.width + padding * 2; const height = bounds.height + padding * 2; // Zoom in a bit - svg.attr('class', 'statediagram'); + svg.attr('class', CSS_DIAGRAM); const svgBounds = svg.node().getBBox(); @@ -312,13 +457,11 @@ export const draw = function (text, id, _version, diag) { // Add label rects for non html labels // if (!evaluate(conf.htmlLabels) || true) { const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); - for (let k = 0; k < labels.length; k++) { - const label = labels[k]; - + for (const label of labels) { // Get dimensions of label const dim = label.getBBox(); - const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + const rect = document.createElementNS('http://www.w3.org/2000/svg', SHAPE_STATE); rect.setAttribute('rx', 0); rect.setAttribute('ry', 0); rect.setAttribute('width', dim.width); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js new file mode 100644 index 000000000..3a118e607 --- /dev/null +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js @@ -0,0 +1,31 @@ +import { expectTypeOf } from 'vitest'; + +import { parser } from './parser/stateDiagram'; +import stateDb from './stateDb'; +import stateRendererV2 from './stateRenderer-v2'; + +// Can use this instead of having to register diagrams and load/orchestrate them, etc. +class FauxDiagramObj { + db = stateDb; + parser = parser; + renderer = stateRendererV2; + + constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) { + this.db = options.db; + this.parser = options.parser; + this.renderer = options.renderer; + this.parser.yy = this.db; + } +} + +describe('stateRenderer-v2', () => { + describe('getClasses', () => { + const diagramText = 'statediagram-v2\n'; + const fauxStateDiagram = new FauxDiagramObj(); + + it('returns a {}', () => { + const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram); + expectTypeOf(result).toBeObject(); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer.js b/packages/mermaid/src/diagrams/state/stateRenderer.js index 75368c557..4eeede12e 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer.js @@ -1,6 +1,6 @@ import { select } from 'd3'; -import dagre from 'dagre'; -import graphlib from 'graphlib'; +import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { log } from '../../logger'; import common from '../common/common'; import { drawState, addTitleAndBox, drawEdge } from './shapes'; @@ -47,7 +47,7 @@ const insertMarkers = function (elem) { export const draw = function (text, id, _version, diagObj) { conf = getConfig().state; const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -120,7 +120,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = } // Set an object for the graph label - if (parentId) + if (parentId) { graph.setGraph({ rankdir: 'LR', multigraph: true, @@ -133,7 +133,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = // ranksep: 5, // nodesep: 1 }); - else { + } else { graph.setGraph({ rankdir: 'TB', multigraph: true, @@ -162,8 +162,8 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = let first = true; - for (let i = 0; i < keys.length; i++) { - const stateDef = states[keys[i]]; + for (const key of keys) { + const stateDef = states[key]; if (parentId) { stateDef.parentId = parentId; @@ -239,13 +239,13 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = ); }); - dagre.layout(graph); + dagreLayout(graph); log.debug('Graph after layout', graph.nodes()); const svgElem = diagram.node(); graph.nodes().forEach(function (v) { - if (typeof v !== 'undefined' && typeof graph.node(v) !== 'undefined') { + if (v !== undefined && graph.node(v) !== undefined) { log.warn('Node ' + v + ': ' + JSON.stringify(graph.node(v))); root .select('#' + svgElem.id + ' #' + v) @@ -268,7 +268,9 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = let pWidth = 0; let pShift = 0; if (parent) { - if (parent.parentElement) pWidth = parent.parentElement.getBBox().width; + if (parent.parentElement) { + pWidth = parent.parentElement.getBBox().width; + } pShift = parseInt(parent.getAttribute('data-x-shift'), 10); if (Number.isNaN(pShift)) { pShift = 0; @@ -285,7 +287,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) = let stateBox = svgElem.getBBox(); graph.edges().forEach(function (e) { - if (typeof e !== 'undefined' && typeof graph.edge(e) !== 'undefined') { + if (e !== undefined && graph.edge(e) !== undefined) { log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e))); drawEdge(diagram, graph.edge(e), graph.edge(e).relation); } diff --git a/packages/mermaid/src/diagrams/state/styles.js b/packages/mermaid/src/diagrams/state/styles.js index 4a1c46512..f4783b477 100644 --- a/packages/mermaid/src/diagrams/state/styles.js +++ b/packages/mermaid/src/diagrams/state/styles.js @@ -194,6 +194,12 @@ g.stateGroup line { stroke: ${options.lineColor}; stroke-width: 1; } + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/user-journey/journeyDb.js b/packages/mermaid/src/diagrams/user-journey/journeyDb.js index 0707636f5..ce8705094 100644 --- a/packages/mermaid/src/diagrams/user-journey/journeyDb.js +++ b/packages/mermaid/src/diagrams/user-journey/journeyDb.js @@ -105,10 +105,10 @@ const compileTasks = function () { }; let allProcessed = true; - for (let i = 0; i < rawTasks.length; i++) { + for (const [i, rawTask] of rawTasks.entries()) { compileTask(i); - allProcessed = allProcessed && rawTasks[i].processed; + allProcessed = allProcessed && rawTask.processed; } return allProcessed; }; diff --git a/packages/mermaid/src/diagrams/user-journey/journeyDetector.ts b/packages/mermaid/src/diagrams/user-journey/journeyDetector.ts index 77c8688ae..535e7be9d 100644 --- a/packages/mermaid/src/diagrams/user-journey/journeyDetector.ts +++ b/packages/mermaid/src/diagrams/user-journey/journeyDetector.ts @@ -1,4 +1,4 @@ -import type { DiagramDetector } from '../../diagram-api/detectType'; +import type { DiagramDetector } from '../../diagram-api/types'; export const journeyDetector: DiagramDetector = (txt) => { return txt.match(/^\s*journey/) !== null; diff --git a/packages/mermaid/src/diagrams/user-journey/journeyRenderer.ts b/packages/mermaid/src/diagrams/user-journey/journeyRenderer.ts index e3ebb839c..b22192101 100644 --- a/packages/mermaid/src/diagrams/user-journey/journeyRenderer.ts +++ b/packages/mermaid/src/diagrams/user-journey/journeyRenderer.ts @@ -15,7 +15,7 @@ export const setConf = function (cnf) { const actors = {}; -/** @param {any} diagram */ +/** @param diagram - The diagram to draw to. */ function drawActorLegend(diagram) { const conf = getConfig().journey; // Draw the actors @@ -54,7 +54,7 @@ export const draw = function (text, id, version, diagObj) { diagObj.parser.parse(text + '\n'); const securityLevel = getConfig().securityLevel; - // Handle root and Document for when rendering in sanbox mode + // Handle root and Document for when rendering in sandbox mode let sandboxElement; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); @@ -74,7 +74,9 @@ export const draw = function (text, id, version, diagObj) { const title = diagObj.db.getDiagramTitle(); const actorNames = diagObj.db.getActors(); - for (const member in actors) delete actors[member]; + for (const member in actors) { + delete actors[member]; + } let actorPos = 0; actorNames.forEach((actorName) => { actors[actorName] = { @@ -144,7 +146,7 @@ export const bounds = { this.verticalPos = 0; }, updateVal: function (obj, key, val, fun) { - if (typeof obj[key] === 'undefined') { + if (obj[key] === undefined) { obj[key] = val; } else { obj[key] = fun(val, obj[key]); @@ -155,8 +157,8 @@ export const bounds = { // eslint-disable-next-line @typescript-eslint/no-this-alias const _self = this; let cnt = 0; - /** @param {any} type */ - function updateFn(type) { + /** @param type - Set to `activation` if activation */ + function updateFn(type?: 'activation') { return function updateItemBounds(item) { cnt++; // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems @@ -219,8 +221,7 @@ export const drawTasks = function (diagram, tasks, verticalPos) { let num = 0; // Draw the tasks - for (let i = 0; i < tasks.length; i++) { - const task = tasks[i]; + for (const [i, task] of tasks.entries()) { if (lastSection !== task.section) { fill = fills[sectionNumber % fills.length]; num = sectionNumber % fills.length; @@ -261,7 +262,7 @@ export const drawTasks = function (diagram, tasks, verticalPos) { // Draw the box with the attached line svgDraw.drawTask(diagram, task, conf); - bounds.insert(task.x, task.y, task.x + task.width + conf.taskMargin, 300 + 5 * 30); // stopy is the length of the descenders. + bounds.insert(task.x, task.y, task.x + task.width + conf.taskMargin, 300 + 5 * 30); // stopY is the length of the descenders. } }; diff --git a/packages/mermaid/src/diagrams/user-journey/svgDraw.js b/packages/mermaid/src/diagrams/user-journey/svgDraw.js index f655b9c3a..74d5d2a02 100644 --- a/packages/mermaid/src/diagrams/user-journey/svgDraw.js +++ b/packages/mermaid/src/diagrams/user-journey/svgDraw.js @@ -11,7 +11,7 @@ export const drawRect = function (elem, rectData) { rectElem.attr('rx', rectData.rx); rectElem.attr('ry', rectData.ry); - if (typeof rectData.class !== 'undefined') { + if (rectData.class !== undefined) { rectElem.attr('class', rectData.class); } @@ -116,11 +116,11 @@ export const drawCircle = function (element, circleData) { circleElement.attr('stroke', circleData.stroke); circleElement.attr('r', circleData.r); - if (typeof circleElement.class !== 'undefined') { + if (circleElement.class !== undefined) { circleElement.attr('class', circleElement.class); } - if (typeof circleData.title !== 'undefined') { + if (circleData.title !== undefined) { circleElement.append('title').text(circleData.title); } @@ -138,7 +138,7 @@ export const drawText = function (elem, textData) { textElem.style('text-anchor', textData.anchor); - if (typeof textData.class !== 'undefined') { + if (textData.class !== undefined) { textElem.attr('class', textData.class); } @@ -218,7 +218,7 @@ export const drawSection = function (elem, section, conf) { let taskCount = -1; /** - * Draws an actor in the diagram with the attaced line + * Draws an actor in the diagram with the attached line * * @param {any} elem The HTML element * @param {any} task The task to render diff --git a/packages/mermaid/src/docs.mts b/packages/mermaid/src/docs.mts index a22dc59e2..313d1f2de 100644 --- a/packages/mermaid/src/docs.mts +++ b/packages/mermaid/src/docs.mts @@ -30,44 +30,59 @@ * @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with * it.) */ -import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; +import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, rmdirSync } from 'fs'; import { exec } from 'child_process'; import { globby } from 'globby'; import { JSDOM } from 'jsdom'; import type { Code, Root } from 'mdast'; -import { join, dirname } from 'path'; +import { posix, dirname, relative, join } from 'path'; import prettier from 'prettier'; import { remark } from 'remark'; +import chokidar from 'chokidar'; +import mm from 'micromatch'; // @ts-ignore No typescript declaration file import flatmap from 'unist-util-flatmap'; +const MERMAID_MAJOR_VERSION = ( + JSON.parse(readFileSync('../mermaid/package.json', 'utf8')).version as string +).split('.')[0]; +const CDN_URL = 'https://cdn.jsdelivr.net/npm'; // 'https://unpkg.com'; + +const verifyOnly: boolean = process.argv.includes('--verify'); +const git: boolean = process.argv.includes('--git'); +const watch: boolean = process.argv.includes('--watch'); +const vitepress: boolean = process.argv.includes('--vitepress'); +const noHeader: boolean = process.argv.includes('--noHeader') || vitepress; + // These paths are from the root of the mono-repo, not from the // mermaid sub-directory -const SOURCE_DOCS_DIR = 'packages/mermaid/src/docs'; -const FINAL_DOCS_DIR = 'docs'; - -const AUTOGENERATED_TEXT = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in ${SOURCE_DOCS_DIR}.`; +const SOURCE_DOCS_DIR = 'src/docs'; +const FINAL_DOCS_DIR = vitepress ? 'src/vitepress' : '../../docs'; const LOGMSG_TRANSFORMED = 'transformed'; const LOGMSG_TO_BE_TRANSFORMED = 'to be transformed'; const LOGMSG_COPIED = `, and copied to ${FINAL_DOCS_DIR}`; -const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run yarn docs:build after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`; +const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run 'pnpm --filter mermaid run docs:build' after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`; -const verifyOnly: boolean = process.argv.includes('--verify'); -const git: boolean = process.argv.includes('--git'); +const prettierConfig = prettier.resolveConfig.sync('.') ?? {}; +// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21 +const includesRE = //g; +const includedFiles: Set = new Set(); -// TODO: Read from .prettierrc? -const prettierConfig: prettier.Config = { - useTabs: false, - tabWidth: 2, - endOfLine: 'auto', - printWidth: 100, - singleQuote: true, +const filesTransformed: Set = new Set(); + +const generateHeader = (file: string): string => { + // path from file in docs/* to repo root, e.g ../ or ../../ */ + const relativePath = relative(file, SOURCE_DOCS_DIR); + const filePathFromRoot = posix.join('/packages/mermaid', file); + const sourcePathRelativeToGenerated = posix.join(relativePath, filePathFromRoot); + return ` +> **Warning** +> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. +> ## Please edit the corresponding file in [${filePathFromRoot}](${sourcePathRelativeToGenerated}).`; }; -let filesWereTransformed = false; - /** * Given a source file name and path, return the documentation destination full path and file name * Create the destination path if it does not already exist. @@ -105,10 +120,10 @@ const logWasOrShouldBeTransformed = (filename: string, wasCopied: boolean) => { * transformed contents to the final documentation directory if the doCopy flag is true. Log * messages to the console. * - * @param {string} filename Name of the file that will be verified - * @param {boolean} [doCopy=false] Whether we should copy that transformedContents to the final + * @param filename Name of the file that will be verified + * @param doCopy?=false Whether we should copy that transformedContents to the final * documentation directory. Default is `false` - * @param {string} [transformedContent] New contents for the file + * @param transformedContent? New contents for the file */ const copyTransformedContents = (filename: string, doCopy = false, transformedContent?: string) => { const fileInFinalDocDir = changeToFinalDocDir(filename); @@ -120,7 +135,7 @@ const copyTransformedContents = (filename: string, doCopy = false, transformedCo return; // Files are same, skip. } - filesWereTransformed = true; + filesTransformed.add(fileInFinalDocDir); if (doCopy) { writeFileSync(fileInFinalDocDir, newBuffer); } @@ -131,6 +146,27 @@ const readSyncedUTF8file = (filename: string): string => { return readFileSync(filename, 'utf8'); }; +const transformToBlockQuote = (content: string, type: string) => { + const title = type === 'warning' ? 'Warning' : 'Note'; + return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`; +}; + +const injectPlaceholders = (text: string): string => + text.replace(//g, MERMAID_MAJOR_VERSION).replace(//g, CDN_URL); + +const transformIncludeStatements = (file: string, text: string): string => { + // resolve includes - src https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L65-L76 + return text.replace(includesRE, (m, m1) => { + try { + const includePath = join(dirname(file), m1); + const content = readSyncedUTF8file(includePath); + includedFiles.add(changeToFinalDocDir(includePath)); + return content; + } catch (error) { + throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`); + } + }); +}; /** * Transform a markdown file and write the transformed file to the directory for published * documentation @@ -144,23 +180,38 @@ const readSyncedUTF8file = (filename: string): string => { * @param file {string} name of the file that will be verified */ const transformMarkdown = (file: string) => { - const doc = readSyncedUTF8file(file); + const doc = injectPlaceholders(transformIncludeStatements(file, readSyncedUTF8file(file))); const ast: Root = remark.parse(doc); const out = flatmap(ast, (c: Code) => { - if (c.type !== 'code') { + if (c.type !== 'code' || !c.lang) { return [c]; } - if (c.lang === 'mermaid' || c.lang === 'mmd') { + + // Convert mermaid code blocks to mermaid-example blocks + if (['mermaid', 'mmd', 'mermaid-example'].includes(c.lang)) { c.lang = 'mermaid-example'; + return [c, Object.assign({}, c, { lang: 'mermaid' })]; } - if (c.lang !== 'mermaid-example') { - return [c]; + + // Transform codeblocks into block quotes. + if (['note', 'tip', 'warning'].includes(c.lang)) { + return [remark.parse(transformToBlockQuote(c.value, c.lang))]; } - return [c, Object.assign({}, c, { lang: 'mermaid' })]; + + return [c]; }); - // Add the AUTOGENERATED_TEXT to the start of the file - const transformed = `${AUTOGENERATED_TEXT}\n${remark.stringify(out)}`; + let transformed = remark.stringify(out); + if (!noHeader) { + // Add the header to the start of the file + transformed = `${generateHeader(file)}\n${transformed}`; + } + + if (vitepress && file === 'src/docs/index.md') { + // Skip transforming index if vitepress is enabled + transformed = doc; + } + const formatted = prettier.format(transformed, { parser: 'markdown', ...prettierConfig, @@ -185,10 +236,15 @@ const transformHtml = (filename: string) => { * @returns {string} The contents of the file with the comment inserted */ const insertAutoGeneratedComment = (fileName: string): string => { - const fileContents = readSyncedUTF8file(fileName); + const fileContents = injectPlaceholders(readSyncedUTF8file(fileName)); + + if (noHeader) { + return fileContents; + } + const jsdom = new JSDOM(fileContents); const htmlDoc = jsdom.window.document; - const autoGeneratedComment = jsdom.window.document.createComment(AUTOGENERATED_TEXT); + const autoGeneratedComment = jsdom.window.document.createComment(generateHeader(fileName)); const rootElement = htmlDoc.documentElement; rootElement.prepend(autoGeneratedComment); @@ -203,42 +259,86 @@ const transformHtml = (filename: string) => { copyTransformedContents(filename, !verifyOnly, formattedHTML); }; +const getGlobs = (globs: string[]): string[] => { + globs.push('!**/dist', '!**/redirect.spec.ts'); + if (!vitepress) { + globs.push('!**/.vitepress', '!**/vite.config.ts', '!src/docs/index.md'); + } + return globs; +}; + +const getFilesFromGlobs = async (globs: string[]): Promise => { + return await globby(globs, { dot: true }); +}; + /** Main method (entry point) */ (async () => { if (verifyOnly) { console.log('Verifying that all files are in sync with the source files'); } - const sourceDirGlob = join('.', SOURCE_DOCS_DIR, '**'); - const includeFilesStartingWithDot = true; - console.log('Transforming markdown files...'); - const mdFiles = await globby([join(sourceDirGlob, '*.md')], { - dot: includeFilesStartingWithDot, - }); + const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**'); + const action = verifyOnly ? 'Verifying' : 'Transforming'; + + const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]); + const mdFiles = await getFilesFromGlobs(mdFileGlobs); + console.log(`${action} ${mdFiles.length} markdown files...`); mdFiles.forEach(transformMarkdown); - console.log('Transforming html files...'); - const htmlFiles = await globby([join(sourceDirGlob, '*.html')], { - dot: includeFilesStartingWithDot, - }); + for (const includedFile of includedFiles) { + rmSync(includedFile, { force: true }); + filesTransformed.delete(includedFile); + console.log(`Removed ${includedFile} as it was used inside an @include block.`); + } + + const htmlFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.html')]); + const htmlFiles = await getFilesFromGlobs(htmlFileGlobs); + console.log(`${action} ${htmlFiles.length} html files...`); htmlFiles.forEach(transformHtml); - console.log('Transforming all other files...'); - const otherFiles = await globby([sourceDirGlob, '!**/*.md', '!**/*.html'], { - dot: includeFilesStartingWithDot, - }); + const otherFileGlobs = getGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']); + const otherFiles = await getFilesFromGlobs(otherFileGlobs); + console.log(`${action} ${otherFiles.length} other files...`); otherFiles.forEach((file: string) => { copyTransformedContents(file, !verifyOnly); // no transformation }); - if (filesWereTransformed) { + if (filesTransformed.size > 0) { if (verifyOnly) { console.log(WARN_DOCSDIR_DOESNT_MATCH); process.exit(1); } if (git) { - console.log('Adding changes in ${FINAL_DOCS_DIR} folder to git'); - exec('git add docs'); + console.log(`Adding changes in ${FINAL_DOCS_DIR} folder to git`); + exec(`git add ${FINAL_DOCS_DIR}`); } } + + if (watch) { + console.log(`Watching for changes in ${SOURCE_DOCS_DIR}`); + + const matcher = (globs: string[]) => (file: string) => mm.every(file, globs); + const isMd = matcher(mdFileGlobs); + const isHtml = matcher(htmlFileGlobs); + const isOther = matcher(otherFileGlobs); + + chokidar + .watch(SOURCE_DOCS_DIR) + // Delete files from the final docs dir if they are deleted from the source dir + .on('unlink', (file: string) => rmSync(changeToFinalDocDir(file))) + .on('unlinkDir', (file: string) => rmdirSync(changeToFinalDocDir(file))) + .on('all', (event, path) => { + // Ignore other events. + if (!['add', 'change'].includes(event)) { + return; + } + if (isMd(path)) { + transformMarkdown(path); + } else if (isHtml(path)) { + transformHtml(path); + } else if (isOther(path)) { + copyTransformedContents(path, true); + } + }); + } })(); diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts new file mode 100644 index 000000000..216541d52 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -0,0 +1,165 @@ +import { version } from '../../../package.json'; +import MermaidExample from './mermaid-markdown-all'; +import { defineConfig, MarkdownOptions } from 'vitepress'; + +const allMarkdownTransformers: MarkdownOptions = { + // the shiki theme to highlight code blocks + theme: 'github-dark', + config: async (md) => { + await MermaidExample(md); + }, +}; + +export default defineConfig({ + lang: 'en-US', + title: 'Mermaid', + description: 'Create diagrams and visualizations using text and code.', + base: '/mermaid/', + markdown: allMarkdownTransformers, + head: [['link', { rel: 'icon', type: 'image/x-icon', href: '/mermaid/favicon.ico' }]], + themeConfig: { + nav: nav(), + editLink: { + pattern: 'https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/src/docs/:path', + text: 'Edit this page on GitHub', + }, + + sidebar: { + '/': sidebarAll(), + }, + }, +}); + +function nav() { + return [ + { text: 'Intro', link: '/intro/', activeMatch: '/intro/' }, + { + text: 'Configuration', + link: '/config/configuration', + activeMatch: '/config/', + }, + { text: 'Syntax', link: '/syntax/classDiagram', activeMatch: '/syntax/' }, + { text: 'Misc', link: '/misc/integrations', activeMatch: '/misc/' }, + { + text: 'Community', + link: '/community/n00b-overview', + activeMatch: '/community/', + }, + { + text: version, + items: [ + { + text: 'Changelog', + link: 'https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md', + }, + { + text: 'Contributing', + link: 'https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md', + }, + ], + }, + { + text: '💻 Live Editor', + link: 'https://mermaid.live', + }, + ]; +} + +function sidebarAll() { + return [ + { + text: '📔 Introduction', + collapsible: true, + items: [ + { text: 'About Mermaid', link: '/intro/' }, + { text: 'Deployment', link: '/intro/n00b-gettingStarted' }, + { + text: 'Syntax and Configuration', + link: '/intro/n00b-syntaxReference', + }, + ], + }, + ...sidebarSyntax(), + ...sidebarConfig(), + ...sidebarMisc(), + ...sidebarCommunity(), + ]; +} + +function sidebarSyntax() { + return [ + { + text: '📊 Diagram Syntax', + collapsible: true, + items: [ + { text: 'Flowchart', link: '/syntax/flowchart' }, + { text: 'Sequence Diagram', link: '/syntax/sequenceDiagram' }, + { text: 'Class Diagram', link: '/syntax/classDiagram' }, + { text: 'State Diagram', link: '/syntax/stateDiagram' }, + { + text: 'Entity Relationship Diagram', + link: '/syntax/entityRelationshipDiagram', + }, + { text: 'User Journey', link: '/syntax/userJourney' }, + { text: 'Gantt', link: '/syntax/gantt' }, + { text: 'Pie Chart', link: '/syntax/pie' }, + { text: 'Requirement Diagram', link: '/syntax/requirementDiagram' }, + { text: 'Gitgraph (Git) Diagram 🔥', link: '/syntax/gitgraph' }, + { text: 'C4C Diagram (Context) Diagram 🦺⚠️', link: '/syntax/c4c' }, + { text: 'Mindmaps 🔥', link: '/syntax/mindmap' }, + { text: 'Other Examples', link: '/syntax/examples' }, + ], + }, + ]; +} + +function sidebarConfig() { + return [ + { + text: '⚙️ Deployment and Configuration', + collapsible: true, + items: [ + { text: 'Configuration', link: '/config/configuration' }, + { text: 'Tutorials', link: '/config/Tutorials' }, + { text: 'API-Usage', link: '/config/usage' }, + { text: 'Mermaid API Configuration', link: '/config/setup/README' }, + { text: 'Directives', link: '/config/directives' }, + { text: 'Theming', link: '/config/theming' }, + { text: 'Accessibility', link: '/config/accessibility' }, + { text: 'Mermaid CLI', link: '/config/mermaidCLI' }, + { text: 'Advanced usage', link: '/config/n00b-advanced' }, + ], + }, + ]; +} + +function sidebarMisc() { + return [ + { + text: '📚 Misc', + collapsible: true, + items: [ + { text: 'Use-Cases and Integrations', link: '/misc/integrations' }, + { text: 'FAQ', link: '/misc/faq' }, + ], + }, + ]; +} + +function sidebarCommunity() { + return [ + { + text: '🙌 Contributions and Community', + collapsible: true, + items: [ + { text: 'Overview for Beginners', link: '/community/n00b-overview' }, + { + text: 'Development and Contribution', + link: '/community/development', + }, + { text: 'Adding Diagrams', link: '/community/newDiagram' }, + { text: 'Security', link: '/community/security' }, + ], + }, + ]; +} diff --git a/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts new file mode 100644 index 000000000..14340462c --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts @@ -0,0 +1,71 @@ +import type { MarkdownRenderer } from 'vitepress'; + +const MermaidExample = async (md: MarkdownRenderer) => { + const defaultRenderer = md.renderer.rules.fence; + + if (!defaultRenderer) { + throw new Error('defaultRenderer is undefined'); + } + + md.renderer.rules.fence = (tokens, index, options, env, slf) => { + const token = tokens[index]; + + if (token.info.trim() === 'mermaid-example') { + if (!md.options.highlight) { + // this function is always created by vitepress, but we need to check it + // anyway to make TypeScript happy + throw new Error( + 'Missing MarkdownIt highlight function (should be automatically created by vitepress' + ); + } + + // doing ```mermaid-example {line-numbers=5 highlight=14-17} is not supported + const langAttrs = ''; + return ` +
Code:
+
+ + mermaid + ${ + // html is pre-escaped by the highlight function + // (it also adds `v-pre` to ignore Vue template syntax) + md.options.highlight(token.content, 'mermaid', langAttrs) + } +
`; + } else if (token.info.trim() === 'mermaid') { + const key = index; + return ` + + + + + +`; + } + if (token.info.trim() === 'warning') { + return `

WARNING

${token.content}}

`; + } + + if (token.info.trim() === 'note') { + return `

NOTE

${token.content}}

`; + } + + if (token.info.trim() === 'jison') { + return `
+ + jison +
+      ${token.content.replace(//g, '>')}
+      
+
`; + } + + return defaultRenderer(tokens, index, options, env, slf); + }; +}; + +export default MermaidExample; diff --git a/packages/mermaid/src/docs/.vitepress/theme/Mermaid.vue b/packages/mermaid/src/docs/.vitepress/theme/Mermaid.vue new file mode 100644 index 000000000..85c13393c --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/Mermaid.vue @@ -0,0 +1,72 @@ + + + diff --git a/packages/mermaid/src/docs/.vitepress/theme/custom.css b/packages/mermaid/src/docs/.vitepress/theme/custom.css new file mode 100644 index 000000000..e1ef049cd --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/custom.css @@ -0,0 +1,27 @@ +:root { + --vp-c-brand: #ff3670; + --vp-c-brand-light: #ff5e8c; + --vp-c-brand-lighter: #ff85a8; + --vp-c-brand-lightest: #ff9bb7; + --vp-c-brand-dark: #bd34fe; + --vp-c-brand-darker: #9339bd; + --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); +} + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #ff3670); + + --vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #ff3670 50%); + --vp-home-hero-image-filter: blur(72px); +} + +.vp-doc > div { + width: 100%; +} + +a.edit { + margin: 12px; + position: relative; + top: 10px; +} diff --git a/packages/mermaid/src/docs/.vitepress/theme/index.ts b/packages/mermaid/src/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..efb065fea --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/index.ts @@ -0,0 +1,26 @@ +import DefaultTheme from 'vitepress/theme'; +import './custom.css'; +// @ts-ignore +import Mermaid from './Mermaid.vue'; +import { getRedirect } from './redirect'; + +export default { + ...DefaultTheme, + enhanceApp({ app, router }) { + // register global components + app.component('Mermaid', Mermaid); + router.onBeforeRouteChange = (to) => { + if (router.route.path !== '/') { + return; + } + try { + const newPath = getRedirect(to); + if (newPath) { + console.log(`Redirecting to ${newPath} from ${window.location}`); + // router.go isn't loading the ID properly. + window.location.href = `/mermaid/${newPath}`; + } + } catch (e) {} + }; + }, +} as typeof DefaultTheme; diff --git a/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts new file mode 100644 index 000000000..b287346f9 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts @@ -0,0 +1,14 @@ +import mermaid, { type MermaidConfig } from 'mermaid'; +import mindmap from '@mermaid-js/mermaid-mindmap'; + +try { + await mermaid.registerExternalDiagrams([mindmap]); +} catch (e) { + console.error(e); +} + +export const render = async (id: string, code: string, config: MermaidConfig): Promise => { + mermaid.initialize(config); + const svg = await mermaid.renderAsync(id, code); + return svg; +}; diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts new file mode 100644 index 000000000..c26364108 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts @@ -0,0 +1,37 @@ +// This file should be moved into .vitepress folder once https://github.com/vitest-dev/vitest/issues/2344 is resolved. +// Update https://github.com/mermaid-js/mermaid/blob/18c27c6f1d0537a738cbd95898df301b83c38ffc/packages/mermaid/src/docs.mts#L246 once fixed + +import { expect, test } from 'vitest'; +import { getRedirect } from './redirect'; + +test.each([ + ['http://localhost:1234/mermaid/#/flowchart.md', 'syntax/flowchart.html'], + ['http://localhost/mermaid/#/flowchart.md', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#/flowchart.md', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#/./flowchart', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#/flowchart', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#flowchart', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#/flowchart', 'syntax/flowchart.html'], + ['https://mermaid-js.github.io/mermaid/#/flowchart.md?id=my-id', 'syntax/flowchart.html#my-id'], + ['https://mermaid-js.github.io/mermaid/#/./flowchart.md?id=my-id', 'syntax/flowchart.html#my-id'], + [ + 'https://mermaid-js.github.io/mermaid/#/flowchart?another=test&id=my-id&one=more', + 'syntax/flowchart.html#my-id', + ], + ['https://mermaid-js.github.io/mermaid/#/n00b-advanced', 'config/n00b-advanced.html'], + ['https://mermaid-js.github.io/mermaid/#/n00b-advanced.md', 'config/n00b-advanced.html'], + [ + 'https://mermaid-js.github.io/mermaid/#/flowchart?id=a-node-in-the-form-of-a-circle', + 'syntax/flowchart.html#a-node-in-the-form-of-a-circle', + ], +])('should process url %s to %s', (link: string, path: string) => { + expect(getRedirect(link)).toBe(path); +}); + +test('should throw for invalid URL', () => { + // Not mermaid domain + expect(() => getRedirect('https://www.google.com')).toThrowError(); + + // Not `/mermaid/` path + expect(() => getRedirect('http://localhost/#/flowchart.md')).toThrowError(); +}); diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts new file mode 100644 index 000000000..ca4606be0 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts @@ -0,0 +1,89 @@ +export interface Redirect { + path: string; + id?: string; +} + +/** + * Extracts the base slug from the old URL. + * @param link - The old URL. + */ +const getBaseFile = (link: string): Redirect => { + const url = new URL(link); + if ( + (url.hostname !== 'mermaid-js.github.io' && url.hostname !== 'localhost') || + url.pathname !== '/mermaid/' + ) { + throw new Error('Not mermaidjs url'); + } + const [path, params, ...rest] = url.hash + .toLowerCase() + .replace('.md', '') + .replace(/^#\/?/g, '') + .replace(/^\.\//g, '') + .split('?'); + + // Find id in params + const id = params + ?.split('&') + .find((param) => param.startsWith('id=')) + ?.split('=')[1]; + + return { path, id }; +}; + +const redirectMap: Record = { + '8.6.0_docs': '', + accessibility: 'config/theming', + breakingchanges: '', + c4c: 'syntax/c4c', + classdiagram: 'syntax/classDiagram', + configuration: 'config/configuration', + demos: 'misc/integrations', + development: 'community/development', + directives: 'config/directives', + entityrelationshipdiagram: 'syntax/entityRelationshipDiagram', + examples: 'syntax/examples', + faq: 'misc/faq', + flowchart: 'syntax/flowchart', + gantt: 'syntax/gantt', + gitgraph: 'syntax/gitgraph', + integrations: 'misc/integrations', + 'language-highlight': '', + markdown: '', + mermaidapi: 'config/usage', + mermaidcli: 'config/mermaidCLI', + mindmap: 'syntax/mindmap', + 'more-pages': '', + 'n00b-advanced': 'config/n00b-advanced', + 'n00b-gettingstarted': 'intro/n00b-gettingStarted', + 'n00b-overview': 'community/n00b-overview', + 'n00b-syntaxreference': '', + newdiagram: 'community/newDiagram', + pie: 'syntax/pie', + plugins: '', + quickstart: 'intro/n00b-gettingStarted', + requirementdiagram: 'syntax/requirementDiagram', + security: 'community/security', + sequencediagram: 'syntax/sequenceDiagram', + setup: 'config/setup/README', + statediagram: 'syntax/stateDiagram', + themes: 'config/theming', + theming: 'config/theming', + tutorials: 'config/Tutorials', + upgrading: '', + usage: 'config/usage', + 'user-journey': 'syntax/userJourney', +}; + +/** + * + * @param link - The old documentation URL. + * @returns The new documentation path. + */ +export const getRedirect = (link: string): string | undefined => { + const { path, id } = getBaseFile(link); + if (!(path in redirectMap)) { + return; + } + return `${redirectMap[path]}.html${id ? `#${id}` : ''}`; +}; diff --git a/packages/mermaid/src/docs/CHANGELOG.md b/packages/mermaid/src/docs/CHANGELOG.md index b80e52b30..cc725bf00 100644 --- a/packages/mermaid/src/docs/CHANGELOG.md +++ b/packages/mermaid/src/docs/CHANGELOG.md @@ -11,10 +11,10 @@ All changes are in descending order, beginning with the newest (latest) version. 🔖 [Release Notes](https://github.com/mermaid-js/mermaid/releases/tag/8.7.0) | 📜 [Full Changelog](https://github.com/mermaid-js/mermaid/compare/8.6.0...8.7.0) -This version brings with it a system for [dynamic and integrated configuration of the diagram themes](./theming.md). +This version brings with it a system for [dynamic and integrated configuration of the diagram themes](config/theming.md). The objective of this is to increase the customizability of mermaid and the ease of Styling, with the customization of themes through the `%%init%%` directive and `initialize` calls. -Themes follow and build upon the Levels of Configuration and employ `directives` to modify and create custom configurations, as they were introduced in Version [8.6.0](../getting-started/8.6.0_docs.md). +Themes follow and build upon the Levels of Configuration and employ `directives` to modify and create custom configurations, as they were introduced in Version [8.6.0](config/8.6.0_docs.md). **These Theming Configurations, similar to directives, will also be made applicable in the Live-Editor, for easier styling.** diff --git a/packages/mermaid/src/docs/Configuration.md b/packages/mermaid/src/docs/Configuration.md deleted file mode 100644 index 6eaab8e47..000000000 --- a/packages/mermaid/src/docs/Configuration.md +++ /dev/null @@ -1,20 +0,0 @@ -# Configuration - -Configuration is the second half of Mermaid, after deployment. Together Deployment and Configuration constitute the whole of Mermaid. - -This section will introduce the different methods of configuring of the behaviors and appearances of Mermaid Diagrams. -The Following are the most commonly used methods, and are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods. - -## Configuration Section in the [Live Editor](https://mermaid.live/). - -## The `initialize()` call, for when Mermaid is called via an API, or through a - -A summary of all options and their defaults is found [here][3]. -A description of each option follows below. - -## theme - -Theme , the CSS style sheet - -| Parameter | Description | Type | Required | Values | -| --------- | --------------- | ------ | -------- | ---------------------------------------------- | -| theme | Built in Themes | string | Optional | 'default', 'forest', 'dark', 'neutral', 'null' | - -**Notes:** To disable any pre-defined mermaid theme, use "null".
 "theme": "forest",
-"themeCSS": ".node rect { fill: red; }" 
- -## fontFamily - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------------------------------------------ | ------ | -------- | --------------------------- | -| fontFamily | specifies the font to be used in the rendered diagrams | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: '"trebuchet ms", verdana, arial, sans-serif;'. - -## logLevel - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------------------------- | ---------------- | -------- | --------------------------------------------- | -| logLevel | This option decides the amount of logging to be used. | string \| number | Required | 'trace','debug','info','warn','error','fatal' | - -**Notes:** - -- Trace: 0 -- Debug: 1 -- Info: 2 -- Warn: 3 -- Error: 4 -- Fatal: 5 (default) - -## securityLevel - -| Parameter | Description | Type | Required | Values | -| ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ | -| securityLevel | Level of trust for parsed diagram | string | Required | 'sandbox', 'strict', 'loose', 'antiscript' | - -**Notes**: - -- **strict**: (**default**) tags in text are encoded, click functionality is disabled -- **loose**: tags in text are allowed, click functionality is enabled -- **antiscript**: html tags in text are allowed, (only script element is removed), click - functionality is enabled -- **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This - prevent any JavaScript from running in the context. This may hinder interactive functionality - of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc. - -## startOnLoad - -| Parameter | Description | Type | Required | Values | -| ----------- | -------------------------------------------- | ------- | -------- | ----------- | -| startOnLoad | Dictates whether mermaid starts on Page load | boolean | Required | true, false | - -**Notes:** Default value: true - -## arrowMarkerAbsolute - -| Parameter | Description | Type | Required | Values | -| ------------------- | ---------------------------------------------------------------------------- | ------- | -------- | ----------- | -| arrowMarkerAbsolute | Controls whether or arrow markers in html code are absolute paths or anchors | boolean | Required | true, false | - -**Notes**: - -This matters if you are using base tag settings. - -Default value: false - -## secure - -This option controls which currentConfig keys are considered _secure_ and can only be changed -via call to mermaidAPI.initialize. Calls to mermaidAPI.reinitialize cannot make changes to the -`secure` keys in the current currentConfig. This prevents malicious graph directives from -overriding a site's default security. - -**Notes**: - -Default value: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'] - -## deterministicIds - -This option controls if the generated ids of nodes in the SVG are generated randomly or based -on a seed. If set to false, the IDs are generated based on the current date and thus are not -deterministic. This is the default behaviour. - -**Notes**: - -This matters if your files are checked into sourcecontrol e.g. git and should not change unless -content is changed. - -Default value: false - -## deterministicIDSeed - -This option is the optional seed for deterministic ids. if set to undefined but -deterministicIds is true, a simple number iterator is used. You can set this attribute to base -the seed on a static string. - -## flowchart - -The object containing configurations specific for flowcharts - -### diagramPadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | -| diagramPadding | Amount of padding around the diagram as a whole | Integer | Required | Any Positive Value | - -**Notes:** - -The amount of padding around the diagram as a whole so that embedded diagrams have margins, -expressed in pixels - -Default value: 8 - -### htmlLabels - -| Parameter | Description | Type | Required | Values | -| ---------- | -------------------------------------------------------------------------------------------- | ------- | -------- | ----------- | -| htmlLabels | Flag for setting whether or not a html tag should be used for rendering labels on the edges. | boolean | Required | true, false | - -**Notes:** Default value: true. - -### nodeSpacing - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------------------------------------- | ------- | -------- | ------------------- | -| nodeSpacing | Defines the spacing between nodes on the same level | Integer | Required | Any positive Number | - -**Notes:** - -Pertains to horizontal spacing for TB (top to bottom) or BT (bottom to top) graphs, and the -vertical spacing for LR as well as RL graphs.\*\* - -Default value: 50 - -### rankSpacing - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------------------------------------------------- | ------- | -------- | ------------------- | -| rankSpacing | Defines the spacing between nodes on different levels | Integer | Required | Any Positive Number | - -**Notes**: - -Pertains to vertical spacing for TB (top to bottom) or BT (bottom to top), and the horizontal -spacing for LR as well as RL graphs. - -Default value 50 - -### curve - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------------------------------- | ------ | -------- | ----------------------------- | -| curve | Defines how mermaid renders curves for flowcharts. | string | Required | 'basis', 'linear', 'cardinal' | - -**Notes:** - -Default Value: 'basis' - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes:** - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-wrapper' - -## sequence - -The object containing configurations specific for sequence diagrams - -### activationWidth - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------- | ------- | -------- | ------------------ | -| activationWidth | Width of the activation rect | Integer | Required | Any Positive Value | - -**Notes:** Default value :10 - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | ------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### actorMargin - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------- | ------- | -------- | ------------------ | -| actorMargin | Margin between actors | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------- | ------- | -------- | ------------------ | -| width | Width of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 150 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| height | Height of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 65 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------------ | ------- | -------- | ------------------ | -| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### boxTextMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| boxTextMargin | Margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 5 - -### noteMargin - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------- | ------- | -------- | ------------------ | -| noteMargin | margin around notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### messageMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | ---------------------- | ------- | -------- | ------------------ | -| messageMargin | Space between messages | Integer | Required | Any Positive Value | - -**Notes:** Default value: 35 - -### messageAlign - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ------ | -------- | ------------------------- | -| messageAlign | Multiline message alignment | string | Required | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### mirrorActors - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ------- | -------- | ----------- | -| mirrorActors | Mirror actors under diagram | boolean | Required | true, false | - -**Notes:** Default value: true - -### forceMenus - -| Parameter | Description | Type | Required | Values | -| ---------- | ----------------------------------------------------------------------- | ------- | -------- | ----------- | -| forceMenus | forces actor popup menus to always be visible (to support E2E testing). | Boolean | Required | True, False | - -**Notes:** - -Default value: false. - -### bottomMarginAdj - -| Parameter | Description | Type | Required | Values | -| --------------- | ------------------------------------------ | ------- | -------- | ------------------ | -| bottomMarginAdj | Prolongs the edge of the diagram downwards | Integer | Required | Any Positive Value | - -**Notes:** - -Depending on css styling this might need adjustment. - -Default value: 1 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** When this flag is set to true, the height and width is set to 100% and is then -scaling with the available space. If set to false, the absolute space required is used. - -Default value: true - -### rightAngles - -| Parameter | Description | Type | Required | Values | -| ----------- | ------------------------------------ | ------- | -------- | ----------- | -| rightAngles | display curve arrows as right angles | boolean | Required | true, false | - -**Notes:** - -This will display arrows that start and begin at the same node as right angles, rather than a -curve - -Default value: false - -### showSequenceNumbers - -| Parameter | Description | Type | Required | Values | -| ------------------- | ------------------------------- | ------- | -------- | ----------- | -| showSequenceNumbers | This will show the node numbers | boolean | Required | true, false | - -**Notes:** Default value: false - -### actorFontSize - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------------- | ------- | -------- | ------------------ | -| actorFontSize | This sets the font size of the actor's description | Integer | Require | Any Positive Value | - -**Notes:** **Default value 14**.. - -### actorFontFamily - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------------------------------- | ------ | -------- | --------------------------- | -| actorFontFamily | This sets the font family of the actor's description | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: "'Open Sans", sans-serif' - -### actorFontWeight - -This sets the font weight of the actor's description - -**Notes:** Default value: 400. - -### noteFontSize - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------------------------------------------- | ------- | -------- | ------------------ | -| noteFontSize | This sets the font size of actor-attached notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 14 - -### noteFontFamily - -| Parameter | Description | Type | Required | Values | -| -------------- | -------------------------------------------------- | ------ | -------- | --------------------------- | -| noteFontFamily | This sets the font family of actor-attached notes. | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: ''"trebuchet ms", verdana, arial, sans-serif' - -### noteFontWeight - -This sets the font weight of the note's description - -**Notes:** Default value: 400 - -### noteAlign - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------------------------------------- | ------ | -------- | ------------------------- | -| noteAlign | This sets the text alignment of actor-attached notes | string | required | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### messageFontSize - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------------------------------------- | ------- | -------- | ------------------- | -| messageFontSize | This sets the font size of actor messages | Integer | Required | Any Positive Number | - -**Notes:** Default value: 16 - -### messageFontFamily - -| Parameter | Description | Type | Required | Values | -| ----------------- | ------------------------------------------- | ------ | -------- | --------------------------- | -| messageFontFamily | This sets the font family of actor messages | string | Required | Any Possible CSS FontFamily | - -**Notes:** Default value: '"trebuchet ms", verdana, arial, sans-serif' - -### messageFontWeight - -This sets the font weight of the message's description - -**Notes:** Default value: 400. - -### wrap - -This sets the auto-wrap state for the diagram - -**Notes:** Default value: false. - -### wrapPadding - -This sets the auto-wrap padding for the diagram (sides only) - -**Notes:** Default value: 0. - -### labelBoxWidth - -This sets the width of the loop-box (loop, alt, opt, par) - -**Notes:** Default value: 50. - -### labelBoxHeight - -This sets the height of the loop-box (loop, alt, opt, par) - -**Notes:** Default value: 20. - -## gantt - -The object containing configurations specific for gantt diagrams - -### titleTopMargin - -### titleTopMargin - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | -| titleTopMargin | Margin top for the text over the gantt diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 25 - -### barHeight - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------- | ------- | -------- | ------------------ | -| barHeight | The height of the bars in the graph | Integer | Required | Any Positive Value | - -**Notes:** Default value: 20 - -### barGap - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------------------------------------------------- | ------- | -------- | ------------------ | -| barGap | The margin between the different activities in the gantt diagram | Integer | Optional | Any Positive Value | - -**Notes:** Default value: 4 - -### topPadding - -| Parameter | Description | Type | Required | Values | -| ---------- | -------------------------------------------------------------------------- | ------- | -------- | ------------------ | -| topPadding | Margin between title and gantt diagram and between axis and gantt diagram. | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### rightPadding - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------------------------------------------------------------------- | ------- | -------- | ------------------ | -| rightPadding | The space allocated for the section name to the right of the activities | Integer | Required | Any Positive Value | - -**Notes:** Default value: 75 - -### leftPadding - -| Parameter | Description | Type | Required | Values | -| ----------- | ---------------------------------------------------------------------- | ------- | -------- | ------------------ | -| leftPadding | The space allocated for the section name to the left of the activities | Integer | Required | Any Positive Value | - -**Notes:** Default value: 75 - -### gridLineStartPadding - -| Parameter | Description | Type | Required | Values | -| -------------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| gridLineStartPadding | Vertical starting position of the grid lines | Integer | Required | Any Positive Value | - -**Notes:** Default value: 35 - -### fontSize - -| Parameter | Description | Type | Required | Values | -| --------- | ----------- | ------- | -------- | ------------------ | -| fontSize | Font size | Integer | Required | Any Positive Value | - -**Notes:** Default value: 11 - -### sectionFontSize - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------- | ------- | -------- | ------------------ | -| sectionFontSize | Font size for sections | Integer | Required | Any Positive Value | - -**Notes:** Default value: 11 - -### numberSectionStyles - -| Parameter | Description | Type | Required | Values | -| ------------------- | ---------------------------------------- | ------- | -------- | ------------------ | -| numberSectionStyles | The number of alternating section styles | Integer | 4 | Any Positive Value | - -**Notes:** Default value: 4 - -### axisFormat - -| Parameter | Description | Type | Required | Values | -| ---------- | --------------------------- | ---- | -------- | ---------------- | -| axisFormat | Datetime format of the axis | 3 | Required | Date in yy-mm-dd | - -**Notes:** - -This might need adjustment to match your locale and preferences - -Default value: '%Y-%m-%d'. - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### topAxis - -| Parameter | Description | Type | Required | Values | -| --------- | ----------- | ------- | -------- | ----------- | -| topAxis | See notes | Boolean | 4 | True, False | - -**Notes:** when this flag is set date labels will be added to the top of the chart - -**Default value false**. - -## journey - -The object containing configurations specific for journey diagrams - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the sequence diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | -------------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the sequence diagram. | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### leftMargin - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------- | ------- | -------- | ------------------ | -| actorMargin | Margin between actors | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------- | ------- | -------- | ------------------ | -| width | Width of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 150 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| height | Height of actor boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 65 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------------ | ------- | -------- | ------------------ | -| boxMargin | Margin around loop boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### boxTextMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | -------------------------------------------- | ------- | -------- | ------------------ | -| boxTextMargin | Margin around the text in loop/alt/opt boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 5 - -### noteMargin - -| Parameter | Description | Type | Required | Values | -| ---------- | ------------------- | ------- | -------- | ------------------ | -| noteMargin | Margin around notes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### messageMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | ----------------------- | ------- | -------- | ------------------ | -| messageMargin | Space between messages. | Integer | Required | Any Positive Value | - -**Notes:** - -Space between messages. - -Default value: 35 - -### messageAlign - -| Parameter | Description | Type | Required | Values | -| ------------ | --------------------------- | ---- | -------- | ------------------------- | -| messageAlign | Multiline message alignment | 3 | 4 | 'left', 'center', 'right' | - -**Notes:** Default value: 'center' - -### bottomMarginAdj - -| Parameter | Description | Type | Required | Values | -| --------------- | ------------------------------------------ | ------- | -------- | ------------------ | -| bottomMarginAdj | Prolongs the edge of the diagram downwards | Integer | 4 | Any Positive Value | - -**Notes:** - -Depending on css styling this might need adjustment. - -Default value: 1 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -### rightAngles - -| Parameter | Description | Type | Required | Values | -| ----------- | --------------------------------- | ---- | -------- | ----------- | -| rightAngles | Curved Arrows become Right Angles | 3 | 4 | true, false | - -**Notes:** - -This will display arrows that start and begin at the same node as right angles, rather than a -curves - -Default value: false - -## useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -## defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes**: - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-d3' - -## useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See notes | boolean | 4 | true, false | - -**Notes:** - -When this flag is set the height and width is set to 100% and is then scaling with the -available space if not the absolute space required is used. - -Default value: true - -## defaultRenderer - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ----------------------- | -| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | - -**Notes:** - -Decides which rendering engine that is to be used for the rendering. Legal values are: -dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid - -Default value: 'dagre-d3' - -## er - -The object containing configurations specific for entity relationship diagrams - -### diagramPadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ----------------------------------------------- | ------- | -------- | ------------------ | -| diagramPadding | Amount of padding around the diagram as a whole | Integer | Required | Any Positive Value | - -**Notes:** - -The amount of padding around the diagram as a whole so that embedded diagrams have margins, -expressed in pixels - -Default value: 20 - -### layoutDirection - -| Parameter | Description | Type | Required | Values | -| --------------- | ---------------------------------------- | ------ | -------- | ---------------------- | -| layoutDirection | Directional bias for layout of entities. | string | Required | "TB", "BT", "LR", "RL" | - -**Notes:** - -'TB' for Top-Bottom, 'BT'for Bottom-Top, 'LR' for Left-Right, or 'RL' for Right to Left. - -T = top, B = bottom, L = left, and R = right. - -Default value: 'TB' - -### minEntityWidth - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------- | ------- | -------- | ------------------ | -| minEntityWidth | The minimum width of an entity box | Integer | Required | Any Positive Value | - -**Notes:** Expressed in pixels. Default value: 100 - -### minEntityHeight - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------------------------------- | ------- | -------- | ------------------ | -| minEntityHeight | The minimum height of an entity box | Integer | 4 | Any Positive Value | - -**Notes:** Expressed in pixels Default value: 75 - -### entityPadding - -| Parameter | Description | Type | Required | Values | -| ------------- | ------------------------------------------------------------ | ------- | -------- | ------------------ | -| entityPadding | Minimum internal padding between text in box and box borders | Integer | 4 | Any Positive Value | - -**Notes:** - -The minimum internal padding between text in an entity box and the enclosing box borders, -expressed in pixels. - -Default value: 15 - -### stroke - -| Parameter | Description | Type | Required | Values | -| --------- | ----------------------------------- | ------ | -------- | -------------------- | -| stroke | Stroke color of box edges and lines | string | 4 | Any recognized color | - -**Notes:** Default value: 'gray' - -### fill - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------- | ------ | -------- | -------------------- | -| fill | Fill color of entity boxes | string | 4 | Any recognized color | - -**Notes:** Default value: 'honeydew' - -### fontSize - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------- | ------- | -------- | ------------------ | -| fontSize | Font Size in pixels | Integer | | Any Positive Value | - -**Notes:** - -Font size (expressed as an integer representing a number of pixels) Default value: 12 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## pie - -The object containing configurations specific for pie diagrams - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## requirement - -The object containing configurations specific for req diagrams - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** - -When this flag is set to true, the diagram width is locked to 100% and scaled based on -available space. If set to false, the diagram reserves its absolute width. - -Default value: true - -## c4 - -The object containing configurations specific for c4 diagrams - -### diagramMarginX - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginX | Margin to the right and left of the c4 diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### diagramMarginY - -| Parameter | Description | Type | Required | Values | -| -------------- | ------------------------------------------- | ------- | -------- | ------------------ | -| diagramMarginY | Margin to the over and under the c4 diagram | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### c4ShapeMargin - -| Parameter | Description | Type | Required | Values | -| ------------- | --------------------- | ------- | -------- | ------------------ | -| c4ShapeMargin | Margin between shapes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 50 - -### c4ShapePadding - -| Parameter | Description | Type | Required | Values | -| -------------- | ---------------------- | ------- | -------- | ------------------ | -| c4ShapePadding | Padding between shapes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 20 - -### width - -| Parameter | Description | Type | Required | Values | -| --------- | --------------------- | ------- | -------- | ------------------ | -| width | Width of person boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 216 - -### height - -| Parameter | Description | Type | Required | Values | -| --------- | ---------------------- | ------- | -------- | ------------------ | -| height | Height of person boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 60 - -### boxMargin - -| Parameter | Description | Type | Required | Values | -| --------- | ------------------- | ------- | -------- | ------------------ | -| boxMargin | Margin around boxes | Integer | Required | Any Positive Value | - -**Notes:** Default value: 10 - -### useMaxWidth - -| Parameter | Description | Type | Required | Values | -| ----------- | ----------- | ------- | -------- | ----------- | -| useMaxWidth | See Notes | boolean | Required | true, false | - -**Notes:** When this flag is set to true, the height and width is set to 100% and is then -scaling with the available space. If set to false, the absolute space required is used. - -Default value: true - -### c4ShapeInRow - -| Parameter | Description | Type | Required | Values | -| ------------ | ----------- | ------- | -------- | ------------------ | -| c4ShapeInRow | See Notes | Integer | Required | Any Positive Value | - -**Notes:** How many shapes to place in each row. - -Default value: 4 - -### c4BoundaryInRow - -| Parameter | Description | Type | Required | Values | -| --------------- | ----------- | ------- | -------- | ------------------ | -| c4BoundaryInRow | See Notes | Integer | Required | Any Positive Value | - -**Notes:** How many boundarys to place in each row. - -Default value: 2 - -### personFontSize - -This sets the font size of Person shape for the diagram - -**Notes:** Default value: 14. - -### personFontFamily - -This sets the font family of Person shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### personFontWeight - -This sets the font weight of Person shape for the diagram - -**Notes:** Default value: normal. - -### external_personFontSize - -This sets the font size of External Person shape for the diagram - -**Notes:** Default value: 14. - -### external_personFontFamily - -This sets the font family of External Person shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_personFontWeight - -This sets the font weight of External Person shape for the diagram - -**Notes:** Default value: normal. - -### systemFontSize - -This sets the font size of System shape for the diagram - -**Notes:** Default value: 14. - -### systemFontFamily - -This sets the font family of System shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### systemFontWeight - -This sets the font weight of System shape for the diagram - -**Notes:** Default value: normal. - -### external_systemFontSize - -This sets the font size of External System shape for the diagram - -**Notes:** Default value: 14. - -### external_systemFontFamily - -This sets the font family of External System shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_systemFontWeight - -This sets the font weight of External System shape for the diagram - -**Notes:** Default value: normal. - -### system_dbFontSize - -This sets the font size of System DB shape for the diagram - -**Notes:** Default value: 14. - -### system_dbFontFamily - -This sets the font family of System DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### system_dbFontWeight - -This sets the font weight of System DB shape for the diagram - -**Notes:** Default value: normal. - -### external_system_dbFontSize - -This sets the font size of External System DB shape for the diagram - -**Notes:** Default value: 14. - -### external_system_dbFontFamily - -This sets the font family of External System DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_system_dbFontWeight - -This sets the font weight of External System DB shape for the diagram - -**Notes:** Default value: normal. - -### system_queueFontSize - -This sets the font size of System Queue shape for the diagram - -**Notes:** Default value: 14. - -### system_queueFontFamily - -This sets the font family of System Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### system_queueFontWeight - -This sets the font weight of System Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_system_queueFontSize - -This sets the font size of External System Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_system_queueFontFamily - -This sets the font family of External System Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_system_queueFontWeight - -This sets the font weight of External System Queue shape for the diagram - -**Notes:** Default value: normal. - -### boundaryFontSize - -This sets the font size of Boundary shape for the diagram - -**Notes:** Default value: 14. - -### boundaryFontFamily - -This sets the font family of Boundary shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### boundaryFontWeight - -This sets the font weight of Boundary shape for the diagram - -**Notes:** Default value: normal. - -### messageFontSize - -This sets the font size of Message shape for the diagram - -**Notes:** Default value: 12. - -### messageFontFamily - -This sets the font family of Message shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### messageFontWeight - -This sets the font weight of Message shape for the diagram - -**Notes:** Default value: normal. - -### containerFontSize - -This sets the font size of Container shape for the diagram - -**Notes:** Default value: 14. - -### containerFontFamily - -This sets the font family of Container shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### containerFontWeight - -This sets the font weight of Container shape for the diagram - -**Notes:** Default value: normal. - -### external_containerFontSize - -This sets the font size of External Container shape for the diagram - -**Notes:** Default value: 14. - -### external_containerFontFamily - -This sets the font family of External Container shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_containerFontWeight - -This sets the font weight of External Container shape for the diagram - -**Notes:** Default value: normal. - -### container_dbFontSize - -This sets the font size of Container DB shape for the diagram - -**Notes:** Default value: 14. - -### container_dbFontFamily - -This sets the font family of Container DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### container_dbFontWeight - -This sets the font weight of Container DB shape for the diagram - -**Notes:** Default value: normal. - -### external_container_dbFontSize - -This sets the font size of External Container DB shape for the diagram - -**Notes:** Default value: 14. - -### external_container_dbFontFamily - -This sets the font family of External Container DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_container_dbFontWeight - -This sets the font weight of External Container DB shape for the diagram - -**Notes:** Default value: normal. - -### container_queueFontSize - -This sets the font size of Container Queue shape for the diagram - -**Notes:** Default value: 14. - -### container_queueFontFamily - -This sets the font family of Container Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### container_queueFontWeight - -This sets the font weight of Container Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_container_queueFontSize - -This sets the font size of External Container Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_container_queueFontFamily - -This sets the font family of External Container Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_container_queueFontWeight - -This sets the font weight of External Container Queue shape for the diagram - -**Notes:** Default value: normal. - -### componentFontSize - -This sets the font size of Component shape for the diagram - -**Notes:** Default value: 14. - -### componentFontFamily - -This sets the font family of Component shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### componentFontWeight - -This sets the font weight of Component shape for the diagram - -**Notes:** Default value: normal. - -### external_componentFontSize - -This sets the font size of External Component shape for the diagram - -**Notes:** Default value: 14. - -### external_componentFontFamily - -This sets the font family of External Component shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_componentFontWeight - -This sets the font weight of External Component shape for the diagram - -**Notes:** Default value: normal. - -### component_dbFontSize - -This sets the font size of Component DB shape for the diagram - -**Notes:** Default value: 14. - -### component_dbFontFamily - -This sets the font family of Component DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### component_dbFontWeight - -This sets the font weight of Component DB shape for the diagram - -**Notes:** Default value: normal. - -### external_component_dbFontSize - -This sets the font size of External Component DB shape for the diagram - -**Notes:** Default value: 14. - -### external_component_dbFontFamily - -This sets the font family of External Component DB shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_component_dbFontWeight - -This sets the font weight of External Component DB shape for the diagram - -**Notes:** Default value: normal. - -### component_queueFontSize - -This sets the font size of Component Queue shape for the diagram - -**Notes:** Default value: 14. - -### component_queueFontFamily - -This sets the font family of Component Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### component_queueFontWeight - -This sets the font weight of Component Queue shape for the diagram - -**Notes:** Default value: normal. - -### external_component_queueFontSize - -This sets the font size of External Component Queue shape for the diagram - -**Notes:** Default value: 14. - -### external_component_queueFontFamily - -This sets the font family of External Component Queue shape for the diagram - -**Notes:** Default value: "Open Sans", sans-serif. - -### external_component_queueFontWeight - -This sets the font weight of External Component Queue shape for the diagram - -**Notes:** Default value: normal. - -### wrap - -This sets the auto-wrap state for the diagram - -**Notes:** Default value: true. - -### wrapPadding - -This sets the auto-wrap padding for the diagram (sides only) - -**Notes:** Default value: 0. - -## parse - -### Parameters - -- `text` **[string][4]** -- `parseError` **[Function][5]?** - -Returns **[boolean][6]** - -## setSiteConfig - -## setSiteConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------- | ----------- | --------------------------------------- | -| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | - -**Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls -to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) -will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this -function _Default value: At default, will mirror Global Config_ - -### Parameters - -- `conf` **MermaidConfig** The base currentConfig to use as siteConfig - -Returns **[object][7]** The siteConfig - -## getSiteConfig - -## getSiteConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------------------- | ----------- | -------------------------------- | -| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig | - -**Notes**: Returns **any** values in siteConfig. - -Returns **[object][7]** The siteConfig - -## setConfig - -## setConfig - -| Function | Description | Type | Values | -| ------------- | ------------------------------------- | ----------- | --------------------------------------- | -| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array | - -**Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure -keys. Any values found in conf with key found in siteConfig.secure will be replaced with the -corresponding siteConfig value. - -### Parameters - -- `conf` **any** The potential currentConfig - -Returns **any** The currentConfig merged with the sanitized conf - -## render - -Function that renders an svg with a graph from a chart definition. Usage example below. - -```javascript -mermaidAPI.initialize({ - startOnLoad: true, -}); -$(function () { - const graphDefinition = 'graph TB\na-->b'; - const cb = function (svgGraph) { - console.log(svgGraph); - }; - mermaidAPI.render('id1', graphDefinition, cb); -}); -``` - -### Parameters - -- `id` **[string][4]** The id of the element to be rendered -- `text` **[string][4]** The graph definition -- `cb` **function (svgCode: [string][4], bindFunctions: function (element: [Element][8]): void): void** -- `container` **[Element][8]** Selector to element in which a div with the graph temporarily will be - inserted. If one is provided a hidden div will be inserted in the body of the page instead. The - element will be removed when rendering is completed. - -Returns **void** - -## getConfig - -## getConfig - -| Function | Description | Type | Return Values | -| --------- | ------------------------- | ----------- | ------------------------------ | -| getConfig | Obtains the currentConfig | Get Request | Any Values from current Config | - -**Notes**: Returns **any** the currentConfig - -Returns **any** The currentConfig - -## sanitize - -## sanitize - -| Function | Description | Type | Values | -| -------- | -------------------------------------- | ----------- | ------ | -| sanitize | Sets the siteConfig to desired values. | Put Request | None | - -Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies -options in-place - -### Parameters - -- `options` **any** The potential setConfig parameter - -## addDirective - -Pushes in a directive to the configuration - -### Parameters - -- `directive` **[object][7]** The directive to push in - -## reset - -## reset - -| Function | Description | Type | Required | Values | -| -------- | ---------------------------- | ----------- | -------- | ------ | -| reset | Resets currentConfig to conf | Put Request | Required | None | - -## conf - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- | -| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array | - -**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) - -### Parameters - -- `config` (optional, default `siteConfig`) - -Returns **void** - -## initialize - -### Parameters - -- `options` **MermaidConfig** - -## - -## mermaidAPI configuration defaults - -```html - -``` - -[1]: Setup.md?id=render -[2]: 8.6.0_docs.md -[3]: #mermaidapi-configuration-defaults -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object -[8]: https://developer.mozilla.org/docs/Web/API/Element diff --git a/packages/mermaid/src/docs/_navbar.md b/packages/mermaid/src/docs/_navbar.md deleted file mode 100644 index c77bde3bd..000000000 --- a/packages/mermaid/src/docs/_navbar.md +++ /dev/null @@ -1,13 +0,0 @@ -- Getting started - - - [Quick start](quickstart.md) - - [Writing more pages](more-pages.md) - - [Custom navbar](custom-navbar.md) - - [Cover page](cover.md) - -- Configuration - - [Configuration](configuration.md) - - [Themes](themes.md) - - [Using plugins](plugins.md) - - [Markdown configuration](markdown.md) - - [Language highlight](language-highlight.md) diff --git a/packages/mermaid/src/docs/_sidebar.md b/packages/mermaid/src/docs/_sidebar.md deleted file mode 100644 index f89f30318..000000000 --- a/packages/mermaid/src/docs/_sidebar.md +++ /dev/null @@ -1,44 +0,0 @@ -- 📔 Introduction - - - [About Mermaid](README.md) - - [Deployment](n00b-gettingStarted.md) - - [Syntax and Configuration](n00b-syntaxReference.md) - -- 📊 Diagram Syntax - - - [Flowchart](flowchart.md) - - [Sequence Diagram](sequenceDiagram.md) - - [Class Diagram](classDiagram.md) - - [State Diagram](stateDiagram.md) - - [Entity Relationship Diagram](entityRelationshipDiagram.md) - - [User Journey](user-journey.md) - - [Gantt](gantt.md) - - [Pie Chart](pie.md) - - [Requirement Diagram](requirementDiagram.md) - - [Gitgraph (Git) Diagram 🔥](gitgraph.md) - - [C4C Diagram (Context) Diagram 🦺⚠️](c4c.md) - - [Mindmaps 🦺⚠️](mindmap.md) - - [Other Examples](examples.md) - -- ⚙️ Deployment and Configuration - - - [Tutorials](Tutorials.md) - - [API-Usage](usage.md) - - [Mermaid API Configuration](Setup.md) - - [Directives](directives.md) - - [Theming](theming.md) - - [Accessibility](accessibility.md) - - [Mermaid CLI](mermaidCLI.md) - - [Advanced usage](n00b-advanced.md) - -- 📚 Misc - - - [Use-Cases and Integrations](integrations.md) - - [FAQ](faq.md) - -- 🙌 Contributions and Community - - [Overview for Beginners](n00b-overview.md) - - [Development and Contribution ](development.md) - - [Changelog](CHANGELOG.md) - - [Adding Diagrams ](newDiagram.md) - - [Security ](security.md) diff --git a/packages/mermaid/src/docs/breakingChanges.md b/packages/mermaid/src/docs/breakingChanges.md deleted file mode 100644 index 41b411df6..000000000 --- a/packages/mermaid/src/docs/breakingChanges.md +++ /dev/null @@ -1,49 +0,0 @@ -# Breaking changes - -### Breaking changes from history version to latest version: - -## #1 - -```javascript -mermaid.initialize({ - sequenceDiagram:{ - ... - } -}) -``` - -has been changed to - -```javascript -mermaid.initialize({ - sequence:{ - ... - } -}) -``` - -## #2 - -In old versions you needed to reference a CSS file in your HTML: - -```html - -``` - -or - -```html - -``` - -Now it is not needed, and there are no more CSS files in the distribution files. - -You just: - -```javascript -mermaid.initialize({ - theme: 'forest', -}); -``` - -and it works like a charm because now the CSS is inline with the SVG to allow simpler portability. diff --git a/packages/mermaid/src/docs/development.md b/packages/mermaid/src/docs/community/development.md similarity index 85% rename from packages/mermaid/src/docs/development.md rename to packages/mermaid/src/docs/community/development.md index 80edb7719..bfa5ddfcf 100644 --- a/packages/mermaid/src/docs/development.md +++ b/packages/mermaid/src/docs/community/development.md @@ -6,7 +6,7 @@ So you want to help? That's great! Here are a few things to get you started on the right path. -**The Docs Structure is dictated by [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)** +**The Docs Structure is dictated by [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. **Note: Commits and Pull Requests should be directed to the develop branch.** @@ -26,7 +26,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 (we encourage updates to the `src/docs` folder; you can submit them via direct commits) +- Documentation (we encourage updates to the `/packages/mermaid/src/docs` folder; you can submit them via direct commits) When you commit code, create a branch with the following naming convention: @@ -44,9 +44,9 @@ Start with the type, such as **feature** or **bug**, followed by the issue numbe If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature? -The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via the **[sidebar](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +The docs are located in the `src/docs` folder and are written in Markdown. Just pick the right section and start typing. If you want to propose changes to the structure of the documentation, such as adding a new section or a new file you do that via **[.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. -> **All the documents displayed in the GitHub.io page are listed in [sidebar.md](https://github.com/mermaid-js/mermaid/edit/develop/src/docs/_sidebar.md)**. +> **All the documents displayed in the GitHub.io page are listed in [.vitepress/config.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/.vitepress/config.ts)**. The contents of [https://mermaid-js.github.io/mermaid/](https://mermaid-js.github.io/mermaid/) are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid-js.github.io/mermaid/) once released. @@ -58,7 +58,7 @@ The documentation is located in the `src/docs` directory and organized according The `docs` folder will be automatically generated when committing to `src/docs` and should not be edited manually. -We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) +We encourage contributions to the documentation at [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). We publish documentation using GitHub Pages with [Docsify](https://www.youtube.com/watch?v=TV88lp7egMw&t=3s) ### Add Unit Tests for Parsing @@ -111,7 +111,7 @@ Markdown is used to format the text, for more information about Markdown [see th To edit Docs on your computer: -1. Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs) directory in the `develop` branch. +1. Find the Markdown file (.md) to edit in the [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) directory in the `develop` branch. 2. Create a fork of the develop branch. 3. Make changes or add new documentation. 4. Commit changes to your fork and push it to GitHub. @@ -120,7 +120,7 @@ To edit Docs on your computer: To edit Docs on GitHub: 1. Login to [GitHub.com](https://www.github.com). -2. Navigate to [mermaid-js/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/src/docs). +2. Navigate to [packages/mermaid/src/docs](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs). 3. To edit a file, click the pencil icon at the top-right of the file contents panel. 4. Describe what you changed in the **Propose file change** section, located at the bottom of the page. 5. Submit your changes by clicking the button **Propose file change** at the bottom (by automatic creation of a fork and a new branch). diff --git a/packages/mermaid/src/docs/community/img/er.png b/packages/mermaid/src/docs/community/img/er.png new file mode 100644 index 000000000..21c44c257 Binary files /dev/null and b/packages/mermaid/src/docs/community/img/er.png differ diff --git a/packages/mermaid/src/docs/n00b-overview.md b/packages/mermaid/src/docs/community/n00b-overview.md similarity index 91% rename from packages/mermaid/src/docs/n00b-overview.md rename to packages/mermaid/src/docs/community/n00b-overview.md index b784ba737..a72e500bd 100644 --- a/packages/mermaid/src/docs/n00b-overview.md +++ b/packages/mermaid/src/docs/community/n00b-overview.md @@ -39,7 +39,7 @@ It is a relatively straightforward solution to a significant hurdle with the sof **Nodes** -> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](./n00b-syntaxReference) +> These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](../intro/n00b-syntaxReference.md) ## Advantages of using Mermaid @@ -63,6 +63,6 @@ In fact one can pick up the syntax for it quite easily from the examples given a ## Mermaid is for everyone. -Video [Tutorials](https://mermaid-js.github.io/mermaid/#/./Tutorials) are also available for the mermaid [live editor](https://mermaid.live/). +Video [Tutorials](https://mermaid-js.github.io/mermaid/#/../config/Tutorials) are also available for the mermaid [live editor](https://mermaid.live/). Alternatively you can use Mermaid [Plug-Ins](https://mermaid-js.github.io/mermaid/#/./integrations), with tools you already use, like Google Docs. diff --git a/packages/mermaid/src/docs/newDiagram.md b/packages/mermaid/src/docs/community/newDiagram.md similarity index 97% rename from packages/mermaid/src/docs/newDiagram.md rename to packages/mermaid/src/docs/community/newDiagram.md index 4b6c7dfd6..74026b3ff 100644 --- a/packages/mermaid/src/docs/newDiagram.md +++ b/packages/mermaid/src/docs/community/newDiagram.md @@ -26,7 +26,7 @@ statement In the extract of the grammar above, it is defined that a call to the setTitle method in the data object will be done when parsing and the title keyword is encountered. -```tip +```note Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user. ``` @@ -43,8 +43,7 @@ exports.parseError = function (err, hash) { when parsing the `yy` object is initialized as per below: ```javascript -var parser; -parser = exampleParser.parser; +const parser = exampleParser.parser; parser.yy = db; ``` @@ -67,8 +66,8 @@ At this point when mermaid is trying to render the diagram, it will detect it as ### Setup ```javascript -var graph = require('./graphDb'); -var flow = require('./parser/flow'); +const graph = require('./graphDb'); +const flow = require('./parser/flow'); flow.parser.yy = graph; ``` @@ -89,7 +88,7 @@ graph.getEdges(); The parser is also exposed in the mermaid api by calling: ```javascript -var parser = mermaid.getParser(); +const parser = mermaid.getParser(); ``` Note that the parse needs a graph object to store the data as per: @@ -115,13 +114,12 @@ There are a few features that are common between the different types of diagrams Here some pointers on how to handle these different areas. -#### [Directives](./directives.md) +#### [Directives](../config/directives.md) Here is example handling from flowcharts: Jison: ```jison - /* lexical grammar */ %lex %x open_directive @@ -180,6 +178,7 @@ accDescr { In a similar way to the directives the jison syntax are quite similar between the diagrams. ```jison + * lexical grammar */ %lex %x acc_title @@ -199,6 +198,7 @@ statement : acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } + ``` The functions for setting title and description are provided by a common module. This is the import from flowDb.js: @@ -228,7 +228,7 @@ addSVGAccessibilityFields(parser.yy, svg, id); ## Theming -Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](./theming.md). +Mermaid supports themes and has an integrated theming engine. You can read more about how the themes can be used [in the docs](../config/theming.md). When adding themes to a diagram it comes down to a few important locations in the code. diff --git a/packages/mermaid/src/docs/security.md b/packages/mermaid/src/docs/community/security.md similarity index 71% rename from packages/mermaid/src/docs/security.md rename to packages/mermaid/src/docs/community/security.md index 7e61a60cf..e7a0db6ed 100644 --- a/packages/mermaid/src/docs/security.md +++ b/packages/mermaid/src/docs/community/security.md @@ -4,13 +4,13 @@ The Mermaid team takes the security of Mermaid and the applications that use Mer ## Reporting vulnerabilities -To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. +To report a vulnerability, please e-mail with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue. We aim to reply within three working days, probably much sooner. -You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates. +You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to again if you do not receive prompt attention and regular updates. -You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. +You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk. ## Best practices diff --git a/packages/mermaid/src/docs/8.6.0_docs.md b/packages/mermaid/src/docs/config/8.6.0_docs.md similarity index 93% rename from packages/mermaid/src/docs/8.6.0_docs.md rename to packages/mermaid/src/docs/config/8.6.0_docs.md index 6ba835c2e..bc19e08d5 100644 --- a/packages/mermaid/src/docs/8.6.0_docs.md +++ b/packages/mermaid/src/docs/config/8.6.0_docs.md @@ -6,8 +6,8 @@ With version 8.6.0 comes the release of directives for mermaid, a new system for modifying configurations, with the aim of establishing centralized, sane defaults and simple implementation. -`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](./Setup.md). -This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. +`directives` allow for a single-use overwriting of `config`, as it has been discussed in [Configurations](../config/configuration.md). +This allows site Diagram Authors to instantiate temporary modifications to `config` through the use of [Directives](directives.md), which are parsed before rendering diagram definitions. This allows the Diagram Authors to alter the appearance of the diagrams. **A likely application for this is in the creation of diagrams/charts inside company/organizational webpages, that rely on mermaid for diagram and chart rendering.** @@ -64,7 +64,7 @@ Older versions of mermaid will not parse directives because `%%` will comment ou init would be an argument-directive: `%%{init: { **insert argument here**}}%%` The json object that is passed as {**argument** } must be valid, quoted json or it will be ignored. - **for example**: +**for example**: `%%{init: {"theme": "default", "logLevel": 1 }}%%` @@ -96,7 +96,7 @@ When deployed within code, init is called before the graph/diagram description. ```note Wrap is a function that is currently only deployable for sequence diagrams. -Wrap respects a manually added , so if the user wants to break up their text, they have full control over line breaks by adding tags. +`Wrap respects a manually added
, so if the user wants to break up their text, they have full control over line breaks by adding
tags.` It is a non-argument directive and can be executed thusly: @@ -105,7 +105,7 @@ It is a non-argument directive and can be executed thusly: **An example of text wrapping in a sequence diagram**: -![Image showing wrapped text](img/wrapped%20text.png) +![Image showing wrapped text](img/wrapped text.png) # Resetting Configurations: @@ -129,7 +129,7 @@ Example of **assignWithDepth**: Example of **object.Assign**: -![Image showing object.assign without depth](img/object.assign%20without%20depth.png) +![Image showing object.assign without depth](img/object.assign without depth.png) • **calculateTextDimensions**, **calculateTextWidth**, and **calculateTextHeight** - for measuring text dimensions, width and height. @@ -158,7 +158,7 @@ Default value: will mirror Global Config | `getSiteConfig` | Returns the current `siteConfig` base configuration | Get Request | Returns Any Values in `siteConfig` | ```note -Returns any values in siteConfig. +Returns any values in siteConfig. ``` ## setConfig @@ -207,7 +207,7 @@ Ensures options parameter does not attempt to override siteConfig secure keys. | `conf` | base set of values, which `currentConfig` could be reset to. | Dictionary | Required | Any Values, with respect to the secure Array | ```note -default: current siteConfig (optional, default `getSiteConfig()`) +default: current siteConfig (optional, default `getSiteConfig()`) ``` -## For more information, read [Setup](Setup.md). +## For more information, read [Setup](./setup/README.md). diff --git a/packages/mermaid/src/docs/Tutorials.md b/packages/mermaid/src/docs/config/Tutorials.md similarity index 94% rename from packages/mermaid/src/docs/Tutorials.md rename to packages/mermaid/src/docs/config/Tutorials.md index f4570d8b5..e07635641 100644 --- a/packages/mermaid/src/docs/Tutorials.md +++ b/packages/mermaid/src/docs/config/Tutorials.md @@ -4,7 +4,7 @@ This is list of publicly available Tutorials for using Mermaid.JS . This is inte **Note that these tutorials might display an older interface, but the usage of the live-editor will largely be the same.** -For most purposes, you can use the [Live Editor](https://mermaid-js.github.io/mermaid-live-editor), to quickly and easily render a diagram. +For most purposes, you can use the [Live Editor](https://mermaid.live), to quickly and easily render a diagram. ## Live-Editor Tutorials @@ -22,7 +22,7 @@ The definitions that can be generated the Live-Editor are also backwards-compati ## Mermaid with HTML -Examples are provided in [Getting Started](n00b-gettingStarted.md) +Examples are provided in [Getting Started](../intro/n00b-gettingStarted.md) **CodePen Examples:** diff --git a/packages/mermaid/src/docs/accessibility.md b/packages/mermaid/src/docs/config/accessibility.md similarity index 98% rename from packages/mermaid/src/docs/accessibility.md rename to packages/mermaid/src/docs/config/accessibility.md index 387871de4..ade20a839 100644 --- a/packages/mermaid/src/docs/accessibility.md +++ b/packages/mermaid/src/docs/config/accessibility.md @@ -17,7 +17,7 @@ The diagram authors can now add the accessibility options in the diagram definit - `accTitle: "Your Accessibility Title"` or - `accDescr: "Your Accessibility Description"` -**When these two options are defined, they will add a coressponding `` and `<desc>` tag in the SVG.** +**When these two options are defined, they will add a corresponding `<title>` and `<desc>` tag in the SVG.** Let us take a look at the following example with a flowchart diagram: diff --git a/packages/mermaid/src/docs/developer-docs/configuration.md b/packages/mermaid/src/docs/config/configuration.md similarity index 100% rename from packages/mermaid/src/docs/developer-docs/configuration.md rename to packages/mermaid/src/docs/config/configuration.md diff --git a/packages/mermaid/src/docs/directives.md b/packages/mermaid/src/docs/config/directives.md similarity index 95% rename from packages/mermaid/src/docs/directives.md rename to packages/mermaid/src/docs/config/directives.md index 47af50c31..bc74ad309 100644 --- a/packages/mermaid/src/docs/directives.md +++ b/packages/mermaid/src/docs/config/directives.md @@ -24,7 +24,7 @@ Mermaid basically supports two types of configuration options to be overridden b 2. _Diagram specific configurations_ : These are the configurations that are available and applied to a specific diagram. For each diagram there are specific configuration that will alter how that particular diagram looks and behaves. For example, `mirrorActors` is a configuration that is specific to the `SequenceDiagram` and alter whether the actors are mirrored or not. So this config is available only for the `SequenceDiagram` type. -**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code. +**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code. ``` Soon we plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs @@ -84,7 +84,7 @@ Here the directive declaration will set the `logLevel` to `debug` and the `theme Note: You can use 'init' or 'initialize' as both acceptable as init directives. Also note that `%%init%%` and `%%initialize%%` directives will be grouped together after they are parsed. This means: -```mmd2 +```mmd %%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% %%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%% ... @@ -92,11 +92,11 @@ Note: You can use 'init' or 'initialize' as both acceptable as init directives. parsing the above generates a single `%%init%%` JSON object below, combining the two directives and carrying over the last value given for `loglevel`: -```json5 +```json { - logLevel: 'fatal', - theme: 'dark', - startOnLoad: true, + "logLevel": "fatal", + "theme": "dark", + "startOnLoad": true } ``` @@ -188,7 +188,7 @@ Some common flowchart configurations are: - _diagramPadding_: number - _useMaxWidth_: number -For complete list of flowchart configurations, see [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code. +For complete list of flowchart configurations, see [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code. _Soon we plan to publish a complete list all diagram specific configurations updated in the docs_ The following code snippet changes flowchart config: @@ -221,7 +221,7 @@ Some common sequence configurations are: - _showSequenceNumbers_: boolean - _wrap_: boolean -For complete list of sequence diagram configurations, see _defaultConfig.js_ in the source code. +For complete list of sequence diagram configurations, see _defaultConfig.ts_ in the source code. _Soon we plan to publish a complete list all diagram specific configurations updated in the docs_ So, `wrap` by default has a value of `false` for sequence diagrams. diff --git a/packages/mermaid/src/docs/img/accessibility-div-example-2.png b/packages/mermaid/src/docs/config/img/accessibility-div-example-2.png similarity index 100% rename from packages/mermaid/src/docs/img/accessibility-div-example-2.png rename to packages/mermaid/src/docs/config/img/accessibility-div-example-2.png diff --git a/packages/mermaid/src/docs/img/accessibility-div-example.png b/packages/mermaid/src/docs/config/img/accessibility-div-example.png similarity index 100% rename from packages/mermaid/src/docs/img/accessibility-div-example.png rename to packages/mermaid/src/docs/config/img/accessibility-div-example.png diff --git a/packages/mermaid/src/docs/img/assignWithDepth.png b/packages/mermaid/src/docs/config/img/assignWithDepth.png similarity index 100% rename from packages/mermaid/src/docs/img/assignWithDepth.png rename to packages/mermaid/src/docs/config/img/assignWithDepth.png diff --git a/packages/mermaid/src/docs/img/object.assign without depth.png b/packages/mermaid/src/docs/config/img/object.assign without depth.png similarity index 100% rename from packages/mermaid/src/docs/img/object.assign without depth.png rename to packages/mermaid/src/docs/config/img/object.assign without depth.png diff --git a/packages/mermaid/src/docs/img/python-mermaid-integration.png b/packages/mermaid/src/docs/config/img/python-mermaid-integration.png similarity index 100% rename from packages/mermaid/src/docs/img/python-mermaid-integration.png rename to packages/mermaid/src/docs/config/img/python-mermaid-integration.png diff --git a/packages/mermaid/src/docs/img/wrapped text.png b/packages/mermaid/src/docs/config/img/wrapped text.png similarity index 100% rename from packages/mermaid/src/docs/img/wrapped text.png rename to packages/mermaid/src/docs/config/img/wrapped text.png diff --git a/packages/mermaid/src/docs/mermaidCLI.md b/packages/mermaid/src/docs/config/mermaidCLI.md similarity index 100% rename from packages/mermaid/src/docs/mermaidCLI.md rename to packages/mermaid/src/docs/config/mermaidCLI.md diff --git a/packages/mermaid/src/docs/n00b-advanced.md b/packages/mermaid/src/docs/config/n00b-advanced.md similarity index 100% rename from packages/mermaid/src/docs/n00b-advanced.md rename to packages/mermaid/src/docs/config/n00b-advanced.md diff --git a/packages/mermaid/src/docs/theming.md b/packages/mermaid/src/docs/config/theming.md similarity index 98% rename from packages/mermaid/src/docs/theming.md rename to packages/mermaid/src/docs/config/theming.md index 66b612c05..78f3546cc 100644 --- a/packages/mermaid/src/docs/theming.md +++ b/packages/mermaid/src/docs/config/theming.md @@ -255,25 +255,7 @@ In the following examples, the directive `init` is used, with the `theme` being ### Flowchart -```mmd -%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% - graph TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - B --> G[/Another/] - C ==>|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car] - subgraph section - C - D - E - F - G - end -``` - -```mermaid +```mermaid-example %%{init: {'securityLevel': 'loose', 'theme':'base'}}%% graph TD A[Christmas] -->|Get money| B(Go shopping) diff --git a/packages/mermaid/src/docs/usage.md b/packages/mermaid/src/docs/config/usage.md similarity index 88% rename from packages/mermaid/src/docs/usage.md rename to packages/mermaid/src/docs/config/usage.md index 026625894..3eac4ad6f 100644 --- a/packages/mermaid/src/docs/usage.md +++ b/packages/mermaid/src/docs/config/usage.md @@ -12,7 +12,7 @@ Please note that you can switch versions through the dropdown box at the top rig ## Using mermaid -For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./Setup.md). +For the majority of users, Using the [Live Editor](https://mermaid.live/) would be sufficient, however you may also opt to deploy mermaid as a dependency or using the [Mermaid API](./setup/README.md). We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor. @@ -37,25 +37,11 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai **Hosting mermaid on a web page.** -> Note:This topic explored in greater depth in the [User Guide for Beginners](./n00b-gettingStarted.md) +> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md) -The easiest way to integrate mermaid on a web page requires three elements: +The easiest way to integrate mermaid on a web page requires two elements: -1. Inclusion of the mermaid address in the html page using a `script` tag, in the `src` section.Example: - - ```html - <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> - ``` - -2. The `mermaidAPI` call, in a separate `script` tag. Example: - - ```html - <script> - mermaid.initialize({ startOnLoad: true }); - </script> - ``` - -3. A graph definition, inside `<div>` tags labeled `class=mermaid`. Example: +- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example: ```html <pre class="mermaid"> @@ -66,8 +52,18 @@ The easiest way to integrate mermaid on a web page requires three elements: </pre> ``` -**Following these directions, mermaid starts at page load and (when the page has loaded) it will -locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.** +- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call. + +Example: + +```html +<script type="module"> + import mermaid from '<CDN_URL>/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs'; + mermaid.initialize({ startOnLoad: true }); +</script> +``` + +**Following these directions, mermaid starts at page load and (when the page has loaded) it will locate the graph definitions inside the `pre` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.** ## Simple full example: @@ -84,8 +80,8 @@ locate the graph definitions inside the `div` tags with `class="mermaid"` and re B-->C[fa:fa-ban forbidden] B-->D(fa:fa-spinner); </pre> - <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> - <script> + <script type="module"> + import mermaid from '<CDN_URL>/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: true }); </script> </body> @@ -204,18 +200,17 @@ fetch the graph definition from the site (perhaps from a textarea), render it an The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console. ```html -<script src="mermaid.js"></script> - -<script> +<script type="module"> + import mermaid from './mermaid.mjs'; mermaid.mermaidAPI.initialize({ startOnLoad: false }); - $(function () { + $(async function () { // Example of using the API var element = document.querySelector('#graphDiv'); - var insertSvg = function (svgCode, bindFunctions) { + const insertSvg = function (svgCode, bindFunctions) { element.innerHTML = svgCode; }; - var graphDefinition = 'graph TB\na-->b'; - var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg); + const graphDefinition = 'graph TB\na-->b'; + const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg); }); </script> ``` @@ -229,7 +224,7 @@ The example code below is an extract of what mermaid does when using the API. Th bind events to an SVG when using the API for rendering. ```javascript -var insertSvg = function (svgCode, bindFunctions) { +const insertSvg = function (svgCode, bindFunctions) { element.innerHTML = svgCode; if (typeof callback !== 'undefined') { callback(id); @@ -237,7 +232,7 @@ var insertSvg = function (svgCode, bindFunctions) { bindFunctions(element); }; -var id = 'theGraph'; +const id = 'theGraph'; mermaidAPI.render(id, txt, insertSvg, element); ``` @@ -253,7 +248,7 @@ mermaidAPI.render(id, txt, insertSvg, element); This is the renderer used for transforming the documentation from Markdown to html with mermaid diagrams in the html. ```javascript -var renderer = new marked.Renderer(); +const renderer = new marked.Renderer(); renderer.code = function (code, language) { if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) { return '<pre class="mermaid">' + code + '</pre>'; @@ -304,8 +299,8 @@ mermaid.parseError = function (err, hash) { displayErrorInGui(err); }; -var textFieldUpdated = function () { - var textStr = getTextFromFormField('code'); +const textFieldUpdated = function () { + const textStr = getTextFromFormField('code'); if (mermaid.parse(textStr)) { reRender(textStr); @@ -329,7 +324,7 @@ setting the options in mermaid. 4. Instantiation of the configuration using the **mermaid.init** call- **Deprecated** The list above has two ways too many of doing this. Three are deprecated and will eventually be removed. The list of -configuration objects are described [in the mermaidAPI documentation](Setup.md). +configuration objects are described [in the mermaidAPI documentation](./setup/README.md). ## Using the `mermaidAPI.initialize`/`mermaid.initialize` call @@ -339,12 +334,12 @@ on what kind of integration you use. ```html <script src="../dist/mermaid.js"></script> <script> - var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; + let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; mermaid.initialize(config); </script> ``` -```tip +```note This is the preferred way of configuring mermaid. ``` @@ -352,7 +347,7 @@ This is the preferred way of configuring mermaid. ## Using the mermaid object -Is it possible to set some configuration via the mermaid object. The two parameters that are supported using this +It is possible to set some configuration via the mermaid object. The two parameters that are supported using this approach are: - mermaid.startOnLoad diff --git a/packages/mermaid/src/docs/diagrams-and-syntax-and-examples/flowchart.md b/packages/mermaid/src/docs/diagrams-and-syntax-and-examples/flowchart.md deleted file mode 100644 index 252faadc2..000000000 --- a/packages/mermaid/src/docs/diagrams-and-syntax-and-examples/flowchart.md +++ /dev/null @@ -1,645 +0,0 @@ ---- -sort: 3 -title: Flowchart ---- - -# Flowcharts - Basic Syntax - -## Graph - -This statement declares the direction of the flowchart, either from top to bottom (`TD` or `TB`): - -```mermaid-example -graph TD - Start --> Stop -``` - -or left to right (`LR`): - -```mermaid-example -graph LR - Start --> Stop -``` - -## Flowchart Orientation - -Possible FlowChart orientations are: - -- TB - top to bottom -- TD - top-down (same as top to bottom) -- BT - bottom to top -- RL - right to left -- LR - left to right - -## Flowcharts - -This renders a flowchart that allows for features such as: more arrow types, multi directional arrows, and linking to and from subgraphs. - -Apart from the graph type, the syntax is the same. This is currently experimental. When the beta period is over, both the graph and flowchart keywords will render in this new way. At this point it is OK to start beta testing flowcharts. - -> **Important note** Do not type the word "end" as a Flowchart node. Capitalize all or any one the letters to keep the flowchart from breaking, i.e, "End" or "END". Or you can apply this [workaround](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897).\*\* - -## Nodes and shapes - -### A node (default) - -```mermaid-example -graph LR - id -``` - -> **Note** The id is what is displayed in the box. - -### A node with text - -It is also possible to set text in the box that differs from the id. If this is done several times, only the last text -found for the node will be rendered. Also if you define edges for the node later on, you can omit text definitions. The -text previously defined will be used when rendering the box. - -```mermaid-example -graph LR - id1[This is the text in the box] -``` - -## Node Shapes - -### A node with round edges - -```mermaid-example -graph LR - id1(This is the text in the box) -``` - -### A stadium-shaped node - -```mermaid-example -graph LR - id1([This is the text in the box]) -``` - -### A node in a subroutine shape - -```mermaid-example -graph LR - id1[[This is the text in the box]] -``` - -### A node in a cylindrical shape - -```mermaid-example -graph LR - id1[(Database)] -``` - -### A node in the form of a circle - -```mermaid-example -graph LR - id1((This is the text in the circle)) -``` - -### A node in an asymmetric shape - -```mermaid-example -graph LR - id1>This is the text in the box] -``` - -Currently it is only possible to render the shape above, and not its mirror. _This might change with future releases._ - -### A node (rhombus) - -```mermaid-example -graph LR - id1{This is the text in the box} -``` - -### A hexagonal node - -```mermaid-example -graph LR - id1{{This is the text in the box}} -``` - -### Parallelogram - -```mermaid-example -graph TD - id1[/This is the text in the box/] -``` - -### Parallelogram alt - -```mermaid-example -graph TD - id1[\This is the text in the box\] -``` - -### Trapezoid - -```mermaid-example -graph TD - A[/Christmas\] -``` - -### Trapezoid alt - -```mermaid-example -graph TD - B[\Go shopping/] -``` - -## Links between nodes - -Nodes can be connected with links/edges. It is possible to have different types of links, or attach a text string on a link. - -### Link with arrow head - -```mermaid-example -graph LR - A-->B -``` - -### Open link - -```mermaid-example -graph LR - A --- B -``` - -### Text on links - -```mermaid-example -graph LR - A-- This is the text! ---B -``` - -or - -```mermaid-example -graph LR - A---|This is the text|B -``` - -### Link with arrow head and text - -```mermaid-example -graph LR - A-->|text|B -``` - -or - -```mermaid-example -graph LR - A-- text -->B -``` - -### Dotted link - -```mermaid-example -graph LR; - A-.->B; -``` - -### Dotted link with text - -```mermaid-example -graph LR - A-. text .-> B -``` - -### Thick link - -```mermaid-example -graph LR - A ==> B -``` - -### Thick link with text - -```mermaid-example -graph LR - A == text ==> B -``` - -### Chaining of links - -It is possible to declare many links on the same line as per below: - -```mermaid-example -graph LR - A -- text --> B -- text2 --> C -``` - -It is also possible to declare multiple nodes links in the same line as per below: - -```mermaid-example -graph LR - a --> b & c--> d -``` - -You can then describe dependencies in a very expressive way. Like the one-liner below: - -```mermaid-example -graph TB - A & B--> C & D -``` - -If you describe the same diagram using the the basic syntax, it will take four lines: - -```mmd -graph TB - A --> C - A --> D - B --> C - B --> D -``` - -A word of warning, one could go overboard with this, making the graph harder to read in -markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little. -This goes for expressive syntaxes as well. - -### New arrow types - -When using flowchart instead of graph there are new types of arrows supported as per below: - -```mermaid-example -flowchart LR - A --o B - B --x C -``` - -### Multi directional arrows - -When using flowchart instead of graph there is the possibility to use multidirectional arrows. - -```mermaid-example -flowchart LR - A o--o B - B <--> C - C x--x D -``` - -### Minimum length of a link - -Each node in the flowchart is ultimately assigned to a rank in the rendered -graph, i.e. to a vertical or horizontal level (depending on the flowchart -orientation), based on the nodes to which it is linked. By default, links -can span any number of ranks, but you can ask for any link to be longer -than the others by adding extra dashes in the link definition. - -In the following example, two extra dashes are added in the link from node _B_ -to node _E_, so that it spans two more ranks than regular links: - -```mermaid-example -graph TD - A[Start] --> B{Is it?}; - B -->|Yes| C[OK]; - C --> D[Rethink]; - D --> B; - B ---->|No| E[End]; -``` - -> **Note** The rendering engine may cause some links to be longer than -> the number of ranks requested in order to accommodate the overall topology. - -When the link label is written in the middle of the link, the extra dashes must -be added on the right side of the link. The following example is equivalent to -the previous one: - -```mermaid-example -graph TD - A[Start] --> B{Is it?}; - B -- Yes --> C[OK]; - C --> D[Rethink]; - D --> B; - B -- No ----> E[End]; -``` - -For dotted or thick links, the characters to add are equals signs or dots, -as summed up in the following table: - -| Length | 1 | 2 | 3 | -| ----------------- | :----: | :-----: | :------: | -| Normal | `---` | `----` | `-----` | -| Normal with arrow | `-->` | `--->` | `---->` | -| Thick | `===` | `====` | `=====` | -| Thick with arrow | `==>` | `===>` | `====>` | -| Dotted | `-.-` | `-..-` | `-...-` | -| Dotted with arrow | `-.->` | `-..->` | `-...->` | - -## Special characters that break syntax - -Use quotes around text in order to render more troublesome characters, as in the example below: - -```mermaid-example -graph LR - id1["This is the (text) in the box"] -``` - -### Entity codes to escape characters - -Special characters (including Unicode) can be included by using HTML escaping syntax: - -```mermaid-example - graph LR - A["A double quote:#quot;"] -->B["A dec char:#9829;"] -``` - -## Subgraphs - -``` -subgraph title - graph definition -end -``` - -An example: - -```mermaid-example -graph TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end -``` - -You can also set an explicit id for the subgraph: - -```mermaid-example -graph TB - c1-->a2 - subgraph ide1 [one] - a1-->a2 - end -``` - -## Flowcharts - -With the graphtype `flowchart` it is also possible to set edges to and from subgraphs: - -```mermaid-example -flowchart TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end - one --> two - three --> two - two --> c2 -``` - -## Interaction - -A node can have click events bound that lead to either a JavaScript callback or to open a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. - -``` -click nodeId callback -click nodeId call callback() -``` - -- nodeId is the id of the node -- `callback` is the name of a JavaScript function defined on the page displaying the graph. The function will be called with the nodeId as an incoming parameter. - -```html -<script> - var callback = function (nodeId) { - alert('A callback was triggered on ' + nodeId); - }; -</script> -``` - -Examples of tooltip usage: - -The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class .mermaidTooltip. - -```mermaid-example -graph LR; - A-->B; - B-->C; - C-->D; - click A callback "Tooltip for a callback" - click B "https://www.github.com" "This is a tooltip for a link" - click A call callback() "Tooltip for a callback" - click B href "https://www.github.com" "This is a tooltip for a link" -``` - -> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. - -?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). - -Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): - -```mermaid-example -graph LR; - A-->B; - B-->C; - C-->D; - D-->E; - click A "https://www.github.com" _blank - click B "https://www.github.com" "Open this in a new tab" _blank - click C href "https://www.github.com" _blank - click D href "https://www.github.com" "Open this in a new tab" _blank -``` - -Beginner's tip—here's a full example of using interactive links in HTML: - -```html -<body> - <pre class="mermaid"> - graph LR; - A-->B; - B-->C; - C-->D; - click A callback "Tooltip" - click B "https://www.github.com" "This is a link" - click C call callback() "Tooltip" - click D href "https://www.github.com" "This is a link" - </pre> - - <script> - var callback = function () { - alert('A callback was triggered'); - }; - var config = { - startOnLoad: true, - flowchart: { - useMaxWidth: true, - htmlLabels: true, - curve: 'cardinal', - }, - securityLevel: 'loose', - }; - mermaid.initialize(config); - </script> -</body> -``` - -### Comments - -Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including all punctuation and any flow syntax. - -```mmd -graph LR -%% this is a comment A -- text --> B{node} - A -- text --> B -- text2 --> C -``` - -## Styling and classes - -### Styling links - -It is possible to style links. For instance, you might want to style a link that is going backwards in the flow. As links -have no ids in the same way as nodes, some other way of attaching style is required. -So instead of ids, the order number of when the link was defined in the graph is used, starting with zero. Here's a linkStyle statement that would apply style to the fourth link in the graph: - -``` -linkStyle 3 stroke:#ff3,stroke-width:4px,color:red; -``` - -You can specify a `default` to apply to all links, or you can give a comma-separated list of link order numbers. - -Instead of giving a styles option, you can also use custom d3 curve types with the following syntax: - -``` -linkStyle default|numList|num interpolate curveType -``` - -If you want to add both D3 and style options, instead of writing: - -``` -linkStyle default interpolate cardinal -linkStyle default stroke:#ff3,stroke-width:4px,color:red; -``` - -You can combine them: - -``` -linkStyle default interpolate cardinal stroke:#ff3,stroke-width:4px,color:red; -``` - -### Styling a node - -It is possible to apply specific styles such as a thicker border or a different background color to a node. - -```mermaid-example -graph LR - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px - style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 -``` - -#### Classes - -More convenient than defining the style every time is to define a class of styles and attach this class reference to multiple nodes. - -here's a class definition: - -``` - classDef className fill:#f9f,stroke:#333,stroke-width:4px; -``` - -and then attaching this class to a node is simply: - -``` - class nodeId1 className; -``` - -It is also possible to attach a class to multiple nodes in one statement: - -``` - class nodeId1,nodeId2 className; -``` - -An even shorter form of adding a class is to attach the classname to the node using the `:::`operator: - -```mermaid-example -graph LR - A:::someclass --> B - classDef someclass fill:#f96; -``` - -### Css classes - -It is also possible to predefine classes in css styles that can be applied from the graph definition: - -**Example style** - -```css -.cssClass > rect { - fill: #ff0000; - stroke: #ffff00; - stroke-width: 4px; -} -``` - -**Example definition** - -```mermaid-example -graph LR; - A-->B[AAA<span>BBB</span>]; - B-->D; - class A cssClass; -``` - -### Default class - -If a class is named `default` it will be assigned to all nodes that do not have a specific class definition. - -``` - classDef default fill:#f9f,stroke:#333,stroke-width:4px; -``` - -## Basic support for fontawesome - -It is possible to add icons from fontawesome. These are accessed via the syntax fa:#icon-class-name#. - -```mermaid-example -graph TD - B["fa:fa-twitter for peace"] - B-->C[fa:fa-ban forbidden] - B-->D(fa:fa-spinner); - B-->E(A fa:fa-camera-retro perhaps?); -``` - -## Graph declarations with spaces between vertices and link and without semicolon - -- After release 0.2.16, graph declaration statements do not need to end with a semicolon. (And they can continue to have the ending semicolon—it has now just become optional.) So the below graph declaration is valid along with the old declarations. - -- A single space is allowed between vertices and the link, however there should not be any space between a vertex and its text, or a link and its text. The old syntax of graph declarations will also work, so this new feature is optional and is introduced to improve readability. - -Below is an example of the new way to declare graph edges. This is valid alongside any old-style declarations of graph edges. - -```mermaid-example -graph LR - A[Hard edge] -->|Link text| B(Round edge) - B --> C{Decision} - C -->|One| D[Result one] - C -->|Two| E[Result two] -``` - -## Configuration... - -Is it possible to adjust the width of the rendered flowchart. - -This is done by defining **mermaid.flowchartConfig**, or by the CLI to use a json file with the configuration (which is described in the mermaidCLI page). -In Javascript config parameters can be set by using `mermaid.flowchartConfig`: - -```javascript -mermaid.flowchartConfig = { - width: '100%', -}; -``` diff --git a/packages/mermaid/src/docs/img/Configuration.png b/packages/mermaid/src/docs/img/Configuration.png deleted file mode 100644 index 60a808f2c..000000000 Binary files a/packages/mermaid/src/docs/img/Configuration.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/Editing-process.png b/packages/mermaid/src/docs/img/Editing-process.png deleted file mode 100644 index a49b35224..000000000 Binary files a/packages/mermaid/src/docs/img/Editing-process.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/EditingHistory+Links.png b/packages/mermaid/src/docs/img/EditingHistory+Links.png deleted file mode 100644 index 3891f39c1..000000000 Binary files a/packages/mermaid/src/docs/img/EditingHistory+Links.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/GitHub-Mark-32px.png b/packages/mermaid/src/docs/img/GitHub-Mark-32px.png deleted file mode 100644 index 790fa7710..000000000 Binary files a/packages/mermaid/src/docs/img/GitHub-Mark-32px.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/Live-Editor-Usage.png b/packages/mermaid/src/docs/img/Live-Editor-Usage.png deleted file mode 100644 index 04df642dc..000000000 Binary files a/packages/mermaid/src/docs/img/Live-Editor-Usage.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/book-banner-post-release.jpeg b/packages/mermaid/src/docs/img/book-banner-post-release.jpeg deleted file mode 100644 index 005a3282b..000000000 Binary files a/packages/mermaid/src/docs/img/book-banner-post-release.jpeg and /dev/null differ diff --git a/packages/mermaid/src/docs/img/book-banner-post-release.png b/packages/mermaid/src/docs/img/book-banner-post-release.png deleted file mode 100644 index 7db35ea7a..000000000 Binary files a/packages/mermaid/src/docs/img/book-banner-post-release.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/book-banner-pre-release.jpg b/packages/mermaid/src/docs/img/book-banner-pre-release.jpg deleted file mode 100644 index 6dc996fd9..000000000 Binary files a/packages/mermaid/src/docs/img/book-banner-pre-release.jpg and /dev/null differ diff --git a/packages/mermaid/src/docs/img/book-banner-pre-release.png b/packages/mermaid/src/docs/img/book-banner-pre-release.png deleted file mode 100644 index b85b165db..000000000 Binary files a/packages/mermaid/src/docs/img/book-banner-pre-release.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/class.png b/packages/mermaid/src/docs/img/class.png deleted file mode 100644 index fde265f63..000000000 Binary files a/packages/mermaid/src/docs/img/class.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/flow.png b/packages/mermaid/src/docs/img/flow.png deleted file mode 100644 index 37537c18f..000000000 Binary files a/packages/mermaid/src/docs/img/flow.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/gantt.png b/packages/mermaid/src/docs/img/gantt.png deleted file mode 100644 index 304b598b8..000000000 Binary files a/packages/mermaid/src/docs/img/gantt.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/git.png b/packages/mermaid/src/docs/img/git.png deleted file mode 100644 index 2da331a1e..000000000 Binary files a/packages/mermaid/src/docs/img/git.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/n00b-firstFlow.png b/packages/mermaid/src/docs/img/n00b-firstFlow.png deleted file mode 100644 index 5d3c7738d..000000000 Binary files a/packages/mermaid/src/docs/img/n00b-firstFlow.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/new-diagrams.png b/packages/mermaid/src/docs/img/new-diagrams.png deleted file mode 100644 index bd9c8c97a..000000000 Binary files a/packages/mermaid/src/docs/img/new-diagrams.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/sequence.png b/packages/mermaid/src/docs/img/sequence.png deleted file mode 100644 index f37d523f8..000000000 Binary files a/packages/mermaid/src/docs/img/sequence.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/simple-er.png b/packages/mermaid/src/docs/img/simple-er.png deleted file mode 100644 index 6ebf41352..000000000 Binary files a/packages/mermaid/src/docs/img/simple-er.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/user-journey.png b/packages/mermaid/src/docs/img/user-journey.png deleted file mode 100644 index 825d467d8..000000000 Binary files a/packages/mermaid/src/docs/img/user-journey.png and /dev/null differ diff --git a/packages/mermaid/src/docs/img/without wrap.png b/packages/mermaid/src/docs/img/without wrap.png deleted file mode 100644 index 038408d2b..000000000 Binary files a/packages/mermaid/src/docs/img/without wrap.png and /dev/null differ diff --git a/packages/mermaid/src/docs/index.html b/packages/mermaid/src/docs/index.html deleted file mode 100644 index ea3969c77..000000000 --- a/packages/mermaid/src/docs/index.html +++ /dev/null @@ -1,163 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <title> - mermaid - Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, - gantt charts and git graphs. - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - diff --git a/packages/mermaid/src/docs/index.md b/packages/mermaid/src/docs/index.md new file mode 100644 index 000000000..6c2763904 --- /dev/null +++ b/packages/mermaid/src/docs/index.md @@ -0,0 +1,184 @@ +--- +layout: home + +title: Mermaid +titleTemplate: Diagramming and charting tool + +hero: + name: Mermaid + text: Diagramming and charting tool + tagline: JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. + image: + src: /mermaid-logo.svg + alt: Mermaid + actions: + - theme: brand + text: Get Started + link: /intro/ + - theme: alt + text: View on GitHub + link: https://github.com/mermaid-js/mermaid + +features: + - title: ➕ Easy to use! + details: Mermaid allows even non-programmers to easily create detailed and diagrams through the Mermaid Live Editor. + - title: 🎥 Video Tutorials! + details: Has video tutorials for beginners and advanced users. + - title: 🏆 Award winner! + details: Mermaid was nominated and won the JS Open Source Awards (2019) in the category "The most exciting use of technology"!!! + - title: 🧩 Integrations available! + details: Use Mermaid with your favorite applications, check out the list of Integrations and Usages of Mermaid. +--- + + + +
+

Meet The Team

+ +
+ + diff --git a/packages/mermaid/src/docs/intro/examples.md b/packages/mermaid/src/docs/intro/examples.md new file mode 100644 index 000000000..f4cb3b929 --- /dev/null +++ b/packages/mermaid/src/docs/intro/examples.md @@ -0,0 +1,100 @@ +## Diagram Types + +### [Flowchart](../syntax/flowchart.md?id=flowcharts-basic-syntax) + +```mermaid-example +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +``` + +### [Sequence diagram](../syntax/sequenceDiagram.md) + +```mermaid-example +sequenceDiagram + participant Alice + participant Bob + Alice->>John: Hello John, how are you? + loop Healthcheck + John->>John: Fight against hypochondria + end + Note right of John: Rational thoughts
prevail! + John-->>Alice: Great! + John->>Bob: How about you? + Bob-->>John: Jolly good! +``` + +### [Gantt diagram](../syntax/gantt.md) + +```mermaid-example +gantt +dateFormat YYYY-MM-DD +title Adding GANTT diagram to mermaid +excludes weekdays 2014-01-10 + +section A section +Completed task :done, des1, 2014-01-06,2014-01-08 +Active task :active, des2, 2014-01-09, 3d +Future task : des3, after des2, 5d +Future task2 : des4, after des3, 5d +``` + +### [Class diagram](../syntax/classDiagram.md) + +```mermaid-example +classDiagram +Class01 <|-- AveryLongClass : Cool +Class03 *-- Class04 +Class05 o-- Class06 +Class07 .. Class08 +Class09 --> C2 : Where am i? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +Class08 <--> C2: Cool label +``` + +### [Git graph](../syntax/gitgraph.md) + +```mermaid-example + gitGraph + commit + commit + branch develop + commit + commit + commit + checkout main + commit + commit +``` + +### [Entity Relationship Diagram - :exclamation: experimental](../syntax/entityRelationshipDiagram.md) + +```mermaid-example +erDiagram + CUSTOMER ||--o{ ORDER : places + ORDER ||--|{ LINE-ITEM : contains + CUSTOMER }|..|{ DELIVERY-ADDRESS : uses + +``` + +### [User Journey Diagram](../syntax/userJourney.md) + +```mermaid-example +journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 5: Me +``` diff --git a/packages/mermaid/src/docs/img/Code-Preview-Config.png b/packages/mermaid/src/docs/intro/img/Code-Preview-Config.png similarity index 100% rename from packages/mermaid/src/docs/img/Code-Preview-Config.png rename to packages/mermaid/src/docs/intro/img/Code-Preview-Config.png diff --git a/packages/mermaid/src/docs/img/Live-Editor-Choices.png b/packages/mermaid/src/docs/intro/img/Live-Editor-Choices.png similarity index 100% rename from packages/mermaid/src/docs/img/Live-Editor-Choices.png rename to packages/mermaid/src/docs/intro/img/Live-Editor-Choices.png diff --git a/packages/mermaid/src/docs/img/book-banner-post-release.jpg b/packages/mermaid/src/docs/intro/img/book-banner-post-release.jpg similarity index 100% rename from packages/mermaid/src/docs/img/book-banner-post-release.jpg rename to packages/mermaid/src/docs/intro/img/book-banner-post-release.jpg diff --git a/packages/mermaid/src/docs/README.md b/packages/mermaid/src/docs/intro/index.md similarity index 69% rename from packages/mermaid/src/docs/README.md rename to packages/mermaid/src/docs/intro/index.md index e8bba38da..df1aa3b62 100644 --- a/packages/mermaid/src/docs/README.md +++ b/packages/mermaid/src/docs/intro/index.md @@ -4,11 +4,11 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. -> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](./n00b-syntaxReference.md). +> If you are familiar with Markdown you should have no problem learning [Mermaid's Syntax](n00b-syntaxReference.md). - + -[![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) +[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_) @@ -25,12 +25,12 @@ But not having diagrams or docs ruins productivity and hurts organizational lear Mermaid addresses this problem by enabling users to create easily modifiable diagrams, it can also be made part of production scripts (and other pieces of code).

Mermaid allows even non-programmers to easily create detailed and diagrams through the [Mermaid Live Editor](https://mermaid.live/).
-[Tutorials](./Tutorials.md) has video tutorials. -Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./integrations.md). +[Tutorials](../config/Tutorials.md) has video tutorials. +Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](../misc/integrations.md). -For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./n00b-overview.md) and [Usage](./usage.md). +For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](../community/n00b-overview.md) and [Usage](../config/usage.md). -🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/docs/development.md) | 📜 [Version Log](./CHANGELOG.md) | 🔌 [Plug-Ins](./integrations.md) +🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](../community/development.md) | 🔌 [Plug-Ins](../misc/integrations.md) > 🖖 Keep a steady pulse: mermaid needs more Collaborators, [Read More](https://github.com/knsv/mermaid/issues/866). @@ -44,124 +44,13 @@ In our release process we rely heavily on visual regression tests using [applito -## Diagram Types - -### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax) - -```mmd -graph TD; - A-->B; - A-->C; - B-->D; - C-->D; -``` - -![Flowchart](img/flow.png) - -### [Sequence diagram](./sequenceDiagram.md) - -```mmd -sequenceDiagram - participant Alice - participant Bob - Alice->>John: Hello John, how are you? - loop Healthcheck - John->>John: Fight against hypochondria - end - Note right of John: Rational thoughts
prevail! - John-->>Alice: Great! - John->>Bob: How about you? - Bob-->>John: Jolly good! -``` - -![Sequence diagram](img/sequence.png) - -### [Gantt diagram](./gantt.md) - -```mmd -gantt -dateFormat YYYY-MM-DD -title Adding GANTT diagram to mermaid -excludes weekdays 2014-01-10 - -section A section -Completed task :done, des1, 2014-01-06,2014-01-08 -Active task :active, des2, 2014-01-09, 3d -Future task : des3, after des2, 5d -Future task2 : des4, after des3, 5d -``` - -![Gantt diagram](img/gantt.png) - -### [Class diagram](./classDiagram.md) - -```mmd -classDiagram -Class01 <|-- AveryLongClass : Cool -Class03 *-- Class04 -Class05 o-- Class06 -Class07 .. Class08 -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -Class08 <--> C2: Cool label -``` - -![Class diagram](img/class.png) - -### Git graph - -```mermaid-example - gitGraph - commit - commit - branch develop - commit - commit - commit - checkout main - commit - commit -``` - -### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md) - -```mmd -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses - -``` - -![ER diagram](img/simple-er.png) - -### [User Journey Diagram](./user-journey.md) - -```mmd -journey - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me -``` - -![Journey diagram](img/user-journey.png) + ## Installation -**In depth guides and examples can be found at [Getting Started](/n00b-gettingStarted) and [Usage](/usage).** +**In depth guides and examples can be found at [Getting Started](./n00b-gettingStarted.md) and [Usage](../config/usage.md).** -**It would also be helpful to learn more about mermaid's [Syntax](/n00b-syntaxReference).** +**It would also be helpful to learn more about mermaid's [Syntax](./n00b-syntaxReference.md).** ### CDN @@ -180,25 +69,25 @@ Latest Version: [https://unpkg.com/browse/mermaid@8.8.0/](https://unpkg.com/brow To Deploy Mermaid: 1. You will need to install node v16, which would have npm -2. Download yarn using npm -3. Enter the following command: `yarn add mermaid` -4. You can then add mermaid as a dev dependency using this command: - `yarn add --dev mermaid` +2. Install mermaid + - NPM: `npm i mermaid` + - Yarn: `yarn add mermaid` + - Pnpm: `pnpm add mermaid` -### [Mermaid API](./Setup.md): +### [Mermaid API](../config/setup/README.md): -**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:** +**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:** ```html - - ``` -**Doing so will command the mermaid parser to look for the `
` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.** +**Doing so will command the mermaid parser to look for the `
` or `
` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
 
-**Examples can be found at** [Other examples](/examples)
+**Examples can be found at** [Other examples](../syntax/examples.md)
 
 ## Sibling projects
 
@@ -224,22 +113,26 @@ Don't hesitate to contact me if you want to get involved!
 
 ## For contributors
 
-### Setup
+### Requirements
 
-```sh
-yarn install
-```
+- [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`
 
-### Build
+## Development Installation
 
-```sh
-yarn build:watch
+```bash
+git clone git@github.com:mermaid-js/mermaid.git
+cd mermaid
+# npx is required for first install as volta support for pnpm is not added yet.
+npx pnpm install
+pnpm test
 ```
 
 ### Lint
 
 ```sh
-yarn lint
+pnpm lint
 ```
 
 We use [eslint](https://eslint.org/).
@@ -248,7 +141,7 @@ We recommend you to install [editor plugins](https://eslint.org/docs/user-guide/
 ### Test
 
 ```sh
-yarn test
+pnpm test
 ```
 
 Manual test in browser: open `dist/index.html`
@@ -263,7 +156,7 @@ Update version number in `package.json`.
 npm publish
 ```
 
-The above command generates files into the `dist` folder and publishes them to npmjs.org.
+The above command generates files into the `dist` folder and publishes them to .
 
 ## Related projects
 
@@ -275,11 +168,11 @@ The above command generates files into the `dist` folder and publishes them to n
 
 Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
 
-Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
+Detailed information about how to contribute can be found in the [contribution guide](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
 
 ## Security and safe diagrams
 
-For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
+For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitize the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
 
 As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing JavaScript in the code from being executed. This is a great step forward for better security.
 
@@ -293,10 +186,33 @@ 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!_
 
 ---
 
 _Mermaid was created by Knut Sveidqvist for easier documentation._
+
+
diff --git a/packages/mermaid/src/docs/n00b-gettingStarted.md b/packages/mermaid/src/docs/intro/n00b-gettingStarted.md
similarity index 72%
rename from packages/mermaid/src/docs/n00b-gettingStarted.md
rename to packages/mermaid/src/docs/intro/n00b-gettingStarted.md
index 950c4eba6..a4dd7662f 100644
--- a/packages/mermaid/src/docs/n00b-gettingStarted.md
+++ b/packages/mermaid/src/docs/intro/n00b-gettingStarted.md
@@ -2,32 +2,41 @@
 
 Mermaid is composed of three parts: Deployment, Syntax and Configuration.
 
-This section talks about the different ways to deploy Mermaid. Learning the [Syntax](./n00b-syntaxReference.md) would be of great help to the beginner.
+This section talks about the different ways to deploy Mermaid. Learning the [Syntax](n00b-syntaxReference.md) would be of great help to the beginner.
 
 > Generally the live editor is enough for most general uses of mermaid, and is a good place to start learning.
 
-**Absolute beginners are advised to view the Video [Tutorials](./Tutorials.md) on the Live Editor, to gain a better understanding of mermaid.**
+**Absolute beginners are advised to view the Video [Tutorials](../config/Tutorials.md) on the Live Editor, to gain a better understanding of mermaid.**
 
 ## Four ways of using mermaid:
 
 1. Using the Mermaid Live Editor at [mermaid.live](https://mermaid.live).
-2. Using [mermaid plugins](./integrations.md) with programs you are familiar with.
+2. Using [mermaid plugins](../misc/integrations.md) with programs you are familiar with.
 3. Calling the Mermaid JavaScript API.
 4. Deploying Mermaid as a dependency.
 
 **Note: It is our recommendation that you review all approaches, and choose the one that is best for your project.**
 
-> More in depth information can be found at [Usage](./usage.md).
+> More in depth information can be found at [Usage](../config/usage.md).
 
 ## 1. Using the Live Editor
 
 Available at [mermaid.live](https://mermaid.live)
 
-![EditingProcess](./img/Editing-process.png)
+```mermaid
+graph TD
+    A[Enter Chart Definition] --> B(Preview)
+    B --> C{decide}
+    C --> D[Keep]
+    C --> E[Edit Definition]
+    E --> B
+    D --> F[Save Image and Code]
+    F --> B
+```
 
 In the `Code` section one can write or edit raw mermaid code, and instantly `Preview` the rendered result on the panel beside it.
 
-The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](./n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](Setup.md) page.
+The `Configuration` Section is for changing the appearance and behavior of mermaid diagrams. An easy introduction to mermaid configuration is found in the [Advanced usage](../config/n00b-advanced.md) section. A complete configuration reference cataloging the default values can be found on the [mermaidAPI](../config/setup/README.md) page.
 
 ![Code,Config and Preview](./img/Code-Preview-Config.png)
 
@@ -59,9 +68,9 @@ and to View, https://mermaid.live/view?gist=https://gist.github.com/sidharthv96/
 
 ## 2. Using Mermaid Plugins:
 
-You can generate mermaid diagrams from within popular applications using plug-ins. It can be done in the same way, you would use the Live Editor. Here's a list of [Mermaid Plugins](./integrations.md).
+You can generate mermaid diagrams from within popular applications using plug-ins. It can be done in the same way, you would use the Live Editor. Here's a list of [Mermaid Plugins](../misc/integrations.md).
 
-**This is covered in greater detail in the [Usage section](usage.md)**
+**This is covered in greater detail in the [Usage section](../config/usage.md)**
 
 ## 3. Calling the JavaScript API
 
@@ -73,23 +82,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
 
 ### Requirements for the Mermaid API.
 
-When writing the .html file, we give three instructions inside the html code to the web browser:
+When writing the .html file, we give two instructions inside the html code to the web browser:
 
-a. A reference for fetching the online mermaid renderer, through the `mermaid.js` or `mermaid.min.js`.
+a. The mermaid code for the diagram we want to create.
 
-b. The mermaid code for the diagram we want to create.
+b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
 
-c. The `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
-
-**a. A reference to the external CDN in a `
-
-```
-
-**b. The embedded mermaid diagram definition inside a `
`:**
+**a. The embedded mermaid diagram definition inside a `
`:**
 
 ```html
 
@@ -105,13 +104,14 @@ c. The `mermaid.initialize()` call, which dictates the appearance of diagrams an
 
 **Notes**: Every Mermaid chart/graph/diagram definition, should have separate `
` tags.
 
-**c. The `mermaid.initialize()` call.**
+**b. The import of mermaid and the `mermaid.initialize()` call.**
 
 `mermaid.initialize()` call takes all the definitions contained in all the `
` tags that it finds in the html body and renders them into diagrams. Example:
 
 ```html
 
-  
 
@@ -126,6 +126,10 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
 | ----------- | --------------------------------- | ------- | ----------- |
 | startOnLoad | Toggle for Rendering upon loading | Boolean | true, false |
 
+### Adding external diagrams to mermaid
+
+Please refer to the [Mindmap](../syntax/mindmap.md?id=integrating-with-your-librarywebsite) section for more information.
+
 ### Working Examples
 
 **Here is a full working example of the mermaidAPI being called through the CDN:**
@@ -133,11 +137,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
 ```html
 
   
-    
-    
-
     Here is one mermaid diagram:
     
             graph TD 
@@ -154,6 +153,11 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
             B -->|tcp_456| C[Server1] 
             B -->|tcp_456| D[Server2]
     
+ + ``` @@ -179,8 +183,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file, B --> C[Server1] B --> D[Server2]
- - @@ -204,4 +208,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file, **Comments from Knut Sveidqvist, creator of mermaid:** -- In early versions of mermaid, the ` - - - - - - -
-
- -
-
-
-

MermaidPress

-

- The Official Guide to Mermaid.js -

-

- Learn to create complex diagrams and beautiful flowcharts easily using text and code - using Mermaid.js. -

- - - -
-
-
- -
- -
-
-
-
- - - - - - - - - - - - -
-
-
-

- Get up to speed with using Mermaid diagrams along with real-world examples and expert tips - from the authors to facilitate a seamless development workflow -

-
-
-
-
-
-

- Flowcharts is a diagram type that visualizes a process or an algorithm by showing the - steps in order, as well as the different paths the execution can take. -

-
-
- -
-
-
-
- -
-
-
-

- Sequence diagrams lets you model and visualize interactions between different actors - or objects in a system, as well as the order of those interactions -

-
-
-
-
-
-

- A class diagram is a graphical representation that is used to visualize and describe - an object-oriented system. -

-
-
- -
-
-
-
- -
-
-
-

- An entity-relationship diagram is a graphical representation that is used to - visualize the different types of entities that exist within a system. -

-
-
-
-
-
-

- Use State diagrams to model and document state machines, an abstract way of - representing a system or an algorithm. -

-
-
- -
-
-
-
- -
-
-
-

- A Gantt chart is a graphical representation that is used to visualize and describe - tasks (events or activities) over time. -

-
-
-
-
-

- These were a few of the diagrams supported by Mermaid. -

-
- -
-
-

- Book description -

-
-

- Mermaid lets you represent diagrams using text and code which simplifies the maintenance - of complex diagrams. This is a great option for developers as they’re more familiar with - code, rather than special tools for generating diagrams. Besides, diagrams in code - simplify maintenance and ensure that the code is supported by version control systems. - In some cases, Mermaid makes refactoring support for name changes possible while also - enabling team collaboration for review distribution and updates. -

-

- Developers working with any system will be able to put their knowledge to work with this - practical guide to using Mermaid for documentation. The book is also a great reference - for looking up the syntax for specific diagrams when authoring diagrams. -

-

- You’ll start by getting up to speed with the importance of accurate and visual - documentation. Next, the book introduces Mermaid and establishes how to use it to create - effective documentation. By using different tools, editors, or a custom documentation - platform, you’ll also learn how to use Mermaid syntax for various diagrams. Later - chapters cover advanced configuration settings and theme options to manipulate your - diagram as per your needs. -

-

- By the end of this Mermaid book, you’ll have become well-versed with the different types - of Mermaid diagrams and how they can be used in your workflows. -

-
-
-
-
-
-

- What you will learn -

-
-
-
-
-
-
-
    -
  • - Understand good and bad documentation, and the art of effective documentation -
  • -
  • - Become well-versed with maintaining complex diagrams with ease -
  • -
  • - Learn how to set up a custom documentation system -
  • -
  • - Learn how to implement Mermaid diagrams in your workflows -
  • -
  • - Understand how to set up themes for a Mermaid diagram for an entire site -
  • -
  • - Discover how to draw different types of diagrams such as flowcharts, class - diagrams, Gantt charts, and more -
  • -
-
-
-
-
-
- - - - - - - - - - - - - - - - - -
-

- Purchase The Official Guide to Mermaid.js -

-
-
-
-

-

Written by Knut Sveidqvist and Ashish Jain.

-

- Knut is the creator of Mermaid and both authors are active core team members of the - Mermaid open-source project. -

-

- - - -
- - - diff --git a/packages/mermaid/src/docs/landing/sequence-diagram.png b/packages/mermaid/src/docs/landing/sequence-diagram.png deleted file mode 100644 index 8c51ac1c5..000000000 Binary files a/packages/mermaid/src/docs/landing/sequence-diagram.png and /dev/null differ diff --git a/packages/mermaid/src/docs/landing/state.png b/packages/mermaid/src/docs/landing/state.png deleted file mode 100644 index 2ef66ea2f..000000000 Binary files a/packages/mermaid/src/docs/landing/state.png and /dev/null differ diff --git a/packages/mermaid/src/docs/faq.md b/packages/mermaid/src/docs/misc/faq.md similarity index 100% rename from packages/mermaid/src/docs/faq.md rename to packages/mermaid/src/docs/misc/faq.md diff --git a/docs/integrations.md b/packages/mermaid/src/docs/misc/integrations.md similarity index 95% rename from docs/integrations.md rename to packages/mermaid/src/docs/misc/integrations.md index 49c103492..06d09634f 100644 --- a/docs/integrations.md +++ b/packages/mermaid/src/docs/misc/integrations.md @@ -1,5 +1,3 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. Please edit the corresponding file in packages/mermaid/src/docs. - # Integrations The following list is a compilation of different integrations and plugins that allow the rendering of mermaid definitions within other applications. @@ -33,8 +31,9 @@ They also serve as proof of concept, for the variety of things that can be built - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro) - [redmine-mermaid](https://github.com/styz/redmine_mermaid) - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin) -- [Jetsbrain IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) +- [JetBrains IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) - [mermerd](https://github.com/KarnerTh/mermerd) +- Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive) ## CRM/ERP/Similar @@ -117,6 +116,7 @@ They also serve as proof of concept, for the variety of things that can be built - [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin) - [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid) - [Vim](https://www.vim.org) + - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid) - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram) - [GNU Emacs](https://www.gnu.org/software/emacs/) - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode) @@ -163,7 +163,6 @@ They also serve as proof of concept, for the variety of things that can be built | Extensions for Mermaid | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) | | Chrome Diagrammer | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - | | Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - | -| Mermaid Markdown | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg) | - | - | - | - | | Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - | | Mermaid Previewer | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-previewer/oidjnlhbegipkcklbdfnbkikplpghfdl) | - | - | - | - | diff --git a/packages/mermaid/src/docs/.nojekyll b/packages/mermaid/src/docs/public/.nojekyll similarity index 100% rename from packages/mermaid/src/docs/.nojekyll rename to packages/mermaid/src/docs/public/.nojekyll diff --git a/packages/mermaid/src/docs/public/favicon.ico b/packages/mermaid/src/docs/public/favicon.ico new file mode 100644 index 000000000..d41818c5b Binary files /dev/null and b/packages/mermaid/src/docs/public/favicon.ico differ diff --git a/packages/mermaid/src/docs/public/favicon.png b/packages/mermaid/src/docs/public/favicon.png new file mode 100644 index 000000000..05d8a737b Binary files /dev/null and b/packages/mermaid/src/docs/public/favicon.png differ diff --git a/packages/mermaid/src/docs/public/favicon.svg b/packages/mermaid/src/docs/public/favicon.svg new file mode 100644 index 000000000..993c56b94 --- /dev/null +++ b/packages/mermaid/src/docs/public/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/mermaid/src/docs/img/header.png b/packages/mermaid/src/docs/public/header.png similarity index 100% rename from packages/mermaid/src/docs/img/header.png rename to packages/mermaid/src/docs/public/header.png diff --git a/packages/mermaid/src/docs/public/manifest.json b/packages/mermaid/src/docs/public/manifest.json new file mode 100644 index 000000000..85c11395c --- /dev/null +++ b/packages/mermaid/src/docs/public/manifest.json @@ -0,0 +1,14 @@ +{ + "short_name": "Mermaid", + "name": "Mermaid JS", + "icons": [ + { + "src": "/favicon.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "background_color": "#6366F1", + "display": "standalone", + "theme_color": "#6366F1" +} diff --git a/packages/mermaid/src/docs/public/mermaid-logo.svg b/packages/mermaid/src/docs/public/mermaid-logo.svg new file mode 100644 index 000000000..5ac259968 --- /dev/null +++ b/packages/mermaid/src/docs/public/mermaid-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/mermaid/src/docs/stateDiagram.md b/packages/mermaid/src/docs/stateDiagram.md deleted file mode 100644 index e28819e7a..000000000 --- a/packages/mermaid/src/docs/stateDiagram.md +++ /dev/null @@ -1,260 +0,0 @@ -# State diagrams - -> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the case, while at other times this is a reasonable abstraction." Wikipedia - -Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml. - -```mermaid-example -stateDiagram-v2 - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -Older renderer: - -```mermaid-example -stateDiagram - [*] --> Still - Still --> [*] - - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] -``` - -In state diagrams systems are described in terms of its states and how the systems state can change to another state via a transitions. The example diagram above shows three states **Still**, **Moving** and **Crash**. You start in the state of Still. From Still you can change the state to Moving. In Moving you can change the state either back to Still or to Crash. There is no transition from Still to Crash. - -## States - -A state can be declared in multiple ways. The simplest way is to define a state id as a description. - -```mermaid-example -stateDiagram-v2 - s1 -``` - -Another way is by using the state keyword with a description as per below: - -```mermaid-example -stateDiagram-v2 - state "This is a state description" as s2 -``` - -Another way to define a state with a description is to define the state id followed by a colon and the description: - -```mermaid-example -stateDiagram-v2 - s2 : This is a state description -``` - -## Transitions - -Transitions are path/edges when one state passes into another. This is represented using text arrow, "\-\-\>". - -When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way. - -```mermaid-example -stateDiagram-v2 - s1 --> s2 -``` - -It is possible to add text to a transition. To describe what it represents. - -```mermaid-example -stateDiagram-v2 - s1 --> s2: A transition -``` - -## Start and End - -There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and the direction of the transition to it defines it either as a start or a stop state. - -```mermaid-example -stateDiagram-v2 - [*] --> s1 - s1 --> [*] -``` - -## Composite states - -In a real world use of state diagrams you often end up with diagrams that are multi-dimensional as one state can -have several internal states. These are called composite states in this terminology. - -In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between \{\}. See the example below: - -```mermaid-example -stateDiagram-v2 - [*] --> First - state First { - [*] --> second - second --> [*] - } -``` - -You can do this in several layers: - -```mermaid-example -stateDiagram-v2 - [*] --> First - - state First { - [*] --> Second - - state Second { - [*] --> second - second --> Third - - state Third { - [*] --> third - third --> [*] - } - } - } -``` - -You can also define transitions also between composite states: - -```mermaid-example -stateDiagram-v2 - [*] --> First - First --> Second - First --> Third - - state First { - [*] --> fir - fir --> [*] - } - state Second { - [*] --> sec - sec --> [*] - } - state Third { - [*] --> thi - thi --> [*] - } -``` - -_You can not define transitions between internal states belonging to different composite states_ - -## Choice - -Sometimes you need to model a choice between two or more paths, you can do so using <<choice>>. - -```mermaid-example -stateDiagram-v2 - state if_state <> - [*] --> IsPositive - IsPositive --> if_state - if_state --> False: if n < 0 - if_state --> True : if n >= 0 -``` - -## Forks - -It is possible to specify a fork in the diagram using <<fork>> <<join>>. - -```mermaid-example - stateDiagram-v2 - state fork_state <> - [*] --> fork_state - fork_state --> State2 - fork_state --> State3 - - state join_state <> - State2 --> join_state - State3 --> join_state - join_state --> State4 - State4 --> [*] -``` - -## Notes - -Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams. - -Here you can choose to put the note to the _right of_ or to the _left of_ a node. - -```mermaid-example - stateDiagram-v2 - State1: The state with a note - note right of State1 - Important information! You can write - notes. - end note - State1 --> State2 - note left of State2 : This is the note to the left. -``` - -## Concurrency - -As in plantUml you can specify concurrency using the -- symbol. - -```mermaid-example -stateDiagram-v2 - [*] --> Active - - state Active { - [*] --> NumLockOff - NumLockOff --> NumLockOn : EvNumLockPressed - NumLockOn --> NumLockOff : EvNumLockPressed - -- - [*] --> CapsLockOff - CapsLockOff --> CapsLockOn : EvCapsLockPressed - CapsLockOn --> CapsLockOff : EvCapsLockPressed - -- - [*] --> ScrollLockOff - ScrollLockOff --> ScrollLockOn : EvScrollLockPressed - ScrollLockOn --> ScrollLockOff : EvScrollLockPressed - } -``` - -## Setting the direction of the diagram - -With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example. - -```mermaid-example -stateDiagram - direction LR - [*] --> A - A --> B - B --> C - state B { - direction LR - a --> b - } - B --> D -``` - -## Comments - -Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax - -```mmd -stateDiagram-v2 - [*] --> Still - Still --> [*] -%% this is a comment - Still --> Moving - Moving --> Still %% another comment - Moving --> Crash - Crash --> [*] -``` - -## Styling - -Styling of the a state diagram is done by defining a number of css classes. During rendering these classes are extracted from the file located at src/themes/state.scss - -## Spaces in state names - -Spaces can be added to a state by defining it at the top and referencing the acronym later. - -```mermaid-example -stateDiagram-v2 - Yswsii: Your state with spaces in it - [*] --> Yswsii -``` diff --git a/packages/mermaid/src/docs/c4c.md b/packages/mermaid/src/docs/syntax/c4c.md similarity index 99% rename from packages/mermaid/src/docs/c4c.md rename to packages/mermaid/src/docs/syntax/c4c.md index 0ab805182..78528f7b9 100644 --- a/packages/mermaid/src/docs/c4c.md +++ b/packages/mermaid/src/docs/syntax/c4c.md @@ -131,7 +131,7 @@ The following unfinished features are not supported in the short term. - - [x] Rel_Back - - [x] RelIndex \* Compatible with C4-Plantuml syntax, but ignores the index parameter. The sequence number is determined by the order in which the rel statements are written. -- [ ] Custom tags/stereotypes support and skinparam updates +- [ ] Custom tags/stereotypes support and skin param updates - - [ ] AddElementTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new element tag. The styles of the tagged elements are updated and the tag is displayed in the calculated legend. - - [ ] AddRelTag(tagStereo, ?textColor, ?lineColor, ?lineStyle, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new Relationship tag. The styles of the tagged relationships are updated and the tag is displayed in the calculated legend. - - [x] UpdateElementStyle(elementName, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): This call updates the default style of the elements (component, ...) and creates no additional legend entry. @@ -318,7 +318,7 @@ UpdateRelStyle(customerA, bankA, $offsetY="60") Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.") } - Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){ + Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS"){ Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,
Apple Safari or Microsoft Edge"){ Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.") } diff --git a/packages/mermaid/src/docs/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md similarity index 94% rename from packages/mermaid/src/docs/classDiagram.md rename to packages/mermaid/src/docs/syntax/classDiagram.md index 51383fb6a..a0f4e5611 100644 --- a/packages/mermaid/src/docs/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -9,8 +9,13 @@ The class diagram is the main building block of object-oriented modeling. It is Mermaid can render class diagrams. ```mermaid-example +--- +title: Animal example +--- classDiagram + note "From Duck till Zebra" Animal <|-- Duck + note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging" Animal <|-- Fish Animal <|-- Zebra Animal : +int age @@ -44,6 +49,9 @@ A single instance of a class in the diagram contains three compartments: - The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase. ```mermaid-example +--- +title: Bank example +--- classDiagram class BankAccount BankAccount : +String owner @@ -165,16 +173,16 @@ A relationship is a general term covering the specific types of logical connecti There are eight different types of relations defined for classes under UML which are currently supported: -| Type | Description | -| ----- | ------------- | -| <\|-- | Inheritance | -| \*-- | Composition | -| o-- | Aggregation | -| --> | Association | -| -- | Link (Solid) | -| ..> | Dependency | -| ..\|> | Realization | -| .. | Link (Dashed) | +| Type | Description | +| ------- | ------------- | +| `<\|--` | Inheritance | +| `\*--` | Composition | +| `o--` | Aggregation | +| `-->` | Association | +| `--` | Link (Solid) | +| `..>` | Dependency | +| `..\|>` | Realization | +| `..` | Link (Dashed) | ```mermaid-example classDiagram @@ -236,14 +244,14 @@ Here is the syntax: Where `Relation Type` can be one of: -| Type | Description | -| ---- | ----------- | -| <\| | Inheritance | -| \* | Composition | -| o | Aggregation | -| > | Association | -| < | Association | -| \|> | Realization | +| Type | Description | +| ----- | ----------- | +| `<\|` | Inheritance | +| `\*` | Composition | +| `o` | Aggregation | +| `>` | Association | +| `<` | Association | +| `\|>` | Realization | And `Link` can be one of: @@ -376,6 +384,10 @@ click className href "url" "tooltip" - (_optional_) tooltip is a string to be displayed when hovering over element (note: The styles of the tooltip are set by the class .mermaidTooltip.) - note: callback function will be called with the nodeId as parameter. +## Notes + +It is possible to add notes on diagram using `note "line1\nline2"` or note for class using `note for class "line1\nline2"` + ### Examples _URL Link:_ @@ -400,7 +412,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback" ```html @@ -452,10 +464,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
@@ -495,10 +508,10 @@ Beginner's tip—a full example using interactive links in a html context:
+``` + +You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done. diff --git a/packages/mermaid/src/docs/pie.md b/packages/mermaid/src/docs/syntax/pie.md similarity index 89% rename from packages/mermaid/src/docs/pie.md rename to packages/mermaid/src/docs/syntax/pie.md index b7dcd7aa5..2fe8c3e54 100644 --- a/packages/mermaid/src/docs/pie.md +++ b/packages/mermaid/src/docs/syntax/pie.md @@ -19,10 +19,10 @@ Drawing a pie chart is really simple in mermaid. - Start with `pie` keyword to begin the diagram - `showData` to render the actual data values after the legend text. This is **_OPTIONAL_** - Followed by `title` keyword and its value in string to give a title to the pie-chart. This is **_OPTIONAL_** -- Followed by dataSet +- Followed by dataSet. Pie slices will be ordered clockwise in the same order as the labels. - `label` for a section in the pie diagram within `" "` quotes. - Followed by `:` colon as separator - - Followed by `positive numeric value` (supported upto two decimal places) + - Followed by `positive numeric value` (supported up to two decimal places) [pie] [showData] (OPTIONAL) [title] [titlevalue] (OPTIONAL) diff --git a/packages/mermaid/src/docs/requirementDiagram.md b/packages/mermaid/src/docs/syntax/requirementDiagram.md similarity index 100% rename from packages/mermaid/src/docs/requirementDiagram.md rename to packages/mermaid/src/docs/syntax/requirementDiagram.md diff --git a/packages/mermaid/src/docs/sequenceDiagram.md b/packages/mermaid/src/docs/syntax/sequenceDiagram.md similarity index 99% rename from packages/mermaid/src/docs/sequenceDiagram.md rename to packages/mermaid/src/docs/syntax/sequenceDiagram.md index 434e9572f..9c28883c9 100644 --- a/packages/mermaid/src/docs/sequenceDiagram.md +++ b/packages/mermaid/src/docs/syntax/sequenceDiagram.md @@ -534,10 +534,10 @@ text.actor { ## Configuration -Is it possible to adjust the margins for rendering the sequence diagram. +It is possible to adjust the margins for rendering the sequence diagram. This is done by defining `mermaid.sequenceConfig` or by the CLI to use a json file with the configuration. -How to use the CLI is described in the [mermaidCLI](mermaidCLI) page. +How to use the CLI is described in the [mermaidCLI](../config/mermaidCLI.md) page. `mermaid.sequenceConfig` can be set to a JSON string with config parameters or the corresponding object. ```javascript diff --git a/packages/mermaid/src/docs/syntax/stateDiagram.md b/packages/mermaid/src/docs/syntax/stateDiagram.md new file mode 100644 index 000000000..29e355a72 --- /dev/null +++ b/packages/mermaid/src/docs/syntax/stateDiagram.md @@ -0,0 +1,412 @@ +# State diagrams + +> "A state diagram is a type of diagram used in computer science and related fields to describe the behavior of systems. +> State diagrams require that the system described is composed of a finite number of states; sometimes, this is indeed the +> case, while at other times this is a reasonable abstraction." Wikipedia + +Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make +it easier for users to share diagrams between mermaid and plantUml. + +```mermaid-example +--- +title: Simple sample +--- +stateDiagram-v2 + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +Older renderer: + +```mermaid-example +stateDiagram + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] +``` + +In state diagrams systems are described in terms of _states_ and how one _state_ can change to another _state_ via +a _transition._ The example diagram above shows three states: **Still**, **Moving** and **Crash**. You start in the +**Still** state. From **Still** you can change to the **Moving** state. From **Moving** you can change either back to the **Still** state or to +the **Crash** state. There is no transition from **Still** to **Crash**. (You can't crash if you're still.) + +## States + +A state can be declared in multiple ways. The simplest way is to define a state with just an id: + +```mermaid-example +stateDiagram-v2 + stateId +``` + +Another way is by using the state keyword with a description as per below: + +```mermaid-example +stateDiagram-v2 + state "This is a state description" as s2 +``` + +Another way to define a state with a description is to define the state id followed by a colon and the description: + +```mermaid-example +stateDiagram-v2 + s2 : This is a state description +``` + +## Transitions + +Transitions are path/edges when one state passes into another. This is represented using text arrow, "\-\-\>". + +When you define a transition between two states and the states are not already defined, the undefined states are defined +with the id from the transition. You can later add descriptions to states defined this way. + +```mermaid-example +stateDiagram-v2 + s1 --> s2 +``` + +It is possible to add text to a transition to describe what it represents: + +```mermaid-example +stateDiagram-v2 + s1 --> s2: A transition +``` + +## Start and End + +There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and +the direction of the transition to it defines it either as a start or a stop state. + +```mermaid-example +stateDiagram-v2 + [*] --> s1 + s1 --> [*] +``` + +## Composite states + +In a real world use of state diagrams you often end up with diagrams that are multidimensional as one state can +have several internal states. These are called composite states in this terminology. + +In order to define a composite state you need to use the state keyword followed by an id and the body of the composite +state between \{\}. See the example below: + +```mermaid-example +stateDiagram-v2 + [*] --> First + state First { + [*] --> second + second --> [*] + } +``` + +You can do this in several layers: + +```mermaid-example +stateDiagram-v2 + [*] --> First + + state First { + [*] --> Second + + state Second { + [*] --> second + second --> Third + + state Third { + [*] --> third + third --> [*] + } + } + } +``` + +You can also define transitions also between composite states: + +```mermaid-example +stateDiagram-v2 + [*] --> First + First --> Second + First --> Third + + state First { + [*] --> fir + fir --> [*] + } + state Second { + [*] --> sec + sec --> [*] + } + state Third { + [*] --> thi + thi --> [*] + } +``` + +_You can not define transitions between internal states belonging to different composite states_ + +## Choice + +Sometimes you need to model a choice between two or more paths, you can do so using <<choice>>. + +```mermaid-example +stateDiagram-v2 + state if_state <> + [*] --> IsPositive + IsPositive --> if_state + if_state --> False: if n < 0 + if_state --> True : if n >= 0 +``` + +## Forks + +It is possible to specify a fork in the diagram using <<fork>> <<join>>. + +```mermaid-example + stateDiagram-v2 + state fork_state <> + [*] --> fork_state + fork_state --> State2 + fork_state --> State3 + + state join_state <> + State2 --> join_state + State3 --> join_state + join_state --> State4 + State4 --> [*] +``` + +## Notes + +Sometimes nothing says it better than a Post-it note. That is also the case in state diagrams. + +Here you can choose to put the note to the _right of_ or to the _left of_ a node. + +```mermaid-example + stateDiagram-v2 + State1: The state with a note + note right of State1 + Important information! You can write + notes. + end note + State1 --> State2 + note left of State2 : This is the note to the left. +``` + +## Concurrency + +As in plantUml you can specify concurrency using the -- symbol. + +```mermaid-example +stateDiagram-v2 + [*] --> Active + + state Active { + [*] --> NumLockOff + NumLockOff --> NumLockOn : EvNumLockPressed + NumLockOn --> NumLockOff : EvNumLockPressed + -- + [*] --> CapsLockOff + CapsLockOff --> CapsLockOn : EvCapsLockPressed + CapsLockOn --> CapsLockOff : EvCapsLockPressed + -- + [*] --> ScrollLockOff + ScrollLockOff --> ScrollLockOn : EvScrollLockPressed + ScrollLockOn --> ScrollLockOff : EvScrollLockPressed + } +``` + +## Setting the direction of the diagram + +With state diagrams you can use the direction statement to set the direction which the diagram will render like in this +example. + +```mermaid-example +stateDiagram + direction LR + [*] --> A + A --> B + B --> C + state B { + direction LR + a --> b + } + B --> D +``` + +## Comments + +Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their +own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next +newline will be treated as a comment, including any diagram syntax + +```mmd +stateDiagram-v2 + [*] --> Still + Still --> [*] +%% this is a comment + Still --> Moving + Moving --> Still %% another comment + Moving --> Crash + Crash --> [*] +``` + +## Styling with classDefs + +As with other diagrams (like flowcharts), you can define a style in the diagram itself and apply that named style to a +state or states in the diagram. + +**These are the current limitations with state diagram classDefs:** + +1. Cannot be applied to start or end states +2. Cannot be applied to or within composite states + +_These are in development and will be available in a future version._ + +You define a style using the `classDef` keyword, which is short for "class definition" (where "class" means something +like a _CSS class_) +followed by _a name for the style,_ +and then one or more _property-value pairs_. Each _property-value pair_ is +a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by a colon (`:`) and then a _value._ + +Here is an example of a classDef with just one property-value pair: + +``` + classDef movement font-style:italic; +``` + +where + +- the _name_ of the style is `movement` +- the only _property_ is `font-style` and its _value_ is `italic` + +If you want to have more than one _property-value pair_ then you put a comma (`,`) between each _property-value pair._ + +Here is an example with three property-value pairs: + +``` + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow +``` + +where + +- the _name_ of the style is `badBadEvent` +- the first _property_ is `fill` and its _value_ is `#f00` +- the second _property_ is `color` and its _value_ is `white` +- the third _property_ is `font-weight` and its _value_ is `bold` +- the fourth _property_ is `stroke-width` and its _value_ is `2px` +- the fifth _property_ is `stroke` and its _value_ is `yello` + +### Apply classDef styles to states + +There are two ways to apply a `classDef` style to a state: + +1. use the `class` keyword to apply a classDef style to one or more states in a single statement, or +2. use the `:::` operator to apply a classDef style to a state as it is being used in a transition statement (e.g. with an arrow + to/from another state) + +#### 1. `class` statement + +A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is: + +```text + class [one or more state names, separated by commas] [name of a style defined with classDef] +``` + +Here is an example applying the `badBadEvent` style to a state named `Crash`: + +```text +class Crash badBadEvent +``` + +Here is an example applying the `movement` style to the two states `Moving` and `Crash`: + +```text +class Moving, Crash movement +``` + +Here is a diagram that shows the examples in use. Note that the `Crash` state has two classDef styles applied: `movement` +and `badBadEvent` + +```mermaid-example + stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*]--> Still + Still --> [*] + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + + class Still notMoving + class Moving, Crash movement + class Crash badBadEvent + class end badBadEvent +``` + +#### 2. `:::` operator to apply a style to a state + +You can apply a classDef style to a state using the `:::` (three colons) operator. The syntax is + +```text +[state]:::[style name] +``` + +You can use this in a diagram within a statement using a class. This includes the start and end states. For example: + +```mermaid-example +stateDiagram + direction TB + + accTitle: This is the accessible title + accDescr: This is an accessible description + + classDef notMoving fill:white + classDef movement font-style:italic; + classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow + + [*] --> Still:::notMoving + Still --> [*] + Still --> Moving:::movement + Moving --> Still + Moving --> Crash:::movement + Crash:::badBadEvent --> [*] +``` + +## Spaces in state names + +Spaces can be added to a state by first defining the state with an id and then referencing the id later. + +In the following example there is a state with the id **yswsii** and description **Your state with spaces in it**. +After it has been defined, **yswsii** is used in the diagram in the first transition (`[*] --> yswsii`) +and also in the transition to **YetAnotherState** (`yswsii --> YetAnotherState`). +(**yswsii** has been styled so that it is different from the other states.) + +```mermaid-example +stateDiagram + classDef yourState font-style:italic,font-weight:bold,fill:white + + yswsii: Your state with spaces in it + [*] --> yswsii:::yourState + [*] --> SomeOtherState + SomeOtherState --> YetAnotherState + yswsii --> YetAnotherState + YetAnotherState --> [*] +``` diff --git a/packages/mermaid/src/docs/user-journey.md b/packages/mermaid/src/docs/syntax/userJourney.md similarity index 100% rename from packages/mermaid/src/docs/user-journey.md rename to packages/mermaid/src/docs/syntax/userJourney.md diff --git a/packages/mermaid/src/docs/theme.css b/packages/mermaid/src/docs/theme.css deleted file mode 100644 index 28dbc0ab5..000000000 --- a/packages/mermaid/src/docs/theme.css +++ /dev/null @@ -1,827 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600'); -* { - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-text-size-adjust: none; - -webkit-touch-callout: none; - box-sizing: border-box; -} - -body:not(.ready) { - overflow: hidden; -} -body:not(.ready) .app-nav, -body:not(.ready) > nav, -body:not(.ready) [data-cloak] { - display: none; -} -div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; -} -div#app:empty:before { - content: 'Loading...'; -} -.emoji { - height: 1.2rem; - vertical-align: middle; -} -.progress { - background-color: var(--theme-color, #42b983); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; -} -.search .search-keyword, -.search a:hover { - color: var(--theme-color, #42b983); -} -.search .search-keyword { - font-style: normal; - font-weight: 700; -} -body, -html { - height: 100%; -} -body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #34495e; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; -} -img { - max-width: 100%; -} -a[disabled] { - cursor: not-allowed; - opacity: 0.6; -} -kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; -} -li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; -} -.app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; -} -.app-nav.no-badge { - margin-right: 25px; -} -.app-nav p { - margin: 0; -} -.app-nav > a { - margin: 0 1rem; - padding: 5px 0; -} -.app-nav li, -.app-nav ul { - display: inline-block; - list-style: none; - margin: 0; -} -.app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; -} -.app-nav a.active, -.app-nav a:hover { - color: var(--theme-color, #42b983); -} -.app-nav a.active { - border-bottom: 2px solid var(--theme-color, #42b983); -} -.app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; -} -.app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; -} -.app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; -} -.app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; -} -.app-nav li ul a.active { - border-bottom: 0; -} -.app-nav li:hover ul { - display: block; -} -.github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; -} -.github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; -} -.github-corner svg { - color: #fff; - fill: var(--theme-color, #42b983); - height: 80px; - width: 80px; -} -main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; -} -main.hidden { - display: none; -} -.anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; -} -.anchor span { - color: #34495e; -} -.anchor:hover { - text-decoration: underline; -} -.sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; -} -.sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; -} -.sidebar > h1 a { - color: inherit; - text-decoration: none; -} -.sidebar > h1 .app-nav { - display: block; - position: static; -} -.sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; -} -.sidebar li.collapse .app-sub-sidebar { - display: none; -} -.sidebar ul { - margin: 0 0 0 15px; - padding: 0; -} -.sidebar li > p { - font-weight: 700; - margin: 0; -} -.sidebar ul, -.sidebar ul li { - list-style: none; -} -.sidebar ul li a { - border-bottom: none; - display: block; -} -.sidebar ul li ul { - padding-left: 20px; -} -.sidebar::-webkit-scrollbar { - width: 4px; -} -.sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; -} -.sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); -} -.sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); -} -.sidebar-toggle { - background-color: transparent; - background-color: hsla(0, 0%, 100%, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; -} -.sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; -} -.sidebar-toggle span { - background-color: var(--theme-color, #42b983); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; -} -body.sticky .sidebar, -body.sticky .sidebar-toggle { - position: fixed; -} -.content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; -} -.markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; -} -.markdown-section > * { - box-sizing: border-box; - font-size: inherit; -} -.markdown-section > :first-child { - margin-top: 0 !important; -} -.markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; -} -.markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; -} -.markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; -} -.markdown-section th { - font-weight: 700; -} -.markdown-section td, -.markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; -} -.markdown-section tr { - border-top: 1px solid #ccc; -} -.markdown-section p.tip, -.markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; -} -.markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; -} -.markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #fff; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; -} -.markdown-section p.tip code { - background-color: #efefef; -} -.markdown-section p.tip em { - color: #34495e; -} -.markdown-section p.warn { - background: rgba(66, 185, 131, 0.1); - border-radius: 2px; - padding: 1rem; -} -.markdown-section ul.task-list > li { - list-style-type: none; -} -body.close .sidebar { - transform: translateX(-300px); -} -body.close .sidebar-toggle { - width: auto; -} -body.close .content { - left: 0; -} -@media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } -} -@media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: hsla(0, 0%, 100%, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } -} -@-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } -} -@keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } -} -section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; -} -section.cover.show { - display: flex; -} -section.cover.has-mask .mask { - background-color: #fff; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; -} -section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; -} -section.cover a { - color: inherit; -} -section.cover a, -section.cover a:hover { - text-decoration: none; -} -section.cover p { - line-height: 1.5rem; - margin: 1em 0; -} -section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; -} -section.cover h1 a { - display: block; -} -section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; -} -section.cover blockquote { - font-size: 1.5rem; - text-align: center; -} -section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; -} -section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #42b983); - box-sizing: border-box; - color: var(--theme-color, #42b983); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; -} -section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #42b983); - color: #fff; -} -section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; -} -section.cover .cover-main > p:last-child a:hover { - color: inherit; -} -section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #42b983); - transition: color 0.3s; -} -section.cover blockquote > p > a:hover { - color: var(--theme-color, #42b983); -} -.sidebar, -body { - background-color: #fff; -} -.sidebar { - color: #364149; -} -.sidebar li { - margin: 6px 0; -} -.sidebar ul li a { - color: #505d6b; - font-size: 14px; - font-weight: 400; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; -} -.sidebar ul li a:hover { - text-decoration: underline; -} -.sidebar ul li ul { - padding: 0; -} -.sidebar ul li.active > a { - border-right: 2px solid; - color: var(--theme-color, #42b983); - font-weight: 600; -} -.app-sub-sidebar li:before { - content: '-'; - padding-right: 4px; - float: left; -} -.markdown-section h1, -.markdown-section h2, -.markdown-section h3, -.markdown-section h4, -.markdown-section strong { - color: #2c3e50; - font-weight: 600; -} -.markdown-section a { - color: var(--theme-color, #42b983); - font-weight: 600; -} -.markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; -} -.markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; -} -.markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; -} -.markdown-section h4 { - font-size: 1.25rem; -} -.markdown-section h5 { - font-size: 1rem; -} -.markdown-section h6 { - color: #777; - font-size: 1rem; -} -.markdown-section figure, -.markdown-section p { - margin: 1.2em 0; -} -.markdown-section ol, -.markdown-section p, -.markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; -} -.markdown-section ol, -.markdown-section ul { - padding-left: 1.5rem; -} -.markdown-section blockquote { - border-left: 4px solid var(--theme-color, #42b983); - color: #858585; - margin: 2em 0; - padding-left: 20px; -} -.markdown-section blockquote p { - font-weight: 600; - margin-left: 0; -} -.markdown-section iframe { - margin: 1em 0; -} -.markdown-section em { - color: #7f8c8d; -} -.markdown-section code { - border-radius: 2px; - color: #e96900; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; -} -.markdown-section code, -.markdown-section pre { - background-color: #f8f8f8; - font-family: Roboto Mono, Monaco, courier, monospace; -} -.markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; -} -.token.cdata, -.token.comment, -.token.doctype, -.token.prolog { - color: #8e908c; -} -.token.namespace { - opacity: 0.7; -} -.token.boolean, -.token.number { - color: #c76b29; -} -.token.punctuation { - color: #525252; -} -.token.property { - color: #c08b30; -} -.token.tag { - color: #2973b7; -} -.token.string { - color: var(--theme-color, #42b983); -} -.token.selector { - color: #6679cc; -} -.token.attr-name { - color: #2973b7; -} -.language-css .token.string, -.style .token.string, -.token.entity, -.token.url { - color: #22a2c9; -} -.token.attr-value, -.token.control, -.token.directive, -.token.unit { - color: var(--theme-color, #42b983); -} -.token.function, -.token.keyword { - color: #e96900; -} -.token.atrule, -.token.regex, -.token.statement { - color: #22a2c9; -} -.token.placeholder, -.token.variable { - color: #3d8fd1; -} -.token.deleted { - text-decoration: line-through; -} -.token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; -} -.token.italic { - font-style: italic; -} -.token.bold, -.token.important { - font-weight: 700; -} -.token.important { - color: #c94922; -} -.token.entity { - cursor: help; -} -.markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #f8f8f8; - border-radius: 2px; - color: #525252; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; -} -.markdown-section code:after, -.markdown-section code:before { - letter-spacing: 0.05rem; -} -code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; -} -pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; -} diff --git a/packages/mermaid/src/docs/theme_themed.css b/packages/mermaid/src/docs/theme_themed.css deleted file mode 100644 index 9cb520ed7..000000000 --- a/packages/mermaid/src/docs/theme_themed.css +++ /dev/null @@ -1,1653 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600'); -* { - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-text-size-adjust: none; - -webkit-touch-callout: none; - box-sizing: border-box; -} - -@media (prefers-color-scheme: dark2) { - body:not(.ready) { - overflow: hidden; - } - body:not(.ready) .app-nav, - body:not(.ready) > nav, - body:not(.ready) [data-cloak] { - display: none; - } - div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; - } - div#app:empty:before { - content: 'Loading...'; - } - .emoji { - height: 1.2rem; - vertical-align: middle; - } - .progress { - background-color: var(--theme-color, #ea6f5a); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; - } - .search .search-keyword, - .search a:hover { - color: var(--theme-color, #ea6f5a); - } - .search .search-keyword { - font-style: normal; - font-weight: 700; - } - body, - html { - height: 100%; - } - body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #c8c8c8; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; - } - img { - max-width: 100%; - } - a[disabled] { - cursor: not-allowed; - opacity: 0.6; - } - kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; - } - li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; - } - .app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; - } - .app-nav.no-badge { - margin-right: 25px; - } - .app-nav p { - margin: 0; - } - .app-nav > a { - margin: 0 1rem; - padding: 5px 0; - } - .app-nav li, - .app-nav ul { - display: inline-block; - list-style: none; - margin: 0; - } - .app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; - } - .app-nav a.active, - .app-nav a:hover { - color: var(--theme-color, #ea6f5a); - } - .app-nav a.active { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - } - .app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; - } - .app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; - } - .app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; - } - .app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; - } - .app-nav li ul a.active { - border-bottom: 0; - } - .app-nav li:hover ul { - display: block; - } - .github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; - } - .github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - .github-corner svg { - color: #3f3f3f; - fill: var(--theme-color, #ea6f5a); - height: 80px; - width: 80px; - } - main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; - } - main.hidden { - display: none; - } - .anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; - } - .anchor span { - color: #c8c8c8; - } - .anchor:hover { - text-decoration: underline; - } - .sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; - } - .sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; - } - .sidebar > h1 a { - color: inherit; - text-decoration: none; - } - .sidebar > h1 .app-nav { - display: block; - position: static; - } - .sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; - } - .sidebar li.collapse .app-sub-sidebar { - display: none; - } - .sidebar ul { - margin: 0 0 0 15px; - padding: 0; - } - .sidebar li > p { - font-weight: 700; - margin: 0; - } - .sidebar ul, - .sidebar ul li { - list-style: none; - } - .sidebar ul li a { - border-bottom: none; - display: block; - } - .sidebar ul li ul { - padding-left: 20px; - } - .sidebar::-webkit-scrollbar { - width: 4px; - } - .sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; - } - .sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); - } - .sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); - } - .sidebar-toggle { - background-color: transparent; - background-color: rgba(63, 63, 63, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; - } - .sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; - } - .sidebar-toggle span { - background-color: var(--theme-color, #ea6f5a); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; - } - body.sticky .sidebar, - body.sticky .sidebar-toggle { - position: fixed; - } - .content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; - } - .markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; - } - .markdown-section > * { - box-sizing: border-box; - font-size: inherit; - } - .markdown-section > :first-child { - margin-top: 0 !important; - } - .markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; - } - .markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; - } - .markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; - } - .markdown-section th { - font-weight: 700; - } - .markdown-section td, - .markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; - } - .markdown-section tr { - border-top: 1px solid #ccc; - } - .markdown-section p.tip, - .markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; - } - .markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; - } - .markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #3f3f3f; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; - } - .markdown-section p.tip code { - background-color: #efefef; - } - .markdown-section p.tip em { - color: #c8c8c8; - } - .markdown-section p.warn { - background: rgba(234, 111, 90, 0.1); - border-radius: 2px; - padding: 1rem; - } - .markdown-section ul.task-list > li { - list-style-type: none; - } - body.close .sidebar { - transform: translateX(-300px); - } - body.close .sidebar-toggle { - width: auto; - } - body.close .content { - left: 0; - } - @media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } - } - @media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: rgba(63, 63, 63, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - } - @-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - @keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; - } - section.cover.show { - display: flex; - } - section.cover.has-mask .mask { - background-color: #3f3f3f; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; - } - section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; - } - section.cover a { - color: inherit; - } - section.cover a, - section.cover a:hover { - text-decoration: none; - } - section.cover p { - line-height: 1.5rem; - margin: 1em 0; - } - section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; - } - section.cover h1 a { - display: block; - } - section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; - } - section.cover blockquote { - font-size: 1.5rem; - text-align: center; - } - section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; - } - section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #ea6f5a); - box-sizing: border-box; - color: var(--theme-color, #ea6f5a); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; - } - section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #ea6f5a); - color: #fff; - } - section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; - } - section.cover .cover-main > p:last-child a:hover { - color: inherit; - } - section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - transition: color 0.3s; - } - section.cover blockquote > p > a:hover { - color: var(--theme-color, #ea6f5a); - } - .sidebar, - body { - background-color: #3f3f3f; - } - .sidebar { - color: #c8c8c8; - } - .sidebar li { - margin: 6px 15px 6px 0; - } - .sidebar ul li a { - color: #c8c8c8; - font-size: 14px; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; - } - .sidebar ul li a:hover { - text-decoration: underline; - } - .sidebar ul li ul { - padding: 0; - } - .sidebar ul li.active > a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; - } - .markdown-section h1, - .markdown-section h2, - .markdown-section h3, - .markdown-section h4, - .markdown-section strong { - color: #657b83; - font-weight: 600; - } - .markdown-section a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; - } - .markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; - } - .markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; - } - .markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; - } - .markdown-section h4 { - font-size: 1.25rem; - } - .markdown-section h5 { - font-size: 1rem; - } - .markdown-section h6 { - color: #777; - font-size: 1rem; - } - .markdown-section figure, - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - margin: 1.2em 0; - } - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; - } - .markdown-section ol, - .markdown-section ul { - padding-left: 1.5rem; - } - .markdown-section blockquote { - border-left: 4px solid var(--theme-color, #ea6f5a); - color: #858585; - margin: 2em 0; - padding-left: 20px; - } - .markdown-section blockquote p { - font-weight: 600; - margin-left: 0; - } - .markdown-section iframe { - margin: 1em 0; - } - .markdown-section em { - color: #7f8c8d; - } - .markdown-section code { - border-radius: 2px; - color: #657b83; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; - } - .markdown-section code, - .markdown-section pre { - background-color: #282828; - font-family: Roboto Mono, Monaco, courier, monospace; - } - .markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; - } - .token.cdata, - .token.comment, - .token.doctype, - .token.prolog { - color: #8e908c; - } - .token.namespace { - opacity: 0.7; - } - .token.boolean, - .token.number { - color: #c76b29; - } - .token.punctuation { - color: #525252; - } - .token.property { - color: #c08b30; - } - .token.tag { - color: #2973b7; - } - .token.string { - color: var(--theme-color, #ea6f5a); - } - .token.selector { - color: #6679cc; - } - .token.attr-name { - color: #2973b7; - } - .language-css .token.string, - .style .token.string, - .token.entity, - .token.url { - color: #22a2c9; - } - .token.attr-value, - .token.control, - .token.directive, - .token.unit { - color: var(--theme-color, #ea6f5a); - } - .token.keyword { - color: #e96900; - } - .token.atrule, - .token.regex, - .token.statement { - color: #22a2c9; - } - .token.placeholder, - .token.variable { - color: #3d8fd1; - } - .token.deleted { - text-decoration: line-through; - } - .token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; - } - .token.italic { - font-style: italic; - } - .token.bold, - .token.important { - font-weight: 700; - } - .token.important { - color: #c94922; - } - .token.entity { - cursor: help; - } - .markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #282828; - border-radius: 2px; - color: #657b83; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; - } - .markdown-section code:after, - .markdown-section code:before { - letter-spacing: 0.05rem; - } - code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; - } - pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; - } - .markdown-section p.tip { - background-color: #282828; - color: #657b83; - } - input[type='search'] { - background: #4f4f4f; - border-color: #4f4f4f; - color: #c8c8c8; - } -} - -@media (prefers-color-scheme: light or prefers-color-scheme: dark) { - /* @media (screen) { */ - body:not(.ready) { - overflow: hidden; - } - body:not(.ready) .app-nav, - body:not(.ready) > nav, - body:not(.ready) [data-cloak] { - display: none; - } - div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; - } - div#app:empty:before { - content: 'Loading...'; - } - .emoji { - height: 1.2rem; - vertical-align: middle; - } - .progress { - background-color: var(--theme-color, #42b983); - height: 2px; - left: 0; - position: fixed; - right: 0; - top: 0; - transition: width 0.2s, opacity 0.4s; - width: 0; - z-index: 999999; - } - .search .search-keyword, - .search a:hover { - color: var(--theme-color, #42b983); - } - .search .search-keyword { - font-style: normal; - font-weight: 700; - } - body, - html { - height: 100%; - } - body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #34495e; - font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; - } - img { - max-width: 100%; - } - a[disabled] { - cursor: not-allowed; - opacity: 0.6; - } - kbd { - border: 1px solid #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; - } - li input[type='checkbox'] { - margin: 0 0.2em 0.25em 0; - vertical-align: middle; - } - .app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; - } - .app-nav.no-badge { - margin-right: 25px; - } - .app-nav p { - margin: 0; - } - .app-nav > a { - margin: 0 1rem; - padding: 5px 0; - } - .app-nav li, - .app-nav ul { - display: inline-block; - list-style: none; - margin: 0; - } - .app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - transition: color 0.3s; - } - .app-nav a.active, - .app-nav a:hover { - color: var(--theme-color, #42b983); - } - .app-nav a.active { - border-bottom: 2px solid var(--theme-color, #42b983); - } - .app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; - cursor: pointer; - } - .app-nav li ul { - background-color: #fff; - border: 1px solid; - border-color: #ddd #ddd #ccc; - border-radius: 4px; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; - } - .app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 8px 14px; - white-space: nowrap; - } - .app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; - } - .app-nav li ul a.active { - border-bottom: 0; - } - .app-nav li:hover ul { - display: block; - } - .github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; - } - .github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - .github-corner svg { - color: #fff; - fill: var(--theme-color, #42b983); - height: 80px; - width: 80px; - } - main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; - } - main.hidden { - display: none; - } - .anchor { - display: inline-block; - text-decoration: none; - transition: all 0.3s; - } - .anchor span { - color: #34495e; - } - .anchor:hover { - text-decoration: underline; - } - .sidebar { - border-right: 1px solid rgba(0, 0, 0, 0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - transition: transform 0.25s ease-out; - width: 300px; - z-index: 20; - } - .sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; - } - .sidebar > h1 a { - color: inherit; - text-decoration: none; - } - .sidebar > h1 .app-nav { - display: block; - position: static; - } - .sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; - } - .sidebar li.collapse .app-sub-sidebar { - display: none; - } - .sidebar ul { - margin: 0 0 0 15px; - padding: 0; - } - .sidebar li > p { - font-weight: 700; - margin: 0; - } - .sidebar ul, - .sidebar ul li { - list-style: none; - } - .sidebar ul li a { - border-bottom: none; - display: block; - } - .sidebar ul li ul { - padding-left: 20px; - } - .sidebar::-webkit-scrollbar { - width: 4px; - } - .sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; - } - .sidebar:hover::-webkit-scrollbar-thumb { - background: hsla(0, 0%, 53.3%, 0.4); - } - .sidebar:hover::-webkit-scrollbar-track { - background: hsla(0, 0%, 53.3%, 0.1); - } - .sidebar-toggle { - background-color: transparent; - background-color: hsla(0, 0%, 100%, 0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - transition: opacity 0.3s; - width: 284px; - z-index: 30; - cursor: pointer; - } - .sidebar-toggle:hover .sidebar-toggle-button { - opacity: 0.4; - } - .sidebar-toggle span { - background-color: var(--theme-color, #42b983); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; - } - body.sticky .sidebar, - body.sticky .sidebar-toggle { - position: fixed; - } - .content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - transition: left 0.25s ease; - } - .markdown-section { - margin: 0 auto; - max-width: 80%; - padding: 30px 15px 40px; - position: relative; - } - .markdown-section > * { - box-sizing: border-box; - font-size: inherit; - } - .markdown-section > :first-child { - margin-top: 0 !important; - } - .markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; - } - .markdown-section iframe { - border: 1px solid #eee; - width: 1px; - min-width: 100%; - } - .markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; - } - .markdown-section th { - font-weight: 700; - } - .markdown-section td, - .markdown-section th { - border: 1px solid #ddd; - padding: 6px 13px; - } - .markdown-section tr { - border-top: 1px solid #ccc; - } - .markdown-section p.tip, - .markdown-section tr:nth-child(2n) { - background-color: #f8f8f8; - } - .markdown-section p.tip { - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; - } - .markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #fff; - content: '!'; - font-family: Dosis, Source Sans Pro, Helvetica Neue, Arial, sans-serif; - font-size: 14px; - font-weight: 700; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; - } - .markdown-section p.tip code { - background-color: #efefef; - } - .markdown-section p.tip em { - color: #34495e; - } - .markdown-section p.warn { - background: rgba(66, 185, 131, 0.1); - border-radius: 2px; - padding: 1rem; - } - .markdown-section ul.task-list > li { - list-style-type: none; - } - body.close .sidebar { - transform: translateX(-300px); - } - body.close .sidebar-toggle { - width: auto; - } - body.close .content { - left: 0; - } - @media print { - .app-nav, - .github-corner, - .sidebar, - .sidebar-toggle { - display: none; - } - } - @media screen and (max-width: 768px) { - .github-corner, - .sidebar, - .sidebar-toggle { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - transition: transform 0.25s ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - transition: transform 0.25s ease; - } - .app-nav, - .github-corner { - transition: transform 0.25s ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: hsla(0, 0%, 100%, 0.8); - transition: background-color 1s; - width: 284px; - padding: 10px; - } - body.close .content { - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 0.56s ease-in-out; - animation: octocat-wave 0.56s ease-in-out; - } - } - @-webkit-keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - @keyframes octocat-wave { - 0%, - to { - transform: rotate(0); - } - 20%, - 60% { - transform: rotate(-25deg); - } - 40%, - 80% { - transform: rotate(10deg); - } - } - section.cover { - align-items: center; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - width: 100vw; - display: none; - } - section.cover.show { - display: flex; - } - section.cover.has-mask .mask { - background-color: #fff; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; - } - section.cover .cover-main { - flex: 1; - margin: -20px 16px 0; - text-align: center; - } - section.cover a { - color: inherit; - } - section.cover a, - section.cover a:hover { - text-decoration: none; - } - section.cover p { - line-height: 1.5rem; - margin: 1em 0; - } - section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; - } - section.cover h1 a { - display: block; - } - section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; - } - section.cover blockquote { - font-size: 1.5rem; - text-align: center; - } - section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; - } - section.cover .cover-main > p:last-child a { - border-radius: 2rem; - border: 1px solid var(--theme-color, #42b983); - box-sizing: border-box; - color: var(--theme-color, #42b983); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - transition: all 0.15s ease; - } - section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #42b983); - color: #fff; - } - section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; - } - section.cover .cover-main > p:last-child a:hover { - color: inherit; - } - section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #42b983); - transition: color 0.3s; - } - section.cover blockquote > p > a:hover { - color: var(--theme-color, #42b983); - } - .sidebar, - body { - background-color: #fff; - } - .sidebar { - color: #364149; - } - .sidebar li { - margin: 6px 0; - } - .sidebar ul li a { - color: #505d6b; - font-size: 14px; - font-weight: 400; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; - } - .sidebar ul li a:hover { - text-decoration: underline; - } - .sidebar ul li ul { - padding: 0; - } - .sidebar ul li.active > a { - border-right: 2px solid; - color: var(--theme-color, #42b983); - font-weight: 600; - } - .app-sub-sidebar li:before { - content: '-'; - padding-right: 4px; - float: left; - } - .markdown-section h1, - .markdown-section h2, - .markdown-section h3, - .markdown-section h4, - .markdown-section strong { - color: #2c3e50; - font-weight: 600; - } - .markdown-section a { - color: var(--theme-color, #42b983); - font-weight: 600; - } - .markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; - } - .markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; - } - .markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; - } - .markdown-section h4 { - font-size: 1.25rem; - } - .markdown-section h5 { - font-size: 1rem; - } - .markdown-section h6 { - color: #777; - font-size: 1rem; - } - .markdown-section figure, - .markdown-section p { - margin: 1.2em 0; - } - .markdown-section ol, - .markdown-section p, - .markdown-section ul { - line-height: 1.6rem; - word-spacing: 0.05rem; - } - .markdown-section ol, - .markdown-section ul { - padding-left: 1.5rem; - } - .markdown-section blockquote { - border-left: 4px solid var(--theme-color, #42b983); - color: #858585; - margin: 2em 0; - padding-left: 20px; - } - .markdown-section blockquote p { - font-weight: 600; - margin-left: 0; - } - .markdown-section iframe { - margin: 1em 0; - } - .markdown-section em { - color: #7f8c8d; - } - .markdown-section code { - border-radius: 2px; - color: #e96900; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; - } - .markdown-section code, - .markdown-section pre { - background-color: #f8f8f8; - font-family: Roboto Mono, Monaco, courier, monospace; - } - .markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; - } - .token.cdata, - .token.comment, - .token.doctype, - .token.prolog { - color: #8e908c; - } - .token.namespace { - opacity: 0.7; - } - .token.boolean, - .token.number { - color: #c76b29; - } - .token.punctuation { - color: #525252; - } - .token.property { - color: #c08b30; - } - .token.tag { - color: #2973b7; - } - .token.string { - color: var(--theme-color, #42b983); - } - .token.selector { - color: #6679cc; - } - .token.attr-name { - color: #2973b7; - } - .language-css .token.string, - .style .token.string, - .token.entity, - .token.url { - color: #22a2c9; - } - .token.attr-value, - .token.control, - .token.directive, - .token.unit { - color: var(--theme-color, #42b983); - } - .token.function, - .token.keyword { - color: #e96900; - } - .token.atrule, - .token.regex, - .token.statement { - color: #22a2c9; - } - .token.placeholder, - .token.variable { - color: #3d8fd1; - } - .token.deleted { - text-decoration: line-through; - } - .token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; - } - .token.italic { - font-style: italic; - } - .token.bold, - .token.important { - font-weight: 700; - } - .token.important { - color: #c94922; - } - .token.entity { - cursor: help; - } - .markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #f8f8f8; - border-radius: 2px; - color: #525252; - display: block; - font-family: Roboto Mono, Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; - } - .markdown-section code:after, - .markdown-section code:before { - letter-spacing: 0.05rem; - } - code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; - position: relative; - left: auto; - } - pre:after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; - } -} diff --git a/packages/mermaid/src/docs/upgrading.md b/packages/mermaid/src/docs/upgrading.md deleted file mode 100644 index 16dea1cba..000000000 --- a/packages/mermaid/src/docs/upgrading.md +++ /dev/null @@ -1,25 +0,0 @@ -# Upgrading - -Some of the interfaces has been upgraded. - -## From version 0.4.0 to 0.5.0 - -### Initialization - -`mermaid_config` is no longer used. Instead a call to mermaid initialize is done as in the example below: - -#### version 0.4.0 - -```javascript -mermaid_config = { - startOnLoad: true, -}; -``` - -#### version 0.5.0 - -```javascript -mermaid.initialize({ - startOnLoad: true, -}); -``` diff --git a/packages/mermaid/src/docs/vite.config.ts b/packages/mermaid/src/docs/vite.config.ts new file mode 100644 index 000000000..15652c21c --- /dev/null +++ b/packages/mermaid/src/docs/vite.config.ts @@ -0,0 +1,51 @@ +import { defineConfig, searchForWorkspaceRoot } from 'vite'; +import path from 'path'; +// @ts-ignore: still in alpha +import { SearchPlugin } from 'vitepress-plugin-search'; + +const virtualModuleId = 'virtual:mermaid-config'; +const resolvedVirtualModuleId = '\0' + virtualModuleId; + +export default defineConfig({ + plugins: [ + SearchPlugin(), + { + // TODO: will be fixed in the next vitepress release. + name: 'fix-virtual', + + async resolveId(id) { + if (id === virtualModuleId) { + return resolvedVirtualModuleId; + } + }, + async load(this, id) { + if (id === resolvedVirtualModuleId) { + return `export default ${JSON.stringify({ + securityLevel: 'loose', + startOnLoad: false, + })};`; + } + }, + }, + ], + resolve: { + alias: { + mermaid: path.join(__dirname, '../../dist/mermaid.esm.min.mjs'), // Use this one to build + + '@mermaid-js/mermaid-mindmap': path.join( + __dirname, + '../../../mermaid-mindmap/dist/mermaid-mindmap.esm.min.mjs' + ), // Use this one to build + }, + }, + server: { + fs: { + allow: [ + // search up for workspace root + searchForWorkspaceRoot(process.cwd()), + // Allow serving files from one level up to the project root + path.join(__dirname, '..'), + ], + }, + }, +}); diff --git a/packages/mermaid/src/logger.ts b/packages/mermaid/src/logger.ts index b01934e88..b1c035e22 100644 --- a/packages/mermaid/src/logger.ts +++ b/packages/mermaid/src/logger.ts @@ -27,7 +27,7 @@ export const log: Record = { /** * Sets a log level * - * @param {LogLevel} [level="fatal"] The level to set the logging to. Default is `"fatal"` + * @param level - The level to set the logging to. Default is `"fatal"` */ export const setLogLevel = function (level: keyof typeof LEVELS | number | string = 'fatal') { let numericLevel: number = LEVELS.fatal; @@ -45,6 +45,7 @@ export const setLogLevel = function (level: keyof typeof LEVELS | number | strin log.warn = () => {}; log.error = () => {}; log.fatal = () => {}; + if (numericLevel <= LEVELS.fatal) { log.fatal = console.error ? console.error.bind(console, format('FATAL'), 'color: orange') @@ -80,10 +81,10 @@ export const setLogLevel = function (level: keyof typeof LEVELS | number | strin /** * Returns a format with the timestamp and the log level * - * @param {LogLevel} level The level for the log format - * @returns {string} The format with the timestamp and log level + * @param level - The level for the log format + * @returns The format with the timestamp and log level */ -const format = (level: string): string => { +const format = (level: Uppercase): string => { const time = moment().format('ss.SSS'); return `%c${time} : ${level} : `; }; diff --git a/packages/mermaid/src/mermaid.spec.ts b/packages/mermaid/src/mermaid.spec.ts index df6439c82..aa797af0e 100644 --- a/packages/mermaid/src/mermaid.spec.ts +++ b/packages/mermaid/src/mermaid.spec.ts @@ -1,7 +1,6 @@ import mermaid from './mermaid'; import { mermaidAPI } from './mermaidAPI'; import './diagram-api/diagram-orchestration'; -import { vi, describe, it, beforeEach, afterEach, expect } from 'vitest'; const spyOn = vi.spyOn; vi.mock('./mermaidAPI'); @@ -55,6 +54,88 @@ describe('when using mermaid and ', function () { expect(mermaidAPI.render).toHaveBeenCalled(); }); }); + describe('when using #registerExternalDiagrams', function () { + it('should throw error (but still render) if registerExternalDiagrams fails', async () => { + const node = document.createElement('div'); + node.appendChild(document.createTextNode('graph TD;\na;')); + + await expect( + mermaid.registerExternalDiagrams( + [ + { + id: 'dummy', + detector: (text) => /dummy/.test(text), + loader: () => Promise.reject('error'), + }, + ], + { lazyLoad: false } + ) + ).rejects.toThrow('Failed to load 1 external diagrams'); + + expect(() => mermaid.initThrowsErrorsAsync(undefined, node)).not.toThrow(); + // should still render, even if lazyLoadedDiagrams fails + expect(mermaidAPI.renderAsync).toHaveBeenCalled(); + }); + + it('should defer diagram load based on parameter', async () => { + let loaded = false; + const dummyDiagram = { + db: {}, + renderer: () => { + // do nothing + }, + parser: () => { + // do nothing + }, + styles: () => { + // do nothing + }, + }; + await expect( + mermaid.registerExternalDiagrams( + [ + { + id: 'dummy', + detector: (text) => /dummy/.test(text), + loader: () => { + loaded = true; + return Promise.resolve({ + id: 'dummy', + diagram: dummyDiagram, + }); + }, + }, + ], + { lazyLoad: true } + ) + ).resolves.toBe(undefined); + expect(loaded).toBe(false); + await expect( + mermaid.registerExternalDiagrams( + [ + { + id: 'dummy2', + detector: (text) => /dummy2/.test(text), + loader: () => { + loaded = true; + return Promise.resolve({ + id: 'dummy2', + diagram: dummyDiagram, + }); + }, + }, + ], + { lazyLoad: false } + ) + ).resolves.toBe(undefined); + expect(loaded).toBe(true); + }); + + afterEach(() => { + // we modify mermaid config in some tests, so we need to make sure to reset them + mermaidAPI.reset(); + }); + }); describe('checking validity of input ', function () { it('should throw for an invalid definition', function () { diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index a7af45510..7a4d744e4 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -7,16 +7,14 @@ import { log } from './logger'; import utils from './utils'; import { mermaidAPI } from './mermaidAPI'; import { addDetector } from './diagram-api/detectType'; -import { - registerDiagram, - DiagramDefinition, - setLogLevel, - getConfig, - setupGraphViewbox, - sanitizeText, -} from './diagram-api/diagramAPI'; -import { isDetailedError } from './utils'; +import type { ParseErrorFunction } from './Diagram'; +import { isDetailedError, type DetailedError } from './utils'; +import { registerDiagram } from './diagram-api/diagramAPI'; +import { ExternalDiagramDefinition } from './diagram-api/types'; +export type { MermaidConfig, DetailedError, ExternalDiagramDefinition, ParseErrorFunction }; + +let externalDiagramsRegistered = false; /** * ## init * @@ -26,12 +24,6 @@ import { isDetailedError } from './utils'; * elements with the attribute already set. This way the init function can be triggered several * times. * - * Optionally, `init` can accept in the second argument one of the following: - * - * - A DOM Node - * - An array of DOM nodes (as would come from a jQuery selector) - * - A W3C selector, a la `.mermaid` - * * ```mermaid * graph LR; * a(Find elements)-->b{Processed} @@ -41,11 +33,14 @@ import { isDetailedError } from './utils'; * * Renders the mermaid diagrams * - * @param config - * @param nodes - * @param callback + * @param config - **Deprecated**, please set configuration in {@link initialize}. + * @param nodes - **Default**: `.mermaid`. One of the following: + * - A DOM Node + * - An array of DOM nodes (as would come from a jQuery selector) + * - A W3C selector, a la `.mermaid` + * @param callback - Called once for each rendered diagram's id. */ -const init = function ( +const init = async function ( config?: MermaidConfig, // eslint-disable-next-line no-undef nodes?: string | HTMLElement | NodeListOf, @@ -53,18 +48,45 @@ const init = function ( callback?: Function ) { try { - log.info('Detectors in init', mermaid.detectors); // eslint-disable-line - mermaid.detectors.forEach(({ id, detector, path }) => { - addDetector(id, detector, path); - }); - initThrowsErrors(config, nodes, callback); + // Not really sure if we need to check this, or simply call initThrowsErrorsAsync directly. + if (externalDiagramsRegistered) { + await initThrowsErrorsAsync(config, nodes, callback); + } else { + initThrowsErrors(config, nodes, callback); + } } catch (e) { log.warn('Syntax Error rendering'); if (isDetailedError(e)) { log.warn(e.str); } if (mermaid.parseError) { - mermaid.parseError(e); + mermaid.parseError(e as string); + } + } +}; + +// eslint-disable-next-line @typescript-eslint/ban-types +const handleError = (error: unknown, errors: DetailedError[], parseError?: Function) => { + log.warn(error); + if (isDetailedError(error)) { + // handle case where error string and hash were + // wrapped in object like`const error = { str, hash };` + if (parseError) { + parseError(error.str, error.hash); + } + errors.push({ ...error, message: error.str, error }); + } else { + // assume it is just error string and pass it on + if (parseError) { + parseError(error); + } + if (error instanceof Error) { + errors.push({ + str: error.message, + message: error.message, + hash: error.name, + error, + }); } } }; @@ -77,7 +99,6 @@ const initThrowsErrors = function ( callback?: Function ) { const conf = mermaidAPI.getConfig(); - // console.log('Starting rendering diagrams (init) - mermaid.init', conf); if (config) { // This is a legacy way of setting config. It is not documented and should be removed in the future. // @ts-ignore: TODO Fix ts errors @@ -87,7 +108,7 @@ const initThrowsErrors = function ( // if last argument is a function this is the callback function log.debug(`${!callback ? 'No ' : ''}Callback function found`); let nodesToProcess: ArrayLike; - if (typeof nodes === 'undefined') { + if (nodes === undefined) { nodesToProcess = document.querySelectorAll('.mermaid'); } else if (typeof nodes === 'string') { nodesToProcess = document.querySelectorAll(nodes); @@ -100,17 +121,19 @@ const initThrowsErrors = function ( } log.debug(`Found ${nodesToProcess.length} diagrams`); - if (typeof config?.startOnLoad !== 'undefined') { + if (config?.startOnLoad !== undefined) { log.debug('Start On Load: ' + config?.startOnLoad); mermaidAPI.updateSiteConfig({ startOnLoad: config?.startOnLoad }); } + // generate the id of the diagram const idGenerator = new utils.initIdGenerator(conf.deterministicIds, conf.deterministicIDSeed); - let txt; - const errors = []; + let txt: string; + const errors: DetailedError[] = []; // element is the current div with mermaid class + // eslint-disable-next-line unicorn/prefer-spread for (const element of Array.from(nodesToProcess)) { log.info('Rendering diagram: ' + element.id); /*! Check if previously processed */ @@ -140,21 +163,159 @@ const initThrowsErrors = function ( txt, (svgCode: string, bindFunctions?: (el: Element) => void) => { element.innerHTML = svgCode; - if (typeof callback !== 'undefined') { + if (callback !== undefined) { callback(id); } - if (bindFunctions) bindFunctions(element); + if (bindFunctions) { + bindFunctions(element); + } }, element ); } catch (error) { - log.warn('Catching Error (bootstrap)', error); - // @ts-ignore: TODO Fix ts errors - const mermaidError = { error, str: error.str, hash: error.hash, message: error.str }; - if (typeof mermaid.parseError === 'function') { - mermaid.parseError(mermaidError); - } - errors.push(mermaidError); + handleError(error, errors, mermaid.parseError); + } + } + if (errors.length > 0) { + // TODO: We should be throwing an error object. + throw errors[0]; + } +}; + +/** + * This is an internal function and should not be made public, as it will likely change. + * @internal + * @param diagrams - Array of {@link ExternalDiagramDefinition}. + */ +const registerLazyLoadedDiagrams = (diagrams: ExternalDiagramDefinition[]) => { + for (const { id, detector, loader } of diagrams) { + addDetector(id, detector, loader); + } +}; + +/** + * This is an internal function and should not be made public, as it will likely change. + * @internal + * @param diagrams - Array of {@link ExternalDiagramDefinition}. + */ +const loadExternalDiagrams = async (diagrams: ExternalDiagramDefinition[]) => { + log.debug(`Loading ${diagrams.length} external diagrams`); + // Load all lazy loaded diagrams in parallel + const results = await Promise.allSettled( + diagrams.map(async ({ id, detector, loader }) => { + const { diagram } = await loader(); + registerDiagram(id, diagram, detector); + }) + ); + const failed = results.filter((result) => result.status === 'rejected'); + if (failed.length > 0) { + log.error(`Failed to load ${failed.length} external diagrams`); + for (const res of failed) { + log.error(res); + } + throw new Error(`Failed to load ${failed.length} external diagrams`); + } +}; + +/** + * Equivalent to {@link init}, except an error will be thrown on error. + * + * @alpha + * @deprecated This is an internal function and will very likely be modified in v10, or earlier. + * We recommend staying with {@link initThrowsErrors} if you don't need `lazyLoadedDiagrams`. + * + * @param config - **Deprecated** Mermaid sequenceConfig. + * @param nodes - One of: + * - A DOM Node + * - An array of DOM nodes (as would come from a jQuery selector) + * - A W3C selector, a la `.mermaid` (default) + * @param callback - Function that is called with the id of each generated mermaid diagram. + * @returns Resolves on success, otherwise the {@link Promise} will be rejected. + */ +const initThrowsErrorsAsync = async function ( + config?: MermaidConfig, + // eslint-disable-next-line no-undef + nodes?: string | HTMLElement | NodeListOf, + // eslint-disable-next-line @typescript-eslint/ban-types + callback?: Function +) { + const conf = mermaidAPI.getConfig(); + + if (config) { + // This is a legacy way of setting config. It is not documented and should be removed in the future. + // @ts-ignore: TODO Fix ts errors + mermaid.sequenceConfig = config; + } + + // if last argument is a function this is the callback function + log.debug(`${!callback ? 'No ' : ''}Callback function found`); + let nodesToProcess: ArrayLike; + if (nodes === undefined) { + nodesToProcess = document.querySelectorAll('.mermaid'); + } else if (typeof nodes === 'string') { + nodesToProcess = document.querySelectorAll(nodes); + } else if (nodes instanceof HTMLElement) { + nodesToProcess = [nodes]; + } else if (nodes instanceof NodeList) { + nodesToProcess = nodes; + } else { + throw new Error('Invalid argument nodes for mermaid.init'); + } + + log.debug(`Found ${nodesToProcess.length} diagrams`); + if (config?.startOnLoad !== undefined) { + log.debug('Start On Load: ' + config?.startOnLoad); + mermaidAPI.updateSiteConfig({ startOnLoad: config?.startOnLoad }); + } + + // generate the id of the diagram + const idGenerator = new utils.initIdGenerator(conf.deterministicIds, conf.deterministicIDSeed); + + let txt: string; + const errors: DetailedError[] = []; + + // element is the current div with mermaid class + // eslint-disable-next-line unicorn/prefer-spread + for (const element of Array.from(nodesToProcess)) { + log.info('Rendering diagram: ' + element.id); + /*! Check if previously processed */ + if (element.getAttribute('data-processed')) { + continue; + } + element.setAttribute('data-processed', 'true'); + + const id = `mermaid-${idGenerator.next()}`; + + // Fetch the graph definition including tags + txt = element.innerHTML; + + // transforms the html to pure text + txt = utils + .entityDecode(txt) + .trim() + .replace(//gi, '
'); + + const init = utils.detectInit(txt); + if (init) { + log.debug('Detected early reinit: ', init); + } + try { + await mermaidAPI.renderAsync( + id, + txt, + (svgCode: string, bindFunctions?: (el: Element) => void) => { + element.innerHTML = svgCode; + if (callback !== undefined) { + callback(id); + } + if (bindFunctions) { + bindFunctions(element); + } + }, + element + ); + } catch (error) { + handleError(error, errors, mermaid.parseError); } } if (errors.length > 0) { @@ -167,6 +328,27 @@ const initialize = function (config: MermaidConfig) { mermaidAPI.initialize(config); }; +/** + * Used to register external diagram types. + * @param diagrams - Array of {@link ExternalDiagramDefinition}. + * @param opts - If opts.lazyLoad is true, the diagram will be loaded on demand. + */ +const registerExternalDiagrams = async ( + diagrams: ExternalDiagramDefinition[], + { + lazyLoad = true, + }: { + lazyLoad?: boolean; + } = {} +) => { + if (lazyLoad) { + registerLazyLoadedDiagrams(diagrams); + } else { + await loadExternalDiagrams(diagrams); + } + externalDiagramsRegistered = true; +}; + /** * ##contentLoaded Callback function that is called when page is loaded. This functions fetches * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the @@ -200,7 +382,7 @@ if (typeof document !== 'undefined') { * This is provided for environments where the mermaid object can't directly have a new member added * to it (eg. dart interop wrapper). (Initially there is no parseError member of mermaid). * - * @param {function (err, hash)} newParseErrorHandler New parseError() callback. + * @param newParseErrorHandler - New parseError() callback. */ const setParseErrorHandler = function (newParseErrorHandler: (err: any, hash: any) => void) { mermaid.parseError = newParseErrorHandler; @@ -210,52 +392,120 @@ const parse = (txt: string) => { return mermaidAPI.parse(txt, mermaid.parseError); }; -const connectDiagram = ( +const executionQueue: (() => Promise)[] = []; +let executionQueueRunning = false; +const executeQueue = async () => { + if (executionQueueRunning) { + return; + } + executionQueueRunning = true; + while (executionQueue.length > 0) { + const f = executionQueue.shift(); + if (f) { + try { + await f(); + } catch (e) { + log.error('Error executing queue', e); + } + } + } + executionQueueRunning = false; +}; + +/** + * @param txt - The mermaid code to be parsed. + * @deprecated This is an internal function and should not be used. Will be removed in v10. + */ +const parseAsync = (txt: string): Promise => { + return new Promise((resolve, reject) => { + // This promise will resolve when the mermaidAPI.render call is done. + // It will be queued first and will be executed when it is first in line + const performCall = () => + new Promise((res, rej) => { + mermaidAPI.parseAsync(txt, mermaid.parseError).then( + (r) => { + // This resolves for the promise for the queue handling + res(r); + // This fulfills the promise sent to the value back to the original caller + resolve(r); + }, + (e) => { + log.error('Error parsing', e); + rej(e); + reject(e); + } + ); + }); + executionQueue.push(performCall); + executeQueue(); + }); +}; + +/** + * @deprecated This is an internal function and should not be used. Will be removed in v10. + */ +const renderAsync = ( id: string, - diagram: DiagramDefinition, - callback: ( - _log: any, - _setLogLevel: any, - _getConfig: any, - _sanitizeText: any, - _setupGraphViewbox: any - ) => void -) => { - registerDiagram(id, diagram, callback); - // Todo move this connect call to after the diagram is actually loaded - callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox); + text: string, + cb?: (svgCode: string, bindFunctions?: (element: Element) => void) => void, + container?: Element +): Promise => { + return new Promise((resolve, reject) => { + // This promise will resolve when the mermaidAPI.render call is done. + // It will be queued first and will be executed when it is first in line + const performCall = () => + new Promise((res, rej) => { + mermaidAPI.renderAsync(id, text, cb, container).then( + (r) => { + // This resolves for the promise for the queue handling + res(r); + // This fulfills the promise sent to the value back to the original caller + resolve(r); + }, + (e) => { + log.error('Error parsing', e); + rej(e); + reject(e); + } + ); + }); + executionQueue.push(performCall); + executeQueue(); + }); }; const mermaid: { startOnLoad: boolean; diagrams: any; - // eslint-disable-next-line @typescript-eslint/ban-types - parseError?: Function; + parseError?: ParseErrorFunction; mermaidAPI: typeof mermaidAPI; parse: typeof parse; + parseAsync: typeof parseAsync; render: typeof mermaidAPI.render; + renderAsync: typeof renderAsync; init: typeof init; initThrowsErrors: typeof initThrowsErrors; + initThrowsErrorsAsync: typeof initThrowsErrorsAsync; + registerExternalDiagrams: typeof registerExternalDiagrams; initialize: typeof initialize; contentLoaded: typeof contentLoaded; setParseErrorHandler: typeof setParseErrorHandler; - // Array of functions to use for detecting diagram types - detectors: Array; // eslint-disable-line @typescript-eslint/no-explicit-any - connectDiagram: (id: string, diagram: DiagramDefinition, callback: (id: string) => void) => void; } = { startOnLoad: true, diagrams: {}, mermaidAPI, parse, + parseAsync, render: mermaidAPI.render, + renderAsync, init, initThrowsErrors, + initThrowsErrorsAsync, + registerExternalDiagrams, initialize, parseError: undefined, contentLoaded, setParseErrorHandler, - detectors: [], - connectDiagram: connectDiagram, }; export default mermaid; diff --git a/packages/mermaid/src/mermaidAPI.spec.js b/packages/mermaid/src/mermaidAPI.spec.js deleted file mode 100644 index 241b5ec86..000000000 --- a/packages/mermaid/src/mermaidAPI.spec.js +++ /dev/null @@ -1,150 +0,0 @@ -'use strict'; -import mermaid from './mermaid'; -import mermaidAPI from './mermaidAPI'; -import assignWithDepth from './assignWithDepth'; - -describe('when using mermaidAPI and ', function () { - describe('doing initialize ', function () { - beforeEach(function () { - document.body.innerHTML = ''; - mermaidAPI.globalReset(); - }); - - it('should copy a literal into the configuration', function () { - const orgConfig = mermaidAPI.getConfig(); - expect(orgConfig.testLiteral).toBe(undefined); - - mermaidAPI.initialize({ testLiteral: true }); - const config = mermaidAPI.getConfig(); - - expect(config.testLiteral).toBe(true); - }); - it('should copy a an object into the configuration', function () { - const orgConfig = mermaidAPI.getConfig(); - expect(orgConfig.testObject).toBe(undefined); - - const object = { - test1: 1, - test2: false, - }; - - mermaidAPI.initialize({ testObject: object }); - let config = mermaidAPI.getConfig(); - - expect(config.testObject.test1).toBe(1); - mermaidAPI.updateSiteConfig({ testObject: { test3: true } }); - config = mermaidAPI.getConfig(); - - expect(config.testObject.test1).toBe(1); - expect(config.testObject.test2).toBe(false); - expect(config.testObject.test3).toBe(true); - }); - it('should reset mermaid config to global defaults', function () { - let config = { - logLevel: 0, - securityLevel: 'loose', - }; - mermaidAPI.initialize(config); - mermaidAPI.setConfig({ securityLevel: 'strict', logLevel: 1 }); - expect(mermaidAPI.getConfig().logLevel).toBe(1); - expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); - mermaidAPI.reset(); - expect(mermaidAPI.getConfig().logLevel).toBe(0); - expect(mermaidAPI.getConfig().securityLevel).toBe('loose'); - mermaidAPI.globalReset(); - expect(mermaidAPI.getConfig().logLevel).toBe(5); - expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); - }); - - it('should prevent changes to site defaults (sneaky)', function () { - let config = { - logLevel: 0, - }; - mermaidAPI.initialize(config); - const siteConfig = mermaidAPI.getSiteConfig(); - expect(mermaidAPI.getConfig().logLevel).toBe(0); - config.secure = { - toString: function () { - mermaidAPI.initialize({ securityLevel: 'loose' }); - }, - }; - // mermaidAPI.reinitialize(config); - expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure); - expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); - mermaidAPI.reset(); - expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig); - expect(mermaidAPI.getConfig()).toEqual(siteConfig); - }); - it('should prevent clobbering global defaults (direct)', function () { - let config = assignWithDepth({}, mermaidAPI.defaultConfig); - assignWithDepth(config, { logLevel: 0 }); - - let error = { message: '' }; - try { - mermaidAPI['defaultConfig'] = config; - } catch (e) { - error = e; - } - expect(error.message).toBe( - "Cannot assign to read only property 'defaultConfig' of object '#'" - ); - expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); - }); - it('should prevent changes to global defaults (direct)', function () { - let error = { message: '' }; - try { - mermaidAPI.defaultConfig['logLevel'] = 0; - } catch (e) { - error = e; - } - expect(error.message).toBe( - "Cannot assign to read only property 'logLevel' of object '#'" - ); - expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); - }); - it('should prevent sneaky changes to global defaults (assignWithDepth)', function () { - let config = { - logLevel: 0, - }; - let error = { message: '' }; - try { - assignWithDepth(mermaidAPI.defaultConfig, config); - } catch (e) { - error = e; - } - expect(error.message).toBe( - "Cannot assign to read only property 'logLevel' of object '#'" - ); - expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); - }); - }); - describe('dompurify config', function () { - it('should allow dompurify config to be set', function () { - mermaidAPI.initialize({ dompurifyConfig: { ADD_ATTR: ['onclick'] } }); - expect(mermaidAPI.getConfig().dompurifyConfig.ADD_ATTR).toEqual(['onclick']); - }); - }); - describe('test mermaidApi.parse() for checking validity of input ', function () { - mermaid.parseError = undefined; // ensure it parseError undefined - it('should throw for an invalid definition (with no mermaid.parseError() defined)', function () { - expect(mermaid.parseError).toEqual(undefined); - expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow(); - }); - it('should not throw for a valid definition', function () { - expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow(); - }); - it('it should return false for invalid definition WITH a parseError() callback defined', function () { - let parseErrorWasCalled = false; - // also test setParseErrorHandler() call working to set mermaid.parseError - expect( - mermaidAPI.parse('this is not a mermaid diagram definition', () => { - parseErrorWasCalled = true; - }) - ).toEqual(false); - expect(parseErrorWasCalled).toEqual(true); - }); - it('should return true for valid definition', function () { - expect(mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).toEqual(true); - }); - }); -}); diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts new file mode 100644 index 000000000..55d46ae7c --- /dev/null +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -0,0 +1,649 @@ +'use strict'; +import { vi } from 'vitest'; + +import mermaid from './mermaid'; +import { MermaidConfig } from './config.type'; + +import mermaidAPI, { removeExistingElements } from './mermaidAPI'; +import { + encodeEntities, + decodeEntities, + createCssStyles, + createUserStyles, + appendDivSvgG, + cleanUpSvgCode, + putIntoIFrame, +} from './mermaidAPI'; + +import assignWithDepth from './assignWithDepth'; + +// -------------- +// Mocks +// To mock a module, first define a mock for it, then (if used explicitly in the tests) import it. Be sure the path points to exactly the same file as is imported in mermaidAPI (the module being tested) +vi.mock('./styles', () => { + return { + addStylesForDiagram: vi.fn(), + default: vi.fn().mockReturnValue(' .userStyle { font-weight:bold; }'), + }; +}); +import getStyles from './styles'; + +vi.mock('stylis', () => { + return { + stringify: vi.fn(), + compile: vi.fn(), + serialize: vi.fn().mockReturnValue('stylis serialized css'), + }; +}); +import { compile, serialize } from 'stylis'; + +import { MockedD3 } from './tests/MockedD3'; + +// ------------------------------------------------------------------------------------- + +describe('mermaidAPI', function () { + describe('encodeEntities', () => { + it('removes the ending ; from style [text1]:[optional word]#[text2]; with ', () => { + const text = 'style this; is ; everything :something#not-nothing; and this too;'; + expect(encodeEntities(text)).toEqual( + 'style this; is ; everything :something#not-nothing; and this too' + ); + }); + it('removes the ending ; from classDef [text1]:[optional word]#[text2]; with ', () => { + const text = 'classDef this; is ; everything :something#not-nothing; and this too;'; + expect(encodeEntities(text)).toEqual( + 'classDef this; is ; everything :something#not-nothing; and this too' + ); + }); + + describe('replaces words starting with # and ending with ;', () => { + const testStr = 'Hello #there;'; + + it('removes the #', () => { + const result = encodeEntities(testStr); + expect(result.substring(0, 7)).toEqual('Hello fl'); + }); + + it('prefix is fl°° if is all digits', () => { + const result = encodeEntities('Hello #77653;'); + expect(result.substring(6, result.length)).toEqual('fl°°77653¶ß'); + }); + + it('prefix is fl° if is not all digits', () => { + const result = encodeEntities(testStr); + expect(result.substring(6, result.length)).toEqual('fl°there¶ß'); + }); + it('always removes the semi-colon and ends with ¶ß', () => { + const result = encodeEntities(testStr); + expect(result.substring(result.length - 2, result.length)).toEqual('¶ß'); + }); + }); + + it('does all the replacements on the given text', () => { + const text = + 'style this; is ; everything :something#not-nothing; and this too; \n' + + 'classDef this; is ; everything :something#not-nothing; and this too; \n' + + 'Hello #there; #andHere;#77653;'; + + const result = encodeEntities(text); + expect(result).toEqual( + 'style this; is ; everything :something#not-nothing; and this too \n' + + 'classDef this; is ; everything :something#not-nothing; and this too \n' + + 'Hello fl°there¶ß fl°andHere¶ßfl°°77653¶ß' + ); + }); + }); + + describe('decodeEntities', () => { + it('replaces fl°° with &#', () => { + expect(decodeEntities('fl°°hfl°°ifl°°')).toEqual('&#h&#i&#'); + }); + it('replaces fl° with &', () => { + expect(decodeEntities('fl°hfl°ifl°')).toEqual('&h&i&'); + }); + it('replaces ¶ß with ;', () => { + expect(decodeEntities('¶ßh¶ßi¶ß')).toEqual(';h;i;'); + }); + it('runs all the replacements on the given text', () => { + expect(decodeEntities('¶ßfl°¶ßfl°°¶ß')).toEqual(';&;&#;'); + }); + }); + + describe('cleanUpSvgCode', () => { + it('replaces marker end URLs with just the anchor if not sandboxed and not useMarkerUrls', () => { + const markerFullUrl = 'marker-end="url(some-URI#that)"'; + let useArrowMarkerUrls = false; + let isSandboxed = false; + let result = cleanUpSvgCode(markerFullUrl, isSandboxed, useArrowMarkerUrls); + expect(result).toEqual('marker-end="url(#that)"'); + + useArrowMarkerUrls = true; + result = cleanUpSvgCode(markerFullUrl, isSandboxed, useArrowMarkerUrls); + expect(result).toEqual(markerFullUrl); // not changed + + useArrowMarkerUrls = false; + isSandboxed = true; + result = cleanUpSvgCode(markerFullUrl, isSandboxed, useArrowMarkerUrls); + expect(result).toEqual(markerFullUrl); // not changed + }); + + it('decodesEntities', () => { + const result = cleanUpSvgCode('¶ß brrrr', true, true); + expect(result).toEqual('; brrrr'); + }); + + it('replaces old style br tags with new style', () => { + const result = cleanUpSvgCode('
brrrr
', true, true); + expect(result).toEqual('
brrrr
'); + }); + }); + + describe('putIntoIFrame', () => { + const inputSvgCode = 'this is the SVG code'; + + it('uses the default SVG iFrame height is used if no svgElement given', () => { + const result = putIntoIFrame(inputSvgCode); + expect(result).toMatch(/style="(.*)height:100%(.*);"/); + }); + it('default style attributes are: width: 100%, height: 100%, border: 0, margin: 0', () => { + const result = putIntoIFrame(inputSvgCode); + expect(result).toMatch(/style="(.*)width:100%(.*);"/); + expect(result).toMatch(/style="(.*)height:100%(.*);"/); + expect(result).toMatch(/style="(.*)border:0(.*);"/); + expect(result).toMatch(/style="(.*)margin:0(.*);"/); + }); + it('sandbox="allow-top-navigation-by-user-activation allow-popups">', () => { + const result = putIntoIFrame(inputSvgCode); + expect(result).toMatch(/sandbox="allow-top-navigation-by-user-activation allow-popups">/); + }); + it('msg shown is "The "iframe" tag is not supported by your browser.\\n" if iFrames are not supported in the browser', () => { + const result = putIntoIFrame(inputSvgCode); + expect(result).toMatch(/\s*The "iframe" tag is not supported by your browser\./); + }); + + it('sets src to base64 version of svgCode', () => { + const base64encodedSrc = btoa('' + inputSvgCode + ''); + const expectedRegExp = new RegExp('src="data:text/html;base64,' + base64encodedSrc + '"'); + + const result = putIntoIFrame(inputSvgCode); + expect(result).toMatch(expectedRegExp); + }); + + it('uses the height and appends px from the svgElement given', () => { + const faux_svgElement = { + viewBox: { + baseVal: { + height: 42, + }, + }, + }; + + const result = putIntoIFrame(inputSvgCode, faux_svgElement); + expect(result).toMatch(/style="(.*)height:42px;/); + }); + }); + + const fauxParentNode = new MockedD3(); + const fauxEnclosingDiv = new MockedD3(); + const fauxSvgNode = new MockedD3(); + + describe('appendDivSvgG', () => { + const fauxGNode = new MockedD3(); + const parent_append_spy = vi.spyOn(fauxParentNode, 'append').mockReturnValue(fauxEnclosingDiv); + const div_append_spy = vi.spyOn(fauxEnclosingDiv, 'append').mockReturnValue(fauxSvgNode); + // @ts-ignore @todo TODO why is this getting a type error? + const div_attr_spy = vi.spyOn(fauxEnclosingDiv, 'attr').mockReturnValue(fauxEnclosingDiv); + const svg_append_spy = vi.spyOn(fauxSvgNode, 'append').mockReturnValue(fauxGNode); + // @ts-ignore @todo TODO why is this getting a type error? + const svg_attr_spy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); + + it('appends a div node', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(parent_append_spy).toHaveBeenCalledWith('div'); + expect(div_append_spy).toHaveBeenCalledWith('svg'); + }); + it('the id for the div is "d" with the id appended', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(div_attr_spy).toHaveBeenCalledWith('id', 'dtheId'); + }); + + it('sets the style for the div if one is given', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId', 'given div style', 'given x link'); + expect(div_attr_spy).toHaveBeenCalledWith('style', 'given div style'); + }); + + it('appends a svg node to the div node', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(div_attr_spy).toHaveBeenCalledWith('id', 'dtheId'); + }); + it('sets the svg width to 100%', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(svg_attr_spy).toHaveBeenCalledWith('width', '100%'); + }); + it('the svg id is the id', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(svg_attr_spy).toHaveBeenCalledWith('id', 'theId'); + }); + it('the svg xml namespace is the 2000 standard', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(svg_attr_spy).toHaveBeenCalledWith('xmlns', 'http://www.w3.org/2000/svg'); + }); + it('sets the svg xlink if one is given', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId', 'div style', 'given x link'); + expect(svg_attr_spy).toHaveBeenCalledWith('xmlns:xlink', 'given x link'); + }); + it('appends a g (group) node to the svg node', () => { + appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); + expect(svg_append_spy).toHaveBeenCalledWith('g'); + }); + it('returns the given parentRoot d3 nodes', () => { + expect(appendDivSvgG(fauxParentNode, 'theId', 'dtheId')).toEqual(fauxParentNode); + }); + }); + + describe('createCssStyles', () => { + const serif = 'serif'; + const sansSerif = 'sans-serif'; + const mocked_config_with_htmlLabels: MermaidConfig = { + themeCSS: 'default', + fontFamily: serif, + altFontFamily: sansSerif, + htmlLabels: true, + }; + + it('gets the cssStyles from the theme', () => { + const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', null); + expect(styles).toMatch(/^\ndefault(.*)/); + }); + it('gets the fontFamily from the config', () => { + const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', {}); + expect(styles).toMatch(/(.*)\n:root { --mermaid-font-family: serif(.*)/); + }); + it('gets the alt fontFamily from the config', () => { + const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', undefined); + expect(styles).toMatch(/(.*)\n:root { --mermaid-alt-font-family: sans-serif(.*)/); + }); + + describe('there are some classDefs', () => { + const classDef1 = { id: 'classDef1', styles: ['style1-1', 'style1-2'], textStyles: [] }; + const classDef2 = { id: 'classDef2', styles: [], textStyles: ['textStyle2-1'] }; + const classDef3 = { id: 'classDef3', textStyles: ['textStyle3-1', 'textStyle3-2'] }; + const classDefs = { classDef1, classDef2, classDef3 }; + + describe('the graph supports classDefs', () => { + const graphType = 'flowchart-v2'; + + const REGEXP_SPECIALS = ['^', '$', '?', '(', '{', '[', '.', '*', '!']; + + // prefix any special RegExp characters in the given string with a \ so we can use the literal character in a RegExp + function escapeForRegexp(str: string) { + const strChars = [...str]; // split into array of every char + const strEscaped = strChars.map((char) => { + if (REGEXP_SPECIALS.includes(char)) { + return `\\${char}`; + } else { + return char; + } + }); + return strEscaped.join(''); + } + + // Common test expecting given styles to have .classDef1 and .classDef2 statements but not .classDef3 + function expect_styles_matchesHtmlElements(styles: string, htmlElement: string) { + expect(styles).toMatch( + new RegExp( + `\\.classDef1 ${escapeForRegexp( + htmlElement + )} \\{ style1-1 !important; style1-2 !important; }` + ) + ); + // no CSS styles are created if there are no styles for a classDef + expect(styles).not.toMatch( + new RegExp(`\\.classDef2 ${escapeForRegexp(htmlElement)} \\{ style(.*) !important; }`) + ); + expect(styles).not.toMatch( + new RegExp(`\\.classDef3 ${escapeForRegexp(htmlElement)} \\{ style(.*) !important; }`) + ); + } + + // Common test expecting given textStyles to have .classDef2 and .classDef3 statements but not .classDef1 + function expect_textStyles_matchesHtmlElements(textStyles: string, htmlElement: string) { + expect(textStyles).toMatch( + new RegExp( + `\\.classDef2 ${escapeForRegexp(htmlElement)} \\{ textStyle2-1 !important; }` + ) + ); + expect(textStyles).toMatch( + new RegExp( + `\\.classDef3 ${escapeForRegexp( + htmlElement + )} \\{ textStyle3-1 !important; textStyle3-2 !important; }` + ) + ); + + // no CSS styles are created if there are no textStyles for a classDef + expect(textStyles).not.toMatch( + new RegExp( + `\\.classDef1 ${escapeForRegexp(htmlElement)} \\{ textStyle(.*) !important; }` + ) + ); + } + + // common suite and tests to verify that the right styles are created with the right htmlElements + function expect_correct_styles_with_htmlElements(mocked_config: MermaidConfig) { + describe('creates styles for "> *" and "span" elements', () => { + const htmlElements = ['> *', 'span']; + + it('creates CSS styles for every style and textStyle in every classDef', () => { + // @todo TODO Can't figure out how to spy on the cssImportantStyles method. That would be a much better approach than manually checking the result + + const styles = createCssStyles(mocked_config, graphType, classDefs); + htmlElements.forEach((htmlElement) => { + expect_styles_matchesHtmlElements(styles, htmlElement); + }); + expect_textStyles_matchesHtmlElements(styles, 'tspan'); + }); + }); + } + + it('there are htmlLabels in the configuration', () => { + expect_correct_styles_with_htmlElements(mocked_config_with_htmlLabels); + }); + + it('there are flowchart.htmlLabels in the configuration', () => { + const mocked_config_flowchart_htmlLabels: MermaidConfig = { + themeCSS: 'default', + fontFamily: 'serif', + altFontFamily: 'sans-serif', + flowchart: { + htmlLabels: true, + }, + }; + expect_correct_styles_with_htmlElements(mocked_config_flowchart_htmlLabels); + }); + + describe('no htmlLabels in the configuration', () => { + const mocked_config_no_htmlLabels = { + themeCSS: 'default', + fontFamily: 'serif', + altFontFamily: 'sans-serif', + }; + + describe('creates styles for shape elements "rect", "polygon", "ellipse", and "circle"', () => { + const htmlElements = ['rect', 'polygon', 'ellipse', 'circle']; + + it('creates CSS styles for every style and textStyle in every classDef', () => { + // @todo TODO Can't figure out how to spy on the cssImportantStyles method. That would be a much better approach than manually checking the result + + const styles = createCssStyles(mocked_config_no_htmlLabels, graphType, classDefs); + htmlElements.forEach((htmlElement) => { + expect_styles_matchesHtmlElements(styles, htmlElement); + }); + expect_textStyles_matchesHtmlElements(styles, 'tspan'); + }); + }); + }); + }); + }); + }); + + describe('createUserStyles', () => { + const mockConfig = { + themeCSS: 'default', + htmlLabels: true, + themeVariables: { fontFamily: 'serif' }, + }; + + const classDef1 = { id: 'classDef1', styles: ['style1-1'], textStyles: [] }; + + it('gets the css styles created', () => { + // @todo TODO if a single function in the module can be mocked, do it for createCssStyles and mock the results. + + createUserStyles(mockConfig, 'flowchart-v2', { classDef1 }, 'someId'); + const expectedStyles = + '\ndefault' + + '\n.classDef1 > * { style1-1 !important; }' + + '\n.classDef1 span { style1-1 !important; }'; + expect(getStyles).toHaveBeenCalledWith('flowchart-v2', expectedStyles, { + fontFamily: 'serif', + }); + }); + + it('calls getStyles to get css for all graph, user css styles, and config theme variables', () => { + createUserStyles(mockConfig, 'someDiagram', {}, 'someId'); + expect(getStyles).toHaveBeenCalled(); + }); + + it('returns the result of compiling, stringifying, and serializing the css code with stylis', () => { + const result = createUserStyles(mockConfig, 'someDiagram', {}, 'someId'); + expect(compile).toHaveBeenCalled(); + expect(serialize).toHaveBeenCalled(); + expect(result).toEqual('stylis serialized css'); + }); + }); + + describe('removeExistingElements', () => { + const svgId = 'svgId'; + const tempDivId = 'tempDivId'; + const tempIframeId = 'tempIFrameId'; + const givenDocument = new Document(); + const rootHtml = givenDocument.createElement('html'); + givenDocument.append(rootHtml); + + const svgElement = givenDocument.createElement('svg'); // doesn't matter what the tag is in the test + svgElement.id = svgId; + const tempDivElement = givenDocument.createElement('div'); // doesn't matter what the tag is in the test + tempDivElement.id = tempDivId; + const tempiFrameElement = givenDocument.createElement('div'); // doesn't matter what the tag is in the test + tempiFrameElement.id = tempIframeId; + + it('removes an existing element with given id', () => { + rootHtml.appendChild(svgElement); + expect(givenDocument.getElementById(svgElement.id)).toEqual(svgElement); + removeExistingElements(givenDocument, false, svgId, tempDivId, tempIframeId); + expect(givenDocument.getElementById(svgElement.id)).toBeNull(); + }); + + describe('is in sandboxed mode', () => { + const inSandboxedMode = true; + + it('removes an existing element with the given iFrame selector', () => { + tempiFrameElement.append(svgElement); + rootHtml.append(tempiFrameElement); + rootHtml.append(tempDivElement); + + expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); + expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); + expect(givenDocument.getElementById(svgId)).toEqual(svgElement); + removeExistingElements( + givenDocument, + inSandboxedMode, + svgId, + '#' + tempDivId, + '#' + tempIframeId + ); + expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); + expect(givenDocument.getElementById(tempIframeId)).toBeNull(); + expect(givenDocument.getElementById(svgId)).toBeNull(); + }); + }); + describe('not in sandboxed mode', () => { + const inSandboxedMode = false; + + it('removes an existing element with the given enclosing div selector', () => { + tempDivElement.append(svgElement); + rootHtml.append(tempDivElement); + rootHtml.append(tempiFrameElement); + + expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); + expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); + expect(givenDocument.getElementById(svgId)).toEqual(svgElement); + removeExistingElements( + givenDocument, + inSandboxedMode, + svgId, + '#' + tempDivId, + '#' + tempIframeId + ); + expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); + expect(givenDocument.getElementById(tempDivId)).toBeNull(); + expect(givenDocument.getElementById(svgId)).toBeNull(); + }); + }); + }); + + describe('initialize', function () { + beforeEach(function () { + document.body.innerHTML = ''; + mermaidAPI.globalReset(); + }); + + it('copies a literal into the configuration', function () { + const orgConfig: any = mermaidAPI.getConfig(); + expect(orgConfig.testLiteral).toBe(undefined); + + const testConfig: any = { testLiteral: true }; + + mermaidAPI.initialize(testConfig); + const config: any = mermaidAPI.getConfig(); + + expect(config.testLiteral).toBe(true); + }); + + it('copies a an object into the configuration', function () { + const orgConfig: any = mermaidAPI.getConfig(); + expect(orgConfig.testObject).toBe(undefined); + + const object = { + test1: 1, + test2: false, + }; + + const testConfig: any = { testObject: object }; + + mermaidAPI.initialize(testConfig); + + let config: any = mermaidAPI.getConfig(); + + expect(config.testObject.test1).toBe(1); + + const testObjSetting: any = { testObject: { test3: true } }; + mermaidAPI.updateSiteConfig(testObjSetting); + config = mermaidAPI.getConfig(); + + expect(config.testObject.test1).toBe(1); + expect(config.testObject.test2).toBe(false); + expect(config.testObject.test3).toBe(true); + }); + + it('resets mermaid config to global defaults', function () { + const config = { + logLevel: 0, + securityLevel: 'loose', + }; + mermaidAPI.initialize(config); + mermaidAPI.setConfig({ securityLevel: 'strict', logLevel: 1 }); + expect(mermaidAPI.getConfig().logLevel).toBe(1); + expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); + mermaidAPI.reset(); + expect(mermaidAPI.getConfig().logLevel).toBe(0); + expect(mermaidAPI.getConfig().securityLevel).toBe('loose'); + mermaidAPI.globalReset(); + expect(mermaidAPI.getConfig().logLevel).toBe(5); + expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); + }); + + it('prevents changes to site defaults (sneaky)', function () { + const config: any = { + logLevel: 0, + }; + mermaidAPI.initialize(config); + const siteConfig = mermaidAPI.getSiteConfig(); + expect(mermaidAPI.getConfig().logLevel).toBe(0); + config.secure = { + toString: function () { + mermaidAPI.initialize({ securityLevel: 'loose' }); + }, + }; + // mermaidAPI.reinitialize(config); + expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure); + expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); + mermaidAPI.reset(); + expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig); + expect(mermaidAPI.getConfig()).toEqual(siteConfig); + }); + it('prevents clobbering global defaults (direct)', function () { + const config = assignWithDepth({}, mermaidAPI.defaultConfig); + assignWithDepth(config, { logLevel: 0 }); + + let error: any = { message: '' }; + try { + // @ts-ignore This is a read-only property. Typescript will not allow assignment, but regular javascript might. + mermaidAPI['defaultConfig'] = config; + } catch (e) { + error = e; + } + expect(error.message).toBe( + "Cannot assign to read only property 'defaultConfig' of object '#'" + ); + expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); + }); + it('prevents changes to global defaults (direct)', function () { + let error: any = { message: '' }; + try { + mermaidAPI.defaultConfig['logLevel'] = 0; + } catch (e) { + error = e; + } + expect(error.message).toBe( + "Cannot assign to read only property 'logLevel' of object '#'" + ); + expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); + }); + it('prevents sneaky changes to global defaults (assignWithDepth)', function () { + const config = { + logLevel: 0, + }; + let error: any = { message: '' }; + try { + assignWithDepth(mermaidAPI.defaultConfig, config); + } catch (e) { + error = e; + } + expect(error.message).toBe( + "Cannot assign to read only property 'logLevel' of object '#'" + ); + expect(mermaidAPI.defaultConfig['logLevel']).toBe(5); + }); + }); + describe('dompurify config', function () { + it('allows dompurify config to be set', function () { + mermaidAPI.initialize({ dompurifyConfig: { ADD_ATTR: ['onclick'] } }); + + expect(mermaidAPI!.getConfig()!.dompurifyConfig!.ADD_ATTR).toEqual(['onclick']); + }); + }); + describe('parse', function () { + mermaid.parseError = undefined; // ensure it parseError undefined + it('throws for an invalid definition (with no mermaid.parseError() defined)', function () { + expect(mermaid.parseError).toEqual(undefined); + expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow(); + }); + it('does not throw for a valid definition', function () { + expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow(); + }); + it('returns false for invalid definition WITH a parseError() callback defined', function () { + let parseErrorWasCalled = false; + // also test setParseErrorHandler() call working to set mermaid.parseError + expect( + mermaidAPI.parse('this is not a mermaid diagram definition', () => { + parseErrorWasCalled = true; + }) + ).toEqual(false); + expect(parseErrorWasCalled).toEqual(true); + }); + it('returns true for valid definition', function () { + expect(mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).toEqual(true); + }); + }); +}); diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 30a68ce29..5687a1807 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -9,8 +9,6 @@ * page or do something completely different. * * In addition to the render function, a number of behavioral configuration options are available. - * - * @name mermaidAPI */ import { select } from 'd3'; import { compile, serialize, stringify } from 'stylis'; @@ -20,9 +18,8 @@ import * as configApi from './config'; import { addDiagrams } from './diagram-api/diagram-orchestration'; import classDb from './diagrams/class/classDb'; import flowDb from './diagrams/flowchart/flowDb'; -import flowRenderer from './diagrams/flowchart/flowRenderer'; import ganttDb from './diagrams/gantt/ganttDb'; -import Diagram, { getDiagramFromText } from './Diagram'; +import Diagram, { getDiagramFromText, type ParseErrorFunction } from './Diagram'; import errorRenderer from './diagrams/error/errorRenderer'; import { attachFunctions } from './interactionDb'; import { log, setLogLevel } from './logger'; @@ -32,33 +29,81 @@ import utils, { directiveSanitizer } from './utils'; import DOMPurify from 'dompurify'; import { MermaidConfig } from './config.type'; import { evaluate } from './diagrams/common/common'; +import isEmpty from 'lodash-es/isEmpty'; -let hasLoadedDiagrams = false; +// diagram names that support classDef statements +const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2']; + +const MAX_TEXTLENGTH_EXCEEDED_MSG = + 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa'; + +const SECURITY_LVL_SANDBOX = 'sandbox'; +const SECURITY_LVL_LOOSE = 'loose'; + +const XMLNS_SVG_STD = 'http://www.w3.org/2000/svg'; +const XMLNS_XLINK_STD = 'http://www.w3.org/1999/xlink'; +const XMLNS_XHTML_STD = 'http://www.w3.org/1999/xhtml'; + +// ------------------------------ +// iFrame +const IFRAME_WIDTH = '100%'; +const IFRAME_HEIGHT = '100%'; +const IFRAME_STYLES = 'border:0;margin:0;'; +const IFRAME_BODY_STYLE = 'margin:0'; +const IFRAME_SANDBOX_OPTS = 'allow-top-navigation-by-user-activation allow-popups'; +const IFRAME_NOT_SUPPORTED_MSG = 'The "iframe" tag is not supported by your browser.'; + +// DOMPurify settings for svgCode +const DOMPURE_TAGS = ['foreignobject']; +const DOMPURE_ATTR = ['dominant-baseline']; + +// This is what is returned from getClasses(...) methods. +// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word. +// It makes it clear we're working with a style class definition, even though defining the type is currently difficult. +interface DiagramStyleClassDef { + id: string; + styles?: string[]; + textStyles?: string[]; +} + +// This makes it clear that we're working with a d3 selected element of some kind, even though it's hard to specify the exact type. +// @ts-ignore Could replicate the type definition in d3. This also makes it possible to use the untyped info from the js diagram files. +type D3Element = any; + +// ---------------------------------------------------------------------------- /** - * @param text - * @param parseError + * @param text - The mermaid diagram definition. + * @param parseError - If set, handles errors. */ -// eslint-disable-next-line @typescript-eslint/ban-types -function parse(text: string, parseError?: Function): boolean { - if (!hasLoadedDiagrams) { - addDiagrams(); - hasLoadedDiagrams = true; - } +function parse(text: string, parseError?: ParseErrorFunction): boolean { + addDiagrams(); const diagram = new Diagram(text, parseError); return diagram.parse(text, parseError); } +/** + * @param text - The mermaid diagram definition. + * @param parseError - If set, handles errors. + */ +async function parseAsync(text: string, parseError?: ParseErrorFunction): Promise { + addDiagrams(); + const diagram = await getDiagramFromText(text, parseError); + return diagram.parse(text, parseError); +} + +/** + * @param text - text to be encoded + * @returns + */ export const encodeEntities = function (text: string): string { let txt = text; - txt = txt.replace(/style.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1); - return innerTxt; + txt = txt.replace(/style.*:\S*#.*;/g, function (s): string { + return s.substring(0, s.length - 1); }); - txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1); - return innerTxt; + txt = txt.replace(/classDef.*:\S*#.*;/g, function (s): string { + return s.substring(0, s.length - 1); }); txt = txt.replace(/#\w+;/g, function (s) { @@ -75,21 +120,238 @@ export const encodeEntities = function (text: string): string { return txt; }; +/** + * + * @param text - text to be decoded + * @returns + */ export const decodeEntities = function (text: string): string { let txt = text; - txt = txt.replace(/fl°°/g, function () { - return '&#'; - }); - txt = txt.replace(/fl°/g, function () { - return '&'; - }); - txt = txt.replace(/¶ß/g, function () { - return ';'; - }); + txt = txt.replace(/fl°°/g, '&#'); + txt = txt.replace(/fl°/g, '&'); + txt = txt.replace(/¶ß/g, ';'); return txt; }; + +// append !important; to each cssClass followed by a final !important, all enclosed in { } +// +/** + * Create a CSS style that starts with the given class name, then the element, + * with an enclosing block that has each of the cssClasses followed by !important; + * @param cssClass - CSS class name + * @param element - CSS element + * @param cssClasses - list of CSS styles to append after the element + * @returns - the constructed string + */ +export const cssImportantStyles = ( + cssClass: string, + element: string, + cssClasses: string[] = [] +): string => { + return `\n.${cssClass} ${element} { ${cssClasses.join(' !important; ')} !important; }`; +}; + +/** + * Create the user styles + * + * @param config - configuration that has style and theme settings to use + * @param graphType - used for checking if classDefs should be applied + * @param classDefs - the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) + * @returns the string with all the user styles + */ +export const createCssStyles = ( + config: MermaidConfig, + graphType: string, + classDefs: Record | null | undefined = {} +): string => { + let cssStyles = ''; + + // user provided theme CSS info + // If you add more configuration driven data into the user styles make sure that the value is + // sanitized by the sanitize CSS function TODO where is this method? what should be used to replace it? refactor so that it's always sanitized + if (config.themeCSS !== undefined) { + cssStyles += `\n${config.themeCSS}`; + } + + if (config.fontFamily !== undefined) { + cssStyles += `\n:root { --mermaid-font-family: ${config.fontFamily}}`; + } + if (config.altFontFamily !== undefined) { + cssStyles += `\n:root { --mermaid-alt-font-family: ${config.altFontFamily}}`; + } + + // classDefs defined in the diagram text + if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) { + const htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config? + + const cssHtmlElements = ['> *', 'span']; // TODO make a constant + const cssShapeElements = ['rect', 'polygon', 'ellipse', 'circle', 'path']; // TODO make a constant + + const cssElements = htmlLabels ? cssHtmlElements : cssShapeElements; + + // create the CSS styles needed for each styleClass definition and css element + for (const classId in classDefs) { + const styleClassDef = classDefs[classId]; + // create the css styles for each cssElement and the styles (only if there are styles) + if (!isEmpty(styleClassDef.styles)) { + cssElements.forEach((cssElement) => { + cssStyles += cssImportantStyles(styleClassDef.id, cssElement, styleClassDef.styles); + }); + } + // create the css styles for the tspan element and the text styles (only if there are textStyles) + if (!isEmpty(styleClassDef.textStyles)) { + cssStyles += cssImportantStyles(styleClassDef.id, 'tspan', styleClassDef.textStyles); + } + } + } + return cssStyles; +}; + +export const createUserStyles = ( + config: MermaidConfig, + graphType: string, + classDefs: Record, + svgId: string +): string => { + const userCSSstyles = createCssStyles(config, graphType, classDefs); + const allStyles = getStyles(graphType, userCSSstyles, config.themeVariables); + + // Now turn all of the styles into a (compiled) string that starts with the id + // use the stylis library to compile the css, turn the results into a valid CSS string (serialize(...., stringify)) + // @see https://github.com/thysultan/stylis + return serialize(compile(`${svgId}{${allStyles}}`), stringify); +}; + +/** + * Clean up svgCode. Do replacements needed + * + * @param svgCode - the code to clean up + * @param inSandboxMode - security level + * @param useArrowMarkerUrls - should arrow marker's use full urls? (vs. just the anchors) + * @returns the cleaned up svgCode + */ +export const cleanUpSvgCode = ( + svgCode = '', + inSandboxMode: boolean, + useArrowMarkerUrls: boolean +): string => { + let cleanedUpSvg = svgCode; + + // Replace marker-end urls with just the # anchor (remove the preceding part of the URL) + if (!useArrowMarkerUrls && !inSandboxMode) { + cleanedUpSvg = cleanedUpSvg.replace(/marker-end="url\(.*?#/g, 'marker-end="url(#'); + } + + cleanedUpSvg = decodeEntities(cleanedUpSvg); + + // replace old br tags with newer style + cleanedUpSvg = cleanedUpSvg.replace(/
/g, '
'); + + return cleanedUpSvg; +}; + +/** + * Put the svgCode into an iFrame. Return the iFrame code + * + * @param svgCode - the svg code to put inside the iFrame + * @param svgElement - the d3 node that has the current svgElement so we can get the height from it + * @returns - the code with the iFrame that now contains the svgCode + * TODO replace btoa(). Replace with buf.toString('base64')? + */ +export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => { + const height = svgElement ? svgElement.viewBox.baseVal.height + 'px' : IFRAME_HEIGHT; + const base64encodedSrc = btoa('' + svgCode + ''); + return ``; +}; + +/** + * Append an enclosing div, then svg, then g (group) to the d3 parentRoot. Set attributes. + * Only set the style attribute on the enclosing div if divStyle is given. + * Only set the xmlns:xlink attribute on svg if svgXlink is given. + * Return the last node appended + * + * @param parentRoot - the d3 node to append things to + * @param id - the value to set the id attr to + * @param enclosingDivId - the id to set the enclosing div to + * @param divStyle - if given, the style to set the enclosing div to + * @param svgXlink - if given, the link to set the new svg element to + * @returns - returns the parentRoot that had nodes appended + */ +export const appendDivSvgG = ( + parentRoot: D3Element, + id: string, + enclosingDivId: string, + divStyle?: string, + svgXlink?: string +): D3Element => { + const enclosingDiv = parentRoot.append('div'); + enclosingDiv.attr('id', enclosingDivId); + if (divStyle) { + enclosingDiv.attr('style', divStyle); + } + + const svgNode = enclosingDiv + .append('svg') + .attr('id', id) + .attr('width', '100%') + .attr('xmlns', XMLNS_SVG_STD); + if (svgXlink) { + svgNode.attr('xmlns:xlink', svgXlink); + } + + svgNode.append('g'); + return parentRoot; +}; + +/** + * Append an iFrame node to the given parentNode and set the id, style, and 'sandbox' attributes + * Return the appended iframe d3 node + * + * @param parentNode - the d3 node to append the iFrame node to + * @param iFrameId - id to use for the iFrame + * @returns the appended iframe d3 node + */ +function sandboxedIframe(parentNode: D3Element, iFrameId: string): D3Element { + return parentNode + .append('iframe') + .attr('id', iFrameId) + .attr('style', 'width: 100%; height: 100%;') + .attr('sandbox', ''); +} + +/** + * Remove any existing elements from the given document + * + * @param doc - the document to removed elements from + * @param isSandboxed - whether or not we are in sandboxed mode + * @param id - id for any existing SVG element + * @param divSelector - selector for any existing enclosing div element + * @param iFrameSelector - selector for any existing iFrame element + */ +export const removeExistingElements = ( + doc: Document, + isSandboxed: boolean, + id: string, + divSelector: string, + iFrameSelector: string +) => { + // Remove existing SVG element if it exists + const existingSvg = doc.getElementById(id); + if (existingSvg) { + existingSvg.remove(); + } + + // Remove previous temporary element if it exists + const element = isSandboxed ? doc.querySelector(iFrameSelector) : doc.querySelector(divSelector); + if (element) { + element.remove(); + } +}; + /** * Function that renders an svg with a graph from a chart definition. Usage example below. * @@ -106,207 +368,145 @@ export const decodeEntities = function (text: string): string { * }); * ``` * - * @param {string} id The id of the element to be rendered - * @param {string} text The graph definition - * @param {(svgCode: string, bindFunctions?: (element: Element) => void) => void} cb Callback which - * is called after rendering is finished with the svg code as inparam. - * @param {Element} container Selector to element in which a div with the graph temporarily will be + * @param id - The id for the SVG element (the element to be rendered) + * @param text - The text for the graph definition + * @param cb - Callback which is called after rendering is finished with the svg code as in param. + * @param container - HTML element where the svg will be inserted. (Is usually element with the .mermaid class) + * If no svgContainingElement is provided then the SVG element will be appended to the body. + * Selector to element in which a div with the graph temporarily will be * inserted. If one is provided a hidden div will be inserted in the body of the page instead. The * element will be removed when rendering is completed. - * @returns {void} + * @returns Returns the rendered element as a string containing the SVG definition. */ -const render = async function ( +const render = function ( id: string, text: string, - cb: (svgCode: string, bindFunctions?: (element: Element) => void) => void, - container?: Element -): Promise { - if (!hasLoadedDiagrams) { - addDiagrams(); - hasLoadedDiagrams = true; - } + cb?: (svgCode: string, bindFunctions?: (element: Element) => void) => void, + svgContainingElement?: Element +): string { + addDiagrams(); + configApi.reset(); - text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;; + + // Add Directives. Must do this before getting the config and before creating the diagram. const graphInit = utils.detectInit(text); if (graphInit) { directiveSanitizer(graphInit); configApi.addDirective(graphInit); } - const cnf = configApi.getConfig(); - log.debug(cnf); + const config = configApi.getConfig(); + log.debug(config); // Check the maximum allowed text size - if (text.length > cnf.maxTextSize!) { - text = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa'; + // TODO: Remove magic number + if (text.length > (config?.maxTextSize ?? 50000)) { + text = MAX_TEXTLENGTH_EXCEEDED_MSG; } + // clean up text CRLFs + text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;; + + const idSelector = '#' + id; + const iFrameID = 'i' + id; + const iFrameID_selector = '#' + iFrameID; + const enclosingDivID = 'd' + id; + const enclosingDivID_selector = '#' + enclosingDivID; + let root: any = select('body'); - // In regular execution the container will be the div with a mermaid class - if (typeof container !== 'undefined') { - // A container was provided by the caller - if (container) { - container.innerHTML = ''; + const isSandboxed = config.securityLevel === SECURITY_LVL_SANDBOX; + const isLooseSecurityLevel = config.securityLevel === SECURITY_LVL_LOOSE; + + const fontFamily = config.fontFamily; + + // ------------------------------------------------------------------------------- + // Define the root d3 node + // In regular execution the svgContainingElement will be the element with a mermaid class + + if (svgContainingElement !== undefined) { + if (svgContainingElement) { + svgContainingElement.innerHTML = ''; } - if (cnf.securityLevel === 'sandbox') { - // IF we are in sandboxed mode, we do everyting mermaid related - // in a sandboxed div - const iframe = select(container) - .append('iframe') - .attr('id', 'i' + id) - .attr('style', 'width: 100%; height: 100%;') - .attr('sandbox', ''); - // const iframeBody = ; + if (isSandboxed) { + // If we are in sandboxed mode, we do everything mermaid related in a (sandboxed )iFrame + const iframe = sandboxedIframe(select(svgContainingElement), iFrameID); root = select(iframe.nodes()[0]!.contentDocument!.body); root.node().style.margin = 0; } else { - root = select(container); + root = select(svgContainingElement); } - - root - .append('div') - .attr('id', 'd' + id) - .attr('style', 'font-family: ' + cnf.fontFamily) - .append('svg') - .attr('id', id) - .attr('width', '100%') - .attr('xmlns', 'http://www.w3.org/2000/svg') - .attr('xmlns:xlink', 'http://www.w3.org/1999/xlink') - .append('g'); + appendDivSvgG(root, id, enclosingDivID, `font-family: ${fontFamily}`, XMLNS_XLINK_STD); } else { - // No container was provided - // If there is an existing element with the id, we remove it - // this likely a previously rendered diagram - const existingSvg = document.getElementById(id); - if (existingSvg) { - existingSvg.remove(); - } + // No svgContainingElement was provided - // Remove previous tpm element if it exists - let element; - if (cnf.securityLevel === 'sandbox') { - element = document.querySelector('#i' + id); - } else { - element = document.querySelector('#d' + id); - } + // If there is an existing element with the id, we remove it. This likely a previously rendered diagram + removeExistingElements(document, isSandboxed, id, iFrameID_selector, enclosingDivID_selector); - if (element) { - element.remove(); - } - - // Add the tmp div used for rendering with the id `d${id}` - // d+id it will contain a svg with the id "id" - - if (cnf.securityLevel === 'sandbox') { - // IF we are in sandboxed mode, we do everyting mermaid related - // in a sandboxed div - const iframe = select('body') - .append('iframe') - .attr('id', 'i' + id) - .attr('style', 'width: 100%; height: 100%;') - .attr('sandbox', ''); + // Add the temporary div used for rendering with the enclosingDivID. + // This temporary div will contain a svg with the id == id + if (isSandboxed) { + // If we are in sandboxed mode, we do everything mermaid related in a (sandboxed) iFrame + const iframe = sandboxedIframe(select('body'), iFrameID); root = select(iframe.nodes()[0]!.contentDocument!.body); root.node().style.margin = 0; } else { root = select('body'); } - // This is the temporary div - root - .append('div') - .attr('id', 'd' + id) - // this is the seed of the svg to be rendered - .append('svg') - .attr('id', id) - .attr('width', '100%') - .attr('xmlns', 'http://www.w3.org/2000/svg') - .append('g'); + appendDivSvgG(root, id, enclosingDivID); } text = encodeEntities(text); + // ------------------------------------------------------------------------------- + // Create the diagram + // Important that we do not create the diagram until after the directives have been included let diag; let parseEncounteredException; + try { // diag = new Diagram(text); - diag = await getDiagramFromText(text); + diag = getDiagramFromText(text); + if ('then' in diag) { + throw new Error('Diagram is a promise. Use renderAsync.'); + } } catch (error) { diag = new Diagram('error'); parseEncounteredException = error; } - // Get the tmp element containing the the svg - const element = root.select('#d' + id).node(); + + // Get the temporary div element containing the svg + const element = root.select(enclosingDivID_selector).node(); const graphType = diag.type; - // insert inline style into svg + // ------------------------------------------------------------------------------- + // Create and insert the styles (user styles, theme styles, config styles) + + // Insert an element into svg. This is where we put the styles const svg = element.firstChild; const firstChild = svg.firstChild; + const diagramClassDefs = CLASSDEF_DIAGRAMS.includes(graphType) + ? diag.renderer.getClasses(text, diag) + : {}; - let userStyles = ''; - // user provided theme CSS - // If you add more configuration driven data into the user styles make sure that the value is - // sanitized bye the santiizeCSS function - if (cnf.themeCSS !== undefined) { - userStyles += `\n${cnf.themeCSS}`; - } - // user provided theme CSS - if (cnf.fontFamily !== undefined) { - userStyles += `\n:root { --mermaid-font-family: ${cnf.fontFamily}}`; - } - // user provided theme CSS - if (cnf.altFontFamily !== undefined) { - userStyles += `\n:root { --mermaid-alt-font-family: ${cnf.altFontFamily}}`; - } - - // classDef - if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') { - const classes: any = flowRenderer.getClasses(text, diag); - const htmlLabels = cnf.htmlLabels || cnf.flowchart?.htmlLabels; - for (const className in classes) { - if (htmlLabels) { - userStyles += `\n.${className} > * { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - userStyles += `\n.${className} span { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - } else { - userStyles += `\n.${className} path { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - userStyles += `\n.${className} rect { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - userStyles += `\n.${className} polygon { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - userStyles += `\n.${className} ellipse { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - userStyles += `\n.${className} circle { ${classes[className].styles.join( - ' !important; ' - )} !important; }`; - if (classes[className].textStyles) { - userStyles += `\n.${className} tspan { ${classes[className].textStyles.join( - ' !important; ' - )} !important; }`; - } - } - } - } - - const stylis = (selector: string, styles: string) => - serialize(compile(`${selector}{${styles}}`), stringify); - const rules = stylis(`#${id}`, getStyles(graphType, userStyles, cnf.themeVariables)); + const rules = createUserStyles( + config, + graphType, + // @ts-ignore convert renderer to TS. + diagramClassDefs, + idSelector + ); const style1 = document.createElement('style'); - style1.innerHTML = `#${id} ` + rules; + style1.innerHTML = rules; svg.insertBefore(style1, firstChild); + // ------------------------------------------------------------------------------- + // Draw the diagram with the renderer try { diag.renderer.draw(text, id, pkg.version, diag); } catch (e) { @@ -314,46 +514,30 @@ const render = async function ( throw e; } - root - .select(`[id="${id}"]`) - .selectAll('foreignobject > *') - .attr('xmlns', 'http://www.w3.org/1999/xhtml'); + // ------------------------------------------------------------------------------- + // Clean up SVG code + root.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', XMLNS_XHTML_STD); // Fix for when the base tag is used - let svgCode = root.select('#d' + id).node().innerHTML; + let svgCode = root.select(enclosingDivID_selector).node().innerHTML; - log.debug('cnf.arrowMarkerAbsolute', cnf.arrowMarkerAbsolute); - if (!evaluate(cnf.arrowMarkerAbsolute) && cnf.securityLevel !== 'sandbox') { - svgCode = svgCode.replace(/marker-end="url\(.*?#/g, 'marker-end="url(#', 'g'); + log.debug('config.arrowMarkerAbsolute', config.arrowMarkerAbsolute); + svgCode = cleanUpSvgCode(svgCode, isSandboxed, evaluate(config.arrowMarkerAbsolute)); + + if (isSandboxed) { + const svgEl = root.select(enclosingDivID_selector + ' svg').node(); + svgCode = putIntoIFrame(svgCode, svgEl); + } else if (isLooseSecurityLevel) { + // Sanitize the svgCode using DOMPurify + svgCode = DOMPurify.sanitize(svgCode, { + ADD_TAGS: DOMPURE_TAGS, + ADD_ATTR: DOMPURE_ATTR, + }); } - svgCode = decodeEntities(svgCode); - - // Fix for when the br tag is used - svgCode = svgCode.replace(/
/g, '
'); - - if (cnf.securityLevel === 'sandbox') { - const svgEl = root.select('#d' + id + ' svg').node(); - const width = '100%'; - let height = '100%'; - if (svgEl) { - height = svgEl.viewBox.baseVal.height + 'px'; - } - svgCode = ``; - } else { - if (cnf.securityLevel !== 'loose') { - svgCode = DOMPurify.sanitize(svgCode, { - ADD_TAGS: ['foreignobject'], - ADD_ATTR: ['dominant-baseline'], - }); - } - } - - if (typeof cb !== 'undefined') { + // ------------------------------------------------------------------------------- + // Do any callbacks (cb = callback) + if (cb !== undefined) { switch (graphType) { case 'flowchart': case 'flowchart-v2': @@ -374,7 +558,205 @@ const render = async function ( } attachFunctions(); - const tmpElementSelector = cnf.securityLevel === 'sandbox' ? '#i' + id : '#d' + id; + // ------------------------------------------------------------------------------- + // Remove the temporary element if appropriate + const tmpElementSelector = isSandboxed ? iFrameID_selector : enclosingDivID_selector; + const node = select(tmpElementSelector).node(); + if (node && 'remove' in node) { + node.remove(); + } + + if (parseEncounteredException) { + throw parseEncounteredException; + } + + return svgCode; +}; + +/** + * @deprecated This is an internal function and should not be used. Will be removed in v10. + */ + +const renderAsync = async function ( + id: string, + text: string, + cb?: (svgCode: string, bindFunctions?: (element: Element) => void) => void, + svgContainingElement?: Element +): Promise { + addDiagrams(); + + configApi.reset(); + + // Add Directives. Must do this before getting the config and before creating the diagram. + const graphInit = utils.detectInit(text); + if (graphInit) { + directiveSanitizer(graphInit); + configApi.addDirective(graphInit); + } + + const config = configApi.getConfig(); + log.debug(config); + + // Check the maximum allowed text size + // TODO: Remove magic number + if (text.length > (config?.maxTextSize ?? 50000)) { + text = MAX_TEXTLENGTH_EXCEEDED_MSG; + } + + // clean up text CRLFs + text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;; + + const idSelector = '#' + id; + const iFrameID = 'i' + id; + const iFrameID_selector = '#' + iFrameID; + const enclosingDivID = 'd' + id; + const enclosingDivID_selector = '#' + enclosingDivID; + + let root: any = select('body'); + + const isSandboxed = config.securityLevel === SECURITY_LVL_SANDBOX; + const isLooseSecurityLevel = config.securityLevel === SECURITY_LVL_LOOSE; + + const fontFamily = config.fontFamily; + + // ------------------------------------------------------------------------------- + // Define the root d3 node + // In regular execution the svgContainingElement will be the element with a mermaid class + + if (svgContainingElement !== undefined) { + if (svgContainingElement) { + svgContainingElement.innerHTML = ''; + } + + if (isSandboxed) { + // If we are in sandboxed mode, we do everything mermaid related in a (sandboxed )iFrame + const iframe = sandboxedIframe(select(svgContainingElement), iFrameID); + root = select(iframe.nodes()[0]!.contentDocument!.body); + root.node().style.margin = 0; + } else { + root = select(svgContainingElement); + } + appendDivSvgG(root, id, enclosingDivID, `font-family: ${fontFamily}`, XMLNS_XLINK_STD); + } else { + // No svgContainingElement was provided + + // If there is an existing element with the id, we remove it. This likely a previously rendered diagram + removeExistingElements(document, isSandboxed, id, iFrameID_selector, enclosingDivID_selector); + + // Add the temporary div used for rendering with the enclosingDivID. + // This temporary div will contain a svg with the id == id + + if (isSandboxed) { + // If we are in sandboxed mode, we do everything mermaid related in a (sandboxed) iFrame + const iframe = sandboxedIframe(select('body'), iFrameID); + root = select(iframe.nodes()[0]!.contentDocument!.body); + root.node().style.margin = 0; + } else { + root = select('body'); + } + + appendDivSvgG(root, id, enclosingDivID); + } + + text = encodeEntities(text); + + // ------------------------------------------------------------------------------- + // Create the diagram + + // Important that we do not create the diagram until after the directives have been included + let diag; + let parseEncounteredException; + + try { + // diag = new Diagram(text); + diag = await getDiagramFromText(text); + } catch (error) { + diag = new Diagram('error'); + parseEncounteredException = error; + } + + // Get the temporary div element containing the svg + const element = root.select(enclosingDivID_selector).node(); + const graphType = diag.type; + + // ------------------------------------------------------------------------------- + // Create and insert the styles (user styles, theme styles, config styles) + + // Insert an element into svg. This is where we put the styles + const svg = element.firstChild; + const firstChild = svg.firstChild; + const diagramClassDefs = CLASSDEF_DIAGRAMS.includes(graphType) + ? diag.renderer.getClasses(text, diag) + : {}; + + const rules = createUserStyles( + config, + graphType, + // @ts-ignore convert renderer to TS. + diagramClassDefs, + idSelector + ); + + const style1 = document.createElement('style'); + style1.innerHTML = rules; + svg.insertBefore(style1, firstChild); + + // ------------------------------------------------------------------------------- + // Draw the diagram with the renderer + try { + await diag.renderer.draw(text, id, pkg.version, diag); + } catch (e) { + errorRenderer.draw(text, id, pkg.version); + throw e; + } + + // ------------------------------------------------------------------------------- + // Clean up SVG code + root.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', XMLNS_XHTML_STD); + + // Fix for when the base tag is used + let svgCode = root.select(enclosingDivID_selector).node().innerHTML; + + log.debug('config.arrowMarkerAbsolute', config.arrowMarkerAbsolute); + svgCode = cleanUpSvgCode(svgCode, isSandboxed, evaluate(config.arrowMarkerAbsolute)); + + if (isSandboxed) { + const svgEl = root.select(enclosingDivID_selector + ' svg').node(); + svgCode = putIntoIFrame(svgCode, svgEl); + } else if (isLooseSecurityLevel) { + // Sanitize the svgCode using DOMPurify + svgCode = DOMPurify.sanitize(svgCode, { + ADD_TAGS: DOMPURE_TAGS, + ADD_ATTR: DOMPURE_ATTR, + }); + } + + // ------------------------------------------------------------------------------- + // Do any callbacks (cb = callback) + if (cb !== undefined) { + switch (graphType) { + case 'flowchart': + case 'flowchart-v2': + cb(svgCode, flowDb.bindFunctions); + break; + case 'gantt': + cb(svgCode, ganttDb.bindFunctions); + break; + case 'class': + case 'classDiagram': + cb(svgCode, classDb.bindFunctions); + break; + default: + cb(svgCode); + } + } else { + log.debug('CB = undefined!'); + } + attachFunctions(); + + // ------------------------------------------------------------------------------- + // Remove the temporary element if appropriate + const tmpElementSelector = isSandboxed ? iFrameID_selector : enclosingDivID_selector; const node = select(tmpElementSelector).node(); if (node && 'remove' in node) { node.remove(); @@ -398,11 +780,15 @@ const parseDirective = function (p: any, statement: string, context: string, typ currentDirective = {}; break; case 'type_directive': - if (!currentDirective) throw new Error('currentDirective is undefined'); + if (!currentDirective) { + throw new Error('currentDirective is undefined'); + } currentDirective.type = statement.toLowerCase(); break; case 'arg_directive': - if (!currentDirective) throw new Error('currentDirective is undefined'); + if (!currentDirective) { + throw new Error('currentDirective is undefined'); + } currentDirective.args = JSON.parse(statement); break; case 'close_directive': @@ -426,7 +812,7 @@ const handleDirective = function (p: any, directive: any, type: string): void { case 'init': case 'initialize': { ['config'].forEach((prop) => { - if (typeof directive.args[prop] !== 'undefined') { + if (directive.args[prop] !== undefined) { if (type === 'flowchart-v2') { type = 'flowchart'; } @@ -460,13 +846,13 @@ const handleDirective = function (p: any, directive: any, type: string): void { } }; -/** @param {MermaidConfig} options */ -function initialize(options: MermaidConfig) { +/** + * @param options - Initial Mermaid options + */ +function initialize(options: MermaidConfig = {}) { // Handle legacy location of font-family configuration - if (options?.fontFamily) { - if (!options.themeVariables?.fontFamily) { - options.themeVariables = { fontFamily: options.fontFamily }; - } + if (options?.fontFamily && !options.themeVariables?.fontFamily) { + options.themeVariables = { fontFamily: options.fontFamily }; } // Set default options @@ -485,39 +871,14 @@ function initialize(options: MermaidConfig) { typeof options === 'object' ? configApi.setSiteConfig(options) : configApi.getSiteConfig(); setLogLevel(config.logLevel); - if (!hasLoadedDiagrams) { - addDiagrams(); - hasLoadedDiagrams = true; - } + addDiagrams(); } -export const mermaidAPI = Object.freeze({ - render, - parse, - parseDirective, - initialize, - getConfig: configApi.getConfig, - setConfig: configApi.setConfig, - getSiteConfig: configApi.getSiteConfig, - updateSiteConfig: configApi.updateSiteConfig, - reset: () => { - configApi.reset(); - }, - globalReset: () => { - configApi.reset(configApi.defaultConfig); - }, - defaultConfig: configApi.defaultConfig, -}); - -setLogLevel(configApi.getConfig().logLevel); -configApi.reset(configApi.getConfig()); -export default mermaidAPI; /** * ## mermaidAPI configuration defaults * - * ```html - * * ``` */ + +export const mermaidAPI = Object.freeze({ + render, + renderAsync, + parse, + parseAsync, + parseDirective, + initialize, + getConfig: configApi.getConfig, + setConfig: configApi.setConfig, + getSiteConfig: configApi.getSiteConfig, + updateSiteConfig: configApi.updateSiteConfig, + reset: () => { + configApi.reset(); + }, + globalReset: () => { + configApi.reset(configApi.defaultConfig); + }, + defaultConfig: configApi.defaultConfig, +}); + +setLogLevel(configApi.getConfig().logLevel); +configApi.reset(configApi.getConfig()); +export default mermaidAPI; diff --git a/packages/mermaid/src/setupGraphViewbox.js b/packages/mermaid/src/setupGraphViewbox.js index 8ffdab5e7..14929d3d7 100644 --- a/packages/mermaid/src/setupGraphViewbox.js +++ b/packages/mermaid/src/setupGraphViewbox.js @@ -1,7 +1,7 @@ import { log } from './logger'; /** - * Applys d3 attributes + * Applies d3 attributes * * @param {any} d3Elem D3 Element to apply the attributes onto * @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes @@ -26,6 +26,7 @@ export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) { attrs.set('width', '100%'); attrs.set('style', `max-width: ${width}px;`); } else { + attrs.set('height', height); attrs.set('width', width); } return attrs; diff --git a/packages/mermaid/src/styles.ts b/packages/mermaid/src/styles.ts index 0c4a7e1a5..055f63be5 100644 --- a/packages/mermaid/src/styles.ts +++ b/packages/mermaid/src/styles.ts @@ -53,7 +53,7 @@ const getStyles = ( } else { log.warn(`No theme found for ${type}`); } - return ` { + return ` & { font-family: ${options.fontFamily}; font-size: ${options.fontSize}; fill: ${options.textColor} @@ -61,40 +61,40 @@ const getStyles = ( /* Classes common for multiple diagrams */ - .error-icon { + & .error-icon { fill: ${options.errorBkgColor}; } - .error-text { + & .error-text { fill: ${options.errorTextColor}; stroke: ${options.errorTextColor}; } - .edge-thickness-normal { + & .edge-thickness-normal { stroke-width: 2px; } - .edge-thickness-thick { + & .edge-thickness-thick { stroke-width: 3.5px } - .edge-pattern-solid { + & .edge-pattern-solid { stroke-dasharray: 0; } - .edge-pattern-dashed{ + & .edge-pattern-dashed{ stroke-dasharray: 3; } .edge-pattern-dotted { stroke-dasharray: 2; } - .marker { + & .marker { fill: ${options.lineColor}; stroke: ${options.lineColor}; } - .marker.cross { + & .marker.cross { stroke: ${options.lineColor}; } - svg { + & svg { font-family: ${options.fontFamily}; font-size: ${options.fontSize}; } diff --git a/packages/mermaid/src/tests/MockedD3.ts b/packages/mermaid/src/tests/MockedD3.ts new file mode 100644 index 000000000..9cf01ddad --- /dev/null +++ b/packages/mermaid/src/tests/MockedD3.ts @@ -0,0 +1,126 @@ +/** + * This is a mocked/stubbed version of the d3 Selection type. Each of the main functions are all + * mocked (via vi.fn()) so you can track if they have been called, etc. + */ +export class MockedD3 { + public attribs = new Map(); + public id: string | undefined = ''; + _children: MockedD3[] = []; + + constructor(givenId = 'mock-id') { + this.id = givenId; + } + + /** Helpful utility during development/debugging. This is not a real d3 function */ + public listChildren(): string { + return this._children + .map((child) => { + return child.id; + }) + .join(', '); + } + + select = vi.fn().mockImplementation(({ select_str = '' }): MockedD3 => { + // Get the id from an argument string. if it is of the form [id='some-id'], strip off the + // surrounding id[..] + const stripSurroundRegexp = /\[id='(.*)']/; + const matchedSurrounds = select_str.match(stripSurroundRegexp); + const cleanId = matchedSurrounds ? matchedSurrounds[1] : select_str; + return new MockedD3(cleanId); + }); + + append = vi + .fn() + .mockImplementation(function (this: MockedD3, type: string, id = '' + '-appended'): MockedD3 { + const newMock = new MockedD3(id); + newMock.attribs.set('type', type); + this._children.push(newMock); + return newMock; + }); + + // NOTE: The d3 implementation allows for a selector ('beforeSelector' arg below). + // With this mocked implementation, we assume it will always refer to an node id + // and will always be of the form "#[id of the node to insert before]". + // To keep this simple, any leading '#' is removed and the resulting string is the node id searched. + insert = (type: string, beforeSelector?: string, id = this.id + '-inserted'): MockedD3 => { + const newMock = new MockedD3(id); + newMock.attribs.set('type', type); + if (beforeSelector === undefined) { + this._children.push(newMock); + } else { + const idOnly = beforeSelector[0] == '#' ? beforeSelector.substring(1) : beforeSelector; + const foundIndex = this._children.findIndex((child) => child.id === idOnly); + if (foundIndex < 0) { + this._children.push(newMock); + } else { + this._children.splice(foundIndex, 0, newMock); + } + } + return newMock; + }; + + attr(attrName: string): null | undefined | string | number; + // attr(attrName: string, attrValue: string): MockedD3; + attr(attrName: string, attrValue?: string): null | undefined | string | number | MockedD3 { + if (arguments.length === 1) { + return this.attribs.get(attrName); + } else { + if (attrName === 'id') { + this.id = attrValue; // also set the id explicitly + } + if (attrValue !== undefined) { + this.attribs.set(attrName, attrValue); + } + return this; + } + } + + public lower(attrValue = '') { + this.attribs.set('lower', attrValue); + return this; + } + public style(attrValue = '') { + this.attribs.set('style', attrValue); + return this; + } + public text(attrValue = '') { + this.attribs.set('text', attrValue); + return this; + } + // NOTE: Arbitrarily returns an empty object. The return value could be something different with a mockReturnValue() or mockImplementation() + public node = vi.fn().mockReturnValue({}); + + nodes = vi.fn().mockImplementation(function (this: MockedD3): MockedD3[] { + return this._children; + }); + + // This will try to use attrs that have been set. + getBBox = () => { + const x = this.attribs.has('x') ? this.attribs.get('x') : 20; + const y = this.attribs.has('y') ? this.attribs.get('y') : 30; + const width = this.attribs.has('width') ? this.attribs.get('width') : 140; + const height = this.attribs.has('height') ? this.attribs.get('height') : 250; + return { + x: x, + y: y, + width: width, + height: height, + }; + }; + + // -------------------------------------------------------------------------------- + // The following functions are here for completeness. They simply return a vi.fn() + + insertBefore = vi.fn(); + curveBasis = vi.fn(); + curveBasisClosed = vi.fn(); + curveBasisOpen = vi.fn(); + curveLinear = vi.fn(); + curveLinearClosed = vi.fn(); + curveMonotoneX = vi.fn(); + curveMonotoneY = vi.fn(); + curveNatural = vi.fn(); + curveStep = vi.fn(); + curveStepAfter = vi.fn(); + curveStepBefore = vi.fn(); +} diff --git a/packages/mermaid/src/tests/setup.ts b/packages/mermaid/src/tests/setup.ts index e8058c517..b3330787c 100644 --- a/packages/mermaid/src/tests/setup.ts +++ b/packages/mermaid/src/tests/setup.ts @@ -1,3 +1,3 @@ import { vi } from 'vitest'; vi.mock('d3'); -vi.mock('dagre-d3'); +vi.mock('dagre-d3-es'); diff --git a/packages/mermaid/src/tests/util.ts b/packages/mermaid/src/tests/util.ts index 76f8572e3..042f2cb43 100644 --- a/packages/mermaid/src/tests/util.ts +++ b/packages/mermaid/src/tests/util.ts @@ -26,7 +26,7 @@ ${'2w'} | ${moment.duration(2, 'w')} ``` */ -export const convert = (template: TemplateStringsArray, ...params: any[]) => { +export const convert = (template: TemplateStringsArray, ...params: unknown[]) => { const header = template[0] .trim() .split('|') diff --git a/packages/mermaid/src/themes/erDiagram-oldHardcodedValues.ts b/packages/mermaid/src/themes/erDiagram-oldHardcodedValues.ts index 8f88a70cd..95ce40e79 100644 --- a/packages/mermaid/src/themes/erDiagram-oldHardcodedValues.ts +++ b/packages/mermaid/src/themes/erDiagram-oldHardcodedValues.ts @@ -1,5 +1,5 @@ /** - * @file Values that have been hardcoded in src/diagrams/er/styles.js. These can be used by + * Values that have been hardcoded in src/diagrams/er/styles.js. These can be used by * theme-_._ files to maintain display styles until themes, styles, renderers are revised. -- * 2022-09-22 */ diff --git a/packages/mermaid/src/themes/theme-base.js b/packages/mermaid/src/themes/theme-base.js index 86338c13c..c940a0055 100644 --- a/packages/mermaid/src/themes/theme-base.js +++ b/packages/mermaid/src/themes/theme-base.js @@ -20,6 +20,8 @@ class Theme { this.noteBkgColor = '#fff5ad'; this.noteTextColor = '#333'; + this.THEME_COLOR_LIMIT = 12; + // dark this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif'; @@ -123,6 +125,50 @@ class Theme { this.transitionColor = this.transitionColor || this.lineColor; this.specialStateColor = this.lineColor; + /* Color Scale */ + /* Each color-set will have a background, a foreground and a border color */ + this.cScale0 = this.cScale0 || this.primaryColor; + this.cScale1 = this.cScale1 || this.secondaryColor; + this.cScale2 = this.cScale2 || this.tertiaryColor; + this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 }); + this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 }); + this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 }); + this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 }); + this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 }); + this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210, l: 150 }); + this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 }); + this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 }); + this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 }); + if (this.darkMode) { + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScale' + i] = darken(this['cScale' + i], 75); + } + } else { + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScale' + i] = darken(this['cScale' + i], 25); + } + } + + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]); + } + // Setup the peer color for the set, useful for borders + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + if (this.darkMode) { + this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10); + } else { + this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 10); + } + } + + // Setup teh label color for the set + this.scaleLabelColor = this.scaleLabelColor || this.labelTextColor; + + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor; + } + /* class */ this.classText = this.classText || this.textColor; diff --git a/packages/mermaid/src/themes/theme-dark.js b/packages/mermaid/src/themes/theme-dark.js index d0ea1269e..5ba63e155 100644 --- a/packages/mermaid/src/themes/theme-dark.js +++ b/packages/mermaid/src/themes/theme-dark.js @@ -29,6 +29,7 @@ class Theme { this.fontSize = '16px'; this.labelBackground = '#181818'; this.textColor = '#ccc'; + this.THEME_COLOR_LIMIT = 12; /* Flowchart variables */ this.nodeBkg = 'calculated'; @@ -157,19 +158,55 @@ class Theme { this.fillType6 = adjust(this.primaryColor, { h: 128 }); this.fillType7 = adjust(this.secondaryColor, { h: 128 }); - /* pie */ - this.pie1 = this.pie1 || '#0b0000'; - this.pie2 = this.pie2 || '#4d1037'; - this.pie3 = this.pie3 || '#3f5258'; - this.pie4 = this.pie4 || '#4f2f1b'; - this.pie5 = this.pie5 || '#6e0a0a'; - this.pie6 = this.pie6 || '#3b0048'; - this.pie7 = this.pie7 || '#995a01'; - this.pie8 = this.pie8 || '#154706'; - this.pie9 = this.pie9 || '#161722'; - this.pie10 = this.pie10 || '#00296f'; - this.pie11 = this.pie11 || '#01629c'; - this.pie12 = this.pie12 || '#010029'; + /* cScale */ + this.cScale1 = this.cScale1 || '#0b0000'; + this.cScale2 = this.cScale2 || '#4d1037'; + this.cScale3 = this.cScale3 || '#3f5258'; + this.cScale4 = this.cScale4 || '#4f2f1b'; + this.cScale5 = this.cScale5 || '#6e0a0a'; + this.cScale6 = this.cScale6 || '#3b0048'; + this.cScale7 = this.cScale7 || '#995a01'; + this.cScale8 = this.cScale8 || '#154706'; + this.cScale9 = this.cScale9 || '#161722'; + this.cScale10 = this.cScale10 || '#00296f'; + this.cScale11 = this.cScale11 || '#01629c'; + this.cScale12 = this.cScale12 || '#010029'; + + /* Color Scale */ + /* Each color-set will have a background, a foreground and a border color */ + this.cScale0 = this.cScale0 || this.primaryColor; + this.cScale1 = this.cScale1 || this.secondaryColor; + this.cScale2 = this.cScale2 || this.tertiaryColor; + this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 }); + this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 }); + this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 }); + this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 }); + this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 }); + this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 }); + this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 }); + this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 }); + this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 }); + + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]); + } + // Setup the peer color for the set, useful for borders + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10); + } + + // Setup teh label color for the set + this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor); + + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor; + } + + /* Pie diagram */ + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['pie' + i] = this['cScale' + i]; + } this.pieTitleTextSize = this.pieTitleTextSize || '25px'; this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor; this.pieSectionTextSize = this.pieSectionTextSize || '17px'; diff --git a/packages/mermaid/src/themes/theme-default.js b/packages/mermaid/src/themes/theme-default.js index a8abbfc57..95710629b 100644 --- a/packages/mermaid/src/themes/theme-default.js +++ b/packages/mermaid/src/themes/theme-default.js @@ -36,6 +36,7 @@ class Theme { this.fontSize = '16px'; this.labelBackground = '#e8e8e8'; this.textColor = '#333'; + this.THEME_COLOR_LIMIT = 12; /* Flowchart variables */ @@ -119,8 +120,48 @@ class Theme { this.updateColors(); } updateColors() { - /* Flowchart variables */ + /* Color Scale */ + /* Each color-set will have a background, a foreground and a border color */ + this.cScale0 = this.cScale0 || this.primaryColor; + this.cScale1 = this.cScale1 || this.secondaryColor; + this.cScale2 = this.cScale2 || this.tertiaryColor; + this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 }); + this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 }); + this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 }); + this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 }); + this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 }); + this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 }); + this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 }); + this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 }); + this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 }); + this['cScalePeer' + 1] = this['cScalePeer' + 1] || darken(this.secondaryColor, 45); + this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40); + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + // Setup the peer color for the set, useful for borders + this['cScale' + i] = darken(this['cScale' + i], 10); + this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25); + } + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || adjust(this['cScale' + i], { h: 180 }); + } + + // Setup the label color for the set + this.scaleLabelColor = + this.scaleLabelColor !== 'calculated' && this.scaleLabelColor + ? this.scaleLabelColor + : this.labelTextColor; + + if (this.labelTextColor !== 'calculated') { + this.cScaleLabel0 = this.cScaleLabel0 || invert(this.labelTextColor); + this.cScaleLabel3 = this.cScaleLabel3 || invert(this.labelTextColor); + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.labelTextColor; + } + } + + /* Flowchart variables */ this.nodeBkg = this.mainBkg; this.nodeBorder = this.border1; // border 1 this.clusterBkg = this.secondBkg; diff --git a/packages/mermaid/src/themes/theme-forest.js b/packages/mermaid/src/themes/theme-forest.js index d02d46e5a..860326dea 100644 --- a/packages/mermaid/src/themes/theme-forest.js +++ b/packages/mermaid/src/themes/theme-forest.js @@ -30,6 +30,7 @@ class Theme { this.tertiaryTextColor = invert(this.primaryColor); this.lineColor = invert(this.background); this.textColor = invert(this.background); + this.THEME_COLOR_LIMIT = 12; /* Flowchart variables */ this.nodeBkg = 'calculated'; @@ -93,6 +94,42 @@ class Theme { this.errorTextColor = '#552222'; } updateColors() { + /* Each color-set will have a background, a foreground and a border color */ + this.cScale0 = this.cScale0 || this.primaryColor; + this.cScale1 = this.cScale1 || this.secondaryColor; + this.cScale2 = this.cScale2 || this.tertiaryColor; + this.cScale3 = this.cScale3 || adjust(this.primaryColor, { h: 30 }); + this.cScale4 = this.cScale4 || adjust(this.primaryColor, { h: 60 }); + this.cScale5 = this.cScale5 || adjust(this.primaryColor, { h: 90 }); + this.cScale6 = this.cScale6 || adjust(this.primaryColor, { h: 120 }); + this.cScale7 = this.cScale7 || adjust(this.primaryColor, { h: 150 }); + this.cScale8 = this.cScale8 || adjust(this.primaryColor, { h: 210 }); + this.cScale9 = this.cScale9 || adjust(this.primaryColor, { h: 270 }); + this.cScale10 = this.cScale10 || adjust(this.primaryColor, { h: 300 }); + this.cScale11 = this.cScale11 || adjust(this.primaryColor, { h: 330 }); + this['cScalePeer' + 1] = this['cScalePeer' + 1] || darken(this.secondaryColor, 45); + this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40); + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + // Setup the peer color for the set, useful for borders + this['cScale' + i] = darken(this['cScale' + i], 10); + this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25); + } + + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || adjust(this['cScale' + i], { h: 180 }); + } + + // Setup teh label color for the set + this.scaleLabelColor = + this.scaleLabelColor !== 'calculated' && this.scaleLabelColor + ? this.scaleLabelColor + : this.labelTextColor; + + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor; + } + /* Flowchart variables */ this.nodeBkg = this.mainBkg; diff --git a/packages/mermaid/src/themes/theme-neutral.js b/packages/mermaid/src/themes/theme-neutral.js index c4bbf8241..f22710387 100644 --- a/packages/mermaid/src/themes/theme-neutral.js +++ b/packages/mermaid/src/themes/theme-neutral.js @@ -41,6 +41,7 @@ class Theme { this.arrowheadColor = '#333333'; this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif'; this.fontSize = '16px'; + this.THEME_COLOR_LIMIT = 12; /* Flowchart variables */ @@ -108,6 +109,44 @@ class Theme { this.secondBkg = lighten(this.contrast, 55); this.border2 = this.contrast; + /* Color Scale */ + /* Each color-set will have a background, a foreground and a border color */ + + this.cScale0 = this.cScale0 || '#555'; + this.cScale1 = this.cScale1 || '#F4F4F4'; + this.cScale2 = this.cScale2 || '#555'; + this.cScale3 = this.cScale3 || '#BBB'; + this.cScale4 = this.cScale4 || '#777'; + this.cScale5 = this.cScale5 || '#999'; + this.cScale6 = this.cScale6 || '#DDD'; + this.cScale7 = this.cScale7 || '#FFF'; + this.cScale8 = this.cScale8 || '#DDD'; + this.cScale9 = this.cScale9 || '#BBB'; + this.cScale10 = this.cScale10 || '#999'; + this.cScale11 = this.cScale11 || '#777'; + + // Setup the inverted color for the set + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleInv' + i] = this['cScaleInv' + i] || invert(this['cScale' + i]); + } + // Setup the peer color for the set, useful for borders + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + if (this.darkMode) { + this['cScalePeer' + i] = this['cScalePeer' + i] || lighten(this['cScale' + i], 10); + } else { + this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 10); + } + } + + // Setup the label color for the set + this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor); + + this['cScaleLabel0'] = this['cScaleLabel0'] || this.cScale1; + this['cScaleLabel2'] = this['cScaleLabel2'] || this.cScale1; + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor; + } + /* Flowchart variables */ this.nodeBkg = this.mainBkg; @@ -185,18 +224,11 @@ class Theme { this.fillType7 = adjust(this.secondaryColor, { h: 128 }); // /* pie */ - this.pie1 = this.pie1 || '#F4F4F4'; - this.pie2 = this.pie2 || '#555'; - this.pie3 = this.pie3 || '#BBB'; - this.pie4 = this.pie4 || '#777'; - this.pie5 = this.pie5 || '#999'; - this.pie6 = this.pie6 || '#DDD'; - this.pie7 = this.pie7 || '#FFF'; - this.pie8 = this.pie8 || '#DDD'; - this.pie9 = this.pie9 || '#BBB'; - this.pie10 = this.pie10 || '#999'; - this.pie11 = this.pie11 || '#777'; - this.pie12 = this.pie12 || '#555'; + /* Pie diagram */ + for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { + this['pie' + i] = this['cScale' + i]; + } + this.pie12 = this.pie0; this.pieTitleTextSize = this.pieTitleTextSize || '25px'; this.pieTitleTextColor = this.pieTitleTextColor || this.taskTextDarkColor; this.pieSectionTextSize = this.pieSectionTextSize || '17px'; @@ -207,19 +239,6 @@ class Theme { this.pieStrokeWidth = this.pieStrokeWidth || '2px'; this.pieOpacity = this.pieOpacity || '0.7'; - // this.pie1 = this.pie1 || '#212529'; - // this.pie2 = this.pie2 || '#343A40'; - // this.pie3 = this.pie3 || '#495057'; - // this.pie4 = this.pie4 || '#6C757D'; - // this.pie5 = this.pie5 || adjust(this.secondaryColor, { l: -10 }); - // this.pie6 = this.pie6 || adjust(this.tertiaryColor, { l: -10 }); - // this.pie7 = this.pie7 || adjust(this.primaryColor, { h: +60, l: -10 }); - // this.pie8 = this.pie8 || adjust(this.primaryColor, { h: -60, l: -10 }); - // this.pie9 = this.pie9 || adjust(this.primaryColor, { h: 120, l: 0 }); - // this.pie10 = this.pie10 || adjust(this.primaryColor, { h: +60, l: -20 }); - // this.pie11 = this.pie11 || adjust(this.primaryColor, { h: -60, l: -20 }); - // this.pie12 = this.pie12 || adjust(this.primaryColor, { h: 120, l: -10 }); - /* requirement-diagram */ this.requirementBackground = this.requirementBackground || this.primaryColor; this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor; diff --git a/packages/mermaid/src/utils.spec.js b/packages/mermaid/src/utils.spec.js index f1523aca5..54262f10e 100644 --- a/packages/mermaid/src/utils.spec.js +++ b/packages/mermaid/src/utils.spec.js @@ -1,9 +1,10 @@ -import { vi, describe, it, expect, beforeEach } from 'vitest'; +import { vi } from 'vitest'; import utils from './utils'; import assignWithDepth from './assignWithDepth'; import { detectType } from './diagram-api/detectType'; import { addDiagrams } from './diagram-api/diagram-orchestration'; -import memoize from 'lodash/memoize'; +import memoize from 'lodash-es/memoize'; +import { MockD3 } from 'd3'; addDiagrams(); describe('when assignWithDepth: should merge objects within objects', function () { @@ -232,6 +233,15 @@ Alice->Bob: hi`; const type = detectType(str); expect(type).toBe('gitGraph'); }); + it('should handle frontmatter', function () { + const str = '---\ntitle: foo\n---\n gitGraph TB:\nbfs1:queue'; + const type = detectType(str); + expect(type).toBe('gitGraph'); + }); + it('should not allow frontmatter with leading spaces', function () { + const str = ' ---\ntitle: foo\n---\n gitGraph TB:\nbfs1:queue'; + expect(() => detectType(str)).toThrow('No diagram type detected for text'); + }); }); describe('when finding substring in array ', function () { it('should return the array index that contains the substring', function () { @@ -340,3 +350,23 @@ describe('when initializing the id generator', function () { expect(idGenerator.next()).toEqual(lastId + 1); }); }); + +describe('when inserting titles', function () { + it('should do nothing when title is empty', function () { + const svg = MockD3('svg'); + utils.insertTitle(svg, 'testClass', 0, ''); + expect(svg.__children.length).toBe(0); + }); + + it('should insert title centered', function () { + const svg = MockD3('svg'); + utils.insertTitle(svg, 'testClass', 5, 'test title'); + expect(svg.__children.length).toBe(1); + const text = svg.__children[0]; + expect(text.__name).toBe('text'); + expect(text.text).toHaveBeenCalledWith('test title'); + expect(text.attr).toHaveBeenCalledWith('x', 15); + expect(text.attr).toHaveBeenCalledWith('y', -5); + expect(text.attr).toHaveBeenCalledWith('class', 'testClass'); + }); +}); diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index 395e6fe2a..16566c3b1 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -4,6 +4,7 @@ import { curveBasis, curveBasisClosed, curveBasisOpen, + CurveFactory, curveLinear, curveLinearClosed, curveMonotoneX, @@ -20,7 +21,7 @@ import { log } from './logger'; import { detectType } from './diagram-api/detectType'; import assignWithDepth from './assignWithDepth'; import { MermaidConfig } from './config.type'; -import memoize from 'lodash/memoize'; +import memoize from 'lodash-es/memoize'; // Effectively an enum of the supported curve types, accessible by name const d3CurveTypes = { @@ -36,19 +37,18 @@ const d3CurveTypes = { curveStepAfter: curveStepAfter, curveStepBefore: curveStepBefore, }; -const directive = - /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; +const directive = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi; const directiveWithoutOpen = - /\s*(?:(?:(\w+)(?=:):|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; + /\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi; /** - * @function detectInit Detects the init config object from the text - * @param config + * Detects the init config object from the text * - * ```mermaid + * @param text - The text defining the graph. For example: * - * %%{init: {"theme": "debug", "logLevel": 1 }}%% - * graph LR + * ```mermaid + * %%{init: {"theme": "debug", "logLevel": 1 }}%% + * graph LR * a-->b * b-->c * c-->d @@ -58,11 +58,11 @@ const directiveWithoutOpen = * g-->h * ``` * - * Or + * Or * - * ```mermaid - * %%{initialize: {"theme": "dark", logLevel: "debug" }}%% - * graph LR + * ```mermaid + * %%{initialize: {"theme": "dark", logLevel: "debug" }}%% + * graph LR * a-->b * b-->c * c-->d @@ -71,8 +71,9 @@ const directiveWithoutOpen = * f-->g * g-->h * ``` - * @param {string} text The text defining the graph - * @returns {object} The json object representing the init passed to mermaid.initialize() + * + * @param config - Optional mermaid configuration object. + * @returns The json object representing the init passed to mermaid.initialize() */ export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig { const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/); @@ -89,7 +90,7 @@ export const detectInit = function (text: string, config?: MermaidConfig): Merma if (results) { let type = detectType(text, config); ['config'].forEach((prop) => { - if (typeof results[prop] !== 'undefined') { + if (results[prop] !== undefined) { if (type === 'flowchart-v2') { type = 'flowchart'; } @@ -104,12 +105,14 @@ export const detectInit = function (text: string, config?: MermaidConfig): Merma }; /** - * @function detectDirective Detects the directive from the text. Text can be single line or - * multiline. If type is null or omitted the first directive encountered in text will be returned + * Detects the directive from the text. * - * ```mermaid - * graph LR - * %%{somedirective}%% + * Text can be single line or multiline. If type is null or omitted, + * the first directive encountered in text will be returned + * + * ```mermaid + * graph LR + * %%{someDirective}%% * a-->b * b-->c * c-->d @@ -118,13 +121,16 @@ export const detectInit = function (text: string, config?: MermaidConfig): Merma * f-->g * g-->h * ``` - * @param {string} text The text defining the graph - * @param {string | RegExp} type The directive to return (default: null) - * @returns {object | Array} An object or Array representing the directive(s): { type: string, args: - * object|null } matched by the input type if a single directive was found, that directive object - * will be returned. + * + * @param text - The text defining the graph + * @param type - The directive to return (default: `null`) + * @returns An object or Array representing the directive(s) matched by the input type. + * If a single directive was found, that directive object will be returned. */ -export const detectDirective = function (text, type = null) { +export const detectDirective = function ( + text: string, + type: string | RegExp = null +): { type?: string; args?: any } | { type?: string; args?: any }[] { try { const commentWithoutDirectives = new RegExp( `[%]{2}(?![{]${directiveWithoutOpen.source})(?=[}][%]{2}).*\n`, @@ -166,14 +172,17 @@ export const detectDirective = function (text, type = null) { }; /** - * @function isSubstringInArray Detects whether a substring in present in a given array - * @param {string} str The substring to detect - * @param {Array} arr The array to search - * @returns {number} The array index containing the substring or -1 if not present + * Detects whether a substring in present in a given array + * + * @param str - The substring to detect + * @param arr - The array to search + * @returns The array index containing the substring or -1 if not present */ -export const isSubstringInArray = function (str, arr) { - for (let i = 0; i < arr.length; i++) { - if (arr[i].match(str)) return i; +export const isSubstringInArray = function (str: string, arr: string[]): number { + for (const [i, element] of arr.entries()) { + if (element.match(str)) { + return i; + } } return -1; }; @@ -181,26 +190,26 @@ export const isSubstringInArray = function (str, arr) { /** * Returns a d3 curve given a curve name * - * @param {string | undefined} interpolate The interpolation name - * @param {any} defaultCurve The default curve to return - * @returns {import('d3-shape').CurveFactory} The curve factory to use + * @param interpolate - The interpolation name + * @param defaultCurve - The default curve to return + * @returns The curve factory to use */ -export const interpolateToCurve = (interpolate, defaultCurve) => { +export function interpolateToCurve(interpolate?: string, defaultCurve: CurveFactory): CurveFactory { if (!interpolate) { return defaultCurve; } const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`; return d3CurveTypes[curveName] || defaultCurve; -}; +} /** * Formats a URL string * - * @param {string} linkStr String of the URL - * @param {{ securityLevel: string }} config Configuration passed to MermaidJS - * @returns {string | undefined} The formatted URL + * @param linkStr - String of the URL + * @param config - Configuration passed to MermaidJS + * @returns The formatted URL or `undefined`. */ -export const formatUrl = (linkStr, config) => { +export function formatUrl(linkStr: string, config: { securityLevel: string }): string | undefined { const url = linkStr.trim(); if (url) { @@ -210,15 +219,15 @@ export const formatUrl = (linkStr, config) => { return url; } -}; +} /** * Runs a function * - * @param {string} functionName A dot seperated path to the function relative to the `window` - * @param {...any} params Parameters to pass to the function + * @param functionName - A dot separated path to the function relative to the `window` + * @param params - Parameters to pass to the function */ -export const runFunc = (functionName, ...params) => { +export const runFunc = (functionName: string, ...params) => { const arrPaths = functionName.split('.'); const len = arrPaths.length - 1; @@ -227,34 +236,39 @@ export const runFunc = (functionName, ...params) => { let obj = window; for (let i = 0; i < len; i++) { obj = obj[arrPaths[i]]; - if (!obj) return; + if (!obj) { + return; + } } obj[fnName](...params); }; -/** - * @typedef {object} Point A (x, y) point - * @property {number} x The x value - * @property {number} y The y value - */ +/** A (x, y) point */ +interface Point { + /** The x value */ + x: number; + /** The y value */ + y: number; +} /** * Finds the distance between two points using the Distance Formula * - * @param {Point} p1 The first point - * @param {Point} p2 The second point - * @returns {number} The distance + * @param p1 - The first point + * @param p2 - The second point + * @returns The distance between the two points. */ -const distance = (p1, p2) => - p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; +function distance(p1: Point, p2: Point): number { + return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; +} /** - * @param {Point[]} points List of points - * @returns {Point} - * @todo Give this a description + * TODO: Give this a description + * + * @param points - List of points */ -const traverseEdge = (points) => { +function traverseEdge(points: Point[]): Point { let prevPoint; let totalDistance = 0; @@ -276,8 +290,12 @@ const traverseEdge = (points) => { // The point is remainingDistance from prevPoint in the vector between prevPoint and point // Calculate the coordinates const distanceRatio = remainingDistance / vectorDistance; - if (distanceRatio <= 0) center = prevPoint; - if (distanceRatio >= 1) center = { x: point.x, y: point.y }; + if (distanceRatio <= 0) { + center = prevPoint; + } + if (distanceRatio >= 1) { + center = { x: point.x, y: point.y }; + } if (distanceRatio > 0 && distanceRatio < 1) { center = { x: (1 - distanceRatio) * prevPoint.x + distanceRatio * point.x, @@ -289,32 +307,24 @@ const traverseEdge = (points) => { prevPoint = point; }); return center; -}; +} /** - * Alias for `traverseEdge` - * - * @param {Point[]} points List of points - * @returns {Point} Return result of `transverseEdge` + * {@inheritdoc traverseEdge} */ -const calcLabelPosition = (points) => { +function calcLabelPosition(points: Point[]): Point { if (points.length === 1) { return points[0]; } return traverseEdge(points); -}; +} const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => { let prevPoint; - log.info('our points', points); + log.info(`our points ${JSON.stringify(points)}`); if (points[0] !== initialPosition) { points = points.reverse(); } - points.forEach((point) => { - totalDistance += distance(point, prevPoint); - prevPoint = point; - }); - // Traverse only 25 total distance along points to find cardinality point const distanceToCardinalityPoint = 25; @@ -330,8 +340,12 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) // The point is remainingDistance from prevPoint in the vector between prevPoint and point // Calculate the coordinates const distanceRatio = remainingDistance / vectorDistance; - if (distanceRatio <= 0) center = prevPoint; - if (distanceRatio >= 1) center = { x: point.x, y: point.y }; + if (distanceRatio <= 0) { + center = prevPoint; + } + if (distanceRatio >= 1) { + center = { x: point.x, y: point.y }; + } if (distanceRatio > 0 && distanceRatio < 1) { center = { x: (1 - distanceRatio) * prevPoint.x + distanceRatio * point.x, @@ -354,14 +368,18 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) }; /** - * Position ['start_left', 'start_right', 'end_left', 'end_right'] + * Calculates the terminal label position. * - * @param {any} terminalMarkerSize - * @param {any} position - * @param {any} _points - * @returns {any} + * @param terminalMarkerSize - Terminal marker size. + * @param position - Position of label relative to points. + * @param _points - Array of points. + * @returns - The `cardinalityPosition`. */ -const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => { +function calcTerminalLabelPosition( + terminalMarkerSize: number, + position: 'start_left' | 'start_right' | 'end_left' | 'end_right', + _points: Point[] +): Point { // Todo looking to faster cloning method let points = JSON.parse(JSON.stringify(_points)); let prevPoint; @@ -389,8 +407,12 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => { // The point is remainingDistance from prevPoint in the vector between prevPoint and point // Calculate the coordinates const distanceRatio = remainingDistance / vectorDistance; - if (distanceRatio <= 0) center = prevPoint; - if (distanceRatio >= 1) center = { x: point.x, y: point.y }; + if (distanceRatio <= 0) { + center = prevPoint; + } + if (distanceRatio >= 1) { + center = { x: point.x, y: point.y }; + } if (distanceRatio > 0 && distanceRatio < 1) { center = { x: (1 - distanceRatio) * prevPoint.x + distanceRatio * point.x, @@ -425,31 +447,31 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => { cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2 - 5; } return cardinalityPosition; -}; +} /** * Gets styles from an array of declarations * - * @param {string[]} arr Declarations - * @returns {{ style: string; labelStyle: string }} The styles grouped as strings + * @param arr - Declarations + * @returns The styles grouped as strings */ -export const getStylesFromArray = (arr) => { +export function getStylesFromArray(arr: string[]): { style: string; labelStyle: string } { let style = ''; let labelStyle = ''; - for (let i = 0; i < arr.length; i++) { - if (typeof arr[i] !== 'undefined') { + for (const element of arr) { + if (element !== undefined) { // add text properties to label style definition - if (arr[i].startsWith('color:') || arr[i].startsWith('text-align:')) { - labelStyle = labelStyle + arr[i] + ';'; + if (element.startsWith('color:') || element.startsWith('text-align:')) { + labelStyle = labelStyle + element + ';'; } else { - style = style + arr[i] + ';'; + style = style + element + ';'; } } } return { style: style, labelStyle: labelStyle }; -}; +} let cnt = 0; export const generateId = () => { @@ -458,10 +480,12 @@ export const generateId = () => { }; /** - * @param {any} length - * @returns {any} + * Generates a random hexadecimal id of the given length. + * + * @param length - Length of ID. + * @returns The generated ID. */ -function makeid(length) { +function makeid(length: number): string { let result = ''; const characters = '0123456789abcdef'; const charactersLength = characters.length; @@ -494,22 +518,25 @@ export const getTextObj = function () { /** * Adds text to an element * - * @param {SVGElement} elem Element to add text to - * @param {{ - * text: string; - * x: number; - * y: number; - * anchor: 'start' | 'middle' | 'end'; - * fontFamily: string; - * fontSize: string | number; - * fontWeight: string | number; - * fill: string; - * class: string | undefined; - * textMargin: number; - * }} textData - * @returns {SVGTextElement} Text element with given styling and content + * @param elem - SVG Element to add text to + * @param textData - Text options. + * @returns Text element with given styling and content */ -export const drawSimpleText = function (elem, textData) { +export const drawSimpleText = function ( + elem: SVGElement, + textData: { + text: string; + x: number; + y: number; + anchor: 'start' | 'middle' | 'end'; + fontFamily: string; + fontSize: string | number; + fontWeight: string | number; + fill: string; + class: string | undefined; + textMargin: number; + } +): SVGTextElement { // Remove and ignore br:s const nText = textData.text.replace(common.lineBreakRegex, ' '); @@ -521,7 +548,7 @@ export const drawSimpleText = function (elem, textData) { textElem.style('font-size', textData.fontSize); textElem.style('font-weight', textData.fontWeight); textElem.attr('fill', textData.fill); - if (typeof textData.class !== 'undefined') { + if (textData.class !== undefined) { textElem.attr('class', textData.class); } @@ -533,54 +560,77 @@ export const drawSimpleText = function (elem, textData) { return textElem; }; -export const wrapLabel = memoize( - (label, maxWidth, config) => { - if (!label) { - return label; - } - config = Object.assign( - { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', joinWith: '
' }, - config - ); - if (common.lineBreakRegex.test(label)) { - return label; - } - const words = label.split(' '); - const completedLines = []; - let nextLine = ''; - words.forEach((word, index) => { - const wordLength = calculateTextWidth(`${word} `, config); - const nextLineLength = calculateTextWidth(nextLine, config); - if (wordLength > maxWidth) { - const { hyphenatedStrings, remainingWord } = breakString(word, maxWidth, '-', config); - completedLines.push(nextLine, ...hyphenatedStrings); - nextLine = remainingWord; - } else if (nextLineLength + wordLength >= maxWidth) { - completedLines.push(nextLine); - nextLine = word; - } else { - nextLine = [nextLine, word].filter(Boolean).join(' '); - } - const currentWord = index + 1; - const isLastWord = currentWord === words.length; - if (isLastWord) { - completedLines.push(nextLine); - } - }); - return completedLines.filter((line) => line !== '').join(config.joinWith); - }, - (label, maxWidth, config) => - `${label}${maxWidth}${config.fontSize}${config.fontWeight}${config.fontFamily}${config.joinWith}` -); +interface WrapLabelConfig { + fontSize: number; + fontFamily: string; + fontWeight: number; + joinWith: string; +} -const breakString = memoize( - (word, maxWidth, hyphenCharacter = '-', config) => { +export const wrapLabel: (label: string, maxWidth: string, config: WrapLabelConfig) => string = + memoize( + (label: string, maxWidth: string, config: WrapLabelConfig): string => { + if (!label) { + return label; + } + config = Object.assign( + { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', joinWith: '
' }, + config + ); + if (common.lineBreakRegex.test(label)) { + return label; + } + const words = label.split(' '); + const completedLines = []; + let nextLine = ''; + words.forEach((word, index) => { + const wordLength = calculateTextWidth(`${word} `, config); + const nextLineLength = calculateTextWidth(nextLine, config); + if (wordLength > maxWidth) { + const { hyphenatedStrings, remainingWord } = breakString(word, maxWidth, '-', config); + completedLines.push(nextLine, ...hyphenatedStrings); + nextLine = remainingWord; + } else if (nextLineLength + wordLength >= maxWidth) { + completedLines.push(nextLine); + nextLine = word; + } else { + nextLine = [nextLine, word].filter(Boolean).join(' '); + } + const currentWord = index + 1; + const isLastWord = currentWord === words.length; + if (isLastWord) { + completedLines.push(nextLine); + } + }); + return completedLines.filter((line) => line !== '').join(config.joinWith); + }, + (label, maxWidth, config) => + `${label}${maxWidth}${config.fontSize}${config.fontWeight}${config.fontFamily}${config.joinWith}` + ); + +interface BreakStringOutput { + hyphenatedStrings: string[]; + remainingWord: string; +} + +const breakString: ( + word: string, + maxWidth: number, + hyphenCharacter: string, + config: WrapLabelConfig +) => BreakStringOutput = memoize( + ( + word: string, + maxWidth: number, + hyphenCharacter = '-', + config: WrapLabelConfig + ): BreakStringOutput => { config = Object.assign( { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0 }, config ); - const characters = word.split(''); - const lines = []; + const characters = [...word]; + const lines: string[] = []; let currentLine = ''; characters.forEach((character, index) => { const nextLine = `${currentLine}${character}`; @@ -607,43 +657,62 @@ const breakString = memoize( * * If the wrapped text text has greater height, we extend the height, so it's value won't overflow. * - * @param {any} text The text to measure - * @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the + * @param text - The text to measure + * @param config - The config for fontSize, fontFamily, and fontWeight all impacting the * resulting size - * @returns {any} - The height for the given text + * @returns The height for the given text */ -export const calculateTextHeight = function (text, config) { +export function calculateTextHeight( + text: Parameters[0], + config: Parameters[1] +): ReturnType['height'] { config = Object.assign( { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 }, config ); return calculateTextDimensions(text, config).height; -}; +} /** * This calculates the width of the given text, font size and family. * - * @param {any} text - The text to calculate the width of - * @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the + * @param text - The text to calculate the width of + * @param config - The config for fontSize, fontFamily, and fontWeight all impacting the * resulting size - * @returns {any} - The width for the given text + * @returns The width for the given text */ -export const calculateTextWidth = function (text, config) { +export function calculateTextWidth( + text: Parameters[0], + config: Parameters[1] +): ReturnType['width'] { config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); return calculateTextDimensions(text, config).width; -}; +} +interface TextDimensionConfig { + fontSize?: number; + fontWeight?: number; + fontFamily?: string; +} +interface TextDimensions { + width: number; + height: number; + lineHeight?: number; +} /** * This calculates the dimensions of the given text, font size, font family, font weight, and * margins. * - * @param {any} text - The text to calculate the width of - * @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting + * @param text - The text to calculate the width of + * @param config - The config for fontSize, fontFamily, fontWeight, and margin all impacting * the resulting size - * @returns - The width for the given text + * @returns The dimensions for the given text */ -export const calculateTextDimensions = memoize( - function (text, config) { +export const calculateTextDimensions: ( + text: string, + config: TextDimensionConfig +) => TextDimensions = memoize( + (text: string, config: TextDimensionConfig): TextDimensions => { config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config); const { fontSize, fontFamily, fontWeight } = config; if (!text) { @@ -712,7 +781,9 @@ export const initIdGenerator = class iterator { } next() { - if (!this.deterministic) return Date.now(); + if (!this.deterministic) { + return Date.now(); + } return this.count++; } @@ -723,10 +794,10 @@ let decoder; /** * Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js} * - * @param {string} html HTML as a string - * @returns {string} Unescaped HTML + * @param html - HTML as a string + * @returns Unescaped HTML */ -export const entityDecode = function (html) { +export const entityDecode = function (html: string): string { decoder = decoder || document.createElement('div'); // Escape HTML before decoding for HTML Entities html = escape(html).replace(/%26/g, '&').replace(/%23/g, '#').replace(/%3B/g, ';'); @@ -738,9 +809,9 @@ export const entityDecode = function (html) { /** * Sanitizes directive objects * - * @param {object} args Directive's JSON + * @param args - Directive's JSON */ -export const directiveSanitizer = (args) => { +export const directiveSanitizer = (args: any) => { log.debug('directiveSanitizer called with', args); if (typeof args === 'object') { // check for array @@ -750,34 +821,34 @@ export const directiveSanitizer = (args) => { // This is an object Object.keys(args).forEach((key) => { log.debug('Checking key', key); - if (key.indexOf('__') === 0) { + if (key.startsWith('__')) { log.debug('sanitize deleting __ option', key); delete args[key]; } - if (key.indexOf('proto') >= 0) { + if (key.includes('proto')) { log.debug('sanitize deleting proto option', key); delete args[key]; } - if (key.indexOf('constr') >= 0) { + if (key.includes('constr')) { log.debug('sanitize deleting constr option', key); delete args[key]; } - if (key.indexOf('themeCSS') >= 0) { + if (key.includes('themeCSS')) { log.debug('sanitizing themeCss option'); args[key] = sanitizeCss(args[key]); } - if (key.indexOf('fontFamily') >= 0) { + if (key.includes('fontFamily')) { log.debug('sanitizing fontFamily option'); args[key] = sanitizeCss(args[key]); } - if (key.indexOf('altFontFamily') >= 0) { + if (key.includes('altFontFamily')) { log.debug('sanitizing altFontFamily option'); args[key] = sanitizeCss(args[key]); } - if (configKeys.indexOf(key) < 0) { + if (!configKeys.includes(key)) { log.debug('sanitize deleting option', key); delete args[key]; } else { @@ -791,10 +862,9 @@ export const directiveSanitizer = (args) => { } if (args.themeVariables) { const kArr = Object.keys(args.themeVariables); - for (let i = 0; i < kArr.length; i++) { - const k = kArr[i]; + for (const k of kArr) { const val = args.themeVariables[k]; - if (val && val.match && !val.match(/^[a-zA-Z0-9#,";()%. ]+$/)) { + if (val && val.match && !val.match(/^[\d "#%(),.;A-Za-z]+$/)) { args.themeVariables[k] = ''; } } @@ -805,13 +875,13 @@ export const sanitizeCss = (str) => { let startCnt = 0; let endCnt = 0; - for (let i = 0; i < str.length; i++) { + for (const element of str) { if (startCnt < endCnt) { return '{ /* ERROR: Unbalanced CSS */ }'; } - if (str[i] === '{') { + if (element === '{') { startCnt++; - } else if (str[i] === '}') { + } else if (element === '}') { endCnt++; } } @@ -825,19 +895,49 @@ export const sanitizeCss = (str) => { export interface DetailedError { str: string; hash: any; + error?: any; + message?: string; } -/** @param error */ +/** @param error - The error to check */ export function isDetailedError(error: unknown): error is DetailedError { return 'str' in error; } -/** @param error */ +/** @param error - The error to convert to an error message */ export function getErrorMessage(error: unknown): string { - if (error instanceof Error) return error.message; + if (error instanceof Error) { + return error.message; + } return String(error); } +/** + * Appends element with the given title, centered. + * + * @param parent - d3 svg object to append title to + * @param cssClass - CSS class for the element containing the title + * @param titleTopMargin - Margin in pixels between title and rest of the graph + * @param title - The title. If empty, returns immediately. + */ +export const insertTitle = ( + parent, + cssClass: string, + titleTopMargin: number, + title?: string +): void => { + if (!title) { + return; + } + const bounds = parent.node().getBBox(); + parent + .append('text') + .text(title) + .attr('x', bounds.x + bounds.width / 2) + .attr('y', -titleTopMargin) + .attr('class', cssClass); +}; + export default { assignWithDepth, wrapLabel, @@ -860,4 +960,5 @@ export default { initIdGenerator: initIdGenerator, directiveSanitizer, sanitizeCss, + insertTitle, }; diff --git a/packages/mermaid/typedoc.json b/packages/mermaid/typedoc.json new file mode 100644 index 000000000..971f6d562 --- /dev/null +++ b/packages/mermaid/typedoc.json @@ -0,0 +1,11 @@ +{ + "plugin": ["typedoc-plugin-markdown"], + "readme": "none", + "githubPages": false, + "sourceLinkTemplate": "https://github.com/mermaid-js/mermaid/blob/{gitRevision}/{path}#L{line}", + "gitRevision": "master", + "out": "src/docs/config/setup", + "entryPointStrategy": "expand", + "hideBreadcrumbs": true, + "hideInPageTOC": true +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37c6a24c9..55d775801 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,297 +1,549 @@ -lockfileVersion: 5.4 - -overrides: - d3: ^7.0.0 +lockfileVersion: 5.4-inlineSpecifiers importers: .: - specifiers: - '@applitools/eyes-cypress': ^3.25.7 - '@braintree/sanitize-url': ^6.0.0 - '@commitlint/cli': ^17.1.2 - '@commitlint/config-conventional': ^17.0.0 - '@types/d3': ^7.4.0 - '@types/dompurify': ^2.3.4 - '@types/eslint': ^8.4.6 - '@types/express': ^4.17.13 - '@types/jsdom': ^20.0.0 - '@types/lodash': ^4.14.185 - '@types/node': ^18.7.21 - '@types/prettier': ^2.7.1 - '@types/stylis': ^4.0.2 - '@types/uuid': ^8.3.4 - '@typescript-eslint/eslint-plugin': ^5.37.0 - '@typescript-eslint/parser': ^5.37.0 - '@vitest/coverage-c8': ^0.23.2 - '@vitest/ui': ^0.23.2 - concurrently: ^7.4.0 - coveralls: ^3.1.1 - cypress: ^10.0.0 - cypress-image-snapshot: ^4.0.1 - d3: ^7.0.0 - dagre: ^0.8.5 - dagre-d3: ^0.6.4 - documentation: 13.2.0 - dompurify: 2.4.0 - eslint: ^8.24.0 - eslint-config-prettier: ^8.5.0 - eslint-plugin-cypress: ^2.12.1 - eslint-plugin-html: ^7.1.0 - eslint-plugin-jest: ^27.0.4 - eslint-plugin-jsdoc: ^39.3.6 - eslint-plugin-json: ^3.1.0 - eslint-plugin-markdown: ^3.0.0 - express: ^4.18.1 - fast-clone: ^1.5.13 - globby: ^13.1.2 - graphlib: ^2.1.8 - husky: ^8.0.0 - identity-obj-proxy: ^3.0.0 - jest: 29.x - jison: ^0.4.18 - jsdom: ^20.0.0 - khroma: ^2.0.0 - lint-staged: ^13.0.0 - lodash: ^4.17.21 - moment: ^2.23.0 - moment-mini: ^2.24.0 - non-layered-tidy-tree-layout: ^2.0.2 - path-browserify: ^1.0.1 - prettier: ^2.7.1 - prettier-plugin-jsdoc: ^0.4.2 - remark: ^14.0.2 - rimraf: ^3.0.2 - rollup: ^2.79.1 - start-server-and-test: ^1.12.6 - stylis: ^4.1.2 - ts-node: ^10.9.1 - typescript: ^4.8.3 - unist-util-flatmap: ^1.0.0 - uuid: ^9.0.0 - vite: ^3.0.9 - vitest: ^0.23.1 - dependencies: - '@braintree/sanitize-url': 6.0.0 - '@types/node': 18.7.21 - '@types/uuid': 8.3.4 - d3: 7.6.1 - dagre: 0.8.5 - dagre-d3: 0.6.4 - dompurify: 2.4.0 - fast-clone: 1.5.13 - graphlib: 2.1.8 - khroma: 2.0.0 - lodash: 4.17.21 - moment-mini: 2.29.4 - non-layered-tidy-tree-layout: 2.0.2 - rollup: 2.79.1 - stylis: 4.1.2 - uuid: 9.0.0 devDependencies: - '@applitools/eyes-cypress': 3.27.1 - '@commitlint/cli': 17.1.2 - '@commitlint/config-conventional': 17.1.0 - '@types/d3': 7.4.0 - '@types/dompurify': 2.3.4 - '@types/eslint': 8.4.6 - '@types/express': 4.17.14 - '@types/jsdom': 20.0.0 - '@types/lodash': 4.14.185 - '@types/prettier': 2.7.1 - '@types/stylis': 4.0.2 - '@typescript-eslint/eslint-plugin': 5.38.0_4gkcvl6qsi23tqqawfqgcwtp54 - '@typescript-eslint/parser': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku - '@vitest/coverage-c8': 0.23.4_y2hohvmcqnhseytaw4yjcnsnkm - '@vitest/ui': 0.23.4 - concurrently: 7.4.0 - coveralls: 3.1.1 - cypress: 10.8.0 - cypress-image-snapshot: 4.0.1_cypress@10.8.0+jest@29.1.1 - documentation: 13.2.0 - eslint: 8.24.0 - eslint-config-prettier: 8.5.0_eslint@8.24.0 - eslint-plugin-cypress: 2.12.1_eslint@8.24.0 - eslint-plugin-html: 7.1.0 - eslint-plugin-jest: 27.0.4_zkp6l2tlaisogzmthlfexujswu - eslint-plugin-jsdoc: 39.3.6_eslint@8.24.0 - eslint-plugin-json: 3.1.0 - eslint-plugin-markdown: 3.0.0_eslint@8.24.0 - express: 4.18.1 - globby: 13.1.2 - husky: 8.0.1 - identity-obj-proxy: 3.0.0 - jest: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq - jison: 0.4.18 - jsdom: 20.0.0 - lint-staged: 13.0.3 - moment: 2.29.4 - path-browserify: 1.0.1 - prettier: 2.7.1 - prettier-plugin-jsdoc: 0.4.2_prettier@2.7.1 - remark: 14.0.2 - rimraf: 3.0.2 - start-server-and-test: 1.14.0 - ts-node: 10.9.1_ke6ijd35va4xbeayrnhu4zwagm - typescript: 4.8.3 - unist-util-flatmap: 1.0.0 - vite: 3.1.3 - vitest: 0.23.4_y2hohvmcqnhseytaw4yjcnsnkm + '@applitools/eyes-cypress': + specifier: ^3.27.6 + version: 3.27.6 + '@commitlint/cli': + specifier: ^17.2.0 + version: 17.2.0 + '@commitlint/config-conventional': + specifier: ^17.2.0 + version: 17.2.0 + '@cspell/eslint-plugin': + specifier: ^6.14.2 + version: 6.14.2 + '@types/eslint': + specifier: ^8.4.10 + version: 8.4.10 + '@types/express': + specifier: ^4.17.14 + version: 4.17.14 + '@types/js-yaml': + specifier: ^4.0.5 + version: 4.0.5 + '@types/jsdom': + specifier: ^20.0.1 + version: 20.0.1 + '@types/lodash': + specifier: ^4.14.188 + version: 4.14.188 + '@types/mdast': + specifier: ^3.0.10 + version: 3.0.10 + '@types/node': + specifier: ^18.11.9 + version: 18.11.9 + '@types/prettier': + specifier: ^2.7.1 + version: 2.7.1 + '@types/rollup-plugin-visualizer': + specifier: ^4.2.1 + version: 4.2.1 + '@typescript-eslint/eslint-plugin': + specifier: ^5.42.1 + version: 5.42.1_2udltptbznfmezdozpdoa2aemq + '@typescript-eslint/parser': + specifier: ^5.42.1 + version: 5.42.1_rmayb2veg2btbq6mbmnyivgasy + '@vitest/coverage-c8': + specifier: ^0.25.1 + version: 0.25.1_oullksb5ic6y72oh2wekoaiuii + '@vitest/ui': + specifier: ^0.25.1 + version: 0.25.1 + concurrently: + specifier: ^7.5.0 + version: 7.5.0 + coveralls: + specifier: ^3.1.1 + version: 3.1.1 + cypress: + specifier: ^10.11.0 + version: 10.11.0 + cypress-image-snapshot: + specifier: ^4.0.1 + version: 4.0.1_bg25yee4qeg7mpleuvd346a3tq + esbuild: + specifier: ^0.15.13 + version: 0.15.13 + eslint: + specifier: ^8.27.0 + version: 8.27.0 + eslint-config-prettier: + specifier: ^8.5.0 + version: 8.5.0_eslint@8.27.0 + eslint-plugin-cypress: + specifier: ^2.12.1 + version: 2.12.1_eslint@8.27.0 + eslint-plugin-html: + specifier: ^7.1.0 + version: 7.1.0 + eslint-plugin-jest: + specifier: ^27.1.5 + version: 27.1.5_kdswgjmqcx7mthqz7ow2zlfevy + eslint-plugin-jsdoc: + specifier: ^39.6.2 + version: 39.6.2_eslint@8.27.0 + eslint-plugin-json: + specifier: ^3.1.0 + version: 3.1.0 + eslint-plugin-lodash: + specifier: ^7.4.0 + version: 7.4.0_eslint@8.27.0 + eslint-plugin-markdown: + specifier: ^3.0.0 + version: 3.0.0_eslint@8.27.0 + eslint-plugin-no-only-tests: + specifier: ^3.1.0 + version: 3.1.0 + eslint-plugin-tsdoc: + specifier: ^0.2.17 + version: 0.2.17 + eslint-plugin-unicorn: + specifier: ^45.0.0 + version: 45.0.0_eslint@8.27.0 + express: + specifier: ^4.18.2 + version: 4.18.2 + globby: + specifier: ^13.1.2 + version: 13.1.2 + husky: + specifier: ^8.0.2 + version: 8.0.2 + jest: + specifier: ^29.3.1 + version: 29.3.1_odkjkoia5xunhxkdrka32ib6vi + jison: + specifier: ^0.4.18 + version: 0.4.18 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + jsdom: + specifier: ^20.0.2 + version: 20.0.2 + lint-staged: + specifier: ^13.0.3 + version: 13.0.3 + path-browserify: + specifier: ^1.0.1 + version: 1.0.1 + pnpm: + specifier: ^7.15.0 + version: 7.15.0 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + prettier-plugin-jsdoc: + specifier: ^0.4.2 + version: 0.4.2_prettier@2.7.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + rollup-plugin-visualizer: + specifier: ^5.8.3 + version: 5.8.3 + start-server-and-test: + specifier: ^1.14.0 + version: 1.14.0 + ts-node: + specifier: ^10.9.1 + version: 10.9.1_cbe7ovvae6zqfnmtgctpgpys54 + typescript: + specifier: ^4.8.4 + version: 4.8.4 + vite: + specifier: ^3.2.3 + version: 3.2.3_@types+node@18.11.9 + vitest: + specifier: ^0.25.3 + version: 0.25.3_oullksb5ic6y72oh2wekoaiuii packages/mermaid: - specifiers: - '@applitools/eyes-cypress': ^3.25.7 - '@braintree/sanitize-url': ^6.0.0 - '@commitlint/cli': ^17.1.2 - '@commitlint/config-conventional': ^17.0.0 - '@types/d3': ^7.4.0 - '@types/dompurify': ^2.3.4 - '@types/eslint': ^8.4.6 - '@types/express': ^4.17.13 - '@types/jsdom': ^20.0.0 - '@types/lodash': ^4.14.185 - '@types/prettier': ^2.7.0 - '@types/stylis': ^4.0.2 - '@typescript-eslint/eslint-plugin': ^5.37.0 - '@typescript-eslint/parser': ^5.37.0 - '@vitest/coverage-c8': ^0.23.2 - '@vitest/ui': ^0.23.2 - concurrently: ^7.4.0 - coveralls: ^3.1.1 - cypress: ^10.0.0 - cypress-image-snapshot: ^4.0.1 - d3: ^7.0.0 - dagre: ^0.8.5 - dagre-d3: ^0.6.4 - documentation: 13.2.0 - dompurify: 2.4.0 - esbuild: ^0.15.8 - eslint: ^8.23.1 - eslint-config-prettier: ^8.5.0 - eslint-plugin-cypress: ^2.12.1 - eslint-plugin-html: ^7.1.0 - eslint-plugin-jest: ^27.0.4 - eslint-plugin-jsdoc: ^39.3.6 - eslint-plugin-json: ^3.1.0 - eslint-plugin-markdown: ^3.0.0 - express: ^4.18.1 - fast-clone: ^1.5.13 - globby: ^13.1.2 - graphlib: ^2.1.8 - husky: ^8.0.0 - identity-obj-proxy: ^3.0.0 - jison: ^0.4.18 - js-base64: 3.7.2 - jsdom: ^20.0.0 - khroma: ^2.0.0 - lint-staged: ^13.0.0 - lodash: ^4.17.21 - moment: ^2.23.0 - moment-mini: ^2.24.0 - non-layered-tidy-tree-layout: ^2.0.2 - path-browserify: ^1.0.1 - prettier: ^2.7.1 - prettier-plugin-jsdoc: ^0.4.2 - remark: ^14.0.2 - rimraf: ^3.0.2 - start-server-and-test: ^1.12.6 - stylis: ^4.1.2 - ts-node: ^10.9.1 - typescript: ^4.8.3 - unist-util-flatmap: ^1.0.0 - vitest: ^0.23.1 dependencies: - '@braintree/sanitize-url': 6.0.0 - d3: 7.6.1 - dagre: 0.8.5 - dagre-d3: 0.6.4 - dompurify: 2.4.0 - fast-clone: 1.5.13 - graphlib: 2.1.8 - khroma: 2.0.0 - lodash: 4.17.21 - moment-mini: 2.29.4 - non-layered-tidy-tree-layout: 2.0.2 - stylis: 4.1.2 + '@braintree/sanitize-url': + specifier: ^6.0.0 + version: 6.0.0 + d3: + specifier: ^7.0.0 + version: 7.6.1 + dagre-d3-es: + specifier: 7.0.4 + version: 7.0.4 + dompurify: + specifier: 2.4.1 + version: 2.4.1 + khroma: + specifier: ^2.0.0 + version: 2.0.0 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + moment-mini: + specifier: ^2.24.0 + version: 2.29.4 + non-layered-tidy-tree-layout: + specifier: ^2.0.2 + version: 2.0.2 + stylis: + specifier: ^4.1.2 + version: 4.1.2 + uuid: + specifier: ^9.0.0 + version: 9.0.0 devDependencies: - '@applitools/eyes-cypress': 3.27.1 - '@commitlint/cli': 17.1.2 - '@commitlint/config-conventional': 17.1.0 - '@types/d3': 7.4.0 - '@types/dompurify': 2.3.4 - '@types/eslint': 8.4.6 - '@types/express': 4.17.14 - '@types/jsdom': 20.0.0 - '@types/lodash': 4.14.185 - '@types/prettier': 2.7.0 - '@types/stylis': 4.0.2 - '@typescript-eslint/eslint-plugin': 5.38.0_wsb62dxj2oqwgas4kadjymcmry - '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha - '@vitest/coverage-c8': 0.23.4_y2hohvmcqnhseytaw4yjcnsnkm - '@vitest/ui': 0.23.4 - concurrently: 7.4.0 - coveralls: 3.1.1 - cypress: 10.8.0 - cypress-image-snapshot: 4.0.1_cypress@10.8.0 - documentation: 13.2.0 - esbuild: 0.15.8 - eslint: 8.23.1 - eslint-config-prettier: 8.5.0_eslint@8.23.1 - eslint-plugin-cypress: 2.12.1_eslint@8.23.1 - eslint-plugin-html: 7.1.0 - eslint-plugin-jest: 27.0.4_w7j56xfuh6bbmrubefdaspmpla - eslint-plugin-jsdoc: 39.3.6_eslint@8.23.1 - eslint-plugin-json: 3.1.0 - eslint-plugin-markdown: 3.0.0_eslint@8.23.1 - express: 4.18.1 - globby: 13.1.2 - husky: 8.0.1 - identity-obj-proxy: 3.0.0 - jison: 0.4.18 - js-base64: 3.7.2 - jsdom: 20.0.0 - lint-staged: 13.0.3 - moment: 2.29.4 - path-browserify: 1.0.1 - prettier: 2.7.1 - prettier-plugin-jsdoc: 0.4.2_prettier@2.7.1 - remark: 14.0.2 - rimraf: 3.0.2 - start-server-and-test: 1.14.0 - ts-node: 10.9.1_typescript@4.8.3 - typescript: 4.8.3 - unist-util-flatmap: 1.0.0 - vitest: 0.23.4_y2hohvmcqnhseytaw4yjcnsnkm + '@types/d3': + specifier: ^7.4.0 + version: 7.4.0 + '@types/dompurify': + specifier: ^2.4.0 + version: 2.4.0 + '@types/jsdom': + specifier: ^20.0.1 + version: 20.0.1 + '@types/lodash-es': + specifier: ^4.17.6 + version: 4.17.6 + '@types/micromatch': + specifier: ^4.0.2 + version: 4.0.2 + '@types/prettier': + specifier: ^2.7.1 + version: 2.7.1 + '@types/stylis': + specifier: ^4.0.2 + version: 4.0.2 + '@types/uuid': + specifier: ^8.3.4 + version: 8.3.4 + '@typescript-eslint/eslint-plugin': + specifier: ^5.42.1 + version: 5.42.1_2udltptbznfmezdozpdoa2aemq + '@typescript-eslint/parser': + specifier: ^5.42.1 + version: 5.42.1_rmayb2veg2btbq6mbmnyivgasy + chokidar: + specifier: ^3.5.3 + version: 3.5.3 + concurrently: + specifier: ^7.5.0 + version: 7.5.0 + coveralls: + specifier: ^3.1.1 + version: 3.1.1 + cspell: + specifier: ^6.14.3 + version: 6.14.3 + globby: + specifier: ^13.1.2 + version: 13.1.2 + jison: + specifier: ^0.4.18 + version: 0.4.18 + js-base64: + specifier: ^3.7.2 + version: 3.7.2 + jsdom: + specifier: ^20.0.2 + version: 20.0.2 + micromatch: + specifier: ^4.0.5 + version: 4.0.5 + moment: + specifier: ^2.29.4 + version: 2.29.4 + path-browserify: + specifier: ^1.0.1 + version: 1.0.1 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + remark: + specifier: ^14.0.2 + version: 14.0.2 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + start-server-and-test: + specifier: ^1.14.0 + version: 1.14.0 + typedoc: + specifier: ^0.23.18 + version: 0.23.18_typescript@4.8.4 + typedoc-plugin-markdown: + specifier: ^3.13.6 + version: 3.13.6_typedoc@0.23.18 + typescript: + specifier: ^4.8.4 + version: 4.8.4 + unist-util-flatmap: + specifier: ^1.0.0 + version: 1.0.0 + vitepress: + specifier: ^1.0.0-alpha.28 + version: 1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y + vitepress-plugin-search: + specifier: ^1.0.4-alpha.15 + version: 1.0.4-alpha.15_s3edpouswd4dgoi2en7bdlrp54 packages/mermaid-example-diagram: - specifiers: - concurrently: ^7.4.0 - rimraf: ^3.0.2 devDependencies: - concurrently: 7.4.0 - rimraf: 3.0.2 + concurrently: + specifier: ^7.5.0 + version: 7.5.0 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 packages/mermaid-mindmap: - specifiers: - '@braintree/sanitize-url': ^6.0.0 - concurrently: ^7.4.0 - d3: ^7.0.0 - mermaid: workspace:* - non-layered-tidy-tree-layout: ^2.0.2 - rimraf: ^3.0.2 dependencies: - '@braintree/sanitize-url': 6.0.0 - d3: 7.6.1 - mermaid: link:../mermaid - non-layered-tidy-tree-layout: 2.0.2 + '@braintree/sanitize-url': + specifier: ^6.0.0 + version: 6.0.0 + cytoscape: + specifier: ^3.23.0 + version: 3.23.0 + cytoscape-cose-bilkent: + specifier: ^4.1.0 + version: 4.1.0_cytoscape@3.23.0 + cytoscape-fcose: + specifier: ^2.1.0 + version: 2.1.0_cytoscape@3.23.0 + d3: + specifier: ^7.0.0 + version: 7.6.1 + khroma: + specifier: ^2.0.0 + version: 2.0.0 + non-layered-tidy-tree-layout: + specifier: ^2.0.2 + version: 2.0.2 devDependencies: - concurrently: 7.4.0 - rimraf: 3.0.2 + concurrently: + specifier: ^7.5.0 + version: 7.5.0 + mermaid: + specifier: workspace:* + version: link:../mermaid + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + + tests/webpack: + dependencies: + '@mermaid-js/mermaid-mindmap': + specifier: workspace:* + version: link:../../packages/mermaid-mindmap + mermaid: + specifier: workspace:* + version: link:../../packages/mermaid + devDependencies: + webpack: + specifier: ^5.74.0 + version: 5.75.0_webpack-cli@4.10.0 + webpack-cli: + specifier: ^4.10.0 + version: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + webpack-dev-server: + specifier: ^4.11.1 + version: 4.11.1_pda42hcaj7d62cr262fr632kue packages: - /@applitools/dom-capture/11.1.1: - resolution: {integrity: sha512-aUPsS3h/caQryythSjaX4uG23HzTBsnFBfO7BUvuomMdAm3qIHBstIHPCiUSJbXmPBabfqlWm59YKdxC3PTWcw==} + /@algolia/autocomplete-core/1.7.2: + resolution: {integrity: sha512-eclwUDC6qfApNnEfu1uWcL/rudQsn59tjEoUYZYE2JSXZrHLRjBUGMxiCoknobU2Pva8ejb0eRxpIYDtVVqdsw==} + dependencies: + '@algolia/autocomplete-shared': 1.7.2 + dev: true + + /@algolia/autocomplete-preset-algolia/1.7.2_qs6lk5nhygj2o3hj4sf6xnr724: + resolution: {integrity: sha512-+RYEG6B0QiGGfRb2G3MtPfyrl0dALF3cQNTWBzBX6p5o01vCCGTTinAm2UKG3tfc2CnOMAtnPLkzNZyJUpnVJw==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/autocomplete-shared': 1.7.2 + '@algolia/client-search': 4.14.2 + algoliasearch: 4.14.2 + dev: true + + /@algolia/autocomplete-shared/1.7.2: + resolution: {integrity: sha512-QCckjiC7xXHIUaIL3ektBtjJ0w7tTA3iqKcAE/Hjn1lZ5omp7i3Y4e09rAr9ZybqirL7AbxCLLq0Ra5DDPKeug==} + dev: true + + /@algolia/cache-browser-local-storage/4.14.2: + resolution: {integrity: sha512-FRweBkK/ywO+GKYfAWbrepewQsPTIEirhi1BdykX9mxvBPtGNKccYAxvGdDCumU1jL4r3cayio4psfzKMejBlA==} + dependencies: + '@algolia/cache-common': 4.14.2 + dev: true + + /@algolia/cache-common/4.14.2: + resolution: {integrity: sha512-SbvAlG9VqNanCErr44q6lEKD2qoK4XtFNx9Qn8FK26ePCI8I9yU7pYB+eM/cZdS9SzQCRJBbHUumVr4bsQ4uxg==} + dev: true + + /@algolia/cache-in-memory/4.14.2: + resolution: {integrity: sha512-HrOukWoop9XB/VFojPv1R5SVXowgI56T9pmezd/djh2JnVN/vXswhXV51RKy4nCpqxyHt/aGFSq2qkDvj6KiuQ==} + dependencies: + '@algolia/cache-common': 4.14.2 + dev: true + + /@algolia/client-account/4.14.2: + resolution: {integrity: sha512-WHtriQqGyibbb/Rx71YY43T0cXqyelEU0lB2QMBRXvD2X0iyeGl4qMxocgEIcbHyK7uqE7hKgjT8aBrHqhgc1w==} + dependencies: + '@algolia/client-common': 4.14.2 + '@algolia/client-search': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + + /@algolia/client-analytics/4.14.2: + resolution: {integrity: sha512-yBvBv2mw+HX5a+aeR0dkvUbFZsiC4FKSnfqk9rrfX+QrlNOKEhCG0tJzjiOggRW4EcNqRmaTULIYvIzQVL2KYQ==} + dependencies: + '@algolia/client-common': 4.14.2 + '@algolia/client-search': 4.14.2 + '@algolia/requester-common': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + + /@algolia/client-common/4.14.2: + resolution: {integrity: sha512-43o4fslNLcktgtDMVaT5XwlzsDPzlqvqesRi4MjQz2x4/Sxm7zYg5LRYFol1BIhG6EwxKvSUq8HcC/KxJu3J0Q==} + dependencies: + '@algolia/requester-common': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + + /@algolia/client-personalization/4.14.2: + resolution: {integrity: sha512-ACCoLi0cL8CBZ1W/2juehSltrw2iqsQBnfiu/Rbl9W2yE6o2ZUb97+sqN/jBqYNQBS+o0ekTMKNkQjHHAcEXNw==} + dependencies: + '@algolia/client-common': 4.14.2 + '@algolia/requester-common': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + + /@algolia/client-search/4.14.2: + resolution: {integrity: sha512-L5zScdOmcZ6NGiVbLKTvP02UbxZ0njd5Vq9nJAmPFtjffUSOGEp11BmD2oMJ5QvARgx2XbX4KzTTNS5ECYIMWw==} + dependencies: + '@algolia/client-common': 4.14.2 + '@algolia/requester-common': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + + /@algolia/logger-common/4.14.2: + resolution: {integrity: sha512-/JGlYvdV++IcMHBnVFsqEisTiOeEr6cUJtpjz8zc0A9c31JrtLm318Njc72p14Pnkw3A/5lHHh+QxpJ6WFTmsA==} + dev: true + + /@algolia/logger-console/4.14.2: + resolution: {integrity: sha512-8S2PlpdshbkwlLCSAB5f8c91xyc84VM9Ar9EdfE9UmX+NrKNYnWR1maXXVDQQoto07G1Ol/tYFnFVhUZq0xV/g==} + dependencies: + '@algolia/logger-common': 4.14.2 + dev: true + + /@algolia/requester-browser-xhr/4.14.2: + resolution: {integrity: sha512-CEh//xYz/WfxHFh7pcMjQNWgpl4wFB85lUMRyVwaDPibNzQRVcV33YS+63fShFWc2+42YEipFGH2iPzlpszmDw==} + dependencies: + '@algolia/requester-common': 4.14.2 + dev: true + + /@algolia/requester-common/4.14.2: + resolution: {integrity: sha512-73YQsBOKa5fvVV3My7iZHu1sUqmjjfs9TteFWwPwDmnad7T0VTCopttcsM3OjLxZFtBnX61Xxl2T2gmG2O4ehg==} + dev: true + + /@algolia/requester-node-http/4.14.2: + resolution: {integrity: sha512-oDbb02kd1o5GTEld4pETlPZLY0e+gOSWjWMJHWTgDXbv9rm/o2cF7japO6Vj1ENnrqWvLBmW1OzV9g6FUFhFXg==} + dependencies: + '@algolia/requester-common': 4.14.2 + dev: true + + /@algolia/transporter/4.14.2: + resolution: {integrity: sha512-t89dfQb2T9MFQHidjHcfhh6iGMNwvuKUvojAj+JsrHAGbuSy7yE4BylhLX6R0Q1xYRoC4Vvv+O5qIw/LdnQfsQ==} + dependencies: + '@algolia/cache-common': 4.14.2 + '@algolia/logger-common': 4.14.2 + '@algolia/requester-common': 4.14.2 + dev: true + + /@applitools/core-base/1.1.7: + resolution: {integrity: sha512-jxiRS7pQ9Q6deXeDa/mIACL/7S7ZxIOms49WSZGhUjb+1bfKEsH6+kLZKy5wUDHrUWRqPdILkLKWgQ0rLnKmFA==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/image': 1.0.4 + '@applitools/logger': 1.1.27 + '@applitools/req': 1.1.12 + '@applitools/utils': 1.3.13 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@applitools/core-base/1.1.8: + resolution: {integrity: sha512-h5bm1uJmpn5NVagFnLpoXWEKfLtBBmdQsgtOwYAmbWGImMNsexEnki1JPPo4yTn6KN1sdGE1ShYo2+YzbQPgKA==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/image': 1.0.5 + '@applitools/logger': 1.1.27 + '@applitools/req': 1.1.12 + '@applitools/utils': 1.3.13 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@applitools/core/1.2.4: + resolution: {integrity: sha512-BFbmUn39XFEVKHCb/bBXFZVAb46hOl4D/6VRnC5ey5tNTdriI35/l0jWpuBnYHU6LgK+5AvG70SUTKqiFJDZPQ==} + engines: {node: '>=12.13.0'} + hasBin: true + dependencies: + '@applitools/core-base': 1.1.7 + '@applitools/dom-capture': 11.2.0 + '@applitools/dom-snapshot': 4.7.0 + '@applitools/driver': 1.11.0 + '@applitools/logger': 1.1.27 + '@applitools/nml-client': 1.3.5 + '@applitools/req': 1.1.12 + '@applitools/screenshoter': 3.7.0 + '@applitools/snippets': 2.4.5 + '@applitools/ufg-client': 1.1.2 + '@applitools/utils': 1.3.13 + abort-controller: 3.0.0 + throat: 6.0.1 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /@applitools/core/1.2.7: + resolution: {integrity: sha512-cVH60tV3Uw1kIbml6IMPtwHRtJTRP5ySs2GRvDvHwq+dJNEddyIwJUwjHOI/xYYgc9rQRZOmM5Z4mzZXLjtgyw==} + engines: {node: '>=12.13.0'} + hasBin: true + dependencies: + '@applitools/core-base': 1.1.8 + '@applitools/dom-capture': 11.2.0 + '@applitools/dom-snapshot': 4.7.0 + '@applitools/driver': 1.11.1 + '@applitools/logger': 1.1.27 + '@applitools/nml-client': 1.3.5 + '@applitools/req': 1.1.12 + '@applitools/screenshoter': 3.7.2 + '@applitools/snippets': 2.4.6 + '@applitools/ufg-client': 1.1.2 + '@applitools/utils': 1.3.13 + abort-controller: 3.0.0 + throat: 6.0.1 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /@applitools/dom-capture/11.2.0: + resolution: {integrity: sha512-zFfYgvdXq5oTpLuYvOJdkh7jsbAxajOpD67pVoKc27lKwE0CGaM9I0Uf+qGh7GYtY93qyzMWBzqC7C8JlSK1gA==} engines: {node: '>=8.9.0'} dependencies: '@applitools/dom-shared': 1.0.5 @@ -303,38 +555,48 @@ packages: engines: {node: '>=8.9.0'} dev: true - /@applitools/dom-shared/1.0.8: - resolution: {integrity: sha512-HQtYfFvtlPuE9ZShBamtW1LGW2Qq4HxjQx5nF7KiNvrRTlf5/e+AWpZhXCTVEhVkAcSNs/7xR2WvumOUd+usxg==} + /@applitools/dom-shared/1.0.9: + resolution: {integrity: sha512-u6nRHBklRAaODILm0HRluE0IAwrnjs8AMNRBFxHThKGt4qpbkhnwazGMr4zDu3WCBjr/sA31kekUqNl0Jx3YeQ==} engines: {node: '>=8.9.0'} dev: true - /@applitools/dom-snapshot/4.6.2: - resolution: {integrity: sha512-8XFbsIl154VK3rqNhHbSzcYDNLJ8QEgHzWht5cM0WhScWVokXUfL+kDmqjLIMZ47VgP3XXxk0rgX5QOs2TZx8Q==} + /@applitools/dom-snapshot/4.7.0: + resolution: {integrity: sha512-exLRB2dTLiqD8i5oOK/QyfNMSLramVF5CFYNI29WWQjbXkIpCGOomGA8/xL+sYiC53jjx3Y9u6jHtlkb5ASJAQ==} engines: {node: '>=8.9.0'} dependencies: - '@applitools/dom-shared': 1.0.8 + '@applitools/dom-shared': 1.0.9 '@applitools/functional-commons': 1.6.0 css-tree: 1.0.0-alpha.39 pako: 1.0.11 dev: true - /@applitools/driver/1.9.20: - resolution: {integrity: sha512-yrVydj5ukcBzADVTyrqEJ9rV2GauUOgC0NvXupvT+3qZSkwGumFb6SxlP5q39jy6/1EmRL9Szl1y9/DbwZ9OdQ==} + /@applitools/driver/1.11.0: + resolution: {integrity: sha512-yNo4ljkk5C2wJ7foqENoIgtlbW3/RpDYBT5UCjq5yTK/xfnvAlh+zUmnqGJ43w8PZj4IH7E8xLRVBVIq2Mv9oQ==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 1.1.15 + '@applitools/logger': 1.1.27 '@applitools/snippets': 2.4.5 - '@applitools/types': 1.5.8 - '@applitools/utils': 1.3.10 + '@applitools/utils': 1.3.13 + semver: 7.3.7 dev: true - /@applitools/execution-grid-client/1.1.23: - resolution: {integrity: sha512-9J66rP3HYpI10pLH+wbMWr6BAcCuaGIskSDJyitvfS8hc2UyWdpVsAIHdkmivvTEpu3f+VaLKlhINRYlCJRJpQ==} + /@applitools/driver/1.11.1: + resolution: {integrity: sha512-HFkbEeTaBI+k5RMQFM6RjaIRCvLOrVx4UUDehnSlyfAwZIN/RMuxMcAQaiU5ZdNPf3K/+TtNjtmJoXuG8veEcQ==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/logger': 1.1.27 + '@applitools/snippets': 2.4.6 + '@applitools/utils': 1.3.13 + semver: 7.3.7 + dev: true + + /@applitools/execution-grid-client/1.1.30: + resolution: {integrity: sha512-LoX0ZcNDZZV4aD6bpldfOTk94tNznRcIZPAVRRrKiqQJWJnDPP661EGxykXsfVnluCHaOGmbDPH6bfJGdDfUuQ==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/logger': 1.1.15 - '@applitools/utils': 1.3.10 + '@applitools/logger': 1.1.27 + '@applitools/utils': 1.3.13 abort-controller: 3.0.0 node-fetch: 2.6.7 proxy-agent: 5.0.0 @@ -345,77 +607,74 @@ packages: - supports-color dev: true - /@applitools/eyes-api/1.7.5: - resolution: {integrity: sha512-wvFHjPFAVRSCCUg3zEr8HNoRS8lChnm9TwYI/+qjo91eNM+nVSEtPE6tb2GcdUbDqz0zpnCi8N3Mi2TulAZj2w==} + /@applitools/eyes-api/1.9.1: + resolution: {integrity: sha512-P/42YMcV8SbdZFXEph+Q37tMngIJv0jSC2S1QDp09/zi0V1z81yyAm8zK36PU0h0JTYeZxSs/T3BRhfitpzAIg==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 1.1.15 - '@applitools/types': 1.5.8 - '@applitools/utils': 1.3.10 - dev: true - - /@applitools/eyes-cypress/3.27.1: - resolution: {integrity: sha512-QtQawBi0B16ClPcyFEyvd8+3VKoZnJcj2UX41U5gnycQvidvJCyruFJlmuL9OnCBgpA17U4y9NnRceeHsywhqQ==} - engines: {node: '>=12.13.0'} - hasBin: true - dependencies: - '@applitools/eyes-api': 1.7.5 - '@applitools/eyes-universal': 2.10.3 - '@applitools/functional-commons': 1.6.0 - '@applitools/logger': 1.1.15 - '@applitools/visual-grid-client': 15.13.13 - chalk: 3.0.0 - uuid: 8.3.2 - ws: 8.5.0 + '@applitools/core': 1.2.4 + '@applitools/logger': 1.1.27 + '@applitools/utils': 1.3.13 transitivePeerDependencies: - bufferutil - - debug - encoding - supports-color - utf-8-validate dev: true - /@applitools/eyes-sdk-core/13.8.19: - resolution: {integrity: sha512-brijRwys0kNyGdVictyJPGdqS+6iE3G0gwYHnzBZWvP7ryh6FeIwDbLxyc43UVpmNJPKAToVZ50J+2C/S6E3pQ==} + /@applitools/eyes-cypress/3.27.6: + resolution: {integrity: sha512-2FpWKQ7rVhrr94Z8DjmJ8kD3f71aYahvTpT3dJyjfVKV8GxwAYAb/qrq6gAUnItaaoB2PgLHbIsqpOpRPki1tQ==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/dom-capture': 11.1.1 - '@applitools/dom-snapshot': 4.6.2 - '@applitools/driver': 1.9.20 - '@applitools/execution-grid-client': 1.1.23 - '@applitools/isomorphic-fetch': 3.0.0 - '@applitools/logger': 1.1.15 - '@applitools/screenshoter': 3.4.14 - '@applitools/snippets': 2.4.5 - '@applitools/types': 1.5.8 - '@applitools/utils': 1.3.10 - axios: 0.26.0 + '@applitools/core': 1.2.7 + '@applitools/eyes-api': 1.9.1 + '@applitools/eyes-universal': 2.16.9 + '@applitools/functional-commons': 1.6.0 + '@applitools/logger': 1.1.27 chalk: 3.0.0 - tunnel: 0.0.6 + semver: 7.3.8 + uuid: 8.3.2 + which: 2.0.2 + ws: 8.5.0 transitivePeerDependencies: - - debug + - bufferutil - encoding - supports-color + - utf-8-validate dev: true - /@applitools/eyes-universal/2.10.3: - resolution: {integrity: sha512-z/1N9RaDakfosQfGTEwFgky0DwPjpw4bCILYx1Te4vlOywCDGSD9KrJmmMqe2YkO2wgqi61uNvQvrBDePKvmHQ==} + /@applitools/eyes-sdk-core/13.11.15: + resolution: {integrity: sha512-oN2yTzFsuRMpmBpgzzqiUGRkezIez1JwQFRqqa6dsxUUBWE2IWp52MqJV5NRGHt9Sdh8q4+M6Hk6h8sVHE3LGg==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/core': 1.2.7 + '@applitools/driver': 1.11.1 + '@applitools/execution-grid-client': 1.1.30 + '@applitools/utils': 1.3.13 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /@applitools/eyes-universal/2.16.9: + resolution: {integrity: sha512-D8MeOLoBETyg0oPxkaim3taiKWo6XMILTSAX+rWQHz0X7u+JRuCBLZu0WFlQPLTo7ndLiVyo2BpbBy9KIp5haA==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/execution-grid-client': 1.1.23 - '@applitools/eyes-sdk-core': 13.8.19 - '@applitools/logger': 1.1.15 - '@applitools/utils': 1.3.10 - '@applitools/visual-grid-client': 15.13.13 + '@applitools/core': 1.2.7 + '@applitools/driver': 1.11.1 + '@applitools/execution-grid-client': 1.1.30 + '@applitools/eyes-sdk-core': 13.11.15 + '@applitools/logger': 1.1.27 + '@applitools/utils': 1.3.13 proxy-agent: 5.0.0 webdriver: 7.16.11 ws: 7.4.6 yargs: 17.4.1 transitivePeerDependencies: - bufferutil - - debug - encoding - supports-color - utf-8-validate @@ -426,28 +685,22 @@ packages: engines: {node: '>=8.0.0'} dev: true - /@applitools/http-commons/2.4.7: - resolution: {integrity: sha512-fsq8ULh70/htb9oHSMTkibMR7AiB+ScraYfQw4H7Sq7JfbFnlefSK0c6ZGfSrjJQx79GRfjrqQYtz59s5lxkcw==} - engines: {node: '>=8.0.0'} + /@applitools/image/1.0.4: + resolution: {integrity: sha512-eNr/fa+loGz1hrgwv/NKuVP13uRyfRUPFyCU8EtTdSWuGFJXIqwhtQWCFCokX1EXnhoCyGfFBAzWgW9StqTGfQ==} + engines: {node: '>=12.13.0'} dependencies: - '@applitools/functional-commons': 1.6.0 - '@applitools/monitoring-commons': 1.0.19 - agentkeepalive: 4.2.1 - debug: 4.3.4 - lodash.merge: 4.6.2 - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - - supports-color + '@applitools/utils': 1.3.13 + jpeg-js: 0.4.4 + png-async: 0.9.4 dev: true - /@applitools/isomorphic-fetch/3.0.0: - resolution: {integrity: sha512-7rutaN/2M5wYjOIOTKS/Zuc1Na90fJNEAqvo/jCxt7nSD1kYscHV3aCk9t7RD59gmzLMvUTIxFbjl4RUMV8qfg==} + /@applitools/image/1.0.5: + resolution: {integrity: sha512-khv0fkjaoe0j/btEog8K/sqC2ULss+bkkHQQz80AOxnW/ixq5C4eQhTNzVRZ9/X7EDi7XsskvAXsi9RseIRnBw==} + engines: {node: '>=12.13.0'} dependencies: - node-fetch: 2.6.7 - whatwg-fetch: 3.6.2 - transitivePeerDependencies: - - encoding + '@applitools/utils': 1.3.13 + jpeg-js: 0.4.4 + png-async: 0.9.4 dev: true /@applitools/jsdom/1.0.4: @@ -479,7 +732,7 @@ packages: whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 10.0.0 - ws: 8.5.0 + ws: 8.9.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -487,30 +740,60 @@ packages: - utf-8-validate dev: true - /@applitools/logger/1.1.15: - resolution: {integrity: sha512-2SNbINnxvGxy8G5TXIZHhXWqWBFFn0o/+4ZP57VvohPG8AF4wqXBO3H93LZMMpDz/4prND0bBLqK3XFLY4ppTQ==} + /@applitools/logger/1.1.27: + resolution: {integrity: sha512-lwKCNhuMfLkqxfwYhLalDg2JZNgNj6rEgD8LnozsQdfxqVXThrJb/fkdSaSeUwnF+ljJyR7fnPy+p742p66U0Q==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/utils': 1.3.10 + '@applitools/utils': 1.3.13 chalk: 4.1.2 dev: true - /@applitools/monitoring-commons/1.0.19: - resolution: {integrity: sha512-rzEOvGoiEF4KnK0PJ9I0btdwnaNlIPLYhjF1vTEG15PoucbbKpix9fYusxWlDG7kMiZya8ZycVPc0woVlNaHRQ==} - engines: {node: '>=8.0.0'} + /@applitools/nml-client/1.3.5: + resolution: {integrity: sha512-MW1kB5AGe5l8HZ5GMkVhTm6XMndeIADmed37WrW3obD3FrmBGQLLj04GP6J7czLTeGjeh7QojvuAEvQUGFV5MQ==} + engines: {node: '>=12.13.0'} dependencies: - debug: 4.3.4 + '@applitools/logger': 1.1.27 + '@applitools/req': 1.1.12 + '@applitools/utils': 1.3.13 transitivePeerDependencies: + - encoding - supports-color dev: true - /@applitools/screenshoter/3.4.14: - resolution: {integrity: sha512-vdaHxzSobJzujyXENSuVybYyOfBWZlDb6OwVzRsiJxpwuN9L5VtOu30kuvxAXzycHMfa+8vLgO2pHnU6Vp/MiQ==} + /@applitools/req/1.1.12: + resolution: {integrity: sha512-eA8gsbqMxGEvW1KHb6P/AZ+IXlkxhf+Best683z9uo6O/wPQbg+B/20GoUpbUgpqWDQZmdhZDUb/RvxKwSl/PA==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 1.1.15 + '@applitools/utils': 1.3.13 + '@types/node-fetch': 2.6.2 + abort-controller: 3.0.0 + node-fetch: 2.6.7 + proxy-agent: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@applitools/screenshoter/3.7.0: + resolution: {integrity: sha512-d723TI4InLQi06TpVj4rP+V5OrNL9mFQr+cWv2MOMfQbuAnZETTRzvDyk97e3qoDJHAPjyQuxi81qEaxsFxhOA==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/image': 1.0.4 + '@applitools/logger': 1.1.27 '@applitools/snippets': 2.4.5 - '@applitools/utils': 1.3.10 + '@applitools/utils': 1.3.13 + jpeg-js: 0.4.4 + png-async: 0.9.4 + dev: true + + /@applitools/screenshoter/3.7.2: + resolution: {integrity: sha512-bWtNQeRvdcQBcc+5kAwVBnEQ3DhDncAE853SuJPgpczZkqy9t7Ot8L3kNLbi+210vbWSqpnVGt9tAeLgG/xZdA==} + engines: {node: '>=12.13.0'} + dependencies: + '@applitools/image': 1.0.5 + '@applitools/logger': 1.1.27 + '@applitools/snippets': 2.4.6 + '@applitools/utils': 1.3.13 jpeg-js: 0.4.4 png-async: 0.9.4 dev: true @@ -520,38 +803,34 @@ packages: engines: {node: '>=12.13.0'} dev: true - /@applitools/types/1.5.8: - resolution: {integrity: sha512-trMH32oewkrptYG26IzEbwMW9VG9BJo64bzwx/T4oz6ZfndXGCjwGCFQE4FDE++dRZTjzSF00h2YSzIxPAapeQ==} + /@applitools/snippets/2.4.6: + resolution: {integrity: sha512-hAsAalDxaa1w2RCEx2b35D9XJIGGRlqQKzXEE6/rNr5vMtT0eYye61SST5e2PD7B4F2jJ7jRKrZd7REawoxxmg==} engines: {node: '>=12.13.0'} dev: true - /@applitools/utils/1.3.10: - resolution: {integrity: sha512-CI/5BLB0D/aZn6uL8JJmsErI+TOHCa4Gz5Wi8sJknuPz/V9Ws6jIh9ZCTzvOCDUIp99qLJwD6TSA2BY9aMhCNw==} - engines: {node: '>=12.13.0'} - dev: true - - /@applitools/visual-grid-client/15.13.13: - resolution: {integrity: sha512-3GkzrR0WEcsihRZEgbxXecfBb8Q0U/L7VDNpy/APlw7K54kWPgTal/CYk1NwLDKj9iqpHlFfvDhI0zoeCNrR4A==} + /@applitools/ufg-client/1.1.2: + resolution: {integrity: sha512-yhjlp4QHWVazImfUUr9S9ueQhKstxfI3NNu/SLPPX7lHLOdpdWn7fUZOzTBCs6j914s87r9J9cmsU2gnOO8bOQ==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/eyes-sdk-core': 13.8.19 - '@applitools/functional-commons': 1.6.0 - '@applitools/http-commons': 2.4.7 - '@applitools/isomorphic-fetch': 3.0.0 '@applitools/jsdom': 1.0.4 - '@applitools/logger': 1.1.15 + '@applitools/logger': 1.1.27 + '@applitools/req': 1.1.12 + '@applitools/utils': 1.3.13 abort-controller: 3.0.0 - chalk: 3.0.0 - postcss-value-parser: 4.1.0 - throat: 5.0.0 + postcss-value-parser: 4.2.0 + throat: 6.0.1 transitivePeerDependencies: - bufferutil - - debug - encoding - supports-color - utf-8-validate dev: true + /@applitools/utils/1.3.13: + resolution: {integrity: sha512-UwA1skl9kzK+WrXu7WyX6A4K4TdIFZbDAcFJq2PA5fhmbviAlk4iFJtQjyopYTdY0sSh3VRSsCPr3DsbFa79AA==} + engines: {node: '>=12.13.0'} + dev: true + /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -559,20 +838,15 @@ packages: '@babel/highlight': 7.18.6 dev: true - /@babel/compat-data/7.19.1: - resolution: {integrity: sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==} - engines: {node: '>=6.9.0'} - dev: true - /@babel/core/7.12.3: resolution: {integrity: sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.12.1 + '@babel/generator': 7.19.0 '@babel/helper-module-transforms': 7.19.0 '@babel/helpers': 7.19.0 - '@babel/parser': 7.12.3 + '@babel/parser': 7.19.1 '@babel/template': 7.18.10 '@babel/traverse': 7.19.1 '@babel/types': 7.19.0 @@ -588,14 +862,6 @@ packages: - supports-color dev: true - /@babel/generator/7.12.1: - resolution: {integrity: sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==} - dependencies: - '@babel/types': 7.19.0 - jsesc: 2.5.2 - source-map: 0.5.7 - dev: true - /@babel/generator/7.19.0: resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==} engines: {node: '>=6.9.0'} @@ -605,91 +871,11 @@ packages: jsesc: 2.5.2 dev: true - /@babel/helper-annotate-as-pure/7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.0 - dev: true - - /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: - resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.19.0 - dev: true - - /@babel/helper-compilation-targets/7.19.1_@babel+core@7.12.3: - resolution: {integrity: sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.19.1 - '@babel/core': 7.12.3 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 - semver: 6.3.0 - dev: true - - /@babel/helper-create-class-features-plugin/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-member-expression-to-functions': 7.18.9 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.19.1 - '@babel/helper-split-export-declaration': 7.18.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-create-regexp-features-plugin/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - regexpu-core: 5.2.1 - dev: true - - /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.12.3: - resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} - peerDependencies: - '@babel/core': ^7.4.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helper-environment-visitor/7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-explode-assignable-expression/7.18.6: - resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.0 - dev: true - /@babel/helper-function-name/7.19.0: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} engines: {node: '>=6.9.0'} @@ -705,13 +891,6 @@ packages: '@babel/types': 7.19.0 dev: true - /@babel/helper-member-expression-to-functions/7.18.9: - resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.0 - dev: true - /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} @@ -735,46 +914,11 @@ packages: - supports-color dev: true - /@babel/helper-optimise-call-expression/7.18.6: - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.0 - dev: true - /@babel/helper-plugin-utils/7.19.0: resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-wrap-function': 7.19.0 - '@babel/types': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-replace-supers/7.19.1: - resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-member-expression-to-functions': 7.18.9 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.19.1 - '@babel/types': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helper-simple-access/7.18.6: resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} engines: {node: '>=6.9.0'} @@ -782,13 +926,6 @@ packages: '@babel/types': 7.19.0 dev: true - /@babel/helper-skip-transparent-expression-wrappers/7.18.9: - resolution: {integrity: sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.19.0 - dev: true - /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} @@ -806,23 +943,6 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option/7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-wrap-function/7.19.0: - resolution: {integrity: sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.19.0 - '@babel/template': 7.18.10 - '@babel/traverse': 7.19.1 - '@babel/types': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helpers/7.19.0: resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==} engines: {node: '>=6.9.0'} @@ -843,14 +963,6 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser/7.12.3: - resolution: {integrity: sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.19.0 - dev: true - /@babel/parser/7.19.1: resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==} engines: {node: '>=6.0.0'} @@ -859,297 +971,6 @@ packages: '@babel/types': 7.19.0 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-async-generator-functions/7.19.1_@babel+core@7.12.3: - resolution: {integrity: sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-decorators/7.19.1_@babel+core@7.12.3: - resolution: {integrity: sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-replace-supers': 7.19.1 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/plugin-syntax-decorators': 7.19.0_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-do-expressions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-ddToGCONJhCuL+l4FhtGnKl5ZYCj9fDVFiqiCdQDpeIbVn/NvMeSib+7T1/rk08jRafae4qNiP8OnJyuqlsuYA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-do-expressions': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-export-default-from/7.18.10_@babel+core@7.12.3: - resolution: {integrity: sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-export-default-from': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-function-bind/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-9RfxqKkRBCCT0xoBl9AqieCMscJmSAL9HYixGMWH549jUpT9csWWK/HEYZEx9t9iW/PRSXgX95x9bDlgtAJGFA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-function-bind': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-function-sent/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-UdaOKPOLPt0O+Xu26tnw6oAZMLXhk+yMrXOzn6kAzTHBnWHJsoN1hlrgxFAQ+FRLS0ql1oYIQ2phvoFzmN3GMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-wrap-function': 7.19.0 - '@babel/plugin-syntax-function-sent': 7.18.6_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-object-rest-spread/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.19.1 - '@babel/core': 7.12.3 - '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-pipeline-operator/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-Pc33e6m8f4MJhRXVCUwiKZNtEm+W2CUPHIL0lyJNtkp+w6d75CLw3gsBKQ81VAMUgT9jVPIEU8gwJ5nJgmJ1Ag==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-pipeline-operator': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-throw-expressions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-WHOrJyhGoGrdtW480L79cF7Iq/gZDZ/z6OqK7mVyFR5I37dTpog/wNgb6hmaM3HYZtULEJl++7VaMWkNZsOcHg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-throw-expressions': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} - engines: {node: '>=4'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.12.3: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -1177,104 +998,6 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.12.3: - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-decorators/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-do-expressions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-kTogvOsjBTVOSZtkkziiXB5hwGXqwhq2gBXDaiWVruRLDT7C2GqfbsMnicHJ7ePq2GE8UJeWS34YbNP6yDhwUA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.12.3: - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-export-default-from/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.12.3: - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-flow/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-function-bind/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-wZN0Aq/AScknI9mKGcR3TpHdASMufFGaeJgc1rhPmLtZ/PniwjePSh8cfh8tXMB3U4kh/3cRKrLjDtedejg8jQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-function-sent/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-f3OJHIlFIkg+cP1Hfo2SInLhsg0pz2Ikmgo7jMdIIKC+3jVXQlHB0bgSapOWxeWI0SU28qIWmfn5ZKu1yPJHkg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-import-assertions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.12.3: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -1357,36 +1080,6 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-syntax-pipeline-operator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-pFtIdQomJtkTHWcNsGXhjJ5YUkL+AxJnP4G+Ol85UO6uT2fpHTPYLLE5bBeRA9cxf25qa/VKsJ3Fi67Gyqe3rA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.12.3: - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-syntax-throw-expressions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-rp1CqEZXGv1z1YZ3qYffBH3rhnOxrTwQG8fh2yqulTurwv9zu3Gthfd+niZBLSOi1rY6146TgF+JmVeDXaX4TQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.12.3: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -1407,562 +1100,6 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-block-scoping/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-classes/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.12.3 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-replace-supers': 7.19.1 - '@babel/helper-split-export-declaration': 7.18.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-destructuring/7.18.13_@babel+core@7.12.3: - resolution: {integrity: sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-flow-strip-types/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.12.3: - resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.12.3 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-literals/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-modules-amd/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-module-transforms': 7.19.0 - '@babel/helper-plugin-utils': 7.19.0 - babel-plugin-dynamic-import-node: 2.3.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-commonjs/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-module-transforms': 7.19.0 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-simple-access': 7.18.6 - babel-plugin-dynamic-import-node: 2.3.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-systemjs/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.19.0 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-validator-identifier': 7.19.1 - babel-plugin-dynamic-import-node: 2.3.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-module-transforms': 7.19.0 - '@babel/helper-plugin-utils': 7.19.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-named-capturing-groups-regex/7.19.1_@babel+core@7.12.3: - resolution: {integrity: sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-replace-supers': 7.19.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-parameters/7.18.8_@babel+core@7.12.3: - resolution: {integrity: sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.12.3 - dev: true - - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.12.3 - '@babel/types': 7.19.0 - dev: true - - /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - regenerator-transform: 0.15.0 - dev: true - - /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-spread/7.19.0_@babel+core@7.12.3: - resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 - dev: true - - /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.12.3: - resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.12.3: - resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/preset-env/7.19.1_@babel+core@7.12.3: - resolution: {integrity: sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.19.1 - '@babel/core': 7.12.3 - '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-async-generator-functions': 7.19.1_@babel+core@7.12.3 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-object-rest-spread': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.12.3 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.12.3 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.12.3 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-import-assertions': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.12.3 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.12.3 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.12.3 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.12.3 - '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-block-scoping': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-classes': 7.19.0_@babel+core@7.12.3 - '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-destructuring': 7.18.13_@babel+core@7.12.3 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.12.3 - '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-modules-amd': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-modules-systemjs': 7.19.0_@babel+core@7.12.3 - '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-named-capturing-groups-regex': 7.19.1_@babel+core@7.12.3 - '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.12.3 - '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.12.3 - '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.12.3 - '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.12.3 - '@babel/preset-modules': 0.1.5_@babel+core@7.12.3 - '@babel/types': 7.19.0 - babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.12.3 - babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.12.3 - babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.12.3 - core-js-compat: 3.25.2 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/preset-flow/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-flow-strip-types': 7.19.0_@babel+core@7.12.3 - dev: true - - /@babel/preset-modules/0.1.5_@babel+core@7.12.3: - resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.12.3 - '@babel/types': 7.19.0 - esutils: 2.0.3 - dev: true - - /@babel/preset-react/7.18.6_@babel+core@7.12.3: - resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.12.3 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.12.3 - dev: true - - /@babel/preset-stage-0/7.8.3: - resolution: {integrity: sha512-+l6FlG1j73t4wh78W41StbcCz0/9a1/y+vxfnjtHl060kSmcgMfGzK9MEkLvrCOXfhp9RCX+d88sm6rOqxEIEQ==} - dev: true - - /@babel/runtime/7.19.0: - resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.9 - dev: true - /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} engines: {node: '>=6.9.0'} @@ -2014,15 +1151,15 @@ packages: dev: true optional: true - /@commitlint/cli/17.1.2: - resolution: {integrity: sha512-h/4Hlka3bvCLbnxf0Er2ri5A44VMlbMSkdTRp8Adv2tRiklSTRIoPGs7OEXDv3EoDs2AAzILiPookgM4Gi7LOw==} + /@commitlint/cli/17.2.0: + resolution: {integrity: sha512-kd1zykcrjIKyDRftWW1E1TJqkgzeosEkv1BiYPCdzkb/g/3BrfgwZUHR1vg+HO3qKUb/0dN+jNXArhGGAHpmaQ==} engines: {node: '>=v14'} hasBin: true dependencies: '@commitlint/format': 17.0.0 - '@commitlint/lint': 17.1.0 - '@commitlint/load': 17.1.2 - '@commitlint/read': 17.1.0 + '@commitlint/lint': 17.2.0 + '@commitlint/load': 17.2.0 + '@commitlint/read': 17.2.0 '@commitlint/types': 17.0.0 execa: 5.1.1 lodash: 4.17.21 @@ -2034,8 +1171,8 @@ packages: - '@swc/wasm' dev: true - /@commitlint/config-conventional/17.1.0: - resolution: {integrity: sha512-WU2p0c9/jLi8k2q2YrDV96Y8XVswQOceIQ/wyJvQxawJSCasLdRB3kUIYdNjOCJsxkpoUlV/b90ZPxp1MYZDiA==} + /@commitlint/config-conventional/17.2.0: + resolution: {integrity: sha512-g5hQqRa80f++SYS233dbDSg16YdyounMTAhVcmqtInNeY/GF3aA4st9SVtJxpeGrGmueMrU4L+BBb+6Vs5wrcg==} engines: {node: '>=v14'} dependencies: conventional-changelog-conventionalcommits: 5.0.0 @@ -2070,26 +1207,26 @@ packages: chalk: 4.1.2 dev: true - /@commitlint/is-ignored/17.1.0: - resolution: {integrity: sha512-JITWKDMHhIh8IpdIbcbuH9rEQJty1ZWelgjleTFrVRAcEwN/sPzk1aVUXRIZNXMJWbZj8vtXRJnFihrml8uECQ==} + /@commitlint/is-ignored/17.2.0: + resolution: {integrity: sha512-rgUPUQraHxoMLxiE8GK430HA7/R2vXyLcOT4fQooNrZq9ERutNrP6dw3gdKLkq22Nede3+gEHQYUzL4Wu75ndg==} engines: {node: '>=v14'} dependencies: '@commitlint/types': 17.0.0 semver: 7.3.7 dev: true - /@commitlint/lint/17.1.0: - resolution: {integrity: sha512-ltpqM2ogt/+SDhUaScFo0MdscncEF96lvQTPMM/VTTWlw7sTGLLWkOOppsee2MN/uLNNWjQ7kqkd4h6JqoM9AQ==} + /@commitlint/lint/17.2.0: + resolution: {integrity: sha512-N2oLn4Dj672wKH5qJ4LGO+73UkYXGHO+NTVUusGw83SjEv7GjpqPGKU6KALW2kFQ/GsDefSvOjpSi3CzWHQBDg==} engines: {node: '>=v14'} dependencies: - '@commitlint/is-ignored': 17.1.0 - '@commitlint/parse': 17.0.0 - '@commitlint/rules': 17.0.0 + '@commitlint/is-ignored': 17.2.0 + '@commitlint/parse': 17.2.0 + '@commitlint/rules': 17.2.0 '@commitlint/types': 17.0.0 dev: true - /@commitlint/load/17.1.2: - resolution: {integrity: sha512-sk2p/jFYAWLChIfOIp/MGSIn/WzZ0vkc3afw+l4X8hGEYkvDe4gQUUAVxjl/6xMRn0HgnSLMZ04xXh5pkTsmgg==} + /@commitlint/load/17.2.0: + resolution: {integrity: sha512-HDD57qSqNrk399R4TIjw31AWBG8dBjNj1MrDKZKmC/wvimtnIFlqzcu1+sxfXIOHj/+M6tcMWDtvknGUd7SU+g==} engines: {node: '>=v14'} dependencies: '@commitlint/config-validator': 17.1.0 @@ -2099,23 +1236,23 @@ packages: '@types/node': 14.18.29 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 4.1.0_3owiowz3ujipd4k6pbqn3n7oui + cosmiconfig-typescript-loader: 4.1.0_nxlrwu45zhpwmwjzs33dzt3ak4 lodash: 4.17.21 resolve-from: 5.0.0 - ts-node: 10.9.1_ck2axrxkiif44rdbzjywaqjysa - typescript: 4.8.3 + ts-node: 10.9.1_sqjhzn5m3vxyw66a2xhtc43hby + typescript: 4.8.4 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' dev: true - /@commitlint/message/17.0.0: - resolution: {integrity: sha512-LpcwYtN+lBlfZijHUdVr8aNFTVpHjuHI52BnfoV01TF7iSLnia0jttzpLkrLmI8HNQz6Vhr9UrxDWtKZiMGsBw==} + /@commitlint/message/17.2.0: + resolution: {integrity: sha512-/4l2KFKxBOuoEn1YAuuNNlAU05Zt7sNsC9H0mPdPm3chOrT4rcX0pOqrQcLtdMrMkJz0gC7b3SF80q2+LtdL9Q==} engines: {node: '>=v14'} dev: true - /@commitlint/parse/17.0.0: - resolution: {integrity: sha512-cKcpfTIQYDG1ywTIr5AG0RAiLBr1gudqEsmAGCTtj8ffDChbBRxm6xXs2nv7GvmJN7msOt7vOKleLvcMmRa1+A==} + /@commitlint/parse/17.2.0: + resolution: {integrity: sha512-vLzLznK9Y21zQ6F9hf8D6kcIJRb2haAK5T/Vt1uW2CbHYOIfNsR/hJs0XnF/J9ctM20Tfsqv4zBitbYvVw7F6Q==} engines: {node: '>=v14'} dependencies: '@commitlint/types': 17.0.0 @@ -2123,8 +1260,8 @@ packages: conventional-commits-parser: 3.2.4 dev: true - /@commitlint/read/17.1.0: - resolution: {integrity: sha512-73BoFNBA/3Ozo2JQvGsE0J8SdrJAWGfZQRSHqvKaqgmY042Su4gXQLqvAzgr55S9DI1l9TiU/5WDuh8IE86d/g==} + /@commitlint/read/17.2.0: + resolution: {integrity: sha512-bbblBhrHkjxra3ptJNm0abxu7yeAaxumQ8ZtD6GIVqzURCETCP7Dm0tlVvGRDyXBuqX6lIJxh3W7oyKqllDsHQ==} engines: {node: '>=v14'} dependencies: '@commitlint/top-level': 17.0.0 @@ -2146,12 +1283,12 @@ packages: resolve-global: 1.0.0 dev: true - /@commitlint/rules/17.0.0: - resolution: {integrity: sha512-45nIy3dERKXWpnwX9HeBzK5SepHwlDxdGBfmedXhL30fmFCkJOdxHyOJsh0+B0RaVsLGT01NELpfzJUmtpDwdQ==} + /@commitlint/rules/17.2.0: + resolution: {integrity: sha512-1YynwD4Eh7HXZNpqG8mtUlL2pSX2jBy61EejYJv4ooZPcg50Ak7LPOyD3a9UZnsE76AXWFBz+yo9Hv4MIpAa0Q==} engines: {node: '>=v14'} dependencies: '@commitlint/ensure': 17.0.0 - '@commitlint/message': 17.0.0 + '@commitlint/message': 17.2.0 '@commitlint/to-lines': 17.0.0 '@commitlint/types': 17.0.0 execa: 5.1.1 @@ -2176,6 +1313,319 @@ packages: chalk: 4.1.2 dev: true + /@cspell/cspell-bundled-dicts/6.14.2: + resolution: {integrity: sha512-gh6h/1vy332s3IR7x1v53Cp/WGPpbKKRdte3qUG0KZol9A52agfPCju8TEHxsyk8rXAbVtqYwue8Y68Nz4ZbVg==} + engines: {node: '>=14'} + dependencies: + '@cspell/dict-ada': 4.0.0 + '@cspell/dict-aws': 3.0.0 + '@cspell/dict-bash': 4.1.0 + '@cspell/dict-companies': 3.0.3 + '@cspell/dict-cpp': 4.0.0 + '@cspell/dict-cryptocurrencies': 3.0.1 + '@cspell/dict-csharp': 4.0.1 + '@cspell/dict-css': 4.0.0 + '@cspell/dict-dart': 2.0.0 + '@cspell/dict-django': 4.0.0 + '@cspell/dict-docker': 1.1.3 + '@cspell/dict-dotnet': 4.0.0 + '@cspell/dict-elixir': 4.0.0 + '@cspell/dict-en-gb': 1.1.33 + '@cspell/dict-en_us': 4.1.0 + '@cspell/dict-filetypes': 3.0.0 + '@cspell/dict-fonts': 3.0.0 + '@cspell/dict-fullstack': 3.0.0 + '@cspell/dict-git': 2.0.0 + '@cspell/dict-golang': 5.0.0 + '@cspell/dict-haskell': 4.0.0 + '@cspell/dict-html': 4.0.1 + '@cspell/dict-html-symbol-entities': 4.0.0 + '@cspell/dict-java': 5.0.2 + '@cspell/dict-latex': 3.0.0 + '@cspell/dict-lorem-ipsum': 3.0.0 + '@cspell/dict-lua': 3.0.0 + '@cspell/dict-node': 4.0.1 + '@cspell/dict-npm': 4.0.1 + '@cspell/dict-php': 3.0.3 + '@cspell/dict-powershell': 3.0.0 + '@cspell/dict-public-licenses': 2.0.0 + '@cspell/dict-python': 4.0.0 + '@cspell/dict-r': 2.0.0 + '@cspell/dict-ruby': 3.0.0 + '@cspell/dict-rust': 3.0.0 + '@cspell/dict-scala': 3.0.0 + '@cspell/dict-software-terms': 3.0.5 + '@cspell/dict-sql': 2.0.0 + '@cspell/dict-swift': 2.0.0 + '@cspell/dict-typescript': 3.0.1 + '@cspell/dict-vue': 3.0.0 + dev: true + + /@cspell/cspell-bundled-dicts/6.14.3: + resolution: {integrity: sha512-bgPBduoDi1jkrcLkmAwRG1c6F1iprF2yfBgEDT19dRG1kYuq/fLGNOcSmEp4CbApn8m0MmxsrhEp8O0Q9owQRQ==} + engines: {node: '>=14'} + dependencies: + '@cspell/dict-ada': 4.0.0 + '@cspell/dict-aws': 3.0.0 + '@cspell/dict-bash': 4.1.0 + '@cspell/dict-companies': 3.0.3 + '@cspell/dict-cpp': 4.0.0 + '@cspell/dict-cryptocurrencies': 3.0.1 + '@cspell/dict-csharp': 4.0.1 + '@cspell/dict-css': 4.0.0 + '@cspell/dict-dart': 2.0.0 + '@cspell/dict-django': 4.0.0 + '@cspell/dict-docker': 1.1.3 + '@cspell/dict-dotnet': 4.0.0 + '@cspell/dict-elixir': 4.0.0 + '@cspell/dict-en-gb': 1.1.33 + '@cspell/dict-en_us': 4.1.0 + '@cspell/dict-filetypes': 3.0.0 + '@cspell/dict-fonts': 3.0.0 + '@cspell/dict-fullstack': 3.0.0 + '@cspell/dict-git': 2.0.0 + '@cspell/dict-golang': 5.0.0 + '@cspell/dict-haskell': 4.0.0 + '@cspell/dict-html': 4.0.1 + '@cspell/dict-html-symbol-entities': 4.0.0 + '@cspell/dict-java': 5.0.2 + '@cspell/dict-latex': 3.0.0 + '@cspell/dict-lorem-ipsum': 3.0.0 + '@cspell/dict-lua': 3.0.0 + '@cspell/dict-node': 4.0.1 + '@cspell/dict-npm': 4.0.1 + '@cspell/dict-php': 3.0.3 + '@cspell/dict-powershell': 3.0.0 + '@cspell/dict-public-licenses': 2.0.0 + '@cspell/dict-python': 4.0.0 + '@cspell/dict-r': 2.0.0 + '@cspell/dict-ruby': 3.0.0 + '@cspell/dict-rust': 3.0.0 + '@cspell/dict-scala': 3.0.0 + '@cspell/dict-software-terms': 3.0.5 + '@cspell/dict-sql': 2.0.0 + '@cspell/dict-swift': 2.0.0 + '@cspell/dict-typescript': 3.0.1 + '@cspell/dict-vue': 3.0.0 + dev: true + + /@cspell/cspell-pipe/6.14.2: + resolution: {integrity: sha512-9H7Z/jy2tGpMW9T/JOk8T3bqvQoHJIz1wddktA5Lq8fnMqlDhM9le2uykhVlLpemLhWpDS2fNzLJ3sHiaPgHBA==} + engines: {node: '>=14'} + dev: true + + /@cspell/cspell-pipe/6.14.3: + resolution: {integrity: sha512-/mLZxJOK3/UFpnR4jrImKY5W4cn5XWjvQPXnFCEzpU0tAAF6GboJgWl30TegqFJjLVCKTNRMOtT1r6kgvb66zw==} + engines: {node: '>=14'} + dev: true + + /@cspell/cspell-service-bus/6.14.2: + resolution: {integrity: sha512-IOK4MqwDNS2y29eZjdpHrCQ0ouTWZCS2e3EOmlvY+yUpT7e1AX8pVOaar4jLnXg03evAjrFrrmfmhFI6poO6Hg==} + engines: {node: '>=14'} + dev: true + + /@cspell/cspell-service-bus/6.14.3: + resolution: {integrity: sha512-89OWGBzhorhiWcFqFTeHl9Y6WTdd5MGC2XNNCVZLM3VTYaFx4DVkiyxWdkE7gHjYxvNdGSH54/fE18TqLc//dQ==} + engines: {node: '>=14'} + dev: true + + /@cspell/cspell-types/6.14.2: + resolution: {integrity: sha512-/EZYVglm6+2GlnkFTzuLuQFr7vrttkhG+ZsNO9EDcFYB5N7O2ndNSkTQFxGi8FS8R3RS5CHyS5X6hANnolzvfQ==} + engines: {node: '>=14'} + dev: true + + /@cspell/cspell-types/6.14.3: + resolution: {integrity: sha512-u4Hun0vOQVkk3tJ6VzPjHVmv2dq0D6jYqX8pWLKWRwo38rdoIkdWseN359sWCz96tDM8g5rpSFdmecbWLU7BYg==} + engines: {node: '>=14'} + dev: true + + /@cspell/dict-ada/4.0.0: + resolution: {integrity: sha512-M0n4ZYmpLOXbDD07Qb/Ekk0K5pX2C+mCuJ2ZxPgbTq9HGlrN43PmqrGJHWcgtVHE3fd1D4VxS85QcQP6r1Y+KQ==} + dev: true + + /@cspell/dict-aws/3.0.0: + resolution: {integrity: sha512-O1W6nd5y3Z00AMXQMzfiYrIJ1sTd9fB1oLr+xf/UD7b3xeHeMeYE2OtcWbt9uyeHim4tk+vkSTcmYEBKJgS5bQ==} + dev: true + + /@cspell/dict-bash/4.1.0: + resolution: {integrity: sha512-8pFL03ZKejynfbsa2UZ3iZ7BrT1TAGTD8ZlK822ioAb7aoDvQhYao2Bjz5cXU0uk7CyrlgsSnYX94sLfqDfTxQ==} + dev: true + + /@cspell/dict-companies/3.0.3: + resolution: {integrity: sha512-qBWdwA97HdnLbxPLOUTZ+/mg9eYhi14hM7PEUM1PZ004MEIxQHum0IQpypKAwP3teR1KEsyxEPHp8v24Dw45Zg==} + dev: true + + /@cspell/dict-cpp/4.0.0: + resolution: {integrity: sha512-NrCmer14tTSbPs1TwqyCjFEmWCBw0UFvAn4O3pdWuxktArHxRJ5vUQOoL2Gus2H9s3ihhOJZkcuJ47Kd21E7BQ==} + dev: true + + /@cspell/dict-cryptocurrencies/3.0.1: + resolution: {integrity: sha512-Tdlr0Ahpp5yxtwM0ukC13V6+uYCI0p9fCRGMGZt36rWv8JQZHIuHfehNl7FB/Qc09NCF7p5ep0GXbL+sVTd/+w==} + dev: true + + /@cspell/dict-csharp/4.0.1: + resolution: {integrity: sha512-BkfT6S790FcyWLTWYBwkj9dKxuNz4pHFDrj9GFrmqXd2HWzfSa944S0NJhal42TnW30JJljQY5P1ZYau+s2Pbg==} + dev: true + + /@cspell/dict-css/4.0.0: + resolution: {integrity: sha512-ieSeG9KAJGIr5eK0JRWqD5KXstPPUw6JUTmGWc7P/qiqj/sjmhWqWKEt7HhoSNcb8uQxAkAoxhrNpfbKzqnKAw==} + dev: true + + /@cspell/dict-dart/2.0.0: + resolution: {integrity: sha512-p7vHszsu2uJt+F04gvNy1e5okypFfVEYHBWgpOV/Jrvs0F5A+gUzFTG2Ix9b1jkCigAULYKQkIGue+qlhSoK5Q==} + dev: true + + /@cspell/dict-django/4.0.0: + resolution: {integrity: sha512-k0npSzQrPQSqjR2XtumV14sv9waTRMUzPx0UfOuJZcnCCZY8ofPeqFYoku+O+9Kc9etFOziOxnScshKVDzYWOQ==} + dev: true + + /@cspell/dict-docker/1.1.3: + resolution: {integrity: sha512-Iz7EQGnLBgnnmzCC8iLQ7JssCCQlCjZLiCs0qhooETWLifob3nzsI9AVBh3gkYLhISLIIjBpfa4LTknskT7LzA==} + dev: true + + /@cspell/dict-dotnet/4.0.0: + resolution: {integrity: sha512-biZiTWyDqwVV2m+c17lLIliPDXPjOR1VwwmyMxvb3nFS84aP9x52SAVCf0w7Io1CIpUiY7XnG6/xeI7esYU78w==} + dev: true + + /@cspell/dict-elixir/4.0.0: + resolution: {integrity: sha512-0TqqdQjg/zu3wAjk2FQkZ87pPIS9tA9kl6he5NJB729ysrWhND/7aSPC48QrP46VZ+oFrvFZK8DC8ZlYs16cjQ==} + dev: true + + /@cspell/dict-en-gb/1.1.33: + resolution: {integrity: sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==} + dev: true + + /@cspell/dict-en_us/4.1.0: + resolution: {integrity: sha512-EnfxP/5U3kDhmTWcHV7Xs2Fxa9KAE5fbHm+4u8LGBOUZvSkZC5+ayjQ50CfEyTGuaI/946ITQYPRNxUZ7oqOiQ==} + dev: true + + /@cspell/dict-filetypes/3.0.0: + resolution: {integrity: sha512-Fiyp0z5uWaK0d2TfR9GMUGDKmUMAsOhGD5A0kHoqnNGswL2iw0KB0mFBONEquxU65fEnQv4R+jdM2d9oucujuA==} + dev: true + + /@cspell/dict-fonts/3.0.0: + resolution: {integrity: sha512-zTZni0AbwBVG1MKA0WpwPyIJPVF+gp6neXDQzHcu4RUnuQ4uDu0PVEuZjGHCJWwwFoR5JmkqZxVSg1y3ufJODA==} + dev: true + + /@cspell/dict-fullstack/3.0.0: + resolution: {integrity: sha512-BMQRTaeReLufjMwgWqqwPdrXQ7jkVGTv7/YvOLsHFZvcAP3eM7WqX+rvdXckLhJmuuzbceFRDKs5F/9Ig2x/tQ==} + dev: true + + /@cspell/dict-git/2.0.0: + resolution: {integrity: sha512-n1AxyX5Kgxij/sZFkxFJlzn3K9y/sCcgVPg/vz4WNJ4K9YeTsUmyGLA2OQI7d10GJeiuAo2AP1iZf2A8j9aj2w==} + dev: true + + /@cspell/dict-golang/5.0.0: + resolution: {integrity: sha512-Cbx4mVHsGbr5D+wlT0yU3n/0c5iLvciU48rSOQR7SCAzu5mTXyM1mqRu6nqnRiMv6G6mO50EL2LCTq6RZrlIOg==} + dev: true + + /@cspell/dict-haskell/4.0.0: + resolution: {integrity: sha512-U/DPpDoitGeUvduM9teDkDc1zs4Plgh0pNONDP3YbsEICErSlp1NfatD0i35Z6cR0C7I8uEe4gG2phG00zrSqw==} + dev: true + + /@cspell/dict-html-symbol-entities/4.0.0: + resolution: {integrity: sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==} + dev: true + + /@cspell/dict-html/4.0.1: + resolution: {integrity: sha512-q5fCzkoOz+8BW79qLrnANEDnG+Jb2WS2fXERxg9xwgKBXwXUxH8ttGVNhfkLpNWe/UMm00U1IZMnVGyYLNTO5w==} + dev: true + + /@cspell/dict-java/5.0.2: + resolution: {integrity: sha512-HWgdp8plZOdYjOkndwmgHGVxoewylZcl886PqSL6TMcDshyI0+2nePft31nIuALRvt7HL8IX++DM1uk4UfY4kg==} + dev: true + + /@cspell/dict-latex/3.0.0: + resolution: {integrity: sha512-QsRWj+Jll4ueVbce8ofKa743oQ2exmbVNZN70MaMbmu8PSbjW2+Rj3OdExVStesANMj7qc20inS/TgPr8DrInQ==} + dev: true + + /@cspell/dict-lorem-ipsum/3.0.0: + resolution: {integrity: sha512-msEV24qEpzWZs2kcEicqYlhyBpR0amfDkJOs+iffC07si9ftqtQ+yP3lf1VFLpgqw3SQh1M1vtU7RD4sPrNlcQ==} + dev: true + + /@cspell/dict-lua/3.0.0: + resolution: {integrity: sha512-WOhSCgS5wMxkGQJ8siB90iTB9ElquJB7FeqYSbJqqs6cUwH8G7MM/CEDPL6h7vCo0+v3GuxQ8yKWDSUcUhz9Lg==} + dev: true + + /@cspell/dict-node/4.0.1: + resolution: {integrity: sha512-4EmT5yZFitdwnG0hYEd+Ek19zzD81Bp+n7w0kglZKldS5AvapwW6GM/SAps5YMQQc5zZMi+bMgV7NIzapREqUg==} + dev: true + + /@cspell/dict-npm/4.0.1: + resolution: {integrity: sha512-jNKImVG5ZX+Pp6PhbSR3TmC9+0ROx09dGhSgUsZyvXV5CGEr+OQGJtNL98TGwU3pP2Xjc++qnHA/XPwB5WvLfA==} + dev: true + + /@cspell/dict-php/3.0.3: + resolution: {integrity: sha512-7dvXdPTfbIF2xEob9w94/eV5SU8BkYoN0R7EQghXi0fcF7T1unK+JwDgfoEs6wqApB5aCVYwguiaj8HGX2IRIQ==} + dev: true + + /@cspell/dict-powershell/3.0.0: + resolution: {integrity: sha512-pkztY9Ak4oc33q+Qxcn9/CTOKo4N8YIRRE6v67WwQOncA5QIJfcOPUrjfR3Z8SpzElXhu3s9qtWWSqbCy6qmcA==} + dev: true + + /@cspell/dict-public-licenses/2.0.0: + resolution: {integrity: sha512-NdMHnS6xiYJKlzVoTV5CBhMiDpXMZ/PDcvXiOpxeR50xkjR18O/XFP4f4eDZpxGiBSUCMFRWf4JjILJ04Rpcfg==} + dev: true + + /@cspell/dict-python/4.0.0: + resolution: {integrity: sha512-MC6CKbYOly3Ig25ZnhlCzPbE/QozqfQv4VYW6HcoMQ5IbHu33ddf2lzkZ89qTXlxsF5NT5qfZEkQYHYuhuL6AQ==} + dev: true + + /@cspell/dict-r/2.0.0: + resolution: {integrity: sha512-rdt1cKc3VL2uXJ2X088gRhTFreN/MkJWK1jccW1EWdFHLzDwhKfrlAkoLCp0paD6HvmloLQ+eSR09D58DdsYfA==} + dev: true + + /@cspell/dict-ruby/3.0.0: + resolution: {integrity: sha512-sA98T8Y1Pmq3RStVkO14E8vTWkq6JUn8c8PldiMyYgV0yfQgwhQfFAzlSfF3Gg2B0VkIdqt2et2SPN7f9wp7fQ==} + dev: true + + /@cspell/dict-rust/3.0.0: + resolution: {integrity: sha512-L1T1IBsYJZVDmfOGAbVLcpc6arWxRRCSJYvHSwEDBGrNuMyJ4jx/NvBEz5crcKf4vVKgwVlXgzQlJJZ8AVxU9w==} + dev: true + + /@cspell/dict-scala/3.0.0: + resolution: {integrity: sha512-sIiCQDIMMnNns/fzD61z5npbh5pypaKq07Orqe0+eRfdQpika8iRSGUGFHVbtdd1JzB1DyTCV2e8OwdaQiXqJQ==} + dev: true + + /@cspell/dict-software-terms/3.0.5: + resolution: {integrity: sha512-xZVcX1zsIUbLvUc/RX+YgJRvbHaGMcdkRR+Vw8UoLjmhnT0yXWLds5uwRwAVjlQIrIcHylfDWuG70Cq5nmJHfA==} + dev: true + + /@cspell/dict-sql/2.0.0: + resolution: {integrity: sha512-J3X8VSgWpc/4McQEs138abtBw/SO3Z+vGaYi5X7XV1pKPBxjupHTTNQHSS/HWUDmVWj6fR3OV+ZGptcmvv3Clg==} + dev: true + + /@cspell/dict-swift/2.0.0: + resolution: {integrity: sha512-VStJ0fKPPNIXKmxJrbGH6vKNtJCwAnQatfSH0fVj+Unf3QHHlmuLKRG0cN0aVgEIolpRkxNXJcSB3CPbYr0Xhw==} + dev: true + + /@cspell/dict-typescript/3.0.1: + resolution: {integrity: sha512-nKEtOpj+rJNIUK268/mCFDCIv1MWFdK1efm9YL4q1q3NHT+qCKhkXoA0eG8k4AaDIpsvebB8CgNIYFPxY92r4A==} + dev: true + + /@cspell/dict-vue/3.0.0: + resolution: {integrity: sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==} + dev: true + + /@cspell/eslint-plugin/6.14.2: + resolution: {integrity: sha512-GnwM/DOenB6VIt4lMpmw4jI1Sc83eR9/lsxz/yTQ8LZFYVxK0yWi+LbSLCLvKhLJ9RNm7jzyHCanIFNtx+aEyw==} + engines: {node: '>=14'} + dependencies: + cspell-lib: 6.14.2 + transitivePeerDependencies: + - encoding + dev: true + + /@cspell/strong-weak-map/6.14.2: + resolution: {integrity: sha512-OS/t4e5vfUyAiOcyuI1I9d4/EWCx7pA3L8uHNOQQHgjVP41tffMaKTirqRiNhkruIhmxa5Tk5fbQLRMEFapalg==} + engines: {node: '>=14.6'} + dev: true + + /@cspell/strong-weak-map/6.14.3: + resolution: {integrity: sha512-/FTvcywuwfFTMEpRabL8+rqB/ezSjvMp6todO0SwL/agYQmRIuTvTYLh0Ikq430oVnjo7LDgztW0tHq38UlFLw==} + engines: {node: '>=14.6'} + dev: true + /@cspotcode/source-map-support/0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -2216,28 +1666,69 @@ packages: - supports-color dev: true - /@es-joy/jsdoccomment/0.31.0: - resolution: {integrity: sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==} - engines: {node: ^14 || ^16 || ^17 || ^18} + /@discoveryjs/json-ext/0.5.7: + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + dev: true + + /@docsearch/css/3.3.0: + resolution: {integrity: sha512-rODCdDtGyudLj+Va8b6w6Y85KE85bXRsps/R4Yjwt5vueXKXZQKYw0aA9knxLBT6a/bI/GMrAcmCR75KYOM6hg==} + dev: true + + /@docsearch/js/3.3.0_tbpndr44ulefs3hehwpi2mkf2y: + resolution: {integrity: sha512-oFXWRPNvPxAzBhnFJ9UCFIYZiQNc3Yrv6912nZHw/UIGxsyzKpNRZgHq8HDk1niYmOSoLKtVFcxkccpQmYGFyg==} + dependencies: + '@docsearch/react': 3.3.0_tbpndr44ulefs3hehwpi2mkf2y + preact: 10.11.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + dev: true + + /@docsearch/react/3.3.0_tbpndr44ulefs3hehwpi2mkf2y: + resolution: {integrity: sha512-fhS5adZkae2SSdMYEMVg6pxI5a/cE+tW16ki1V0/ur4Fdok3hBRkmN/H8VvlXnxzggkQIIRIVvYPn00JPjen3A==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + '@algolia/autocomplete-core': 1.7.2 + '@algolia/autocomplete-preset-algolia': 1.7.2_qs6lk5nhygj2o3hj4sf6xnr724 + '@docsearch/css': 3.3.0 + algoliasearch: 4.14.2 + transitivePeerDependencies: + - '@algolia/client-search' + dev: true + + /@es-joy/jsdoccomment/0.36.0: + resolution: {integrity: sha512-u0XZyvUF6Urb2cSivSXA8qXIpT/CxkHcdtZKoWusAzgzmsTWpg0F2FpWXsolHmMUyVY3dLWaoy+0ccJ5uf2QjA==} + engines: {node: ^14 || ^16 || ^17 || ^18 || ^19} dependencies: comment-parser: 1.3.1 esquery: 1.4.0 jsdoc-type-pratt-parser: 3.1.0 dev: true - /@esbuild/android-arm/0.15.8: - resolution: {integrity: sha512-CyEWALmn+no/lbgbAJsbuuhT8s2J19EJGHkeyAwjbFJMrj80KJ9zuYsoAvidPTU7BgBf87r/sgae8Tw0dbOc4Q==} + /@esbuild/android-arm/0.15.13: + resolution: {integrity: sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==} engines: {node: '>=12'} cpu: [arm] os: [android] requiresBuild: true - dependencies: - esbuild-wasm: 0.15.8 dev: true optional: true - /@esbuild/linux-loong64/0.15.8: - resolution: {integrity: sha512-pE5RQsOTSERCtfZdfCT25wzo7dfhOSlhAXcsZmuvRYhendOv7djcdvtINdnDp2DAjP17WXlBB4nBO6sHLczmsg==} + /@esbuild/linux-loong64/0.15.13: + resolution: {integrity: sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -2245,8 +1736,8 @@ packages: dev: true optional: true - /@eslint/eslintrc/1.3.2: - resolution: {integrity: sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==} + /@eslint/eslintrc/1.3.3: + resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -2272,8 +1763,8 @@ packages: '@hapi/hoek': 9.3.0 dev: true - /@humanwhocodes/config-array/0.10.5: - resolution: {integrity: sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==} + /@humanwhocodes/config-array/0.11.7: + resolution: {integrity: sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 @@ -2283,10 +1774,6 @@ packages: - supports-color dev: true - /@humanwhocodes/gitignore-to-minimatch/1.0.2: - resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} - dev: true - /@humanwhocodes/module-importer/1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} @@ -2296,11 +1783,6 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@hutson/parse-repository-url/3.0.2: - resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} - engines: {node: '>=6.9.0'} - dev: true - /@istanbuljs/load-nyc-config/1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -2317,20 +1799,20 @@ packages: engines: {node: '>=8'} dev: true - /@jest/console/29.1.0: - resolution: {integrity: sha512-yNoFMuAsXTP8OyweaMaIoa6Px6rJkbbG7HtgYKGP3CY7lE7ADRA0Fn5ad9O+KefKcaf6W9rywKpCWOw21WMsAw==} + /@jest/console/29.3.1: + resolution: {integrity: sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 chalk: 4.1.2 - jest-message-util: 29.1.0 - jest-util: 29.1.0 + jest-message-util: 29.3.1 + jest-util: 29.3.1 slash: 3.0.0 dev: true - /@jest/core/29.1.1_ts-node@10.9.1: - resolution: {integrity: sha512-ppym+PLiuSmvU9ufXVb/8OtHUPcjW+bBlb8CLh6oMATgJtCE3fjDYrzJi5u1uX8q9jbmtQ7VADKJKIlp68zi3A==} + /@jest/core/29.3.1_ts-node@10.9.1: + resolution: {integrity: sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2338,32 +1820,32 @@ packages: node-notifier: optional: true dependencies: - '@jest/console': 29.1.0 - '@jest/reporters': 29.1.0 - '@jest/test-result': 29.1.0 - '@jest/transform': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/console': 29.3.1 + '@jest/reporters': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 ansi-escapes: 4.3.2 chalk: 4.1.2 - ci-info: 3.4.0 + ci-info: 3.6.2 exit: 0.1.2 graceful-fs: 4.2.10 - jest-changed-files: 29.0.0 - jest-config: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq - jest-haste-map: 29.1.0 - jest-message-util: 29.1.0 - jest-regex-util: 29.0.0 - jest-resolve: 29.1.0 - jest-resolve-dependencies: 29.1.1 - jest-runner: 29.1.1 - jest-runtime: 29.1.1 - jest-snapshot: 29.1.0 - jest-util: 29.1.0 - jest-validate: 29.1.0 - jest-watcher: 29.1.0 + jest-changed-files: 29.2.0 + jest-config: 29.3.1_odkjkoia5xunhxkdrka32ib6vi + jest-haste-map: 29.3.1 + jest-message-util: 29.3.1 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-resolve-dependencies: 29.3.1 + jest-runner: 29.3.1 + jest-runtime: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 + jest-watcher: 29.3.1 micromatch: 4.0.5 - pretty-format: 29.1.0 + pretty-format: 29.3.1 slash: 3.0.0 strip-ansi: 6.0.1 transitivePeerDependencies: @@ -2371,59 +1853,59 @@ packages: - ts-node dev: true - /@jest/environment/29.1.1: - resolution: {integrity: sha512-69WULhTD38UcjvLGRAnnwC5hDt35ZC91ZwnvWipNOAOSaQNT32uKYL/TVCT3tncB9L1D++LOmBbYhTYP4TLuuQ==} + /@jest/environment/29.3.1: + resolution: {integrity: sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/fake-timers': 29.1.1 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 - jest-mock: 29.1.1 + '@jest/fake-timers': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 + jest-mock: 29.3.1 dev: true - /@jest/expect-utils/29.1.0: - resolution: {integrity: sha512-YcD5CF2beqfoB07WqejPzWq1/l+zT3SgGwcqqIaPPG1DHFn/ea8MWWXeqV3KKMhTaOM1rZjlYplj1GQxR0XxKA==} + /@jest/expect-utils/29.3.1: + resolution: {integrity: sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.0.0 + jest-get-type: 29.2.0 dev: true - /@jest/expect/29.1.0: - resolution: {integrity: sha512-qWQttxE5rEwzvDW9G3f0o8chu1EKvIfsMQDeRlXMLCtsDS94ckcqEMNgbKKz0NYlZ45xrIoy+/pngt3ZFr/2zw==} + /@jest/expect/29.3.1: + resolution: {integrity: sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - expect: 29.1.0 - jest-snapshot: 29.1.0 + expect: 29.3.1 + jest-snapshot: 29.3.1 transitivePeerDependencies: - supports-color dev: true - /@jest/fake-timers/29.1.1: - resolution: {integrity: sha512-5wTGObRfL/OjzEz0v2ShXlzeJFJw8mO6ByMBwmPLd6+vkdPcmIpCvASG/PR/g8DpchSIEeDXCxQADojHxuhX8g==} + /@jest/fake-timers/29.3.1: + resolution: {integrity: sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.7.21 - jest-message-util: 29.1.0 - jest-mock: 29.1.1 - jest-util: 29.1.0 + '@types/node': 18.11.9 + jest-message-util: 29.3.1 + jest-mock: 29.3.1 + jest-util: 29.3.1 dev: true - /@jest/globals/29.1.1: - resolution: {integrity: sha512-yTiusxeEHjXwmo3guWlN31a1harU8zekLBMlZpOZ+84rfO3HDrkNZLTfd/YaHF8CrwlNCFpDGNSQCH8WkklH/Q==} + /@jest/globals/29.3.1: + resolution: {integrity: sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.1 - '@jest/expect': 29.1.0 - '@jest/types': 29.1.0 - jest-mock: 29.1.1 + '@jest/environment': 29.3.1 + '@jest/expect': 29.3.1 + '@jest/types': 29.3.1 + jest-mock: 29.3.1 transitivePeerDependencies: - supports-color dev: true - /@jest/reporters/29.1.0: - resolution: {integrity: sha512-szSjHjVuBQ7aZUdBzTicCoQAAQsQFLk+/PtMfO0RQxL5mQ1iw+PSKOpyvMZcA5T6bH9pIapue5U9UCrxfOtL3w==} + /@jest/reporters/29.3.1: + resolution: {integrity: sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2432,12 +1914,12 @@ packages: optional: true dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.1.0 - '@jest/test-result': 29.1.0 - '@jest/transform': 29.1.0 - '@jest/types': 29.1.0 + '@jest/console': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.15 - '@types/node': 18.7.21 + '@types/node': 18.11.9 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -2448,13 +1930,12 @@ packages: istanbul-lib-report: 3.0.0 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.5 - jest-message-util: 29.1.0 - jest-util: 29.1.0 - jest-worker: 29.1.0 + jest-message-util: 29.3.1 + jest-util: 29.3.1 + jest-worker: 29.3.1 slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 - terminal-link: 2.1.1 v8-to-istanbul: 9.0.1 transitivePeerDependencies: - supports-color @@ -2467,8 +1948,8 @@ packages: '@sinclair/typebox': 0.24.43 dev: true - /@jest/source-map/29.0.0: - resolution: {integrity: sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==} + /@jest/source-map/29.2.0: + resolution: {integrity: sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jridgewell/trace-mapping': 0.3.15 @@ -2476,41 +1957,41 @@ packages: graceful-fs: 4.2.10 dev: true - /@jest/test-result/29.1.0: - resolution: {integrity: sha512-RMBhPlw1Qfc2bKSf3RFPCyFSN7cfWVSTxRD8JrnvqdqgaDgrq4aGJT1A/V2+5Vq9bqBd187FpaxGTQ4zLrt08g==} + /@jest/test-result/29.3.1: + resolution: {integrity: sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.1.0 - '@jest/types': 29.1.0 + '@jest/console': 29.3.1 + '@jest/types': 29.3.1 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.1 dev: true - /@jest/test-sequencer/29.1.0: - resolution: {integrity: sha512-1diQfwNhBAte+x3TmyfWloxT1C8GcPEPEZ4BZjmELBK2j3cdqi0DofoJUxBDDUBBnakbv8ce0B7CIzprsupPSA==} + /@jest/test-sequencer/29.3.1: + resolution: {integrity: sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.1.0 + '@jest/test-result': 29.3.1 graceful-fs: 4.2.10 - jest-haste-map: 29.1.0 + jest-haste-map: 29.3.1 slash: 3.0.0 dev: true - /@jest/transform/29.1.0: - resolution: {integrity: sha512-NI1zd62KgM0lW6rWMIZDx52dfTIDd+cnLQNahH0YhH7TVmQVigumJ6jszuhAzvKHGm55P2Fozcglb5sGMfFp3Q==} + /@jest/transform/29.3.1: + resolution: {integrity: sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.12.3 - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.15 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 - convert-source-map: 1.8.0 + convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.10 - jest-haste-map: 29.1.0 - jest-regex-util: 29.0.0 - jest-util: 29.1.0 + jest-haste-map: 29.3.1 + jest-regex-util: 29.2.0 + jest-util: 29.3.1 micromatch: 4.0.5 pirates: 4.0.5 slash: 3.0.0 @@ -2519,14 +2000,14 @@ packages: - supports-color dev: true - /@jest/types/29.1.0: - resolution: {integrity: sha512-lE30u3z4lbTOqf5D7fDdoco3Qd8H6F/t73nLOswU4x+7VhgDQMX5y007IMqrKjFHdnpslaYymVFhWX+ttXNARQ==} + /@jest/types/29.3.1: + resolution: {integrity: sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.7.21 + '@types/node': 18.11.9 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -2550,6 +2031,13 @@ packages: engines: {node: '>=6.0.0'} dev: true + /@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.15 + dev: true + /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} dev: true @@ -2568,6 +2056,23 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@leichtgewicht/ip-codec/2.0.4: + resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} + dev: true + + /@microsoft/tsdoc-config/0.16.2: + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + dev: true + + /@microsoft/tsdoc/0.14.2: + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + dev: true + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2694,7 +2199,17 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.7.21 + '@types/node': 18.11.9 + dev: true + + /@types/bonjour/3.5.10: + resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} + dependencies: + '@types/node': 18.11.9 + dev: true + + /@types/braces/3.0.1: + resolution: {integrity: sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==} dev: true /@types/cacheable-request/6.0.2: @@ -2702,7 +2217,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.7.21 + '@types/node': 18.11.9 '@types/responselike': 1.0.0 dev: true @@ -2716,10 +2231,17 @@ packages: resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==} dev: true + /@types/connect-history-api-fallback/1.3.5: + resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} + dependencies: + '@types/express-serve-static-core': 4.17.31 + '@types/node': 18.11.9 + dev: true + /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 dev: true /@types/d3-array/3.0.3: @@ -2907,19 +2429,30 @@ packages: '@types/ms': 0.7.31 dev: true - /@types/dompurify/2.3.4: - resolution: {integrity: sha512-EXzDatIb5EspL2eb/xPGmaC8pePcTHrkDCONjeisusLFrVfl38Pjea/R0YJGu3k9ZQadSvMqW0WXPI2hEo2Ajg==} + /@types/dompurify/2.4.0: + resolution: {integrity: sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==} dependencies: '@types/trusted-types': 2.0.2 dev: true - /@types/eslint/8.4.6: - resolution: {integrity: sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==} + /@types/eslint-scope/3.7.4: + resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} + dependencies: + '@types/eslint': 8.4.10 + '@types/estree': 1.0.0 + dev: true + + /@types/eslint/8.4.10: + resolution: {integrity: sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==} dependencies: '@types/estree': 1.0.0 '@types/json-schema': 7.0.11 dev: true + /@types/estree/0.0.51: + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + dev: true + /@types/estree/1.0.0: resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} dev: true @@ -2927,7 +2460,7 @@ packages: /@types/express-serve-static-core/4.17.31: resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -2941,6 +2474,10 @@ packages: '@types/serve-static': 1.15.0 dev: true + /@types/flexsearch/0.7.3: + resolution: {integrity: sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==} + dev: true + /@types/geojson/7946.0.10: resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==} dev: true @@ -2948,13 +2485,19 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 dev: true /@types/http-cache-semantics/4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true + /@types/http-proxy/1.17.9: + resolution: {integrity: sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==} + dependencies: + '@types/node': 18.11.9 + dev: true + /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true @@ -2971,10 +2514,14 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true - /@types/jsdom/20.0.0: - resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} + /@types/js-yaml/4.0.5: + resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} + dev: true + + /@types/jsdom/20.0.1: + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 '@types/tough-cookie': 4.0.2 parse5: 7.1.1 dev: true @@ -2986,11 +2533,28 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 dev: true - /@types/lodash/4.14.185: - resolution: {integrity: sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==} + /@types/linkify-it/3.0.2: + resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} + dev: true + + /@types/lodash-es/4.17.6: + resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==} + dependencies: + '@types/lodash': 4.14.188 + dev: true + + /@types/lodash/4.14.188: + resolution: {integrity: sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==} + dev: true + + /@types/markdown-it/12.2.3: + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + dependencies: + '@types/linkify-it': 3.0.2 + '@types/mdurl': 1.0.2 dev: true /@types/mdast/3.0.10: @@ -2999,6 +2563,16 @@ packages: '@types/unist': 2.0.6 dev: true + /@types/mdurl/1.0.2: + resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} + dev: true + + /@types/micromatch/4.0.2: + resolution: {integrity: sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==} + dependencies: + '@types/braces': 3.0.1 + dev: true + /@types/mime/3.0.1: resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} dev: true @@ -3011,6 +2585,13 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true + /@types/node-fetch/2.6.2: + resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} + dependencies: + '@types/node': 18.11.9 + form-data: 3.0.1 + dev: true + /@types/node/14.18.29: resolution: {integrity: sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A==} dev: true @@ -3019,8 +2600,9 @@ packages: resolution: {integrity: sha512-6u+36Dj3aDzhfBVUf/mfmc92OEdzQ2kx2jcXGdigfl70E/neV21ZHE6UCz4MDzTRcVqGAM27fk+DLXvyDsn3Jw==} dev: true - /@types/node/18.7.21: - resolution: {integrity: sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==} + /@types/node/18.11.9: + resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} + dev: true /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -3030,10 +2612,6 @@ packages: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: true - /@types/prettier/2.7.0: - resolution: {integrity: sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==} - dev: true - /@types/prettier/2.7.1: resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} dev: true @@ -3049,14 +2627,35 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 + dev: true + + /@types/retry/0.12.0: + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + dev: true + + /@types/rollup-plugin-visualizer/4.2.1: + resolution: {integrity: sha512-Fk4y0EgmsSbvbayYhtSI9+cGvgw1rcQ9RlbExkQt4ivXRdiEwFKuRpxNuJCr0JktXIvOPUuPR7GSmtyZu0dujQ==} + dependencies: + '@types/node': 18.11.9 + rollup: 2.79.1 + dev: true + + /@types/semver/7.3.12: + resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==} + dev: true + + /@types/serve-index/1.9.1: + resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} + dependencies: + '@types/express': 4.17.14 dev: true /@types/serve-static/1.15.0: resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} dependencies: '@types/mime': 3.0.1 - '@types/node': 18.7.21 + '@types/node': 18.11.9 dev: true /@types/sinonjs__fake-timers/8.1.1: @@ -3067,6 +2666,12 @@ packages: resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} dev: true + /@types/sockjs/0.3.33: + resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} + dependencies: + '@types/node': 18.11.9 + dev: true + /@types/stack-utils/2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true @@ -3089,7 +2694,17 @@ packages: /@types/uuid/8.3.4: resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} - dev: false + dev: true + + /@types/web-bluetooth/0.0.16: + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + dev: true + + /@types/ws/8.5.3: + resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + dependencies: + '@types/node': 18.11.9 + dev: true /@types/yargs-parser/21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} @@ -3105,12 +2720,12 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 dev: true optional: true - /@typescript-eslint/eslint-plugin/5.38.0_4gkcvl6qsi23tqqawfqgcwtp54: - resolution: {integrity: sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==} + /@typescript-eslint/eslint-plugin/5.42.1_2udltptbznfmezdozpdoa2aemq: + resolution: {integrity: sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -3120,49 +2735,24 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/type-utils': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku - '@typescript-eslint/utils': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku + '@typescript-eslint/parser': 5.42.1_rmayb2veg2btbq6mbmnyivgasy + '@typescript-eslint/scope-manager': 5.42.1 + '@typescript-eslint/type-utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy + '@typescript-eslint/utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy debug: 4.3.4 - eslint: 8.24.0 + eslint: 8.27.0 ignore: 5.2.0 + natural-compare-lite: 1.4.0 regexpp: 3.2.0 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.8.3 - typescript: 4.8.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.8.4 + typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/eslint-plugin/5.38.0_wsb62dxj2oqwgas4kadjymcmry: - resolution: {integrity: sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/type-utils': 5.38.0_irgkl5vooow2ydyo6aokmferha - '@typescript-eslint/utils': 5.38.0_irgkl5vooow2ydyo6aokmferha - debug: 4.3.4 - eslint: 8.23.1 - ignore: 5.2.0 - regexpp: 3.2.0 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.8.3 - typescript: 4.8.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser/5.38.0_7ilbxdl5iguzcjriqqcg2m5cku: - resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} + /@typescript-eslint/parser/5.42.1_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3171,46 +2761,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 + '@typescript-eslint/scope-manager': 5.42.1 + '@typescript-eslint/types': 5.42.1 + '@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4 debug: 4.3.4 - eslint: 8.24.0 - typescript: 4.8.3 + eslint: 8.27.0 + typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.38.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 - debug: 4.3.4 - eslint: 8.23.1 - typescript: 4.8.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager/5.38.0: - resolution: {integrity: sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==} + /@typescript-eslint/scope-manager/5.42.1: + resolution: {integrity: sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/visitor-keys': 5.38.0 + '@typescript-eslint/types': 5.42.1 + '@typescript-eslint/visitor-keys': 5.42.1 dev: true - /@typescript-eslint/type-utils/5.38.0_7ilbxdl5iguzcjriqqcg2m5cku: - resolution: {integrity: sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==} + /@typescript-eslint/type-utils/5.42.1_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -3219,43 +2789,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 - '@typescript-eslint/utils': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku + '@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4 + '@typescript-eslint/utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy debug: 4.3.4 - eslint: 8.24.0 - tsutils: 3.21.0_typescript@4.8.3 - typescript: 4.8.3 + eslint: 8.27.0 + tsutils: 3.21.0_typescript@4.8.4 + typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/type-utils/5.38.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 - '@typescript-eslint/utils': 5.38.0_irgkl5vooow2ydyo6aokmferha - debug: 4.3.4 - eslint: 8.23.1 - tsutils: 3.21.0_typescript@4.8.3 - typescript: 4.8.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types/5.38.0: - resolution: {integrity: sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==} + /@typescript-eslint/types/5.42.1: + resolution: {integrity: sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.38.0_typescript@4.8.3: - resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} + /@typescript-eslint/typescript-estree/5.42.1_typescript@4.8.4: + resolution: {integrity: sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -3263,67 +2813,62 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/visitor-keys': 5.38.0 + '@typescript-eslint/types': 5.42.1 + '@typescript-eslint/visitor-keys': 5.42.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.8.3 - typescript: 4.8.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.8.4 + typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.38.0_7ilbxdl5iguzcjriqqcg2m5cku: - resolution: {integrity: sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==} + /@typescript-eslint/utils/5.42.1_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 - eslint: 8.24.0 + '@types/semver': 7.3.12 + '@typescript-eslint/scope-manager': 5.42.1 + '@typescript-eslint/types': 5.42.1 + '@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4 + eslint: 8.27.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.24.0 + eslint-utils: 3.0.0_eslint@8.27.0 + semver: 7.3.8 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils/5.38.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 - eslint: 8.23.1 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.23.1 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys/5.38.0: - resolution: {integrity: sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==} + /@typescript-eslint/visitor-keys/5.42.1: + resolution: {integrity: sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/types': 5.42.1 eslint-visitor-keys: 3.3.0 dev: true - /@vitest/coverage-c8/0.23.4_y2hohvmcqnhseytaw4yjcnsnkm: - resolution: {integrity: sha512-jmD00a5DQH9gu9K+YdvVhcMuv2CzHvU4gCnySS40Ec5hKlXtlCzRfNHl00VnhfuBeaQUmaQYe60BLT413HyDdg==} + /@vitejs/plugin-vue/3.2.0_vite@3.2.3+vue@3.2.41: + resolution: {integrity: sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^3.0.0 + vue: ^3.2.25 + dependencies: + vite: 3.2.3 + vue: 3.2.41 + dev: true + + /@vitest/coverage-c8/0.25.1_oullksb5ic6y72oh2wekoaiuii: + resolution: {integrity: sha512-gpl5QNaNeIN0mfRiosCqBFoZcizb5GA458TDnOQXkGDc4kklazxn70u9evGfV62wiiAUfGGebgRhxlBkAa6m6g==} dependencies: c8: 7.12.0 - vitest: 0.23.4_y2hohvmcqnhseytaw4yjcnsnkm + vitest: 0.25.1_oullksb5ic6y72oh2wekoaiuii transitivePeerDependencies: - '@edge-runtime/vm' - '@vitest/browser' @@ -3333,16 +2878,130 @@ packages: - less - sass - stylus + - sugarss - supports-color - terser dev: true - /@vitest/ui/0.23.4: - resolution: {integrity: sha512-lNZVTTrkHThGAwNQ1ah1qCNnm70r7OLB5LCUdSqboStve/1eKTrtt27QfDSSUTG8AVJQzU0eaN/j8UocH+CqfA==} + /@vitest/ui/0.25.1: + resolution: {integrity: sha512-VjzyfLjNS5Zc7XCCFJW3cM2iVW305D65NG0PIWefA4A8mwOH/QJJ4nFj/4cwXzwL0/VT3/ppvpv3UDNZoh/YOQ==} dependencies: sirv: 2.0.2 dev: true + /@vue/compiler-core/3.2.41: + resolution: {integrity: sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==} + dependencies: + '@babel/parser': 7.19.1 + '@vue/shared': 3.2.41 + estree-walker: 2.0.2 + source-map: 0.6.1 + dev: true + + /@vue/compiler-dom/3.2.41: + resolution: {integrity: sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==} + dependencies: + '@vue/compiler-core': 3.2.41 + '@vue/shared': 3.2.41 + dev: true + + /@vue/compiler-sfc/3.2.41: + resolution: {integrity: sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==} + requiresBuild: true + dependencies: + '@babel/parser': 7.19.1 + '@vue/compiler-core': 3.2.41 + '@vue/compiler-dom': 3.2.41 + '@vue/compiler-ssr': 3.2.41 + '@vue/reactivity-transform': 3.2.41 + '@vue/shared': 3.2.41 + estree-walker: 2.0.2 + magic-string: 0.25.9 + postcss: 8.4.18 + source-map: 0.6.1 + dev: true + + /@vue/compiler-ssr/3.2.41: + resolution: {integrity: sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==} + dependencies: + '@vue/compiler-dom': 3.2.41 + '@vue/shared': 3.2.41 + dev: true + + /@vue/devtools-api/6.4.5: + resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==} + dev: true + + /@vue/reactivity-transform/3.2.41: + resolution: {integrity: sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==} + dependencies: + '@babel/parser': 7.19.1 + '@vue/compiler-core': 3.2.41 + '@vue/shared': 3.2.41 + estree-walker: 2.0.2 + magic-string: 0.25.9 + dev: true + + /@vue/reactivity/3.2.41: + resolution: {integrity: sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==} + dependencies: + '@vue/shared': 3.2.41 + dev: true + + /@vue/runtime-core/3.2.41: + resolution: {integrity: sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==} + dependencies: + '@vue/reactivity': 3.2.41 + '@vue/shared': 3.2.41 + dev: true + + /@vue/runtime-dom/3.2.41: + resolution: {integrity: sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==} + dependencies: + '@vue/runtime-core': 3.2.41 + '@vue/shared': 3.2.41 + csstype: 2.6.21 + dev: true + + /@vue/server-renderer/3.2.41_vue@3.2.41: + resolution: {integrity: sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==} + peerDependencies: + vue: 3.2.41 + dependencies: + '@vue/compiler-ssr': 3.2.41 + '@vue/shared': 3.2.41 + vue: 3.2.41 + dev: true + + /@vue/shared/3.2.41: + resolution: {integrity: sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==} + dev: true + + /@vueuse/core/9.4.0_vue@3.2.41: + resolution: {integrity: sha512-JzgenGj1ZF2BHOen5rsFiAyyI9sXAv7aKhNLlm9b7SwYQeKTcxTWdhudonURCSP3Egl9NQaRBzes2lv/1JUt/Q==} + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.4.0 + '@vueuse/shared': 9.4.0_vue@3.2.41 + vue-demi: 0.13.11_vue@3.2.41 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/metadata/9.4.0: + resolution: {integrity: sha512-7GKMdGAsJyQJl35MYOz/RDpP0FxuiZBRDSN79QIPbdqYx4Sd0sVTnIC68KJ6Oln0t0SouvSUMvRHuno216Ud2Q==} + dev: true + + /@vueuse/shared/9.4.0_vue@3.2.41: + resolution: {integrity: sha512-fTuem51KwMCnqUKkI8B57qAIMcFovtGgsCtAeqxIzH3i6nE9VYge+gVfneNHAAy7lj8twbkNfqQSygOPJTm4tQ==} + dependencies: + vue-demi: 0.13.11_vue@3.2.41 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + /@wdio/config/7.16.11: resolution: {integrity: sha512-sIk9FINQfXohuDONb8RA1uv+29XvUw6OBHfaaU7/c9gfKiOWiRczdfiLqfySZRwYgEgNhzCw5vHIogTry1h+xQ==} engines: {node: '>=12.0.0'} @@ -3385,6 +3044,152 @@ packages: p-iteration: 1.1.8 dev: true + /@webassemblyjs/ast/1.11.1: + resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + dev: true + + /@webassemblyjs/floating-point-hex-parser/1.11.1: + resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} + dev: true + + /@webassemblyjs/helper-api-error/1.11.1: + resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} + dev: true + + /@webassemblyjs/helper-buffer/1.11.1: + resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} + dev: true + + /@webassemblyjs/helper-numbers/1.11.1: + resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.1 + '@webassemblyjs/helper-api-error': 1.11.1 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode/1.11.1: + resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} + dev: true + + /@webassemblyjs/helper-wasm-section/1.11.1: + resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + dev: true + + /@webassemblyjs/ieee754/1.11.1: + resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128/1.11.1: + resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8/1.11.1: + resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} + dev: true + + /@webassemblyjs/wasm-edit/1.11.1: + resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/helper-wasm-section': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + '@webassemblyjs/wasm-opt': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + '@webassemblyjs/wast-printer': 1.11.1 + dev: true + + /@webassemblyjs/wasm-gen/1.11.1: + resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/ieee754': 1.11.1 + '@webassemblyjs/leb128': 1.11.1 + '@webassemblyjs/utf8': 1.11.1 + dev: true + + /@webassemblyjs/wasm-opt/1.11.1: + resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-buffer': 1.11.1 + '@webassemblyjs/wasm-gen': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + dev: true + + /@webassemblyjs/wasm-parser/1.11.1: + resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/helper-api-error': 1.11.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + '@webassemblyjs/ieee754': 1.11.1 + '@webassemblyjs/leb128': 1.11.1 + '@webassemblyjs/utf8': 1.11.1 + dev: true + + /@webassemblyjs/wast-printer/1.11.1: + resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} + dependencies: + '@webassemblyjs/ast': 1.11.1 + '@xtuc/long': 4.2.2 + dev: true + + /@webpack-cli/configtest/1.2.0_pda42hcaj7d62cr262fr632kue: + resolution: {integrity: sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==} + peerDependencies: + webpack: 4.x.x || 5.x.x + webpack-cli: 4.x.x + dependencies: + webpack: 5.75.0_webpack-cli@4.10.0 + webpack-cli: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + dev: true + + /@webpack-cli/info/1.5.0_webpack-cli@4.10.0: + resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==} + peerDependencies: + webpack-cli: 4.x.x + dependencies: + envinfo: 7.8.1 + webpack-cli: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + dev: true + + /@webpack-cli/serve/1.7.0_ud4agclah7rahur6ntojouq57y: + resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==} + peerDependencies: + webpack-cli: 4.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + dependencies: + webpack-cli: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + webpack-dev-server: 4.11.1_pda42hcaj7d62cr262fr632kue + dev: true + + /@xtuc/ieee754/1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long/4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + /JSONSelect/0.4.0: resolution: {integrity: sha512-VRLR3Su35MH+XV2lrvh9O7qWoug/TUyj9tLDjn9rtpUCNnILLrHjgd/tB0KrhugCxUpj3UqoLqfYb3fLJdIQQQ==} engines: {node: '>=0.4.7'} @@ -3428,6 +3233,21 @@ packages: acorn-walk: 7.2.0 dev: true + /acorn-globals/7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + dependencies: + acorn: 8.8.0 + acorn-walk: 8.2.0 + dev: true + + /acorn-import-assertions/1.8.0_acorn@8.8.0: + resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.8.0 + dev: true + /acorn-jsx/5.3.2_acorn@8.8.0: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3436,14 +3256,6 @@ packages: acorn: 8.8.0 dev: true - /acorn-node/1.8.2: - resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} - dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 - xtend: 4.0.2 - dev: true - /acorn-walk/7.2.0: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} @@ -3466,10 +3278,6 @@ packages: hasBin: true dev: true - /add-stream/1.0.0: - resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - dev: true - /agent-base/6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -3479,17 +3287,6 @@ packages: - supports-color dev: true - /agentkeepalive/4.2.1: - resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} - engines: {node: '>= 8.0.0'} - dependencies: - debug: 4.3.4 - depd: 1.1.2 - humanize-ms: 1.2.1 - transitivePeerDependencies: - - supports-color - dev: true - /aggregate-error/3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -3498,6 +3295,34 @@ packages: indent-string: 4.0.0 dev: true + /ajv-formats/2.1.1_ajv@8.11.0: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.11.0 + dev: true + + /ajv-keywords/3.5.2_ajv@6.12.6: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + + /ajv-keywords/5.1.0_ajv@8.11.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + dependencies: + ajv: 8.11.0 + fast-deep-equal: 3.1.3 + dev: true + /ajv/6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -3516,6 +3341,25 @@ packages: uri-js: 4.4.1 dev: true + /algoliasearch/4.14.2: + resolution: {integrity: sha512-ngbEQonGEmf8dyEh5f+uOIihv4176dgbuOZspiuhmTTBRBuzWu3KCGHre6uHj5YyuC7pNvQGzB6ZNJyZi0z+Sg==} + dependencies: + '@algolia/cache-browser-local-storage': 4.14.2 + '@algolia/cache-common': 4.14.2 + '@algolia/cache-in-memory': 4.14.2 + '@algolia/client-account': 4.14.2 + '@algolia/client-analytics': 4.14.2 + '@algolia/client-common': 4.14.2 + '@algolia/client-personalization': 4.14.2 + '@algolia/client-search': 4.14.2 + '@algolia/logger-common': 4.14.2 + '@algolia/logger-console': 4.14.2 + '@algolia/requester-browser-xhr': 4.14.2 + '@algolia/requester-common': 4.14.2 + '@algolia/requester-node-http': 4.14.2 + '@algolia/transporter': 4.14.2 + dev: true + /amdefine/1.0.1: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} engines: {node: '>=0.4.2'} @@ -3534,8 +3378,8 @@ packages: type-fest: 0.21.3 dev: true - /ansi-html/0.0.7: - resolution: {integrity: sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==} + /ansi-html-community/0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} hasBin: true dev: true @@ -3599,13 +3443,6 @@ packages: execa: 1.0.0 dev: true - /append-buffer/1.0.2: - resolution: {integrity: sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==} - engines: {node: '>=0.10.0'} - dependencies: - buffer-equal: 1.0.0 - dev: true - /arch/2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} dev: true @@ -3624,39 +3461,27 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /arr-diff/4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-flatten/1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-union/3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: true - /array-flatten/1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: true + /array-flatten/2.1.2: + resolution: {integrity: sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==} + dev: true + /array-ify/1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} dev: true + /array-timsort/1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + dev: true + /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array-unique/0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - dev: true - /arrify/1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} @@ -3677,11 +3502,6 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true - /assign-symbols/1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - dev: true - /ast-types/0.13.4: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} @@ -3707,12 +3527,6 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /atob/2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - dev: true - /aws-sign2/0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} dev: true @@ -3729,25 +3543,17 @@ packages: - debug dev: true - /axios/0.26.0: - resolution: {integrity: sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==} - dependencies: - follow-redirects: 1.15.2_debug@4.3.2 - transitivePeerDependencies: - - debug - dev: true - - /babel-jest/29.1.0_@babel+core@7.12.3: - resolution: {integrity: sha512-0XiBgPRhMSng+ThuXz0M/WpOeml/q5S4BFIaDS5uQb+lCjOzd0OfYEN4hWte5fDy7SZ6rNmEi16UpWGurSg2nQ==} + /babel-jest/29.3.1_@babel+core@7.12.3: + resolution: {integrity: sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: '@babel/core': 7.12.3 - '@jest/transform': 29.1.0 + '@jest/transform': 29.3.1 '@types/babel__core': 7.1.19 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.0.2_@babel+core@7.12.3 + babel-preset-jest: 29.2.0_@babel+core@7.12.3 chalk: 4.1.2 graceful-fs: 4.2.10 slash: 3.0.0 @@ -3755,12 +3561,6 @@ packages: - supports-color dev: true - /babel-plugin-dynamic-import-node/2.3.3: - resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} - dependencies: - object.assign: 4.1.4 - dev: true - /babel-plugin-istanbul/6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} @@ -3774,8 +3574,8 @@ packages: - supports-color dev: true - /babel-plugin-jest-hoist/29.0.2: - resolution: {integrity: sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg==} + /babel-plugin-jest-hoist/29.2.0: + resolution: {integrity: sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.18.10 @@ -3784,42 +3584,6 @@ packages: '@types/babel__traverse': 7.18.2 dev: true - /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.12.3: - resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.19.1 - '@babel/core': 7.12.3 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.12.3 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.12.3: - resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.12.3 - core-js-compat: 3.25.2 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.12.3: - resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.12.3 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.12.3 - transitivePeerDependencies: - - supports-color - dev: true - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.12.3: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -3840,30 +3604,17 @@ packages: '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.12.3 dev: true - /babel-preset-jest/29.0.2_@babel+core@7.12.3: - resolution: {integrity: sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA==} + /babel-preset-jest/29.2.0_@babel+core@7.12.3: + resolution: {integrity: sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.12.3 - babel-plugin-jest-hoist: 29.0.2 + babel-plugin-jest-hoist: 29.2.0 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.3 dev: true - /babelify/10.0.0_@babel+core@7.12.3: - resolution: {integrity: sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.12.3 - dev: true - - /bail/1.0.5: - resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} - dev: true - /bail/2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} dev: true @@ -3872,23 +3623,14 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true - /base/0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.0 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - dev: true - /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true + /batch/0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + dev: true + /bcrypt-pbkdf/1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: @@ -3912,8 +3654,8 @@ packages: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: true - /body-parser/1.20.0: - resolution: {integrity: sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==} + /body-parser/1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dependencies: bytes: 3.1.2 @@ -3924,7 +3666,7 @@ packages: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.10.3 + qs: 6.11.0 raw-body: 2.5.1 type-is: 1.6.18 unpipe: 1.0.0 @@ -3932,13 +3674,17 @@ packages: - supports-color dev: true - /body/5.1.0: - resolution: {integrity: sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==} + /body-scroll-lock/4.0.0-beta.0: + resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} + dev: true + + /bonjour-service/1.0.14: + resolution: {integrity: sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==} dependencies: - continuable-cache: 0.3.1 - error: 7.2.1 - raw-body: 1.1.7 - safe-json-parse: 1.0.1 + array-flatten: 2.1.2 + dns-equal: 1.0.0 + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 dev: true /brace-expansion/1.1.11: @@ -3948,22 +3694,10 @@ packages: concat-map: 0.0.1 dev: true - /braces/2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color + balanced-match: 1.0.2 dev: true /braces/3.0.2: @@ -3977,21 +3711,15 @@ packages: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} dev: true - /browser-resolve/1.11.3: - resolution: {integrity: sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==} - dependencies: - resolve: 1.1.7 - dev: true - /browserslist/4.21.4: resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001409 - electron-to-chromium: 1.4.257 + caniuse-lite: 1.0.30001431 + electron-to-chromium: 1.4.284 node-releases: 2.0.6 - update-browserslist-db: 1.0.9_browserslist@4.21.4 + update-browserslist-db: 1.0.10_browserslist@4.21.4 dev: true /bser/2.1.1: @@ -4004,19 +3732,10 @@ packages: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true - /buffer-equal/1.0.0: - resolution: {integrity: sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==} - engines: {node: '>=0.4.0'} - dev: true - /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer-shims/1.0.0: - resolution: {integrity: sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==} - dev: true - /buffer/5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -4024,8 +3743,14 @@ packages: ieee754: 1.2.1 dev: true - /bytes/1.0.0: - resolution: {integrity: sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==} + /builtin-modules/3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /bytes/3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} dev: true /bytes/3.1.2: @@ -4052,21 +3777,6 @@ packages: yargs-parser: 20.2.9 dev: true - /cache-base/1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.0 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - dev: true - /cacheable-lookup/5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} @@ -4085,10 +3795,6 @@ packages: responselike: 2.0.1 dev: true - /cached-path-relative/1.1.0: - resolution: {integrity: sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==} - dev: true - /cachedir/2.3.0: resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} engines: {node: '>=6'} @@ -4125,18 +3831,14 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001409: - resolution: {integrity: sha512-V0mnJ5dwarmhYv8/MzhJ//aW68UpvnQBXv8lJ2QUsvn2pHcmAuNtu8hQEDz37XnA1iE+lRR9CIfGWWpgJ5QedQ==} + /caniuse-lite/1.0.30001431: + resolution: {integrity: sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==} dev: true /caseless/0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /ccount/1.1.0: - resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} - dev: true - /chai/4.3.6: resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} engines: {node: '>=4'} @@ -4191,10 +3893,6 @@ packages: engines: {node: '>=10'} dev: true - /character-entities-html4/1.1.4: - resolution: {integrity: sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==} - dev: true - /character-entities-legacy/1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} dev: true @@ -4235,8 +3933,14 @@ packages: fsevents: 2.3.2 dev: true - /ci-info/3.4.0: - resolution: {integrity: sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==} + /chrome-trace-event/1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + dev: true + + /ci-info/3.6.2: + resolution: {integrity: sha512-lVZdhvbEudris15CLytp2u6Y0p5EKfztae9Fqa189MfNmln9F33XuH69v5fvNfiRN5/0eAUz2yJL3mo+nhaRKg==} + engines: {node: '>=8'} dev: true /cjs-module-lexer/1.2.2: @@ -4250,14 +3954,11 @@ packages: jsonlint: 1.6.0 dev: true - /class-utils/0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} + /clean-regexp/1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 + escape-string-regexp: 1.0.5 dev: true /clean-stack/2.2.0: @@ -4265,6 +3966,14 @@ packages: engines: {node: '>=6'} dev: true + /clear-module/4.1.2: + resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==} + engines: {node: '>=8'} + dependencies: + parent-module: 2.0.0 + resolve-from: 5.0.0 + dev: true + /cli-cursor/3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -4297,14 +4006,6 @@ packages: string-width: 5.1.2 dev: true - /cliui/6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: true - /cliui/7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -4313,9 +4014,13 @@ packages: wrap-ansi: 7.0.0 dev: true - /clone-buffer/1.0.0: - resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} - engines: {node: '>= 0.10'} + /clone-deep/4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 dev: true /clone-response/1.0.3: @@ -4324,44 +4029,15 @@ packages: mimic-response: 1.0.1 dev: true - /clone-stats/1.0.0: - resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} - dev: true - - /clone/2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - dev: true - - /cloneable-readable/1.1.3: - resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} - dependencies: - inherits: 2.0.4 - process-nextick-args: 2.0.1 - readable-stream: 2.3.7 - dev: true - /co/4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true - /collapse-white-space/1.0.6: - resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} - dev: true - /collect-v8-coverage/1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} dev: true - /collection-visit/1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: true - /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -4399,8 +4075,8 @@ packages: delayed-stream: 1.0.0 dev: true - /comma-separated-tokens/1.0.8: - resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true /commander/5.1.0: @@ -4411,13 +4087,28 @@ packages: /commander/7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} - dev: false /commander/9.4.0: resolution: {integrity: sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==} engines: {node: ^12.20.0 || >=14} dev: true + /commander/9.4.1: + resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /comment-json/4.2.3: + resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} + engines: {node: '>= 6'} + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + dev: true + /comment-parser/1.3.1: resolution: {integrity: sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==} engines: {node: '>= 12.0.0'} @@ -4435,45 +4126,34 @@ packages: dot-prop: 5.3.0 dev: true - /component-emitter/1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + /compressible/2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression/1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color dev: true /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /concat-stream/1.5.2: - resolution: {integrity: sha512-H6xsIBfQ94aESBG8jGHXQ7i5AEpy5ZeVaLDOisDICiTCKpqEfr34/KmTrspKQNoLKNu9gTkovlpQcUi630AKiQ==} - engines: {'0': node >= 0.8} - dependencies: - inherits: 2.0.4 - readable-stream: 2.0.6 - typedarray: 0.0.6 - dev: true - - /concat-stream/1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.7 - typedarray: 0.0.6 - dev: true - - /concat-stream/2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.0 - typedarray: 0.0.6 - dev: true - - /concurrently/7.4.0: - resolution: {integrity: sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA==} + /concurrently/7.5.0: + resolution: {integrity: sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==} engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} hasBin: true dependencies: @@ -4488,6 +4168,23 @@ packages: yargs: 17.5.1 dev: true + /configstore/5.0.1: + resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} + engines: {node: '>=8'} + dependencies: + dot-prop: 5.3.0 + graceful-fs: 4.2.10 + make-dir: 3.1.0 + unique-string: 2.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 4.0.0 + dev: true + + /connect-history-api-fallback/2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + dev: true + /content-disposition/0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -4500,10 +4197,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /continuable-cache/0.3.1: - resolution: {integrity: sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==} - dev: true - /conventional-changelog-angular/5.0.13: resolution: {integrity: sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==} engines: {node: '>=10'} @@ -4512,33 +4205,6 @@ packages: q: 1.5.1 dev: true - /conventional-changelog-atom/2.0.8: - resolution: {integrity: sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-codemirror/2.0.8: - resolution: {integrity: sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-config-spec/2.1.0: - resolution: {integrity: sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==} - dev: true - - /conventional-changelog-conventionalcommits/4.6.3: - resolution: {integrity: sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - lodash: 4.17.21 - q: 1.5.1 - dev: true - /conventional-changelog-conventionalcommits/5.0.0: resolution: {integrity: sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==} engines: {node: '>=10'} @@ -4548,108 +4214,6 @@ packages: q: 1.5.1 dev: true - /conventional-changelog-core/4.2.4: - resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==} - engines: {node: '>=10'} - dependencies: - add-stream: 1.0.0 - conventional-changelog-writer: 5.0.1 - conventional-commits-parser: 3.2.4 - dateformat: 3.0.3 - get-pkg-repo: 4.2.1 - git-raw-commits: 2.0.11 - git-remote-origin-url: 2.0.0 - git-semver-tags: 4.1.1 - lodash: 4.17.21 - normalize-package-data: 3.0.3 - q: 1.5.1 - read-pkg: 3.0.0 - read-pkg-up: 3.0.0 - through2: 4.0.2 - dev: true - - /conventional-changelog-ember/2.0.9: - resolution: {integrity: sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-eslint/3.0.9: - resolution: {integrity: sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-express/2.0.6: - resolution: {integrity: sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-jquery/3.0.11: - resolution: {integrity: sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true - - /conventional-changelog-jshint/2.0.9: - resolution: {integrity: sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - q: 1.5.1 - dev: true - - /conventional-changelog-preset-loader/2.3.4: - resolution: {integrity: sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==} - engines: {node: '>=10'} - dev: true - - /conventional-changelog-writer/5.0.1: - resolution: {integrity: sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - conventional-commits-filter: 2.0.7 - dateformat: 3.0.3 - handlebars: 4.7.7 - json-stringify-safe: 5.0.1 - lodash: 4.17.21 - meow: 8.1.2 - semver: 6.3.0 - split: 1.0.1 - through2: 4.0.2 - dev: true - - /conventional-changelog/3.1.25: - resolution: {integrity: sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==} - engines: {node: '>=10'} - dependencies: - conventional-changelog-angular: 5.0.13 - conventional-changelog-atom: 2.0.8 - conventional-changelog-codemirror: 2.0.8 - conventional-changelog-conventionalcommits: 4.6.3 - conventional-changelog-core: 4.2.4 - conventional-changelog-ember: 2.0.9 - conventional-changelog-eslint: 3.0.9 - conventional-changelog-express: 2.0.6 - conventional-changelog-jquery: 3.0.11 - conventional-changelog-jshint: 2.0.9 - conventional-changelog-preset-loader: 2.3.4 - dev: true - - /conventional-commits-filter/2.0.7: - resolution: {integrity: sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==} - engines: {node: '>=10'} - dependencies: - lodash.ismatch: 4.4.0 - modify-values: 1.0.1 - dev: true - /conventional-commits-parser/3.2.4: resolution: {integrity: sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==} engines: {node: '>=10'} @@ -4663,27 +4227,16 @@ packages: through2: 4.0.2 dev: true - /conventional-recommended-bump/6.1.0: - resolution: {integrity: sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - concat-stream: 2.0.0 - conventional-changelog-preset-loader: 2.3.4 - conventional-commits-filter: 2.0.7 - conventional-commits-parser: 3.2.4 - git-raw-commits: 2.0.11 - git-semver-tags: 4.1.1 - meow: 8.1.2 - q: 1.5.1 - dev: true - /convert-source-map/1.8.0: resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} dependencies: safe-buffer: 5.1.2 dev: true + /convert-source-map/2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + /cookie-signature/1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: true @@ -4693,17 +4246,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /copy-descriptor/0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: true - - /core-js-compat/3.25.2: - resolution: {integrity: sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ==} - dependencies: - browserslist: 4.21.4 - dev: true - /core-util-is/1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true @@ -4712,7 +4254,19 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true - /cosmiconfig-typescript-loader/4.1.0_3owiowz3ujipd4k6pbqn3n7oui: + /cose-base/1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + dependencies: + layout-base: 1.0.2 + dev: false + + /cose-base/2.1.0: + resolution: {integrity: sha512-HTMm07dhxq1dIPGWwpiVrIk9n+DH7KYmqWA786mLe8jDS+1ZjGtJGIIsJVKoseZXS6/FxiUWCJ2B7XzqUCuhPw==} + dependencies: + layout-base: 2.0.1 + dev: false + + /cosmiconfig-typescript-loader/4.1.0_nxlrwu45zhpwmwjzs33dzt3ak4: resolution: {integrity: sha512-HbWIuR5O+XO5Oj9SZ5bzgrD4nN+rfhrm2PMb0FVx+t+XIvC45n8F0oTNnztXtspWGw0i2IzHaUWFD5LzV1JB4A==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -4723,8 +4277,8 @@ packages: dependencies: '@types/node': 14.18.29 cosmiconfig: 7.0.1 - ts-node: 10.9.1_ck2axrxkiif44rdbzjywaqjysa - typescript: 4.8.3 + ts-node: 10.9.1_sqjhzn5m3vxyw66a2xhtc43hby + typescript: 4.8.4 dev: true /cosmiconfig/7.0.1: @@ -4738,6 +4292,17 @@ packages: yaml: 1.10.2 dev: true + /cosmiconfig/7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + /coveralls/3.1.1: resolution: {integrity: sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==} engines: {node: '>=6'} @@ -4774,6 +4339,198 @@ packages: which: 2.0.2 dev: true + /crypto-random-string/2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /cspell-dictionary/6.14.2: + resolution: {integrity: sha512-j2+uZRru3xFtW7VUOoJCrlXta1DBiPq44yGjN/Npc0wtR/aWA/NOdRysap3jWhBS1t43CiA5fqXyMO7d4wDqxw==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-pipe': 6.14.2 + '@cspell/cspell-types': 6.14.2 + cspell-trie-lib: 6.14.2 + fast-equals: 4.0.3 + gensequence: 4.0.2 + dev: true + + /cspell-dictionary/6.14.3: + resolution: {integrity: sha512-yIqJEZZj36j1CmmjAiuQOYZM6T62Ih7k35DhAU1hYVARUEEnFN/Uz72UkDj2SAmURVn2On+bAmZ5zCx0JZzf2g==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-pipe': 6.14.3 + '@cspell/cspell-types': 6.14.3 + cspell-trie-lib: 6.14.3 + fast-equals: 4.0.3 + gensequence: 4.0.2 + dev: true + + /cspell-gitignore/6.14.3: + resolution: {integrity: sha512-CZTGxx3msF6p1Z0xgLe5LXXvve7DooSuRMBMdGn230usce1nKoxpPoPxgs+zXeCpi+FanykKnoZkdRvjolMpOA==} + engines: {node: '>=14'} + hasBin: true + dependencies: + cspell-glob: 6.14.3 + find-up: 5.0.0 + dev: true + + /cspell-glob/6.14.2: + resolution: {integrity: sha512-a9o3lBccEcH2676RGge2YqEORovm+II++D53P6hOW/23ltDe1J509MSY6CJdYdPk/VssOExas6akJ6FbKSCBgw==} + engines: {node: '>=14'} + dependencies: + micromatch: 4.0.5 + dev: true + + /cspell-glob/6.14.3: + resolution: {integrity: sha512-ISwCK8GqM/dnvtaxA17w1MPmMzFLOqdTz+JWIcR4at47T9qd8bNB0X0P4eqyuqgsbKkWbfnSlsYlEjRHTi4a7A==} + engines: {node: '>=14'} + dependencies: + micromatch: 4.0.5 + dev: true + + /cspell-grammar/6.14.2: + resolution: {integrity: sha512-Q9+gwp1U/qnECTqxa7WBMPn6sgBfXPIM68jXg8RgNMAuy1CE+m1eTCM9FBNFNpNKJWjaZPvANLOW5/EStN2A/A==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@cspell/cspell-pipe': 6.14.2 + '@cspell/cspell-types': 6.14.2 + dev: true + + /cspell-grammar/6.14.3: + resolution: {integrity: sha512-Nz8tYUmstyKcFlXbxdw4N8NsQ2ZY/5ztNfouokk47LKaTAS0LyWlLSkZUxN016fMY2h+C+3dI+jaut2H/rtNew==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@cspell/cspell-pipe': 6.14.3 + '@cspell/cspell-types': 6.14.3 + dev: true + + /cspell-io/6.14.2: + resolution: {integrity: sha512-QyQ0BBfDvF6B37SlSsmlzRnaGqiIHt7c5NsCNKf3ZfioTWkNI/fiabvSkpNGBAkELP6BPBxjsG+TaS+swZp+Kg==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-service-bus': 6.14.2 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: true + + /cspell-io/6.14.3: + resolution: {integrity: sha512-EbH+qopgWIzr9SZCGDsF4AWYgucN4QzYeAgyXjTbV9RnNIGKOKovMe3vN9nxjOZyPKv2TvmgU+uMXDM61iObRw==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-service-bus': 6.14.3 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: true + + /cspell-lib/6.14.2: + resolution: {integrity: sha512-QNsmWix0oFi1CjzFfNG1xAJVl1OC+6kiWvq0A1S8VD3LJhJVvBqSv1vudpL1oS7H2/2yxk9PUC/MajGLi5i5MQ==} + engines: {node: '>=14.6'} + dependencies: + '@cspell/cspell-bundled-dicts': 6.14.2 + '@cspell/cspell-pipe': 6.14.2 + '@cspell/cspell-types': 6.14.2 + '@cspell/strong-weak-map': 6.14.2 + clear-module: 4.1.2 + comment-json: 4.2.3 + configstore: 5.0.1 + cosmiconfig: 7.0.1 + cspell-dictionary: 6.14.2 + cspell-glob: 6.14.2 + cspell-grammar: 6.14.2 + cspell-io: 6.14.2 + cspell-trie-lib: 6.14.2 + fast-equals: 4.0.3 + find-up: 5.0.0 + fs-extra: 10.1.0 + gensequence: 4.0.2 + import-fresh: 3.3.0 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + vscode-languageserver-textdocument: 1.0.7 + vscode-uri: 3.0.6 + transitivePeerDependencies: + - encoding + dev: true + + /cspell-lib/6.14.3: + resolution: {integrity: sha512-RJT5Tbe0UCMCtqDWRujjxq9u23sc2XylIpDP7MnpLx8wLVgFv2WPzESYNRGZqceqZYwBAPnpqS9h2ANxXSi8UQ==} + engines: {node: '>=14.6'} + dependencies: + '@cspell/cspell-bundled-dicts': 6.14.3 + '@cspell/cspell-pipe': 6.14.3 + '@cspell/cspell-types': 6.14.3 + '@cspell/strong-weak-map': 6.14.3 + clear-module: 4.1.2 + comment-json: 4.2.3 + configstore: 5.0.1 + cosmiconfig: 7.1.0 + cspell-dictionary: 6.14.3 + cspell-glob: 6.14.3 + cspell-grammar: 6.14.3 + cspell-io: 6.14.3 + cspell-trie-lib: 6.14.3 + fast-equals: 4.0.3 + find-up: 5.0.0 + fs-extra: 10.1.0 + gensequence: 4.0.2 + import-fresh: 3.3.0 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + vscode-languageserver-textdocument: 1.0.7 + vscode-uri: 3.0.6 + transitivePeerDependencies: + - encoding + dev: true + + /cspell-trie-lib/6.14.2: + resolution: {integrity: sha512-+aTRwFUzBPFbJ8zlDwzB1ew/gP7L6kddoXjmqCNeFx9B5DiwN1KPFRo+uBx21JOkoavnviGU//DpyWSU9Cittw==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-pipe': 6.14.2 + '@cspell/cspell-types': 6.14.2 + fs-extra: 10.1.0 + gensequence: 4.0.2 + dev: true + + /cspell-trie-lib/6.14.3: + resolution: {integrity: sha512-WVa5gbD9glsZ4c60qPD5RTwojKc5ooxw/Gn+HC9CBdWv5rE1AmM1V3yVWhYx2ZMbJufboBrzmSjJB9qdmUl3oA==} + engines: {node: '>=14'} + dependencies: + '@cspell/cspell-pipe': 6.14.3 + '@cspell/cspell-types': 6.14.3 + fs-extra: 10.1.0 + gensequence: 4.0.2 + dev: true + + /cspell/6.14.3: + resolution: {integrity: sha512-DimVpUiw2iOSvO1daOTtOWjmryVZdFnPmjPhyhWZUqakOEgE2MgoBuk3cFzXqb8GsGXHQh5PqiWr1rqIkQ99qA==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@cspell/cspell-pipe': 6.14.3 + chalk: 4.1.2 + commander: 9.4.1 + cspell-gitignore: 6.14.3 + cspell-glob: 6.14.3 + cspell-lib: 6.14.3 + fast-json-stable-stringify: 2.1.0 + file-entry-cache: 6.0.1 + fs-extra: 10.1.0 + get-stdin: 8.0.0 + glob: 8.0.3 + imurmurhash: 0.1.4 + semver: 7.3.8 + strip-ansi: 6.0.1 + vscode-uri: 3.0.6 + transitivePeerDependencies: + - encoding + dev: true + /css-tree/1.0.0-alpha.39: resolution: {integrity: sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==} engines: {node: '>=8.0.0'} @@ -4797,42 +4554,29 @@ packages: cssom: 0.3.8 dev: true - /cypress-image-snapshot/4.0.1_cypress@10.8.0: + /csstype/2.6.21: + resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} + dev: true + + /cypress-image-snapshot/4.0.1_bg25yee4qeg7mpleuvd346a3tq: resolution: {integrity: sha512-PBpnhX/XItlx3/DAk5ozsXQHUi72exybBNH5Mpqj1DVmjq+S5Jd9WE5CRa4q5q0zuMZb2V2VpXHth6MjFpgj9Q==} engines: {node: '>=8'} peerDependencies: cypress: ^4.5.0 dependencies: chalk: 2.4.2 - cypress: 10.8.0 + cypress: 10.11.0 fs-extra: 7.0.1 glob: 7.2.3 - jest-image-snapshot: 4.2.0 + jest-image-snapshot: 4.2.0_jest@29.3.1 pkg-dir: 3.0.0 term-img: 4.1.0 transitivePeerDependencies: - jest dev: true - /cypress-image-snapshot/4.0.1_cypress@10.8.0+jest@29.1.1: - resolution: {integrity: sha512-PBpnhX/XItlx3/DAk5ozsXQHUi72exybBNH5Mpqj1DVmjq+S5Jd9WE5CRa4q5q0zuMZb2V2VpXHth6MjFpgj9Q==} - engines: {node: '>=8'} - peerDependencies: - cypress: ^4.5.0 - dependencies: - chalk: 2.4.2 - cypress: 10.8.0 - fs-extra: 7.0.1 - glob: 7.2.3 - jest-image-snapshot: 4.2.0_jest@29.1.1 - pkg-dir: 3.0.0 - term-img: 4.1.0 - transitivePeerDependencies: - - jest - dev: true - - /cypress/10.8.0: - resolution: {integrity: sha512-QVse0dnLm018hgti2enKMVZR9qbIO488YGX06nH5j3Dg1isL38DwrBtyrax02CANU6y8F4EJUuyW6HJKw1jsFA==} + /cypress/10.11.0: + resolution: {integrity: sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==} engines: {node: '>=12.0.0'} hasBin: true requiresBuild: true @@ -4874,13 +4618,39 @@ packages: pretty-bytes: 5.6.0 proxy-from-env: 1.0.0 request-progress: 3.0.0 - semver: 7.3.7 + semver: 7.3.8 supports-color: 8.1.1 tmp: 0.2.1 untildify: 4.0.0 yauzl: 2.10.0 dev: true + /cytoscape-cose-bilkent/4.1.0_cytoscape@3.23.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + dependencies: + cose-base: 1.0.3 + cytoscape: 3.23.0 + dev: false + + /cytoscape-fcose/2.1.0_cytoscape@3.23.0: + resolution: {integrity: sha512-Q3apPl66jf8/2sMsrCjNP247nbDkyIPjA9g5iPMMWNLZgP3/mn9aryF7EFY/oRPEpv7bKJ4jYmCoU5r5/qAc1Q==} + peerDependencies: + cytoscape: ^3.2.0 + dependencies: + cose-base: 2.1.0 + cytoscape: 3.23.0 + dev: false + + /cytoscape/3.23.0: + resolution: {integrity: sha512-gRZqJj/1kiAVPkrVFvz/GccxsXhF3Qwpptl32gKKypO4IlqnKBjTOu+HbXtEggSGzC5KCaHp3/F7GgENrtsFkA==} + engines: {node: '>=0.10'} + dependencies: + heap: 0.2.7 + lodash: 4.17.21 + dev: false + /d3-array/3.2.0: resolution: {integrity: sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==} engines: {node: '>=12'} @@ -5129,20 +4899,11 @@ packages: d3-zoom: 3.0.0 dev: false - /dagre-d3/0.6.4: - resolution: {integrity: sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==} + /dagre-d3-es/7.0.4: + resolution: {integrity: sha512-fQL8ldFR9UYpecz48d1smrXNJ9zGUK38Vl5OzX6Fhn9LR+oQh0GzHRPQylP5kWawmMTKm1QtqcHMVySMJ5CYaQ==} dependencies: d3: 7.6.1 - dagre: 0.8.5 - graphlib: 2.1.8 - lodash: 4.17.21 - dev: false - - /dagre/0.8.5: - resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==} - dependencies: - graphlib: 2.1.8 - lodash: 4.17.21 + lodash-es: 4.17.21 dev: false /dargs/7.0.0: @@ -5176,18 +4937,10 @@ packages: engines: {node: '>=0.11'} dev: true - /dateformat/3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dev: true - /dayjs/1.11.5: resolution: {integrity: sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==} dev: true - /de-indent/1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - dev: true - /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -5199,17 +4952,6 @@ packages: ms: 2.0.0 dev: true - /debug/3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - /debug/3.2.7_supports-color@8.1.1: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -5282,11 +5024,6 @@ packages: character-entities: 2.0.2 dev: true - /decode-uri-component/0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} - engines: {node: '>=0.10'} - dev: true - /decompress-response/6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -5314,43 +5051,21 @@ packages: engines: {node: '>=0.10.0'} dev: true + /default-gateway/6.0.3: + resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} + engines: {node: '>= 10'} + dependencies: + execa: 5.1.1 + dev: true + /defer-to-connect/2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} dev: true - /define-properties/1.1.4: - resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /define-property/0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: true - - /define-property/1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: true - - /define-property/2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: true - - /defined/1.0.0: - resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==} + /define-lazy-prop/2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} dev: true /degenerator/3.0.2: @@ -5394,34 +5109,17 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: true - /detab/2.0.4: - resolution: {integrity: sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==} - dependencies: - repeat-string: 1.6.1 - dev: true - - /detect-indent/6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - dev: true - /detect-newline/3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} dev: true - /detective/5.2.1: - resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} - engines: {node: '>=0.8.0'} - hasBin: true - dependencies: - acorn-node: 1.8.2 - defined: 1.0.0 - minimist: 1.2.6 + /detect-node/2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true - /diff-sequences/29.0.0: - resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==} + /diff-sequences/29.3.1: + resolution: {integrity: sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true @@ -5442,11 +5140,15 @@ packages: path-type: 4.0.0 dev: true - /doctrine-temporary-fork/2.1.0: - resolution: {integrity: sha512-nliqOv5NkE4zMON4UA6AMJE6As35afs8aYXATpU4pTUdIKiARZwrJVEP1boA3Rx1ZXHVkwxkhcq4VkqvsuRLsA==} - engines: {node: '>=0.10.0'} + /dns-equal/1.0.0: + resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} + dev: true + + /dns-packet/5.4.0: + resolution: {integrity: sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==} + engines: {node: '>=6'} dependencies: - esutils: 2.0.3 + '@leichtgewicht/ip-codec': 2.0.4 dev: true /doctrine/3.0.0: @@ -5456,81 +5158,6 @@ packages: esutils: 2.0.3 dev: true - /documentation/13.2.0: - resolution: {integrity: sha512-c7lIXNZ9t3481c+OGpj4lWPhtdmQilg4E04wc6TXH1gYg2wWu+/f3c60Otg2HDRVnCQoXrozSWuUYNl7y7FJxw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@babel/core': 7.12.3 - '@babel/generator': 7.12.1 - '@babel/parser': 7.12.3 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-decorators': 7.19.1_@babel+core@7.12.3 - '@babel/plugin-proposal-do-expressions': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.12.3 - '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-function-bind': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-function-sent': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-pipeline-operator': 7.18.9_@babel+core@7.12.3 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-proposal-throw-expressions': 7.18.6_@babel+core@7.12.3 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.12.3 - '@babel/preset-env': 7.19.1_@babel+core@7.12.3 - '@babel/preset-flow': 7.18.6_@babel+core@7.12.3 - '@babel/preset-react': 7.18.6_@babel+core@7.12.3 - '@babel/preset-stage-0': 7.8.3 - '@babel/traverse': 7.19.1 - '@babel/types': 7.19.0 - ansi-html: 0.0.7 - babelify: 10.0.0_@babel+core@7.12.3 - chalk: 2.4.2 - chokidar: 3.5.3 - concat-stream: 1.6.2 - diff: 4.0.2 - doctrine-temporary-fork: 2.1.0 - get-port: 5.1.1 - git-url-parse: 11.6.0 - github-slugger: 1.2.0 - glob: 7.2.3 - globals-docs: 2.4.1 - highlight.js: 10.7.3 - ini: 1.3.8 - js-yaml: 3.14.1 - lodash: 4.17.21 - mdast-util-inject: 1.1.0 - micromatch: 3.1.10 - mime: 2.6.0 - module-deps-sortable: 5.0.3 - parse-filepath: 1.0.2 - pify: 5.0.0 - read-pkg-up: 4.0.0 - remark: 9.0.0 - remark-html: 8.0.0 - remark-reference-links: 4.0.4 - remark-toc: 5.1.1 - resolve: 1.22.1 - stream-array: 1.1.2 - strip-json-comments: 2.0.1 - tiny-lr: 1.1.1 - unist-builder: 1.0.4 - unist-util-visit: 1.4.1 - vfile: 4.2.1 - vfile-reporter: 6.0.2 - vfile-sort: 2.2.2 - vinyl: 2.2.1 - vinyl-fs: 3.0.3 - vue-template-compiler: 2.7.10 - yargs: 15.4.1 - transitivePeerDependencies: - - supports-color - dev: true - /dom-serializer/2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -5557,8 +5184,8 @@ packages: domelementtype: 2.3.0 dev: true - /dompurify/2.4.0: - resolution: {integrity: sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==} + /dompurify/2.4.1: + resolution: {integrity: sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==} dev: false /domutils/3.0.1: @@ -5576,33 +5203,10 @@ packages: is-obj: 2.0.0 dev: true - /dotgitignore/2.1.0: - resolution: {integrity: sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==} - engines: {node: '>=6'} - dependencies: - find-up: 3.0.0 - minimatch: 3.1.2 - dev: true - /duplexer/0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} dev: true - /duplexer2/0.1.4: - resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} - dependencies: - readable-stream: 2.3.7 - dev: true - - /duplexify/3.7.1: - resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} - dependencies: - end-of-stream: 1.4.4 - inherits: 2.0.4 - readable-stream: 2.3.7 - stream-shift: 1.0.1 - dev: true - /eastasianwidth/0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true @@ -5622,19 +5226,15 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium/1.4.257: - resolution: {integrity: sha512-C65sIwHqNnPC2ADMfse/jWTtmhZMII+x6ADI9gENzrOiI7BpxmfKFE84WkIEl5wEg+7+SfIkwChDlsd1Erju2A==} + /electron-to-chromium/1.4.284: + resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} dev: true - /emittery/0.10.2: - resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} + /emittery/0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} dev: true - /emoji-regex/6.1.1: - resolution: {integrity: sha512-WfVwM9e+M9B/4Qjh9SRnPX2A74Tom3WlVfWF9QWJ8f2BPa1u+/q4aEp1tizZ3vBKAZTg7B6yxn3t9iMjT+dv4w==} - dev: true - /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -5654,6 +5254,14 @@ packages: once: 1.4.0 dev: true + /enhanced-resolve/5.10.0: + resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.10 + tapable: 2.2.1 + dev: true + /enquirer/2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} @@ -5661,36 +5269,43 @@ packages: ansi-colors: 4.1.3 dev: true + /entities/3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + dev: true + /entities/4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} dev: true + /envinfo/7.8.1: + resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} + engines: {node: '>=4'} + hasBin: true + dev: true + /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 dev: true - /error/7.2.1: - resolution: {integrity: sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==} - dependencies: - string-template: 0.2.1 + /es-module-lexer/0.9.3: + resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} dev: true - /esbuild-android-64/0.15.8: - resolution: {integrity: sha512-bVh8FIKOolF7/d4AMzt7xHlL0Ljr+mYKSHI39TJWDkybVWHdn6+4ODL3xZGHOxPpdRpitemXA1WwMKYBsw8dGw==} + /esbuild-android-64/0.15.13: + resolution: {integrity: sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true - dependencies: - esbuild-wasm: 0.15.8 dev: true optional: true - /esbuild-android-arm64/0.15.8: - resolution: {integrity: sha512-ReAMDAHuo0H1h9LxRabI6gwYPn8k6WiUeyxuMvx17yTrJO+SCnIfNc/TSPFvDwtK9MiyiKG/2dBYHouT/M0BXQ==} + /esbuild-android-arm64/0.15.13: + resolution: {integrity: sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -5698,8 +5313,8 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.15.8: - resolution: {integrity: sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==} + /esbuild-darwin-64/0.15.13: + resolution: {integrity: sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -5707,8 +5322,8 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.15.8: - resolution: {integrity: sha512-8tjEaBgAKnXCkP7bhEJmEqdG9HEV6oLkF36BrMzpfW2rgaw0c48Zrxe+9RlfeGvs6gDF4w+agXyTjikzsS3izw==} + /esbuild-darwin-arm64/0.15.13: + resolution: {integrity: sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -5716,8 +5331,8 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.15.8: - resolution: {integrity: sha512-jaxcsGHYzn2L0/lffON2WfH4Nc+d/EwozVTP5K2v016zxMb5UQMhLoJzvLgBqHT1SG0B/mO+a+THnJCMVg15zw==} + /esbuild-freebsd-64/0.15.13: + resolution: {integrity: sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -5725,8 +5340,8 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.15.8: - resolution: {integrity: sha512-2xp2UlljMvX8HExtcg7VHaeQk8OBU0CSl1j18B5CcZmSDkLF9p3utuMXIopG3a08fr9Hv+Dz6+seSXUow/G51w==} + /esbuild-freebsd-arm64/0.15.13: + resolution: {integrity: sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -5734,8 +5349,8 @@ packages: dev: true optional: true - /esbuild-linux-32/0.15.8: - resolution: {integrity: sha512-9u1E54BRz1FQMl86iaHK146+4ID2KYNxL3trLZT4QLLx3M7Q9n4lGG3lrzqUatGR2cKy8c33b0iaCzsItZWkFg==} + /esbuild-linux-32/0.15.13: + resolution: {integrity: sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -5743,8 +5358,8 @@ packages: dev: true optional: true - /esbuild-linux-64/0.15.8: - resolution: {integrity: sha512-4HxrsN9eUzJXdVGMTYA5Xler82FuZUu21bXKN42zcLHHNKCAMPUzD62I+GwDhsdgUBAUj0tRXDdsQHgaP6v0HA==} + /esbuild-linux-64/0.15.13: + resolution: {integrity: sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -5752,8 +5367,8 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.15.8: - resolution: {integrity: sha512-7DVBU9SFjX4+vBwt8tHsUCbE6Vvl6y6FQWHAgyw1lybC5gULqn/WnjHYHN2/LJaZRsDBvxWT4msEgwLGq1Wd3Q==} + /esbuild-linux-arm/0.15.13: + resolution: {integrity: sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -5761,8 +5376,8 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.15.8: - resolution: {integrity: sha512-1OCm7Aq0tEJT70PbxmHSGYDLYP8DKH8r4Nk7/XbVzWaduo9beCjGBB+tGZIHK6DdTQ3h00/4Tb/70YMH/bOtKg==} + /esbuild-linux-arm64/0.15.13: + resolution: {integrity: sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -5770,8 +5385,8 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.15.8: - resolution: {integrity: sha512-yeFoNPVFPEzZvFYBfUQNG2TjGRaCyV1E27OcOg4LOtnGrxb2wA+mkW3luckyv1CEyd00mpAg7UdHx8nlx3ghgA==} + /esbuild-linux-mips64le/0.15.13: + resolution: {integrity: sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -5779,8 +5394,8 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.15.8: - resolution: {integrity: sha512-CEyMMUUNabXibw8OSNmBXhOIGhnjNVl5Lpseiuf00iKN0V47oqDrbo4dsHz1wH62m49AR8iG8wpDlTqfYgKbtg==} + /esbuild-linux-ppc64le/0.15.13: + resolution: {integrity: sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -5788,8 +5403,8 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.15.8: - resolution: {integrity: sha512-OCGSOaspMUjexSCU8ZiA0UnV/NiRU+s2vIfEcAQWQ6u32R+2luyfh/4ZaY6jFbylJE07Esc/yRvb9Q5fXuClXA==} + /esbuild-linux-riscv64/0.15.13: + resolution: {integrity: sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -5797,8 +5412,8 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.15.8: - resolution: {integrity: sha512-RHdpdfxRTSrZXZJlFSLazFU4YwXLB5Rgf6Zr5rffqSsO4y9JybgtKO38bFwxZNlDXliYISXN/YROKrG9s7mZQA==} + /esbuild-linux-s390x/0.15.13: + resolution: {integrity: sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -5806,8 +5421,8 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.15.8: - resolution: {integrity: sha512-VolFFRatBH09T5QMWhiohAWCOien1R1Uz9K0BRVVTBgBaVBt7eArsXTKxVhUgRf2vwu2c2SXkuP0r7HLG0eozw==} + /esbuild-netbsd-64/0.15.13: + resolution: {integrity: sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -5815,8 +5430,8 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.15.8: - resolution: {integrity: sha512-HTAPlg+n4kUeE/isQxlCfsOz0xJGNoT5LJ9oYZWFKABfVf4Ycu7Zlf5ITgOnrdheTkz8JeL/gISIOCFAoOXrSA==} + /esbuild-openbsd-64/0.15.13: + resolution: {integrity: sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -5824,8 +5439,8 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.15.8: - resolution: {integrity: sha512-qMP/jR/FzcIOwKj+W+Lb+8Cfr8GZHbHUJxAPi7DUhNZMQ/6y7sOgRzlOSpRrbbUntrRZh0MqOyDhJ3Gpo6L1QA==} + /esbuild-sunos-64/0.15.13: + resolution: {integrity: sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -5833,16 +5448,8 @@ packages: dev: true optional: true - /esbuild-wasm/0.15.8: - resolution: {integrity: sha512-Y7uCl5RNO4URjlemjdx++ukVHEMt5s5AfMWYUnMiK4Sry+pPCvQIctzXq6r6FKCyGKjX6/NGMCqR2OX6aLxj0w==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-32/0.15.8: - resolution: {integrity: sha512-RKR1QHh4iWzjUhkP8Yqi75PPz/KS+b8zw3wUrzw6oAkj+iU5Qtyj61ZDaSG3Qf2vc6hTIUiPqVTqBH0NpXFNwg==} + /esbuild-windows-32/0.15.13: + resolution: {integrity: sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -5850,8 +5457,8 @@ packages: dev: true optional: true - /esbuild-windows-64/0.15.8: - resolution: {integrity: sha512-ag9ptYrsizgsR+PQE8QKeMqnosLvAMonQREpLw4evA4FFgOBMLEat/dY/9txbpozTw9eEOYyD3a4cE9yTu20FA==} + /esbuild-windows-64/0.15.13: + resolution: {integrity: sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -5859,8 +5466,8 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.15.8: - resolution: {integrity: sha512-dbpAb0VyPaUs9mgw65KRfQ9rqiWCHpNzrJusoPu+LpEoswosjt/tFxN7cd2l68AT4qWdBkzAjDLRon7uqMeWcg==} + /esbuild-windows-arm64/0.15.13: + resolution: {integrity: sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -5868,34 +5475,34 @@ packages: dev: true optional: true - /esbuild/0.15.8: - resolution: {integrity: sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==} + /esbuild/0.15.13: + resolution: {integrity: sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.15.8 - '@esbuild/linux-loong64': 0.15.8 - esbuild-android-64: 0.15.8 - esbuild-android-arm64: 0.15.8 - esbuild-darwin-64: 0.15.8 - esbuild-darwin-arm64: 0.15.8 - esbuild-freebsd-64: 0.15.8 - esbuild-freebsd-arm64: 0.15.8 - esbuild-linux-32: 0.15.8 - esbuild-linux-64: 0.15.8 - esbuild-linux-arm: 0.15.8 - esbuild-linux-arm64: 0.15.8 - esbuild-linux-mips64le: 0.15.8 - esbuild-linux-ppc64le: 0.15.8 - esbuild-linux-riscv64: 0.15.8 - esbuild-linux-s390x: 0.15.8 - esbuild-netbsd-64: 0.15.8 - esbuild-openbsd-64: 0.15.8 - esbuild-sunos-64: 0.15.8 - esbuild-windows-32: 0.15.8 - esbuild-windows-64: 0.15.8 - esbuild-windows-arm64: 0.15.8 + '@esbuild/android-arm': 0.15.13 + '@esbuild/linux-loong64': 0.15.13 + esbuild-android-64: 0.15.13 + esbuild-android-arm64: 0.15.13 + esbuild-darwin-64: 0.15.13 + esbuild-darwin-arm64: 0.15.13 + esbuild-freebsd-64: 0.15.13 + esbuild-freebsd-arm64: 0.15.13 + esbuild-linux-32: 0.15.13 + esbuild-linux-64: 0.15.13 + esbuild-linux-arm: 0.15.13 + esbuild-linux-arm64: 0.15.13 + esbuild-linux-mips64le: 0.15.13 + esbuild-linux-ppc64le: 0.15.13 + esbuild-linux-riscv64: 0.15.13 + esbuild-linux-s390x: 0.15.13 + esbuild-netbsd-64: 0.15.13 + esbuild-openbsd-64: 0.15.13 + esbuild-sunos-64: 0.15.13 + esbuild-windows-32: 0.15.13 + esbuild-windows-64: 0.15.13 + esbuild-windows-arm64: 0.15.13 dev: true /escalade/3.1.1: @@ -5960,39 +5567,21 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.5.0_eslint@8.23.1: + /eslint-config-prettier/8.5.0_eslint@8.27.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.23.1 + eslint: 8.27.0 dev: true - /eslint-config-prettier/8.5.0_eslint@8.24.0: - resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.24.0 - dev: true - - /eslint-plugin-cypress/2.12.1_eslint@8.23.1: + /eslint-plugin-cypress/2.12.1_eslint@8.27.0: resolution: {integrity: sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==} peerDependencies: eslint: '>= 3.2.1' dependencies: - eslint: 8.23.1 - globals: 11.12.0 - dev: true - - /eslint-plugin-cypress/2.12.1_eslint@8.24.0: - resolution: {integrity: sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==} - peerDependencies: - eslint: '>= 3.2.1' - dependencies: - eslint: 8.24.0 + eslint: 8.27.0 globals: 11.12.0 dev: true @@ -6002,8 +5591,8 @@ packages: htmlparser2: 8.0.1 dev: true - /eslint-plugin-jest/27.0.4_w7j56xfuh6bbmrubefdaspmpla: - resolution: {integrity: sha512-BuvY78pHMpMJ6Cio7sKg6jrqEcnRYPUc4Nlihku4vKx3FjlmMINSX4vcYokZIe+8TKcyr1aI5Kq7vYwgJNdQSA==} + /eslint-plugin-jest/27.1.5_kdswgjmqcx7mthqz7ow2zlfevy: + resolution: {integrity: sha512-CK2dekZ5VBdzsOSOH5Fc1rwC+cWXjkcyrmf1RV714nDUDKu+o73TTJiDxpbILG8PtPPpAAl3ywzh5QA7Ft0mjA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^5.0.0 @@ -6015,67 +5604,28 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.38.0_wsb62dxj2oqwgas4kadjymcmry - '@typescript-eslint/utils': 5.38.0_irgkl5vooow2ydyo6aokmferha - eslint: 8.23.1 + '@typescript-eslint/eslint-plugin': 5.42.1_2udltptbznfmezdozpdoa2aemq + '@typescript-eslint/utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 + jest: 29.3.1_odkjkoia5xunhxkdrka32ib6vi transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jest/27.0.4_zkp6l2tlaisogzmthlfexujswu: - resolution: {integrity: sha512-BuvY78pHMpMJ6Cio7sKg6jrqEcnRYPUc4Nlihku4vKx3FjlmMINSX4vcYokZIe+8TKcyr1aI5Kq7vYwgJNdQSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.0.0 - eslint: ^7.0.0 || ^8.0.0 - jest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true - dependencies: - '@typescript-eslint/eslint-plugin': 5.38.0_4gkcvl6qsi23tqqawfqgcwtp54 - '@typescript-eslint/utils': 5.38.0_7ilbxdl5iguzcjriqqcg2m5cku - eslint: 8.24.0 - jest: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /eslint-plugin-jsdoc/39.3.6_eslint@8.23.1: - resolution: {integrity: sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==} - engines: {node: ^14 || ^16 || ^17 || ^18} + /eslint-plugin-jsdoc/39.6.2_eslint@8.27.0: + resolution: {integrity: sha512-dvgY/W7eUFoAIIiaWHERIMI61ZWqcz9YFjEeyTzdPlrZc3TY/3aZm5aB91NUoTLWYZmO/vFlYSuQi15tF7uE5A==} + engines: {node: ^14 || ^16 || ^17 || ^18 || ^19} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@es-joy/jsdoccomment': 0.31.0 + '@es-joy/jsdoccomment': 0.36.0 comment-parser: 1.3.1 debug: 4.3.4 escape-string-regexp: 4.0.0 - eslint: 8.23.1 + eslint: 8.27.0 esquery: 1.4.0 - semver: 7.3.7 - spdx-expression-parse: 3.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-jsdoc/39.3.6_eslint@8.24.0: - resolution: {integrity: sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==} - engines: {node: ^14 || ^16 || ^17 || ^18} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - dependencies: - '@es-joy/jsdoccomment': 0.31.0 - comment-parser: 1.3.1 - debug: 4.3.4 - escape-string-regexp: 4.0.0 - eslint: 8.24.0 - esquery: 1.4.0 - semver: 7.3.7 + semver: 7.3.8 spdx-expression-parse: 3.0.1 transitivePeerDependencies: - supports-color @@ -6089,28 +5639,63 @@ packages: vscode-json-languageservice: 4.2.1 dev: true - /eslint-plugin-markdown/3.0.0_eslint@8.23.1: + /eslint-plugin-lodash/7.4.0_eslint@8.27.0: + resolution: {integrity: sha512-Tl83UwVXqe1OVeBRKUeWcfg6/pCW1GTRObbdnbEJgYwjxp5Q92MEWQaH9+dmzbRt6kvYU1Mp893E79nJiCSM8A==} + engines: {node: '>=10'} + peerDependencies: + eslint: '>=2' + dependencies: + eslint: 8.27.0 + lodash: 4.17.21 + dev: true + + /eslint-plugin-markdown/3.0.0_eslint@8.27.0: resolution: {integrity: sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.23.1 + eslint: 8.27.0 mdast-util-from-markdown: 0.8.5 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-markdown/3.0.0_eslint@8.24.0: - resolution: {integrity: sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + /eslint-plugin-no-only-tests/3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + + /eslint-plugin-tsdoc/0.2.17: + resolution: {integrity: sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==} dependencies: - eslint: 8.24.0 - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + dev: true + + /eslint-plugin-unicorn/45.0.0_eslint@8.27.0: + resolution: {integrity: sha512-iP8cMRxXKHonKioOhnCoCcqVhoqhAp6rB+nsoLjXFDxTHz3btWMAp8xwzjHA0B1K6YV/U/Yvqn1bUXZt8sJPuQ==} + engines: {node: '>=14.18'} + peerDependencies: + eslint: '>=8.28.0' + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + ci-info: 3.6.2 + clean-regexp: 1.0.0 + eslint: 8.27.0 + eslint-utils: 3.0.0_eslint@8.27.0 + esquery: 1.4.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.0 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.24 + regjsparser: 0.9.1 + safe-regex: 2.1.1 + semver: 7.3.8 + strip-indent: 3.0.0 dev: true /eslint-scope/5.1.1: @@ -6129,23 +5714,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.23.1: + /eslint-utils/3.0.0_eslint@8.27.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.23.1 - eslint-visitor-keys: 2.1.0 - dev: true - - /eslint-utils/3.0.0_eslint@8.24.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.24.0 + eslint: 8.27.0 eslint-visitor-keys: 2.1.0 dev: true @@ -6159,15 +5734,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.23.1: - resolution: {integrity: sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==} + /eslint/8.27.0: + resolution: {integrity: sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.3.2 - '@humanwhocodes/config-array': 0.10.5 - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 + '@eslint/eslintrc': 1.3.3 + '@humanwhocodes/config-array': 0.11.7 '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 @@ -6175,7 +5750,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.23.1 + eslint-utils: 3.0.0_eslint@8.27.0 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -6185,60 +5760,12 @@ packages: find-up: 5.0.0 glob-parent: 6.0.2 globals: 13.17.0 - globby: 11.1.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.0 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - js-sdsl: 4.1.4 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.1 - regexpp: 3.2.0 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint/8.24.0: - resolution: {integrity: sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint/eslintrc': 1.3.2 - '@humanwhocodes/config-array': 0.10.5 - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 - '@humanwhocodes/module-importer': 1.0.1 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.24.0 - eslint-visitor-keys: 3.3.0 - espree: 9.4.0 - esquery: 1.4.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.17.0 - globby: 11.1.0 grapheme-splitter: 1.0.4 ignore: 5.2.0 import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 + is-path-inside: 3.0.3 js-sdsl: 4.1.4 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 @@ -6305,6 +5832,10 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + /esutils/1.0.0: resolution: {integrity: sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==} engines: {node: '>=0.10.0'} @@ -6341,6 +5872,15 @@ packages: resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} dev: true + /eventemitter3/4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: true + + /events/3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + /execa/1.0.0: resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} engines: {node: '>=6'} @@ -6411,39 +5951,24 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /expand-brackets/2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /expect/29.1.0: - resolution: {integrity: sha512-1NCfR0FEArn9Vq1KEjhPd1rggRLiWgo87gfMK4iKn6DcVzJBRMyDNX22hyND5KiSRPIPQ5KtsY6HLxsQ0MU86w==} + /expect/29.3.1: + resolution: {integrity: sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/expect-utils': 29.1.0 - jest-get-type: 29.0.0 - jest-matcher-utils: 29.1.0 - jest-message-util: 29.1.0 - jest-util: 29.1.0 + '@jest/expect-utils': 29.3.1 + jest-get-type: 29.2.0 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-util: 29.3.1 dev: true - /express/4.18.1: - resolution: {integrity: sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==} + /express/4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} engines: {node: '>= 0.10.0'} dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.0 + body-parser: 1.20.1 content-disposition: 0.5.4 content-type: 1.0.4 cookie: 0.5.0 @@ -6462,7 +5987,7 @@ packages: parseurl: 1.3.3 path-to-regexp: 0.1.7 proxy-addr: 2.0.7 - qs: 6.10.3 + qs: 6.11.0 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.18.0 @@ -6476,41 +6001,10 @@ packages: - supports-color dev: true - /extend-shallow/2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - - /extend-shallow/3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - dev: true - /extend/3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true - /extglob/2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - /extract-zip/2.0.1_supports-color@8.1.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -6530,14 +6024,14 @@ packages: engines: {'0': node >=0.6.0} dev: true - /fast-clone/1.5.13: - resolution: {integrity: sha512-0ez7coyFBQFjZtId+RJqJ+EQs61w9xARfqjqK0AD9vIUkSxWD4HvPt80+5evebZ1tTnv1GYKrPTipx7kOW5ipA==} - dev: false - /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true + /fast-equals/4.0.3: + resolution: {integrity: sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==} + dev: true + /fast-glob/3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -6557,15 +6051,20 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fastest-levenshtein/1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + dev: true + /fastq/1.13.0: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 dev: true - /faye-websocket/0.10.0: - resolution: {integrity: sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==} - engines: {node: '>=0.4.0'} + /faye-websocket/0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} dependencies: websocket-driver: 0.7.4 dev: true @@ -6601,16 +6100,6 @@ packages: engines: {node: '>= 6'} dev: true - /fill-range/4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - dev: true - /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -6618,11 +6107,6 @@ packages: to-regex-range: 5.0.1 dev: true - /filter-obj/1.1.0: - resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} - engines: {node: '>=0.10.0'} - dev: true - /finalhandler/1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} @@ -6638,13 +6122,6 @@ packages: - supports-color dev: true - /find-up/2.1.0: - resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} - engines: {node: '>=4'} - dependencies: - locate-path: 2.0.0 - dev: true - /find-up/3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -6680,11 +6157,18 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /flush-write-stream/1.1.1: - resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.7 + /flexsearch/0.7.31: + resolution: {integrity: sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==} + dev: true + + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true dev: true /follow-redirects/1.15.2_debug@4.3.2: @@ -6699,11 +6183,6 @@ packages: debug: 4.3.2 dev: true - /for-in/1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: true - /foreground-child/2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} @@ -6725,6 +6204,15 @@ packages: mime-types: 2.1.35 dev: true + /form-data/3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + /form-data/4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -6739,13 +6227,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /fragment-cache/0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} - dependencies: - map-cache: 0.2.2 - dev: true - /fresh/0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -6792,12 +6273,8 @@ packages: universalify: 2.0.0 dev: true - /fs-mkdirp-stream/1.0.0: - resolution: {integrity: sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==} - engines: {node: '>= 0.10'} - dependencies: - graceful-fs: 4.2.10 - through2: 2.0.5 + /fs-monkey/1.0.3: + resolution: {integrity: sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==} dev: true /fs.realpath/1.0.0: @@ -6809,6 +6286,7 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true + dev: true optional: true /ftp/0.3.10: @@ -6823,6 +6301,11 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true + /gensequence/4.0.2: + resolution: {integrity: sha512-mQiFskYFPFDSUpBJ/n3ebAV2Ufu6DZGvUPXzyWYzFfJr6/DyOOZVnjx6VTWE4y0RLvYWnc5tZq5sCjzEWhRjqQ==} + engines: {node: '>=14'} + dev: true + /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -6850,27 +6333,16 @@ packages: engines: {node: '>=8.0.0'} dev: true - /get-pkg-repo/4.2.1: - resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} - engines: {node: '>=6.9.0'} - hasBin: true - dependencies: - '@hutson/parse-repository-url': 3.0.2 - hosted-git-info: 4.1.0 - through2: 2.0.5 - yargs: 16.2.0 - dev: true - - /get-port/5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - dev: true - /get-stdin/5.0.1: resolution: {integrity: sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==} engines: {node: '>=0.12.0'} dev: true + /get-stdin/8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: true + /get-stream/4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -6904,11 +6376,6 @@ packages: - supports-color dev: true - /get-value/2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - dev: true - /getos/3.2.1: resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} dependencies: @@ -6933,59 +6400,6 @@ packages: through2: 4.0.2 dev: true - /git-remote-origin-url/2.0.0: - resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} - engines: {node: '>=4'} - dependencies: - gitconfiglocal: 1.0.0 - pify: 2.3.0 - dev: true - - /git-semver-tags/4.1.1: - resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - meow: 8.1.2 - semver: 6.3.0 - dev: true - - /git-up/4.0.5: - resolution: {integrity: sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA==} - dependencies: - is-ssh: 1.4.0 - parse-url: 6.0.5 - dev: true - - /git-url-parse/11.6.0: - resolution: {integrity: sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g==} - dependencies: - git-up: 4.0.5 - dev: true - - /gitconfiglocal/1.0.0: - resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} - dependencies: - ini: 1.3.8 - dev: true - - /github-slugger/1.2.0: - resolution: {integrity: sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==} - dependencies: - emoji-regex: 6.1.1 - dev: true - - /github-slugger/1.4.0: - resolution: {integrity: sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==} - dev: true - - /glob-parent/3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: true - /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -7000,20 +6414,8 @@ packages: is-glob: 4.0.3 dev: true - /glob-stream/6.1.0: - resolution: {integrity: sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==} - engines: {node: '>= 0.10'} - dependencies: - extend: 3.0.2 - glob: 7.2.3 - glob-parent: 3.1.0 - is-negated-glob: 1.0.0 - ordered-read-streams: 1.0.1 - pumpify: 1.5.1 - readable-stream: 2.3.7 - remove-trailing-separator: 1.1.0 - to-absolute-glob: 2.0.2 - unique-stream: 2.3.1 + /glob-to-regexp/0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} dev: true /glob/7.2.3: @@ -7027,6 +6429,17 @@ packages: path-is-absolute: 1.0.1 dev: true + /glob/8.0.3: + resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.0 + once: 1.4.0 + dev: true + /global-dirs/0.1.1: resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} engines: {node: '>=4'} @@ -7041,10 +6454,6 @@ packages: ini: 2.0.0 dev: true - /globals-docs/2.4.1: - resolution: {integrity: sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==} - dev: true - /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -7109,11 +6518,9 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true - /graphlib/2.1.8: - resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==} - dependencies: - lodash: 4.17.21 - dev: false + /handle-thing/2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + dev: true /handlebars/4.7.7: resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} @@ -7125,7 +6532,7 @@ packages: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.17.1 + uglify-js: 3.17.3 dev: true /har-schema/2.0.0: @@ -7147,10 +6554,6 @@ packages: engines: {node: '>=6'} dev: true - /harmony-reflect/1.6.2: - resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} - dev: true - /has-ansi/2.0.0: resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} engines: {node: '>=0.10.0'} @@ -7168,10 +6571,9 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors/1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.1.3 + /has-own-prop/2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} dev: true /has-symbols/1.0.3: @@ -7179,37 +6581,6 @@ packages: engines: {node: '>= 0.4'} dev: true - /has-value/0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - dev: true - - /has-value/1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - dev: true - - /has-values/0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - dev: true - - /has-values/1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - dev: true - /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -7217,43 +6588,9 @@ packages: function-bind: 1.1.1 dev: true - /hast-util-is-element/1.1.0: - resolution: {integrity: sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==} - dev: true - - /hast-util-sanitize/1.3.1: - resolution: {integrity: sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==} - dependencies: - xtend: 4.0.2 - dev: true - - /hast-util-to-html/4.0.1: - resolution: {integrity: sha512-2emzwyf0xEsc4TBIPmDJmBttIw8R4SXAJiJZoiRR/s47ODYWgOqNoDbf2SJAbMbfNdFWMiCSOrI3OVnX6Qq2Mg==} - dependencies: - ccount: 1.1.0 - comma-separated-tokens: 1.0.8 - hast-util-is-element: 1.1.0 - hast-util-whitespace: 1.0.4 - html-void-elements: 1.0.5 - property-information: 4.2.0 - space-separated-tokens: 1.1.5 - stringify-entities: 1.3.2 - unist-util-is: 2.1.3 - xtend: 4.0.2 - dev: true - - /hast-util-whitespace/1.0.4: - resolution: {integrity: sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==} - dev: true - - /he/1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - dev: true - - /highlight.js/10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - dev: true + /heap/0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + dev: false /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -7266,6 +6603,15 @@ packages: lru-cache: 6.0.0 dev: true + /hpack.js/2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.7 + wbuf: 1.7.3 + dev: true + /html-encoding-sniffer/3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} engines: {node: '>=12'} @@ -7273,12 +6619,12 @@ packages: whatwg-encoding: 2.0.0 dev: true - /html-escaper/2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + /html-entities/2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} dev: true - /html-void-elements/1.0.5: - resolution: {integrity: sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==} + /html-escaper/2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true /htmlparser2/8.0.1: @@ -7294,6 +6640,20 @@ packages: resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} dev: true + /http-deceiver/1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + dev: true + + /http-errors/1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + dev: true + /http-errors/2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -7331,6 +6691,36 @@ packages: - supports-color dev: true + /http-proxy-middleware/2.0.6_@types+express@4.17.14: + resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + dependencies: + '@types/express': 4.17.14 + '@types/http-proxy': 1.17.9 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.5 + transitivePeerDependencies: + - debug + dev: true + + /http-proxy/1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.2 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: true + /http-signature/1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} @@ -7382,14 +6772,8 @@ packages: engines: {node: '>=12.20.0'} dev: true - /humanize-ms/1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - dependencies: - ms: 2.1.3 - dev: true - - /husky/8.0.1: - resolution: {integrity: sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==} + /husky/8.0.2: + resolution: {integrity: sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==} engines: {node: '>=14'} hasBin: true dev: true @@ -7407,13 +6791,6 @@ packages: dependencies: safer-buffer: 2.1.2 - /identity-obj-proxy/3.0.0: - resolution: {integrity: sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==} - engines: {node: '>=4'} - dependencies: - harmony-reflect: 1.6.2 - dev: true - /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true @@ -7457,6 +6834,10 @@ packages: wrappy: 1.0.2 dev: true + /inherits/2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: true + /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true @@ -7475,6 +6856,11 @@ packages: engines: {node: '>=12'} dev: false + /interpret/2.2.0: + resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} + engines: {node: '>= 0.10'} + dev: true + /ip/1.1.8: resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} dev: true @@ -7488,37 +6874,15 @@ packages: engines: {node: '>= 0.10'} dev: true - /is-absolute/1.0.0: - resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} - engines: {node: '>=0.10.0'} - dependencies: - is-relative: 1.0.0 - is-windows: 1.0.2 - dev: true - - /is-accessor-descriptor/0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-accessor-descriptor/1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 + /ipaddr.js/2.0.1: + resolution: {integrity: sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==} + engines: {node: '>= 10'} dev: true /is-alphabetical/1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} dev: true - /is-alphanumeric/1.0.0: - resolution: {integrity: sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==} - engines: {node: '>=0.10.0'} - dev: true - /is-alphanumerical/1.0.4: resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} dependencies: @@ -7537,20 +6901,23 @@ packages: binary-extensions: 2.2.0 dev: true - /is-buffer/1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - /is-buffer/2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} dev: true + /is-builtin-module/3.2.0: + resolution: {integrity: sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + /is-ci/3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true dependencies: - ci-info: 3.4.0 + ci-info: 3.6.2 dev: true /is-core-module/2.10.0: @@ -7559,52 +6926,14 @@ packages: has: 1.0.3 dev: true - /is-data-descriptor/0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-data-descriptor/1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - /is-decimal/1.0.4: resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} dev: true - /is-descriptor/0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: true - - /is-descriptor/1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: true - - /is-extendable/0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-extendable/1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true dev: true /is-extglob/2.1.1: @@ -7627,13 +6956,6 @@ packages: engines: {node: '>=6'} dev: true - /is-glob/3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -7653,18 +6975,6 @@ packages: is-path-inside: 3.0.3 dev: true - /is-negated-glob/1.0.0: - resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==} - engines: {node: '>=0.10.0'} - dev: true - - /is-number/3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -7685,6 +6995,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-plain-obj/3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + dev: true + /is-plain-obj/4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -7701,19 +7016,6 @@ packages: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true - /is-relative/1.0.0: - resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} - engines: {node: '>=0.10.0'} - dependencies: - is-unc-path: 1.0.0 - dev: true - - /is-ssh/1.4.0: - resolution: {integrity: sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==} - dependencies: - protocols: 2.0.1 - dev: true - /is-stream/1.1.0: resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} engines: {node: '>=0.10.0'} @@ -7740,38 +7042,16 @@ packages: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true - /is-unc-path/1.0.0: - resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} - engines: {node: '>=0.10.0'} - dependencies: - unc-path-regex: 0.1.2 - dev: true - /is-unicode-supported/0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: true - /is-utf8/0.2.1: - resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} - dev: true - - /is-valid-glob/1.0.0: - resolution: {integrity: sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==} - engines: {node: '>=0.10.0'} - dev: true - - /is-whitespace-character/1.0.4: - resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} - dev: true - - /is-windows/1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /is-word-character/1.0.4: - resolution: {integrity: sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==} + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 dev: true /isarray/0.0.1: @@ -7786,13 +7066,6 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isobject/2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - dependencies: - isarray: 1.0.0 - dev: true - /isobject/3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} @@ -7856,43 +7129,43 @@ packages: plist: 3.0.6 dev: true - /jest-changed-files/29.0.0: - resolution: {integrity: sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ==} + /jest-changed-files/29.2.0: + resolution: {integrity: sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: execa: 5.1.1 p-limit: 3.1.0 dev: true - /jest-circus/29.1.1: - resolution: {integrity: sha512-Ii+3JIeLF3z8j2E7fPSjPjXJLBdbAcZyfEiALRQ1Fk+FWTIfuEfZrZcjSaBdz/k/waoq+bPf9x/vBCXIAyLLEQ==} + /jest-circus/29.3.1: + resolution: {integrity: sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.1 - '@jest/expect': 29.1.0 - '@jest/test-result': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/environment': 29.3.1 + '@jest/expect': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 is-generator-fn: 2.1.0 - jest-each: 29.1.0 - jest-matcher-utils: 29.1.0 - jest-message-util: 29.1.0 - jest-runtime: 29.1.1 - jest-snapshot: 29.1.0 - jest-util: 29.1.0 + jest-each: 29.3.1 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-runtime: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 p-limit: 3.1.0 - pretty-format: 29.1.0 + pretty-format: 29.3.1 slash: 3.0.0 stack-utils: 2.0.5 transitivePeerDependencies: - supports-color dev: true - /jest-cli/29.1.1_pliq7kienpvt4xqyxfwljzmzmq: - resolution: {integrity: sha512-nz/JNtqDFf49R2KgeZ9+6Zl1uxSuRsg/tICC+DHMh+bQ0co6QqBPWKg3FtW4534bs8/J2YqFC2Lct9DZR24z0Q==} + /jest-cli/29.3.1_odkjkoia5xunhxkdrka32ib6vi: + resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -7901,16 +7174,16 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.1.1_ts-node@10.9.1 - '@jest/test-result': 29.1.0 - '@jest/types': 29.1.0 + '@jest/core': 29.3.1_ts-node@10.9.1 + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq - jest-util: 29.1.0 - jest-validate: 29.1.0 + jest-config: 29.3.1_odkjkoia5xunhxkdrka32ib6vi + jest-util: 29.3.1 + jest-validate: 29.3.1 prompts: 2.4.2 yargs: 17.5.1 transitivePeerDependencies: @@ -7919,8 +7192,8 @@ packages: - ts-node dev: true - /jest-config/29.1.1_pliq7kienpvt4xqyxfwljzmzmq: - resolution: {integrity: sha512-o2iZrQMOiF54zOw1kOcJGmfKzAW+V2ajZVWxbt+Ex+g0fVaTkk215BD/GFhrviuic+Xk7DpzUmdTT9c1QfsPqg==} + /jest-config/29.3.1_odkjkoia5xunhxkdrka32ib6vi: + resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@types/node': '*' @@ -7932,98 +7205,98 @@ packages: optional: true dependencies: '@babel/core': 7.12.3 - '@jest/test-sequencer': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 - babel-jest: 29.1.0_@babel+core@7.12.3 + '@jest/test-sequencer': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 + babel-jest: 29.3.1_@babel+core@7.12.3 chalk: 4.1.2 - ci-info: 3.4.0 + ci-info: 3.6.2 deepmerge: 4.2.2 glob: 7.2.3 graceful-fs: 4.2.10 - jest-circus: 29.1.1 - jest-environment-node: 29.1.1 - jest-get-type: 29.0.0 - jest-regex-util: 29.0.0 - jest-resolve: 29.1.0 - jest-runner: 29.1.1 - jest-util: 29.1.0 - jest-validate: 29.1.0 + jest-circus: 29.3.1 + jest-environment-node: 29.3.1 + jest-get-type: 29.2.0 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-runner: 29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.1.0 + pretty-format: 29.3.1 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1_ke6ijd35va4xbeayrnhu4zwagm + ts-node: 10.9.1_cbe7ovvae6zqfnmtgctpgpys54 transitivePeerDependencies: - supports-color dev: true - /jest-diff/29.1.0: - resolution: {integrity: sha512-ZJyWG30jpVHwxLs8xxR1so4tz6lFARNztnFlxssFpQdakaW0isSx9rAKs/6aQUKQDZ/DgSpY6HjUGLO9xkNdRw==} + /jest-diff/29.3.1: + resolution: {integrity: sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - diff-sequences: 29.0.0 - jest-get-type: 29.0.0 - pretty-format: 29.1.0 + diff-sequences: 29.3.1 + jest-get-type: 29.2.0 + pretty-format: 29.3.1 dev: true - /jest-docblock/29.0.0: - resolution: {integrity: sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==} + /jest-docblock/29.2.0: + resolution: {integrity: sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: detect-newline: 3.1.0 dev: true - /jest-each/29.1.0: - resolution: {integrity: sha512-ELSZV/L4yjqKU2O0bnDTNHlizD4IRS9DX94iAB6QpiPIJsR453dJW7Ka7TXSmxQdc66HNNOhUcQ5utIeVCKGyA==} + /jest-each/29.3.1: + resolution: {integrity: sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 chalk: 4.1.2 - jest-get-type: 29.0.0 - jest-util: 29.1.0 - pretty-format: 29.1.0 + jest-get-type: 29.2.0 + jest-util: 29.3.1 + pretty-format: 29.3.1 dev: true - /jest-environment-node/29.1.1: - resolution: {integrity: sha512-0nwTca4L2N8iM33A+JMfBdygR6B3N/bcPoLe1hEd9o87KLxDZwKGvpTGSfXpjtyqNQXiaL/3G+YOcSoeq/syPw==} + /jest-environment-node/29.3.1: + resolution: {integrity: sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.1 - '@jest/fake-timers': 29.1.1 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 - jest-mock: 29.1.1 - jest-util: 29.1.0 + '@jest/environment': 29.3.1 + '@jest/fake-timers': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 + jest-mock: 29.3.1 + jest-util: 29.3.1 dev: true - /jest-get-type/29.0.0: - resolution: {integrity: sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==} + /jest-get-type/29.2.0: + resolution: {integrity: sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /jest-haste-map/29.1.0: - resolution: {integrity: sha512-qn+QVZ6JHzzx6g8XrMrNNvvIWrgVT6FzOoxTP5hQ1vEu6r9use2gOb0sSeC3Xle7eaDLN4DdAazSKnWskK3B/g==} + /jest-haste-map/29.3.1: + resolution: {integrity: sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.7.21 + '@types/node': 18.11.9 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 - jest-regex-util: 29.0.0 - jest-util: 29.1.0 - jest-worker: 29.1.0 + jest-regex-util: 29.2.0 + jest-util: 29.3.1 + jest-worker: 29.3.1 micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: fsevents: 2.3.2 dev: true - /jest-image-snapshot/4.2.0: + /jest-image-snapshot/4.2.0_jest@29.3.1: resolution: {integrity: sha512-6aAqv2wtfOgxiJeBayBCqHo1zX+A12SUNNzo7rIxiXh6W6xYVu8QyHWkada8HeRi+QUTHddp0O0Xa6kmQr+xbQ==} engines: {node: '>= 10.14.2'} peerDependencies: @@ -8032,6 +7305,7 @@ packages: chalk: 1.1.3 get-stdin: 5.0.1 glur: 1.1.2 + jest: 29.3.1_odkjkoia5xunhxkdrka32ib6vi lodash: 4.17.21 mkdirp: 0.5.6 pixelmatch: 5.3.0 @@ -8040,67 +7314,49 @@ packages: ssim.js: 3.5.0 dev: true - /jest-image-snapshot/4.2.0_jest@29.1.1: - resolution: {integrity: sha512-6aAqv2wtfOgxiJeBayBCqHo1zX+A12SUNNzo7rIxiXh6W6xYVu8QyHWkada8HeRi+QUTHddp0O0Xa6kmQr+xbQ==} - engines: {node: '>= 10.14.2'} - peerDependencies: - jest: '>=20 <=26' - dependencies: - chalk: 1.1.3 - get-stdin: 5.0.1 - glur: 1.1.2 - jest: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq - lodash: 4.17.21 - mkdirp: 0.5.6 - pixelmatch: 5.3.0 - pngjs: 3.4.0 - rimraf: 2.7.1 - ssim.js: 3.5.0 - dev: true - - /jest-leak-detector/29.1.0: - resolution: {integrity: sha512-7ZdlIA2UXBIzXBNadta7pohrrvbD/Jp5T55Ux2DE1BSGul4RglIPHt7cZ0V3ll+ppBC1pGaBiWPBfLcQ2dDc3Q==} + /jest-leak-detector/29.3.1: + resolution: {integrity: sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.0.0 - pretty-format: 29.1.0 + jest-get-type: 29.2.0 + pretty-format: 29.3.1 dev: true - /jest-matcher-utils/29.1.0: - resolution: {integrity: sha512-pfthsLu27kZg+T1XTUGvox0r3gP3KtqdMPliVd/bs6iDrZ9Z6yJgLbw6zNc4DHtCcyzq9UW0jmszCX8DdFU/wA==} + /jest-matcher-utils/29.3.1: + resolution: {integrity: sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - jest-diff: 29.1.0 - jest-get-type: 29.0.0 - pretty-format: 29.1.0 + jest-diff: 29.3.1 + jest-get-type: 29.2.0 + pretty-format: 29.3.1 dev: true - /jest-message-util/29.1.0: - resolution: {integrity: sha512-NzGXD9wgCxUy20sIvyOsSA/KzQmkmagOVGE5LnT2juWn+hB88gCQr8N/jpu34CXRIXmV7INwrQVVwhnh72pY5A==} + /jest-message-util/29.3.1: + resolution: {integrity: sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/code-frame': 7.18.6 - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.10 micromatch: 4.0.5 - pretty-format: 29.1.0 + pretty-format: 29.3.1 slash: 3.0.0 stack-utils: 2.0.5 dev: true - /jest-mock/29.1.1: - resolution: {integrity: sha512-vDe56JmImqt3j8pHcEIkahQbSCnBS49wda0spIl0bkrIM7VDZXjKaes6W28vKZye0atNAcFaj3dxXh0XWjBW4Q==} + /jest-mock/29.3.1: + resolution: {integrity: sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 - '@types/node': 18.7.21 - jest-util: 29.1.0 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 + jest-util: 29.3.1 dev: true - /jest-pnp-resolver/1.2.2_jest-resolve@29.1.0: + /jest-pnp-resolver/1.2.2_jest-resolve@29.3.1: resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} engines: {node: '>=6'} peerDependencies: @@ -8109,100 +7365,100 @@ packages: jest-resolve: optional: true dependencies: - jest-resolve: 29.1.0 + jest-resolve: 29.3.1 dev: true - /jest-regex-util/29.0.0: - resolution: {integrity: sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==} + /jest-regex-util/29.2.0: + resolution: {integrity: sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /jest-resolve-dependencies/29.1.1: - resolution: {integrity: sha512-AMRTJyiK8caRXq3pa9i4oXX6yH+am5v0HwCUq1yk9lxI3ARihyT2OfEySJJo3ER7xpxf3b6isfp1sO6PQY3N0Q==} + /jest-resolve-dependencies/29.3.1: + resolution: {integrity: sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-regex-util: 29.0.0 - jest-snapshot: 29.1.0 + jest-regex-util: 29.2.0 + jest-snapshot: 29.3.1 transitivePeerDependencies: - supports-color dev: true - /jest-resolve/29.1.0: - resolution: {integrity: sha512-0IETuMI58nbAWwCrtX1QQmenstlWOEdwNS5FXxpEMAs6S5tttFiEoXUwGTAiI152nqoWRUckAgt21FP4wqeZWA==} + /jest-resolve/29.3.1: + resolution: {integrity: sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 graceful-fs: 4.2.10 - jest-haste-map: 29.1.0 - jest-pnp-resolver: 1.2.2_jest-resolve@29.1.0 - jest-util: 29.1.0 - jest-validate: 29.1.0 + jest-haste-map: 29.3.1 + jest-pnp-resolver: 1.2.2_jest-resolve@29.3.1 + jest-util: 29.3.1 + jest-validate: 29.3.1 resolve: 1.22.1 resolve.exports: 1.1.0 slash: 3.0.0 dev: true - /jest-runner/29.1.1: - resolution: {integrity: sha512-HqazsMPXB62Zi2oJEl+Ta9aUWAaR4WdT7ow25pcS99PkOsWQoYH+yyaKbAHBUf8NOqPbZ8T4Q8gt8ZBFEJJdVQ==} + /jest-runner/29.3.1: + resolution: {integrity: sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.1.0 - '@jest/environment': 29.1.1 - '@jest/test-result': 29.1.0 - '@jest/transform': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/console': 29.3.1 + '@jest/environment': 29.3.1 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 chalk: 4.1.2 - emittery: 0.10.2 + emittery: 0.13.1 graceful-fs: 4.2.10 - jest-docblock: 29.0.0 - jest-environment-node: 29.1.1 - jest-haste-map: 29.1.0 - jest-leak-detector: 29.1.0 - jest-message-util: 29.1.0 - jest-resolve: 29.1.0 - jest-runtime: 29.1.1 - jest-util: 29.1.0 - jest-watcher: 29.1.0 - jest-worker: 29.1.0 + jest-docblock: 29.2.0 + jest-environment-node: 29.3.1 + jest-haste-map: 29.3.1 + jest-leak-detector: 29.3.1 + jest-message-util: 29.3.1 + jest-resolve: 29.3.1 + jest-runtime: 29.3.1 + jest-util: 29.3.1 + jest-watcher: 29.3.1 + jest-worker: 29.3.1 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color dev: true - /jest-runtime/29.1.1: - resolution: {integrity: sha512-DA2nW5GUAEFUOFztVqX6BOHbb1tUO1iDzlx+bOVdw870UIkv09u3P5nTfK3N+xtqy/fGlLsg7UCzhpEJnwKilg==} + /jest-runtime/29.3.1: + resolution: {integrity: sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.1 - '@jest/fake-timers': 29.1.1 - '@jest/globals': 29.1.1 - '@jest/source-map': 29.0.0 - '@jest/test-result': 29.1.0 - '@jest/transform': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/environment': 29.3.1 + '@jest/fake-timers': 29.3.1 + '@jest/globals': 29.3.1 + '@jest/source-map': 29.2.0 + '@jest/test-result': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 glob: 7.2.3 graceful-fs: 4.2.10 - jest-haste-map: 29.1.0 - jest-message-util: 29.1.0 - jest-mock: 29.1.1 - jest-regex-util: 29.0.0 - jest-resolve: 29.1.0 - jest-snapshot: 29.1.0 - jest-util: 29.1.0 + jest-haste-map: 29.3.1 + jest-message-util: 29.3.1 + jest-mock: 29.3.1 + jest-regex-util: 29.2.0 + jest-resolve: 29.3.1 + jest-snapshot: 29.3.1 + jest-util: 29.3.1 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color dev: true - /jest-snapshot/29.1.0: - resolution: {integrity: sha512-nHZoA+hpbFlkyV8uLoLJQ/80DLi3c6a5zeELgfSZ5bZj+eljqULr79KBQakp5xyH3onezf4k+K+2/Blk5/1O+g==} + /jest-snapshot/29.3.1: + resolution: {integrity: sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.12.3 @@ -8211,77 +7467,87 @@ packages: '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.12.3 '@babel/traverse': 7.19.1 '@babel/types': 7.19.0 - '@jest/expect-utils': 29.1.0 - '@jest/transform': 29.1.0 - '@jest/types': 29.1.0 + '@jest/expect-utils': 29.3.1 + '@jest/transform': 29.3.1 + '@jest/types': 29.3.1 '@types/babel__traverse': 7.18.2 '@types/prettier': 2.7.1 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.3 chalk: 4.1.2 - expect: 29.1.0 + expect: 29.3.1 graceful-fs: 4.2.10 - jest-diff: 29.1.0 - jest-get-type: 29.0.0 - jest-haste-map: 29.1.0 - jest-matcher-utils: 29.1.0 - jest-message-util: 29.1.0 - jest-util: 29.1.0 + jest-diff: 29.3.1 + jest-get-type: 29.2.0 + jest-haste-map: 29.3.1 + jest-matcher-utils: 29.3.1 + jest-message-util: 29.3.1 + jest-util: 29.3.1 natural-compare: 1.4.0 - pretty-format: 29.1.0 - semver: 7.3.7 + pretty-format: 29.3.1 + semver: 7.3.8 transitivePeerDependencies: - supports-color dev: true - /jest-util/29.1.0: - resolution: {integrity: sha512-5haD8egMAEAq/e8ritN2Gr1WjLYtXi4udAIZB22GnKlv/2MHkbCjcyjgDBmyezAMMeQKGfoaaDsWCmVlnHZ1WQ==} + /jest-util/29.3.1: + resolution: {integrity: sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 chalk: 4.1.2 - ci-info: 3.4.0 + ci-info: 3.6.2 graceful-fs: 4.2.10 picomatch: 2.3.1 dev: true - /jest-validate/29.1.0: - resolution: {integrity: sha512-EQKRweSxmIJelCdirpuVkeCS1rSNXJFtSGEeSRFwH39QGioy7qKRSY8XBB4qFiappbsvgHnH0V6Iq5ASs11knA==} + /jest-validate/29.3.1: + resolution: {integrity: sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.0 + '@jest/types': 29.3.1 camelcase: 6.3.0 chalk: 4.1.2 - jest-get-type: 29.0.0 + jest-get-type: 29.2.0 leven: 3.1.0 - pretty-format: 29.1.0 + pretty-format: 29.3.1 dev: true - /jest-watcher/29.1.0: - resolution: {integrity: sha512-JXw7+VpLSf+2yfXlux1/xR65fMn//0pmiXd6EtQWySS9233aA+eGS+8Y5o2imiJ25JBKdG8T45+s78CNQ71Fbg==} + /jest-watcher/29.3.1: + resolution: {integrity: sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.1.0 - '@jest/types': 29.1.0 - '@types/node': 18.7.21 + '@jest/test-result': 29.3.1 + '@jest/types': 29.3.1 + '@types/node': 18.11.9 ansi-escapes: 4.3.2 chalk: 4.1.2 - emittery: 0.10.2 - jest-util: 29.1.0 + emittery: 0.13.1 + jest-util: 29.3.1 string-length: 4.0.2 dev: true - /jest-worker/29.1.0: - resolution: {integrity: sha512-yr7RFRAxI+vhL/cGB9B0FhD+QfaWh1qSxurx7gLP16dfmqhG8w75D/CQFU8ZetvhiQqLZh8X0C4rxwsZy6HITQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + /jest-worker/27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.7.21 + '@types/node': 18.11.9 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest/29.1.1_pliq7kienpvt4xqyxfwljzmzmq: - resolution: {integrity: sha512-Doe41PZ8MvGLtOZIW2RIVu94wa7jm/N775BBloVXk/G/vV6VYnDCOxBwrqekEgrd3Pn/bv8b5UdB2x0pAoQpwQ==} + /jest-worker/29.3.1: + resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 18.11.9 + jest-util: 29.3.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest/29.3.1_odkjkoia5xunhxkdrka32ib6vi: + resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -8290,10 +7556,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.1.1_ts-node@10.9.1 - '@jest/types': 29.1.0 + '@jest/core': 29.3.1_ts-node@10.9.1 + '@jest/types': 29.3.1 import-local: 3.1.0 - jest-cli: 29.1.1_pliq7kienpvt4xqyxfwljzmzmq + jest-cli: 29.3.1_odkjkoia5xunhxkdrka32ib6vi transitivePeerDependencies: - '@types/node' - supports-color @@ -8324,6 +7590,10 @@ packages: nomnom: 1.5.2 dev: true + /jju/1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + dev: true + /joi/17.6.0: resolution: {integrity: sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==} dependencies: @@ -8374,8 +7644,8 @@ packages: engines: {node: '>=12.0.0'} dev: true - /jsdom/20.0.0: - resolution: {integrity: sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==} + /jsdom/20.0.2: + resolution: {integrity: sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==} engines: {node: '>=14'} peerDependencies: canvas: ^2.5.0 @@ -8385,7 +7655,7 @@ packages: dependencies: abab: 2.0.6 acorn: 8.8.0 - acorn-globals: 6.0.0 + acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 data-urls: 3.0.2 @@ -8402,13 +7672,12 @@ packages: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 4.1.2 - w3c-hr-time: 1.0.2 w3c-xmlserializer: 3.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - ws: 8.8.1 + ws: 8.9.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -8427,12 +7696,14 @@ packages: hasBin: true dev: true - /json-buffer/3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + /jsesc/3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true dev: true - /json-parse-better-errors/1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + /json-buffer/3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true /json-parse-even-better-errors/2.3.1: @@ -8527,25 +7798,6 @@ packages: resolution: {integrity: sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g==} dev: false - /kind-of/3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of/4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of/5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: true - /kind-of/6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -8561,44 +7813,29 @@ packages: engines: {node: '>=6'} dev: true - /konan/2.1.1: - resolution: {integrity: sha512-7ZhYV84UzJ0PR/RJnnsMZcAbn+kLasJhVNWsu8ZyVEJYRpGA5XESQ9d/7zOa08U0Ou4cmB++hMNY/3OSV9KIbg==} - dependencies: - '@babel/parser': 7.19.1 - '@babel/traverse': 7.19.1 - transitivePeerDependencies: - - supports-color - dev: true - /ky/0.28.7: resolution: {integrity: sha512-a23i6qSr/ep15vdtw/zyEQIDLoUaKDg9Jf04CYl/0ns/wXNYna26zJpI+MeIFaPeDvkrjLPrKtKOiiI3IE53RQ==} engines: {node: '>=12'} dev: true + /layout-base/1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + dev: false + + /layout-base/2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + dev: false + /lazy-ass/1.6.0: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} dev: true - /lazystream/1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - dependencies: - readable-stream: 2.3.7 - dev: true - /lcov-parse/1.0.0: resolution: {integrity: sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==} hasBin: true dev: true - /lead/1.0.0: - resolution: {integrity: sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==} - engines: {node: '>= 0.10'} - dependencies: - flush-write-stream: 1.1.1 - dev: true - /leven/3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -8633,6 +7870,12 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /linkify-it/4.0.1: + resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + dependencies: + uc.micro: 1.0.6 + dev: true + /lint-staged/13.0.3: resolution: {integrity: sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==} engines: {node: ^14.13.1 || >=16.0.0} @@ -8695,18 +7938,9 @@ packages: wrap-ansi: 7.0.0 dev: true - /livereload-js/2.4.0: - resolution: {integrity: sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==} - dev: true - - /load-json-file/4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.10 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 + /loader-runner/4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} dev: true /local-pkg/0.4.2: @@ -8714,14 +7948,6 @@ packages: engines: {node: '>=14'} dev: true - /locate-path/2.0.0: - resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} - engines: {node: '>=4'} - dependencies: - p-locate: 2.0.0 - path-exists: 3.0.0 - dev: true - /locate-path/3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -8744,13 +7970,9 @@ packages: p-locate: 5.0.0 dev: true - /lodash.debounce/4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: true - - /lodash.ismatch/4.4.0: - resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} - dev: true + /lodash-es/4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -8795,10 +8017,6 @@ packages: engines: {node: '>= 0.6.0'} dev: true - /longest-streak/2.0.4: - resolution: {integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==} - dev: true - /longest-streak/3.0.1: resolution: {integrity: sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==} dev: true @@ -8827,6 +8045,16 @@ packages: yallist: 4.0.0 dev: true + /lunr/2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + dev: true + + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -8844,11 +8072,6 @@ packages: tmpl: 1.0.5 dev: true - /map-cache/0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - /map-obj/1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -8863,31 +8086,21 @@ packages: resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} dev: true - /map-visit/1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} + /markdown-it/13.0.1: + resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} + hasBin: true dependencies: - object-visit: 1.0.1 + argparse: 2.0.1 + entities: 3.0.1 + linkify-it: 4.0.1 + mdurl: 1.0.1 + uc.micro: 1.0.6 dev: true - /markdown-escapes/1.0.4: - resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} - dev: true - - /markdown-table/1.1.3: - resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} - dev: true - - /mdast-util-compact/1.0.4: - resolution: {integrity: sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==} - dependencies: - unist-util-visit: 1.4.1 - dev: true - - /mdast-util-definitions/1.2.5: - resolution: {integrity: sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==} - dependencies: - unist-util-visit: 1.4.1 + /marked/4.1.1: + resolution: {integrity: sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==} + engines: {node: '>= 12'} + hasBin: true dev: true /mdast-util-from-markdown/0.8.5: @@ -8921,28 +8134,6 @@ packages: - supports-color dev: true - /mdast-util-inject/1.1.0: - resolution: {integrity: sha512-CcJ0mHa36QYumDKiZ2OIR+ClhfOM7zIzN+Wfy8tRZ1hpH9DKLCS+Mh4DyK5bCxzE9uxMWcbIpeNFWsg1zrj/2g==} - dependencies: - mdast-util-to-string: 1.1.0 - dev: true - - /mdast-util-to-hast/3.0.4: - resolution: {integrity: sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==} - dependencies: - collapse-white-space: 1.0.6 - detab: 2.0.4 - mdast-util-definitions: 1.2.5 - mdurl: 1.0.1 - trim: 0.0.1 - trim-lines: 1.1.3 - unist-builder: 1.0.4 - unist-util-generated: 1.1.6 - unist-util-position: 3.1.0 - unist-util-visit: 1.4.1 - xtend: 4.0.2 - dev: true - /mdast-util-to-markdown/1.3.0: resolution: {integrity: sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==} dependencies: @@ -8955,10 +8146,6 @@ packages: zwitch: 2.0.2 dev: true - /mdast-util-to-string/1.1.0: - resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} - dev: true - /mdast-util-to-string/2.0.0: resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} dev: true @@ -8967,15 +8154,6 @@ packages: resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} dev: true - /mdast-util-toc/3.1.0: - resolution: {integrity: sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==} - dependencies: - github-slugger: 1.4.0 - mdast-util-to-string: 1.1.0 - unist-util-is: 2.1.3 - unist-util-visit: 1.4.1 - dev: true - /mdn-data/2.0.6: resolution: {integrity: sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==} dev: true @@ -8989,6 +8167,13 @@ packages: engines: {node: '>= 0.6'} dev: true + /memfs/3.4.11: + resolution: {integrity: sha512-GvsCITGAyDCxxsJ+X6prJexFQEhOCJaIlUbsAvjzSI5o5O7j2dle3jWvz5Z5aOdpOxW6ol3vI1+0ut+641F1+w==} + engines: {node: '>= 4.0.0'} + dependencies: + fs-monkey: 1.0.3 + dev: true + /meow/8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -9209,27 +8394,6 @@ packages: - supports-color dev: true - /micromatch/3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - /micromatch/4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -9256,12 +8420,6 @@ packages: hasBin: true dev: true - /mime/2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - dev: true - /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -9287,12 +8445,23 @@ packages: engines: {node: '>=4'} dev: true + /minimalistic-assert/1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: true + /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: true + /minimatch/5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist-options/4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -9306,14 +8475,6 @@ packages: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} dev: true - /mixin-deep/1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - dev: true - /mkdirp/0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -9321,36 +8482,6 @@ packages: minimist: 1.2.6 dev: true - /modify-values/1.0.1: - resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} - engines: {node: '>=0.10.0'} - dev: true - - /module-deps-sortable/5.0.3: - resolution: {integrity: sha512-eiyIZj/A0dj1o4ywXWqicazUL3l0HP3TydUR6xF0X3xh3LGBMLqW8a9aFe6MuNH4mxNMk53QKBHM6LOPR8kSgw==} - engines: {node: '>= 0.6'} - hasBin: true - dependencies: - JSONStream: 1.3.5 - browser-resolve: 1.11.3 - cached-path-relative: 1.1.0 - concat-stream: 1.5.2 - defined: 1.0.0 - detective: 5.2.1 - duplexer2: 0.1.4 - inherits: 2.0.4 - konan: 2.1.1 - readable-stream: 2.3.7 - resolve: 1.22.1 - standard-version: 9.5.0 - stream-combiner2: 1.1.1 - subarg: 1.0.0 - through2: 2.0.5 - xtend: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - /moment-mini/2.29.4: resolution: {integrity: sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==} dev: false @@ -9381,29 +8512,22 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true + /multicast-dns/7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + dependencies: + dns-packet: 5.4.0 + thunky: 1.1.0 + dev: true + /nanoid/3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true - /nanomatch/1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color + /natural-compare-lite/1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true /natural-compare/1.4.0: @@ -9440,6 +8564,11 @@ packages: whatwg-url: 5.0.0 dev: true + /node-forge/1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: true + /node-int64/0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: true @@ -9475,17 +8604,10 @@ packages: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.10.0 - semver: 7.3.7 + semver: 7.3.8 validate-npm-package-license: 3.0.4 dev: true - /normalize-path/2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - dependencies: - remove-trailing-separator: 1.1.0 - dev: true - /normalize-path/3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -9496,13 +8618,6 @@ packages: engines: {node: '>=10'} dev: true - /now-and-later/2.0.1: - resolution: {integrity: sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==} - engines: {node: '>= 0.10'} - dependencies: - once: 1.4.0 - dev: true - /npm-run-path/2.0.2: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} @@ -9532,51 +8647,12 @@ packages: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} dev: true - /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true - - /object-copy/0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: true - /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object-visit/1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.assign/4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /object.pick/1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 + /obuf/1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} dev: true /on-finished/2.4.1: @@ -9586,6 +8662,11 @@ packages: ee-first: 1.1.1 dev: true + /on-headers/1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: true + /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -9606,6 +8687,15 @@ packages: mimic-fn: 4.0.0 dev: true + /open/8.4.0: + resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + /optionator/0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -9630,12 +8720,6 @@ packages: word-wrap: 1.2.3 dev: true - /ordered-read-streams/1.0.1: - resolution: {integrity: sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==} - dependencies: - readable-stream: 2.3.7 - dev: true - /ospath/1.2.2: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} dev: true @@ -9655,13 +8739,6 @@ packages: engines: {node: '>=8.0.0'} dev: true - /p-limit/1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} - dependencies: - p-try: 1.0.0 - dev: true - /p-limit/2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -9676,13 +8753,6 @@ packages: yocto-queue: 0.1.0 dev: true - /p-locate/2.0.0: - resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} - engines: {node: '>=4'} - dependencies: - p-limit: 1.3.0 - dev: true - /p-locate/3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} @@ -9711,9 +8781,12 @@ packages: aggregate-error: 3.1.0 dev: true - /p-try/1.0.0: - resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} - engines: {node: '>=4'} + /p-retry/4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 dev: true /p-try/2.2.0: @@ -9758,15 +8831,11 @@ packages: callsites: 3.1.0 dev: true - /parse-entities/1.2.2: - resolution: {integrity: sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==} + /parent-module/2.0.0: + resolution: {integrity: sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==} + engines: {node: '>=8'} dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 + callsites: 3.1.0 dev: true /parse-entities/2.0.0: @@ -9780,23 +8849,6 @@ packages: is-hexadecimal: 1.0.4 dev: true - /parse-filepath/1.0.2: - resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} - engines: {node: '>=0.8'} - dependencies: - is-absolute: 1.0.0 - map-cache: 0.2.2 - path-root: 0.1.1 - dev: true - - /parse-json/4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: true - /parse-json/5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -9807,24 +8859,6 @@ packages: lines-and-columns: 1.2.4 dev: true - /parse-path/4.0.4: - resolution: {integrity: sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==} - dependencies: - is-ssh: 1.4.0 - protocols: 1.4.8 - qs: 6.11.0 - query-string: 6.14.1 - dev: true - - /parse-url/6.0.5: - resolution: {integrity: sha512-e35AeLTSIlkw/5GFq70IN7po8fmDUjpDPY1rIK+VubRfsUvBonjQ+PBZG+vWMACnQSmNlvl524IucoDmcioMxA==} - dependencies: - is-ssh: 1.4.0 - normalize-url: 6.1.0 - parse-path: 4.0.4 - protocols: 1.4.8 - dev: true - /parse5/6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} dev: true @@ -9840,19 +8874,10 @@ packages: engines: {node: '>= 0.8'} dev: true - /pascalcase/0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - dev: true - /path-browserify/1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} dev: true - /path-dirname/1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: true - /path-exists/3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -9887,29 +8912,10 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /path-root-regex/0.1.2: - resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} - engines: {node: '>=0.10.0'} - dev: true - - /path-root/0.1.1: - resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} - engines: {node: '>=0.10.0'} - dependencies: - path-root-regex: 0.1.2 - dev: true - /path-to-regexp/0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true - /path-type/3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - /path-type/4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -9953,16 +8959,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /pify/3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true - - /pify/5.0.0: - resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} - engines: {node: '>=10'} - dev: true - /pirates/4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} @@ -9997,6 +8993,11 @@ packages: xmlbuilder: 15.1.1 dev: true + /pluralize/8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + /png-async/0.9.4: resolution: {integrity: sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A==} dev: true @@ -10011,17 +9012,18 @@ packages: engines: {node: '>=12.13.0'} dev: true - /posix-character-classes/0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} + /pnpm/7.15.0: + resolution: {integrity: sha512-GGQ5+MCwD0bpq+65uitpgO1+ZusZ1keO5ebG/CH6ciu1ohnZj5Y3X374Ow/CBApa+Jw2/NUifVRz2fW4JChftA==} + engines: {node: '>=14.6'} + hasBin: true dev: true - /postcss-value-parser/4.1.0: - resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss/8.4.16: - resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} + /postcss/8.4.18: + resolution: {integrity: sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -10029,6 +9031,10 @@ packages: source-map-js: 1.0.2 dev: true + /preact/10.11.0: + resolution: {integrity: sha512-Fk6+vB2kb6mSJfDgODq0YDhMfl0HNtK5+Uc9QqECO4nlyPAQwCI+BKyWO//idA7ikV7o+0Fm6LQmNuQi1wXI1w==} + dev: true + /prelude-ls/1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} @@ -10064,8 +9070,8 @@ packages: engines: {node: '>=6'} dev: true - /pretty-format/29.1.0: - resolution: {integrity: sha512-dZ21z0UjKVSiEkrPAt2nJnGfrtYMFBlNW4wTkJsIp9oB5A8SUQ8DuJ9EUgAvYyNfMeoGmKiDnpJvM489jkzdSQ==} + /pretty-format/29.3.1: + resolution: {integrity: sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.0.0 @@ -10073,10 +9079,6 @@ packages: react-is: 18.2.0 dev: true - /process-nextick-args/1.0.7: - resolution: {integrity: sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==} - dev: true - /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true @@ -10089,20 +9091,6 @@ packages: sisteransi: 1.0.5 dev: true - /property-information/4.2.0: - resolution: {integrity: sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==} - dependencies: - xtend: 4.0.2 - dev: true - - /protocols/1.4.8: - resolution: {integrity: sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==} - dev: true - - /protocols/2.0.1: - resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==} - dev: true - /proxy-addr/2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -10147,13 +9135,6 @@ packages: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true - /pump/2.0.1: - resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: true - /pump/3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: @@ -10161,14 +9142,6 @@ packages: once: 1.4.0 dev: true - /pumpify/1.5.1: - resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} - dependencies: - duplexify: 3.7.1 - inherits: 2.0.4 - pump: 2.0.1 - dev: true - /punycode/2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} @@ -10179,13 +9152,6 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} dev: true - /qs/6.10.3: - resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - dev: true - /qs/6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} @@ -10198,16 +9164,6 @@ packages: engines: {node: '>=0.6'} dev: true - /query-string/6.14.1: - resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} - engines: {node: '>=6'} - dependencies: - decode-uri-component: 0.2.0 - filter-obj: 1.1.0 - split-on-first: 1.1.0 - strict-uri-encode: 2.0.0 - dev: true - /querystringify/2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: true @@ -10226,19 +9182,17 @@ packages: engines: {node: '>=10'} dev: true + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /range-parser/1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} dev: true - /raw-body/1.1.7: - resolution: {integrity: sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==} - engines: {node: '>= 0.8.0'} - dependencies: - bytes: 1.0.0 - string_decoder: 0.10.31 - dev: true - /raw-body/2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} engines: {node: '>= 0.8'} @@ -10253,22 +9207,6 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /read-pkg-up/3.0.0: - resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} - engines: {node: '>=4'} - dependencies: - find-up: 2.1.0 - read-pkg: 3.0.0 - dev: true - - /read-pkg-up/4.0.0: - resolution: {integrity: sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==} - engines: {node: '>=6'} - dependencies: - find-up: 3.0.0 - read-pkg: 3.0.0 - dev: true - /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -10278,15 +9216,6 @@ packages: type-fest: 0.8.1 dev: true - /read-pkg/3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: true - /read-pkg/5.2.0: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} @@ -10306,29 +9235,6 @@ packages: string_decoder: 0.10.31 dev: true - /readable-stream/2.0.6: - resolution: {integrity: sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 1.0.7 - string_decoder: 0.10.31 - util-deprecate: 1.0.2 - dev: true - - /readable-stream/2.1.5: - resolution: {integrity: sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==} - dependencies: - buffer-shims: 1.0.0 - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 1.0.7 - string_decoder: 0.10.31 - util-deprecate: 1.0.2 - dev: true - /readable-stream/2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} dependencies: @@ -10357,6 +9263,13 @@ packages: picomatch: 2.3.1 dev: true + /rechoir/0.7.1: + resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} + engines: {node: '>= 0.10'} + dependencies: + resolve: 1.22.1 + dev: true + /redent/3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -10365,33 +9278,9 @@ packages: strip-indent: 3.0.0 dev: true - /regenerate-unicode-properties/10.1.0: - resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - dev: true - - /regenerate/1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: true - - /regenerator-runtime/0.13.9: - resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} - dev: true - - /regenerator-transform/0.15.0: - resolution: {integrity: sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==} - dependencies: - '@babel/runtime': 7.19.0 - dev: true - - /regex-not/1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 + /regexp-tree/0.1.24: + resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==} + hasBin: true dev: true /regexpp/3.2.0: @@ -10399,22 +9288,6 @@ packages: engines: {node: '>=8'} dev: true - /regexpu-core/5.2.1: - resolution: {integrity: sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.0 - regjsgen: 0.7.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.0.0 - dev: true - - /regjsgen/0.7.1: - resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} - dev: true - /regjsparser/0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true @@ -10422,15 +9295,6 @@ packages: jsesc: 0.5.0 dev: true - /remark-html/8.0.0: - resolution: {integrity: sha512-3V2391GL3hxKhrkzYOyfPpxJ6taIKLCfuLVqumeWQOk3H9nTtSQ8St8kMYkBVIEAquXN1chT83qJ/2lAW+dpEg==} - dependencies: - hast-util-sanitize: 1.3.1 - hast-util-to-html: 4.0.1 - mdast-util-to-hast: 3.0.4 - xtend: 4.0.2 - dev: true - /remark-parse/10.0.1: resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} dependencies: @@ -10441,40 +9305,6 @@ packages: - supports-color dev: true - /remark-parse/5.0.0: - resolution: {integrity: sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==} - dependencies: - collapse-white-space: 1.0.6 - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - is-whitespace-character: 1.0.4 - is-word-character: 1.0.4 - markdown-escapes: 1.0.4 - parse-entities: 1.2.2 - repeat-string: 1.6.1 - state-toggle: 1.0.3 - trim: 0.0.1 - trim-trailing-lines: 1.1.4 - unherit: 1.1.3 - unist-util-remove-position: 1.1.4 - vfile-location: 2.0.6 - xtend: 4.0.2 - dev: true - - /remark-reference-links/4.0.4: - resolution: {integrity: sha512-+2X8hwSQqxG4tvjYZNrTcEC+bXp8shQvwRGG6J/rnFTvBoU4G0BBviZoqKGZizLh/DG+0gSYhiDDWCqyxXW1iQ==} - dependencies: - unist-util-visit: 1.4.1 - dev: true - - /remark-slug/5.1.2: - resolution: {integrity: sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==} - dependencies: - github-slugger: 1.2.0 - mdast-util-to-string: 1.1.0 - unist-util-visit: 1.4.1 - dev: true - /remark-stringify/10.0.2: resolution: {integrity: sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==} dependencies: @@ -10483,32 +9313,6 @@ packages: unified: 10.1.2 dev: true - /remark-stringify/5.0.0: - resolution: {integrity: sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==} - dependencies: - ccount: 1.1.0 - is-alphanumeric: 1.0.0 - is-decimal: 1.0.4 - is-whitespace-character: 1.0.4 - longest-streak: 2.0.4 - markdown-escapes: 1.0.4 - markdown-table: 1.1.3 - mdast-util-compact: 1.0.4 - parse-entities: 1.2.2 - repeat-string: 1.6.1 - state-toggle: 1.0.3 - stringify-entities: 1.3.2 - unherit: 1.1.3 - xtend: 4.0.2 - dev: true - - /remark-toc/5.1.1: - resolution: {integrity: sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow==} - dependencies: - mdast-util-toc: 3.1.0 - remark-slug: 5.1.2 - dev: true - /remark/14.0.2: resolution: {integrity: sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==} dependencies: @@ -10520,55 +9324,11 @@ packages: - supports-color dev: true - /remark/9.0.0: - resolution: {integrity: sha512-amw8rGdD5lHbMEakiEsllmkdBP+/KpjW/PRK6NSGPZKCQowh0BT4IWXDAkRMyG3SB9dKPXWMviFjNusXzXNn3A==} - dependencies: - remark-parse: 5.0.0 - remark-stringify: 5.0.0 - unified: 6.2.0 - dev: true - - /remove-bom-buffer/3.0.0: - resolution: {integrity: sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - is-utf8: 0.2.1 - dev: true - - /remove-bom-stream/1.2.0: - resolution: {integrity: sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==} - engines: {node: '>= 0.10'} - dependencies: - remove-bom-buffer: 3.0.0 - safe-buffer: 5.2.1 - through2: 2.0.5 - dev: true - - /remove-trailing-separator/1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - dev: true - - /repeat-element/1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - dev: true - /repeat-string/1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} dev: true - /replace-ext/1.0.0: - resolution: {integrity: sha512-vuNYXC7gG7IeVNBC1xUllqCcZKRbJoSPOBhnTEcAIiKCsbuef6zO3F0Rve3isPMMoNoQRWjQwbAgAjHUHniyEA==} - engines: {node: '>= 0.10'} - dev: true - - /replace-ext/1.0.1: - resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} - engines: {node: '>= 0.10'} - dev: true - /request-progress/3.0.0: resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} dependencies: @@ -10612,10 +9372,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /require-main-filename/2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: true - /requires-port/1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true @@ -10648,25 +9404,16 @@ packages: global-dirs: 0.1.1 dev: true - /resolve-options/1.1.0: - resolution: {integrity: sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==} - engines: {node: '>= 0.10'} - dependencies: - value-or-function: 3.0.0 - dev: true - - /resolve-url/0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true - /resolve.exports/1.1.0: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} engines: {node: '>=10'} dev: true - /resolve/1.1.7: - resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + /resolve/1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + dependencies: + is-core-module: 2.10.0 + path-parse: 1.0.7 dev: true /resolve/1.22.1: @@ -10692,9 +9439,9 @@ packages: signal-exit: 3.0.7 dev: true - /ret/0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} + /retry/0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} dev: true /reusify/1.0.4: @@ -10724,12 +9471,19 @@ packages: resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==} dev: false - /rollup/2.78.1: - resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} - engines: {node: '>=10.0.0'} + /rollup-plugin-visualizer/5.8.3: + resolution: {integrity: sha512-QGJk4Bqe4AOat5AjipOh8esZH1nck5X2KFpf4VytUdSUuuuSwvIQZjMGgjcxe/zXexltqaXp5Vx1V3LmnQH15Q==} + engines: {node: '>=14'} hasBin: true - optionalDependencies: - fsevents: 2.3.2 + peerDependencies: + rollup: 2.x || 3.x + peerDependenciesMeta: + rollup: + optional: true + dependencies: + open: 8.4.0 + source-map: 0.7.4 + yargs: 17.5.1 dev: true /rollup/2.79.1: @@ -10738,7 +9492,7 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.2 - dev: false + dev: true /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -10771,14 +9525,10 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /safe-json-parse/1.0.1: - resolution: {integrity: sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==} - dev: true - - /safe-regex/1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + /safe-regex/2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} dependencies: - ret: 0.1.15 + regexp-tree: 0.1.24 dev: true /safer-buffer/2.1.2: @@ -10798,6 +9548,36 @@ packages: xmlchars: 2.2.0 dev: true + /schema-utils/3.1.1: + resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.11 + ajv: 6.12.6 + ajv-keywords: 3.5.2_ajv@6.12.6 + dev: true + + /schema-utils/4.0.0: + resolution: {integrity: sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==} + engines: {node: '>= 12.13.0'} + dependencies: + '@types/json-schema': 7.0.11 + ajv: 8.11.0 + ajv-formats: 2.1.1_ajv@8.11.0 + ajv-keywords: 5.1.0_ajv@8.11.0 + dev: true + + /select-hose/2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + dev: true + + /selfsigned/2.1.1: + resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} + engines: {node: '>=10'} + dependencies: + node-forge: 1.3.1 + dev: true + /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true @@ -10816,6 +9596,14 @@ packages: lru-cache: 6.0.0 dev: true + /semver/7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /send/0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -10837,6 +9625,27 @@ packages: - supports-color dev: true + /serialize-javascript/6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-index/1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.6.3 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + dev: true + /serve-static/1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -10849,24 +9658,21 @@ packages: - supports-color dev: true - /set-blocking/2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true - - /set-value/2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 + /setprototypeof/1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} dev: true /setprototypeof/1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true + /shallow-clone/3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + /shebang-command/1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -10895,6 +9701,14 @@ packages: resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} dev: true + /shiki/0.11.1: + resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} + dependencies: + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.6.2 + vscode-textmate: 6.0.0 + dev: true + /side-channel/1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -10961,36 +9775,12 @@ packages: engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} dev: true - /snapdragon-node/2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} + /sockjs/0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - dev: true - - /snapdragon-util/3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /snapdragon/0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 dev: true /socks-proxy-agent/5.0.1: @@ -11017,17 +9807,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /source-map-resolve/0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.0 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - dev: true - /source-map-support/0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -11035,9 +9814,11 @@ packages: source-map: 0.6.1 dev: true - /source-map-url/0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated + /source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 dev: true /source-map/0.1.43: @@ -11059,8 +9840,13 @@ packages: engines: {node: '>=0.10.0'} dev: true - /space-separated-tokens/1.1.5: - resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + /source-map/0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} dev: true /spawn-command/0.0.2-1: @@ -11089,16 +9875,30 @@ packages: resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} dev: true - /split-on-first/1.1.0: - resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} - engines: {node: '>=6'} + /spdy-transport/3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + dependencies: + debug: 4.3.4 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.0 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color dev: true - /split-string/3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} + /spdy/4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} dependencies: - extend-shallow: 3.0.2 + debug: 4.3.4 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color dev: true /split/0.3.3: @@ -11107,12 +9907,6 @@ packages: through: 2.3.8 dev: true - /split/1.0.1: - resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} - dependencies: - through: 2.3.8 - dev: true - /split2/3.2.2: resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} dependencies: @@ -11150,27 +9944,6 @@ packages: escape-string-regexp: 2.0.0 dev: true - /standard-version/9.5.0: - resolution: {integrity: sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==} - engines: {node: '>=10'} - hasBin: true - dependencies: - chalk: 2.4.2 - conventional-changelog: 3.1.25 - conventional-changelog-config-spec: 2.1.0 - conventional-changelog-conventionalcommits: 4.6.3 - conventional-recommended-bump: 6.1.0 - detect-indent: 6.1.0 - detect-newline: 3.1.0 - dotgitignore: 2.1.0 - figures: 3.2.0 - find-up: 5.0.0 - git-semver-tags: 4.1.1 - semver: 7.3.7 - stringify-package: 1.0.1 - yargs: 16.2.0 - dev: true - /start-server-and-test/1.14.0: resolution: {integrity: sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw==} engines: {node: '>=6'} @@ -11187,16 +9960,9 @@ packages: - supports-color dev: true - /state-toggle/1.0.3: - resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==} - dev: true - - /static-extend/0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 + /statuses/1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} dev: true /statuses/2.0.1: @@ -11204,35 +9970,12 @@ packages: engines: {node: '>= 0.8'} dev: true - /stream-array/1.1.2: - resolution: {integrity: sha512-1yWdVsMEm/btiMa2YyHiC3mDrtAqlmNNaDRylx2F7KHhm3C4tA6kSR2V9mpeMthv+ujvbl8Kamyh5xaHHdFvyQ==} - engines: {node: '>= 0.8'} - dependencies: - readable-stream: 2.1.5 - dev: true - /stream-combiner/0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} dependencies: duplexer: 0.1.2 dev: true - /stream-combiner2/1.1.1: - resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} - dependencies: - duplexer2: 0.1.4 - readable-stream: 2.3.7 - dev: true - - /stream-shift/1.0.1: - resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} - dev: true - - /strict-uri-encode/2.0.0: - resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} - engines: {node: '>=4'} - dev: true - /string-argv/0.3.1: resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} engines: {node: '>=0.6.19'} @@ -11246,10 +9989,6 @@ packages: strip-ansi: 6.0.1 dev: true - /string-template/0.2.1: - resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==} - dev: true - /string-width/4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -11284,19 +10023,6 @@ packages: safe-buffer: 5.2.1 dev: true - /stringify-entities/1.3.2: - resolution: {integrity: sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==} - dependencies: - character-entities-html4: 1.1.4 - character-entities-legacy: 1.1.4 - is-alphanumerical: 1.0.4 - is-hexadecimal: 1.0.4 - dev: true - - /stringify-package/1.0.1: - resolution: {integrity: sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==} - dev: true - /strip-ansi/3.0.1: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} @@ -11318,11 +10044,6 @@ packages: ansi-regex: 6.0.1 dev: true - /strip-bom/3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - /strip-bom/4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -11350,11 +10071,6 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments/2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: true - /strip-json-comments/3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -11370,12 +10086,6 @@ packages: resolution: {integrity: sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==} dev: false - /subarg/1.0.0: - resolution: {integrity: sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==} - dependencies: - minimist: 1.2.6 - dev: true - /supports-color/2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} @@ -11388,13 +10098,6 @@ packages: has-flag: 3.0.0 dev: true - /supports-color/6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - dependencies: - has-flag: 3.0.0 - dev: true - /supports-color/7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -11409,14 +10112,6 @@ packages: has-flag: 4.0.0 dev: true - /supports-hyperlinks/2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -11426,6 +10121,11 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true + /tapable/2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /term-img/4.1.0: resolution: {integrity: sha512-DFpBhaF5j+2f7kheKFc1ajsAUUDGOaNPpKPtiIMxlbfud6mvfFZuWGnTRpaujUa5J7yl6cIw/h6nyr4mSsENPg==} engines: {node: '>=8'} @@ -11434,12 +10134,39 @@ packages: iterm2-version: 4.2.0 dev: true - /terminal-link/2.1.1: - resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} - engines: {node: '>=8'} + /terser-webpack-plugin/5.3.6_webpack@5.75.0: + resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true dependencies: - ansi-escapes: 4.3.2 - supports-hyperlinks: 2.3.0 + '@jridgewell/trace-mapping': 0.3.15 + jest-worker: 27.5.1 + schema-utils: 3.1.1 + serialize-javascript: 6.0.0 + terser: 5.15.1 + webpack: 5.75.0_webpack-cli@4.10.0 + dev: true + + /terser/5.15.1: + resolution: {integrity: sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.2 + acorn: 8.8.0 + commander: 2.20.3 + source-map-support: 0.5.21 dev: true /test-exclude/6.0.0: @@ -11460,8 +10187,8 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true - /throat/5.0.0: - resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + /throat/6.0.1: + resolution: {integrity: sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==} dev: true /throttleit/1.0.0: @@ -11472,41 +10199,18 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true - /through2-filter/3.0.0: - resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==} - dependencies: - through2: 2.0.5 - xtend: 4.0.2 - dev: true - - /through2/2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.7 - xtend: 4.0.2 - dev: true - /through2/4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} dependencies: readable-stream: 3.6.0 dev: true - /tiny-lr/1.1.1: - resolution: {integrity: sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==} - dependencies: - body: 5.1.0 - debug: 3.2.7 - faye-websocket: 0.10.0 - livereload-js: 2.4.0 - object-assign: 4.1.1 - qs: 6.11.0 - transitivePeerDependencies: - - supports-color + /thunky/1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} dev: true - /tinybench/2.1.5: - resolution: {integrity: sha512-ak+PZZEuH3mw6CCFOgf5S90YH0MARnZNhxjhjguAmoJimEMAJuNip/rJRd6/wyylHItomVpKTzZk9zrhTrQCoQ==} + /tinybench/2.3.1: + resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==} dev: true /tinypool/0.3.0: @@ -11530,34 +10234,11 @@ packages: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true - /to-absolute-glob/2.0.2: - resolution: {integrity: sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==} - engines: {node: '>=0.10.0'} - dependencies: - is-absolute: 1.0.0 - is-negated-glob: 1.0.0 - dev: true - /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} dev: true - /to-object-path/0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /to-regex-range/2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - dev: true - /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -11565,23 +10246,6 @@ packages: is-number: 7.0.0 dev: true - /to-regex/3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - dev: true - - /to-through/2.0.0: - resolution: {integrity: sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==} - engines: {node: '>= 0.10'} - dependencies: - through2: 2.0.5 - dev: true - /toidentifier/1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -11626,32 +10290,47 @@ packages: hasBin: true dev: true - /trim-lines/1.1.3: - resolution: {integrity: sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==} - dev: true - /trim-newlines/3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} dev: true - /trim-trailing-lines/1.1.4: - resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} - dev: true - - /trim/0.0.1: - resolution: {integrity: sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==} - dev: true - - /trough/1.0.5: - resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - dev: true - /trough/2.1.0: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true - /ts-node/10.9.1_ck2axrxkiif44rdbzjywaqjysa: + /ts-node/10.9.1_cbe7ovvae6zqfnmtgctpgpys54: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 18.11.9 + acorn: 8.8.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.8.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /ts-node/10.9.1_sqjhzn5m3vxyw66a2xhtc43hby: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -11677,68 +10356,7 @@ packages: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /ts-node/10.9.1_ke6ijd35va4xbeayrnhu4zwagm: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - '@types/node': 18.7.21 - acorn: 8.8.0 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /ts-node/10.9.1_typescript@4.8.3: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - acorn: 8.8.0 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.8.3 + typescript: 4.8.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: true @@ -11751,14 +10369,14 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: true - /tsutils/3.21.0_typescript@4.8.3: + /tsutils/3.21.0_typescript@4.8.4: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.8.3 + typescript: 4.8.4 dev: true /tunnel-agent/0.6.0: @@ -11767,11 +10385,6 @@ packages: safe-buffer: 5.2.1 dev: true - /tunnel/0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - dev: true - /tweetnacl/0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} dev: true @@ -11828,63 +10441,57 @@ packages: mime-types: 2.1.35 dev: true - /typedarray/0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + /typedarray-to-buffer/3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 dev: true - /typescript/4.8.3: - resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} + /typedoc-plugin-markdown/3.13.6_typedoc@0.23.18: + resolution: {integrity: sha512-ISSc9v3BK7HkokxSBuJPttXox4tJ6hP0N9wfSIk0fmLN67+eqtAxbk97gs2nDiuha+RTO5eW9gdeAb+RPP0mgg==} + peerDependencies: + typedoc: '>=0.23.0' + dependencies: + handlebars: 4.7.7 + typedoc: 0.23.18_typescript@4.8.4 + dev: true + + /typedoc/0.23.18_typescript@4.8.4: + resolution: {integrity: sha512-0Tq/uFkUuWyRYyjOShTkhsOm6u5E8wf0i6L76/k5znEaxvWKHGeT2ywZThGrDrryV/skO/REM824D1gm8ccQuA==} + engines: {node: '>= 14.14'} + hasBin: true + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x + dependencies: + lunr: 2.3.9 + marked: 4.1.1 + minimatch: 5.1.0 + shiki: 0.11.1 + typescript: 4.8.4 + dev: true + + /typescript/4.8.4: + resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} engines: {node: '>=4.2.0'} hasBin: true dev: true - /uglify-js/3.17.1: - resolution: {integrity: sha512-+juFBsLLw7AqMaqJ0GFvlsGZwdQfI2ooKQB39PSBgMnMakcFosi9O8jCwE+2/2nMNcc0z63r9mwjoDG8zr+q0Q==} + /uc.micro/1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: true + + /uglify-js/3.17.3: + resolution: {integrity: sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==} engines: {node: '>=0.8.0'} hasBin: true requiresBuild: true dev: true optional: true - /unc-path-regex/0.1.2: - resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} - engines: {node: '>=0.10.0'} - dev: true - /underscore/1.1.7: resolution: {integrity: sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ==} dev: true - /unherit/1.1.3: - resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==} - dependencies: - inherits: 2.0.4 - xtend: 4.0.2 - dev: true - - /unicode-canonical-property-names-ecmascript/2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: true - - /unicode-match-property-ecmascript/2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - dev: true - - /unicode-match-property-value-ecmascript/2.0.0: - resolution: {integrity: sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==} - engines: {node: '>=4'} - dev: true - - /unicode-property-aliases-ecmascript/2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - dev: true - /unified/10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} dependencies: @@ -11897,75 +10504,21 @@ packages: vfile: 5.3.5 dev: true - /unified/6.2.0: - resolution: {integrity: sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==} + /unique-string/2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} dependencies: - '@types/unist': 2.0.6 - bail: 1.0.5 - extend: 3.0.2 - is-plain-obj: 1.1.0 - trough: 1.0.5 - vfile: 2.3.0 - x-is-string: 0.1.0 - dev: true - - /union-value/1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - dev: true - - /unique-stream/2.3.1: - resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==} - dependencies: - json-stable-stringify-without-jsonify: 1.0.1 - through2-filter: 3.0.0 - dev: true - - /unist-builder/1.0.4: - resolution: {integrity: sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==} - dependencies: - object-assign: 4.1.1 + crypto-random-string: 2.0.0 dev: true /unist-util-flatmap/1.0.0: resolution: {integrity: sha512-IG32jcKJlhARCYT2LsYPJWdoXYkzz3ESAdl1aa2hn9Auh+cgUmU6wgkII4yCc/1GgeWibRdELdCZh/p3QKQ1dQ==} dev: true - /unist-util-generated/1.1.6: - resolution: {integrity: sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==} - dev: true - - /unist-util-is/2.1.3: - resolution: {integrity: sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==} - dev: true - - /unist-util-is/3.0.0: - resolution: {integrity: sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==} - dev: true - /unist-util-is/5.1.1: resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} dev: true - /unist-util-position/3.1.0: - resolution: {integrity: sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==} - dev: true - - /unist-util-remove-position/1.1.4: - resolution: {integrity: sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==} - dependencies: - unist-util-visit: 1.4.1 - dev: true - - /unist-util-stringify-position/1.1.2: - resolution: {integrity: sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==} - dev: true - /unist-util-stringify-position/2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} dependencies: @@ -11978,12 +10531,6 @@ packages: '@types/unist': 2.0.6 dev: true - /unist-util-visit-parents/2.1.2: - resolution: {integrity: sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==} - dependencies: - unist-util-is: 3.0.0 - dev: true - /unist-util-visit-parents/5.1.1: resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} dependencies: @@ -11991,12 +10538,6 @@ packages: unist-util-is: 5.1.1 dev: true - /unist-util-visit/1.4.1: - resolution: {integrity: sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==} - dependencies: - unist-util-visit-parents: 2.1.2 - dev: true - /unist-util-visit/4.1.1: resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} dependencies: @@ -12025,21 +10566,13 @@ packages: engines: {node: '>= 0.8'} dev: true - /unset-value/1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - dev: true - /untildify/4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} dev: true - /update-browserslist-db/1.0.9_browserslist@4.21.4: - resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==} + /update-browserslist-db/1.0.10_browserslist@4.21.4: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -12055,11 +10588,6 @@ packages: punycode: 2.1.1 dev: true - /urix/0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true - /url-parse/1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} dependencies: @@ -12067,11 +10595,6 @@ packages: requires-port: 1.0.0 dev: true - /use/3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - dev: true - /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -12128,11 +10651,6 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /value-or-function/3.0.0: - resolution: {integrity: sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==} - engines: {node: '>= 0.10'} - dev: true - /vary/1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -12147,23 +10665,6 @@ packages: extsprintf: 1.3.0 dev: true - /vfile-location/2.0.6: - resolution: {integrity: sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==} - dev: true - - /vfile-message/1.1.1: - resolution: {integrity: sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==} - dependencies: - unist-util-stringify-position: 1.1.2 - dev: true - - /vfile-message/2.0.4: - resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} - dependencies: - '@types/unist': 2.0.6 - unist-util-stringify-position: 2.0.3 - dev: true - /vfile-message/3.1.2: resolution: {integrity: sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==} dependencies: @@ -12171,43 +10672,6 @@ packages: unist-util-stringify-position: 3.0.2 dev: true - /vfile-reporter/6.0.2: - resolution: {integrity: sha512-GN2bH2gs4eLnw/4jPSgfBjo+XCuvnX9elHICJZjVD4+NM0nsUrMTvdjGY5Sc/XG69XVTgLwj7hknQVc6M9FukA==} - dependencies: - repeat-string: 1.6.1 - string-width: 4.2.3 - supports-color: 6.1.0 - unist-util-stringify-position: 2.0.3 - vfile-sort: 2.2.2 - vfile-statistics: 1.1.4 - dev: true - - /vfile-sort/2.2.2: - resolution: {integrity: sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==} - dev: true - - /vfile-statistics/1.1.4: - resolution: {integrity: sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==} - dev: true - - /vfile/2.3.0: - resolution: {integrity: sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==} - dependencies: - is-buffer: 1.1.6 - replace-ext: 1.0.0 - unist-util-stringify-position: 1.1.2 - vfile-message: 1.1.1 - dev: true - - /vfile/4.2.1: - resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} - dependencies: - '@types/unist': 2.0.6 - is-buffer: 2.0.5 - unist-util-stringify-position: 2.0.3 - vfile-message: 2.0.4 - dev: true - /vfile/5.3.5: resolution: {integrity: sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==} dependencies: @@ -12217,83 +10681,120 @@ packages: vfile-message: 3.1.2 dev: true - /vinyl-fs/3.0.3: - resolution: {integrity: sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==} - engines: {node: '>= 0.10'} - dependencies: - fs-mkdirp-stream: 1.0.0 - glob-stream: 6.1.0 - graceful-fs: 4.2.10 - is-valid-glob: 1.0.0 - lazystream: 1.0.1 - lead: 1.0.0 - object.assign: 4.1.4 - pumpify: 1.5.1 - readable-stream: 2.3.7 - remove-bom-buffer: 3.0.0 - remove-bom-stream: 1.2.0 - resolve-options: 1.1.0 - through2: 2.0.5 - to-through: 2.0.0 - value-or-function: 3.0.0 - vinyl: 2.2.1 - vinyl-sourcemap: 1.1.0 - dev: true - - /vinyl-sourcemap/1.1.0: - resolution: {integrity: sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==} - engines: {node: '>= 0.10'} - dependencies: - append-buffer: 1.0.2 - convert-source-map: 1.8.0 - graceful-fs: 4.2.10 - normalize-path: 2.1.1 - now-and-later: 2.0.1 - remove-bom-buffer: 3.0.0 - vinyl: 2.2.1 - dev: true - - /vinyl/2.2.1: - resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} - engines: {node: '>= 0.10'} - dependencies: - clone: 2.1.2 - clone-buffer: 1.0.0 - clone-stats: 1.0.0 - cloneable-readable: 1.1.3 - remove-trailing-separator: 1.1.0 - replace-ext: 1.0.1 - dev: true - - /vite/3.1.3: - resolution: {integrity: sha512-/3XWiktaopByM5bd8dqvHxRt5EEgRikevnnrpND0gRfNkrMrPaGGexhtLCzv15RcCMtV2CLw+BPas8YFeSG0KA==} + /vite/3.2.3: + resolution: {integrity: sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: + '@types/node': '>= 14' less: '*' sass: '*' stylus: '*' + sugarss: '*' terser: ^5.4.0 peerDependenciesMeta: + '@types/node': + optional: true less: optional: true sass: optional: true stylus: optional: true + sugarss: + optional: true terser: optional: true dependencies: - esbuild: 0.15.8 - postcss: 8.4.16 + esbuild: 0.15.13 + postcss: 8.4.18 resolve: 1.22.1 - rollup: 2.78.1 + rollup: 2.79.1 optionalDependencies: fsevents: 2.3.2 dev: true - /vitest/0.23.4_y2hohvmcqnhseytaw4yjcnsnkm: - resolution: {integrity: sha512-iukBNWqQAv8EKDBUNntspLp9SfpaVFbmzmM0sNcnTxASQZMzRw3PsM6DMlsHiI+I6GeO5/sYDg3ecpC+SNFLrQ==} + /vite/3.2.3_@types+node@18.11.9: + resolution: {integrity: sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.11.9 + esbuild: 0.15.13 + postcss: 8.4.18 + resolve: 1.22.1 + rollup: 2.79.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitepress-plugin-search/1.0.4-alpha.15_s3edpouswd4dgoi2en7bdlrp54: + resolution: {integrity: sha512-Ef/VkhTVYlECVI0H9Ck6745UNPfYFppAqnlxVSMJXdxP2vjOZ5TYNczlTTQ2p9dh16MFw/IurbL1/GrG4nXdNw==} + engines: {node: ^14.13.1 || ^16.7.0 || >=18} + peerDependencies: + flexsearch: ^0.7.31 + vite: 2 || 3 + vitepress: ^1.0.0-alpha.13 + vue: '3' + dependencies: + '@types/flexsearch': 0.7.3 + '@types/markdown-it': 12.2.3 + flexsearch: 0.7.31 + markdown-it: 13.0.1 + vite: 3.2.3 + vitepress: 1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y + vue: 3.2.41 + dev: true + + /vitepress/1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y: + resolution: {integrity: sha512-pvbLssDMgLUN1terajmPlFBxHSDGO4DqwexKbjFyr7LeELerVuwGrG6F2J1hxmwOlbpLd1kHXEDqGm9JX/kTDQ==} + hasBin: true + dependencies: + '@docsearch/css': 3.3.0 + '@docsearch/js': 3.3.0_tbpndr44ulefs3hehwpi2mkf2y + '@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.41 + '@vue/devtools-api': 6.4.5 + '@vueuse/core': 9.4.0_vue@3.2.41 + body-scroll-lock: 4.0.0-beta.0 + shiki: 0.11.1 + vite: 3.2.3 + vue: 3.2.41 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - less + - react + - react-dom + - sass + - stylus + - sugarss + - terser + dev: true + + /vitest/0.25.1_oullksb5ic6y72oh2wekoaiuii: + resolution: {integrity: sha512-eH74h6MkuEgsqR4mAQZeMK9O0PROiKY+i+1GMz/fBi5A3L2ml5U7JQs7LfPU7+uWUziZyLHagl+rkyfR8SLhlA==} engines: {node: '>=v14.16.0'} hasBin: true peerDependencies: @@ -12316,21 +10817,72 @@ packages: dependencies: '@types/chai': 4.3.3 '@types/chai-subset': 1.3.3 - '@types/node': 18.7.21 - '@vitest/ui': 0.23.4 + '@types/node': 18.11.9 + '@vitest/ui': 0.25.1 + acorn: 8.8.0 + acorn-walk: 8.2.0 chai: 4.3.6 debug: 4.3.4 - jsdom: 20.0.0 + jsdom: 20.0.2 local-pkg: 0.4.2 + source-map: 0.6.1 strip-literal: 0.4.2 - tinybench: 2.1.5 + tinybench: 2.3.1 tinypool: 0.3.0 tinyspy: 1.0.2 - vite: 3.1.3 + vite: 3.2.3_@types+node@18.11.9 transitivePeerDependencies: - less - sass - stylus + - sugarss + - supports-color + - terser + dev: true + + /vitest/0.25.3_oullksb5ic6y72oh2wekoaiuii: + resolution: {integrity: sha512-/UzHfXIKsELZhL7OaM2xFlRF8HRZgAHtPctacvNK8H4vOcbJJAMEgbWNGSAK7Y9b1NBe5SeM7VTuz2RsTHFJJA==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.3 + '@types/chai-subset': 1.3.3 + '@types/node': 18.11.9 + '@vitest/ui': 0.25.1 + acorn: 8.8.0 + acorn-walk: 8.2.0 + chai: 4.3.6 + debug: 4.3.4 + jsdom: 20.0.2 + local-pkg: 0.4.2 + source-map: 0.6.1 + strip-literal: 0.4.2 + tinybench: 2.3.1 + tinypool: 0.3.0 + tinyspy: 1.0.2 + vite: 3.2.3_@types+node@18.11.9 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss - supports-color - terser dev: true @@ -12366,19 +10918,46 @@ packages: resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} dev: true + /vscode-oniguruma/1.6.2: + resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} + dev: true + + /vscode-textmate/6.0.0: + resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + dev: true + /vscode-uri/3.0.6: resolution: {integrity: sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==} dev: true - /vue-template-compiler/2.7.10: - resolution: {integrity: sha512-QO+8R9YRq1Gudm8ZMdo/lImZLJVUIAM8c07Vp84ojdDAf8HmPJc7XB556PcXV218k2AkKznsRz6xB5uOjAC4EQ==} + /vue-demi/0.13.11_vue@3.2.41: + resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true dependencies: - de-indent: 1.0.2 - he: 1.2.0 + vue: 3.2.41 + dev: true + + /vue/3.2.41: + resolution: {integrity: sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==} + dependencies: + '@vue/compiler-dom': 3.2.41 + '@vue/compiler-sfc': 3.2.41 + '@vue/runtime-dom': 3.2.41 + '@vue/server-renderer': 3.2.41_vue@3.2.41 + '@vue/shared': 3.2.41 dev: true /w3c-hr-time/1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. dependencies: browser-process-hrtime: 1.0.0 dev: true @@ -12410,6 +10989,20 @@ packages: makeerror: 1.0.12 dev: true + /watchpack/2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.10 + dev: true + + /wbuf/1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + dependencies: + minimalistic-assert: 1.0.1 + dev: true + /webdriver/7.16.11: resolution: {integrity: sha512-6nBOXae4xuBH4Nqvi/zvtwjnxSLTONBpxOiRJtQ68CYTYv5+w3m8CsaWy3HbK/0XXa++NYl62bDNn70OGEKb+Q==} engines: {node: '>=12.0.0'} @@ -12434,6 +11027,159 @@ packages: engines: {node: '>=12'} dev: true + /webpack-cli/4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi: + resolution: {integrity: sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + '@webpack-cli/migrate': '*' + webpack: 4.x.x || 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + '@webpack-cli/migrate': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 1.2.0_pda42hcaj7d62cr262fr632kue + '@webpack-cli/info': 1.5.0_webpack-cli@4.10.0 + '@webpack-cli/serve': 1.7.0_ud4agclah7rahur6ntojouq57y + colorette: 2.0.19 + commander: 7.2.0 + cross-spawn: 7.0.3 + fastest-levenshtein: 1.0.16 + import-local: 3.1.0 + interpret: 2.2.0 + rechoir: 0.7.1 + webpack: 5.75.0_webpack-cli@4.10.0 + webpack-dev-server: 4.11.1_pda42hcaj7d62cr262fr632kue + webpack-merge: 5.8.0 + dev: true + + /webpack-dev-middleware/5.3.3_webpack@5.75.0: + resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + dependencies: + colorette: 2.0.19 + memfs: 3.4.11 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.0.0 + webpack: 5.75.0_webpack-cli@4.10.0 + dev: true + + /webpack-dev-server/4.11.1_pda42hcaj7d62cr262fr632kue: + resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==} + engines: {node: '>= 12.13.0'} + hasBin: true + peerDependencies: + webpack: ^4.37.0 || ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/bonjour': 3.5.10 + '@types/connect-history-api-fallback': 1.3.5 + '@types/express': 4.17.14 + '@types/serve-index': 1.9.1 + '@types/serve-static': 1.15.0 + '@types/sockjs': 0.3.33 + '@types/ws': 8.5.3 + ansi-html-community: 0.0.8 + bonjour-service: 1.0.14 + chokidar: 3.5.3 + colorette: 2.0.19 + compression: 1.7.4 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.18.2 + graceful-fs: 4.2.10 + html-entities: 2.3.3 + http-proxy-middleware: 2.0.6_@types+express@4.17.14 + ipaddr.js: 2.0.1 + open: 8.4.0 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.0.0 + selfsigned: 2.1.1 + serve-index: 1.9.1 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack: 5.75.0_webpack-cli@4.10.0 + webpack-cli: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + webpack-dev-middleware: 5.3.3_webpack@5.75.0 + ws: 8.9.0 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + dev: true + + /webpack-merge/5.8.0: + resolution: {integrity: sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==} + engines: {node: '>=10.0.0'} + dependencies: + clone-deep: 4.0.1 + wildcard: 2.0.0 + dev: true + + /webpack-sources/3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack/5.75.0_webpack-cli@4.10.0: + resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 0.0.51 + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/wasm-edit': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + acorn: 8.8.0 + acorn-import-assertions: 1.8.0_acorn@8.8.0 + browserslist: 4.21.4 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.10.0 + es-module-lexer: 0.9.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.10 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.1.1 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.6_webpack@5.75.0 + watchpack: 2.4.0 + webpack-cli: 4.10.0_uaydpeuxkjjcxdbyfgk36cjdxi + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + /websocket-driver/0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} engines: {node: '>=0.8.0'} @@ -12455,10 +11201,6 @@ packages: iconv-lite: 0.6.3 dev: true - /whatwg-fetch/3.6.2: - resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} - dev: true - /whatwg-mimetype/3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} @@ -12487,10 +11229,6 @@ packages: webidl-conversions: 3.0.1 dev: true - /which-module/2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} - dev: true - /which/1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -12506,6 +11244,10 @@ packages: isexe: 2.0.0 dev: true + /wildcard/2.0.0: + resolution: {integrity: sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==} + dev: true + /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} @@ -12537,6 +11279,15 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /write-file-atomic/3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + /write-file-atomic/4.0.2: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -12571,8 +11322,8 @@ packages: optional: true dev: true - /ws/8.8.1: - resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} + /ws/8.9.0: + resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -12584,8 +11335,9 @@ packages: optional: true dev: true - /x-is-string/0.1.0: - resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==} + /xdg-basedir/4.0.0: + resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} + engines: {node: '>=8'} dev: true /xml-name-validator/4.0.0: @@ -12606,15 +11358,6 @@ packages: resolution: {integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==} dev: true - /xtend/4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: true - - /y18n/4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: true - /y18n/5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -12638,14 +11381,6 @@ packages: engines: {node: '>= 14'} dev: true - /yargs-parser/18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: true - /yargs-parser/20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -12656,23 +11391,6 @@ packages: engines: {node: '>=12'} dev: true - /yargs/15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.0 - y18n: 4.0.3 - yargs-parser: 18.1.3 - dev: true - /yargs/16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 067a01bf0..4b8be5cdc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: # all packages in direct subdirs of packages/ - 'packages/*' + - 'tests/*' diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..548f5b5be --- /dev/null +++ b/renovate.json @@ -0,0 +1,24 @@ +{ + "extends": [ + "config:base", + ":rebaseStalePrs", + "group:allNonMajor", + "schedule:earlyMondays", + ":automergeMinor", + ":automergeTesters", + ":automergeLinters", + ":automergeTypes", + ":automergePatch" + ], + "packageRules": [ + { + "matchUpdateTypes": ["minor", "patch", "digest"], + "automerge": true + } + ], + "dependencyDashboard": true, + "major": { + "dependencyDashboardApproval": true + }, + "dependencyDashboardAutoclose": true +} diff --git a/scripts/fixCSpell.ts b/scripts/fixCSpell.ts new file mode 100644 index 000000000..1d15e2194 --- /dev/null +++ b/scripts/fixCSpell.ts @@ -0,0 +1,24 @@ +/** + * Sorts all the `words` in the cSpell.json file. + * + * Run from the same folder as the `cSpell.json` file + * (i.e. the root of the Mermaid project). + */ + +import { readFileSync, writeFileSync } from 'node:fs'; +import prettier from 'prettier'; + +const filepath = './cSpell.json'; +const cSpell: { words: string[] } = JSON.parse(readFileSync(filepath, 'utf8')); + +cSpell.words = [...new Set(cSpell.words.map((word) => word.toLowerCase()))]; +cSpell.words.sort((a, b) => a.localeCompare(b)); + +const prettierConfig = prettier.resolveConfig.sync(filepath) ?? {}; +writeFileSync( + filepath, + prettier.format(JSON.stringify(cSpell), { + ...prettierConfig, + filepath, + }) +); diff --git a/packages/mermaid/src/jison/lint.mts b/scripts/jison/lint.mts similarity index 82% rename from packages/mermaid/src/jison/lint.mts rename to scripts/jison/lint.mts index 6e17851f7..c410d5999 100644 --- a/packages/mermaid/src/jison/lint.mts +++ b/scripts/jison/lint.mts @@ -11,6 +11,7 @@ const linter = new ESLint({ }); const lint = async (file: string): Promise => { + console.log(`Linting ${file}`); const jisonCode = await readFile(file, 'utf8'); // @ts-ignore no typings const jsCode = new jison.Generator(jisonCode, { moduleType: 'amd' }).generate(); @@ -23,9 +24,11 @@ const lint = async (file: string): Promise => { }; (async () => { - const jisonFiles = await globby(['./src/**/*.jison'], { dot: true }); + const jisonFiles = await globby(['./packages/**/*.jison', '!./**/node_modules/**'], { + dot: true, + }); const lintResults = await Promise.all(jisonFiles.map(lint)); - if (lintResults.some((result) => result === false)) { + if (lintResults.includes(false)) { process.exit(1); } })(); diff --git a/tests/webpack/package.json b/tests/webpack/package.json new file mode 100644 index 000000000..c58f456a6 --- /dev/null +++ b/tests/webpack/package.json @@ -0,0 +1,23 @@ +{ + "name": "webpack", + "version": "1.0.0", + "description": "", + "private": true, + "module": "commonjs", + "scripts": { + "build": "webpack", + "serve": "webpack serve" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "webpack": "^5.74.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.11.1" + }, + "dependencies": { + "mermaid": "workspace:*", + "@mermaid-js/mermaid-mindmap": "workspace:*" + } +} diff --git a/tests/webpack/public/index.html b/tests/webpack/public/index.html new file mode 100644 index 000000000..cf0e7da9f --- /dev/null +++ b/tests/webpack/public/index.html @@ -0,0 +1,11 @@ + + + + + Getting Started + + +
+ + + diff --git a/tests/webpack/src/index.js b/tests/webpack/src/index.js new file mode 100644 index 000000000..899f66596 --- /dev/null +++ b/tests/webpack/src/index.js @@ -0,0 +1,38 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable no-console */ +const mermaid = require('mermaid'); +import mindmap from '@mermaid-js/mermaid-mindmap'; + +const render = async (graph) => { + const svg = await mermaid.renderAsync('dummy', graph); + console.log(svg); + document.getElementById('graphDiv').innerHTML = svg; +}; + +const load = async () => { + await mermaid.registerExternalDiagrams([mindmap]); + await render('info'); + + setTimeout(async () => { + await render(`mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectivness
and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid + `); + }, 2500); +}; + +window.addEventListener('load', load, false); diff --git a/tests/webpack/webpack.config.js b/tests/webpack/webpack.config.js new file mode 100644 index 000000000..3c35a3922 --- /dev/null +++ b/tests/webpack/webpack.config.js @@ -0,0 +1,10 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require('path'); + +module.exports = { + entry: './src/index.js', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist'), + }, +}; diff --git a/todo-fix-root-level-tsconfig.json b/todo-fix-root-level-tsconfig.json deleted file mode 100644 index 0ffa0002e..000000000 --- a/todo-fix-root-level-tsconfig.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - // "incremental": true /* Enable incremental compilation */, - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ - "DOM", - "ES2021" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - - /* Modules */ - "module": "ES6" /* Specify what module code is generated. */, - "rootDir": "./src" /* Specify the root folder within your source files. */, - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./src" /* Specify the base directory to resolve non-relative module names. */, - // "paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */, - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [] /* Specify multiple folders that act like `./node_modules/@types`. */, - "types": [ - "vitest/globals" - ] /* Specify type package names to be included without being referenced in a source file. */, - - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - "resolveJsonModule": true /* Enable importing .json files */, - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - - /* Emit */ - "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist" /* Specify an output folder for all emitted files. */, - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - }, - "include": ["./src/**/*.ts", "./package.json"] -} diff --git a/tsconfig.json b/tsconfig.json index 99feb5bda..fe107f205 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "ES6" /* Specify what module code is generated. */, + "module": "es2022" /* Specify what module code is generated. */, // "rootDir": "./packages" /* Specify the root folder within your source files. */, "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./src" /* Specify the base directory to resolve non-relative module names. */, diff --git a/vite.config.ts b/vite.config.ts index 8d34e6184..e79295425 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -15,4 +15,12 @@ export default defineConfig({ reporter: ['text', 'json', 'html', 'lcov'], }, }, + build: { + /** If you set esmExternals to true, this plugins assumes that + all external dependencies are ES modules */ + + commonjsOptions: { + esmExternals: true, + }, + }, });
Array of array of strings in typescript syntax