mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			bugfix/545
			...
			6097-elk-g
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8277579259 | ||
| 
						 | 
					8336d1cf2d | ||
| 
						 | 
					3c93e4640a | ||
| 
						 | 
					0c28593ea5 | ||
| 
						 | 
					33d8b1a78d | 
@@ -33,14 +33,4 @@ export const packageOptions = {
 | 
			
		||||
    packageName: 'mermaid-layout-elk',
 | 
			
		||||
    file: 'layouts.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-layout-tidy-tree': {
 | 
			
		||||
    name: 'mermaid-layout-tidy-tree',
 | 
			
		||||
    packageName: 'mermaid-layout-tidy-tree',
 | 
			
		||||
    file: 'index.ts',
 | 
			
		||||
  },
 | 
			
		||||
  examples: {
 | 
			
		||||
    name: 'mermaid-examples',
 | 
			
		||||
    packageName: 'examples',
 | 
			
		||||
    file: 'index.ts',
 | 
			
		||||
  },
 | 
			
		||||
} as const satisfies Record<string, PackageOptions>;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [
 | 
			
		||||
  'block',
 | 
			
		||||
  'packet',
 | 
			
		||||
  'architecture',
 | 
			
		||||
  'radar',
 | 
			
		||||
] as const;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -10,16 +10,13 @@ const buildType = (packageName: string) => {
 | 
			
		||||
      console.log(out.toString());
 | 
			
		||||
    }
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error(e);
 | 
			
		||||
    if (e.stdout.length > 0) {
 | 
			
		||||
      console.error(e.stdout.toString());
 | 
			
		||||
    }
 | 
			
		||||
    if (e.stderr.length > 0) {
 | 
			
		||||
      console.error(e.stderr.toString());
 | 
			
		||||
    }
 | 
			
		||||
    // Exit the build process if we are in CI
 | 
			
		||||
    if (process.env.CI) {
 | 
			
		||||
      throw new Error(`Failed to build types for ${packageName}`);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.changeset/angry-bags-brake.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.changeset/angry-bags-brake.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: architecture diagrams no longer grow to extreme heights due to conflicting alignments
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Support edge animation in hand drawn look
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Resolved parsing error where direction TD was not recognized within subgraphs
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Correct viewBox casing and make SVGs responsive
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Improve participant parsing and prevent recursive loops on invalid syntax
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
chore: Fix mindmap rendering in docs and apply tidytree layout
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Ensure edge label color is applied when using classDef with edge IDs
 | 
			
		||||
							
								
								
									
										5
									
								
								.changeset/hungry-guests-drive.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.changeset/hungry-guests-drive.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
'@mermaid-js/layout-elk': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Updated offset calculations for diamond shape when handling intersections
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': minor
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
feat: Add half-arrowheads (solid & stick) and central connection support
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Resolve gantt chart crash due to invalid array length
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': minor
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
feat: Add IDs in architecture diagrams
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
chore: revert marked dependency from ^15.0.7 to ^16.0.0
 | 
			
		||||
 | 
			
		||||
- Reverted marked package version to ^16.0.0 for better compatibility
 | 
			
		||||
- This is a dependency update that maintains API compatibility
 | 
			
		||||
- All tests pass with the updated version
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'@mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix: Mindmap breaking in ELK layout
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
'mermaid': patch
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
fix(er-diagram): prevent syntax error when using 'u', numbers, and decimals in node names
 | 
			
		||||
@@ -47,13 +47,13 @@ edgesep
 | 
			
		||||
EMPTYSTR
 | 
			
		||||
enddate
 | 
			
		||||
ERDIAGRAM
 | 
			
		||||
eslint
 | 
			
		||||
flatmap
 | 
			
		||||
forwardable
 | 
			
		||||
frontmatter
 | 
			
		||||
funs
 | 
			
		||||
gantt
 | 
			
		||||
GENERICTYPE
 | 
			
		||||
getBoundarys
 | 
			
		||||
grammr
 | 
			
		||||
graphtype
 | 
			
		||||
halign
 | 
			
		||||
@@ -88,7 +88,6 @@ NODIR
 | 
			
		||||
NSTR
 | 
			
		||||
outdir
 | 
			
		||||
Qcontrolx
 | 
			
		||||
QSTR
 | 
			
		||||
reinit
 | 
			
		||||
rels
 | 
			
		||||
reqs
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,8 @@
 | 
			
		||||
Ashish Jain
 | 
			
		||||
cpettitt
 | 
			
		||||
Dong Cai
 | 
			
		||||
fourcube
 | 
			
		||||
knsv
 | 
			
		||||
Knut Sveidqvist
 | 
			
		||||
Nikolay Rozhkov
 | 
			
		||||
Peng Xiao
 | 
			
		||||
Per Brolin
 | 
			
		||||
Sidharth Vinod
 | 
			
		||||
subhash-halder
 | 
			
		||||
Vinod Sidharth
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,6 @@ dompurify
 | 
			
		||||
elkjs
 | 
			
		||||
fcose
 | 
			
		||||
fontawesome
 | 
			
		||||
Fonticons
 | 
			
		||||
Forgejo
 | 
			
		||||
Foswiki
 | 
			
		||||
Gitea
 | 
			
		||||
graphlib
 | 
			
		||||
 
 | 
			
		||||
@@ -5,20 +5,19 @@ bmatrix
 | 
			
		||||
braintree
 | 
			
		||||
catmull
 | 
			
		||||
compositTitleSize
 | 
			
		||||
cose
 | 
			
		||||
curv
 | 
			
		||||
doublecircle
 | 
			
		||||
elem
 | 
			
		||||
elems
 | 
			
		||||
gantt
 | 
			
		||||
gitgraph
 | 
			
		||||
gzipped
 | 
			
		||||
handDrawn
 | 
			
		||||
kanban
 | 
			
		||||
knsv
 | 
			
		||||
Knut
 | 
			
		||||
marginx
 | 
			
		||||
marginy
 | 
			
		||||
Markdownish
 | 
			
		||||
mermaidchart
 | 
			
		||||
mermaidjs
 | 
			
		||||
mindmap
 | 
			
		||||
mindmaps
 | 
			
		||||
@@ -36,6 +35,7 @@ sandboxed
 | 
			
		||||
siebling
 | 
			
		||||
statediagram
 | 
			
		||||
substate
 | 
			
		||||
Sveidqvist
 | 
			
		||||
unfixable
 | 
			
		||||
Viewbox
 | 
			
		||||
viewports
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
BRANDES
 | 
			
		||||
Buzan
 | 
			
		||||
circo
 | 
			
		||||
handDrawn
 | 
			
		||||
KOEPF
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { build } from 'esbuild';
 | 
			
		||||
import { cp, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
 | 
			
		||||
import { mkdir, writeFile } from 'node:fs/promises';
 | 
			
		||||
import { packageOptions } from '../.build/common.js';
 | 
			
		||||
import { generateLangium } from '../.build/generateLangium.js';
 | 
			
		||||
import type { MermaidBuildOptions } from './util.js';
 | 
			
		||||
@@ -31,27 +31,6 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
 | 
			
		||||
      // mermaid.js
 | 
			
		||||
      { ...iifeOptions },
 | 
			
		||||
      // mermaid.min.js
 | 
			
		||||
      { ...iifeOptions, minify: true, metafile: shouldVisualize },
 | 
			
		||||
      // mermaid.tiny.min.js
 | 
			
		||||
      {
 | 
			
		||||
        ...iifeOptions,
 | 
			
		||||
        minify: true,
 | 
			
		||||
        includeLargeFeatures: false,
 | 
			
		||||
        metafile: shouldVisualize,
 | 
			
		||||
        sourcemap: false,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  if (entryName === 'mermaid-zenuml') {
 | 
			
		||||
    const iifeOptions: MermaidBuildOptions = {
 | 
			
		||||
      ...commonOptions,
 | 
			
		||||
      format: 'iife',
 | 
			
		||||
      globalName: 'mermaid-zenuml',
 | 
			
		||||
    };
 | 
			
		||||
    buildConfigs.push(
 | 
			
		||||
      // mermaid-zenuml.js
 | 
			
		||||
      { ...iifeOptions },
 | 
			
		||||
      // mermaid-zenuml.min.js
 | 
			
		||||
      { ...iifeOptions, minify: true, metafile: shouldVisualize }
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
@@ -78,21 +57,6 @@ const handler = (e) => {
 | 
			
		||||
  process.exit(1);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const buildTinyMermaid = async () => {
 | 
			
		||||
  await mkdir('./packages/tiny/dist', { recursive: true });
 | 
			
		||||
  await rename(
 | 
			
		||||
    './packages/mermaid/dist/mermaid.tiny.min.js',
 | 
			
		||||
    './packages/tiny/dist/mermaid.tiny.js'
 | 
			
		||||
  );
 | 
			
		||||
  // Copy version from mermaid's package.json to tiny's package.json
 | 
			
		||||
  const mermaidPkg = JSON.parse(await readFile('./packages/mermaid/package.json', 'utf8'));
 | 
			
		||||
  const tinyPkg = JSON.parse(await readFile('./packages/tiny/package.json', 'utf8'));
 | 
			
		||||
  tinyPkg.version = mermaidPkg.version;
 | 
			
		||||
 | 
			
		||||
  await writeFile('./packages/tiny/package.json', JSON.stringify(tinyPkg, null, 2) + '\n');
 | 
			
		||||
  await cp('./packages/mermaid/CHANGELOG.md', './packages/tiny/CHANGELOG.md');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const main = async () => {
 | 
			
		||||
  await generateLangium();
 | 
			
		||||
  await mkdir('stats', { recursive: true });
 | 
			
		||||
@@ -101,7 +65,6 @@ const main = async () => {
 | 
			
		||||
  for (const pkg of packageNames) {
 | 
			
		||||
    await buildPackage(pkg).catch(handler);
 | 
			
		||||
  }
 | 
			
		||||
  await buildTinyMermaid();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void main();
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ export interface MermaidBuildOptions extends BuildOptions {
 | 
			
		||||
  metafile: boolean;
 | 
			
		||||
  format: 'esm' | 'iife';
 | 
			
		||||
  options: PackageOptions;
 | 
			
		||||
  includeLargeFeatures: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'> = {
 | 
			
		||||
@@ -22,7 +21,6 @@ export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'>
 | 
			
		||||
  metafile: false,
 | 
			
		||||
  core: false,
 | 
			
		||||
  format: 'esm',
 | 
			
		||||
  includeLargeFeatures: true,
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
const buildOptions = (override: BuildOptions): BuildOptions => {
 | 
			
		||||
@@ -41,18 +39,12 @@ const buildOptions = (override: BuildOptions): BuildOptions => {
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getFileName = (
 | 
			
		||||
  fileName: string,
 | 
			
		||||
  { core, format, minify, includeLargeFeatures }: MermaidBuildOptions
 | 
			
		||||
) => {
 | 
			
		||||
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
 | 
			
		||||
  if (core) {
 | 
			
		||||
    fileName += '.core';
 | 
			
		||||
  } else if (format === 'esm') {
 | 
			
		||||
    fileName += '.esm';
 | 
			
		||||
  }
 | 
			
		||||
  if (!includeLargeFeatures) {
 | 
			
		||||
    fileName += '.tiny';
 | 
			
		||||
  }
 | 
			
		||||
  if (minify) {
 | 
			
		||||
    fileName += '.min';
 | 
			
		||||
  }
 | 
			
		||||
@@ -62,27 +54,23 @@ const getFileName = (
 | 
			
		||||
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
 | 
			
		||||
  const {
 | 
			
		||||
    core,
 | 
			
		||||
    metafile,
 | 
			
		||||
    format,
 | 
			
		||||
    minify,
 | 
			
		||||
    options: { name, file, packageName },
 | 
			
		||||
    globalName = 'mermaid',
 | 
			
		||||
    includeLargeFeatures,
 | 
			
		||||
    ...rest
 | 
			
		||||
  } = options;
 | 
			
		||||
 | 
			
		||||
  const external: string[] = ['require', 'fs', 'path'];
 | 
			
		||||
  const outFileName = getFileName(name, options);
 | 
			
		||||
  const output: BuildOptions = buildOptions({
 | 
			
		||||
    ...rest,
 | 
			
		||||
    absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
 | 
			
		||||
    entryPoints: {
 | 
			
		||||
      [outFileName]: `src/${file}`,
 | 
			
		||||
    },
 | 
			
		||||
    globalName,
 | 
			
		||||
    metafile,
 | 
			
		||||
    minify,
 | 
			
		||||
    logLevel: 'info',
 | 
			
		||||
    chunkNames: `chunks/${outFileName}/[name]-[hash]`,
 | 
			
		||||
    define: {
 | 
			
		||||
      // This needs to be stringified for esbuild
 | 
			
		||||
      includeLargeFeatures: `${includeLargeFeatures}`,
 | 
			
		||||
      'import.meta.vitest': 'undefined',
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
@@ -101,12 +89,11 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
 | 
			
		||||
  if (format === 'iife') {
 | 
			
		||||
    output.format = 'iife';
 | 
			
		||||
    output.splitting = false;
 | 
			
		||||
    const originalGlobalName = output.globalName ?? 'mermaid';
 | 
			
		||||
    output.globalName = `__esbuild_esm_mermaid_nm[${JSON.stringify(originalGlobalName)}]`;
 | 
			
		||||
    output.globalName = '__esbuild_esm_mermaid';
 | 
			
		||||
    // Workaround for removing the .default access in esbuild IIFE.
 | 
			
		||||
    // https://github.com/mermaid-js/mermaid/pull/4109#discussion_r1292317396
 | 
			
		||||
    output.footer = {
 | 
			
		||||
      js: `globalThis[${JSON.stringify(originalGlobalName)}] = globalThis.${output.globalName}.default;`,
 | 
			
		||||
      js: 'globalThis.mermaid = globalThis.__esbuild_esm_mermaid.default;',
 | 
			
		||||
    };
 | 
			
		||||
    output.outExtension = { '.js': '.js' };
 | 
			
		||||
  } else {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,7 +4,7 @@ contact_links:
 | 
			
		||||
    url: https://github.com/mermaid-js/mermaid/discussions
 | 
			
		||||
    about: Ask the Community questions or share your own graphs in our discussions.
 | 
			
		||||
  - name: Discord
 | 
			
		||||
    url: https://discord.gg/sKeNQX4Wtj
 | 
			
		||||
    url: https://discord.gg/AgrbSrBer3
 | 
			
		||||
    about: Join our Community on Discord for Help and a casual chat.
 | 
			
		||||
  - name: Documentation
 | 
			
		||||
    url: https://mermaid.js.org
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/theme_proposal.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/theme_proposal.yml
									
									
									
									
										vendored
									
									
								
							@@ -29,7 +29,7 @@ body:
 | 
			
		||||
      label: Colors
 | 
			
		||||
      description: |-
 | 
			
		||||
        A detailed list of the different colour values to use.
 | 
			
		||||
        See the [list of currently used variable names](https://mermaid-js.github.io/mermaid/#/theming?id=theme-variables-reference-table)
 | 
			
		||||
        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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							@@ -46,21 +46,8 @@ exclude = [
 | 
			
		||||
# Drupal 403
 | 
			
		||||
"https://(www.)?drupal.org",
 | 
			
		||||
 | 
			
		||||
# Phbpp 403
 | 
			
		||||
"https://(www.)?phpbb.com",
 | 
			
		||||
 | 
			
		||||
# Swimm returns 404, even though the link is valid
 | 
			
		||||
"https://docs.swimm.io",
 | 
			
		||||
 | 
			
		||||
# Certificate Error
 | 
			
		||||
"https://noteshub.app",
 | 
			
		||||
 | 
			
		||||
# Timeout
 | 
			
		||||
"https://huehive.co",
 | 
			
		||||
"https://foswiki.org",
 | 
			
		||||
"https://www.gnu.org",
 | 
			
		||||
"https://redmine.org",
 | 
			
		||||
"https://mermaid-preview.com"
 | 
			
		||||
# Swimm returns 404, eventhough the link is valid
 | 
			
		||||
"https://docs.swimm.io"
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
# Exclude all private IPs from checking.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							@@ -15,5 +15,5 @@ markComment: >
 | 
			
		||||
  If you are still interested in this issue and it is still relevant you can comment to revive it.
 | 
			
		||||
# Comment to post when closing a stale issue. Set to `false` to disable
 | 
			
		||||
closeComment: >
 | 
			
		||||
  This issue has been automatically closed due to a lack of activity. 
 | 
			
		||||
  This issue has been been automatically closed due to a lack of activity. 
 | 
			
		||||
  This is done to maintain a clean list of issues that the community is interested in developing.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/autofix.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/autofix.yml
									
									
									
									
										vendored
									
									
								
							@@ -13,13 +13,13 @@ jobs:
 | 
			
		||||
  autofix:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
@@ -42,4 +42,4 @@ jobs:
 | 
			
		||||
        working-directory: ./packages/mermaid
 | 
			
		||||
        run: pnpm run docs:build
 | 
			
		||||
 | 
			
		||||
      - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # main
 | 
			
		||||
      - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c # main
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							@@ -18,12 +18,12 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/check-readme-in-sync.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/check-readme-in-sync.yml
									
									
									
									
										vendored
									
									
								
							@@ -18,7 +18,7 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - name: Check for difference in README.md and docs/README.md
 | 
			
		||||
        run: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							@@ -26,17 +26,17 @@ jobs:
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        language: ['javascript', 'actions']
 | 
			
		||||
        # CodeQL supports [ 'actions', 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
 | 
			
		||||
        language: ['javascript']
 | 
			
		||||
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
 | 
			
		||||
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      # Initializes the CodeQL tools for scanning.
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
 | 
			
		||||
        uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
 | 
			
		||||
        with:
 | 
			
		||||
          config-file: ./.github/codeql/codeql-config.yml
 | 
			
		||||
          languages: ${{ matrix.language }}
 | 
			
		||||
@@ -48,7 +48,7 @@ jobs:
 | 
			
		||||
      # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
 | 
			
		||||
      # If this step fails, then you should remove it and run the build manually (see below)
 | 
			
		||||
      - name: Autobuild
 | 
			
		||||
        uses: github/codeql-action/autobuild@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
 | 
			
		||||
        uses: github/codeql-action/autobuild@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
 | 
			
		||||
 | 
			
		||||
      # ℹ️ Command-line programs to run using the OS shell.
 | 
			
		||||
      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
 | 
			
		||||
@@ -62,4 +62,4 @@ jobs:
 | 
			
		||||
      #   make release
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
 | 
			
		||||
        uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
								
							@@ -15,6 +15,6 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: 'Checkout Repository'
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
      - name: 'Dependency Review'
 | 
			
		||||
        uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
 | 
			
		||||
        uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							@@ -23,37 +23,38 @@ env:
 | 
			
		||||
jobs:
 | 
			
		||||
  e2e-applitools:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
 | 
			
		||||
      options: --user 1001
 | 
			
		||||
    steps:
 | 
			
		||||
      - if: ${{ ! env.USE_APPLI }}
 | 
			
		||||
        name: Warn if not using Applitools
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "::error,title=Not using Applitools::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
 | 
			
		||||
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 | 
			
		||||
      - if: ${{ env.USE_APPLI }}
 | 
			
		||||
        name: Notify applitools of new batch
 | 
			
		||||
        # Copied from docs https://applitools.com/docs/topics/integrations/github-integration-ci-setup.html
 | 
			
		||||
        run: curl -L -d '' -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
 | 
			
		||||
        env:
 | 
			
		||||
          # e.g. mermaid-js/mermaid/my-branch
 | 
			
		||||
          APPLITOOLS_BRANCH: ${{ github.repository }}/${{ github.ref_name }}
 | 
			
		||||
          APPLITOOLS_PARENT_BRANCH: ${{ github.event.inputs.parent_branch }}
 | 
			
		||||
          APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
 | 
			
		||||
          APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
 | 
			
		||||
        uses: wei/curl@012398a392d02480afa2720780031f8621d5f94c
 | 
			
		||||
        with:
 | 
			
		||||
          args: -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
 | 
			
		||||
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@d79d2d530a66e641eb4a5f227e13bc985c60b964 # v4.2.2
 | 
			
		||||
        id: cypress
 | 
			
		||||
        with:
 | 
			
		||||
          start: pnpm run dev
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								.github/workflows/e2e-timings.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/e2e-timings.yml
									
									
									
									
										vendored
									
									
								
							@@ -11,7 +11,6 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: write
 | 
			
		||||
  pull-requests: write
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  timings:
 | 
			
		||||
@@ -20,19 +19,18 @@ jobs:
 | 
			
		||||
      image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
 | 
			
		||||
      options: --user 1001
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
 | 
			
		||||
        with:
 | 
			
		||||
          runTests: false
 | 
			
		||||
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
 | 
			
		||||
        id: cypress
 | 
			
		||||
        with:
 | 
			
		||||
          install: false
 | 
			
		||||
@@ -46,25 +44,10 @@ jobs:
 | 
			
		||||
          SPLIT: 1
 | 
			
		||||
          SPLIT_INDEX: 0
 | 
			
		||||
          SPLIT_FILE: 'cypress/timings.json'
 | 
			
		||||
 | 
			
		||||
      - name: Compare timings
 | 
			
		||||
        id: compare
 | 
			
		||||
        run: |
 | 
			
		||||
          OUTPUT=$(pnpm tsx scripts/compare-timings.ts)
 | 
			
		||||
          echo "$OUTPUT" >> $GITHUB_STEP_SUMMARY
 | 
			
		||||
 | 
			
		||||
          echo "output<<EOF" >> $GITHUB_OUTPUT
 | 
			
		||||
          echo "$OUTPUT" >> $GITHUB_OUTPUT
 | 
			
		||||
          echo "EOF" >> $GITHUB_OUTPUT
 | 
			
		||||
 | 
			
		||||
      - name: Commit and create pull request
 | 
			
		||||
        uses: peter-evans/create-pull-request@915d841dae6a4f191bb78faf61a257411d7be4d2
 | 
			
		||||
      - name: Commit changes
 | 
			
		||||
        uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
 | 
			
		||||
        with:
 | 
			
		||||
          add-paths: |
 | 
			
		||||
            cypress/timings.json
 | 
			
		||||
          commit-message: 'chore: update E2E timings'
 | 
			
		||||
          branch: update-timings
 | 
			
		||||
          title: Update E2E Timings
 | 
			
		||||
          body: ${{ steps.compare.outputs.output }}
 | 
			
		||||
          delete-branch: true
 | 
			
		||||
          sign-commits: true
 | 
			
		||||
          add: 'cypress/timings.json'
 | 
			
		||||
          author_name: 'github-actions[bot]'
 | 
			
		||||
          author_email: '41898282+github-actions[bot]@users.noreply.github.com'
 | 
			
		||||
          message: 'chore: update E2E timings'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							@@ -28,8 +28,6 @@ env:
 | 
			
		||||
      ) || 
 | 
			
		||||
      github.event.before
 | 
			
		||||
    }}
 | 
			
		||||
  RUN_VISUAL_TEST: >-
 | 
			
		||||
    ${{ github.repository == 'mermaid-js/mermaid' && (github.event_name != 'pull_request' || !startsWith(github.head_ref, 'renovate/')) }}
 | 
			
		||||
jobs:
 | 
			
		||||
  cache:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
@@ -37,29 +35,30 @@ jobs:
 | 
			
		||||
      image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
 | 
			
		||||
      options: --user 1001
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
      - name: Cache snapshots
 | 
			
		||||
        id: cache-snapshot
 | 
			
		||||
        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
 | 
			
		||||
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
 | 
			
		||||
        with:
 | 
			
		||||
          save-always: true
 | 
			
		||||
          path: ./cypress/snapshots
 | 
			
		||||
          key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
 | 
			
		||||
 | 
			
		||||
      # If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
 | 
			
		||||
      - name: Switch to base branch
 | 
			
		||||
        if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
        with:
 | 
			
		||||
          ref: ${{ env.targetHash }}
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
 | 
			
		||||
        with:
 | 
			
		||||
          # just perform install
 | 
			
		||||
          runTests: false
 | 
			
		||||
@@ -82,26 +81,26 @@ jobs:
 | 
			
		||||
      matrix:
 | 
			
		||||
        containers: [1, 2, 3, 4, 5]
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 | 
			
		||||
      # These cached snapshots are downloaded, providing the reference snapshots.
 | 
			
		||||
      - name: Cache snapshots
 | 
			
		||||
        id: cache-snapshot
 | 
			
		||||
        uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
 | 
			
		||||
        uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
 | 
			
		||||
        with:
 | 
			
		||||
          path: ./cypress/snapshots
 | 
			
		||||
          key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
 | 
			
		||||
        with:
 | 
			
		||||
          runTests: false
 | 
			
		||||
 | 
			
		||||
@@ -117,7 +116,7 @@ jobs:
 | 
			
		||||
      # Install NPM dependencies, cache them correctly
 | 
			
		||||
      # and run all Cypress tests
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f # v6.7.16
 | 
			
		||||
        uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6
 | 
			
		||||
        id: cypress
 | 
			
		||||
        with:
 | 
			
		||||
          install: false
 | 
			
		||||
@@ -126,20 +125,21 @@ jobs:
 | 
			
		||||
          browser: chrome
 | 
			
		||||
          # Disable recording if we don't have an API key
 | 
			
		||||
          # e.g. if this action was run from a fork
 | 
			
		||||
          record: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY != '' }}
 | 
			
		||||
          record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
 | 
			
		||||
        env:
 | 
			
		||||
          ARGOS_PARALLEL: ${{ env.RUN_VISUAL_TEST == 'true' }}
 | 
			
		||||
          ARGOS_PARALLEL_TOTAL: ${{ env.RUN_VISUAL_TEST == 'true' && strategy.job-total || 1 }}
 | 
			
		||||
          ARGOS_PARALLEL_INDEX: ${{ env.RUN_VISUAL_TEST == 'true' && matrix.containers || 1 }}
 | 
			
		||||
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
 | 
			
		||||
          VITEST_COVERAGE: true
 | 
			
		||||
          CYPRESS_COMMIT: ${{ github.sha }}
 | 
			
		||||
          CYPRESS_RECORD_KEY: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY || ''}}
 | 
			
		||||
          ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}
 | 
			
		||||
          ARGOS_PARALLEL: true
 | 
			
		||||
          ARGOS_PARALLEL_TOTAL: ${{ strategy.job-total }}
 | 
			
		||||
          ARGOS_PARALLEL_INDEX: ${{ matrix.containers }}
 | 
			
		||||
          SPLIT: ${{ strategy.job-total }}
 | 
			
		||||
          SPLIT_INDEX: ${{ strategy.job-index }}
 | 
			
		||||
          SPLIT_FILE: 'cypress/timings.json'
 | 
			
		||||
          VITEST_COVERAGE: true
 | 
			
		||||
 | 
			
		||||
      - name: Upload Coverage to Codecov
 | 
			
		||||
        uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
 | 
			
		||||
        uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
 | 
			
		||||
        # Run step only pushes to develop and pull_requests
 | 
			
		||||
        if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
 | 
			
		||||
        with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							@@ -29,17 +29,17 @@ jobs:
 | 
			
		||||
      # lychee only uses the GITHUB_TOKEN to avoid rate-limiting
 | 
			
		||||
      contents: read
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - name: Restore lychee cache
 | 
			
		||||
        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
 | 
			
		||||
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
 | 
			
		||||
        with:
 | 
			
		||||
          path: .lycheecache
 | 
			
		||||
          key: cache-lychee-${{ github.sha }}
 | 
			
		||||
          restore-keys: cache-lychee-
 | 
			
		||||
 | 
			
		||||
      - name: Link Checker
 | 
			
		||||
        uses: lycheeverse/lychee-action@f613c4a64e50d792e0b31ec34bbcbba12263c6a6 # v2.3.0
 | 
			
		||||
        uses: lycheeverse/lychee-action@c053181aa0c3d17606addfe97a9075a32723548a # v1.9.3
 | 
			
		||||
        with:
 | 
			
		||||
          args: >-
 | 
			
		||||
            --config .github/lychee.toml
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							@@ -15,7 +15,7 @@ jobs:
 | 
			
		||||
  docker-lint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0
 | 
			
		||||
        with:
 | 
			
		||||
@@ -23,13 +23,13 @@ jobs:
 | 
			
		||||
  lint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								.github/workflows/pr-labeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								.github/workflows/pr-labeler.yml
									
									
									
									
										vendored
									
									
								
							@@ -22,36 +22,10 @@ jobs:
 | 
			
		||||
      pull-requests: write # write permission is required to label PRs
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Label PR
 | 
			
		||||
        uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
 | 
			
		||||
        uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v6.0.0
 | 
			
		||||
        with:
 | 
			
		||||
          config-name: pr-labeler.yml
 | 
			
		||||
          disable-autolabeler: false
 | 
			
		||||
          disable-releaser: true
 | 
			
		||||
        env:
 | 
			
		||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
 | 
			
		||||
      - name: Add "Sponsored by MermaidChart" label
 | 
			
		||||
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
 | 
			
		||||
        with:
 | 
			
		||||
          github-token: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
          script: |
 | 
			
		||||
            const prNumber = context.payload.pull_request.number;
 | 
			
		||||
            const { data: commits } = await github.rest.pulls.listCommits({
 | 
			
		||||
              owner: context.repo.owner,
 | 
			
		||||
              repo: context.repo.repo,
 | 
			
		||||
              pull_number: prNumber,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const isSponsored = commits.every(
 | 
			
		||||
              (c) => c.commit.author.email?.endsWith('@mermaidchart.com')
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (isSponsored) {
 | 
			
		||||
              console.log('PR is sponsored. Adding label.');
 | 
			
		||||
              await github.rest.issues.addLabels({
 | 
			
		||||
                owner: context.repo.owner,
 | 
			
		||||
                repo: context.repo.repo,
 | 
			
		||||
                issue_number: prNumber,
 | 
			
		||||
                labels: ['Sponsored by MermaidChart'],
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							@@ -23,12 +23,12 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
@@ -37,7 +37,7 @@ jobs:
 | 
			
		||||
        run: pnpm install --frozen-lockfile
 | 
			
		||||
 | 
			
		||||
      - name: Setup Pages
 | 
			
		||||
        uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
 | 
			
		||||
        uses: actions/configure-pages@1f0c5cde4bc74cd7e1254d0cb4de8d49e9068c7d # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Run Build
 | 
			
		||||
        run: pnpm --filter mermaid run docs:build:vitepress
 | 
			
		||||
 
 | 
			
		||||
@@ -9,14 +9,14 @@ jobs:
 | 
			
		||||
  publish-preview:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 0
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/release-preview.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/release-preview.yml
									
									
									
									
										vendored
									
									
								
							@@ -26,12 +26,12 @@ jobs:
 | 
			
		||||
    timeout-minutes: 5
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout Repo
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							@@ -21,12 +21,12 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout Repo
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
@@ -36,7 +36,7 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Create Release Pull Request or Publish to npm
 | 
			
		||||
        id: changesets
 | 
			
		||||
        uses: changesets/action@06245a4e0a36c064a573d4150030f5ec548e4fcc # v1.4.10
 | 
			
		||||
        uses: changesets/action@3de3850952bec538fde60aac71731376e57b9b57 # v1.4.8
 | 
			
		||||
        with:
 | 
			
		||||
          version: pnpm changeset:version
 | 
			
		||||
          publish: pnpm changeset:publish
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							@@ -16,22 +16,22 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout code
 | 
			
		||||
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
        with:
 | 
			
		||||
          persist-credentials: false
 | 
			
		||||
      - name: Run analysis
 | 
			
		||||
        uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
 | 
			
		||||
        uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
 | 
			
		||||
        with:
 | 
			
		||||
          results_file: results.sarif
 | 
			
		||||
          results_format: sarif
 | 
			
		||||
          publish_results: true
 | 
			
		||||
      - name: Upload artifact
 | 
			
		||||
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
 | 
			
		||||
        uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
 | 
			
		||||
        with:
 | 
			
		||||
          name: SARIF file
 | 
			
		||||
          path: results.sarif
 | 
			
		||||
          retention-days: 5
 | 
			
		||||
      - name: Upload to code-scanning
 | 
			
		||||
        uses: github/codeql-action/upload-sarif@5378192d256ef1302a6980fffe5ca04426d43091 # v3.28.21
 | 
			
		||||
        uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
 | 
			
		||||
        with:
 | 
			
		||||
          sarif_file: results.sarif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,13 +9,13 @@ jobs:
 | 
			
		||||
  unit-test:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
 | 
			
		||||
        uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
 | 
			
		||||
        with:
 | 
			
		||||
          cache: pnpm
 | 
			
		||||
          node-version-file: '.node-version'
 | 
			
		||||
@@ -43,7 +43,7 @@ jobs:
 | 
			
		||||
          pnpm test:check:tsc
 | 
			
		||||
 | 
			
		||||
      - name: Upload Coverage to Codecov
 | 
			
		||||
        uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
 | 
			
		||||
        uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
 | 
			
		||||
        # Run step only pushes to develop and pull_requests
 | 
			
		||||
        if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
 | 
			
		||||
        with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,8 +8,8 @@ jobs:
 | 
			
		||||
  update-browser-list:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
 | 
			
		||||
      - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
 | 
			
		||||
      - run: npx update-browserslist-db@latest
 | 
			
		||||
      - name: Commit changes
 | 
			
		||||
        uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
 | 
			
		||||
@@ -19,7 +19,7 @@ jobs:
 | 
			
		||||
          message: 'chore: update browsers list'
 | 
			
		||||
          push: false
 | 
			
		||||
      - name: Create Pull Request
 | 
			
		||||
        uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
 | 
			
		||||
        uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
 | 
			
		||||
        with:
 | 
			
		||||
          branch: update-browserslist
 | 
			
		||||
          title: Update Browserslist
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								.github/workflows/validate-lockfile.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								.github/workflows/validate-lockfile.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,70 +0,0 @@
 | 
			
		||||
name: Validate pnpm-lock.yaml
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  pull_request:
 | 
			
		||||
    paths:
 | 
			
		||||
      - 'pnpm-lock.yaml'
 | 
			
		||||
      - '**/package.json'
 | 
			
		||||
      - '.github/workflows/validate-lockfile.yml'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  validate-lockfile:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout code
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 0
 | 
			
		||||
 | 
			
		||||
      - name: Set up Node.js
 | 
			
		||||
        uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          node-version: 20
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
 | 
			
		||||
 | 
			
		||||
      - name: Validate pnpm-lock.yaml entries
 | 
			
		||||
        id: validate # give this step an ID so we can reference its outputs
 | 
			
		||||
        run: |
 | 
			
		||||
          issues=()
 | 
			
		||||
 | 
			
		||||
          # 1) No tarball references
 | 
			
		||||
          if grep -qF 'tarball:' pnpm-lock.yaml; then
 | 
			
		||||
            issues+=("• Tarball references found (forbidden)")
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # 2) No unwanted vitepress paths
 | 
			
		||||
          if grep -qF 'packages/mermaid/src/vitepress' pnpm-lock.yaml; then
 | 
			
		||||
            issues+=("• Disallowed path 'packages/mermaid/src/vitepress' present. Run \`rm -rf packages/mermaid/src/vitepress && pnpm install\` to regenerate.")
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # 3) Lockfile only changes when package.json changes
 | 
			
		||||
          git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} > changed.txt
 | 
			
		||||
          if grep -q '^pnpm-lock.yaml$' changed.txt && ! grep -q 'package.json' changed.txt; then
 | 
			
		||||
            issues+=("• pnpm-lock.yaml changed without any package.json modification")
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # If any issues, output them and fail
 | 
			
		||||
          if [ ${#issues[@]} -gt 0 ]; then
 | 
			
		||||
            # Use the new GITHUB_OUTPUT approach to set a multiline output
 | 
			
		||||
            {
 | 
			
		||||
              echo "errors<<EOF"
 | 
			
		||||
              printf '%s\n' "${issues[@]}"
 | 
			
		||||
              echo "EOF"
 | 
			
		||||
            } >> $GITHUB_OUTPUT
 | 
			
		||||
            exit 1
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
      - name: Comment on PR if validation failed
 | 
			
		||||
        if: failure()
 | 
			
		||||
        uses: peter-evans/create-or-update-comment@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
          issue-number: ${{ github.event.pull_request.number }}
 | 
			
		||||
          body: |
 | 
			
		||||
            The following issue(s) were detected:
 | 
			
		||||
            ${{ steps.validate.outputs.errors }}
 | 
			
		||||
 | 
			
		||||
            Please address these and push an update.
 | 
			
		||||
 | 
			
		||||
            _Posted automatically by GitHub Actions_
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -4,7 +4,6 @@ node_modules/
 | 
			
		||||
coverage/
 | 
			
		||||
.idea/
 | 
			
		||||
.pnpm-store/
 | 
			
		||||
.instructions/
 | 
			
		||||
 | 
			
		||||
dist
 | 
			
		||||
v8-compile-cache-0
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
22.14.0
 | 
			
		||||
20.12.2
 | 
			
		||||
 
 | 
			
		||||
@@ -94,10 +94,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
 | 
			
		||||
      }),
 | 
			
		||||
      ...visualizerOptions(packageName, core),
 | 
			
		||||
    ],
 | 
			
		||||
    define: {
 | 
			
		||||
      // Needs to be string
 | 
			
		||||
      includeLargeFeatures: 'true',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (watch && config.build) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
./packages/mermaid/CHANGELOG.md
 | 
			
		||||
							
								
								
									
										1005
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1005
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
FROM node:22.12.0-alpine3.19@sha256:40dc4b415c17b85bea9be05314b4a753f45a4e1716bb31c01182e6c53d51a654
 | 
			
		||||
FROM node:20.12.2-alpine3.19@sha256:7a91aa397f2e2dfbfcdad2e2d72599f374e0b0172be1d86eeb73f1d33f36a4b2
 | 
			
		||||
 | 
			
		||||
USER 0:0
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								README.md
									
									
									
									
									
								
							@@ -15,7 +15,7 @@ Generate diagrams from markdown-like text.
 | 
			
		||||
<a href="https://mermaid.live/"><b>Live Editor!</b></a>
 | 
			
		||||
</p>
 | 
			
		||||
<p align="center">
 | 
			
		||||
 <a href="https://mermaid.js.org">📖 Documentation</a> | <a href="https://mermaid.js.org/intro/">🚀 Getting Started</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/sKeNQX4Wtj" title="Discord invite">🙌 Join Us</a>
 | 
			
		||||
 <a href="https://mermaid.js.org">📖 Documentation</a> | <a href="https://mermaid.js.org/intro/">🚀 Getting Started</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/AgrbSrBer3" title="Discord invite">🙌 Join Us</a>
 | 
			
		||||
</p>
 | 
			
		||||
<p align="center">
 | 
			
		||||
<a href="./README.zh-CN.md">简体中文</a>
 | 
			
		||||
@@ -33,7 +33,7 @@ Try Live Editor previews of future releases: <a href="https://develop.git.mermai
 | 
			
		||||
[](https://app.codecov.io/github/mermaid-js/mermaid/tree/develop)
 | 
			
		||||
[](https://www.jsdelivr.com/package/npm/mermaid)
 | 
			
		||||
[](https://www.npmjs.com/package/mermaid)
 | 
			
		||||
[](https://discord.gg/sKeNQX4Wtj)
 | 
			
		||||
[](https://discord.gg/AgrbSrBer3)
 | 
			
		||||
[](https://twitter.com/mermaidjs_)
 | 
			
		||||
[](https://argos-ci.com?utm_source=mermaid&utm_campaign=oss)
 | 
			
		||||
[](https://securityscorecards.dev/viewer/?uri=github.com/mermaid-js/mermaid)
 | 
			
		||||
@@ -44,7 +44,7 @@ Try Live Editor previews of future releases: <a href="https://develop.git.mermai
 | 
			
		||||
 | 
			
		||||
**Thanks to all involved, people committing pull requests, people answering questions! 🙏**
 | 
			
		||||
 | 
			
		||||
<a href="https://mermaid.js.org/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/intro/img/book-banner-post-release.jpg" alt='Banner for "The Official Guide to Mermaid.js" book'></a>
 | 
			
		||||
<a href="https://mermaid.js.org/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/intro/img/book-banner-post-release.jpg" alt="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!"></a>
 | 
			
		||||
 | 
			
		||||
## Table of content
 | 
			
		||||
 | 
			
		||||
@@ -253,34 +253,6 @@ pie
 | 
			
		||||
 | 
			
		||||
### Git graph [experimental - <a href="https://mermaid.live/edit#pako:eNqNkMFugzAMhl8F-VyVAR1tOW_aA-zKxSSGRCMJCk6lCvHuNZPKZdM0n-zf3_8r8QIqaIIGMqnB8kfEybQ--y4VnLP8-9RF9Mpkmm40hmlnDKmvkPiH_kfS7nFo_VN0FAf6XwocQGgxa_nGsm1bYEOOWmik1dRjGrmF1q-Cpkkj07u2HCI0PY4zHQATh8-7V9BwTPSE3iwOEd1OjQE1iWkBvk_bzQY7s0Sq4Hs7bHqKo8iGeZqbPN_WR7mpSd1RHpvPVhuMbG7XOq_L-oJlRfW5wteq0qorrpe-PBW9Pr8UJcK6rg-BLYPQ">live editor</a>]
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
gitGraph
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
  branch develop
 | 
			
		||||
  checkout develop
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
  checkout main
 | 
			
		||||
  merge develop
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```mermaid
 | 
			
		||||
gitGraph
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
  branch develop
 | 
			
		||||
  checkout develop
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
  checkout main
 | 
			
		||||
  merge develop
 | 
			
		||||
  commit
 | 
			
		||||
  commit
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Bar chart (using gantt chart) [<a href="https://mermaid.js.org/syntax/gantt.html">docs</a> - <a href="https://mermaid.live/edit#pako:eNptkU1vhCAQhv8KIenNugiI4rkf6bmXpvEyFVxJFDYyNt1u9r8X63Z7WQ9m5pknLzieaBeMpQ3dg0dsPUkPOhwteXZIXmJcbCT3xMAxkuh8Z8kIEclyMIB209fqKcwTICFvG4IvFy_oLrZ-g9F26ILfQgvNFN94VaRXQ1iWqpumZBcu1J8p1E1TXDx59eQNr5LyEqjJn6hv5QnGNlxevZJmdLLpy5xJSzut45biYCfb0iaVxvawjNjS1p-TCguG16PvaIPzYjO67e3BwX6GiTY9jPFKH43DMF_hGMDY1J4oHg-_f8hFTJFd8L3br3yZx4QHxENsdrt1nO8dDstH3oVpF50ZYMbhU6ud4qoGLqyqBJRCmO6j0HXPZdGbihUc6Pmc0QP49xD-b5X69ZQv2gjO81IwzWqhC1lKrjJ6pA3nVS7SMiVjrKirWlYp5fs3osgrWeo00lorLWvOzz8JVbXm">live editor</a>]
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
@@ -447,7 +419,7 @@ For public sites, it can be precarious to retrieve text from users on the intern
 | 
			
		||||
 | 
			
		||||
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 cannot 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._
 | 
			
		||||
_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
 | 
			
		||||
 | 
			
		||||
@@ -463,7 +435,7 @@ A quick note from Knut Sveidqvist:
 | 
			
		||||
>
 | 
			
		||||
> _Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017._
 | 
			
		||||
>
 | 
			
		||||
> _Thank you to the ever-growing list of [contributors](https://github.com/mermaid-js/mermaid/graphs/contributors) that brought the project this far!_
 | 
			
		||||
> _Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!_
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ Mermaid
 | 
			
		||||
<a href="https://mermaid.live/"><b>实时编辑器!</b></a>
 | 
			
		||||
</p>
 | 
			
		||||
<p align="center">
 | 
			
		||||
 <a href="https://mermaid.js.org">📖 文档</a> | <a href="https://mermaid.js.org/intro/">🚀 入门</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/sKeNQX4Wtj" title="Discord invite">🙌 加入我们</a>
 | 
			
		||||
 <a href="https://mermaid.js.org">📖 文档</a> | <a href="https://mermaid.js.org/intro/">🚀 入门</a> | <a href="https://www.jsdelivr.com/package/npm/mermaid">🌐 CDN</a> | <a href="https://discord.gg/AgrbSrBer3" title="Discord invite">🙌 加入我们</a>
 | 
			
		||||
</p>
 | 
			
		||||
<p align="center">
 | 
			
		||||
<a href="./README.md">English</a>
 | 
			
		||||
@@ -34,7 +34,7 @@ Mermaid
 | 
			
		||||
[](https://app.codecov.io/github/mermaid-js/mermaid/tree/develop)
 | 
			
		||||
[](https://www.jsdelivr.com/package/npm/mermaid)
 | 
			
		||||
[](https://www.npmjs.com/package/mermaid)
 | 
			
		||||
[](https://discord.gg/sKeNQX4Wtj)
 | 
			
		||||
[](https://discord.gg/AgrbSrBer3)
 | 
			
		||||
[](https://twitter.com/mermaidjs_)
 | 
			
		||||
 | 
			
		||||
<img src="./img/header.png" alt="" />
 | 
			
		||||
@@ -43,13 +43,13 @@ Mermaid
 | 
			
		||||
 | 
			
		||||
**感谢所有参与进来提交 PR,解答疑问的人们! 🙏**
 | 
			
		||||
 | 
			
		||||
<a href="https://mermaid.js.org/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/intro/img/book-banner-post-release.jpg" alt='Banner for "The Official Guide to Mermaid.js" book'></a>
 | 
			
		||||
<a href="https://mermaid.js.org/landing/"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/intro/img/book-banner-post-release.jpg" alt="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!"></a>
 | 
			
		||||
 | 
			
		||||
## 关于 Mermaid
 | 
			
		||||
 | 
			
		||||
<!-- <Main description>   -->
 | 
			
		||||
 | 
			
		||||
Mermaid 是一个基于 JavaScript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。
 | 
			
		||||
Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。
 | 
			
		||||
 | 
			
		||||
> Doc-Rot 是 Mermaid 致力于解决的一个难题。
 | 
			
		||||
 | 
			
		||||
@@ -358,7 +358,7 @@ _很不幸的是,鱼与熊掌不可兼得,在这个场景下它意味着在
 | 
			
		||||
 | 
			
		||||
> _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库!_ > _同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ > _感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
 | 
			
		||||
>
 | 
			
		||||
> _感谢越来越多的 [贡献者们](https://github.com/mermaid-js/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!_
 | 
			
		||||
> _感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!_
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								__mocks__/d3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								__mocks__/d3.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
import { MockedD3 } from '../packages/mermaid/src/tests/MockedD3.js';
 | 
			
		||||
 | 
			
		||||
export const select = function () {
 | 
			
		||||
  return new MockedD3();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const selectAll = function () {
 | 
			
		||||
  return new MockedD3();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const curveBasis = 'basis';
 | 
			
		||||
export const curveLinear = 'linear';
 | 
			
		||||
export const curveCardinal = 'cardinal';
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import eyesPlugin from '@applitools/eyes-cypress';
 | 
			
		||||
import { registerArgosTask } from '@argos-ci/cypress/task';
 | 
			
		||||
import coverage from '@cypress/code-coverage/task.js';
 | 
			
		||||
import coverage from '@cypress/code-coverage/task';
 | 
			
		||||
import { defineConfig } from 'cypress';
 | 
			
		||||
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin.js';
 | 
			
		||||
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin';
 | 
			
		||||
import cypressSplit from 'cypress-split';
 | 
			
		||||
 | 
			
		||||
export default eyesPlugin(
 | 
			
		||||
@@ -23,12 +23,11 @@ export default eyesPlugin(
 | 
			
		||||
        });
 | 
			
		||||
        // copy any needed variables from process.env to config.env
 | 
			
		||||
        config.env.useAppli = process.env.USE_APPLI ? true : false;
 | 
			
		||||
        config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
 | 
			
		||||
        config.env.useArgos = !!process.env.CI;
 | 
			
		||||
 | 
			
		||||
        if (config.env.useArgos) {
 | 
			
		||||
          registerArgosTask(on, config, {
 | 
			
		||||
            // Enable upload to Argos only when it runs on CI.
 | 
			
		||||
            uploadToArgos: !!process.env.CI,
 | 
			
		||||
            token: 'fc3a35cf5200db928d65b2047861582d9444032b',
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          addMatchImageSnapshotPlugin(on, config);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ interface CypressConfig {
 | 
			
		||||
  listUrl?: boolean;
 | 
			
		||||
  listId?: string;
 | 
			
		||||
  name?: string;
 | 
			
		||||
  screenshot?: boolean;
 | 
			
		||||
}
 | 
			
		||||
type CypressMermaidConfig = MermaidConfig & CypressConfig;
 | 
			
		||||
 | 
			
		||||
@@ -15,7 +14,7 @@ interface CodeObject {
 | 
			
		||||
  mermaid: CypressMermaidConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const utf8ToB64 = (str: string): string => {
 | 
			
		||||
const utf8ToB64 = (str: string): string => {
 | 
			
		||||
  return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -23,7 +22,7 @@ const batchId: string =
 | 
			
		||||
  'mermaid-batch-' +
 | 
			
		||||
  (Cypress.env('useAppli')
 | 
			
		||||
    ? Date.now().toString()
 | 
			
		||||
    : (Cypress.env('CYPRESS_COMMIT') ?? Date.now().toString()));
 | 
			
		||||
    : Cypress.env('CYPRESS_COMMIT') || Date.now().toString());
 | 
			
		||||
 | 
			
		||||
export const mermaidUrl = (
 | 
			
		||||
  graphStr: string | string[],
 | 
			
		||||
@@ -62,7 +61,9 @@ export const imgSnapshotTest = (
 | 
			
		||||
    sequence: {
 | 
			
		||||
      ...(_options.sequence ?? {}),
 | 
			
		||||
      actorFontFamily: 'courier',
 | 
			
		||||
      noteFontFamily: _options.sequence?.noteFontFamily ?? 'courier',
 | 
			
		||||
      noteFontFamily: _options.sequence?.noteFontFamily
 | 
			
		||||
        ? _options.sequence.noteFontFamily
 | 
			
		||||
        : 'courier',
 | 
			
		||||
      messageFontFamily: 'courier',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
@@ -91,7 +92,7 @@ export const renderGraph = (
 | 
			
		||||
 | 
			
		||||
export const openURLAndVerifyRendering = (
 | 
			
		||||
  url: string,
 | 
			
		||||
  { screenshot = true, ...options }: CypressMermaidConfig,
 | 
			
		||||
  options: CypressMermaidConfig,
 | 
			
		||||
  validation?: any
 | 
			
		||||
): void => {
 | 
			
		||||
  const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
 | 
			
		||||
@@ -99,15 +100,12 @@ export const openURLAndVerifyRendering = (
 | 
			
		||||
  cy.visit(url);
 | 
			
		||||
  cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
  cy.get('svg').should('be.visible');
 | 
			
		||||
  cy.get('svg').should('not.have.attr', 'viewbox');
 | 
			
		||||
 | 
			
		||||
  if (validation) {
 | 
			
		||||
    cy.get('svg').should(validation);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (screenshot) {
 | 
			
		||||
    verifyScreenshot(name);
 | 
			
		||||
  }
 | 
			
		||||
  verifyScreenshot(name);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const verifyScreenshot = (name: string): void => {
 | 
			
		||||
@@ -134,10 +132,3 @@ export const verifyScreenshot = (name: string): void => {
 | 
			
		||||
    cy.matchImageSnapshot(name);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const verifyNumber = (value: number, expected: number, deltaPercent = 10): void => {
 | 
			
		||||
  expect(value).to.be.within(
 | 
			
		||||
    expected * (1 - deltaPercent / 100),
 | 
			
		||||
    expected * (1 + deltaPercent / 100)
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -69,9 +69,7 @@ describe('Configuration', () => {
 | 
			
		||||
          .and('include', 'url(#');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    // This has been broken for a long time, but something about the Cypress environment was
 | 
			
		||||
    // rewriting the URL to be relative, causing the test to incorrectly pass.
 | 
			
		||||
    it.skip('should handle arrowMarkerAbsolute explicitly set to "false" as false', () => {
 | 
			
		||||
    it('should handle arrowMarkerAbsolute explicitly set to "false" as false', () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `graph TD
 | 
			
		||||
        A[Christmas] -->|Get money| B(Go shopping)
 | 
			
		||||
@@ -98,12 +96,12 @@ describe('Configuration', () => {
 | 
			
		||||
    it('should handle arrowMarkerAbsolute set to true', () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `flowchart TD
 | 
			
		||||
    A[Christmas] -->|Get money| B(Go shopping)
 | 
			
		||||
    B --> C{Let me think}
 | 
			
		||||
    C -->|One| D[Laptop]
 | 
			
		||||
    C -->|Two| E[iPhone]
 | 
			
		||||
    C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
    `,
 | 
			
		||||
        A[Christmas] -->|Get money| B(Go shopping)
 | 
			
		||||
        B --> C{Let me think}
 | 
			
		||||
        C -->|One| D[Laptop]
 | 
			
		||||
        C -->|Two| E[iPhone]
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        {
 | 
			
		||||
          arrowMarkerAbsolute: true,
 | 
			
		||||
        }
 | 
			
		||||
@@ -113,6 +111,7 @@ describe('Configuration', () => {
 | 
			
		||||
        cy.get('path')
 | 
			
		||||
          .first()
 | 
			
		||||
          .should('have.attr', 'marker-end')
 | 
			
		||||
          .should('exist')
 | 
			
		||||
          .and('include', 'url(http://localhost');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ describe('Interaction', () => {
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    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` tag. The .node is a child of `a`, so we have to use `find()` instead of `parent`.
 | 
			
		||||
      // 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');
 | 
			
		||||
@@ -146,7 +146,7 @@ describe('Interaction', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Interaction - security level other, misspelling', () => {
 | 
			
		||||
  describe('Interaction - security level other, missspelling', () => {
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
      cy.visit('http://localhost:9000/click_security_other.html');
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
 | 
			
		||||
import { mermaidUrl } from '../../helpers/util.ts';
 | 
			
		||||
describe('XSS', () => {
 | 
			
		||||
  it('should handle xss in tags', () => {
 | 
			
		||||
    const str =
 | 
			
		||||
@@ -141,37 +141,4 @@ describe('XSS', () => {
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should sanitize icon labels in architecture diagrams', () => {
 | 
			
		||||
    const str = JSON.stringify({
 | 
			
		||||
      code: `architecture-beta
 | 
			
		||||
    group api(cloud)[API]
 | 
			
		||||
    service db "<img src=x onerror=\\"xssAttack()\\">" [Database] in api`,
 | 
			
		||||
    });
 | 
			
		||||
    imgSnapshotTest(utf8ToB64(str), {}, true);
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should sanitize katex blocks', () => {
 | 
			
		||||
    const str = JSON.stringify({
 | 
			
		||||
      code: `sequenceDiagram
 | 
			
		||||
    participant A as Alice<img src="x" onerror="xssAttack()">$$\\text{Alice}$$
 | 
			
		||||
    A->>John: Hello John, how are you?`,
 | 
			
		||||
    });
 | 
			
		||||
    imgSnapshotTest(utf8ToB64(str), {}, true);
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should sanitize labels', () => {
 | 
			
		||||
    const str = JSON.stringify({
 | 
			
		||||
      code: `erDiagram
 | 
			
		||||
    "<img src=x onerror=xssAttack()>" ||--|| ENTITY2 : "<img src=x onerror=xssAttack()>"
 | 
			
		||||
    `,
 | 
			
		||||
    });
 | 
			
		||||
    imgSnapshotTest(utf8ToB64(str), {}, true);
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -19,25 +19,6 @@ describe.skip('architecture diagram', () => {
 | 
			
		||||
            `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple architecture diagram with titleAndAccessibilities', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `architecture-beta
 | 
			
		||||
          title Simple Architecture Diagram
 | 
			
		||||
          accTitle: Accessibility Title
 | 
			
		||||
          accDescr: Accessibility Description
 | 
			
		||||
          group api(cloud)[API]
 | 
			
		||||
 | 
			
		||||
          service db(database)[Database] in api
 | 
			
		||||
          service disk1(disk)[Storage] in api
 | 
			
		||||
          service disk2(disk)[Storage] in api
 | 
			
		||||
          service server(server)[Server] in api
 | 
			
		||||
 | 
			
		||||
          db:L -- R:server
 | 
			
		||||
          disk1:T -- B:server
 | 
			
		||||
          disk2:T -- B:db
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render an architecture diagram with groups within groups', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `architecture-beta
 | 
			
		||||
@@ -191,7 +172,7 @@ describe.skip('architecture diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render an architecture diagram with a reasonable height', () => {
 | 
			
		||||
  it('should render an architecture diagram with a resonable height', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `architecture-beta
 | 
			
		||||
              group federated(cloud)[Federated Environment]
 | 
			
		||||
 
 | 
			
		||||
@@ -14,9 +14,9 @@ describe('Block diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL2: should handle columns statement in sub-blocks', () => {
 | 
			
		||||
  it('BL2: should handle colums statement in sub-blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  id1["Hello"]
 | 
			
		||||
  block
 | 
			
		||||
    columns 3
 | 
			
		||||
@@ -30,9 +30,9 @@ describe('Block diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
 | 
			
		||||
  it('BL3: should align block widths and handle colums statement in sub-blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  block
 | 
			
		||||
    columns 1
 | 
			
		||||
    id1
 | 
			
		||||
@@ -46,9 +46,9 @@ describe('Block diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
 | 
			
		||||
  it('BL4: should align block widths and handle colums statements in deeper sub-blocks then 1 level', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 1
 | 
			
		||||
  block
 | 
			
		||||
    columns 1
 | 
			
		||||
@@ -66,9 +66,9 @@ describe('Block diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
 | 
			
		||||
  it('BL5: should align block widths and handle colums statements in deeper sub-blocks then 1 level (alt)', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 1
 | 
			
		||||
  block
 | 
			
		||||
    id1
 | 
			
		||||
@@ -87,7 +87,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL6: should handle block arrows and spece statements', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    columns 3
 | 
			
		||||
    space:3
 | 
			
		||||
    ida idb idc
 | 
			
		||||
@@ -106,7 +106,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL7: should handle different types of edges', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 3
 | 
			
		||||
      A space:5
 | 
			
		||||
      A --o B
 | 
			
		||||
@@ -119,7 +119,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL8: should handle sub-blocks without columns statements', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 2
 | 
			
		||||
      C A B
 | 
			
		||||
      block
 | 
			
		||||
@@ -133,7 +133,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 3
 | 
			
		||||
      B space
 | 
			
		||||
      block
 | 
			
		||||
@@ -147,7 +147,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL10: should handle edges from composite blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 3
 | 
			
		||||
      B space
 | 
			
		||||
      block BL
 | 
			
		||||
@@ -161,7 +161,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL11: should handle edges to composite blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 3
 | 
			
		||||
      B space
 | 
			
		||||
      block BL
 | 
			
		||||
@@ -175,7 +175,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL12: edges should handle labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      A
 | 
			
		||||
      space
 | 
			
		||||
      A -- "apa" --> E
 | 
			
		||||
@@ -186,7 +186,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL13: should handle block arrows in different directions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      columns 3
 | 
			
		||||
      space blockArrowId1<["down"]>(down) space
 | 
			
		||||
      blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
 | 
			
		||||
@@ -199,7 +199,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL14: should style statements and class statements', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A
 | 
			
		||||
    B
 | 
			
		||||
    classDef blue fill:#66f,stroke:#333,stroke-width:2px;
 | 
			
		||||
@@ -212,7 +212,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL15: width alignment - D and E should share available space', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  block
 | 
			
		||||
    D
 | 
			
		||||
    E
 | 
			
		||||
@@ -225,7 +225,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL16: width alignment - C should be as wide as the composite block', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  block
 | 
			
		||||
    A("This is the text")
 | 
			
		||||
    B
 | 
			
		||||
@@ -236,9 +236,9 @@ describe('Block diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL17: width alignment - blocks should be equal in width', () => {
 | 
			
		||||
  it('BL17: width alignment - blocks shold be equal in width', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A("This is the text")
 | 
			
		||||
    B
 | 
			
		||||
    C
 | 
			
		||||
@@ -249,7 +249,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL18: block types 1 - square, rounded and circle', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A["square"]
 | 
			
		||||
    B("rounded")
 | 
			
		||||
    C(("circle"))
 | 
			
		||||
@@ -260,7 +260,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL19: block types 2 - odd, diamond and hexagon', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A>"rect_left_inv_arrow"]
 | 
			
		||||
    B{"diamond"}
 | 
			
		||||
    C{{"hexagon"}}
 | 
			
		||||
@@ -271,7 +271,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL20: block types 3 - stadium', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A(["stadium"])
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
@@ -280,7 +280,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A[/"lean right"/]
 | 
			
		||||
    B[\"lean left"\]
 | 
			
		||||
    C[/"trapezoid"\]
 | 
			
		||||
@@ -292,7 +292,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL22: block types 1 - square, rounded and circle', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
    A["square"]
 | 
			
		||||
    B("rounded")
 | 
			
		||||
    C(("circle"))
 | 
			
		||||
@@ -303,7 +303,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL23: sizing - it should be possible to make a block wider', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      A("rounded"):2
 | 
			
		||||
      B:2
 | 
			
		||||
      C
 | 
			
		||||
@@ -314,7 +314,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL24: sizing - it should be possible to make a composite block wider', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
      block:2
 | 
			
		||||
        A
 | 
			
		||||
      end
 | 
			
		||||
@@ -326,7 +326,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL25: block in the middle with space on each side', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
        columns 3
 | 
			
		||||
        space
 | 
			
		||||
        middle["In the middle"]
 | 
			
		||||
@@ -337,7 +337,7 @@ describe('Block diagram', () => {
 | 
			
		||||
  });
 | 
			
		||||
  it('BL26: space and an edge', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 5
 | 
			
		||||
    A space B
 | 
			
		||||
    A --x B
 | 
			
		||||
@@ -347,7 +347,7 @@ describe('Block diagram', () => {
 | 
			
		||||
  });
 | 
			
		||||
  it('BL27: block sizes for regular blocks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 3
 | 
			
		||||
    a["A wide one"] b:2 c:2 d
 | 
			
		||||
      `,
 | 
			
		||||
@@ -356,7 +356,7 @@ describe('Block diagram', () => {
 | 
			
		||||
  });
 | 
			
		||||
  it('BL28: composite block with a set width - f should use the available space', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 3
 | 
			
		||||
  a:3
 | 
			
		||||
  block:e:3
 | 
			
		||||
@@ -370,7 +370,7 @@ describe('Block diagram', () => {
 | 
			
		||||
 | 
			
		||||
  it('BL29: composite block with a set width - f and g should split the available space', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 3
 | 
			
		||||
  a:3
 | 
			
		||||
  block:e:3
 | 
			
		||||
@@ -384,28 +384,4 @@ describe('Block diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL30: block should overflow if too wide for columns', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block-beta
 | 
			
		||||
  columns 2
 | 
			
		||||
  fit:2
 | 
			
		||||
  overflow:3
 | 
			
		||||
  short:1
 | 
			
		||||
  also_overflow:2
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('BL31: edge without arrow syntax should render with no arrowheads', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `block-beta
 | 
			
		||||
  a
 | 
			
		||||
  b
 | 
			
		||||
  a --- b
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -429,7 +429,7 @@ describe('Class diagram', () => {
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class \`This\nTitle\nHas\nMany\nNewlines\` {
 | 
			
		||||
        +String Also
 | 
			
		||||
        -String Many
 | 
			
		||||
        -Stirng Many
 | 
			
		||||
        #int Members
 | 
			
		||||
        +And()
 | 
			
		||||
        -Many()
 | 
			
		||||
@@ -443,7 +443,7 @@ describe('Class diagram', () => {
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class \`This\nTitle\nHas\nMany\nNewlines\` {
 | 
			
		||||
        +String Also
 | 
			
		||||
        -String Many
 | 
			
		||||
        -Stirng Many
 | 
			
		||||
        #int Members
 | 
			
		||||
        +And()
 | 
			
		||||
        -Many()
 | 
			
		||||
@@ -459,7 +459,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      namespace testingNamespace {
 | 
			
		||||
      class \`This\nTitle\nHas\nMany\nNewlines\` {
 | 
			
		||||
        +String Also
 | 
			
		||||
        -String Many
 | 
			
		||||
        -Stirng Many
 | 
			
		||||
        #int Members
 | 
			
		||||
        +And()
 | 
			
		||||
        -Many()
 | 
			
		||||
@@ -495,47 +495,4 @@ describe('Class diagram', () => {
 | 
			
		||||
      cy.get('a').should('have.attr', 'target', '_blank').should('have.attr', 'rel', 'noopener');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Include char sequence "graph" in text (#6795)', () => {
 | 
			
		||||
    it('has a label with char sequence "graph"', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        classDiagram
 | 
			
		||||
          class Person {
 | 
			
		||||
            +String name
 | 
			
		||||
            -Int id
 | 
			
		||||
            #double age
 | 
			
		||||
            +Text demographicProfile
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle backticks for namespace and class names', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      classDiagram
 | 
			
		||||
          namespace \`A::B\` {
 | 
			
		||||
              class \`IPC::Sender\`
 | 
			
		||||
          }
 | 
			
		||||
          RenderProcessHost --|> \`IPC::Sender\`
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    it('should handle an empty class body with empty braces', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        ` classDiagram
 | 
			
		||||
        class FooBase~T~ {}
 | 
			
		||||
    class Bar {
 | 
			
		||||
        +Zip
 | 
			
		||||
        +Zap()
 | 
			
		||||
    }
 | 
			
		||||
    FooBase <|-- Ba
 | 
			
		||||
        `,
 | 
			
		||||
        { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,652 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
const testOptions = [
 | 
			
		||||
  { description: '', options: { logLevel: 1 } },
 | 
			
		||||
  { description: 'ELK: ', options: { logLevel: 1, layout: 'elk' } },
 | 
			
		||||
  { description: 'HD: ', options: { logLevel: 1, look: 'handDrawn' } },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
describe('Entity Relationship Diagram Unified', () => {
 | 
			
		||||
  testOptions.forEach(({ description, options }) => {
 | 
			
		||||
    it(`${description}should render a simple ER diagram`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a simple ER diagram without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with a recursive relationship`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||..o{ CUSTOMER : refers
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with multiple relationships between the same two entities`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||--|{ ADDRESS : "invoiced at"
 | 
			
		||||
          CUSTOMER ||--|{ ADDRESS : "receives goods at"
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a cyclical ER diagram`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          A ||--|{ B : likes
 | 
			
		||||
          B ||--|{ C : likes
 | 
			
		||||
          C ||--|{ A : likes
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a not-so-simple ER diagram`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER }|..|{ DELIVERY-ADDRESS : has
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          CUSTOMER ||--o{ INVOICE : "liable for"
 | 
			
		||||
          DELIVERY-ADDRESS ||--o{ ORDER : receives
 | 
			
		||||
          INVOICE ||--|{ ORDER : covers
 | 
			
		||||
          ORDER ||--|{ ORDER-ITEM : includes
 | 
			
		||||
          PRODUCT-CATEGORY ||--|{ PRODUCT : contains
 | 
			
		||||
          PRODUCT ||--o{ ORDER-ITEM : "ordered in"
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a not-so-simple ER diagram without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER }|..|{ DELIVERY-ADDRESS : has
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          CUSTOMER ||--o{ INVOICE : "liable for"
 | 
			
		||||
          DELIVERY-ADDRESS ||--o{ ORDER : receives
 | 
			
		||||
          INVOICE ||--|{ ORDER : covers
 | 
			
		||||
          ORDER ||--|{ ORDER-ITEM : includes
 | 
			
		||||
          PRODUCT-CATEGORY ||--|{ PRODUCT : contains
 | 
			
		||||
          PRODUCT ||--o{ ORDER-ITEM : "ordered in"
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render multiple ER diagrams`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        [
 | 
			
		||||
          `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
        `,
 | 
			
		||||
          `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
          ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
        `,
 | 
			
		||||
        ],
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with blank or empty labels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK }|..|{ AUTHOR : ""
 | 
			
		||||
          BOOK }|..|{ GENRE : " "
 | 
			
		||||
          AUTHOR }|..|{ GENRE : "  "
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities that have no relationships`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          DEAD_PARROT
 | 
			
		||||
          HERMIT
 | 
			
		||||
          RECLUSE
 | 
			
		||||
          SOCIALITE }o--o{ SOCIALITE : "interacts with"
 | 
			
		||||
          RECLUSE }o--o{ SOCIALITE : avoids
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with and without attributes`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK { string title }
 | 
			
		||||
          AUTHOR }|..|{ BOOK : writes
 | 
			
		||||
          BOOK { float price }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with generic and array attributes`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK {
 | 
			
		||||
            string title
 | 
			
		||||
            string[] authors
 | 
			
		||||
            type~T~ type
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with generic and array attributes without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK {
 | 
			
		||||
            string title
 | 
			
		||||
            string[] authors
 | 
			
		||||
            type~T~ type
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with length in attributes type`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CLUSTER {
 | 
			
		||||
            varchar(99) name
 | 
			
		||||
            string(255) description
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with length in attributes type without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          CLUSTER {
 | 
			
		||||
            varchar(99) name
 | 
			
		||||
            string(255) description
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities and attributes with big and small entity names`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          PRIVATE_FINANCIAL_INSTITUTION {
 | 
			
		||||
            string name
 | 
			
		||||
            int    turnover
 | 
			
		||||
          }
 | 
			
		||||
          PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
 | 
			
		||||
          EMPLOYEE { bool officer_of_firm }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities and attributes with big and small entity names without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          PRIVATE_FINANCIAL_INSTITUTION {
 | 
			
		||||
            string name
 | 
			
		||||
            int    turnover
 | 
			
		||||
          }
 | 
			
		||||
          PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
 | 
			
		||||
          EMPLOYEE { bool officer_of_firm }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with attributes that begin with asterisk`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK {
 | 
			
		||||
            int         *id
 | 
			
		||||
            string      name
 | 
			
		||||
            varchar(99) summary
 | 
			
		||||
          }
 | 
			
		||||
          BOOK }o..o{ STORE : soldBy
 | 
			
		||||
          STORE {
 | 
			
		||||
            int         *id
 | 
			
		||||
            string      name
 | 
			
		||||
            varchar(50) address
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with attributes that begin with asterisk without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          BOOK {
 | 
			
		||||
            int         *id
 | 
			
		||||
            string      name
 | 
			
		||||
            varchar(99) summary
 | 
			
		||||
          }
 | 
			
		||||
          BOOK }o..o{ STORE : soldBy
 | 
			
		||||
          STORE {
 | 
			
		||||
            int         *id
 | 
			
		||||
            string      name
 | 
			
		||||
            varchar(50) address
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with keys`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name PK
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            float price
 | 
			
		||||
            string author FK
 | 
			
		||||
            string title PK
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with keys without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name PK
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            float price
 | 
			
		||||
            string author FK
 | 
			
		||||
            string title PK
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with comments`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name "comment"
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            string author
 | 
			
		||||
            string title "author comment"
 | 
			
		||||
            float price "price comment"
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with comments without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name "comment"
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            string author
 | 
			
		||||
            string title "author comment"
 | 
			
		||||
            float price "price comment"
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with keys and comments`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name PK "comment"
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            string description
 | 
			
		||||
            float price "price comment"
 | 
			
		||||
            string title PK "title comment"
 | 
			
		||||
            string author FK
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with keys and comments without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
          string name PK "comment"
 | 
			
		||||
        }
 | 
			
		||||
        AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
        BOOK {
 | 
			
		||||
            string description
 | 
			
		||||
            float price "price comment"
 | 
			
		||||
            string title PK "title comment"
 | 
			
		||||
            string author FK
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with aliases`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        T1 one or zero to one or more T2 : test
 | 
			
		||||
        T2 one or many optionally to zero or one T3 : test
 | 
			
		||||
        T3 zero or more to zero or many T4 : test
 | 
			
		||||
        T4 many(0) to many(1) T5 : test
 | 
			
		||||
        T5 many optionally to one T6 : test
 | 
			
		||||
        T6 only one optionally to only one T1 : test
 | 
			
		||||
        T4 0+ to 1+ T6 : test
 | 
			
		||||
        T1 1 to 1 T3 : test
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a simple ER diagram with a title`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `---
 | 
			
		||||
  title: simple ER diagram
 | 
			
		||||
  ---
 | 
			
		||||
  erDiagram
 | 
			
		||||
  CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
  ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
  `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with entity name aliases`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        p[Person] {
 | 
			
		||||
          varchar(64) firstName
 | 
			
		||||
          varchar(64) lastName
 | 
			
		||||
        }
 | 
			
		||||
        c["Customer Account"] {
 | 
			
		||||
          varchar(128) email
 | 
			
		||||
        }
 | 
			
		||||
        p ||--o| c : has
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render relationship labels with line breaks`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
        p[Person] {
 | 
			
		||||
            string firstName
 | 
			
		||||
            string lastName
 | 
			
		||||
        }
 | 
			
		||||
        a["Customer Account"] {
 | 
			
		||||
            string email
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
        b["Customer Account Secondary"] {
 | 
			
		||||
          string email
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        c["Customer Account Tertiary"] {
 | 
			
		||||
          string email
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        d["Customer Account Nth"] {
 | 
			
		||||
          string email
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
        p ||--o| a : "has<br />one"
 | 
			
		||||
        p ||--o| b : "has<br />one<br />two"
 | 
			
		||||
        p ||--o| c : "has<br />one<br/>two<br />three"
 | 
			
		||||
        p ||--o| d : "has<br />one<br />two<br/>three<br />...<br/>Nth"
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with unicode text`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          _**testẽζ➕Ø😀㌕ぼ**_ {
 | 
			
		||||
              *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
 | 
			
		||||
              *string(99)~T~~~~~~* firstName "Only __99__ <br>characters are a<br>llowed dsfsdfsdfsdfs"
 | 
			
		||||
              string last*Name*
 | 
			
		||||
              string __phone__ UK
 | 
			
		||||
              int _age_
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with unicode text without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      erDiagram
 | 
			
		||||
          _**testẽζ➕Ø😀㌕ぼ**_ {
 | 
			
		||||
              *__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
 | 
			
		||||
              *string(99)~T~~~~~~* firstName "Only __99__ <br>characters are a<br>llowed dsfsdfsdfsdfs"
 | 
			
		||||
              string last*Name*
 | 
			
		||||
              string __phone__ UK
 | 
			
		||||
              int _age_
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with relationships with unicode text`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
            person[😀] {
 | 
			
		||||
                string *first*Name
 | 
			
		||||
                string _**last**Name_
 | 
			
		||||
            }
 | 
			
		||||
            a["*Customer Account*"] {
 | 
			
		||||
                **string** ema*i*l
 | 
			
		||||
            }
 | 
			
		||||
            person ||--o| a : __hẽ😀__
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with relationships with unicode text without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
            person[😀] {
 | 
			
		||||
                string *first*Name
 | 
			
		||||
                string _**last**Name_
 | 
			
		||||
            }
 | 
			
		||||
            a["*Customer Account*"] {
 | 
			
		||||
                **string** ema*i*l
 | 
			
		||||
            }
 | 
			
		||||
            person ||--o| a : __hẽ😀__
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with TB direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
          direction TB
 | 
			
		||||
          CAR ||--|{ NAMED-DRIVER : allows
 | 
			
		||||
          PERSON ||..o{ NAMED-DRIVER : is
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with BT direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
          direction BT
 | 
			
		||||
          CAR ||--|{ NAMED-DRIVER : allows
 | 
			
		||||
          PERSON ||..o{ NAMED-DRIVER : is
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with LR direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
          direction LR
 | 
			
		||||
          CAR ||--|{ NAMED-DRIVER : allows
 | 
			
		||||
          PERSON ||..o{ NAMED-DRIVER : is
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render an ER diagram with RL direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
          erDiagram
 | 
			
		||||
          direction RL
 | 
			
		||||
          CAR ||--|{ NAMED-DRIVER : allows
 | 
			
		||||
          PERSON ||..o{ NAMED-DRIVER : is
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with styles applied from style statement`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
            erDiagram
 | 
			
		||||
              c[CUSTOMER]
 | 
			
		||||
              p[PERSON]
 | 
			
		||||
              style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with styles applied from style statement without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
            erDiagram
 | 
			
		||||
              c[CUSTOMER]
 | 
			
		||||
              p[PERSON]
 | 
			
		||||
              style c,p fill:#f9f,stroke:blue, color:grey, font-size:24px,font-weight:bold
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with styles applied from class statement`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
            erDiagram
 | 
			
		||||
              c[CUSTOMER]
 | 
			
		||||
              p[PERSON]:::blue
 | 
			
		||||
              classDef bold font-size:24px, font-weight: bold
 | 
			
		||||
              classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
              class c,p bold
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with styles applied from class statement without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
            erDiagram
 | 
			
		||||
              c[CUSTOMER]
 | 
			
		||||
              p[PERSON]:::blue
 | 
			
		||||
              classDef bold font-size:24px, font-weight: bold
 | 
			
		||||
              classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
              class c,p bold
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render entities with styles applied from the default class and other styles`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
            erDiagram
 | 
			
		||||
              c[CUSTOMER]
 | 
			
		||||
              p[PERSON]:::blue
 | 
			
		||||
              classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
              classDef default fill:pink
 | 
			
		||||
              style c color:green
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -109,8 +109,8 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±6%
 | 
			
		||||
      expect(maxWidthValue).to.be.within(140 * 0.96, 140 * 1.06);
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -125,8 +125,8 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±6%
 | 
			
		||||
      expect(width).to.be.within(140 * 0.96, 140 * 1.06);
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(width).to.be.within(140 * 0.95, 140 * 1.05);
 | 
			
		||||
      // expect(svg).to.have.attr('height', '465');
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
@@ -354,107 +354,4 @@ ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Include char sequence "graph" in text (#6795)', () => {
 | 
			
		||||
    it('has a label with char sequence "graph"', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          p[Photograph] {
 | 
			
		||||
            varchar(12) jobId
 | 
			
		||||
            date dateCreated
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Special characters and numbers syntax', () => {
 | 
			
		||||
    it('should render ER diagram with numeric entity names', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          1 ||--|| ORDER : places
 | 
			
		||||
          ORDER ||--|{ 2 : contains
 | 
			
		||||
          2 ||--o{ 3.5 : references
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render ER diagram with "u" character in entity names and cardinality', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          CUSTOMER ||--|| u : has
 | 
			
		||||
          u ||--|| ORDER : places
 | 
			
		||||
          PROJECT u--o{ TEAM_MEMBER : "parent"
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render ER diagram with decimal numbers in relationships', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          2.5 ||--|| 1.5 : has
 | 
			
		||||
          CUSTOMER ||--o{ 3.14 : references
 | 
			
		||||
          1.0 ||--|{ ORDER : contains
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render ER diagram with numeric entity names and attributes', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          1 {
 | 
			
		||||
            string name
 | 
			
		||||
            int value
 | 
			
		||||
          }
 | 
			
		||||
          1 ||--|| ORDER : places
 | 
			
		||||
          ORDER {
 | 
			
		||||
            float price
 | 
			
		||||
            string description
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render complex ER diagram with mixed special entity names', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        erDiagram
 | 
			
		||||
          CUSTOMER ||--o{ 1 : places
 | 
			
		||||
          1 ||--|{ u : contains
 | 
			
		||||
          1.5
 | 
			
		||||
          u ||--|| 2.5 : processes
 | 
			
		||||
          2.5 {
 | 
			
		||||
            string id
 | 
			
		||||
            float value
 | 
			
		||||
          }
 | 
			
		||||
          u {
 | 
			
		||||
            varchar(50) name
 | 
			
		||||
            int count
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render ER diagram with numeric entity names and attributes', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `erDiagram
 | 
			
		||||
         PRODUCT ||--o{ ORDER-ITEM : has
 | 
			
		||||
         1.5
 | 
			
		||||
         u
 | 
			
		||||
         1
 | 
			
		||||
        `,
 | 
			
		||||
        { logLevel: 1 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph, verifyNumber } from '../../helpers/util.ts';
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
describe('Flowchart ELK', () => {
 | 
			
		||||
  it('1-elk: should render a simple flowchart', () => {
 | 
			
		||||
@@ -109,7 +109,7 @@ describe('Flowchart ELK', () => {
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      verifyNumber(maxWidthValue, 380, 15);
 | 
			
		||||
      expect(maxWidthValue).to.be.within(230 * 0.95, 230 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('8-elk: should render a flowchart when useMaxWidth is false', () => {
 | 
			
		||||
@@ -128,7 +128,7 @@ describe('Flowchart ELK', () => {
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      verifyNumber(width, 380, 15);
 | 
			
		||||
      expect(width).to.be.within(230 * 0.95, 230 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@@ -208,13 +208,13 @@ describe('Flowchart ELK', () => {
 | 
			
		||||
      `flowchart-elk TB
 | 
			
		||||
  internet
 | 
			
		||||
  nat
 | 
			
		||||
  router
 | 
			
		||||
  routeur
 | 
			
		||||
  lb1
 | 
			
		||||
  lb2
 | 
			
		||||
  compute1
 | 
			
		||||
  compute2
 | 
			
		||||
  subgraph project
 | 
			
		||||
  router
 | 
			
		||||
  routeur
 | 
			
		||||
  nat
 | 
			
		||||
    subgraph subnet1
 | 
			
		||||
      compute1
 | 
			
		||||
@@ -225,8 +225,8 @@ describe('Flowchart ELK', () => {
 | 
			
		||||
      lb2
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  internet --> router
 | 
			
		||||
  router --> subnet1 & subnet2
 | 
			
		||||
  internet --> routeur
 | 
			
		||||
  routeur --> subnet1 & subnet2
 | 
			
		||||
  subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
@@ -443,7 +443,7 @@ flowchart-elk TD
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('63-elk: title on subgraphs should be themeable', () => {
 | 
			
		||||
  it('63-elk: title on subgraphs should be themable', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
 | 
			
		||||
@@ -692,7 +692,7 @@ A --> B
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const edges = svg[0].querySelectorAll('.edges > path');
 | 
			
		||||
      const edges = svg.querySelectorAll('.edges > path');
 | 
			
		||||
      edges.forEach((edge) => {
 | 
			
		||||
        expect(edge).to.have.class('flowchart-link');
 | 
			
		||||
      });
 | 
			
		||||
@@ -739,7 +739,7 @@ NL\`") --"\`1o **bold**\`"--> c
 | 
			
		||||
          { flowchart: { titleTopMargin: 0 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
      it.skip('Wrapping long text with a new line', () => {
 | 
			
		||||
      it('Wrapping long text with a new line', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `%%{init: {"flowchart": {"htmlLabels": true}} }%%
 | 
			
		||||
flowchart-elk LR
 | 
			
		||||
@@ -841,7 +841,7 @@ end
 | 
			
		||||
          { flowchart: { titleTopMargin: 0 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
      it('Sub graphs', () => {
 | 
			
		||||
      it('Sub graphs and markdown strings', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `---
 | 
			
		||||
config:
 | 
			
		||||
@@ -1053,21 +1053,6 @@ flowchart LR
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6647-elk: should keep node order when using elk layout unless it would add crossings', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  layout: elk
 | 
			
		||||
---
 | 
			
		||||
      flowchart TB
 | 
			
		||||
        a --> a1 & a2 & a3 & a4
 | 
			
		||||
        b --> b1 & b2
 | 
			
		||||
        b2 --> b3
 | 
			
		||||
        b1 --> b4
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('Title and arrow styling #4813', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1029,19 +1029,4 @@ graph TD
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('FDH49: should add edge animation', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart TD
 | 
			
		||||
          A(["Start"]) L_A_B_0@--> B{"Decision"}
 | 
			
		||||
          B --> C["Option A"] & D["Option B"]
 | 
			
		||||
          style C stroke-width:4px,stroke-dasharray: 5
 | 
			
		||||
          L_A_B_0@{ animation: slow } 
 | 
			
		||||
          L_B_D_0@{ animation: fast }`,
 | 
			
		||||
      { look: 'handDrawn', screenshot: false }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('path#L_A_B_0').should('have.class', 'edge-animation-slow');
 | 
			
		||||
    cy.get('path#L_B_D_0').should('have.class', 'edge-animation-fast');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
const themes = ['default', 'forest', 'dark', 'base', 'neutral'];
 | 
			
		||||
 | 
			
		||||
describe('when rendering flowchart with icons', () => {
 | 
			
		||||
  for (const theme of themes) {
 | 
			
		||||
    it(`should render icons from fontawesome library on theme ${theme}`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TD
 | 
			
		||||
            A("fab:fa-twitter Twitter") --> B("fab:fa-facebook Facebook")
 | 
			
		||||
            B --> C("fa:fa-coffee Coffee")
 | 
			
		||||
            C --> D("fa:fa-car Car")
 | 
			
		||||
            D --> E("fab:fa-github GitHub")
 | 
			
		||||
        `,
 | 
			
		||||
        { theme }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`should render registered icons on theme ${theme}`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TD
 | 
			
		||||
            A("fa:fa-bell Bell") 
 | 
			
		||||
        `,
 | 
			
		||||
        { theme }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
@@ -99,7 +99,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.be.within(440 * 0.95, 440 * 1.05);
 | 
			
		||||
      expect(maxWidthValue).to.be.within(417 * 0.95, 417 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('8: should render a flowchart when useMaxWidth is false', () => {
 | 
			
		||||
@@ -118,7 +118,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(440 * 0.95, 440 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(417 * 0.95, 417 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@@ -198,13 +198,13 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      `flowchart TB
 | 
			
		||||
  internet
 | 
			
		||||
  nat
 | 
			
		||||
  router
 | 
			
		||||
  routeur
 | 
			
		||||
  lb1
 | 
			
		||||
  lb2
 | 
			
		||||
  compute1
 | 
			
		||||
  compute2
 | 
			
		||||
  subgraph project
 | 
			
		||||
  router
 | 
			
		||||
  routeur
 | 
			
		||||
  nat
 | 
			
		||||
    subgraph subnet1
 | 
			
		||||
      compute1
 | 
			
		||||
@@ -215,8 +215,8 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      lb2
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  internet --> router
 | 
			
		||||
  router --> subnet1 & subnet2
 | 
			
		||||
  internet --> routeur
 | 
			
		||||
  routeur --> subnet1 & subnet2
 | 
			
		||||
  subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
@@ -433,7 +433,7 @@ flowchart TD
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('63: title on subgraphs should be themeable', () => {
 | 
			
		||||
  it('63: title on subgraphs should be themable', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
 | 
			
		||||
@@ -699,7 +699,7 @@ A --> B
 | 
			
		||||
      { flowchart: { titleTopMargin: 10 } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('3192: It should be possible to render flowcharts with invisible edges', () => {
 | 
			
		||||
  it('3192: It should be possieble to render flowcharts with invisible edges', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
title: Simple flowchart with invisible edges
 | 
			
		||||
@@ -1076,127 +1076,4 @@ end
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  describe('New @ syntax for node metadata edge cases', () => {
 | 
			
		||||
    it('should be possible to use @  syntax to add labels on multi nodes', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TB
 | 
			
		||||
       n2["label for n2"] &   n4@{ label: "label for n4"}   & n5@{ label: "label for n5"}
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should be possible to use @  syntax to add labels with trail spaces and &', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TB
 | 
			
		||||
       n2["label for n2"] &   n4@{ label: "label for n4"}   & n5@{ label: "label for n5"}   
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should be possible to use @  syntax to add labels with trail spaces', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TB
 | 
			
		||||
       n2["label for n2"]
 | 
			
		||||
       n4@{ label: "label for n4"}
 | 
			
		||||
       n5@{ label: "label for n5"}  
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should be possible to use @  syntax to add labels with trail spaces and edge/link', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TD
 | 
			
		||||
    A["A"] --> B["for B"] &    C@{ label: "for c"} & E@{label : "for E"}  
 | 
			
		||||
    D@{label: "for D"}     
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  describe('Flowchart Node Shape Rendering', () => {
 | 
			
		||||
    it('should render a stadium-shaped node', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TB
 | 
			
		||||
          A(["Start"]) --> n1["Untitled Node"]
 | 
			
		||||
          A --> n2["Untitled Node"]
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render a diamond-shaped node using shape config', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart BT
 | 
			
		||||
          n2["Untitled Node"] --> n1["Diamond"]
 | 
			
		||||
          n1@{ shape: diam}
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render a rounded rectangle and a normal rectangle', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart BT
 | 
			
		||||
        n2["Untitled Node"] --> n1["Rounded Rectangle"]
 | 
			
		||||
        n3["Untitled Node"] --> n1
 | 
			
		||||
        n1@{ shape: rounded}
 | 
			
		||||
        n3@{ shape: rect}
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6617: Per Link Curve Styling using edge Ids', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `flowchart TD
 | 
			
		||||
      A e1@-->B e5@--> E
 | 
			
		||||
      E e7@--> D
 | 
			
		||||
      B e3@-->D
 | 
			
		||||
      A e2@-->C e4@-->D
 | 
			
		||||
      C e6@--> F
 | 
			
		||||
      F e8@--> D
 | 
			
		||||
      e1@{ curve: natural }
 | 
			
		||||
      e2@{ curve: stepAfter }
 | 
			
		||||
      e3@{ curve: monotoneY }
 | 
			
		||||
      e4@{ curve: bumpY }
 | 
			
		||||
      e5@{ curve: linear }
 | 
			
		||||
      e6@{ curve: catmullRom }
 | 
			
		||||
      e7@{ curve: cardinal }
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('when rendering unsuported markdown', () => {
 | 
			
		||||
    const graph = `flowchart TB
 | 
			
		||||
    mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
 | 
			
		||||
    mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
 | 
			
		||||
    subgraph subgraph1["\`How to fix **fix**\`"]
 | 
			
		||||
        broken --> B["B"]
 | 
			
		||||
    end
 | 
			
		||||
    githost["Github, Gitlab, BitBucket, etc."]
 | 
			
		||||
    githost2["\`Github, Gitlab, BitBucket, etc.\`"]
 | 
			
		||||
    a["1."]
 | 
			
		||||
    b["- x"]
 | 
			
		||||
      `;
 | 
			
		||||
 | 
			
		||||
    it('should render raw strings', () => {
 | 
			
		||||
      imgSnapshotTest(graph);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render raw strings with htmlLabels: false', () => {
 | 
			
		||||
      imgSnapshotTest(graph, { htmlLabels: false });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('V2 - 17: should apply class def colour to edge label', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      ` graph LR
 | 
			
		||||
    id1(Start) link@-- "Label" -->id2(Stop)
 | 
			
		||||
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
 | 
			
		||||
 | 
			
		||||
class id2 myClass
 | 
			
		||||
classDef myClass fill:#bbf,stroke:#f66,stroke-width:2px,color:white,stroke-dasharray: 5 5
 | 
			
		||||
class link myClass
 | 
			
		||||
`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -774,21 +774,6 @@ describe('Graph', () => {
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('40: should add edge animation', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart TD
 | 
			
		||||
          A(["Start"]) L_A_B_0@--> B{"Decision"}
 | 
			
		||||
          B --> C["Option A"] & D["Option B"]
 | 
			
		||||
          style C stroke-width:4px,stroke-dasharray: 5
 | 
			
		||||
          L_A_B_0@{ animation: slow } 
 | 
			
		||||
          L_B_D_0@{ animation: fast }`,
 | 
			
		||||
      { screenshot: false }
 | 
			
		||||
    );
 | 
			
		||||
    // Verify animation classes are applied to both edges
 | 
			
		||||
    cy.get('path#L_A_B_0').should('have.class', 'edge-animation-slow');
 | 
			
		||||
    cy.get('path#L_B_D_0').should('have.class', 'edge-animation-fast');
 | 
			
		||||
  });
 | 
			
		||||
  it('58: handle styling with style expressions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -910,7 +895,7 @@ graph TD
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      graph TD
 | 
			
		||||
        classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff
 | 
			
		||||
        classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff 
 | 
			
		||||
        hello --> default
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
@@ -932,75 +917,4 @@ graph TD
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('#6369: edge color should affect arrow head', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    flowchart LR
 | 
			
		||||
        A --> B
 | 
			
		||||
        A --> C
 | 
			
		||||
        C --> D
 | 
			
		||||
 | 
			
		||||
        linkStyle 0 stroke:#D50000
 | 
			
		||||
        linkStyle 2 stroke:#D50000
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        flowchart: { htmlLabels: true },
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('68: should honor subgraph direction when inheritDir is false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: {"flowchart": { "inheritDir": false }}}%%
 | 
			
		||||
      flowchart TB
 | 
			
		||||
        direction LR
 | 
			
		||||
        subgraph A
 | 
			
		||||
          direction TB
 | 
			
		||||
          a --> b
 | 
			
		||||
        end
 | 
			
		||||
        subgraph B
 | 
			
		||||
          c --> d
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('69: should inherit global direction when inheritDir is true', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: {"flowchart": { "inheritDir": true }}}%%
 | 
			
		||||
      flowchart TB
 | 
			
		||||
        direction LR
 | 
			
		||||
        subgraph A
 | 
			
		||||
          direction TB
 | 
			
		||||
          a --> b
 | 
			
		||||
        end
 | 
			
		||||
        subgraph B
 | 
			
		||||
          c --> d
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('70: should render a subgraph with direction TD', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
        subgraph A
 | 
			
		||||
          direction TD
 | 
			
		||||
          a --> b
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should FAIL rendering a gantt chart for issue #1060 with invalid date', () => {
 | 
			
		||||
  it('should FAIL redering a gantt chart for issue #1060 with invalid date', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      gantt
 | 
			
		||||
@@ -358,23 +358,6 @@ describe('Gantt diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a gantt diagram with a vert tag', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      gantt
 | 
			
		||||
        title A Gantt Diagram
 | 
			
		||||
        dateFormat   ss
 | 
			
		||||
        axisFormat   %Ss
 | 
			
		||||
 | 
			
		||||
        section Section
 | 
			
		||||
        A task           : a1, 00, 6s
 | 
			
		||||
        Milestone     : vert, 01,
 | 
			
		||||
        section Another
 | 
			
		||||
        Task in sec      : 06, 3s
 | 
			
		||||
        another task     : 3s
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram with tick is 2 milliseconds', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -565,18 +548,6 @@ describe('Gantt diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render only the day when using dateFormat D', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    gantt
 | 
			
		||||
      title Test
 | 
			
		||||
      dateFormat D
 | 
			
		||||
      A :a, 1, 1d
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // TODO: fix it
 | 
			
		||||
  //
 | 
			
		||||
  // This test is skipped deliberately
 | 
			
		||||
@@ -602,7 +573,7 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram excluding friday and saturday', () => {
 | 
			
		||||
  it('should render a gantt diagram exculding friday and saturday', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gantt
 | 
			
		||||
      title A Gantt Diagram
 | 
			
		||||
@@ -613,7 +584,7 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      A task :a1, 2024-02-28, 10d`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram excluding saturday and sunday', () => {
 | 
			
		||||
  it('should render a gantt diagram exculding saturday and sunday', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gantt
 | 
			
		||||
      title A Gantt Diagram
 | 
			
		||||
@@ -659,49 +630,6 @@ describe('Gantt diagram', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a gantt diagram excluding a specific date in YYYY-MM-DD HH:mm:ss format', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    gantt
 | 
			
		||||
      dateFormat  YYYY-MM-DD HH:mm:ss
 | 
			
		||||
      excludes    2025-07-07
 | 
			
		||||
      section     Section
 | 
			
		||||
      A task      :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
 | 
			
		||||
      Another task:after a1, 20h
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a gantt diagram excluding saturday and sunday in YYYY-MM-DD HH:mm:ss format', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
        gantt
 | 
			
		||||
      dateFormat  YYYY-MM-DD HH:mm:ss
 | 
			
		||||
      excludes    weekends
 | 
			
		||||
       weekend saturday
 | 
			
		||||
      section     Section
 | 
			
		||||
      A task      :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
 | 
			
		||||
      Another task:after a1, 20h
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram excluding friday and saturday in YYYY-MM-DD HH:mm:ss format', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
        gantt
 | 
			
		||||
      dateFormat  YYYY-MM-DD HH:mm:ss
 | 
			
		||||
      excludes    weekends
 | 
			
		||||
       weekend friday
 | 
			
		||||
      section     Section
 | 
			
		||||
      A task      :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
 | 
			
		||||
      Another task:after a1, 20h
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it("should render when there's a semicolon in the title", () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -743,7 +671,7 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      title Gantt Digram
 | 
			
		||||
      dateFormat  YYYY-MM-DD
 | 
			
		||||
      section Section
 | 
			
		||||
      ;A task with a semicolon           :a1, 2014-01-01, 30d
 | 
			
		||||
      ;A task with a semiclon           :a1, 2014-01-01, 30d
 | 
			
		||||
      Another task     :after a1  , 20d
 | 
			
		||||
      section Another
 | 
			
		||||
      Task in sec      :2014-01-12  , 12d
 | 
			
		||||
@@ -803,34 +731,4 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle numeric timestamps with dateFormat x', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
     gantt
 | 
			
		||||
     title Process time profile (ms)
 | 
			
		||||
     dateFormat x
 | 
			
		||||
     axisFormat %L
 | 
			
		||||
     tickInterval 250millisecond
 | 
			
		||||
 | 
			
		||||
     section Pipeline
 | 
			
		||||
     Parse JSON p1: 000, 120
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle numeric timestamps with dateFormat X', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
     gantt
 | 
			
		||||
     title Process time profile (ms)
 | 
			
		||||
     dateFormat X
 | 
			
		||||
     axisFormat %L
 | 
			
		||||
     tickInterval 250millisecond
 | 
			
		||||
 | 
			
		||||
     section Pipeline
 | 
			
		||||
     Parse JSON p1: 000, 120
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ describe('Git Graph diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('2: should render a simple gitgraph with commit on main branch with id', () => {
 | 
			
		||||
  it('2: should render a simple gitgraph with commit on main branch with Id', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gitGraph
 | 
			
		||||
       commit id: "One"
 | 
			
		||||
@@ -253,7 +253,7 @@ describe('Git Graph diagram', () => {
 | 
			
		||||
      `
 | 
			
		||||
      gitGraph
 | 
			
		||||
      checkout main
 | 
			
		||||
      %% Make sure to manually set the id of all commits, for consistent visual tests
 | 
			
		||||
      %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
      commit id: "1-abcdefg"
 | 
			
		||||
      checkout main
 | 
			
		||||
      branch branch1
 | 
			
		||||
@@ -343,7 +343,7 @@ gitGraph
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('16: should render a simple gitgraph with commit on main branch with id | Vertical Branch', () => {
 | 
			
		||||
  it('16: should render a simple gitgraph with commit on main branch with Id | Vertical Branch', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gitGraph TB:
 | 
			
		||||
       commit id: "One"
 | 
			
		||||
@@ -585,7 +585,7 @@ gitGraph
 | 
			
		||||
      `
 | 
			
		||||
      gitGraph TB:
 | 
			
		||||
      checkout main
 | 
			
		||||
      %% Make sure to manually set the id of all commits, for consistent visual tests
 | 
			
		||||
      %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
      commit id: "1-abcdefg"
 | 
			
		||||
      checkout main
 | 
			
		||||
      branch branch1
 | 
			
		||||
@@ -1024,7 +1024,7 @@ gitGraph TB:
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('51: should render a simple gitgraph with commit on main branch with id | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
    it('51: should render a simple gitgraph with commit on main branch with Id | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "One"
 | 
			
		||||
@@ -1266,7 +1266,7 @@ gitGraph TB:
 | 
			
		||||
        `
 | 
			
		||||
        gitGraph BT:
 | 
			
		||||
        checkout main
 | 
			
		||||
        %% Make sure to manually set the id of all commits, for consistent visual tests
 | 
			
		||||
        %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
        commit id: "1-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        branch branch1
 | 
			
		||||
@@ -1491,7 +1491,7 @@ gitGraph TB:
 | 
			
		||||
        `
 | 
			
		||||
        gitGraph
 | 
			
		||||
        switch main
 | 
			
		||||
        %% Make sure to manually set the id of all commits, for consistent visual tests
 | 
			
		||||
        %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
        commit id: "1-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        branch branch1
 | 
			
		||||
 
 | 
			
		||||
@@ -63,199 +63,4 @@ section Checkout from website
 | 
			
		||||
      { journey: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should initialize with a left margin of 150px for user journeys', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      config:
 | 
			
		||||
        journey:
 | 
			
		||||
          maxLabelWidth: 320
 | 
			
		||||
      ---
 | 
			
		||||
      journey
 | 
			
		||||
        title User Journey Example
 | 
			
		||||
        section Onboarding
 | 
			
		||||
            Sign Up: 5:
 | 
			
		||||
            Browse Features: 3:
 | 
			
		||||
            Use Core Functionality: 4:
 | 
			
		||||
        section Engagement
 | 
			
		||||
            Browse Features: 3
 | 
			
		||||
            Use Core Functionality: 4
 | 
			
		||||
      `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let diagramStartX;
 | 
			
		||||
 | 
			
		||||
    cy.contains('foreignobject', 'Sign Up').then(($diagram) => {
 | 
			
		||||
      diagramStartX = parseFloat($diagram.attr('x'));
 | 
			
		||||
      expect(diagramStartX).to.be.closeTo(150, 2);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should maintain sufficient space between legend and diagram when legend labels are longer', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `journey
 | 
			
		||||
      title  Web hook life cycle
 | 
			
		||||
      section Darkoob
 | 
			
		||||
        Make preBuilt:5: Darkoob user
 | 
			
		||||
        register slug : 5: Darkoob userf deliberately increasing the size of this label to check if distance between legend and diagram is  maintained
 | 
			
		||||
        Map slug to a Prebuilt Job:5: Darkoob user
 | 
			
		||||
      section External Service
 | 
			
		||||
        set Darkoob slug as hook for an Event : 5 : admin Exjjjnjjjj qwerty
 | 
			
		||||
        listen to the events : 5 :  External Service
 | 
			
		||||
        call darkoob endpoint : 5 : External Service
 | 
			
		||||
      section Darkoob
 | 
			
		||||
        check for inputs : 5 : DarkoobAPI
 | 
			
		||||
        run the prebuilt job : 5 : DarkoobAPI
 | 
			
		||||
        `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let LabelEndX, diagramStartX;
 | 
			
		||||
 | 
			
		||||
    // Get right edge of the legend
 | 
			
		||||
    cy.contains('tspan', 'Darkoob userf').then((textBox) => {
 | 
			
		||||
      const bbox = textBox[0].getBBox();
 | 
			
		||||
      LabelEndX = bbox.x + bbox.width;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Get left edge of the diagram
 | 
			
		||||
    cy.contains('foreignobject', 'Make preBuilt').then((rect) => {
 | 
			
		||||
      diagramStartX = parseFloat(rect.attr('x'));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Assert right edge of the diagram is greater than or equal to the right edge of the label
 | 
			
		||||
    cy.then(() => {
 | 
			
		||||
      expect(diagramStartX).to.be.gte(LabelEndX);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should wrap a single long word with hyphenation', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      config:
 | 
			
		||||
        journey:
 | 
			
		||||
          maxLabelWidth: 100
 | 
			
		||||
      ---
 | 
			
		||||
      journey
 | 
			
		||||
        title Long Word Test
 | 
			
		||||
        section Test
 | 
			
		||||
          VeryLongWord: 5: Supercalifragilisticexpialidocious
 | 
			
		||||
      `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Verify that the line ends with a hyphen, indicating proper hyphenation for words exceeding maxLabelWidth.
 | 
			
		||||
    cy.get('tspan').then((tspans) => {
 | 
			
		||||
      const hasHyphen = [...tspans].some((t) => t.textContent.trim().endsWith('-'));
 | 
			
		||||
      return expect(hasHyphen).to.be.true;
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should wrap text on whitespace without adding hyphens', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      config:
 | 
			
		||||
        journey:
 | 
			
		||||
          maxLabelWidth: 200
 | 
			
		||||
      ---
 | 
			
		||||
      journey
 | 
			
		||||
        title Whitespace Test
 | 
			
		||||
        section Test
 | 
			
		||||
          TextWithSpaces: 5: Gustavo Fring is played by Giancarlo Esposito and is a character in Breaking Bad.
 | 
			
		||||
      `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Verify that none of the text spans end with a hyphen.
 | 
			
		||||
    cy.get('tspan').each(($el) => {
 | 
			
		||||
      const text = $el.text();
 | 
			
		||||
      expect(text.trim()).not.to.match(/-$/);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should wrap long labels into multiple lines, keep them under max width, and maintain margins', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      config:
 | 
			
		||||
        journey:
 | 
			
		||||
          maxLabelWidth: 320
 | 
			
		||||
      ---
 | 
			
		||||
      journey
 | 
			
		||||
        title User Journey Example
 | 
			
		||||
        section Onboarding
 | 
			
		||||
            Sign Up: 5: This is a long label that will be split into multiple lines to test the wrapping functionality
 | 
			
		||||
            Browse Features: 3: This is another long label that will be split into multiple lines to test the wrapping functionality
 | 
			
		||||
            Use Core Functionality: 4: This is yet another long label that will be split into multiple lines to test the wrapping functionality
 | 
			
		||||
        section Engagement
 | 
			
		||||
            Browse Features: 3
 | 
			
		||||
            Use Core Functionality: 4
 | 
			
		||||
      `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let diagramStartX, maxLineWidth;
 | 
			
		||||
 | 
			
		||||
    // Get the diagram's left edge x-coordinate
 | 
			
		||||
    cy.contains('foreignobject', 'Sign Up')
 | 
			
		||||
      .then(($diagram) => {
 | 
			
		||||
        diagramStartX = parseFloat($diagram.attr('x'));
 | 
			
		||||
      })
 | 
			
		||||
      .then(() => {
 | 
			
		||||
        cy.get('text.legend').then(($lines) => {
 | 
			
		||||
          // Check that there are multiple lines
 | 
			
		||||
          expect($lines.length).to.be.equal(9);
 | 
			
		||||
 | 
			
		||||
          // Check that all lines are under the maxLabelWidth
 | 
			
		||||
          $lines.each((index, el) => {
 | 
			
		||||
            const bbox = el.getBBox();
 | 
			
		||||
            expect(bbox.width).to.be.lte(320);
 | 
			
		||||
            maxLineWidth = Math.max(maxLineWidth || 0, bbox.width);
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          /** The expected margin between the diagram and the legend is 150px, as defined by
 | 
			
		||||
           *  conf.leftMargin in user-journey-config.js
 | 
			
		||||
           */
 | 
			
		||||
          expect(diagramStartX - maxLineWidth).to.be.closeTo(150, 2);
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should correctly render the user journey diagram title with the specified styling', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  journey:
 | 
			
		||||
    titleColor: "#2900A5"
 | 
			
		||||
    titleFontFamily: "Times New Roman"
 | 
			
		||||
    titleFontSize: "5rem"
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
journey
 | 
			
		||||
    title User Journey Example
 | 
			
		||||
    section Onboarding
 | 
			
		||||
        Sign Up: 5: John, Shahir
 | 
			
		||||
        Complete Profile: 4: John
 | 
			
		||||
    section Engagement
 | 
			
		||||
        Browse Features: 3: John
 | 
			
		||||
        Use Core Functionality: 4: John
 | 
			
		||||
    section Retention
 | 
			
		||||
        Revisit Application: 5: John
 | 
			
		||||
        Invite Friends: 3: John
 | 
			
		||||
 | 
			
		||||
        size: 2rem
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('text').contains('User Journey Example').as('title');
 | 
			
		||||
    cy.get('@title').then(($title) => {
 | 
			
		||||
      expect($title).to.have.attr('fill', '#2900A5');
 | 
			
		||||
      expect($title).to.have.attr('font-family', 'Times New Roman');
 | 
			
		||||
      expect($title).to.have.attr('font-size', '5rem');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ describe('Kanban diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('6: should handle assignments', () => {
 | 
			
		||||
  it('6: should handle assigments', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `kanban
 | 
			
		||||
  id1[Todo]
 | 
			
		||||
@@ -118,7 +118,7 @@ kanban
 | 
			
		||||
    docs[Create Documentation]
 | 
			
		||||
    docs[Create Blog about the new diagram]
 | 
			
		||||
  id7[In progress]
 | 
			
		||||
    id6[Create renderer so that it works in all cases. We also add some extra text here for testing purposes. And some more just for the extra flare.]
 | 
			
		||||
    id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.]
 | 
			
		||||
    id8[Design grammar]@{ assigned: 'knsv' }
 | 
			
		||||
  id9[Ready for deploy]
 | 
			
		||||
  id10[Ready for test]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
describe('Mindmap Tidy Tree', () => {
 | 
			
		||||
  it('1-tidy-tree: should render a simple mindmap without children', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      ` ---
 | 
			
		||||
      config:
 | 
			
		||||
        layout: tidy-tree
 | 
			
		||||
      ---
 | 
			
		||||
      mindmap
 | 
			
		||||
      root((mindmap))
 | 
			
		||||
        A
 | 
			
		||||
        B
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('2-tidy-tree: should render a simple mindmap', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      ` ---
 | 
			
		||||
      config:
 | 
			
		||||
        layout: tidy-tree
 | 
			
		||||
      ---
 | 
			
		||||
      mindmap
 | 
			
		||||
      root((mindmap is a long thing))
 | 
			
		||||
        A
 | 
			
		||||
        B
 | 
			
		||||
        C
 | 
			
		||||
        D
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('3-tidy-tree: should render a  mindmap with different shapes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      ` ---
 | 
			
		||||
      config:
 | 
			
		||||
        layout: tidy-tree
 | 
			
		||||
      ---
 | 
			
		||||
      mindmap
 | 
			
		||||
      root((mindmap))
 | 
			
		||||
        Origins
 | 
			
		||||
          Long history
 | 
			
		||||
          ::icon(fa fa-book)
 | 
			
		||||
          Popularisation
 | 
			
		||||
            British popular psychology author Tony Buzan
 | 
			
		||||
        Research
 | 
			
		||||
          On effectiveness<br/>and features
 | 
			
		||||
          On Automatic creation
 | 
			
		||||
            Uses
 | 
			
		||||
                Creative techniques
 | 
			
		||||
                Strategic planning
 | 
			
		||||
                Argument mapping
 | 
			
		||||
        Tools
 | 
			
		||||
              id)I am a cloud(
 | 
			
		||||
                  id))I am a bang((
 | 
			
		||||
                    Tools
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('4-tidy-tree: should render a mindmap with children', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      ` ---
 | 
			
		||||
      config:
 | 
			
		||||
        layout: tidy-tree
 | 
			
		||||
      ---
 | 
			
		||||
       mindmap
 | 
			
		||||
      ((This is a mindmap))
 | 
			
		||||
        child1
 | 
			
		||||
         grandchild 1
 | 
			
		||||
         grandchild 2
 | 
			
		||||
        child2
 | 
			
		||||
         grandchild 3
 | 
			
		||||
         grandchild 4
 | 
			
		||||
        child3
 | 
			
		||||
         grandchild 5
 | 
			
		||||
         grandchild 6
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -146,7 +146,7 @@ root
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('text should wrap with icon', () => {
 | 
			
		||||
  it('text shouhld wrap with icon', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
root
 | 
			
		||||
@@ -159,10 +159,12 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('square shape', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
    root[
 | 
			
		||||
      The root
 | 
			
		||||
    ]`,
 | 
			
		||||
    ]
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -170,10 +172,12 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('rounded rect shape', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
    root((
 | 
			
		||||
      The root
 | 
			
		||||
    ))`,
 | 
			
		||||
    ))
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -181,10 +185,12 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('circle shape', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
    root(
 | 
			
		||||
      The root
 | 
			
		||||
    )`,
 | 
			
		||||
    )
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -192,8 +198,10 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('default shape', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
  The root`,
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
  The root
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -201,10 +209,12 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('adding children', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
  The root
 | 
			
		||||
    child1
 | 
			
		||||
    child2`,
 | 
			
		||||
    child2
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -212,11 +222,13 @@ root
 | 
			
		||||
  });
 | 
			
		||||
  it('adding grand children', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `mindmap
 | 
			
		||||
      `
 | 
			
		||||
mindmap
 | 
			
		||||
  The root
 | 
			
		||||
    child1
 | 
			
		||||
      child2
 | 
			
		||||
      child3`,
 | 
			
		||||
      child3
 | 
			
		||||
      `,
 | 
			
		||||
      {},
 | 
			
		||||
      undefined,
 | 
			
		||||
      shouldHaveRoot
 | 
			
		||||
@@ -228,22 +240,9 @@ root
 | 
			
		||||
        `mindmap
 | 
			
		||||
    id1[\`**Start** with
 | 
			
		||||
    a second line 😎\`]
 | 
			
		||||
      id2[\`The dog in **the** hog... a *very long text* about it Word!\`]`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  describe('Include char sequence "graph" in text (#6795)', () => {
 | 
			
		||||
    it('has a label with char sequence "graph"', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        ` mindmap
 | 
			
		||||
          root
 | 
			
		||||
            Photograph
 | 
			
		||||
              Waterfall
 | 
			
		||||
              Landscape
 | 
			
		||||
            Geography
 | 
			
		||||
              Mountains
 | 
			
		||||
              Rocks`,
 | 
			
		||||
        { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
      id2[\`The dog in **the** hog... a *very long text* about it
 | 
			
		||||
Word!\`]
 | 
			
		||||
`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('packet structure', () => {
 | 
			
		||||
  it('should render a simple packet-beta diagram', () => {
 | 
			
		||||
  it('should render a simple packet diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet-beta
 | 
			
		||||
  title Hello world
 | 
			
		||||
@@ -10,18 +10,9 @@ describe('packet structure', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a simple packet diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet
 | 
			
		||||
  title Hello world
 | 
			
		||||
  0-10: "hello"
 | 
			
		||||
`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a simple packet diagram without ranges', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet
 | 
			
		||||
      `packet-beta
 | 
			
		||||
  0: "h"
 | 
			
		||||
  1: "i"
 | 
			
		||||
`
 | 
			
		||||
@@ -30,7 +21,7 @@ describe('packet structure', () => {
 | 
			
		||||
 | 
			
		||||
  it('should render a complex packet diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet
 | 
			
		||||
      `packet-beta
 | 
			
		||||
        0-15: "Source Port"
 | 
			
		||||
        16-31: "Destination Port"
 | 
			
		||||
        32-63: "Sequence Number"
 | 
			
		||||
@@ -61,7 +52,7 @@ describe('packet structure', () => {
 | 
			
		||||
        packet:
 | 
			
		||||
          showBits: false
 | 
			
		||||
      ---
 | 
			
		||||
      packet
 | 
			
		||||
      packet-beta
 | 
			
		||||
        0-15: "Source Port"
 | 
			
		||||
        16-31: "Destination Port"
 | 
			
		||||
        32-63: "Sequence Number"
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ describe('pie chart', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a pie diagram when textPosition is set', () => {
 | 
			
		||||
  it('should render a pie diagram when textPosition is setted', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `pie
 | 
			
		||||
        "Dogs": 50
 | 
			
		||||
@@ -82,13 +82,4 @@ describe('pie chart', () => {
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render pie slices only for non-zero values but shows all legends', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `   pie title Pets adopted by volunteers
 | 
			
		||||
    "Dogs" : 386
 | 
			
		||||
    "Cats" : 85
 | 
			
		||||
    "Rats" : 1
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render y-axis on right side', () => {
 | 
			
		||||
  it('should able to render y-axix on right side', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  %%{init: {"quadrantChart": {"yAxisPosition": "right"}}}%%
 | 
			
		||||
@@ -61,7 +61,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render x-axis on bottom', () => {
 | 
			
		||||
  it('should able to render x-axix on bottom', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  %%{init: {"quadrantChart": {"xAxisPosition": "bottom"}}}%%
 | 
			
		||||
@@ -77,7 +77,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render x-axis on bottom and y-axis on right', () => {
 | 
			
		||||
  it('should able to render x-axix on bottom and y-axis on right', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  %%{init: {"quadrantChart": {"xAxisPosition": "bottom", "yAxisPosition": "right"}}}%%
 | 
			
		||||
 
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('radar structure', () => {
 | 
			
		||||
  it('should render a simple radar diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta
 | 
			
		||||
                title Best Radar Ever
 | 
			
		||||
                axis A, B, C
 | 
			
		||||
                curve c1{1, 2, 3}
 | 
			
		||||
            `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a radar diagram with multiple curves', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta
 | 
			
		||||
                title Best Radar Ever
 | 
			
		||||
                axis A, B, C
 | 
			
		||||
                curve c1{1, 2, 3}
 | 
			
		||||
                curve c2{2, 3, 1}
 | 
			
		||||
            `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a complex radar diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta 
 | 
			
		||||
                title My favorite ninjas
 | 
			
		||||
                axis Agility, Speed, Strength
 | 
			
		||||
                axis Stam["Stamina"] , Intel["Intelligence"]
 | 
			
		||||
 | 
			
		||||
                curve Ninja1["Naruto Uzumaki"]{
 | 
			
		||||
                    Agility 2, Speed 2,
 | 
			
		||||
                    Strength 3, Stam 5,
 | 
			
		||||
                    Intel 0
 | 
			
		||||
                }
 | 
			
		||||
                curve Ninja2["Sasuke"]{2, 3, 4, 1, 5}
 | 
			
		||||
                curve Ninja3 {3, 2, 1, 5, 4}
 | 
			
		||||
 | 
			
		||||
                showLegend true
 | 
			
		||||
                ticks 3
 | 
			
		||||
                max 8
 | 
			
		||||
                min 0
 | 
			
		||||
                graticule polygon
 | 
			
		||||
            `
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.length(1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render radar diagram with config override', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta
 | 
			
		||||
                title Best Radar Ever
 | 
			
		||||
                axis A,B,C
 | 
			
		||||
                curve mycurve{1,2,3}`,
 | 
			
		||||
      { radar: { marginTop: 100, axisScaleFactor: 0.5 } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should parse radar diagram with theme override', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta
 | 
			
		||||
                axis A,B,C
 | 
			
		||||
                curve mycurve{1,2,3}`,
 | 
			
		||||
      { theme: 'base', themeVariables: { fontSize: 80, cScale0: '#FF0000' } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should handle radar diagram with radar style override', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `radar-beta
 | 
			
		||||
                axis A,B,C
 | 
			
		||||
                curve mycurve{1,2,3}`,
 | 
			
		||||
      { theme: 'base', themeVariables: { radar: { axisColor: '#FF0000' } } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,703 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
const testOptions = [
 | 
			
		||||
  { description: '', options: { logLevel: 1 } },
 | 
			
		||||
  { description: 'ELK: ', options: { logLevel: 1, layout: 'elk' } },
 | 
			
		||||
  { description: 'HD: ', options: { logLevel: 1, look: 'handDrawn' } },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
describe('Requirement Diagram Unified', () => {
 | 
			
		||||
  testOptions.forEach(({ description, options }) => {
 | 
			
		||||
    it(`${description}should render a simple Requirement diagram`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a simple Requirement diagram without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a not-so-simple Requirement diagram`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        functionalRequirement test_req2 {
 | 
			
		||||
        id: 1.1
 | 
			
		||||
        text: the second test text.
 | 
			
		||||
        risk: low
 | 
			
		||||
        verifymethod: inspection
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        performanceRequirement test_req3 {
 | 
			
		||||
        id: 1.2
 | 
			
		||||
        text: the third test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: demonstration
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        interfaceRequirement test_req4 {
 | 
			
		||||
        id: 1.2.1
 | 
			
		||||
        text: the fourth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        physicalRequirement test_req5 {
 | 
			
		||||
        id: 1.2.2
 | 
			
		||||
        text: the fifth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        designConstraint test_req6 {
 | 
			
		||||
        id: 1.2.3
 | 
			
		||||
        text: the sixth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity2 {
 | 
			
		||||
        type: word doc
 | 
			
		||||
        docRef: reqs/test_entity
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity3 {
 | 
			
		||||
        type: "test suite"
 | 
			
		||||
        docRef: github.com/all_the_tests
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        test_entity - satisfies -> test_req2
 | 
			
		||||
        test_req - traces -> test_req2
 | 
			
		||||
        test_req - contains -> test_req3
 | 
			
		||||
        test_req3 - contains -> test_req4
 | 
			
		||||
        test_req4 - derives -> test_req5
 | 
			
		||||
        test_req5 - refines -> test_req6
 | 
			
		||||
        test_entity3 - verifies -> test_req5
 | 
			
		||||
        test_req <- copies - test_entity2
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a not-so-simple Requirement diagram without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        functionalRequirement test_req2 {
 | 
			
		||||
        id: 1.1
 | 
			
		||||
        text: the second test text.
 | 
			
		||||
        risk: low
 | 
			
		||||
        verifymethod: inspection
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        performanceRequirement test_req3 {
 | 
			
		||||
        id: 1.2
 | 
			
		||||
        text: the third test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: demonstration
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        interfaceRequirement test_req4 {
 | 
			
		||||
        id: 1.2.1
 | 
			
		||||
        text: the fourth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        physicalRequirement test_req5 {
 | 
			
		||||
        id: 1.2.2
 | 
			
		||||
        text: the fifth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        designConstraint test_req6 {
 | 
			
		||||
        id: 1.2.3
 | 
			
		||||
        text: the sixth test text.
 | 
			
		||||
        risk: medium
 | 
			
		||||
        verifymethod: analysis
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity2 {
 | 
			
		||||
        type: word doc
 | 
			
		||||
        docRef: reqs/test_entity
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element test_entity3 {
 | 
			
		||||
        type: "test suite"
 | 
			
		||||
        docRef: github.com/all_the_tests
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        test_entity - satisfies -> test_req2
 | 
			
		||||
        test_req - traces -> test_req2
 | 
			
		||||
        test_req - contains -> test_req3
 | 
			
		||||
        test_req3 - contains -> test_req4
 | 
			
		||||
        test_req4 - derives -> test_req5
 | 
			
		||||
        test_req5 - refines -> test_req6
 | 
			
		||||
        test_entity3 - verifies -> test_req5
 | 
			
		||||
        test_req <- copies - test_entity2
 | 
			
		||||
        `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render multiple Requirement diagrams`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        [
 | 
			
		||||
          `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req
 | 
			
		||||
    `,
 | 
			
		||||
          `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req
 | 
			
		||||
    `,
 | 
			
		||||
        ],
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with empty information`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        }
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with and without information`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
            id: 1
 | 
			
		||||
            text: the test text.
 | 
			
		||||
            risk: high
 | 
			
		||||
            verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with long and short text`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
            id: 1
 | 
			
		||||
            text: the test text that is long and takes up a lot of space.
 | 
			
		||||
            risk: high
 | 
			
		||||
            verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
        element test_entity_name_that_is_extra_long {
 | 
			
		||||
        }
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with long and short text without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
          requirement test_req {
 | 
			
		||||
              id: 1
 | 
			
		||||
              text: the test text that is long and takes up a lot of space.
 | 
			
		||||
              risk: high
 | 
			
		||||
              verifymethod: test
 | 
			
		||||
          }
 | 
			
		||||
          element test_entity_name_that_is_extra_long {
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with quoted text for spaces`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
          requirement "test req name with spaces" {
 | 
			
		||||
              id: 1
 | 
			
		||||
              text: the test text that is long and takes up a lot of space.
 | 
			
		||||
              risk: high
 | 
			
		||||
              verifymethod: test
 | 
			
		||||
          }
 | 
			
		||||
          element "test entity name that is extra long with spaces" {
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with markdown text`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
          requirement "__my bolded name__" {
 | 
			
		||||
              id: 1
 | 
			
		||||
              text: "**Bolded text** _italicized text_"
 | 
			
		||||
              risk: high
 | 
			
		||||
              verifymethod: test
 | 
			
		||||
          }
 | 
			
		||||
          element "*my italicized name*" {
 | 
			
		||||
            type: "**Bolded type** _italicized type_"
 | 
			
		||||
            docref: "*Italicized* __Bolded__"
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with markdown text without htmlLabels`, () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
          requirement "__my bolded name__" {
 | 
			
		||||
              id: 1
 | 
			
		||||
              text: "**Bolded text** _italicized text_"
 | 
			
		||||
              risk: high
 | 
			
		||||
              verifymethod: test
 | 
			
		||||
          }
 | 
			
		||||
          element "*my italicized name*" {
 | 
			
		||||
            type: "**Bolded type** _italicized type_"
 | 
			
		||||
            docref: "*Italicized* __Bolded__"
 | 
			
		||||
          }
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a simple Requirement diagram with a title`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `---
 | 
			
		||||
  title: simple Requirement diagram
 | 
			
		||||
  ---
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req
 | 
			
		||||
  `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with TB direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
    direction TB
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with BT direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
      direction BT
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with LR direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
      direction LR
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with RL direction`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
      direction RL
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from style statement`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req
 | 
			
		||||
 | 
			
		||||
    style test_req,test_entity fill:#f9f,stroke:blue, color:grey, font-weight:bold
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from style statement without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      requirementDiagram
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
  
 | 
			
		||||
      style test_req,test_entity fill:#f9f,stroke:blue, color:grey, font-weight:bold
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from class statement`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
requirementDiagram
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
      classDef bold font-weight: bold
 | 
			
		||||
      classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
      class test_entity bold
 | 
			
		||||
      class test_req blue, bold
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from class statement without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
    
 | 
			
		||||
        requirement test_req {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        classDef bold font-weight: bold
 | 
			
		||||
        classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
        class test_entity bold
 | 
			
		||||
        class test_req blue, bold
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from classes with shorthand syntax`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
    
 | 
			
		||||
        requirement test_req:::blue {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        classDef bold font-weight: bold
 | 
			
		||||
        classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
        test_entity:::bold
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from classes with shorthand syntax without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
    
 | 
			
		||||
        requirement test_req:::blue {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        classDef bold font-weight: bold
 | 
			
		||||
        classDef blue stroke:lightblue, color: #0000FF
 | 
			
		||||
        test_entity:::bold
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from the default class and other styles`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
requirementDiagram
 | 
			
		||||
  
 | 
			
		||||
      requirement test_req:::blue {
 | 
			
		||||
      id: 1
 | 
			
		||||
      text: the test text.
 | 
			
		||||
      risk: high
 | 
			
		||||
      verifymethod: test
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      element test_entity {
 | 
			
		||||
      type: simulation
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
      test_entity - satisfies -> test_req
 | 
			
		||||
      classDef blue stroke:lightblue, color:blue
 | 
			
		||||
      classDef default fill:pink
 | 
			
		||||
      style test_entity color:green
 | 
			
		||||
        `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render requirements and elements with styles applied from the default class and other styles without htmlLabels`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
    
 | 
			
		||||
        requirement test_req:::blue {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
        classDef blue stroke:lightblue, color:blue
 | 
			
		||||
        classDef default fill:pink
 | 
			
		||||
        style test_entity color:green
 | 
			
		||||
          `,
 | 
			
		||||
        { ...options, htmlLabels: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it(`${description}should render a Requirement diagram with a theme`, () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
---
 | 
			
		||||
  theme: forest
 | 
			
		||||
---
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
    
 | 
			
		||||
        requirement test_req:::blue {
 | 
			
		||||
        id: 1
 | 
			
		||||
        text: the test text.
 | 
			
		||||
        risk: high
 | 
			
		||||
        verifymethod: test
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        element test_entity {
 | 
			
		||||
        type: simulation
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        test_entity - satisfies -> test_req
 | 
			
		||||
          `,
 | 
			
		||||
        options
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -15,7 +15,7 @@ describe('Sankey Diagram', () => {
 | 
			
		||||
  describe('when given a linkColor', function () {
 | 
			
		||||
    this.beforeAll(() => {
 | 
			
		||||
      cy.wrap(
 | 
			
		||||
        `sankey
 | 
			
		||||
        `sankey-beta
 | 
			
		||||
      a,b,10
 | 
			
		||||
      `
 | 
			
		||||
      ).as('graph');
 | 
			
		||||
@@ -62,7 +62,7 @@ describe('Sankey Diagram', () => {
 | 
			
		||||
    this.beforeAll(() => {
 | 
			
		||||
      cy.wrap(
 | 
			
		||||
        `
 | 
			
		||||
        sankey
 | 
			
		||||
        sankey-beta
 | 
			
		||||
        
 | 
			
		||||
        a,b,8
 | 
			
		||||
        b,c,8
 | 
			
		||||
 
 | 
			
		||||
@@ -1,780 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
const looks = ['classic'];
 | 
			
		||||
const participantTypes = [
 | 
			
		||||
  { type: 'participant', display: 'participant' },
 | 
			
		||||
  { type: 'actor', display: 'actor' },
 | 
			
		||||
  { type: 'boundary', display: 'boundary' },
 | 
			
		||||
  { type: 'control', display: 'control' },
 | 
			
		||||
  { type: 'entity', display: 'entity' },
 | 
			
		||||
  { type: 'database', display: 'database' },
 | 
			
		||||
  { type: 'collections', display: 'collections' },
 | 
			
		||||
  { type: 'queue', display: 'queue' },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const restrictedTypes = ['boundary', 'control', 'entity', 'database', 'collections', 'queue'];
 | 
			
		||||
 | 
			
		||||
const interactionTypes = ['->>', '-->>', '->', '-->', '-x', '--x', '->>+', '-->>+'];
 | 
			
		||||
 | 
			
		||||
const notePositions = ['left of', 'right of', 'over'];
 | 
			
		||||
 | 
			
		||||
function getParticipantLine(name, type, alias) {
 | 
			
		||||
  if (restrictedTypes.includes(type)) {
 | 
			
		||||
    return `  participant ${name}@{ "type" : "${type}" }\n`;
 | 
			
		||||
  } else if (alias) {
 | 
			
		||||
    return `  participant ${name}@{ "type" : "${type}" } \n`;
 | 
			
		||||
  } else {
 | 
			
		||||
    return `  participant ${name}@{ "type" : "${type}" }\n`;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
looks.forEach((look) => {
 | 
			
		||||
  describe(`Sequence Diagram Tests - ${look} look`, () => {
 | 
			
		||||
    it('should render all participant types', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      participantTypes.forEach((pt, index) => {
 | 
			
		||||
        const name = `${pt.display}${index}`;
 | 
			
		||||
        diagramCode += getParticipantLine(name, pt.type);
 | 
			
		||||
      });
 | 
			
		||||
      for (let i = 0; i < participantTypes.length - 1; i++) {
 | 
			
		||||
        diagramCode += `  ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
 | 
			
		||||
      }
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render all interaction types', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      diagramCode += getParticipantLine('A', 'actor');
 | 
			
		||||
      diagramCode += getParticipantLine('B', 'boundary');
 | 
			
		||||
      interactionTypes.forEach((interaction, index) => {
 | 
			
		||||
        diagramCode += `  A ${interaction} B: ${interaction} message ${index}\n`;
 | 
			
		||||
      });
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render participant creation and destruction', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      participantTypes.forEach((pt, index) => {
 | 
			
		||||
        const name = `${pt.display}${index}`;
 | 
			
		||||
        diagramCode += getParticipantLine('A', pt.type);
 | 
			
		||||
        diagramCode += getParticipantLine('B', pt.type);
 | 
			
		||||
        diagramCode += `  create participant ${name}@{ "type" : "${pt.type}" }\n`;
 | 
			
		||||
        diagramCode += `  A ->> ${name}: Hello ${pt.display}\n`;
 | 
			
		||||
        if (index % 2 === 0) {
 | 
			
		||||
          diagramCode += `  destroy ${name}\n`;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render notes in all positions', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      diagramCode += getParticipantLine('A', 'actor');
 | 
			
		||||
      diagramCode += getParticipantLine('B', 'boundary');
 | 
			
		||||
      notePositions.forEach((position, index) => {
 | 
			
		||||
        diagramCode += `  Note ${position} A: Note ${position} ${index}\n`;
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  A ->> B: Message with notes\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render parallel interactions', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      participantTypes.slice(0, 4).forEach((pt, index) => {
 | 
			
		||||
        diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  par Parallel actions\n`;
 | 
			
		||||
      for (let i = 0; i < 3; i += 2) {
 | 
			
		||||
        diagramCode += `    ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
 | 
			
		||||
        if (i < participantTypes.length - 2) {
 | 
			
		||||
          diagramCode += `    and\n`;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      diagramCode += `  end\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render alternative flows', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      diagramCode += getParticipantLine('A', 'actor');
 | 
			
		||||
      diagramCode += getParticipantLine('B', 'boundary');
 | 
			
		||||
      diagramCode += `  alt Successful case\n`;
 | 
			
		||||
      diagramCode += `    A ->> B: Request\n`;
 | 
			
		||||
      diagramCode += `    B -->> A: Success\n`;
 | 
			
		||||
      diagramCode += `  else Failure case\n`;
 | 
			
		||||
      diagramCode += `    A ->> B: Request\n`;
 | 
			
		||||
      diagramCode += `    B --x A: Failure\n`;
 | 
			
		||||
      diagramCode += `  end\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render loops', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      participantTypes.slice(0, 3).forEach((pt, index) => {
 | 
			
		||||
        diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  loop For each participant\n`;
 | 
			
		||||
      for (let i = 0; i < 3; i++) {
 | 
			
		||||
        diagramCode += `    ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Message ${i}\n`;
 | 
			
		||||
      }
 | 
			
		||||
      diagramCode += `  end\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render boxes around groups', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      diagramCode += `  box Group 1\n`;
 | 
			
		||||
      participantTypes.slice(0, 3).forEach((pt, index) => {
 | 
			
		||||
        diagramCode += `    ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  end\n`;
 | 
			
		||||
      diagramCode += `  box rgb(200,220,255) Group 2\n`;
 | 
			
		||||
      participantTypes.slice(3, 6).forEach((pt, index) => {
 | 
			
		||||
        diagramCode += `    ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  end\n`;
 | 
			
		||||
      diagramCode += `  ${participantTypes[0].display}0 ->> ${participantTypes[3].display}0: Cross-group message\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, { look });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render with different font settings', () => {
 | 
			
		||||
      let diagramCode = `sequenceDiagram\n`;
 | 
			
		||||
      participantTypes.slice(0, 3).forEach((pt, index) => {
 | 
			
		||||
        diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
 | 
			
		||||
      });
 | 
			
		||||
      diagramCode += `  ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Regular message\n`;
 | 
			
		||||
      diagramCode += `  Note right of ${participantTypes[1].display}1: Regular note\n`;
 | 
			
		||||
      imgSnapshotTest(diagramCode, {
 | 
			
		||||
        look,
 | 
			
		||||
        sequence: {
 | 
			
		||||
          actorFontFamily: 'courier',
 | 
			
		||||
          actorFontSize: 14,
 | 
			
		||||
          messageFontFamily: 'Arial',
 | 
			
		||||
          messageFontSize: 12,
 | 
			
		||||
          noteFontFamily: 'times',
 | 
			
		||||
          noteFontSize: 16,
 | 
			
		||||
          noteAlign: 'left',
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Additional tests for specific combinations
 | 
			
		||||
describe('Sequence Diagram Special Cases', () => {
 | 
			
		||||
  it('should render complex sequence with all features', () => {
 | 
			
		||||
    const diagramCode = `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
        box rgb(200,220,255) Authentication
 | 
			
		||||
          actor User
 | 
			
		||||
          participant LoginUI@{ "type": "boundary" }
 | 
			
		||||
          participant AuthService@{ "type": "control" }
 | 
			
		||||
          participant UserDB@{ "type": "database" }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        box rgb(200,255,220) Order Processing
 | 
			
		||||
          participant Order@{ "type": "entity" }
 | 
			
		||||
          participant OrderQueue@{ "type": "queue" }
 | 
			
		||||
          participant AuditLogs@{ "type": "collections" }
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
        User ->> LoginUI: Enter credentials
 | 
			
		||||
        LoginUI ->> AuthService: Validate
 | 
			
		||||
        AuthService ->> UserDB: Query user
 | 
			
		||||
        UserDB -->> AuthService: User data
 | 
			
		||||
        alt Valid credentials
 | 
			
		||||
          AuthService -->> LoginUI: Success
 | 
			
		||||
          LoginUI -->> User: Welcome
 | 
			
		||||
          
 | 
			
		||||
          par Place order
 | 
			
		||||
            User ->> Order: New order
 | 
			
		||||
            Order ->> OrderQueue: Process
 | 
			
		||||
            and
 | 
			
		||||
            Order ->> AuditLogs: Record
 | 
			
		||||
          end
 | 
			
		||||
          
 | 
			
		||||
          loop Until confirmed
 | 
			
		||||
            OrderQueue ->> Order: Update status
 | 
			
		||||
            Order -->> User: Notification
 | 
			
		||||
          end
 | 
			
		||||
        else Invalid credentials
 | 
			
		||||
          AuthService --x LoginUI: Failure
 | 
			
		||||
          LoginUI --x User: Retry
 | 
			
		||||
        end
 | 
			
		||||
    `;
 | 
			
		||||
    imgSnapshotTest(diagramCode, {});
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render with wrapped messages and notes', () => {
 | 
			
		||||
    const diagramCode = `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
        participant A
 | 
			
		||||
        participant B
 | 
			
		||||
        
 | 
			
		||||
        A ->> B: This is a very long message that should wrap properly in the diagram rendering
 | 
			
		||||
        Note over A,B: This is a very long note that should also wrap properly when rendered in the diagram
 | 
			
		||||
        
 | 
			
		||||
        par Wrapped parallel
 | 
			
		||||
          A ->> B: Parallel message 1<br>with explicit line break
 | 
			
		||||
          and
 | 
			
		||||
          B ->> A: Parallel message 2<br>with explicit line break
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
        loop Wrapped loop
 | 
			
		||||
          Note right of B: This is a long note<br>in a loop
 | 
			
		||||
          A ->> B: Message in loop
 | 
			
		||||
        end
 | 
			
		||||
    `;
 | 
			
		||||
    imgSnapshotTest(diagramCode, { sequence: { wrap: true } });
 | 
			
		||||
  });
 | 
			
		||||
  describe('Sequence Diagram Rendering with Different Participant Types', () => {
 | 
			
		||||
    it('should render a sequence diagram with various participant types', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
          participant User@{ "type": "actor" }
 | 
			
		||||
          participant AuthService@{ "type": "control" }
 | 
			
		||||
          participant UI@{ "type": "boundary" }
 | 
			
		||||
          participant OrderController@{ "type": "control" }
 | 
			
		||||
          participant Product@{ "type": "entity" }
 | 
			
		||||
          participant MongoDB@{ "type": "database" }
 | 
			
		||||
          participant Products@{ "type": "collections" }
 | 
			
		||||
          participant OrderQueue@{ "type": "queue" }
 | 
			
		||||
          User ->> UI: Login request
 | 
			
		||||
          UI ->> AuthService: Validate credentials
 | 
			
		||||
          AuthService -->> UI: Authentication token
 | 
			
		||||
          UI ->> OrderController: Place order
 | 
			
		||||
          OrderController ->> Product: Check availability
 | 
			
		||||
          Product -->> OrderController: Available
 | 
			
		||||
          OrderController ->> MongoDB: Save order
 | 
			
		||||
          MongoDB -->> OrderController: Order saved
 | 
			
		||||
          OrderController ->> OrderQueue: Process payment
 | 
			
		||||
          OrderQueue -->> User: Order confirmation
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render participant creation and destruction with different types', () => {
 | 
			
		||||
      imgSnapshotTest(`
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
          participant Alice@{ "type" : "boundary" }
 | 
			
		||||
          Alice->>Bob: Hello Bob, how are you ?
 | 
			
		||||
          Bob->>Alice: Fine, thank you. And you?
 | 
			
		||||
          create participant Carl@{ "type" : "control" }
 | 
			
		||||
          Alice->>Carl: Hi Carl!
 | 
			
		||||
          create actor D as Donald
 | 
			
		||||
          Carl->>D: Hi!
 | 
			
		||||
          destroy Carl
 | 
			
		||||
          Alice-xCarl: We are too many
 | 
			
		||||
          destroy Bob
 | 
			
		||||
          Bob->>Alice: I agree
 | 
			
		||||
      `);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should handle complex interactions between different participant types', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
        box rgb(200,220,255) Authentication
 | 
			
		||||
          participant User@{ "type": "actor" }
 | 
			
		||||
          participant LoginUI@{ "type": "boundary" }
 | 
			
		||||
          participant AuthService@{ "type": "control" }
 | 
			
		||||
          participant UserDB@{ "type": "database" }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        box rgb(200,255,220) Order Processing
 | 
			
		||||
          participant Order@{ "type": "entity" }
 | 
			
		||||
          participant OrderQueue@{ "type": "queue" }
 | 
			
		||||
          participant AuditLogs@{ "type": "collections" }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        User ->> LoginUI: Enter credentials
 | 
			
		||||
        LoginUI ->> AuthService: Validate
 | 
			
		||||
        AuthService ->> UserDB: Query user
 | 
			
		||||
        UserDB -->> AuthService: User data
 | 
			
		||||
 | 
			
		||||
        alt Valid credentials
 | 
			
		||||
          AuthService -->> LoginUI: Success
 | 
			
		||||
          LoginUI -->> User: Welcome
 | 
			
		||||
 | 
			
		||||
          par Place order
 | 
			
		||||
            User ->> Order: New order
 | 
			
		||||
            Order ->> OrderQueue: Process
 | 
			
		||||
            and
 | 
			
		||||
            Order ->> AuditLogs: Record
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          loop Until confirmed
 | 
			
		||||
            OrderQueue ->> Order: Update status
 | 
			
		||||
            Order -->> User: Notification
 | 
			
		||||
          end
 | 
			
		||||
        else Invalid credentials
 | 
			
		||||
          AuthService --x LoginUI: Failure
 | 
			
		||||
          LoginUI --x User: Retry
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
        { sequence: { useMaxWidth: false } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render parallel processes with different participant types', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
       sequenceDiagram
 | 
			
		||||
        participant Customer@{ "type": "actor" }
 | 
			
		||||
        participant Frontend@{ "type": "participant" }
 | 
			
		||||
        participant PaymentService@{ "type": "boundary" }
 | 
			
		||||
        participant InventoryManager@{ "type": "control" }
 | 
			
		||||
        participant Order@{ "type": "entity" }
 | 
			
		||||
        participant OrdersDB@{ "type": "database" }
 | 
			
		||||
        participant NotificationQueue@{ "type": "queue" }
 | 
			
		||||
 | 
			
		||||
        Customer ->> Frontend: Place order
 | 
			
		||||
        Frontend ->> Order: Create order
 | 
			
		||||
        par Parallel Processing
 | 
			
		||||
          Order ->> PaymentService: Process payment
 | 
			
		||||
          and
 | 
			
		||||
          Order ->> InventoryManager: Reserve items
 | 
			
		||||
        end
 | 
			
		||||
        PaymentService -->> Order: Payment confirmed
 | 
			
		||||
        InventoryManager -->> Order: Items reserved
 | 
			
		||||
        Order ->> OrdersDB: Save finalized order
 | 
			
		||||
        OrdersDB -->> Order: Order saved
 | 
			
		||||
        Order ->> NotificationQueue: Send confirmation
 | 
			
		||||
        NotificationQueue -->> Customer: Order confirmation
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('should render different participant types with notes and loops', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    sequenceDiagram
 | 
			
		||||
    actor Admin
 | 
			
		||||
    participant Dashboard
 | 
			
		||||
    participant AuthService@{ "type" : "boundary" }
 | 
			
		||||
    participant UserManager@{ "type" : "control" }
 | 
			
		||||
    participant UserProfile@{ "type" : "entity" }
 | 
			
		||||
    participant UserDB@{ "type" : "database" }
 | 
			
		||||
    participant Logs@{ "type" : "database" }
 | 
			
		||||
    
 | 
			
		||||
    Admin ->> Dashboard: Open user management
 | 
			
		||||
    loop Authentication check
 | 
			
		||||
      Dashboard ->> AuthService: Verify admin rights
 | 
			
		||||
      AuthService ->> Dashboard: Access granted
 | 
			
		||||
    end
 | 
			
		||||
    Dashboard ->> UserManager: List users
 | 
			
		||||
    UserManager ->> UserDB: Query users
 | 
			
		||||
    UserDB ->> UserManager: Return user data
 | 
			
		||||
    Note right of UserDB: Encrypted data<br/>requires decryption
 | 
			
		||||
    UserManager ->> UserProfile: Format profiles
 | 
			
		||||
    UserProfile ->> UserManager: Formatted data
 | 
			
		||||
    UserManager ->> Dashboard: Display users
 | 
			
		||||
    Dashboard ->> Logs: Record access
 | 
			
		||||
    Logs ->> Admin: Audit trail
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render different participant types with alternative flows', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    sequenceDiagram
 | 
			
		||||
      actor Client
 | 
			
		||||
      participant MobileApp
 | 
			
		||||
      participant CloudService@{ "type" : "boundary" }
 | 
			
		||||
      participant DataProcessor@{ "type" : "control" }
 | 
			
		||||
      participant Transaction@{ "type" : "entity" }
 | 
			
		||||
      participant TransactionsDB@{ "type" : "database" }
 | 
			
		||||
      participant EventBus@{ "type" : "queue" }
 | 
			
		||||
      
 | 
			
		||||
      Client ->> MobileApp: Initiate transaction
 | 
			
		||||
      MobileApp ->> CloudService: Authenticate
 | 
			
		||||
      alt Authentication successful
 | 
			
		||||
        CloudService -->> MobileApp: Auth token
 | 
			
		||||
        MobileApp ->> DataProcessor: Process data
 | 
			
		||||
        DataProcessor ->> Transaction: Create transaction
 | 
			
		||||
        Transaction ->> TransactionsDB: Save record
 | 
			
		||||
        TransactionsDB -->> Transaction: Confirmation
 | 
			
		||||
        Transaction ->> EventBus: Publish event
 | 
			
		||||
        EventBus -->> Client: Notification
 | 
			
		||||
      else Authentication failed
 | 
			
		||||
        CloudService -->> MobileApp: Error
 | 
			
		||||
        MobileApp -->> Client: Show error
 | 
			
		||||
      end
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render different participant types with wrapping text', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  sequenceDiagram
 | 
			
		||||
      participant B@{ "type" : "boundary" }
 | 
			
		||||
      participant C@{ "type" : "control" }
 | 
			
		||||
      participant E@{ "type" : "entity" }
 | 
			
		||||
      participant DB@{ "type" : "database" }
 | 
			
		||||
      participant COL@{ "type" : "collections" }
 | 
			
		||||
      participant Q@{ "type" : "queue" }
 | 
			
		||||
    
 | 
			
		||||
      FE ->> B: Another long message<br/>with explicit<br/>line breaks
 | 
			
		||||
      B -->> FE: Response message that is also quite long and needs to wrap
 | 
			
		||||
      FE ->> C: Process data
 | 
			
		||||
      C ->> E: Validate
 | 
			
		||||
      E -->> C: Validation result
 | 
			
		||||
      C ->> DB: Save
 | 
			
		||||
      DB -->> C: Save result
 | 
			
		||||
      C ->> COL: Log
 | 
			
		||||
      COL -->> Q: Forward
 | 
			
		||||
      Q -->> LongNameUser: Final response with confirmation of all actions taken
 | 
			
		||||
    `,
 | 
			
		||||
      { sequence: { wrap: true } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
 | 
			
		||||
    it('should render long notes left of boundary', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
        participant Alice@{ "type" : "boundary" }
 | 
			
		||||
        actor Bob
 | 
			
		||||
        Alice->>Bob: Hola
 | 
			
		||||
        Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
        Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render wrapped long notes left of control', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "control" }
 | 
			
		||||
      actor Bob
 | 
			
		||||
      Alice->>Bob: Hola
 | 
			
		||||
      Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render long notes right of entity', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "entity" }
 | 
			
		||||
      actor Bob
 | 
			
		||||
      Alice->>Bob: Hola
 | 
			
		||||
      Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render wrapped long notes right of database', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "database" }
 | 
			
		||||
      actor Bob
 | 
			
		||||
      Alice->>Bob: Hola
 | 
			
		||||
      Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render long notes over collections', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "collections" }
 | 
			
		||||
      actor Bob
 | 
			
		||||
      Alice->>Bob: Hola
 | 
			
		||||
      Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render wrapped long notes over queue', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "queue" }
 | 
			
		||||
      actor Bob
 | 
			
		||||
      Alice->>Bob: Hola
 | 
			
		||||
      Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render notes over actor and boundary', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      actor Alice
 | 
			
		||||
      participant Charlie@{ "type" : "boundary" }
 | 
			
		||||
      note over Alice: Some note
 | 
			
		||||
      note over Charlie: Other note
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render long messages from database to collections', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "database" }
 | 
			
		||||
      participant Bob@{ "type" : "collections" }
 | 
			
		||||
      Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render wrapped long messages from control to entity', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "control" }
 | 
			
		||||
      participant Bob@{ "type" : "entity" }
 | 
			
		||||
      Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
      Bob->>Alice: I'm short though
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render long messages from queue to boundary', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice@{ "type" : "queue" }
 | 
			
		||||
      participant Bob@{ "type" : "boundary" }
 | 
			
		||||
      Alice->>Bob: I'm short
 | 
			
		||||
      Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render wrapped long messages from actor to database', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      actor Alice
 | 
			
		||||
      participant Bob@{ "type" : "database" }
 | 
			
		||||
      Alice->>Bob: I'm short
 | 
			
		||||
      Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
 | 
			
		||||
    `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('svg size', () => {
 | 
			
		||||
    it('should render a sequence diagram when useMaxWidth is true (default)', () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
        actor Alice
 | 
			
		||||
        participant Bob@{ "type" : "boundary" }
 | 
			
		||||
        participant John@{ "type" : "control" }
 | 
			
		||||
        Alice ->> Bob: Hello Bob, how are you?
 | 
			
		||||
        Bob-->>John: How about you John?
 | 
			
		||||
        Bob--x Alice: I am good thanks!
 | 
			
		||||
        Bob-x John: I am good thanks!
 | 
			
		||||
        Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
 | 
			
		||||
        Bob-->Alice: Checking with John...
 | 
			
		||||
        alt either this
 | 
			
		||||
          Alice->>John: Yes
 | 
			
		||||
        else or this
 | 
			
		||||
          Alice->>John: No
 | 
			
		||||
        else or this will happen
 | 
			
		||||
          Alice->John: Maybe
 | 
			
		||||
        end
 | 
			
		||||
        par this happens in parallel
 | 
			
		||||
          Alice -->> Bob: Parallel message 1
 | 
			
		||||
        and
 | 
			
		||||
          Alice -->> John: Parallel message 2
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
        { sequence: { useMaxWidth: true } }
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg').should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render a sequence diagram when useMaxWidth is false', () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
        actor Alice
 | 
			
		||||
        participant Bob@{ "type" : "boundary" }
 | 
			
		||||
        participant John@{ "type" : "control" }
 | 
			
		||||
        Alice ->> Bob: Hello Bob, how are you?
 | 
			
		||||
        Bob-->>John: How about you John?
 | 
			
		||||
        Bob--x Alice: I am good thanks!
 | 
			
		||||
        Bob-x John: I am good thanks!
 | 
			
		||||
        Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
 | 
			
		||||
        Bob-->Alice: Checking with John...
 | 
			
		||||
        alt either this
 | 
			
		||||
          Alice->>John: Yes
 | 
			
		||||
        else or this
 | 
			
		||||
          Alice->>John: No
 | 
			
		||||
        else or this will happen
 | 
			
		||||
          Alice->John: Maybe
 | 
			
		||||
        end
 | 
			
		||||
        par this happens in parallel
 | 
			
		||||
          Alice -->> Bob: Parallel message 1
 | 
			
		||||
        and
 | 
			
		||||
          Alice -->> John: Parallel message 2
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
        { sequence: { useMaxWidth: false } }
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg').should((svg) => {
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(width).to.be.within(820 * 0.95, 820 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('Central Connection Rendering Tests', () => {
 | 
			
		||||
      it('should render central connection circles on actor vertical lines', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        Alice ()->>() Bob: Central connection
 | 
			
		||||
        Bob ()-->> Charlie: Reverse central connection
 | 
			
		||||
        Charlie ()<<-->>() Alice: Dual central connection`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with different arrow types', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        Alice ()->>() Bob: Solid open arrow
 | 
			
		||||
        Alice ()-->>() Bob: Dotted open arrow
 | 
			
		||||
        Alice ()-x() Bob: Solid cross
 | 
			
		||||
        Alice ()--x() Bob: Dotted cross
 | 
			
		||||
        Alice ()->() Bob: Solid arrow`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with bidirectional arrows', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        Alice ()<<->>() Bob: Bidirectional solid
 | 
			
		||||
        Alice ()<<-->>() Bob: Bidirectional dotted`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with activations', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        Alice ()->>() Bob: Activate Bob
 | 
			
		||||
        activate Bob
 | 
			
		||||
        Bob ()-->> Charlie: Message to Charlie
 | 
			
		||||
        Bob ()->>() Alice: Response to Alice
 | 
			
		||||
        deactivate Bob`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections mixed with normal messages', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        Alice ->> Bob: Normal message
 | 
			
		||||
        Bob ()->>() Charlie: Central connection
 | 
			
		||||
        Charlie -->> Alice: Normal dotted message
 | 
			
		||||
        Alice ()<<-->>() Bob: Dual central connection
 | 
			
		||||
        Bob -x Charlie: Normal cross message`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with notes', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        Alice ()->>() Bob: Central connection
 | 
			
		||||
        Note over Alice,Bob: Central connection note
 | 
			
		||||
        Bob ()-->> Charlie: Reverse central connection
 | 
			
		||||
        Note right of Charlie: Response note
 | 
			
		||||
        Charlie ()<<-->>() Alice: Dual central connection`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with loops and alternatives', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
        participant Alice
 | 
			
		||||
        participant Bob
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        loop Every minute
 | 
			
		||||
            Alice ()->>() Bob: Central heartbeat
 | 
			
		||||
            Bob ()-->> Charlie: Forward heartbeat
 | 
			
		||||
        end
 | 
			
		||||
        alt Success
 | 
			
		||||
            Charlie ()<<-->>() Alice: Success response
 | 
			
		||||
        else Failure
 | 
			
		||||
            Charlie ()-x() Alice: Failure response
 | 
			
		||||
        end`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render central connections with different participant types', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `sequenceDiagram
 | 
			
		||||
          participant Alice
 | 
			
		||||
          actor Bob
 | 
			
		||||
          participant Charlie@{"type":"boundary"}
 | 
			
		||||
          participant David@{"type":"control"}
 | 
			
		||||
          participant Eve@{"type":"entity"}
 | 
			
		||||
          Alice ()->>() Bob: To actor
 | 
			
		||||
          Bob ()-->> Charlie: To boundary
 | 
			
		||||
          Charlie ()->>() David: To control
 | 
			
		||||
          David ()<<-->>() Eve: To entity
 | 
			
		||||
          Eve ()-x() Alice: Back to participant`,
 | 
			
		||||
          { look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -893,17 +893,6 @@ describe('Sequence diagram', () => {
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should handle bidirectional arrows with autonumber', () => {
 | 
			
		||||
      imgSnapshotTest(`
 | 
			
		||||
       sequenceDiagram
 | 
			
		||||
       autonumber
 | 
			
		||||
       participant A
 | 
			
		||||
       participant B
 | 
			
		||||
       A<<->>B: This is a bidirectional message
 | 
			
		||||
       A->B: This is a normal message`);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
 | 
			
		||||
      //Be aware that the syntax for "properties" is likely to be changed.
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
@@ -1053,167 +1042,4 @@ describe('Sequence diagram', () => {
 | 
			
		||||
      ]);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  describe('render new arrow type', () => {
 | 
			
		||||
    it('should render Solid half arrow top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    sequenceDiagram
 | 
			
		||||
      Alice -|\\  John: Hello John, how are you? 
 | 
			
		||||
      Alice-|\\  John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice -|\\  John: Test
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render Solid half arrow bottom', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
    sequenceDiagram
 | 
			
		||||
      Alice-|/John: Hello John, how are you?
 | 
			
		||||
      Alice-|/John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice-|/John: Test
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow top ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
      Alice-\\\\John: Hello John, how are you?
 | 
			
		||||
      Alice-\\\\John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice-\\\\John: Test
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render Stick half arrow bottom ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
       sequenceDiagram
 | 
			
		||||
      Alice-//John: Hello John, how are you?
 | 
			
		||||
      Alice-//John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice-//John: Test
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render Solid half arrow top reverse ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
       sequenceDiagram
 | 
			
		||||
      Alice/|-John: Hello Alice, how are you?
 | 
			
		||||
      Alice/|-John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice/|-John: Test
 | 
			
		||||
 | 
			
		||||
      `
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Solid half arrow bottom reverse ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `sequenceDiagram
 | 
			
		||||
        Alice \\|- John: Hello Alice, how are you?
 | 
			
		||||
        Alice \\|- John: Hi Alice, I can hear you!
 | 
			
		||||
        Alice \\|- John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow top reverse ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      Alice //-John: Hello Alice, how are you?
 | 
			
		||||
      Alice //-John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice //-John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow bottom reverse ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
       sequenceDiagram
 | 
			
		||||
      Alice \\\\-John: Hello Alice, how are you?
 | 
			
		||||
      Alice \\\\-John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice \\\\-John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Solid half arrow top dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
      Alice --|\\John: Hello John, how are you?
 | 
			
		||||
      Alice --|\\John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice --|\\John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Solid half arrow bottom dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
      Alice --|/John: Hello John, how are you?
 | 
			
		||||
      Alice --|/John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice --|/John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow top dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
      Alice--\\\\John: Hello John, how are you?
 | 
			
		||||
      Alice--\\\\John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice--\\\\John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow bottom dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
     sequenceDiagram
 | 
			
		||||
      Alice--//John: Hello John, how are you?
 | 
			
		||||
      Alice--//John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice--//John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Solid half arrow top reverse dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  sequenceDiagram
 | 
			
		||||
      Alice/|--John: Hello Alice, how are you?
 | 
			
		||||
      Alice/|--John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice/|--John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Solid half arrow bottom reverse dotted', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  sequenceDiagram
 | 
			
		||||
      Alice\\|--John: Hello Alice, how are you?
 | 
			
		||||
      Alice\\|--John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice\\|--John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow top reverse dotted ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  sequenceDiagram
 | 
			
		||||
      Alice//--John: Hello Alice, how are you?
 | 
			
		||||
      Alice//--John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice//--John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render Stick half arrow bottom reverse dotted ', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  sequenceDiagram
 | 
			
		||||
      Alice\\\\--John: Hello Alice, how are you?
 | 
			
		||||
      Alice\\\\--John: Hi Alice, I can hear you!
 | 
			
		||||
      Alice\\\\--John: Test`
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -138,8 +138,8 @@ describe('State diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    stateDiagram-v2
 | 
			
		||||
    State1: This a single line description
 | 
			
		||||
    State2: This a multi line description
 | 
			
		||||
    State1: This a a single line description
 | 
			
		||||
    State2: This a a multi line description
 | 
			
		||||
    State2: here comes the multi part
 | 
			
		||||
    [*] --> State1
 | 
			
		||||
    State1 --> State2
 | 
			
		||||
@@ -345,7 +345,7 @@ stateDiagram
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 width of compound state should grow with title if title is wider', () => {
 | 
			
		||||
  it('v2 width of compond state should grow with title if title is wider', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
@@ -402,8 +402,8 @@ stateDiagram-v2
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
    MyState
 | 
			
		||||
    note left of MyState : I am a lefty
 | 
			
		||||
    note right of MyState : I am a righty
 | 
			
		||||
    note left of MyState : I am a leftie
 | 
			
		||||
    note right of MyState : I am a rightie
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
@@ -552,7 +552,7 @@ style AState fill:#636,border:1px solid red,color:white;
 | 
			
		||||
        { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it(' should let styles take precedence over classes', () => {
 | 
			
		||||
    it(' should let styles take preceedence over classes', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
@@ -565,7 +565,7 @@ style AState fill:#636,border:1px solid red,color:white;
 | 
			
		||||
        { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it(' should allow styles to take effect in subgraphs', () => {
 | 
			
		||||
    it(' should allow styles to take effect in stubgraphs', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  stateDiagram
 | 
			
		||||
@@ -602,231 +602,6 @@ State1 --> [*]
 | 
			
		||||
      --
 | 
			
		||||
      55
 | 
			
		||||
  }
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render edge labels correctly', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
title: On The Way To Something Something DarkSide
 | 
			
		||||
config:
 | 
			
		||||
  look: default
 | 
			
		||||
  theme: default
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
 | 
			
		||||
   state State1_____________
 | 
			
		||||
   {
 | 
			
		||||
      c0
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State2_____________
 | 
			
		||||
   {
 | 
			
		||||
      c1
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State3_____________
 | 
			
		||||
   {
 | 
			
		||||
      c7
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State4_____________
 | 
			
		||||
   {
 | 
			
		||||
      c2
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State5_____________
 | 
			
		||||
   {
 | 
			
		||||
      c3
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State6_____________
 | 
			
		||||
   {
 | 
			
		||||
      c4
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State7_____________
 | 
			
		||||
   {
 | 
			
		||||
      c5
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State8_____________
 | 
			
		||||
   {
 | 
			
		||||
      c6
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[*] --> State1_____________
 | 
			
		||||
State1_____________ --> State2_____________   : Transition1_____
 | 
			
		||||
State2_____________ --> State4_____________   : Transition2_____
 | 
			
		||||
State2_____________ --> State3_____________   : Transition3_____
 | 
			
		||||
State3_____________ --> State2_____________
 | 
			
		||||
State4_____________ --> State2_____________   : Transition5_____
 | 
			
		||||
State4_____________ --> State5_____________   : Transition6_____
 | 
			
		||||
State5_____________ --> State6_____________   : Transition7_____
 | 
			
		||||
State6_____________ --> State4_____________   : Transition8_____
 | 
			
		||||
State2_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State4_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State5_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State6_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State7_____________ --> State1_____________   : Transition9_____
 | 
			
		||||
State5_____________ --> State8_____________   : Transition10____
 | 
			
		||||
State8_____________ --> State5_____________   : Transition11____
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render edge labels correctly with multiple transitions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
title: Multiple Transitions
 | 
			
		||||
config:
 | 
			
		||||
  look: default
 | 
			
		||||
  theme: default
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
 | 
			
		||||
   state State1_____________
 | 
			
		||||
   {
 | 
			
		||||
      c0
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State2_____________
 | 
			
		||||
   {
 | 
			
		||||
      c1
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State3_____________
 | 
			
		||||
   {
 | 
			
		||||
      c7
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State4_____________
 | 
			
		||||
   {
 | 
			
		||||
      c2
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State5_____________
 | 
			
		||||
   {
 | 
			
		||||
      c3
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State6_____________
 | 
			
		||||
   {
 | 
			
		||||
      c4
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State7_____________
 | 
			
		||||
   {
 | 
			
		||||
      c5
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State8_____________
 | 
			
		||||
   {
 | 
			
		||||
      c6
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State9_____________
 | 
			
		||||
   {
 | 
			
		||||
      c9
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
[*] --> State1_____________
 | 
			
		||||
State1_____________ --> State2_____________   : Transition1_____
 | 
			
		||||
State2_____________ --> State4_____________   : Transition2_____
 | 
			
		||||
State2_____________ --> State3_____________   : Transition3_____
 | 
			
		||||
State3_____________ --> State2_____________
 | 
			
		||||
State4_____________ --> State2_____________   : Transition5_____
 | 
			
		||||
State4_____________ --> State5_____________   : Transition6_____
 | 
			
		||||
State5_____________ --> State6_____________   : Transition7_____
 | 
			
		||||
State6_____________ --> State4_____________   : Transition8_____
 | 
			
		||||
State2_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State4_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State5_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State6_____________ --> State7_____________   : Transition4_____
 | 
			
		||||
State7_____________ --> State1_____________   : Transition9_____
 | 
			
		||||
State5_____________ --> State8_____________   : Transition10____
 | 
			
		||||
State8_____________ --> State5_____________   : Transition11____
 | 
			
		||||
State9_____________ --> State8_____________   : Transition12____
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render edge labels correctly with multiple states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
title: Multiple States
 | 
			
		||||
config:
 | 
			
		||||
  look: default
 | 
			
		||||
  theme: default
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
 | 
			
		||||
   state State1_____________
 | 
			
		||||
   {
 | 
			
		||||
      c0
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State2_____________
 | 
			
		||||
   {
 | 
			
		||||
      c1
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State3_____________
 | 
			
		||||
   {
 | 
			
		||||
      c7
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State4_____________
 | 
			
		||||
   {
 | 
			
		||||
      c2
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State5_____________
 | 
			
		||||
   {
 | 
			
		||||
      c3
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State6_____________
 | 
			
		||||
   {
 | 
			
		||||
      c4
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State7_____________
 | 
			
		||||
   {
 | 
			
		||||
      c5
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State8_____________
 | 
			
		||||
   {
 | 
			
		||||
      c6
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State9_____________
 | 
			
		||||
   {
 | 
			
		||||
      c9
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   state State10_____________
 | 
			
		||||
   {
 | 
			
		||||
      c10
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
[*] --> State1_____________
 | 
			
		||||
State1_____________ --> State2_____________   : Transition1_____
 | 
			
		||||
State2_____________ --> State3_____________   : Transition2_____
 | 
			
		||||
State3_____________ --> State4_____________   : Transition3_____
 | 
			
		||||
State4_____________ --> State5_____________   : Transition4_____
 | 
			
		||||
State5_____________ --> State6_____________   : Transition5_____
 | 
			
		||||
State6_____________ --> State7_____________   : Transition6_____
 | 
			
		||||
State7_____________ --> State8_____________   : Transition7_____
 | 
			
		||||
State8_____________ --> State9_____________   : Transition8_____
 | 
			
		||||
State9_____________ --> State10_____________   : Transition9_____
 | 
			
		||||
`,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 
 | 
			
		||||
@@ -129,8 +129,8 @@ describe('State diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    stateDiagram
 | 
			
		||||
    State1: This a single line description
 | 
			
		||||
    State2: This a multi line description
 | 
			
		||||
    State1: This a a single line description
 | 
			
		||||
    State2: This a a multi line description
 | 
			
		||||
    State2: here comes the multi part
 | 
			
		||||
    [*] --> State1
 | 
			
		||||
    State1 --> State2
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
    title History of Social Media Platform
 | 
			
		||||
    2002 : LinkedIn
 | 
			
		||||
    2004 : Facebook : Google
 | 
			
		||||
    2005 : YouTube
 | 
			
		||||
    2005 : Youtube
 | 
			
		||||
    2006 : Twitter
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
@@ -35,7 +35,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        section Stone Age
 | 
			
		||||
          7600 BC : Britain's oldest known house was built in Orkney, Scotland
 | 
			
		||||
          6000 BC : Sea levels rise and Britain becomes an island.<br> The people who live here are hunter-gatherers.
 | 
			
		||||
        section Bronze Age
 | 
			
		||||
        section Broze Age
 | 
			
		||||
          2300 BC : People arrive from Europe and settle in Britain. <br>They bring farming and metalworking.
 | 
			
		||||
                  : New styles of pottery and ways of burying the dead appear.
 | 
			
		||||
          2200 BC : The last major building works are completed at Stonehenge.<br> People now bury their dead in stone circles.
 | 
			
		||||
@@ -51,7 +51,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
@@ -68,7 +68,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -84,7 +84,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -101,7 +101,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -118,7 +118,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -135,7 +135,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -152,7 +152,7 @@ describe('Timeline diagram', () => {
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -161,68 +161,4 @@ describe('Timeline diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('11: should render timeline with many stacked events and proper timeline line length', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `timeline
 | 
			
		||||
        title Medical Device Lifecycle
 | 
			
		||||
        section Pre-Development
 | 
			
		||||
          Quality Management System : Regulatory Compliance : Risk Management
 | 
			
		||||
        section Development
 | 
			
		||||
          Management Responsibility : Planning Activities : Human Resources
 | 
			
		||||
          Resource Management : Management Reviews : Infrastructure
 | 
			
		||||
        section Post-Development
 | 
			
		||||
          Product Realization Activities : Planning Activities : Customer-related Processes
 | 
			
		||||
          Post-Production Activities : Feedback : Complaints : Adverse Events
 | 
			
		||||
                                    : Research and Development : Purchasing Activities
 | 
			
		||||
                                    : Production Activities : Installation Activities
 | 
			
		||||
                                    : Servicing Activities : Post-Market Surveillance
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('12: should render timeline with proper vertical line lengths for all columns', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
    theme: base
 | 
			
		||||
    themeVariables:
 | 
			
		||||
        fontFamily: Fira Sans
 | 
			
		||||
        fontSize: 17px
 | 
			
		||||
        cScale0: '#b3cde0'
 | 
			
		||||
        cScale1: '#f49090'
 | 
			
		||||
        cScale2: '#85d5b8'
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
timeline
 | 
			
		||||
    title Medical Device Lifecycle
 | 
			
		||||
    section Planning
 | 
			
		||||
        Quality Management System (4): Regulatory Compliance (4.1.1)
 | 
			
		||||
            : Risk Management (4.1.2)
 | 
			
		||||
        Management Resposibility (5): Planning Activities (5.4)
 | 
			
		||||
            : Management Reviews (5.6)
 | 
			
		||||
         Resource Management (6): Human Resources (6.2)
 | 
			
		||||
            : Infrastructure (6.3)
 | 
			
		||||
    section Realization
 | 
			
		||||
        Research and Development (7.3): RnD Planning (7.3.2)
 | 
			
		||||
            : Inputs (7.3.3)
 | 
			
		||||
            : Outputs (7.3.4)
 | 
			
		||||
            : Review (7.3.5)
 | 
			
		||||
            : Verification (7.3.6)
 | 
			
		||||
            : Validation (7.3.7)
 | 
			
		||||
        Purchasing (7.4): Purchasing Process (7.4.1)
 | 
			
		||||
            : Purchasing Information (7.4.2)
 | 
			
		||||
        Production (7.5): Production Activities (7.5.1)
 | 
			
		||||
            : Production Feedback (8.2.1)
 | 
			
		||||
        Installation (7.5.3): Installation Activities (7.5.3)
 | 
			
		||||
        Servicing (7.5.4): Servicing Activities (7.5.4)
 | 
			
		||||
    section Post-Production
 | 
			
		||||
        Post-Market Activities (8): Feedback (8.2.1)
 | 
			
		||||
            : Complaints (8.2.2)
 | 
			
		||||
            : Adverse Events (8.2.3)
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,382 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
describe('Treemap Diagram', () => {
 | 
			
		||||
  it('1: should render a basic treemap', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Category A"
 | 
			
		||||
    "Item A1": 10
 | 
			
		||||
    "Item A2": 20
 | 
			
		||||
"Category B"
 | 
			
		||||
    "Item B1": 15
 | 
			
		||||
    "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2: should render a hierarchical treemap', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Products"
 | 
			
		||||
    "Electronics"
 | 
			
		||||
        "Phones": 50
 | 
			
		||||
        "Computers": 30
 | 
			
		||||
        "Accessories": 20
 | 
			
		||||
    "Clothing"
 | 
			
		||||
        "Men's"
 | 
			
		||||
            "Shirts": 10
 | 
			
		||||
            "Pants": 15
 | 
			
		||||
        "Women's"
 | 
			
		||||
            "Dresses": 20
 | 
			
		||||
            "Skirts": 10
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3: should render a treemap with styling using classDef', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Section 1"
 | 
			
		||||
    "Leaf 1.1": 12
 | 
			
		||||
    "Section 1.2":::class1
 | 
			
		||||
      "Leaf 1.2.1": 12
 | 
			
		||||
"Section 2"
 | 
			
		||||
    "Leaf 2.1": 20:::class1
 | 
			
		||||
    "Leaf 2.2": 25
 | 
			
		||||
    "Leaf 2.3": 12
 | 
			
		||||
 | 
			
		||||
classDef class1 fill:red,color:blue,stroke:#FFD600;
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('4: should handle long text that wraps', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Main Category"
 | 
			
		||||
    "This is a very long item name that should wrap to the next line when rendered in the treemap diagram": 50
 | 
			
		||||
    "Short item": 20
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('5: should render with a forest theme', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  theme: forest
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Category A"
 | 
			
		||||
    "Item A1": 10
 | 
			
		||||
    "Item A2": 20
 | 
			
		||||
"Category B"
 | 
			
		||||
    "Item B1": 15
 | 
			
		||||
    "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6: should handle multiple levels of nesting', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Level 1"
 | 
			
		||||
    "Level 2A"
 | 
			
		||||
        "Level 3A": 10
 | 
			
		||||
        "Level 3B": 15
 | 
			
		||||
    "Level 2B"
 | 
			
		||||
        "Level 3C": 20
 | 
			
		||||
        "Level 3D"
 | 
			
		||||
            "Level 4A": 5
 | 
			
		||||
            "Level 4B": 5
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('7: should handle classDef with multiple styles', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `treemap-beta
 | 
			
		||||
"Main"
 | 
			
		||||
    "A": 20
 | 
			
		||||
    "B":::important
 | 
			
		||||
        "B1": 10
 | 
			
		||||
        "B2": 15
 | 
			
		||||
    "C": 5:::secondary
 | 
			
		||||
 | 
			
		||||
classDef important fill:#f96,stroke:#333,stroke-width:2px;
 | 
			
		||||
classDef secondary fill:#6cf,stroke:#333,stroke-dasharray:5 5;
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8: should handle dollar value formatting with thousands separator', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: "$0,0"
 | 
			
		||||
---
 | 
			
		||||
treemap
 | 
			
		||||
"Budget"
 | 
			
		||||
    "Operations"
 | 
			
		||||
        "Salaries": 700000
 | 
			
		||||
        "Equipment": 200000
 | 
			
		||||
        "Supplies": 100000
 | 
			
		||||
    "Marketing"
 | 
			
		||||
        "Advertising": 400000
 | 
			
		||||
        "Events": 100000
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8a: should handle percentage formatting', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: ".1%"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Market Share"
 | 
			
		||||
    "Company A": 0.35
 | 
			
		||||
    "Company B": 0.25
 | 
			
		||||
    "Company C": 0.15
 | 
			
		||||
    "Others": 0.25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8b: should handle decimal formatting', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: ".2f"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Metrics"
 | 
			
		||||
    "Conversion Rate": 0.0567
 | 
			
		||||
    "Bounce Rate": 0.6723
 | 
			
		||||
    "Click-through Rate": 0.1289
 | 
			
		||||
    "Engagement": 0.4521
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8c: should handle dollar sign with decimal places', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: "$.2f"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Product Prices"
 | 
			
		||||
    "Basic": 19.99
 | 
			
		||||
    "Standard": 49.99
 | 
			
		||||
    "Premium": 99.99
 | 
			
		||||
    "Enterprise": 199.99
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8d: should handle dollar sign with thousands separator and decimal places', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: "$,.2f"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Revenue"
 | 
			
		||||
    "Q1": 1250345.75
 | 
			
		||||
    "Q2": 1645789.25
 | 
			
		||||
    "Q3": 1845123.50
 | 
			
		||||
    "Q4": 2145678.75
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8e: should handle simple thousands separator', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: ","
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"User Counts"
 | 
			
		||||
    "Active Users": 1250345
 | 
			
		||||
    "New Signups": 45789
 | 
			
		||||
    "Churned": 12350
 | 
			
		||||
    "Converted": 78975
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8f: should handle valueFormat set via directive with dollar and thousands separator', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: "$,.0f"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Sales by Region"
 | 
			
		||||
    "North": 1234567
 | 
			
		||||
    "South": 7654321
 | 
			
		||||
    "East": 4567890
 | 
			
		||||
    "West": 9876543
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8g: should handle scientific notation format', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: ".2e"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Scientific Values"
 | 
			
		||||
    "Value 1": 1234567
 | 
			
		||||
    "Value 2": 0.0000123
 | 
			
		||||
    "Value 3": 1000000000
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('9: should handle a complex example with multiple features', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  theme: dark
 | 
			
		||||
  treemap:
 | 
			
		||||
    valueFormat: "$0,0"
 | 
			
		||||
---
 | 
			
		||||
treemap-beta
 | 
			
		||||
"Company Budget"
 | 
			
		||||
    "Engineering":::engineering
 | 
			
		||||
        "Frontend": 300000
 | 
			
		||||
        "Backend": 400000
 | 
			
		||||
        "DevOps": 200000
 | 
			
		||||
    "Marketing":::marketing
 | 
			
		||||
        "Digital": 250000
 | 
			
		||||
        "Print": 100000
 | 
			
		||||
        "Events": 150000
 | 
			
		||||
    "Sales":::sales
 | 
			
		||||
        "Direct": 500000
 | 
			
		||||
        "Channel": 300000
 | 
			
		||||
 | 
			
		||||
classDef engineering fill:#6b9bc3,stroke:#333;
 | 
			
		||||
classDef marketing fill:#c36b9b,stroke:#333;
 | 
			
		||||
classDef sales fill:#c3a66b,stroke:#333;
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('10: should render the example from documentation', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    treemap-beta
 | 
			
		||||
      "Section 1"
 | 
			
		||||
          "Leaf 1.1": 12
 | 
			
		||||
          "Section 1.2":::class1
 | 
			
		||||
            "Leaf 1.2.1": 12
 | 
			
		||||
      "Section 2"
 | 
			
		||||
          "Leaf 2.1": 20:::class1
 | 
			
		||||
          "Leaf 2.2": 25
 | 
			
		||||
          "Leaf 2.3": 12
 | 
			
		||||
 | 
			
		||||
      classDef class1 fill:red,color:blue,stroke:#FFD600;
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('11: should handle comments', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    treemap-beta
 | 
			
		||||
      %% This is a comment
 | 
			
		||||
      "Category A"
 | 
			
		||||
          "Item A1": 10
 | 
			
		||||
          "Item A2": 20
 | 
			
		||||
      %% Another comment
 | 
			
		||||
      "Category B"
 | 
			
		||||
          "Item B1": 15
 | 
			
		||||
          "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  /*
 | 
			
		||||
  it.skip('12: should render a treemap with title', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    treemap-beta
 | 
			
		||||
      title Treemap with Title
 | 
			
		||||
      "Category A"
 | 
			
		||||
          "Item A1": 10
 | 
			
		||||
          "Item A2": 20
 | 
			
		||||
      "Category B"
 | 
			
		||||
          "Item B1": 15
 | 
			
		||||
          "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it.skip('13: should render a treemap with accessibility attributes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    treemap-beta
 | 
			
		||||
      accTitle: Accessible Treemap Title
 | 
			
		||||
      accDescr: This is a description of the treemap for accessibility purposes
 | 
			
		||||
      "Category A"
 | 
			
		||||
          "Item A1": 10
 | 
			
		||||
          "Item A2": 20
 | 
			
		||||
      "Category B"
 | 
			
		||||
          "Item B1": 15
 | 
			
		||||
          "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it.skip('14: should render a treemap with title and accessibility attributes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    treemap
 | 
			
		||||
      title Treemap with Title and Accessibility
 | 
			
		||||
      accTitle: Accessible Treemap Title
 | 
			
		||||
      accDescr: This is a description of the treemap for accessibility purposes
 | 
			
		||||
      "Category A"
 | 
			
		||||
          "Item A1": 10
 | 
			
		||||
          "Item A2": 20
 | 
			
		||||
      "Category B"
 | 
			
		||||
          "Item B1": 15
 | 
			
		||||
          "Item B2": 25
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  */
 | 
			
		||||
});
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
describe('XY Chart', () => {
 | 
			
		||||
  it('should render the simplest possible xy-beta chart', () => {
 | 
			
		||||
  it('should render the simplest possible chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart-beta
 | 
			
		||||
@@ -10,19 +10,10 @@ describe('XY Chart', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render the simplest possible xy chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
        line [10, 30, 20]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('Should render a complete chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -35,7 +26,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('Should render a chart without title', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
        bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
@@ -47,7 +38,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('y-axis title not required', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis 4000 --> 11000
 | 
			
		||||
        bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
@@ -59,7 +50,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('Should render a chart without y-axis with different range', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
 | 
			
		||||
        line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
 | 
			
		||||
@@ -70,7 +61,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('x axis title not required', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
 | 
			
		||||
        line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
 | 
			
		||||
@@ -81,7 +72,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('Multiple plots can be rendered', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        line [23, 46, 77, 34]
 | 
			
		||||
        line [45, 32, 33, 12]
 | 
			
		||||
        bar [87, 54, 99, 85]
 | 
			
		||||
@@ -95,7 +86,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('Decimals and negative numbers are supported', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        y-axis -2.4 --> 3.5
 | 
			
		||||
        line [+1.3, .6, 2.4, -.34]
 | 
			
		||||
      `,
 | 
			
		||||
@@ -113,7 +104,7 @@ describe('XY Chart', () => {
 | 
			
		||||
          height: 20
 | 
			
		||||
          plotReservedSpacePercent: 100
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
@@ -139,7 +130,7 @@ describe('XY Chart', () => {
 | 
			
		||||
            showTick: false
 | 
			
		||||
            showAxisLine: false
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
@@ -149,7 +140,7 @@ describe('XY Chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5},  "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60  }}}%%
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -188,9 +179,8 @@ describe('XY Chart', () => {
 | 
			
		||||
            axisLineWidth: 5
 | 
			
		||||
          chartOrientation: horizontal
 | 
			
		||||
          plotReservedSpacePercent: 60
 | 
			
		||||
          showDataLabel: true
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -211,7 +201,7 @@ describe('XY Chart', () => {
 | 
			
		||||
          yAxis:
 | 
			
		||||
            showTitle: false
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -232,7 +222,7 @@ describe('XY Chart', () => {
 | 
			
		||||
          yAxis:
 | 
			
		||||
            showLabel: false
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -253,7 +243,7 @@ describe('XY Chart', () => {
 | 
			
		||||
          yAxis:
 | 
			
		||||
            showTick: false
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -274,7 +264,7 @@ describe('XY Chart', () => {
 | 
			
		||||
          yAxis:
 | 
			
		||||
            showAxisLine: false
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -303,7 +293,7 @@ describe('XY Chart', () => {
 | 
			
		||||
            xAxisLineColor: "#87ceeb"
 | 
			
		||||
            plotColorPalette: "#008000, #faba63"
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
@@ -316,7 +306,7 @@ describe('XY Chart', () => {
 | 
			
		||||
  it('should use the correct distances between data points', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis 0 --> 2
 | 
			
		||||
        line [0, 1, 0, 1]
 | 
			
		||||
        bar [1, 0, 1, 0]
 | 
			
		||||
@@ -325,516 +315,4 @@ describe('XY Chart', () => {
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render vertical bar chart with labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
      title "Sales Revenue"
 | 
			
		||||
      x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
      y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
      bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render horizontal bar chart with labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
      title "Sales Revenue"
 | 
			
		||||
      x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
      y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
      bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render vertical bar chart without labels by default', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    xychart
 | 
			
		||||
      title "Sales Revenue"
 | 
			
		||||
      x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
      y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
      bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render horizontal bar chart without labels by default', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
      title "Sales Revenue"
 | 
			
		||||
      x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
 | 
			
		||||
      y-axis "Revenue (in $)" 4000 --> 11000
 | 
			
		||||
      bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render multiple bar plots vertically with labels correctly', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Multiple Bar Plots"
 | 
			
		||||
        x-axis Categories [A, B, C]
 | 
			
		||||
        y-axis "Values" 0 --> 100
 | 
			
		||||
        bar [10, 50, 90]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render multiple bar plots horizontally with labels correctly', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Multiple Bar Plots"
 | 
			
		||||
        x-axis Categories [A, B, C]
 | 
			
		||||
        y-axis "Values" 0 --> 100
 | 
			
		||||
        bar [10, 50, 90]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a single bar with label for a vertical xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Single Bar Chart"
 | 
			
		||||
        x-axis Categories [A]
 | 
			
		||||
        y-axis "Value" 0 --> 100
 | 
			
		||||
        bar [75]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a single bar with label for a horizontal xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Single Bar Chart"
 | 
			
		||||
        x-axis Categories [A]
 | 
			
		||||
        y-axis "Value" 0 --> 100
 | 
			
		||||
        bar [75]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render negative and decimal values with correct labels for vertical xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Decimal and Negative Values"
 | 
			
		||||
        x-axis Categories [A, B, C]
 | 
			
		||||
        y-axis -10 --> 10
 | 
			
		||||
        bar [ -2.5, 0.75, 5.1 ]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render negative and decimal values with correct labels for horizontal xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Decimal and Negative Values"
 | 
			
		||||
        x-axis Categories [A, B, C]
 | 
			
		||||
        y-axis -10 --> 10
 | 
			
		||||
        bar [ -2.5, 0.75, 5.1 ]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels within each bar in the vertical xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
            title "Sales Revenue"
 | 
			
		||||
            x-axis Months [jan,b,c]
 | 
			
		||||
            y-axis "Revenue (in $)" 4000 --> 12000
 | 
			
		||||
            bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000, 3000, 2000, 500, 2000, 3000, 11000, 5000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            // Check horizontal alignment (within tolerance)
 | 
			
		||||
            expect(textProps.x + textProps.width / 2).to.be.closeTo(
 | 
			
		||||
              barProps.x + barProps.width / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels within each bar in the horizontal xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
            title "Sales Revenue"
 | 
			
		||||
            x-axis Months [jan,b,c]
 | 
			
		||||
            y-axis "Revenue (in $)" 4000 --> 12000
 | 
			
		||||
            bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000, 3000, 2000, 500, 2000, 3000, 11000, 5000, 6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
            expect(textProps.y + textProps.height / 2).to.be.closeTo(
 | 
			
		||||
              barProps.y + barProps.height / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels within each bar in the vertical xy-chart with a lot of bars of different sizes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      config:
 | 
			
		||||
        xyChart:
 | 
			
		||||
          showDataLabel: true
 | 
			
		||||
      ---
 | 
			
		||||
      xychart
 | 
			
		||||
        title "Sales Revenue"
 | 
			
		||||
        x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
 | 
			
		||||
        y-axis "Revenue (in $)" 4000 --> 12000
 | 
			
		||||
        bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000, 8000, 10000, 5000, 7600, 4999,11000 ,5000,6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            // Check horizontal alignment (within tolerance)
 | 
			
		||||
            expect(textProps.x + textProps.width / 2).to.be.closeTo(
 | 
			
		||||
              barProps.x + barProps.width / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels within each bar in the horizontal xy-chart with a lot of bars of different sizes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
      title "Sales Revenue"
 | 
			
		||||
      x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
 | 
			
		||||
      y-axis "Revenue (in $)" 4000 --> 12000
 | 
			
		||||
      bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000, 8000, 10000, 5000, 7600, 4999,11000 ,5000,6000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
            expect(textProps.y + textProps.height / 2).to.be.closeTo(
 | 
			
		||||
              barProps.y + barProps.height / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels correctly for a bar in the vertical xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
            title "Sales Revenue"
 | 
			
		||||
            x-axis Months [jan]
 | 
			
		||||
            y-axis "Revenue (in $)" 3000 --> 12000
 | 
			
		||||
            bar [4000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            // Check horizontal alignment (within tolerance)
 | 
			
		||||
            expect(textProps.x + textProps.width / 2).to.be.closeTo(
 | 
			
		||||
              barProps.x + barProps.width / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render data labels correctly for a bar in the horizontal xy-chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    ---
 | 
			
		||||
    config:
 | 
			
		||||
      xyChart:
 | 
			
		||||
        showDataLabel: true
 | 
			
		||||
        chartOrientation: horizontal
 | 
			
		||||
    ---
 | 
			
		||||
    xychart
 | 
			
		||||
            title "Sales Revenue"
 | 
			
		||||
            x-axis Months [jan]
 | 
			
		||||
            y-axis "Revenue (in $)" 3000 --> 12000
 | 
			
		||||
            bar [4000]
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.get('g.bar-plot-0').within(() => {
 | 
			
		||||
      cy.get('rect').each(($rect, index) => {
 | 
			
		||||
        // Extract bar properties
 | 
			
		||||
        const barProps = {
 | 
			
		||||
          x: parseFloat($rect.attr('x')),
 | 
			
		||||
          y: parseFloat($rect.attr('y')),
 | 
			
		||||
          width: parseFloat($rect.attr('width')),
 | 
			
		||||
          height: parseFloat($rect.attr('height')),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get the text element corresponding to this bar by index.
 | 
			
		||||
        cy.get('text')
 | 
			
		||||
          .eq(index)
 | 
			
		||||
          .then(($text) => {
 | 
			
		||||
            const bbox = $text[0].getBBox();
 | 
			
		||||
            const textProps = {
 | 
			
		||||
              x: bbox.x,
 | 
			
		||||
              y: bbox.y,
 | 
			
		||||
              width: bbox.width,
 | 
			
		||||
              height: bbox.height,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Verify that the text label is positioned within the boundaries of the bar.
 | 
			
		||||
            expect(textProps.x).to.be.greaterThan(barProps.x);
 | 
			
		||||
            expect(textProps.x + textProps.width).to.be.lessThan(barProps.x + barProps.width);
 | 
			
		||||
 | 
			
		||||
            expect(textProps.y).to.be.greaterThan(barProps.y);
 | 
			
		||||
            expect(textProps.y + textProps.height).to.be.lessThan(barProps.y + barProps.height);
 | 
			
		||||
            expect(textProps.y + textProps.height / 2).to.be.closeTo(
 | 
			
		||||
              barProps.y + barProps.height / 2,
 | 
			
		||||
              5
 | 
			
		||||
            );
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"
 | 
			
		||||
@@ -30,8 +30,8 @@
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        background-color: #eee;
 | 
			
		||||
        background-image:
 | 
			
		||||
          radial-gradient(#fff 1%, transparent 11%), radial-gradient(#fff 1%, transparent 11%);
 | 
			
		||||
        background-image: radial-gradient(#fff 1%, transparent 11%),
 | 
			
		||||
          radial-gradient(#fff 1%, transparent 11%);
 | 
			
		||||
        background-size: 20px 20px;
 | 
			
		||||
        background-position:
 | 
			
		||||
          0 0,
 | 
			
		||||
@@ -60,7 +60,7 @@
 | 
			
		||||
    <pre id="diagram" class="mermaid2">
 | 
			
		||||
 timeline
 | 
			
		||||
        title My day
 | 
			
		||||
        section Section with no tasks
 | 
			
		||||
        section section with no tasks
 | 
			
		||||
        section Go to work at the dog office
 | 
			
		||||
          1930 : first step : second step is a long step
 | 
			
		||||
               : third step
 | 
			
		||||
@@ -70,18 +70,18 @@
 | 
			
		||||
          1960 : India fights poverty, looses war to China and gets nuclear weapons from USA and USSR
 | 
			
		||||
          1970 : Green Revolution comes to india
 | 
			
		||||
        section Another section with no tasks
 | 
			
		||||
          I am a very, very big task
 | 
			
		||||
          I am not so big task
 | 
			
		||||
          I am a big big big tasks
 | 
			
		||||
          I am not so big tasks
 | 
			
		||||
    </pre>
 | 
			
		||||
    <pre id="diagram" class="mermaid">
 | 
			
		||||
 timeline
 | 
			
		||||
        title MermaidChart 2023 Timeline
 | 
			
		||||
        section 2023 Q1 <br> Release Personal Tier
 | 
			
		||||
          Bullet 1 : sub-point 1a : sub-point 1b
 | 
			
		||||
          Buttet 1 : sub-point 1a : sub-point 1b
 | 
			
		||||
               : sub-point 1c
 | 
			
		||||
          Bullet 2 : sub-point 2a : sub-point 2b
 | 
			
		||||
        section 2023 Q2 <br> Release XYZ Tier
 | 
			
		||||
          Bullet 3 : sub-point <br> 3a : sub-point 3b
 | 
			
		||||
          Buttet 3 : sub-point <br> 3a : sub-point 3b
 | 
			
		||||
               : sub-point 3c
 | 
			
		||||
          Bullet 4 : sub-point 4a : sub-point 4b
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +93,7 @@
 | 
			
		||||
        section Stone Age
 | 
			
		||||
          7600 BC : Britain's oldest known house was built in Orkney, Scotland
 | 
			
		||||
          6000 BC : Sea levels rise and Britain becomes an island. The people who live here are hunter-gatherers.
 | 
			
		||||
        section Bronze Age
 | 
			
		||||
        section Broze Age
 | 
			
		||||
          2300 BC : People arrive from Europe and settle in Britain. They bring farming and metalworking.
 | 
			
		||||
               : New styles of pottery and ways of burying the dead appear.
 | 
			
		||||
          2200 BC : The last major building works are completed at Stonehenge. People now bury their dead in stone circles.
 | 
			
		||||
@@ -106,7 +106,7 @@
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google : Pixar
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008s : Instagram
 | 
			
		||||
@@ -122,7 +122,7 @@
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google : Pixar
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008s : Instagram
 | 
			
		||||
@@ -139,7 +139,7 @@
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008 : Instagram
 | 
			
		||||
@@ -152,7 +152,7 @@
 | 
			
		||||
        title History of Social Media Platform
 | 
			
		||||
          2002 : LinkedIn
 | 
			
		||||
          2004 : Facebook : Google
 | 
			
		||||
          2005 : YouTube
 | 
			
		||||
          2005 : Youtube
 | 
			
		||||
          2006 : Twitter
 | 
			
		||||
          2007 : Tumblr
 | 
			
		||||
          2008s : Instagram
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
        +String owner
 | 
			
		||||
        +BigDecimal balance
 | 
			
		||||
        +deposit(amount) bool
 | 
			
		||||
        +withdrawal(amount) int
 | 
			
		||||
        +withdrawl(amount) int
 | 
			
		||||
       }
 | 
			
		||||
       cssClass "BankAccount" customCss
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +56,7 @@ classE o-- classF : aggregation
 | 
			
		||||
          +String owner
 | 
			
		||||
          +BigDecimal balance
 | 
			
		||||
          +deposit(amount) bool
 | 
			
		||||
          +withdrawal(amount) int
 | 
			
		||||
          +withdrawl(amount) int
 | 
			
		||||
        }
 | 
			
		||||
          Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
          Class03~T~ *-- Class04~T~
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@
 | 
			
		||||
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
      }
 | 
			
		||||
      mermaid.initialize({ startOnLoad: true, securityLevel: 'strict_', logLevel: 1 });
 | 
			
		||||
      mermaid.initialize({ startOnLoad: true, securityLevel: 'strct', logLevel: 1 });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
        flowchart BT subgraph S1 sub1 -->sub2 end subgraph S2 sub4 end S1 --> S2 sub1 --> sub4
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 200px">
 | 
			
		||||
        sequenceDiagram Alice->>Bob:Extremely utterly long line of longness which had previously
 | 
			
		||||
        sequenceDiagram Alice->>Bob:Extremely utterly long line of longness which had preivously
 | 
			
		||||
        overflown the actor box as it is much longer than what it should be Bob->>Alice: I'm short
 | 
			
		||||
        though
 | 
			
		||||
      </div>
 | 
			
		||||
@@ -61,9 +61,9 @@
 | 
			
		||||
      #quot;elit#quot;."}}
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid2" style="width: 50%; height: 50%">
 | 
			
		||||
      flowchart TB internet nat router lb1 lb2 compute1 compute2 subgraph project router nat
 | 
			
		||||
      subgraph subnet1 compute1 lb1 end subgraph subnet2 compute2 lb2 end end internet --> router
 | 
			
		||||
      router --> subnet1 & subnet2 subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
      flowchart TB internet nat routeur lb1 lb2 compute1 compute2 subgraph project routeur nat
 | 
			
		||||
      subgraph subnet1 compute1 lb1 end subgraph subnet2 compute2 lb2 end end internet --> routeur
 | 
			
		||||
      routeur --> subnet1 & subnet2 subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid2" style="width: 50%; height: 50%">
 | 
			
		||||
      flowchart TD subgraph one[One] subgraph sub_one[Sub One] _sub_one end end subgraph two[Two]
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 | 
			
		||||
    <title>Mermaid Quick Test Page</title>
 | 
			
		||||
    <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
 | 
			
		||||
    <style>
 | 
			
		||||
      div.mermaid {
 | 
			
		||||
        font-family: 'Courier New', Courier, monospace !important;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Pie chart demos</h1>
 | 
			
		||||
    <pre class="mermaid">
 | 
			
		||||
     pie title Default text position: Animal adoption
 | 
			
		||||
        accTitle: simple pie char demo
 | 
			
		||||
        accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
 | 
			
		||||
         "dogs" : -60.67
 | 
			
		||||
        "rats" : 40.12
 | 
			
		||||
    </pre>
 | 
			
		||||
 | 
			
		||||
    <hr />
 | 
			
		||||
    <script type="module">
 | 
			
		||||
      import mermaid from '/mermaid.esm.mjs';
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <style>
 | 
			
		||||
      svg:not(svg svg) {
 | 
			
		||||
      svg {
 | 
			
		||||
        border: 2px solid darkred;
 | 
			
		||||
      }
 | 
			
		||||
      .exClass2 > rect,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
 | 
			
		||||
    <link
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user