mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-26 01:14:09 +02:00 
			
		
		
		
	Compare commits
	
		
			25 Commits
		
	
	
		
			@mermaid-j
			...
			xychart
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 4f9cf4f9fc | ||
|   | 90be8dedf6 | ||
|   | f1490ff679 | ||
|   | 25160d9688 | ||
|   | 533a921ef5 | ||
|   | 3bef03f568 | ||
|   | 737f4f0cf3 | ||
|   | 71e5a2b3a3 | ||
|   | 54f1435839 | ||
|   | 48a20c5cb8 | ||
|   | 5f4f1cc08d | ||
|   | da0a4ae37d | ||
|   | 2972012059 | ||
|   | cf641ba4fd | ||
|   | 39e5064019 | ||
|   | 7830d0c4bf | ||
|   | 60d34bdc72 | ||
|   | 3262a06a8e | ||
|   | 506314598e | ||
|   | 25a9479acf | ||
|   | 1273f440a8 | ||
|   | e1d085925e | ||
|   | 39d175314c | ||
|   | 17426f0a97 | ||
|   | a36fa7cd2f | 
| @@ -1,9 +1,3 @@ | ||||
| export interface PackageOptions { | ||||
|   name: string; | ||||
|   packageName: string; | ||||
|   file: string; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Shared common options for both ESBuild and Vite | ||||
|  */ | ||||
| @@ -28,9 +22,9 @@ export const packageOptions = { | ||||
|     packageName: 'mermaid-zenuml', | ||||
|     file: 'detector.ts', | ||||
|   }, | ||||
|   'mermaid-layout-elk': { | ||||
|     name: 'mermaid-layout-elk', | ||||
|     packageName: 'mermaid-layout-elk', | ||||
|     file: 'layouts.ts', | ||||
|   'mermaid-flowchart-elk': { | ||||
|     name: 'mermaid-flowchart-elk', | ||||
|     packageName: 'mermaid-flowchart-elk', | ||||
|     file: 'detector.ts', | ||||
|   }, | ||||
| } as const satisfies Record<string, PackageOptions>; | ||||
| } as const; | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| import jison from 'jison'; | ||||
|  | ||||
| export const transformJison = (src: string): string => { | ||||
|   // @ts-ignore - Jison is not typed properly | ||||
|   const parser = new jison.Generator(src, { | ||||
|     moduleType: 'js', | ||||
|     'token-stack': true, | ||||
|   | ||||
| @@ -19,15 +19,12 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [ | ||||
|   'xyChart', | ||||
|   'requirement', | ||||
|   'mindmap', | ||||
|   'kanban', | ||||
|   'timeline', | ||||
|   'gitGraph', | ||||
|   'c4', | ||||
|   'sankey', | ||||
|   'block', | ||||
|   'packet', | ||||
|   'architecture', | ||||
|   'radar', | ||||
| ] as const; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| /* eslint-disable no-console */ | ||||
| import { packageOptions } from './common.js'; | ||||
| import { execSync } from 'child_process'; | ||||
|  | ||||
| @@ -6,17 +5,11 @@ const buildType = (packageName: string) => { | ||||
|   console.log(`Building types for ${packageName}`); | ||||
|   try { | ||||
|     const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`); | ||||
|     if (out.length > 0) { | ||||
|       console.log(out.toString()); | ||||
|     } | ||||
|     out.length > 0 && 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()); | ||||
|     } | ||||
|     e.stdout.length > 0 && console.error(e.stdout.toString()); | ||||
|     e.stderr.length > 0 && console.error(e.stderr.toString()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,8 +0,0 @@ | ||||
| # Changesets | ||||
|  | ||||
| Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works | ||||
| with multi-package repos, or single-package repos to help you version and publish your code. You can | ||||
| find the full documentation for it [in our repository](https://github.com/changesets/changesets) | ||||
|  | ||||
| We have a quick list of common questions to get you started engaging with this project in | ||||
| [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) | ||||
| @@ -1,12 +0,0 @@ | ||||
| { | ||||
|   "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", | ||||
|   "changelog": ["@changesets/changelog-github", { "repo": "mermaid-js/mermaid" }], | ||||
|   "commit": false, | ||||
|   "fixed": [], | ||||
|   "linked": [], | ||||
|   "access": "public", | ||||
|   "baseBranch": "master", | ||||
|   "updateInternalDependencies": "patch", | ||||
|   "bumpVersionsWithWorkspaceProtocolOnly": true, | ||||
|   "ignore": ["@mermaid-js/docs", "@mermaid-js/webpack-test", "@mermaid-js/mermaid-example-diagram"] | ||||
| } | ||||
| @@ -13,7 +13,6 @@ bqstring | ||||
| BQUOTE | ||||
| bramp | ||||
| BRKT | ||||
| brotli | ||||
| callbackargs | ||||
| callbackname | ||||
| classdef | ||||
| @@ -26,10 +25,8 @@ concat | ||||
| controlx | ||||
| controly | ||||
| CSSCLASS | ||||
| curv | ||||
| CYLINDEREND | ||||
| CYLINDERSTART | ||||
| DAGA | ||||
| datakey | ||||
| DEND | ||||
| descr | ||||
| @@ -56,7 +53,6 @@ GENERICTYPE | ||||
| getBoundarys | ||||
| grammr | ||||
| graphtype | ||||
| halign | ||||
| iife | ||||
| interp | ||||
| introdcued | ||||
| @@ -68,7 +64,6 @@ Kaufmann | ||||
| keyify | ||||
| LABELPOS | ||||
| LABELTYPE | ||||
| layoutstop | ||||
| lcov | ||||
| LEFTOF | ||||
| Lexa | ||||
| @@ -94,7 +89,6 @@ reqs | ||||
| rewritelinks | ||||
| rgba | ||||
| RIGHTOF | ||||
| roughjs | ||||
| sankey | ||||
| sequencenumber | ||||
| shrc | ||||
| @@ -114,17 +108,13 @@ strikethrough | ||||
| stringifying | ||||
| struct | ||||
| STYLECLASS | ||||
| STYLEDEF | ||||
| STYLEOPTS | ||||
| subcomponent | ||||
| subcomponents | ||||
| subconfig | ||||
| SUBROUTINEEND | ||||
| SUBROUTINESTART | ||||
| Subschemas | ||||
| substr | ||||
| SVGG | ||||
| SVGSVG | ||||
| TAGEND | ||||
| TAGSTART | ||||
| techn | ||||
| @@ -135,13 +125,11 @@ titlevalue | ||||
| topbar | ||||
| TRAPEND | ||||
| TRAPSTART | ||||
| treemap | ||||
| ts-nocheck | ||||
| tsdoc | ||||
| typeof | ||||
| typestr | ||||
| unshift | ||||
| urlsafe | ||||
| verifymethod | ||||
| VERIFYMTHD | ||||
| WARN_DOCSDIR_DOESNT_MATCH | ||||
|   | ||||
| @@ -4,6 +4,5 @@ cpettitt | ||||
| Dong Cai | ||||
| Nikolay Rozhkov | ||||
| Peng Xiao | ||||
| Per Brolin | ||||
| subhash-halder | ||||
| Vinod Sidharth | ||||
|   | ||||
| @@ -28,9 +28,6 @@ dictionaryDefinitions: | ||||
|   - name: suggestions | ||||
|     words: | ||||
|       - none | ||||
|       - disp | ||||
|       - subproc | ||||
|       - tria | ||||
|     suggestWords: | ||||
|       - seperator:separator | ||||
|       - vertice:vertex | ||||
|   | ||||
| @@ -20,18 +20,14 @@ dagre-d3 | ||||
| Deepdwn | ||||
| Docsify | ||||
| Docsy | ||||
| Doctave | ||||
| DokuWiki | ||||
| dompurify | ||||
| elkjs | ||||
| fcose | ||||
| fontawesome | ||||
| Forgejo | ||||
| Foswiki | ||||
| Gitea | ||||
| graphlib | ||||
| Grav | ||||
| icones | ||||
| iconify | ||||
| Inkdrop | ||||
| jiti | ||||
| @@ -58,17 +54,13 @@ presetAttributify | ||||
| pyplot | ||||
| redmine | ||||
| rehype | ||||
| roughjs | ||||
| rscratch | ||||
| shiki | ||||
| Slidev | ||||
| sparkline | ||||
| sphinxcontrib | ||||
| ssim | ||||
| stylis | ||||
| Swimm | ||||
| tsbuildinfo | ||||
| tseslint | ||||
| Tuleap | ||||
| Typora | ||||
| unocss | ||||
|   | ||||
| @@ -1,18 +1,14 @@ | ||||
| Adamiecki | ||||
| arrowend | ||||
| Bendpoints | ||||
| bmatrix | ||||
| braintree | ||||
| catmull | ||||
| compositTitleSize | ||||
| curv | ||||
| doublecircle | ||||
| elems | ||||
| gantt | ||||
| gitgraph | ||||
| gzipped | ||||
| handDrawn | ||||
| kanban | ||||
| knsv | ||||
| Knut | ||||
| marginx | ||||
| @@ -21,12 +17,10 @@ Markdownish | ||||
| mermaidjs | ||||
| mindmap | ||||
| mindmaps | ||||
| mrtree | ||||
| multigraph | ||||
| nodesep | ||||
| NOTEGROUP | ||||
| Pinterest | ||||
| procs | ||||
| rankdir | ||||
| ranksep | ||||
| rect | ||||
|   | ||||
| @@ -1,7 +1 @@ | ||||
| BRANDES | ||||
| circo | ||||
| handDrawn | ||||
| KOEPF | ||||
| neato | ||||
| newbranch | ||||
| validify | ||||
|   | ||||
| @@ -2,17 +2,13 @@ import { build } from 'esbuild'; | ||||
| 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'; | ||||
| import { defaultOptions, getBuildConfig } from './util.js'; | ||||
| import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; | ||||
|  | ||||
| const shouldVisualize = process.argv.includes('--visualize'); | ||||
|  | ||||
| const buildPackage = async (entryName: keyof typeof packageOptions) => { | ||||
|   const commonOptions: MermaidBuildOptions = { | ||||
|     ...defaultOptions, | ||||
|     options: packageOptions[entryName], | ||||
|   } as const; | ||||
|   const buildConfigs: MermaidBuildOptions[] = [ | ||||
|   const commonOptions = { ...defaultOptions, entryName } as const; | ||||
|   const buildConfigs = [ | ||||
|     // package.mjs | ||||
|     { ...commonOptions }, | ||||
|     // package.min.mjs | ||||
| @@ -39,11 +35,11 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { | ||||
|  | ||||
|   if (shouldVisualize) { | ||||
|     for (const { metafile } of results) { | ||||
|       if (!metafile?.outputs) { | ||||
|       if (!metafile) { | ||||
|         continue; | ||||
|       } | ||||
|       const fileName = Object.keys(metafile.outputs) | ||||
|         .find((file) => !file.includes('chunks') && file.endsWith('js'))! | ||||
|         .filter((file) => !file.includes('chunks') && file.endsWith('js'))[0] | ||||
|         .replace('dist/', ''); | ||||
|       // Upload metafile into https://esbuild.github.io/analyze/ | ||||
|       await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile)); | ||||
| @@ -52,14 +48,13 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { | ||||
| }; | ||||
|  | ||||
| const handler = (e) => { | ||||
|   // eslint-disable-next-line no-console | ||||
|   console.error(e); | ||||
|   process.exit(1); | ||||
| }; | ||||
|  | ||||
| const main = async () => { | ||||
|   await generateLangium(); | ||||
|   await mkdir('stats', { recursive: true }); | ||||
|   await mkdir('stats').catch(() => {}); | ||||
|   const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; | ||||
|   // it should build `parser` before `mermaid` because it's a dependency | ||||
|   for (const pkg of packageNames) { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { readFile } from 'node:fs/promises'; | ||||
| import { transformJison } from '../.build/jisonTransformer.js'; | ||||
| import type { Plugin } from 'esbuild'; | ||||
| import { Plugin } from 'esbuild'; | ||||
|  | ||||
| export const jisonPlugin: Plugin = { | ||||
|   name: 'jison', | ||||
|   | ||||
| @@ -1,52 +1,34 @@ | ||||
| /* eslint-disable no-console */ | ||||
| import chokidar from 'chokidar'; | ||||
| import cors from 'cors'; | ||||
| import { context } from 'esbuild'; | ||||
| import type { Request, Response } from 'express'; | ||||
| import express from 'express'; | ||||
| import { packageOptions } from '../.build/common.js'; | ||||
| import type { NextFunction, Request, Response } from 'express'; | ||||
| import cors from 'cors'; | ||||
| import { getBuildConfig, defaultOptions } from './util.js'; | ||||
| import { context } from 'esbuild'; | ||||
| import chokidar from 'chokidar'; | ||||
| import { generateLangium } from '../.build/generateLangium.js'; | ||||
| import { defaultOptions, getBuildConfig } from './util.js'; | ||||
| import { packageOptions } from '../.build/common.js'; | ||||
|  | ||||
| const configs = Object.values(packageOptions).map(({ packageName }) => | ||||
|   getBuildConfig({ | ||||
|     ...defaultOptions, | ||||
|     minify: false, | ||||
|     core: false, | ||||
|     options: packageOptions[packageName], | ||||
|   }) | ||||
|   getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName }) | ||||
| ); | ||||
| const mermaidIIFEConfig = getBuildConfig({ | ||||
|   ...defaultOptions, | ||||
|   minify: false, | ||||
|   core: false, | ||||
|   options: packageOptions.mermaid, | ||||
|   entryName: 'mermaid', | ||||
|   format: 'iife', | ||||
| }); | ||||
| configs.push(mermaidIIFEConfig); | ||||
|  | ||||
| const contexts = await Promise.all( | ||||
|   configs.map(async (config) => ({ config, context: await context(config) })) | ||||
| ); | ||||
| const contexts = await Promise.all(configs.map((config) => context(config))); | ||||
|  | ||||
| let rebuildCounter = 1; | ||||
| const rebuildAll = async () => { | ||||
|   const buildNumber = rebuildCounter++; | ||||
|   const timeLabel = `Rebuild ${buildNumber} Time (total)`; | ||||
|   console.time(timeLabel); | ||||
|   await Promise.all( | ||||
|     contexts.map(async ({ config, context }) => { | ||||
|       const buildVariant = `Rebuild ${buildNumber} Time (${Object.keys(config.entryPoints!)[0]} ${config.format})`; | ||||
|       console.time(buildVariant); | ||||
|       await context.rebuild(); | ||||
|       console.timeEnd(buildVariant); | ||||
|     }) | ||||
|   ).catch((e) => console.error(e)); | ||||
|   console.timeEnd(timeLabel); | ||||
|   console.time('Rebuild time'); | ||||
|   await Promise.all(contexts.map((ctx) => ctx.rebuild())).catch((e) => console.error(e)); | ||||
|   console.timeEnd('Rebuild time'); | ||||
| }; | ||||
|  | ||||
| let clients: { id: number; response: Response }[] = []; | ||||
| function eventsHandler(request: Request, response: Response) { | ||||
| function eventsHandler(request: Request, response: Response, next: NextFunction) { | ||||
|   const headers = { | ||||
|     'Content-Type': 'text/event-stream', | ||||
|     Connection: 'keep-alive', | ||||
| @@ -63,20 +45,19 @@ function eventsHandler(request: Request, response: Response) { | ||||
|   }); | ||||
| } | ||||
|  | ||||
| let timeoutID: NodeJS.Timeout | undefined = undefined; | ||||
| let timeoutId: NodeJS.Timeout | undefined = undefined; | ||||
|  | ||||
| /** | ||||
|  * Debounce file change events to avoid rebuilding multiple times. | ||||
|  */ | ||||
| function handleFileChange() { | ||||
|   if (timeoutID !== undefined) { | ||||
|     clearTimeout(timeoutID); | ||||
|   if (timeoutId !== undefined) { | ||||
|     clearTimeout(timeoutId); | ||||
|   } | ||||
|   // eslint-disable-next-line @typescript-eslint/no-misused-promises | ||||
|   timeoutID = setTimeout(async () => { | ||||
|   timeoutId = setTimeout(async () => { | ||||
|     await rebuildAll(); | ||||
|     sendEventsToAll(); | ||||
|     timeoutID = undefined; | ||||
|     timeoutId = undefined; | ||||
|   }, 100); | ||||
| } | ||||
|  | ||||
| @@ -93,16 +74,15 @@ async function createServer() { | ||||
|       ignoreInitial: true, | ||||
|       ignored: [/node_modules/, /dist/, /docs/, /coverage/], | ||||
|     }) | ||||
|     // eslint-disable-next-line @typescript-eslint/no-misused-promises | ||||
|     .on('all', async (event, path) => { | ||||
|       // Ignore other events. | ||||
|       if (!['add', 'change'].includes(event)) { | ||||
|         return; | ||||
|       } | ||||
|       console.log(`${path} changed. Rebuilding...`); | ||||
|       if (path.endsWith('.langium')) { | ||||
|       if (/\.langium$/.test(path)) { | ||||
|         await generateLangium(); | ||||
|       } | ||||
|       console.log(`${path} changed. Rebuilding...`); | ||||
|       handleFileChange(); | ||||
|     }); | ||||
|  | ||||
| @@ -119,4 +99,4 @@ async function createServer() { | ||||
|   }); | ||||
| } | ||||
|  | ||||
| void createServer(); | ||||
| createServer(); | ||||
|   | ||||
| @@ -3,20 +3,20 @@ import { fileURLToPath } from 'url'; | ||||
| import type { BuildOptions } from 'esbuild'; | ||||
| import { readFileSync } from 'fs'; | ||||
| import jsonSchemaPlugin from './jsonSchemaPlugin.js'; | ||||
| import type { PackageOptions } from '../.build/common.js'; | ||||
| import { packageOptions } from '../.build/common.js'; | ||||
| import { jisonPlugin } from './jisonPlugin.js'; | ||||
|  | ||||
| const __dirname = fileURLToPath(new URL('.', import.meta.url)); | ||||
|  | ||||
| export interface MermaidBuildOptions extends BuildOptions { | ||||
| export interface MermaidBuildOptions { | ||||
|   minify: boolean; | ||||
|   core: boolean; | ||||
|   metafile: boolean; | ||||
|   format: 'esm' | 'iife'; | ||||
|   options: PackageOptions; | ||||
|   entryName: keyof typeof packageOptions; | ||||
| } | ||||
|  | ||||
| export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'> = { | ||||
| export const defaultOptions: Omit<MermaidBuildOptions, 'entryName'> = { | ||||
|   minify: false, | ||||
|   metafile: false, | ||||
|   core: false, | ||||
| @@ -52,16 +52,11 @@ const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOpt | ||||
| }; | ||||
|  | ||||
| export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { | ||||
|   const { | ||||
|     core, | ||||
|     metafile, | ||||
|     format, | ||||
|     minify, | ||||
|     options: { name, file, packageName }, | ||||
|   } = options; | ||||
|   const { core, entryName, metafile, format, minify } = options; | ||||
|   const external: string[] = ['require', 'fs', 'path']; | ||||
|   const { name, file, packageName } = packageOptions[entryName]; | ||||
|   const outFileName = getFileName(name, options); | ||||
|   const output: BuildOptions = buildOptions({ | ||||
|   let output: BuildOptions = buildOptions({ | ||||
|     absWorkingDir: resolve(__dirname, `../packages/${packageName}`), | ||||
|     entryPoints: { | ||||
|       [outFileName]: `src/${file}`, | ||||
|   | ||||
							
								
								
									
										1
									
								
								.eslintignore
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								.eslintignore
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| .gitignore | ||||
							
								
								
									
										190
									
								
								.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| module.exports = { | ||||
|   env: { | ||||
|     browser: true, | ||||
|     es6: true, | ||||
|     'jest/globals': true, | ||||
|     node: true, | ||||
|   }, | ||||
|   root: true, | ||||
|   parser: '@typescript-eslint/parser', | ||||
|   parserOptions: { | ||||
|     ecmaFeatures: { | ||||
|       experimentalObjectRestSpread: true, | ||||
|       jsx: true, | ||||
|     }, | ||||
|     tsconfigRootDir: __dirname, | ||||
|     sourceType: 'module', | ||||
|     ecmaVersion: 2022, | ||||
|     allowAutomaticSingleRunInference: true, | ||||
|     project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], | ||||
|     parser: '@typescript-eslint/parser', | ||||
|   }, | ||||
|   extends: [ | ||||
|     'eslint:recommended', | ||||
|     'plugin:@typescript-eslint/recommended', | ||||
|     'plugin:json/recommended', | ||||
|     'plugin:markdown/recommended-legacy', | ||||
|     'plugin:@cspell/recommended', | ||||
|     'prettier', | ||||
|   ], | ||||
|   plugins: [ | ||||
|     '@typescript-eslint', | ||||
|     'no-only-tests', | ||||
|     'html', | ||||
|     'jest', | ||||
|     'jsdoc', | ||||
|     'json', | ||||
|     '@cspell', | ||||
|     'lodash', | ||||
|     'unicorn', | ||||
|   ], | ||||
|   ignorePatterns: [ | ||||
|     // this file is automatically generated by `pnpm run --filter mermaid types:build-config` | ||||
|     'packages/mermaid/src/config.type.ts', | ||||
|   ], | ||||
|   rules: { | ||||
|     curly: 'error', | ||||
|     'no-console': 'error', | ||||
|     'no-prototype-builtins': 'off', | ||||
|     'no-unused-vars': 'off', | ||||
|     'cypress/no-async-tests': 'off', | ||||
|     '@typescript-eslint/consistent-type-imports': 'error', | ||||
|     '@typescript-eslint/no-explicit-any': 'warn', | ||||
|     '@typescript-eslint/no-floating-promises': 'error', | ||||
|     '@typescript-eslint/no-misused-promises': 'error', | ||||
|     '@typescript-eslint/no-unused-vars': 'warn', | ||||
|     '@typescript-eslint/consistent-type-definitions': 'error', | ||||
|     '@typescript-eslint/ban-ts-comment': [ | ||||
|       'error', | ||||
|       { | ||||
|         'ts-expect-error': 'allow-with-description', | ||||
|         'ts-ignore': 'allow-with-description', | ||||
|         'ts-nocheck': 'allow-with-description', | ||||
|         'ts-check': 'allow-with-description', | ||||
|         minimumDescriptionLength: 10, | ||||
|       }, | ||||
|     ], | ||||
|     '@typescript-eslint/naming-convention': [ | ||||
|       'error', | ||||
|       { | ||||
|         selector: 'typeLike', | ||||
|         format: ['PascalCase'], | ||||
|         custom: { | ||||
|           regex: '^I[A-Z]', | ||||
|           match: false, | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|     'json/*': ['error', 'allowComments'], | ||||
|     '@cspell/spellchecker': [ | ||||
|       'error', | ||||
|       { | ||||
|         checkIdentifiers: true, | ||||
|         checkStrings: true, | ||||
|         checkStringTemplates: true, | ||||
|       }, | ||||
|     ], | ||||
|     'no-empty': [ | ||||
|       'error', | ||||
|       { | ||||
|         allowEmptyCatch: true, | ||||
|       }, | ||||
|     ], | ||||
|     'no-only-tests/no-only-tests': 'error', | ||||
|     'lodash/import-scope': ['error', 'method'], | ||||
|     'unicorn/better-regex': 'error', | ||||
|     'unicorn/no-abusive-eslint-disable': 'error', | ||||
|     'unicorn/no-array-push-push': 'error', | ||||
|     'unicorn/no-for-loop': 'error', | ||||
|     'unicorn/no-instanceof-array': 'error', | ||||
|     'unicorn/no-typeof-undefined': 'error', | ||||
|     'unicorn/no-unnecessary-await': 'error', | ||||
|     'unicorn/no-unsafe-regex': 'warn', | ||||
|     'unicorn/no-useless-promise-resolve-reject': 'error', | ||||
|     'unicorn/prefer-array-find': 'error', | ||||
|     'unicorn/prefer-array-flat-map': 'error', | ||||
|     'unicorn/prefer-array-index-of': 'error', | ||||
|     'unicorn/prefer-array-some': 'error', | ||||
|     'unicorn/prefer-default-parameters': 'error', | ||||
|     'unicorn/prefer-includes': 'error', | ||||
|     'unicorn/prefer-negative-index': 'error', | ||||
|     'unicorn/prefer-object-from-entries': 'error', | ||||
|     'unicorn/prefer-string-starts-ends-with': 'error', | ||||
|     'unicorn/prefer-string-trim-start-end': 'error', | ||||
|     'unicorn/string-content': 'error', | ||||
|     'unicorn/prefer-spread': 'error', | ||||
|     'unicorn/no-lonely-if': 'error', | ||||
|   }, | ||||
|   overrides: [ | ||||
|     { | ||||
|       files: ['cypress/**', 'demos/**'], | ||||
|       rules: { | ||||
|         'no-console': 'off', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       files: ['*.{js,jsx,mjs,cjs}'], | ||||
|       extends: ['plugin:jsdoc/recommended'], | ||||
|       rules: { | ||||
|         'jsdoc/check-indentation': 'off', | ||||
|         'jsdoc/check-alignment': 'off', | ||||
|         'jsdoc/check-line-alignment': 'off', | ||||
|         'jsdoc/multiline-blocks': 'off', | ||||
|         'jsdoc/newline-after-description': 'off', | ||||
|         'jsdoc/tag-lines': 'off', | ||||
|         'jsdoc/require-param-description': 'off', | ||||
|         'jsdoc/require-param-type': 'off', | ||||
|         'jsdoc/require-returns': 'off', | ||||
|         'jsdoc/require-returns-description': 'off', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       files: ['*.{ts,tsx}'], | ||||
|       plugins: ['tsdoc'], | ||||
|       rules: { | ||||
|         'no-restricted-syntax': [ | ||||
|           'error', | ||||
|           { | ||||
|             selector: 'TSEnumDeclaration', | ||||
|             message: | ||||
|               'Prefer using TypeScript union types over TypeScript enum, since TypeScript enums have a bunch of issues, see https://dev.to/dvddpl/whats-the-problem-with-typescript-enums-2okj', | ||||
|           }, | ||||
|         ], | ||||
|         'tsdoc/syntax': 'error', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       files: ['*.spec.{ts,js}', 'cypress/**', 'demos/**', '**/docs/**'], | ||||
|       rules: { | ||||
|         'jsdoc/require-jsdoc': 'off', | ||||
|         '@typescript-eslint/no-unused-vars': 'off', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       files: ['*.spec.{ts,js}', 'tests/**', 'cypress/**/*.js'], | ||||
|       rules: { | ||||
|         '@cspell/spellchecker': [ | ||||
|           'error', | ||||
|           { | ||||
|             checkIdentifiers: false, | ||||
|             checkStrings: false, | ||||
|             checkStringTemplates: false, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       files: ['*.html', '*.md', '**/*.md/*'], | ||||
|       rules: { | ||||
|         'no-var': 'error', | ||||
|         'no-undef': 'off', | ||||
|         '@typescript-eslint/no-unused-vars': 'off', | ||||
|         '@typescript-eslint/no-floating-promises': 'off', | ||||
|         '@typescript-eslint/no-misused-promises': 'off', | ||||
|       }, | ||||
|       parserOptions: { | ||||
|         project: null, | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
| }; | ||||
							
								
								
									
										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 | ||||
|   | ||||
							
								
								
									
										8
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							| @@ -44,13 +44,7 @@ exclude = [ | ||||
| "https://chromewebstore.google.com", | ||||
|  | ||||
| # Drupal 403 | ||||
| "https://(www.)?drupal.org", | ||||
|  | ||||
| # Swimm returns 404, eventhough the link is valid | ||||
| "https://docs.swimm.io", | ||||
|  | ||||
| # Timeout | ||||
| "https://huehive.co" | ||||
| "https://www.drupal.org" | ||||
| ] | ||||
|  | ||||
| # Exclude all private IPs from checking. | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -15,4 +15,4 @@ Make sure you | ||||
| - [ ] :book: have read the [contribution guidelines](https://mermaid.js.org/community/contributing.html) | ||||
| - [ ] :computer: have added necessary unit/e2e tests. | ||||
| - [ ] :notebook: have added documentation. Make sure [`MERMAID_RELEASE_VERSION`](https://mermaid.js.org/community/contributing.html#update-documentation) is used for all new features. | ||||
| - [ ] :butterfly: If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. Changesets that add features should be `minor` and those that fix bugs should be `patch`. Please prefix changeset messages with `feat:`, `fix:`, or `chore:`. | ||||
| - [ ] :bookmark: targeted `develop` branch | ||||
|   | ||||
							
								
								
									
										36
									
								
								.github/release-drafter.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								.github/release-drafter.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| name-template: '$NEXT_PATCH_VERSION' | ||||
| tag-template: '$NEXT_PATCH_VERSION' | ||||
| categories: | ||||
|   - title: '🚨 **Breaking Changes**' | ||||
|     labels: | ||||
|       - 'Breaking Change' | ||||
|   - title: '🚀 Features' | ||||
|     labels: | ||||
|       - 'Type: Enhancement' | ||||
|       - 'feature' # deprecated, new PRs shouldn't have this | ||||
|   - title: '🐛 Bug Fixes' | ||||
|     labels: | ||||
|       - 'Type: Bug / Error' | ||||
|       - 'fix' # deprecated, new PRs shouldn't have this | ||||
|   - title: '🧰 Maintenance' | ||||
|     labels: | ||||
|       - 'Type: Other' | ||||
|       - 'chore' # deprecated, new PRs shouldn't have this | ||||
|   - title: '⚡️ Performance' | ||||
|     labels: | ||||
|       - 'Type: Performance' | ||||
|   - title: '📚 Documentation' | ||||
|     labels: | ||||
|       - 'Area: Documentation' | ||||
| change-template: '- $TITLE (#$NUMBER) @$AUTHOR' | ||||
| sort-by: title | ||||
| sort-direction: ascending | ||||
| exclude-labels: | ||||
|   - 'Skip changelog' | ||||
| no-changes-template: 'This release contains minor changes and bugfixes.' | ||||
| template: | | ||||
|   # Release Notes | ||||
|  | ||||
|   $CHANGES | ||||
|  | ||||
|   🎉 **Thanks to all contributors helping with this release!** 🎉 | ||||
							
								
								
									
										45
									
								
								.github/workflows/autofix.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								.github/workflows/autofix.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,45 +0,0 @@ | ||||
| name: autofix.ci # needed to securely identify the workflow | ||||
|  | ||||
| on: | ||||
|   pull_request: | ||||
|     branches-ignore: | ||||
|       - 'renovate/**' | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| jobs: | ||||
|   autofix: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
|       - name: Install Packages | ||||
|         run: | | ||||
|           pnpm install --frozen-lockfile | ||||
|         env: | ||||
|           CYPRESS_CACHE_FOLDER: .cache/Cypress | ||||
|  | ||||
|       - name: Fix Linting | ||||
|         shell: bash | ||||
|         run: pnpm -w run lint:fix | ||||
|  | ||||
|       - name: Sync `./src/config.type.ts` with `./src/schemas/config.schema.yaml` | ||||
|         shell: bash | ||||
|         run: pnpm run --filter mermaid types:build-config | ||||
|  | ||||
|       - name: Build Docs | ||||
|         working-directory: ./packages/mermaid | ||||
|         run: pnpm run docs:build | ||||
|  | ||||
|       - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef # main | ||||
							
								
								
									
										8
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,8 +8,6 @@ on: | ||||
|   pull_request: | ||||
|   merge_group: | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| @@ -18,12 +16,12 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|   | ||||
							
								
								
									
										49
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| name: Build | ||||
|  | ||||
| on: | ||||
|   push: {} | ||||
|   merge_group: | ||||
|   pull_request: | ||||
|     types: | ||||
|       - opened | ||||
|       - synchronize | ||||
|       - ready_for_review | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   build-mermaid: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
|       - name: Install Packages | ||||
|         run: | | ||||
|           pnpm install --frozen-lockfile | ||||
|         env: | ||||
|           CYPRESS_CACHE_FOLDER: .cache/Cypress | ||||
|  | ||||
|       - name: Run Build | ||||
|         run: pnpm run build | ||||
|  | ||||
|       - name: Upload Mermaid Build as Artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: mermaid-build | ||||
|           path: packages/mermaid/dist | ||||
|  | ||||
|       - name: Upload Mermaid Mindmap Build as Artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: mermaid-mindmap-build | ||||
|           path: packages/mermaid-mindmap/dist | ||||
							
								
								
									
										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@v4 | ||||
|  | ||||
|       - name: Check for difference in README.md and docs/README.md | ||||
|         run: | | ||||
|   | ||||
							
								
								
									
										26
									
								
								.github/workflows/checks.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.github/workflows/checks.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| on: | ||||
|   push: | ||||
|   merge_group: | ||||
|   pull_request: | ||||
|     types: | ||||
|       - opened | ||||
|       - synchronize | ||||
|       - ready_for_review | ||||
|  | ||||
| name: Static analysis on Test files | ||||
|  | ||||
| jobs: | ||||
|   check-tests: | ||||
|     runs-on: ubuntu-latest | ||||
|     name: check tests | ||||
|     if: github.repository_owner == 'mermaid-js' | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|         with: | ||||
|           fetch-depth: 0 | ||||
|       - uses: testomatio/check-tests@stable | ||||
|         with: | ||||
|           framework: cypress | ||||
|           tests: './cypress/e2e/**/**.spec.js' | ||||
|           token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           has-tests-label: true | ||||
							
								
								
									
										11
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							| @@ -11,9 +11,6 @@ on: | ||||
|       - synchronize | ||||
|       - ready_for_review | ||||
|  | ||||
| permissions: # added using https://github.com/step-security/secure-repo | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   analyze: | ||||
|     name: Analyze | ||||
| @@ -32,11 +29,11 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       # Initializes the CodeQL tools for scanning. | ||||
|       - name: Initialize CodeQL | ||||
|         uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 | ||||
|         uses: github/codeql-action/init@v3 | ||||
|         with: | ||||
|           config-file: ./.github/codeql/codeql-config.yml | ||||
|           languages: ${{ matrix.language }} | ||||
| @@ -48,7 +45,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@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 | ||||
|         uses: github/codeql-action/autobuild@v3 | ||||
|  | ||||
|       # ℹ️ 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 +59,4 @@ jobs: | ||||
|       #   make release | ||||
|  | ||||
|       - name: Perform CodeQL Analysis | ||||
|         uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 | ||||
|         uses: github/codeql-action/analyze@v3 | ||||
|   | ||||
							
								
								
									
										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@v4 | ||||
|       - name: 'Dependency Review' | ||||
|         uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0 | ||||
|         uses: actions/dependency-review-action@v4 | ||||
|   | ||||
							
								
								
									
										10
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							| @@ -11,8 +11,6 @@ on: | ||||
|         default: master | ||||
|         description: 'Parent branch to use for PRs' | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| @@ -32,13 +30,13 @@ jobs: | ||||
|         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@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
| @@ -54,7 +52,7 @@ jobs: | ||||
|           APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com' | ||||
|  | ||||
|       - name: Cypress run | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         uses: cypress-io/github-action@v4 | ||||
|         id: cypress | ||||
|         with: | ||||
|           start: pnpm run dev | ||||
|   | ||||
							
								
								
									
										58
									
								
								.github/workflows/e2e-timings.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								.github/workflows/e2e-timings.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,58 +0,0 @@ | ||||
| name: E2E - Generate Timings | ||||
|  | ||||
| on: | ||||
|   # run this workflow every night at 3am | ||||
|   schedule: | ||||
|     - cron: '28 3 * * *' | ||||
|   # or when the user triggers it from GitHub Actions page | ||||
|   workflow_dispatch: | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: | ||||
|   contents: write | ||||
|  | ||||
| jobs: | ||||
|   timings: | ||||
|     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: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
|       - name: Install dependencies | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         with: | ||||
|           runTests: false | ||||
|       - name: Cypress run | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         id: cypress | ||||
|         with: | ||||
|           install: false | ||||
|           start: pnpm run dev:coverage | ||||
|           wait-on: 'http://localhost:9000' | ||||
|           browser: chrome | ||||
|           publish-summary: false | ||||
|         env: | ||||
|           VITEST_COVERAGE: true | ||||
|           CYPRESS_COMMIT: ${{ github.sha }} | ||||
|           SPLIT: 1 | ||||
|           SPLIT_INDEX: 0 | ||||
|           SPLIT_FILE: 'cypress/timings.json' | ||||
|       - name: Commit changes | ||||
|         uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 | ||||
|         with: | ||||
|           add: 'cypress/timings.json' | ||||
|           author_name: 'github-actions[bot]' | ||||
|           author_email: '41898282+github-actions[bot]@users.noreply.github.com' | ||||
|           message: 'chore: update E2E timings' | ||||
|       - name: Create Pull Request | ||||
|         uses: peter-evans/create-pull-request@v5 | ||||
|         with: | ||||
|           branch: release-promotion | ||||
|           title: Update E2E Timings | ||||
							
								
								
									
										59
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							| @@ -2,15 +2,11 @@ name: E2E | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - develop | ||||
|       - master | ||||
|       - release/** | ||||
|     branches-ignore: | ||||
|       - 'gh-readonly-queue/**' | ||||
|   pull_request: | ||||
|   merge_group: | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| @@ -28,8 +24,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 +31,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@v4 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
|       - name: Cache snapshots | ||||
|         id: cache-snapshot | ||||
|         uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 | ||||
|         uses: actions/cache@v4 | ||||
|         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@v4 | ||||
|         with: | ||||
|           ref: ${{ env.targetHash }} | ||||
|  | ||||
|       - name: Install dependencies | ||||
|         if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         uses: cypress-io/github-action@v6 | ||||
|         with: | ||||
|           # just perform install | ||||
|           runTests: false | ||||
| @@ -80,28 +75,28 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         containers: [1, 2, 3, 4, 5] | ||||
|         containers: [1, 2, 3, 4] | ||||
|     steps: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         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@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 | ||||
|         uses: actions/cache/restore@v4 | ||||
|         with: | ||||
|           path: ./cypress/snapshots | ||||
|           key: ${{ runner.os }}-snapshots-${{ env.targetHash }} | ||||
|  | ||||
|       - name: Install dependencies | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         uses: cypress-io/github-action@v6 | ||||
|         with: | ||||
|           runTests: false | ||||
|  | ||||
| @@ -117,8 +112,11 @@ jobs: | ||||
|       # Install NPM dependencies, cache them correctly | ||||
|       # and run all Cypress tests | ||||
|       - name: Cypress run | ||||
|         uses: cypress-io/github-action@18a6541367f4580a515371905f499a27a44e8dbe # v6.7.12 | ||||
|         uses: cypress-io/github-action@v6 | ||||
|         id: cypress | ||||
|         # If CYPRESS_RECORD_KEY is set, run in parallel on all containers | ||||
|         # Otherwise (e.g. if running from fork), we run on a single container only | ||||
|         if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }} | ||||
|         with: | ||||
|           install: false | ||||
|           start: pnpm run dev:coverage | ||||
| @@ -126,20 +124,19 @@ 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 != '' }} | ||||
|           parallel: ${{ 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_COMMIT: ${{ github.sha }} | ||||
|           CYPRESS_RECORD_KEY: ${{ env.RUN_VISUAL_TEST == 'true' && secrets.CYPRESS_RECORD_KEY || ''}} | ||||
|           SPLIT: ${{ strategy.job-total }} | ||||
|           SPLIT_INDEX: ${{ strategy.job-index }} | ||||
|           SPLIT_FILE: 'cypress/timings.json' | ||||
|           CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} | ||||
|           VITEST_COVERAGE: true | ||||
|           CYPRESS_COMMIT: ${{ github.sha }} | ||||
|           ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} | ||||
|           ARGOS_PARALLEL: ${{ secrets.CYPRESS_RECORD_KEY != '' }} | ||||
|           ARGOS_PARALLEL_TOTAL: 4 | ||||
|           ARGOS_PARALLEL_INDEX: ${{ matrix.containers }} | ||||
|  | ||||
|       - name: Upload Coverage to Codecov | ||||
|         uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 | ||||
|         uses: codecov/codecov-action@v4 | ||||
|         # 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: | ||||
|   | ||||
							
								
								
									
										8
									
								
								.github/workflows/issue-triage.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/issue-triage.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,17 +4,11 @@ on: | ||||
|   issues: | ||||
|     types: [opened] | ||||
|  | ||||
| permissions: # added using https://github.com/step-security/secure-repo | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   triage: | ||||
|     permissions: | ||||
|       issues: write # for andymckay/labeler to label issues | ||||
|       pull-requests: write # for andymckay/labeler to label PRs | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4 | ||||
|       - uses: andymckay/labeler@1.0.4 | ||||
|         with: | ||||
|           repo-token: '${{ secrets.GITHUB_TOKEN }}' | ||||
|           add-labels: 'Status: Triage' | ||||
|   | ||||
							
								
								
									
										9
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							| @@ -19,9 +19,6 @@ on: | ||||
|     # * is a special character in YAML so you have to quote this string | ||||
|     - cron: '30 8 * * *' | ||||
|  | ||||
| permissions: # added using https://github.com/step-security/secure-repo | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   link-checker: | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -29,17 +26,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@v4 | ||||
|  | ||||
|       - name: Restore lychee cache | ||||
|         uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 | ||||
|         uses: actions/cache@v4 | ||||
|         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@v1.9.3 | ||||
|         with: | ||||
|           args: >- | ||||
|             --config .github/lychee.toml | ||||
|   | ||||
							
								
								
									
										35
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,32 +4,26 @@ on: | ||||
|   push: | ||||
|   merge_group: | ||||
|   pull_request: | ||||
|     types: | ||||
|       - opened | ||||
|       - synchronize | ||||
|       - ready_for_review | ||||
|   workflow_dispatch: | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: | ||||
|   contents: write | ||||
|  | ||||
| jobs: | ||||
|   docker-lint: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|  | ||||
|       - uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0 | ||||
|         with: | ||||
|           verbose: true | ||||
|   lint: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
| @@ -89,9 +83,14 @@ jobs: | ||||
|         continue-on-error: ${{ github.event_name == 'push' }} | ||||
|         run: pnpm run docs:verify | ||||
|  | ||||
|       - uses: testomatio/check-tests@0ea638fcec1820cf2e7b9854fdbdd04128a55bd4 # stable | ||||
|       - name: Rebuild Docs | ||||
|         if: ${{ steps.verifyDocs.outcome == 'failure' && github.event_name == 'push' }} | ||||
|         working-directory: ./packages/mermaid | ||||
|         run: pnpm run docs:build | ||||
|  | ||||
|       - name: Commit changes | ||||
|         uses: EndBug/add-and-commit@v9 | ||||
|         if: ${{ steps.verifyDocs.outcome == 'failure' && github.event_name == 'push' }} | ||||
|         with: | ||||
|           framework: cypress | ||||
|           tests: './cypress/e2e/**/**.spec.js' | ||||
|           token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           has-tests-label: true | ||||
|           message: 'Update docs' | ||||
|           add: 'docs/*' | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/pr-labeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/pr-labeler.yml
									
									
									
									
										vendored
									
									
								
							| @@ -22,7 +22,7 @@ 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@v6 | ||||
|         with: | ||||
|           config-name: pr-labeler.yml | ||||
|           disable-autolabeler: false | ||||
|   | ||||
							
								
								
									
										12
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.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@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
| @@ -37,13 +37,13 @@ jobs: | ||||
|         run: pnpm install --frozen-lockfile | ||||
|  | ||||
|       - name: Setup Pages | ||||
|         uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 | ||||
|         uses: actions/configure-pages@v4 | ||||
|  | ||||
|       - name: Run Build | ||||
|         run: pnpm --filter mermaid run docs:build:vitepress | ||||
|  | ||||
|       - name: Upload artifact | ||||
|         uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 | ||||
|         uses: actions/upload-pages-artifact@v3 | ||||
|         with: | ||||
|           path: packages/mermaid/src/vitepress/.vitepress/dist | ||||
|  | ||||
| @@ -56,4 +56,4 @@ jobs: | ||||
|     steps: | ||||
|       - name: Deploy to GitHub Pages | ||||
|         id: deployment | ||||
|         uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 | ||||
|         uses: actions/deploy-pages@v4 | ||||
|   | ||||
							
								
								
									
										23
									
								
								.github/workflows/release-draft.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.github/workflows/release-draft.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| name: Draft Release | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   draft-release: | ||||
|     runs-on: ubuntu-latest | ||||
|     permissions: | ||||
|       contents: write # write permission is required to create a GitHub release | ||||
|       pull-requests: read # required to read PR titles/labels | ||||
|     steps: | ||||
|       - name: Draft Release | ||||
|         uses: release-drafter/release-drafter@v6 | ||||
|         with: | ||||
|           disable-autolabeler: true | ||||
|         env: | ||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
| @@ -9,14 +9,14 @@ jobs: | ||||
|   publish-preview: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|       - uses: actions/checkout@v4 | ||||
|         with: | ||||
|           fetch-depth: 0 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
| @@ -28,7 +28,7 @@ jobs: | ||||
|           CYPRESS_CACHE_FOLDER: .cache/Cypress | ||||
|  | ||||
|       - name: Install Json | ||||
|         run: npm i json@11.0.0 --global | ||||
|         run: npm i json --global | ||||
|  | ||||
|       - name: Publish | ||||
|         working-directory: ./packages/mermaid | ||||
|   | ||||
							
								
								
									
										43
									
								
								.github/workflows/release-preview.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/release-preview.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| name: Preview release | ||||
|  | ||||
| on: | ||||
|   pull_request: | ||||
|     branches: [develop] | ||||
|     types: [opened, synchronize, labeled, ready_for_review] | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.event.number }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|   actions: write | ||||
|  | ||||
| jobs: | ||||
|   preview: | ||||
|     if: ${{ github.repository_owner == 'mermaid-js' }} | ||||
|     runs-on: ubuntu-latest | ||||
|     permissions: | ||||
|       contents: read | ||||
|       id-token: write | ||||
|       issues: write | ||||
|       pull-requests: write | ||||
|     name: Publish preview release | ||||
|     timeout-minutes: 5 | ||||
|     steps: | ||||
|       - name: Checkout Repo | ||||
|         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
|       - name: Install Packages | ||||
|         run: pnpm install --frozen-lockfile | ||||
|  | ||||
|       - name: Publish packages | ||||
|         run: pnpx pkg-pr-new publish --pnpm './packages/*' | ||||
							
								
								
									
										47
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| name: Publish release | ||||
|  | ||||
| on: | ||||
|   release: | ||||
|     types: [published] | ||||
|  | ||||
| jobs: | ||||
|   publish: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|       - uses: fregante/setup-git-user@v2 | ||||
|  | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
|       - name: Install Packages | ||||
|         run: | | ||||
|           pnpm install --frozen-lockfile | ||||
|           npm i json --global | ||||
|         env: | ||||
|           CYPRESS_CACHE_FOLDER: .cache/Cypress | ||||
|  | ||||
|       - name: Prepare release | ||||
|         run: | | ||||
|           VERSION=${GITHUB_REF:10} | ||||
|           echo "Preparing release $VERSION" | ||||
|           git checkout -t origin/release/$VERSION | ||||
|           npm version --no-git-tag-version --allow-same-version $VERSION | ||||
|           git add package.json | ||||
|           git commit -nm "Bump version $VERSION" | ||||
|           git checkout -t origin/master | ||||
|           git merge -m "Release $VERSION" --no-ff release/$VERSION | ||||
|           git push --no-verify | ||||
|  | ||||
|       - name: Publish | ||||
|         run: | | ||||
|           npm set //registry.npmjs.org/:_authToken $NPM_TOKEN | ||||
|           npm publish | ||||
|         env: | ||||
|           NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||
							
								
								
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,46 +0,0 @@ | ||||
| name: Release | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|  | ||||
| concurrency: ${{ github.workflow }}-${{ github.ref }} | ||||
|  | ||||
| permissions: # added using https://github.com/step-security/secure-repo | ||||
|   contents: read | ||||
|  | ||||
| jobs: | ||||
|   release: | ||||
|     if: github.repository == 'mermaid-js/mermaid' | ||||
|     permissions: | ||||
|       contents: write # to create release (changesets/action) | ||||
|       id-token: write # OpenID Connect token needed for provenance | ||||
|       pull-requests: write # to create pull request (changesets/action) | ||||
|     name: Release | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout Repo | ||||
|         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
|  | ||||
|       - name: Install Packages | ||||
|         run: pnpm install --frozen-lockfile | ||||
|  | ||||
|       - name: Create Release Pull Request or Publish to npm | ||||
|         id: changesets | ||||
|         uses: changesets/action@c8bada60c408975afd1a20b3db81d6eee6789308 # v1.4.9 | ||||
|         with: | ||||
|           version: pnpm changeset:version | ||||
|           publish: pnpm changeset:publish | ||||
|         env: | ||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|           NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||
|           NPM_CONFIG_PROVENANCE: true | ||||
							
								
								
									
										37
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,37 +0,0 @@ | ||||
| name: Scorecard supply-chain security | ||||
| on: | ||||
|   branch_protection_rule: | ||||
|   push: | ||||
|     branches: | ||||
|       - develop | ||||
|   schedule: | ||||
|     - cron: 29 15 * * 0 | ||||
| permissions: read-all | ||||
| jobs: | ||||
|   analysis: | ||||
|     name: Scorecard analysis | ||||
|     permissions: | ||||
|       id-token: write | ||||
|       security-events: write | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||||
|         with: | ||||
|           persist-credentials: false | ||||
|       - name: Run analysis | ||||
|         uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 | ||||
|         with: | ||||
|           results_file: results.sarif | ||||
|           results_format: sarif | ||||
|           publish_results: true | ||||
|       - name: Upload artifact | ||||
|         uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||||
|         with: | ||||
|           name: SARIF file | ||||
|           path: results.sarif | ||||
|           retention-days: 5 | ||||
|       - name: Upload to code-scanning | ||||
|         uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 | ||||
|         with: | ||||
|           sarif_file: results.sarif | ||||
							
								
								
									
										12
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.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@v4 | ||||
|  | ||||
|       - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|         # uses version from "packageManager" field in package.json | ||||
|  | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 | ||||
|         uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           cache: pnpm | ||||
|           node-version-file: '.node-version' | ||||
| @@ -38,12 +38,8 @@ jobs: | ||||
|         run: | | ||||
|           pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts --coverage | ||||
|  | ||||
|       - name: Verify out-of-tree build with TypeScript | ||||
|         run: | | ||||
|           pnpm test:check:tsc | ||||
|  | ||||
|       - name: Upload Coverage to Codecov | ||||
|         uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 | ||||
|         uses: codecov/codecov-action@v4 | ||||
|         # Run step only pushes to develop and pull_requests | ||||
|         if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }} | ||||
|         with: | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/unlock-reopened-issues.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/unlock-reopened-issues.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,6 +8,6 @@ jobs: | ||||
|   triage: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: Dunning-Kruger/unlock-issues@b06b7f7e5c3f2eaa1c6d5d89f40930e4d6d9699e # v1 | ||||
|       - uses: Dunning-Kruger/unlock-issues@v1 | ||||
|         with: | ||||
|           repo-token: '${{ secrets.GITHUB_TOKEN }}' | ||||
|   | ||||
							
								
								
									
										8
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,18 +8,18 @@ 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@v4 | ||||
|       - uses: pnpm/action-setup@v2 | ||||
|       - run: npx update-browserslist-db@latest | ||||
|       - name: Commit changes | ||||
|         uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 | ||||
|         uses: EndBug/add-and-commit@v9 | ||||
|         with: | ||||
|           author_name: ${{ github.actor }} | ||||
|           author_email: ${{ github.actor }}@users.noreply.github.com | ||||
|           message: 'chore: update browsers list' | ||||
|           push: false | ||||
|       - name: Create Pull Request | ||||
|         uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6 | ||||
|         uses: peter-evans/create-pull-request@v6 | ||||
|         with: | ||||
|           branch: update-browserslist | ||||
|           title: Update Browserslist | ||||
|   | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -35,7 +35,7 @@ cypress/snapshots/ | ||||
| .tsbuildinfo | ||||
| tsconfig.tsbuildinfo | ||||
|  | ||||
| #knsv*.html | ||||
| knsv*.html | ||||
| local*.html | ||||
| stats/ | ||||
|  | ||||
|   | ||||
| @@ -1,2 +0,0 @@ | ||||
| ignored: | ||||
|   - DL3002 # TODO: Last USER should not be root | ||||
| @@ -1,2 +1,4 @@ | ||||
| #!/usr/bin/env sh | ||||
| #!/bin/sh | ||||
| . "$(dirname "$0")/_/husky.sh" | ||||
|  | ||||
| NODE_OPTIONS="--max_old_space_size=8192" pnpm run pre-commit | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| 22.14.0 | ||||
| 20.12.2 | ||||
|   | ||||
| @@ -16,5 +16,3 @@ generated/ | ||||
| # Ignore the files creates in /demos/dev except for example.html | ||||
| demos/dev/** | ||||
| !/demos/dev/example.html | ||||
| # TODO: Lots of errors to fix | ||||
| cypress/platform/state-refactor.html | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import type { InlineConfig } from 'vite'; | ||||
| import { build, type PluginOption } from 'vite'; | ||||
| import { build, InlineConfig, type PluginOption } from 'vite'; | ||||
| import { resolve } from 'path'; | ||||
| import { fileURLToPath } from 'url'; | ||||
| import jisonPlugin from './jisonPlugin.js'; | ||||
| @@ -47,10 +46,9 @@ interface BuildOptions { | ||||
|  | ||||
| export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => { | ||||
|   const external: (string | RegExp)[] = ['require', 'fs', 'path']; | ||||
|   // eslint-disable-next-line no-console | ||||
|   console.log(entryName, packageOptions[entryName]); | ||||
|   const { name, file, packageName } = packageOptions[entryName]; | ||||
|   const output: OutputOptions = [ | ||||
|   let output: OutputOptions = [ | ||||
|     { | ||||
|       name, | ||||
|       format: 'esm', | ||||
| @@ -85,6 +83,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) | ||||
|     plugins: [ | ||||
|       jisonPlugin(), | ||||
|       jsonSchemaPlugin(), // handles `.schema.yaml` files | ||||
|       // @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite | ||||
|       typescript({ compilerOptions: { declaration: false } }), | ||||
|       istanbul({ | ||||
|         exclude: ['node_modules', 'test/', '__mocks__', 'generated'], | ||||
| @@ -122,10 +121,10 @@ await generateLangium(); | ||||
|  | ||||
| if (watch) { | ||||
|   await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); | ||||
|   void build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); | ||||
|   build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); | ||||
|   if (!mermaidOnly) { | ||||
|     void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); | ||||
|     void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' })); | ||||
|     build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); | ||||
|     build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' })); | ||||
|   } | ||||
| } else if (visualize) { | ||||
|   await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import type { PluginOption } from 'vite'; | ||||
| import { PluginOption } from 'vite'; | ||||
| import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -23,9 +23,8 @@ async function createServer() { | ||||
|   app.use(express.static('cypress/platform')); | ||||
|  | ||||
|   app.listen(9000, () => { | ||||
|     // eslint-disable-next-line no-console | ||||
|     console.log(`Listening on http://localhost:9000`); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| void createServer(); | ||||
| createServer(); | ||||
|   | ||||
							
								
								
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,13 +1,2 @@ | ||||
| FROM node:22.12.0-alpine3.19@sha256:40dc4b415c17b85bea9be05314b4a753f45a4e1716bb31c01182e6c53d51a654 | ||||
|  | ||||
| USER 0:0 | ||||
|  | ||||
| RUN corepack enable \ | ||||
|     && corepack enable pnpm | ||||
|  | ||||
| RUN apk add --no-cache git~=2.43.4 \ | ||||
|     && git config --add --system safe.directory /mermaid | ||||
|  | ||||
| ENV NODE_OPTIONS="--max_old_space_size=8192" | ||||
|  | ||||
| EXPOSE 9000 3333 | ||||
| FROM node:20.12.2-alpine3.19 AS base | ||||
| RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh - | ||||
|   | ||||
							
								
								
									
										45
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								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,10 +33,9 @@ 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) | ||||
| [](https://argos-ci.com) | ||||
|  | ||||
| <img src="./img/header.png" alt="" /> | ||||
|  | ||||
| @@ -83,10 +82,6 @@ You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include- | ||||
|  | ||||
| For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](https://mermaid.js.org/intro/getting-started.html), [Usage](https://mermaid.js.org/config/usage.html) and [Tutorials](https://mermaid.js.org/ecosystem/tutorials.html). | ||||
|  | ||||
| Our PR Visual Regression Testing is powered by [Argos](https://argos-ci.com/?utm_source=mermaid&utm_campaign=oss) with their generous Open Source plan. It makes the process of reviewing PRs with visual changes a breeze. | ||||
|  | ||||
| [](https://argos-ci.com?utm_source=mermaid&utm_campaign=oss) | ||||
|  | ||||
| In our release process we rely heavily on visual regression tests using [applitools](https://applitools.com/). Applitools is a great service which has been easy to use and integrate with our tests. | ||||
|  | ||||
| <a href="https://applitools.com/"> | ||||
| @@ -95,10 +90,6 @@ In our release process we rely heavily on visual regression tests using [applito | ||||
|  | ||||
| <!-- </Main description> --> | ||||
|  | ||||
| ## Mermaid AI Bot | ||||
|  | ||||
| [Mermaid](https://codeparrot.ai/oracle?owner=mermaid-js&repo=mermaid) Bot will help you understand this repository better. You can ask for code examples, installation guide, debugging help and much more. | ||||
|  | ||||
| ## Examples | ||||
|  | ||||
| **The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid.js.org/intro/syntax-reference.html).** | ||||
| @@ -257,34 +248,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>] | ||||
|  | ||||
| ``` | ||||
| @@ -467,7 +430,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="" /> | ||||
| @@ -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),没有你们,就没有这个项目的今天!_ | ||||
|  | ||||
| --- | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| import { defineConfig } from 'cypress'; | ||||
| import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; | ||||
| import coverage from '@cypress/code-coverage/task'; | ||||
| import eyesPlugin from '@applitools/eyes-cypress'; | ||||
| import { registerArgosTask } from '@argos-ci/cypress/task'; | ||||
| import coverage from '@cypress/code-coverage/task.js'; | ||||
| import { defineConfig } from 'cypress'; | ||||
| import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin.js'; | ||||
| import cypressSplit from 'cypress-split'; | ||||
|  | ||||
| export default eyesPlugin( | ||||
|   defineConfig({ | ||||
| @@ -14,7 +13,6 @@ export default eyesPlugin( | ||||
|       specPattern: 'cypress/integration/**/*.{js,ts}', | ||||
|       setupNodeEvents(on, config) { | ||||
|         coverage(on, config); | ||||
|         cypressSplit(on, config); | ||||
|         on('before:browser:launch', (browser, launchOptions) => { | ||||
|           if (browser.name === 'chrome' && browser.isHeadless) { | ||||
|             launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1'); | ||||
| @@ -23,10 +21,12 @@ 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); | ||||
|           registerArgosTask(on, config, { | ||||
|             token: 'fc3a35cf5200db928d65b2047861582d9444032b', | ||||
|           }); | ||||
|         } else { | ||||
|           addMatchImageSnapshotPlugin(on, config); | ||||
|         } | ||||
|   | ||||
| @@ -29,14 +29,13 @@ export const mermaidUrl = ( | ||||
|   options: CypressMermaidConfig, | ||||
|   api: boolean | ||||
| ): string => { | ||||
|   options.handDrawnSeed = 1; | ||||
|   const codeObject: CodeObject = { | ||||
|     code: graphStr, | ||||
|     mermaid: options, | ||||
|   }; | ||||
|   const objStr: string = JSON.stringify(codeObject); | ||||
|   let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`; | ||||
|   if (api && typeof graphStr === 'string') { | ||||
|   if (api) { | ||||
|     url = `http://localhost:9000/xss.html?graph=${graphStr}`; | ||||
|   } | ||||
|  | ||||
| @@ -55,15 +54,16 @@ export const imgSnapshotTest = ( | ||||
| ): void => { | ||||
|   const options: CypressMermaidConfig = { | ||||
|     ..._options, | ||||
|     fontFamily: _options.fontFamily ?? 'courier', | ||||
|     fontFamily: _options.fontFamily || 'courier', | ||||
|     // @ts-ignore TODO: Fix type of fontSize | ||||
|     fontSize: _options.fontSize ?? '16px', | ||||
|     fontSize: _options.fontSize || '16px', | ||||
|     sequence: { | ||||
|       ...(_options.sequence ?? {}), | ||||
|       ...(_options.sequence || {}), | ||||
|       actorFontFamily: 'courier', | ||||
|       noteFontFamily: _options.sequence?.noteFontFamily | ||||
|         ? _options.sequence.noteFontFamily | ||||
|         : 'courier', | ||||
|       noteFontFamily: | ||||
|         _options.sequence && _options.sequence.noteFontFamily | ||||
|           ? _options.sequence.noteFontFamily | ||||
|           : 'courier', | ||||
|       messageFontFamily: 'courier', | ||||
|     }, | ||||
|   }; | ||||
| @@ -74,7 +74,7 @@ export const imgSnapshotTest = ( | ||||
|  | ||||
| export const urlSnapshotTest = ( | ||||
|   url: string, | ||||
|   options: CypressMermaidConfig = {}, | ||||
|   options: CypressMermaidConfig, | ||||
|   _api = false, | ||||
|   validation?: any | ||||
| ): void => { | ||||
| @@ -95,7 +95,7 @@ export const openURLAndVerifyRendering = ( | ||||
|   options: CypressMermaidConfig, | ||||
|   validation?: any | ||||
| ): void => { | ||||
|   const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); | ||||
|   const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); | ||||
|  | ||||
|   cy.visit(url); | ||||
|   cy.window().should('have.property', 'rendered', true); | ||||
| @@ -125,17 +125,8 @@ export const verifyScreenshot = (name: string): void => { | ||||
|     cy.log(`Closing eyes ${Cypress.spec.name}`); | ||||
|     cy.eyesClose(); | ||||
|   } else if (useArgos) { | ||||
|     cy.argosScreenshot(name, { | ||||
|       threshold: 0.01, | ||||
|     }); | ||||
|     cy.argosScreenshot(name); | ||||
|   } else { | ||||
|     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) | ||||
|   ); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										14
									
								
								cypress/integration/other/flowchart-elk.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								cypress/integration/other/flowchart-elk.spec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('Flowchart elk', () => { | ||||
|   it('should use dagre as fallback', () => { | ||||
|     urlSnapshotTest('http://localhost:9000/flow-elk.html', { | ||||
|       name: 'flow-elk fallback to dagre', | ||||
|     }); | ||||
|   }); | ||||
|   it('should allow overriding with external package', () => { | ||||
|     urlSnapshotTest('http://localhost:9000/flow-elk.html?elk=true', { | ||||
|       name: 'flow-elk overriding dagre with elk', | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -11,27 +11,6 @@ describe('Git Graph diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should render subgraphs with title margins and edge labels', () => { | ||||
|     imgSnapshotTest( | ||||
|       `flowchart LR | ||||
|  | ||||
|           subgraph TOP | ||||
|               direction TB | ||||
|               subgraph B1 | ||||
|                   direction RL | ||||
|                   i1 --lb1-->f1 | ||||
|               end | ||||
|               subgraph B2 | ||||
|                   direction BT | ||||
|                   i2 --lb2-->f2 | ||||
|               end | ||||
|           end | ||||
|           A --lb3--> TOP --lb4--> B | ||||
|           B1 --lb5--> B2 | ||||
|         `, | ||||
|       { flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } } } | ||||
|     ); | ||||
|   }); | ||||
|   // it(`ultraFastTest`, function () { | ||||
|   //   // Navigate to the url we want to test | ||||
|   //   // ⭐️ Note to see visual bugs, run the test using the above URL for the 1st run. | ||||
|   | ||||
| @@ -1,233 +0,0 @@ | ||||
| import { imgSnapshotTest, urlSnapshotTest } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe.skip('architecture diagram', () => { | ||||
|   it('should render a simple architecture diagram with groups', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 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 | ||||
|                 service gateway(internet)[Gateway]  | ||||
|  | ||||
|                 db L--R server | ||||
|                 disk1 T--B server | ||||
|                 disk2 T--B db | ||||
|                 server T--B gateway | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with groups within groups', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 group api[API] | ||||
|                 group public[Public API] in api | ||||
|                 group private[Private API] in api | ||||
|          | ||||
|                 service serv1(server)[Server] in public | ||||
|          | ||||
|                 service serv2(server)[Server] in private | ||||
|                 service db(database)[Database] in private | ||||
|          | ||||
|                 service gateway(internet)[Gateway] in api | ||||
|          | ||||
|                 serv1 B--T serv2 | ||||
|                 serv2 L--R db | ||||
|                 serv1 L--R gateway | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with the fallback icon', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 service unknown(iconnamedoesntexist)[Unknown Icon] | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with split directioning', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 service db(database)[Database] | ||||
|                 service s3(disk)[Storage] | ||||
|                 service serv1(server)[Server 1] | ||||
|                 service serv2(server)[Server 2] | ||||
|                 service disk(disk)[Disk] | ||||
|          | ||||
|                 db L--R s3 | ||||
|                 serv1 L--T s3 | ||||
|                 serv2 L--B s3 | ||||
|                 serv1 T--B disk | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with directional arrows', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 service servC(server)[Server 1] | ||||
|                 service servL(server)[Server 2] | ||||
|                 service servR(server)[Server 3] | ||||
|                 service servT(server)[Server 4] | ||||
|                 service servB(server)[Server 5] | ||||
|          | ||||
|                 servC (L--R) servL | ||||
|                 servC (R--L) servR | ||||
|                 servC (T--B) servT | ||||
|                 servC (B--T) servB | ||||
|          | ||||
|                 servL (T--L) servT | ||||
|                 servL (B--L) servB | ||||
|                 servR (T--R) servT | ||||
|                 servR (B--R) servB | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with group edges', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 group left_group(cloud)[Left] | ||||
|                 group right_group(cloud)[Right] | ||||
|                 group top_group(cloud)[Top] | ||||
|                 group bottom_group(cloud)[Bottom] | ||||
|                 group center_group(cloud)[Center] | ||||
|          | ||||
|                 service left_disk(disk)[Disk] in left_group | ||||
|                 service right_disk(disk)[Disk] in right_group | ||||
|                 service top_disk(disk)[Disk] in top_group | ||||
|                 service bottom_disk(disk)[Disk] in bottom_group | ||||
|                 service center_disk(disk)[Disk] in center_group | ||||
|          | ||||
|                 left_disk{group} (R--L) center_disk{group} | ||||
|                 right_disk{group} (L--R) center_disk{group} | ||||
|                 top_disk{group} (B--T) center_disk{group} | ||||
|                 bottom_disk{group} (T--B) center_disk{group} | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with edge labels', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 service servC(server)[Server 1] | ||||
|                 service servL(server)[Server 2] | ||||
|                 service servR(server)[Server 3] | ||||
|                 service servT(server)[Server 4] | ||||
|                 service servB(server)[Server 5] | ||||
|          | ||||
|                 servC L-[Label]-R servL | ||||
|                 servC R-[Label]-L servR | ||||
|                 servC T-[Label]-B servT | ||||
|                 servC B-[Label]-T servB | ||||
|          | ||||
|                 servL T-[Label]-L servT | ||||
|                 servL B-[Label]-L servB | ||||
|                 servR T-[Label]-R servT | ||||
|                 servR B-[Label]-R servB | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with simple junction edges', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 service left_disk(disk)[Disk] | ||||
|                 service top_disk(disk)[Disk] | ||||
|                 service bottom_disk(disk)[Disk] | ||||
|                 service top_gateway(internet)[Gateway] | ||||
|                 service bottom_gateway(internet)[Gateway] | ||||
|                 junction juncC | ||||
|                 junction juncR | ||||
|          | ||||
|                 left_disk R--L juncC | ||||
|                 top_disk B--T juncC | ||||
|                 bottom_disk T--B juncC | ||||
|                 juncC R--L juncR | ||||
|                 top_gateway B--T juncR | ||||
|                 bottom_gateway T--B juncR | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|   it('should render an architecture diagram with complex junction edges', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|                 group left | ||||
|                 group right | ||||
|                 service left_disk(disk)[Disk] in left | ||||
|                 service top_disk(disk)[Disk] in left | ||||
|                 service bottom_disk(disk)[Disk] in left | ||||
|                 service top_gateway(internet)[Gateway] in right | ||||
|                 service bottom_gateway(internet)[Gateway] in right | ||||
|                 junction juncC in left | ||||
|                 junction juncR in right | ||||
|          | ||||
|                 left_disk R--L juncC | ||||
|                 top_disk B--T juncC | ||||
|                 bottom_disk T--B juncC | ||||
|          | ||||
|          | ||||
|                 top_gateway (B--T juncR | ||||
|                 bottom_gateway (T--B juncR | ||||
|          | ||||
|                 juncC{group} R--L) juncR{group} | ||||
|             ` | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('should render an architecture diagram with a resonable height', () => { | ||||
|     imgSnapshotTest( | ||||
|       `architecture-beta | ||||
|               group federated(cloud)[Federated Environment] | ||||
|                   service server1(server)[System] in federated | ||||
|                   service edge(server)[Edge Device] in federated | ||||
|                   server1:R -- L:edge | ||||
|  | ||||
|               group on_prem(cloud)[Hub] | ||||
|                   service firewall(server)[Firewall Device] in on_prem | ||||
|                   service server(server)[Server] in on_prem | ||||
|                   firewall:R -- L:server | ||||
|  | ||||
|                   service db1(database)[db1] in on_prem | ||||
|                   service db2(database)[db2] in on_prem | ||||
|                   service db3(database)[db3] in on_prem | ||||
|                   service db4(database)[db4] in on_prem | ||||
|                   service db5(database)[db5] in on_prem | ||||
|                   service db6(database)[db6] in on_prem | ||||
|  | ||||
|                   junction mid in on_prem | ||||
|                   server:B -- T:mid | ||||
|  | ||||
|                   junction 1Leftofmid in on_prem | ||||
|                   1Leftofmid:R -- L:mid | ||||
|                   1Leftofmid:B -- T:db1 | ||||
|  | ||||
|                   junction 2Leftofmid in on_prem | ||||
|                   2Leftofmid:R -- L:1Leftofmid | ||||
|                   2Leftofmid:B -- T:db2 | ||||
|  | ||||
|                   junction 3Leftofmid in on_prem | ||||
|                   3Leftofmid:R -- L:2Leftofmid | ||||
|                   3Leftofmid:B -- T:db3 | ||||
|  | ||||
|                   junction 1RightOfMid in on_prem | ||||
|                   mid:R -- L:1RightOfMid | ||||
|                   1RightOfMid:B -- T:db4 | ||||
|                    | ||||
|                   junction 2RightOfMid in on_prem | ||||
|                   1RightOfMid:R -- L:2RightOfMid | ||||
|                   2RightOfMid:B -- T:db5         | ||||
|                    | ||||
|                   junction 3RightOfMid in on_prem | ||||
|                   2RightOfMid:R -- L:3RightOfMid | ||||
|                   3RightOfMid:B -- T:db6          | ||||
|  | ||||
|                   edge:R -- L:firewall | ||||
|       ` | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| // Skipped as the layout is not deterministic, and causes issues in E2E tests. | ||||
| describe.skip('architecture - external', () => { | ||||
|   it('should allow adding external icons', () => { | ||||
|     urlSnapshotTest('http://localhost:9000/architecture-external.html'); | ||||
|   }); | ||||
| }); | ||||
| @@ -236,7 +236,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL17: width alignment - blocks shold be equal in width', () => { | ||||
|   it('BL16: width alignment - blocks shold be equal in width', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A("This is the text") | ||||
| @@ -247,7 +247,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL18: block types 1 - square, rounded and circle', () => { | ||||
|   it('BL17: block types 1 - square, rounded and circle', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A["square"] | ||||
| @@ -258,7 +258,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL19: block types 2 - odd, diamond and hexagon', () => { | ||||
|   it('BL18: block types 2 - odd, diamond and hexagon', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A>"rect_left_inv_arrow"] | ||||
| @@ -269,7 +269,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL20: block types 3 - stadium', () => { | ||||
|   it('BL19: block types 3 - stadium', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A(["stadium"]) | ||||
| @@ -278,7 +278,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => { | ||||
|   it('BL20: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A[/"lean right"/] | ||||
| @@ -290,7 +290,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL22: block types 1 - square, rounded and circle', () => { | ||||
|   it('BL21: block types 1 - square, rounded and circle', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|     A["square"] | ||||
| @@ -301,7 +301,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL23: sizing - it should be possible to make a block wider', () => { | ||||
|   it('BL22: sizing - it should be possible to make a block wider', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|       A("rounded"):2 | ||||
| @@ -312,7 +312,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL24: sizing - it should be possible to make a composite block wider', () => { | ||||
|   it('BL23: sizing - it should be possible to make a composite block wider', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|       block:2 | ||||
| @@ -324,7 +324,7 @@ describe('Block diagram', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL25: block in the middle with space on each side', () => { | ||||
|   it('BL24: block in the middle with space on each side', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|         columns 3 | ||||
| @@ -335,7 +335,7 @@ describe('Block diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('BL26: space and an edge', () => { | ||||
|   it('BL25: space and an edge', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|   columns 5 | ||||
| @@ -345,7 +345,7 @@ describe('Block diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('BL27: block sizes for regular blocks', () => { | ||||
|   it('BL26: block sizes for regular blocks', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|   columns 3 | ||||
| @@ -354,7 +354,7 @@ describe('Block diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('BL28: composite block with a set width - f should use the available space', () => { | ||||
|   it('BL27: composite block with a set width - f should use the available space', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|   columns 3 | ||||
| @@ -363,12 +363,11 @@ describe('Block diagram', () => { | ||||
|       f | ||||
|   end | ||||
|   g | ||||
|   `, | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('BL29: composite block with a set width - f and g should split the available space', () => { | ||||
|   it('BL23: composite block with a set width - f and g should split the available space', () => { | ||||
|     imgSnapshotTest( | ||||
|       `block-beta | ||||
|   columns 3 | ||||
| @@ -380,7 +379,7 @@ describe('Block diagram', () => { | ||||
|   h | ||||
|   i | ||||
|   j | ||||
|   `, | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('C4 diagram', () => { | ||||
|   it('C4.1 should render a simple C4Context diagram', () => { | ||||
|   it('should render a simple C4Context diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       C4Context | ||||
| @@ -31,7 +31,7 @@ describe('C4 diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('C4.2 should render a simple C4Container diagram', () => { | ||||
|   it('should render a simple C4Container diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       C4Container | ||||
| @@ -50,7 +50,7 @@ describe('C4 diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('C4.3 should render a simple C4Component diagram', () => { | ||||
|   it('should render a simple C4Component diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       C4Component | ||||
| @@ -68,7 +68,7 @@ describe('C4 diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('C4.4 should render a simple C4Dynamic diagram', () => { | ||||
|   it('should render a simple C4Dynamic diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       C4Dynamic | ||||
| @@ -91,7 +91,7 @@ describe('C4 diagram', () => { | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('C4.5 should render a simple C4Deployment diagram', () => { | ||||
|   it('should render a simple C4Deployment diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       C4Deployment | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -76,7 +76,7 @@ describe('Class diagram V2', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('2.1 should render a simple class diagram with different visibilities', () => { | ||||
|   it('should render a simple class diagram with different visibilities', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|     classDiagram-v2 | ||||
| @@ -93,7 +93,7 @@ describe('Class diagram V2', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('3: should render multiple class diagrams', () => { | ||||
|   it('should render multiple class diagrams', () => { | ||||
|     imgSnapshotTest( | ||||
|       [ | ||||
|         ` | ||||
| @@ -581,63 +581,4 @@ class C13["With Città foreign language"] | ||||
|       { logLevel: 1, flowchart: { htmlLabels: false } } | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('renders a class diagram with a generic class in a namespace', () => { | ||||
|     const diagramDefinition = ` | ||||
|       classDiagram-v2 | ||||
|       namespace Company.Project.Module { | ||||
|         class GenericClass~T~ { | ||||
|           +addItem(item: T) | ||||
|           +getItem() T | ||||
|         } | ||||
|       } | ||||
|     `; | ||||
|  | ||||
|     imgSnapshotTest(diagramDefinition); | ||||
|   }); | ||||
|  | ||||
|   it('renders a class diagram with nested namespaces and relationships', () => { | ||||
|     const diagramDefinition = ` | ||||
|       classDiagram-v2 | ||||
|       namespace Company.Project.Module.SubModule { | ||||
|         class Report { | ||||
|           +generatePDF(data: List) | ||||
|           +generateCSV(data: List) | ||||
|         } | ||||
|       } | ||||
|       namespace Company.Project.Module { | ||||
|         class Admin { | ||||
|           +generateReport() | ||||
|         } | ||||
|       } | ||||
|       Admin --> Report : generates | ||||
|     `; | ||||
|  | ||||
|     imgSnapshotTest(diagramDefinition); | ||||
|   }); | ||||
|  | ||||
|   it('renders a class diagram with multiple classes and relationships in a namespace', () => { | ||||
|     const diagramDefinition = ` | ||||
|       classDiagram-v2 | ||||
|       namespace Company.Project.Module { | ||||
|         class User { | ||||
|           +login(username: String, password: String) | ||||
|           +logout() | ||||
|         } | ||||
|         class Admin { | ||||
|           +addUser(user: User) | ||||
|           +removeUser(user: User) | ||||
|           +generateReport() | ||||
|         } | ||||
|         class Report { | ||||
|           +generatePDF(reportData: List) | ||||
|           +generateCSV(reportData: List) | ||||
|         } | ||||
|       } | ||||
|       Admin --> User : manages | ||||
|       Admin --> Report : generates | ||||
|     `; | ||||
|  | ||||
|     imgSnapshotTest(diagramDefinition); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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'); | ||||
|     }); | ||||
| @@ -321,37 +321,4 @@ ORDER ||--|{ LINE-ITEM : contains | ||||
|       { logLevel: 1 } | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('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" | ||||
|       `, | ||||
|       { logLevel: 1 } | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import { imgSnapshotTest } from '../../helpers/util'; | ||||
| describe('Error Diagrams', () => { | ||||
|   beforeEach(() => { | ||||
|     cy.on('uncaught:exception', (err) => { | ||||
|       expect(err.message).to.include('error'); | ||||
|       expect(err.message).to.include('Parse error'); | ||||
|       // return false to prevent the error from | ||||
|       // failing this test | ||||
|       return false; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { imgSnapshotTest, renderGraph, verifyNumber } from '../../helpers/util.ts'; | ||||
| import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('Flowchart ELK', () => { | ||||
| describe.skip('Flowchart ELK', () => { | ||||
|   it('1-elk: should render a simple flowchart', () => { | ||||
|     imgSnapshotTest( | ||||
|       `flowchart-elk TD | ||||
| @@ -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); | ||||
|       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); | ||||
|       expect(width).to.be.within(230 * 0.95, 230 * 1.05); | ||||
|       expect(svg).to.not.have.attr('style'); | ||||
|     }); | ||||
|   }); | ||||
| @@ -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 | ||||
| @@ -837,216 +837,6 @@ subgraph "\`**Two**\`" | ||||
|   in the hat\`") -- "\`1o **ipa**\`" --> d("The dog in the hog") | ||||
| end | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|       it('Sub graphs', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
|  | ||||
| flowchart LR | ||||
|  subgraph subgraph_ko6czgs5u["Untitled subgraph"] | ||||
|         D["Option 1"] | ||||
|   end | ||||
|     C{"Evaluate"} -- One --> D | ||||
|     C -- Two --> E(("Option 2")) | ||||
|     D --> E | ||||
|       A["A"] | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|       it('6080: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
| flowchart LR | ||||
|  subgraph s1["Untitled subgraph"] | ||||
|         n1["Evaluate"] | ||||
|         n2["Option 1"] | ||||
|         n3["Option 2"] | ||||
|         n4["fa:fa-car Option 3"] | ||||
|   end | ||||
|  subgraph s2["Untitled subgraph"] | ||||
|         n5["Evaluate"] | ||||
|         n6["Option 1"] | ||||
|         n7["Option 2"] | ||||
|         n8["fa:fa-car Option 3"] | ||||
|   end | ||||
|     A["Start"] -- Some text --> B("Continue") | ||||
|     B --> C{"Evaluate"} | ||||
|     C -- One --> D["Option 1"] | ||||
|     C -- Two --> E["Option 2"] | ||||
|     C -- Three --> F["fa:fa-car Option 3"] | ||||
|     n1 -- One --> n2 | ||||
|     n1 -- Two --> n3 | ||||
|     n1 -- Three --> n4 | ||||
|     n5 -- One --> n6 | ||||
|     n5 -- Two --> n7 | ||||
|     n5 -- Three --> n8 | ||||
|     n1@{ shape: diam} | ||||
|     n2@{ shape: rect} | ||||
|     n3@{ shape: rect} | ||||
|     n4@{ shape: rect} | ||||
|     n5@{ shape: diam} | ||||
|     n6@{ shape: rect} | ||||
|     n7@{ shape: rect} | ||||
|     n8@{ shape: rect} | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|  | ||||
|       it('6088-1: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
|       flowchart LR | ||||
|       subgraph S2 | ||||
|       subgraph s1["APA"] | ||||
|       D{"Use the editor"} | ||||
|       end | ||||
|  | ||||
|  | ||||
|       D -- Mermaid js --> I{"fa:fa-code Text"} | ||||
|             D --> I | ||||
|             D --> I | ||||
|  | ||||
|       end | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|  | ||||
|       it('6088-2: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
|       flowchart LR | ||||
|       a | ||||
|       subgraph s0["APA"] | ||||
|       subgraph s8["APA"] | ||||
|       subgraph s1["APA"] | ||||
|         D{"X"} | ||||
|         E[Q] | ||||
|       end | ||||
|       subgraph s3["BAPA"] | ||||
|         F[Q] | ||||
|         I | ||||
|       end | ||||
|             D --> I | ||||
|             D --> I | ||||
|             D --> I | ||||
|  | ||||
|       I{"X"} | ||||
|       end | ||||
|       end | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|  | ||||
|       it('6088-3: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
|       flowchart LR | ||||
|       a | ||||
|         D{"Use the editor"} | ||||
|  | ||||
|       D -- Mermaid js --> I{"fa:fa-code Text"} | ||||
|       D-->I | ||||
|       D-->I | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|  | ||||
|       it('6088-4: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
| flowchart LR | ||||
|  subgraph s1["Untitled subgraph"] | ||||
|         n1["Evaluate"] | ||||
|         n2["Option 1"] | ||||
|         n3["Option 2"] | ||||
|         n4["fa:fa-car Option 3"] | ||||
|   end | ||||
|  subgraph s2["Untitled subgraph"] | ||||
|         n5["Evaluate"] | ||||
|         n6["Option 1"] | ||||
|         n7["Option 2"] | ||||
|         n8["fa:fa-car Option 3"] | ||||
|   end | ||||
|     A["Start"] -- Some text --> B("Continue") | ||||
|     B --> C{"Evaluate"} | ||||
|     C -- One --> D["Option 1"] | ||||
|     C -- Two --> E["Option 2"] | ||||
|     C -- Three --> F["fa:fa-car Option 3"] | ||||
|     n1 -- One --> n2 | ||||
|     n1 -- Two --> n3 | ||||
|     n1 -- Three --> n4 | ||||
|     n5 -- One --> n6 | ||||
|     n5 -- Two --> n7 | ||||
|     n5 -- Three --> n8 | ||||
|     n1@{ shape: diam} | ||||
|     n2@{ shape: rect} | ||||
|     n3@{ shape: rect} | ||||
|     n4@{ shape: rect} | ||||
|     n5@{ shape: diam} | ||||
|     n6@{ shape: rect} | ||||
|     n7@{ shape: rect} | ||||
|     n8@{ shape: rect} | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|  | ||||
|       it('6088-5: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
| flowchart LR | ||||
|     A{A} --> B & C | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
|       }); | ||||
|       it('6088-6: should handle diamond shape intersections', () => { | ||||
|         imgSnapshotTest( | ||||
|           `--- | ||||
| config: | ||||
|   layout: elk | ||||
| --- | ||||
| flowchart LR | ||||
|     A{A} --> B & C | ||||
|     subgraph "subbe" | ||||
|       A | ||||
|     end | ||||
|  | ||||
| `, | ||||
|           { flowchart: { titleTopMargin: 0 } } | ||||
|         ); | ||||
| @@ -1065,7 +855,7 @@ describe('Title and arrow styling #4813', () => { | ||||
|       flowchart LR | ||||
|       A-->B | ||||
|       A-->C`, | ||||
|       { layout: 'elk' } | ||||
|       { flowchart: { defaultRenderer: 'elk' } } | ||||
|     ); | ||||
|     cy.get('svg').should((svg) => { | ||||
|       const title = svg[0].querySelector('text'); | ||||
| @@ -1081,14 +871,15 @@ describe('Title and arrow styling #4813', () => { | ||||
|       B-.-oC | ||||
|       C==xD | ||||
|       D ~~~ A`, | ||||
|       { layout: 'elk' } | ||||
|       { flowchart: { defaultRenderer: 'elk' } } | ||||
|     ); | ||||
|     cy.get('svg').should((svg) => { | ||||
|       const edges = svg[0].querySelectorAll('.edges path'); | ||||
|       expect(edges[0].getAttribute('class')).to.contain('edge-pattern-solid'); | ||||
|       expect(edges[1].getAttribute('class')).to.contain('edge-pattern-dotted'); | ||||
|       expect(edges[2].getAttribute('class')).to.contain('edge-thickness-thick'); | ||||
|       expect(edges[3].getAttribute('class')).to.contain('edge-thickness-invisible'); | ||||
|       console.log(edges); | ||||
|       expect(edges[0]).to.have.attr('pattern', 'solid'); | ||||
|       expect(edges[1]).to.have.attr('pattern', 'dotted'); | ||||
|       expect(edges[2]).to.have.css('stroke-width', '3.5px'); | ||||
|       expect(edges[3]).to.have.css('stroke-width', '1.5px'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,142 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util.ts'; | ||||
|  | ||||
| const aliasSet1 = ['process', 'rect', 'proc', 'rectangle'] as const; | ||||
|  | ||||
| const aliasSet2 = ['event', 'rounded'] as const; | ||||
|  | ||||
| const aliasSet3 = ['stadium', 'pill', 'terminal'] as const; | ||||
|  | ||||
| const aliasSet4 = ['fr-rect', 'subproc', 'subprocess', 'framed-rectangle', 'subroutine'] as const; | ||||
|  | ||||
| const aliasSet5 = ['db', 'database', 'cylinder', 'cyl'] as const; | ||||
|  | ||||
| const aliasSet6 = ['diam', 'decision', 'diamond'] as const; | ||||
|  | ||||
| const aliasSet7 = ['hex', 'hexagon', 'prepare'] as const; | ||||
|  | ||||
| const aliasSet8 = ['lean-r', 'lean-right', 'in-out'] as const; | ||||
|  | ||||
| const aliasSet9 = ['lean-l', 'lean-left', 'out-in'] as const; | ||||
|  | ||||
| const aliasSet10 = ['trap-b', 'trapezoid-bottom', 'priority'] as const; | ||||
|  | ||||
| const aliasSet11 = ['trap-t', 'trapezoid-top', 'manual'] as const; | ||||
|  | ||||
| const aliasSet12 = ['dbl-circ', 'double-circle'] as const; | ||||
|  | ||||
| const aliasSet13 = ['notched-rectangle', 'card', 'notch-rect'] as const; | ||||
|  | ||||
| const aliasSet14 = [ | ||||
|   'lin-rect', | ||||
|   'lined-rectangle', | ||||
|   'lin-proc', | ||||
|   'lined-process', | ||||
|   'shaded-process', | ||||
| ] as const; | ||||
|  | ||||
| const aliasSet15 = ['sm-circ', 'small-circle', 'start'] as const; | ||||
|  | ||||
| const aliasSet16 = ['fr-circ', 'framed-circle', 'stop'] as const; | ||||
|  | ||||
| const aliasSet17 = ['fork', 'join'] as const; | ||||
| // brace-r', 'braces' | ||||
| const aliasSet18 = ['comment', 'brace-l'] as const; | ||||
|  | ||||
| const aliasSet19 = ['bolt', 'com-link', 'lightning-bolt'] as const; | ||||
|  | ||||
| const aliasSet20 = ['doc', 'document'] as const; | ||||
|  | ||||
| const aliasSet21 = ['delay', 'half-rounded-rectangle'] as const; | ||||
|  | ||||
| const aliasSet22 = ['h-cyl', 'das', 'horizontal-cylinder'] as const; | ||||
|  | ||||
| const aliasSet23 = ['lin-cyl', 'disk', 'lined-cylinder'] as const; | ||||
|  | ||||
| const aliasSet24 = ['curv-trap', 'display', 'curved-trapezoid'] as const; | ||||
|  | ||||
| const aliasSet25 = ['div-rect', 'div-proc', 'divided-rectangle', 'divided-process'] as const; | ||||
|  | ||||
| const aliasSet26 = ['extract', 'tri', 'triangle'] as const; | ||||
|  | ||||
| const aliasSet27 = ['win-pane', 'internal-storage', 'window-pane'] as const; | ||||
|  | ||||
| const aliasSet28 = ['f-circ', 'junction', 'filled-circle'] as const; | ||||
|  | ||||
| const aliasSet29 = ['lin-doc', 'lined-document'] as const; | ||||
|  | ||||
| const aliasSet30 = ['notch-pent', 'loop-limit', 'notched-pentagon'] as const; | ||||
|  | ||||
| const aliasSet31 = ['flip-tri', 'manual-file', 'flipped-triangle'] as const; | ||||
|  | ||||
| const aliasSet32 = ['sl-rect', 'manual-input', 'sloped-rectangle'] as const; | ||||
|  | ||||
| const aliasSet33 = ['docs', 'documents', 'st-doc', 'stacked-document'] as const; | ||||
|  | ||||
| const aliasSet34 = ['procs', 'processes', 'st-rect', 'stacked-rectangle'] as const; | ||||
|  | ||||
| const aliasSet35 = ['flag', 'paper-tape'] as const; | ||||
|  | ||||
| const aliasSet36 = ['bow-rect', 'stored-data', 'bow-tie-rectangle'] as const; | ||||
|  | ||||
| const aliasSet37 = ['cross-circ', 'summary', 'crossed-circle'] as const; | ||||
|  | ||||
| const aliasSet38 = ['tag-doc', 'tagged-document'] as const; | ||||
|  | ||||
| const aliasSet39 = ['tag-rect', 'tag-proc', 'tagged-rectangle', 'tagged-process'] as const; | ||||
|  | ||||
| const aliasSet40 = ['collate', 'hourglass'] as const; | ||||
|  | ||||
| // Aggregate all alias sets into a single array | ||||
| const aliasSets = [ | ||||
|   aliasSet1, | ||||
|   aliasSet2, | ||||
|   aliasSet3, | ||||
|   aliasSet4, | ||||
|   aliasSet5, | ||||
|   aliasSet6, | ||||
|   aliasSet7, | ||||
|   aliasSet8, | ||||
|   aliasSet9, | ||||
|   aliasSet10, | ||||
|   aliasSet11, | ||||
|   aliasSet12, | ||||
|   aliasSet13, | ||||
|   aliasSet14, | ||||
|   aliasSet15, | ||||
|   aliasSet16, | ||||
|   aliasSet17, | ||||
|   aliasSet18, | ||||
|   aliasSet19, | ||||
|   aliasSet20, | ||||
|   aliasSet21, | ||||
|   aliasSet22, | ||||
|   aliasSet23, | ||||
|   aliasSet24, | ||||
|   aliasSet25, | ||||
|   aliasSet26, | ||||
|   aliasSet27, | ||||
|   aliasSet28, | ||||
|   aliasSet29, | ||||
|   aliasSet30, | ||||
|   aliasSet31, | ||||
|   aliasSet32, | ||||
|   aliasSet33, | ||||
|   aliasSet34, | ||||
|   aliasSet35, | ||||
|   aliasSet36, | ||||
|   aliasSet37, | ||||
|   aliasSet38, | ||||
|   aliasSet39, | ||||
| ] as const; | ||||
|  | ||||
| aliasSets.forEach((aliasSet) => { | ||||
|   describe(`Test ${aliasSet.join(',')} `, () => { | ||||
|     it(`All ${aliasSet.join(',')} should render same shape`, () => { | ||||
|       let flowchartCode = `flowchart \n`; | ||||
|       aliasSet.forEach((alias, index) => { | ||||
|         flowchartCode += ` n${index}@{ shape: ${alias}, label: "${alias}" }\n`; | ||||
|       }); | ||||
|       imgSnapshotTest(flowchartCode); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -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(417 * 0.95, 417 * 1.05); | ||||
|       expect(maxWidthValue).to.be.within(290 * 0.95 - 1, 290 * 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(417 * 0.95, 417 * 1.05); | ||||
|       expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05); | ||||
|       expect(svg).to.not.have.attr('style'); | ||||
|     }); | ||||
|   }); | ||||
| @@ -786,7 +786,7 @@ A ~~~ B | ||||
|       `--- | ||||
|       title: Subgraph nodeSpacing and rankSpacing example | ||||
|       config: | ||||
|         flowchart: | ||||
|         flowchart:  | ||||
|           nodeSpacing: 250 | ||||
|           rankSpacing: 250 | ||||
|       --- | ||||
| @@ -1047,69 +1047,7 @@ end | ||||
|           A --lb3--> TOP --lb4--> B | ||||
|           B1 --lb5--> B2 | ||||
|         `, | ||||
|         { | ||||
|           flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } }, | ||||
|         } | ||||
|       ); | ||||
|     }); | ||||
|     it('Should render self-loops', () => { | ||||
|       imgSnapshotTest( | ||||
|         `flowchart | ||||
|           A --> A | ||||
|           subgraph B | ||||
|             B1 --> B1 | ||||
|           end | ||||
|           subgraph C | ||||
|             subgraph C1 | ||||
|               C2 --> C2 | ||||
|               subgraph D | ||||
|                 D1 --> D1 | ||||
|               end | ||||
|               D --> D | ||||
|             end | ||||
|             C1 --> C1 | ||||
|           end | ||||
|         `, | ||||
|         { | ||||
|           flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } }, | ||||
|         } | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('New @ sytax for node metadata edge cases', () => { | ||||
|     it('should be possible to use @  syntax to add labels on multi nodes', () => { | ||||
|       imgSnapshotTest( | ||||
|         `flowchart TB | ||||
|        n2["label for n2"] &   n4@{ label: "labe for n4"}   & n5@{ label: "labe for n5"} | ||||
|         `, | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('should be possible to use @  syntax to add labels with trail spaces and &', () => { | ||||
|       imgSnapshotTest( | ||||
|         `flowchart TB | ||||
|        n2["label for n2"] &   n4@{ label: "labe for n4"}   & n5@{ label: "labe for n5"}    | ||||
|         `, | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('should be possible to use @  syntax to add labels with trail spaces', () => { | ||||
|       imgSnapshotTest( | ||||
|         `flowchart TB | ||||
|        n2["label for n2"] | ||||
|        n4@{ label: "labe for n4"} | ||||
|        n5@{ label: "labe for n5"}   | ||||
|         `, | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('should be possible to use @  syntax to add labels with trail spaces and edge/link', () => { | ||||
|       imgSnapshotTest( | ||||
|         `flowchart TD | ||||
|     A["A"] --> B["for B"] &    C@{ label: "for c"} & E@{label : "for E"}   | ||||
|     D@{label: "for D"}      | ||||
|         `, | ||||
|         {} | ||||
|         { flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } } } | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   | ||||
| @@ -733,7 +733,7 @@ describe('Graph', () => { | ||||
|   }); | ||||
|   it('38: should render a flowchart when useMaxWidth is true (default)', () => { | ||||
|     renderGraph( | ||||
|       `flowchart TD | ||||
|       `graph TD | ||||
|       A[Christmas] -->|Get money| B(Go shopping) | ||||
|       B --> C{Let me think} | ||||
|       C -->|One| D[Laptop] | ||||
| @@ -751,7 +751,7 @@ describe('Graph', () => { | ||||
|       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(446 * 0.9, 446 * 1.1); | ||||
|       expect(maxWidthValue).to.be.within(300 * 0.9, 300 * 1.1); | ||||
|     }); | ||||
|   }); | ||||
|   it('39: should render a flowchart when useMaxWidth is false', () => { | ||||
| @@ -770,7 +770,7 @@ describe('Graph', () => { | ||||
|       const width = parseFloat(svg.attr('width')); | ||||
|       // use within because the absolute value can be slightly different depending on the environment ±10% | ||||
|       // expect(height).to.be.within(446 * 0.95, 446 * 1.05); | ||||
|       expect(width).to.be.within(446 * 0.9, 446 * 1.1); | ||||
|       expect(width).to.be.within(300 * 0.9, 300 * 1.1); | ||||
|       expect(svg).to.not.have.attr('style'); | ||||
|     }); | ||||
|   }); | ||||
| @@ -895,7 +895,7 @@ graph TD | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       graph TD | ||||
|         classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff | ||||
|         classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff  | ||||
|         hello --> default | ||||
|       `, | ||||
|       { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } | ||||
| @@ -905,33 +905,13 @@ graph TD | ||||
|   it('67: should be able to style default node independently', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       flowchart TD | ||||
|     flowchart TD | ||||
|       classDef default fill:#a34 | ||||
|       hello --> default | ||||
|  | ||||
|       style default stroke:#000,stroke-width:4px | ||||
|     `, | ||||
|       { | ||||
|         flowchart: { htmlLabels: true }, | ||||
|         securityLevel: 'loose', | ||||
|       } | ||||
|     ); | ||||
|   }); | ||||
|   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', | ||||
|       } | ||||
|       { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -1532,41 +1532,5 @@ gitGraph TB: | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('75: should render a gitGraph with multiple tags on a merge commit on bottom-to-top orientation', () => { | ||||
|       imgSnapshotTest( | ||||
|         `gitGraph BT: | ||||
|         commit id: "ZERO" | ||||
|         branch develop | ||||
|         commit id:"A" | ||||
|         checkout main | ||||
|         commit id:"ONE" | ||||
|         checkout develop | ||||
|         commit id:"B" | ||||
|         checkout main | ||||
|         merge develop id:"Release 1.0" type:HIGHLIGHT tag: "SAML v2.0" tag: "OpenID v1.1" | ||||
|         commit id:"TWO" | ||||
|         checkout develop | ||||
|         commit id:"C"`, | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   it('76: should render a gitGraph with multiple tags on a merge commit on left-to-right orientation', () => { | ||||
|     imgSnapshotTest( | ||||
|       `gitGraph | ||||
|     commit id: "ZERO" | ||||
|     branch develop | ||||
|     commit id:"A" | ||||
|     checkout main | ||||
|     commit id:"ONE" | ||||
|     checkout develop | ||||
|     commit id:"B" | ||||
|     checkout main | ||||
|     merge develop id:"Release 1.0" type:HIGHLIGHT tag: "SAML v2.0" tag: "OpenID v1.1" | ||||
|     commit id:"TWO" | ||||
|     checkout develop | ||||
|     commit id:"C"`, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -1,143 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util'; | ||||
|  | ||||
| const looks = ['classic', 'handDrawn'] as const; | ||||
| const directions = [ | ||||
|   'TB', | ||||
|   //'BT', | ||||
|   'LR', | ||||
|   //  'RL' | ||||
| ] as const; | ||||
| const forms = [undefined, 'square', 'circle', 'rounded'] as const; | ||||
| const labelPos = [undefined, 't', 'b'] as const; | ||||
|  | ||||
| looks.forEach((look) => { | ||||
|   directions.forEach((direction) => { | ||||
|     forms.forEach((form) => { | ||||
|       labelPos.forEach((pos) => { | ||||
|         describe(`Test iconShape in ${form ? `${form} form,` : ''} ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => { | ||||
|           it(`without label`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|  | ||||
|           it(`with label`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'This is a label for icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|  | ||||
|           it(`with very long label`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'This is a very very very very very long long long label for icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|  | ||||
|           it(`with markdown htmlLabels:true`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'This is **bold** </br>and <strong>strong</strong> for icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|  | ||||
|           it(`with markdown htmlLabels:false`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'This is **bold** </br>and <strong>strong</strong> for icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             imgSnapshotTest(flowchartCode, { | ||||
|               look, | ||||
|               htmlLabels: false, | ||||
|               flowchart: { htmlLabels: false }, | ||||
|             }); | ||||
|           }); | ||||
|  | ||||
|           it(`with styles`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'new icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             flowchartCode += `  style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|  | ||||
|           it(`with classDef`, () => { | ||||
|             let flowchartCode = `flowchart ${direction}\n`; | ||||
|             flowchartCode += `  classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; | ||||
|             flowchartCode += `  nA --> nAA@{ icon: 'fa:bell', label: 'new icon shape'`; | ||||
|             if (form) { | ||||
|               flowchartCode += `, form: '${form}'`; | ||||
|             } | ||||
|             if (pos) { | ||||
|               flowchartCode += `, pos: '${pos}'`; | ||||
|             } | ||||
|             flowchartCode += ` }\n`; | ||||
|             flowchartCode += `  nAA:::customClazz\n`; | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           }); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('Test iconShape with different h', () => { | ||||
|   it('with different h', () => { | ||||
|     let flowchartCode = `flowchart TB\n`; | ||||
|     const icon = 'fa:bell'; | ||||
|     const iconHeight = 64; | ||||
|     flowchartCode += `  nA --> nAA@{ icon: '${icon}', label: 'icon with different h', h: ${iconHeight} }\n`; | ||||
|     imgSnapshotTest(flowchartCode); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('Test colored iconShape', () => { | ||||
|   it('with no styles', () => { | ||||
|     let flowchartCode = `flowchart TB\n`; | ||||
|     const icon = 'fluent-emoji:tropical-fish'; | ||||
|     flowchartCode += `  nA --> nAA@{ icon: '${icon}', form: 'square', label: 'icon with color' }\n`; | ||||
|     imgSnapshotTest(flowchartCode); | ||||
|   }); | ||||
|  | ||||
|   it('with styles', () => { | ||||
|     let flowchartCode = `flowchart TB\n`; | ||||
|     const icon = 'fluent-emoji:tropical-fish'; | ||||
|     flowchartCode += `  nA --> nAA@{ icon: '${icon}', form: 'square', label: 'icon with color' }\n`; | ||||
|     flowchartCode += `  style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`; | ||||
|     imgSnapshotTest(flowchartCode); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,103 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util'; | ||||
|  | ||||
| const looks = ['classic', 'handDrawn'] as const; | ||||
| const directions = [ | ||||
|   'TB', | ||||
|   //'BT', | ||||
|   'LR', | ||||
|   //  'RL' | ||||
| ] as const; | ||||
| const labelPos = [undefined, 't', 'b'] as const; | ||||
|  | ||||
| looks.forEach((look) => { | ||||
|   directions.forEach((direction) => { | ||||
|     labelPos.forEach((pos) => { | ||||
|       describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => { | ||||
|         it(`without label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }\n`; | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is a label for image shape'`; | ||||
|  | ||||
|           flowchartCode += `, w: '100', h: '200'`; | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with very long label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is a very very very very very long long long label for image shape'`; | ||||
|  | ||||
|           flowchartCode += `, w: '100', h: '250'`; | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:true`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is **bold** </br>and <strong>strong</strong> for image shape'`; | ||||
|  | ||||
|           flowchartCode += `, w: '550', h: '200'`; | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           imgSnapshotTest(flowchartCode, { look, htmlLabels: true }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:false`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is **bold** </br>and <strong>strong</strong> for image shape'`; | ||||
|           flowchartCode += `, w: '250', h: '200'`; | ||||
|  | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           imgSnapshotTest(flowchartCode, { | ||||
|             look, | ||||
|             htmlLabels: false, | ||||
|             flowchart: { htmlLabels: false }, | ||||
|           }); | ||||
|         }); | ||||
|  | ||||
|         it(`with styles`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'new image shape'`; | ||||
|           flowchartCode += `, w: '550', h: '200'`; | ||||
|  | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           flowchartCode += `  style A fill:#f9f,stroke:#333,stroke-width:4px \n`; | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with classDef`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#000000,stroke-dasharray: 5 5\n`; | ||||
|           flowchartCode += `  nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'new image shape'`; | ||||
|  | ||||
|           flowchartCode += `, w: '500', h: '550'`; | ||||
|           if (pos) { | ||||
|             flowchartCode += `, pos: '${pos}'`; | ||||
|           } | ||||
|           flowchartCode += ` }\n`; | ||||
|           flowchartCode += `  A:::customClazz\n`; | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,136 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('Kanban diagram', () => { | ||||
|   it('1: should render a kanban with a single section', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     docs[Create Documentation] | ||||
|     docs[Create Blog about the new diagram] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('2: should render a kanban with multiple sections', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     docs[Create Documentation] | ||||
|   id2 | ||||
|     docs[Create Blog about the new diagram] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('3: should render a kanban with a single wrapping node', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('4: should handle the height of a section with a wrapping node at the end', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     id2[One line] | ||||
|     id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('5: should handle the height of a section with a wrapping node at the top', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] | ||||
|     id3[One line] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('6: should handle the height of a section with a wrapping node in the middle', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     id2[One line] | ||||
|     id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] | ||||
|     id4[One line] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('6: should handle assigments', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     docs[Create Documentation] | ||||
|   id2[In progress] | ||||
|     docs[Create Blog about the new diagram]@{ assigned: 'knsv' } | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('7: should handle prioritization', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id2[In progress] | ||||
|     vh[Very High]@{ priority: 'Very High' } | ||||
|     h[High]@{ priority: 'High' } | ||||
|     m[Default priority] | ||||
|     l[Low]@{ priority: 'Low' } | ||||
|     vl[Very Low]@{ priority: 'Very Low' } | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('7: should handle external tickets', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id1[Todo] | ||||
|     docs[Create Documentation] | ||||
|   id2[In progress] | ||||
|     docs[Create Blog about the new diagram]@{ ticket: MC-2037 } | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('8: should handle assignments, prioritization and tickets ids in the same item', () => { | ||||
|     imgSnapshotTest( | ||||
|       `kanban | ||||
|   id2[In progress] | ||||
|     docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' } | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('10: Full example', () => { | ||||
|     imgSnapshotTest( | ||||
|       `--- | ||||
| config: | ||||
|   kanban: | ||||
|     ticketBaseUrl: 'https://abc123.atlassian.net/browse/#TICKET#' | ||||
| --- | ||||
| kanban | ||||
|   id1[Todo] | ||||
|     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 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] | ||||
|   id11[Done] | ||||
|     id5[define getData] | ||||
|     id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'} | ||||
|     id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' } | ||||
|     id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' } | ||||
|     id66[last item]@{ priority: 'Very Low', assigned: 'knsv' } | ||||
|   id12[Can't reproduce] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,146 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util.ts'; | ||||
|  | ||||
| const looks = ['classic', 'handDrawn'] as const; | ||||
| const directions = [ | ||||
|   'TB', | ||||
|   //'BT', | ||||
|   'LR', | ||||
|   //'RL' | ||||
| ] as const; | ||||
| const newShapesSet1 = [ | ||||
|   'triangle', | ||||
|   'sloped-rectangle', | ||||
|   'horizontal-cylinder', | ||||
|   'flipped-triangle', | ||||
|   'hourglass', | ||||
| ] as const; | ||||
| const newShapesSet2 = [ | ||||
|   'tagged-rectangle', | ||||
|   'documents', | ||||
|   'lightning-bolt', | ||||
|   'filled-circle', | ||||
|   'window-pane', | ||||
| ] as const; | ||||
|  | ||||
| const newShapesSet3 = [ | ||||
|   'curved-trapezoid', | ||||
|   'bow-rect', | ||||
|   'tagged-document', | ||||
|   'divided-rectangle', | ||||
|   'crossed-circle', | ||||
| ] as const; | ||||
|  | ||||
| const newShapesSet4 = [ | ||||
|   'document', | ||||
|   'notched-pentagon', | ||||
|   'lined-cylinder', | ||||
|   'stacked-document', | ||||
|   'half-rounded-rectangle', | ||||
| ] as const; | ||||
|  | ||||
| const newShapesSet5 = [ | ||||
|   'lined-document', | ||||
|   'tagged-document', | ||||
|   'brace-l', | ||||
|   'comment', | ||||
|   'braces', | ||||
|   'brace-r', | ||||
| ] as const; | ||||
|  | ||||
| const newShapesSet6 = ['brace-r', 'braces'] as const; | ||||
| // Aggregate all shape sets into a single array | ||||
| const newShapesSets = [ | ||||
|   newShapesSet1, | ||||
|   newShapesSet2, | ||||
|   newShapesSet3, | ||||
|   newShapesSet4, | ||||
|   newShapesSet5, | ||||
|   newShapesSet6, | ||||
| ]; | ||||
|  | ||||
| looks.forEach((look) => { | ||||
|   directions.forEach((direction) => { | ||||
|     newShapesSets.forEach((newShapesSet) => { | ||||
|       describe(`Test ${newShapesSet.join(', ')} in ${look} look and dir ${direction}`, () => { | ||||
|         it(`without label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape} }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`connect all shapes with each other`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           for (let i = 0; i < newShapesSet.length; i++) { | ||||
|             for (let j = i + 1; j < newShapesSet.length; j++) { | ||||
|               flowchartCode += `  n${i}${i} --> n${j}${j}\n`; | ||||
|             } | ||||
|           } | ||||
|           if (!(direction === 'TB' && look === 'handDrawn' && newShapesSet === newShapesSet1)) { | ||||
|             //skip this test, works in real. Need to look | ||||
|             imgSnapshotTest(flowchartCode, { look }); | ||||
|           } | ||||
|         }); | ||||
|  | ||||
|         it(`with very long label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:true`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:false`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { | ||||
|             look, | ||||
|             htmlLabels: false, | ||||
|             flowchart: { htmlLabels: false }, | ||||
|           }); | ||||
|         }); | ||||
|  | ||||
|         it(`with styles`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; | ||||
|             flowchartCode += `  style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with classDef`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; | ||||
|           newShapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; | ||||
|             flowchartCode += `  n${index}${index}:::customClazz\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,107 +0,0 @@ | ||||
| import { imgSnapshotTest } from '../../helpers/util'; | ||||
|  | ||||
| const looks = ['classic', 'handDrawn'] as const; | ||||
| const directions = [ | ||||
|   'TB', | ||||
|   //'BT', | ||||
|   'LR', | ||||
|   //'RL' | ||||
| ] as const; | ||||
|  | ||||
| const shapesSet1 = ['text', 'card', 'lin-rect', 'diamond', 'hexagon'] as const; | ||||
|  | ||||
| // removing labelRect, need have alias for it | ||||
| const shapesSet2 = ['rounded', 'rect', 'start', 'stop'] as const; | ||||
|  | ||||
| const shapesSet3 = ['fork', 'choice', 'note', 'stadium', 'odd'] as const; | ||||
|  | ||||
| const shapesSet4 = ['subroutine', 'cylinder', 'circle', 'doublecircle', 'odd'] as const; | ||||
|  | ||||
| const shapesSet5 = ['anchor', 'lean-r', 'lean-l', 'trap-t', 'trap-b'] as const; | ||||
|  | ||||
| // Aggregate all shape sets into a single array | ||||
| const shapesSets = [shapesSet1, shapesSet2, shapesSet3, shapesSet4, shapesSet5] as const; | ||||
|  | ||||
| looks.forEach((look) => { | ||||
|   directions.forEach((direction) => { | ||||
|     shapesSets.forEach((shapesSet) => { | ||||
|       describe(`Test ${shapesSet.join(', ')} in ${look} look and dir ${direction}`, () => { | ||||
|         it(`without label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape} }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`connect all shapes with each other`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           for (let i = 0; i < shapesSet.length; i++) { | ||||
|             for (let j = i + 1; j < shapesSet.length; j++) { | ||||
|               flowchartCode += `  n${i}${i} --> n${j}${j}\n`; | ||||
|             } | ||||
|           } | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with very long label`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:true`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with markdown htmlLabels:false`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { | ||||
|             look, | ||||
|             htmlLabels: false, | ||||
|             flowchart: { htmlLabels: false }, | ||||
|           }); | ||||
|         }); | ||||
|  | ||||
|         it(`with styles`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; | ||||
|             flowchartCode += `  style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|  | ||||
|         it(`with classDef`, () => { | ||||
|           let flowchartCode = `flowchart ${direction}\n`; | ||||
|           flowchartCode += `  classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; | ||||
|           shapesSet.forEach((newShape, index) => { | ||||
|             flowchartCode += `  n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; | ||||
|             flowchartCode += `  n${index}${index}:::customClazz\n`; | ||||
|           }); | ||||
|           imgSnapshotTest(flowchartCode, { look }); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -10,15 +10,6 @@ describe('packet structure', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('should render a simple packet diagram without ranges', () => { | ||||
|     imgSnapshotTest( | ||||
|       `packet-beta | ||||
|   0: "h" | ||||
|   1: "i" | ||||
| ` | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('should render a complex packet diagram', () => { | ||||
|     imgSnapshotTest( | ||||
|       `packet-beta | ||||
|   | ||||
| @@ -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 | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,6 +1,8 @@ | ||||
| // <reference types="Cypress" /> | ||||
|  | ||||
| import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('Sequence diagram', () => { | ||||
| context('Sequence diagram', () => { | ||||
|   it('should render a sequence diagram with boxes', () => { | ||||
|     renderGraph( | ||||
|       ` | ||||
| @@ -242,7 +244,7 @@ describe('Sequence diagram', () => { | ||||
|       ` | ||||
|     ); | ||||
|   }); | ||||
|   describe('font settings', () => { | ||||
|   context('font settings', () => { | ||||
|     it('should render different note fonts when configured', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| @@ -339,7 +341,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('auth width scaling', () => { | ||||
|   context('auth width scaling', () => { | ||||
|     it('should render long actor descriptions', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| @@ -528,7 +530,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('background rects', () => { | ||||
|   context('background rects', () => { | ||||
|     it('should render a single and nested rects', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| @@ -808,7 +810,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('directives', () => { | ||||
|   context('directives', () => { | ||||
|     it('should override config with directive settings', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| @@ -840,7 +842,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('links', () => { | ||||
|   context('links', () => { | ||||
|     it('should support actor links', () => { | ||||
|       renderGraph( | ||||
|         ` | ||||
| @@ -856,7 +858,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|       cy.get('#actor0_popup').should((popupMenu) => { | ||||
|         const style = popupMenu.attr('style'); | ||||
|         // expect(style).to.undefined; | ||||
|         expect(style).to.undefined; | ||||
|       }); | ||||
|       cy.get('#root-0').click(); | ||||
|       cy.get('#actor0_popup').should((popupMenu) => { | ||||
| @@ -931,7 +933,7 @@ describe('Sequence diagram', () => { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   describe('svg size', () => { | ||||
|   context('svg size', () => { | ||||
|     it('should render a sequence diagram when useMaxWidth is true (default)', () => { | ||||
|       renderGraph( | ||||
|         ` | ||||
| @@ -1010,7 +1012,7 @@ describe('Sequence diagram', () => { | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
|   describe('render after error', () => { | ||||
|   context('render after error', () => { | ||||
|     it('should render diagram after fixing destroy participant error', () => { | ||||
|       cy.on('uncaught:exception', (err) => { | ||||
|         return false; | ||||
|   | ||||
| @@ -542,43 +542,6 @@ stateDiagram-v2 | ||||
|         { logLevel: 0, fontFamily: 'courier' } | ||||
|       ); | ||||
|     }); | ||||
|     it(' can have styles applied ', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| stateDiagram-v2 | ||||
| AState | ||||
| style AState fill:#636,border:1px solid red,color:white; | ||||
|         `, | ||||
|         { logLevel: 0, fontFamily: 'courier' } | ||||
|       ); | ||||
|     }); | ||||
|     it(' should let styles take preceedence over classes', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
| stateDiagram-v2 | ||||
| AState: Should NOT be white | ||||
| BState | ||||
| classDef exampleStyleClass fill:#fff,color: blue; | ||||
| class AState,BState exampleStyleClass | ||||
| style AState fill:#636,border:1px solid red,color:white; | ||||
|         `, | ||||
|         { logLevel: 0, fontFamily: 'courier' } | ||||
|       ); | ||||
|     }); | ||||
|     it(' should allow styles to take effect in stubgraphs', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|   stateDiagram | ||||
|     state roundWithTitle { | ||||
|       C: Black with white text | ||||
|     } | ||||
|     D: Black with white text | ||||
|  | ||||
|     style C,D stroke:#00f, fill:black, color:white | ||||
|         `, | ||||
|         { logLevel: 0, fontFamily: 'courier' } | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   it('1433: should render a simple state diagram with a title', () => { | ||||
|     imgSnapshotTest( | ||||
| @@ -588,20 +551,6 @@ title: simple state diagram | ||||
| stateDiagram-v2 | ||||
| [*] --> State1 | ||||
| State1 --> [*] | ||||
| `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('should align dividers correctly', () => { | ||||
|     imgSnapshotTest( | ||||
|       `stateDiagram-v2 | ||||
|   state s2 { | ||||
|       s3 | ||||
|       -- | ||||
|       s4 | ||||
|       -- | ||||
|       55 | ||||
|   } | ||||
| `, | ||||
|       {} | ||||
|     ); | ||||
|   | ||||
| @@ -1,18 +1,19 @@ | ||||
| import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; | ||||
|  | ||||
| describe('XY Chart', () => { | ||||
|   it('should render the simplest possible chart', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|   describe('single dataset', () => { | ||||
|     it('should render the simplest possible chart', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       xychart-beta | ||||
|         line [10, 30, 20] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should render a complete chart', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Should render a complete chart', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       xychart-beta | ||||
|         title "Sales Revenue" | ||||
|         x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] | ||||
| @@ -20,82 +21,68 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should render a chart without title', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Should render a chart without title', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       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] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('y-axis title not required', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('y-axis title not required', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       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] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should render a chart without y-axis with different range', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Should render a chart without y-axis with different range', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       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] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('x axis title not required', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('x axis title not required', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       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] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Multiple plots can be rendered', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|       xychart-beta | ||||
|         line [23, 46, 77, 34] | ||||
|         line [45, 32, 33, 12] | ||||
|         bar [87, 54, 99, 85] | ||||
|         line [78, 88, 22, 4] | ||||
|         line [22, 29, 75, 33] | ||||
|         bar [52, 96, 35, 10] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Decimals and negative numbers are supported', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Decimals and negative numbers are supported', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       xychart-beta | ||||
|         y-axis -2.4 --> 3.5 | ||||
|         line [+1.3, .6, 2.4, -.34] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render spark line with "plotReservedSpacePercent"', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render spark line with "plotReservedSpacePercent"', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         theme: dark | ||||
| @@ -107,12 +94,12 @@ describe('XY Chart', () => { | ||||
|       xychart-beta | ||||
|         line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render spark bar without displaying other property', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render spark bar without displaying other property', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         theme: dark | ||||
| @@ -133,12 +120,12 @@ describe('XY Chart', () => { | ||||
|       xychart-beta | ||||
|         bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should use all the config from directive', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Should use all the config from directive', () => { | ||||
|       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-beta | ||||
|         title "Sales Revenue" | ||||
| @@ -147,12 +134,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Should use all the config from yaml', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Should use all the config from yaml', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         theme: forest | ||||
| @@ -187,12 +174,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render with show axis title false', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render with show axis title false', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         xyChart: | ||||
| @@ -208,12 +195,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render with show axis label false', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render with show axis label false', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         xyChart: | ||||
| @@ -229,12 +216,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render with show axis tick false', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render with show axis tick false', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         xyChart: | ||||
| @@ -250,12 +237,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render with show axis line false', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render with show axis line false', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         xyChart: | ||||
| @@ -271,12 +258,12 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|   it('Render all the theme color', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|     it('Render all the theme color', () => { | ||||
|       imgSnapshotTest( | ||||
|         ` | ||||
|       --- | ||||
|       config: | ||||
|         themeVariables: | ||||
| @@ -300,19 +287,110 @@ describe('XY Chart', () => { | ||||
|         bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|         line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|         {} | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|   it('should use the correct distances between data points', () => { | ||||
|     imgSnapshotTest( | ||||
|       ` | ||||
|  | ||||
|   describe('multiple datasets', () => { | ||||
|     describe('vertical', () => { | ||||
|       it('should render bar diagram for 3 datasets', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta | ||||
|         x-axis 0 --> 2 | ||||
|         line [0, 1, 0, 1] | ||||
|         bar [1, 0, 1, 0] | ||||
|       title "Basic xychart with multiple datasets" | ||||
|       x-axis "Relevant categories" [category1, "category 2", category3, category4] | ||||
|       y-axis Animals 0 --> 160 | ||||
|       bar "dogs" [0, 20, 40, 30] | ||||
|       bar "cats" [20, 40, 0, 30] | ||||
|       bar "birds" [30, 60, 50, 30] | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|     cy.get('svg'); | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|  | ||||
|       it('should render line diagram for 3 datasets', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta | ||||
|       title "Basic xychart with multiple datasets" | ||||
|       x-axis "Relevant categories" [category1, "category 2", category3, category4] | ||||
|       y-axis Animals 0 --> 160 | ||||
|       line "dogs" [0, 20, 40, 30] | ||||
|       line "cats" [20, 40, 0, 30] | ||||
|       line "birds" [30, 60, 50, 30] | ||||
|       `, | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|  | ||||
|       it('should render a mix of multiple bar and line plots', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta | ||||
|         line [23, 46, 77, 34] | ||||
|         line [45, 32, 33, 12] | ||||
|         bar [87, 54, 99, 85] | ||||
|         line [78, 88, 22, 4] | ||||
|         line [22, 29, 75, 33] | ||||
|         bar [52, 96, 35, 10] | ||||
|       `, | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|     }); | ||||
|  | ||||
|     describe('horizontal', () => { | ||||
|       it('should render bar diagram for 3 datasets', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta horizontal | ||||
|       title "Basic xychart with multiple datasets" | ||||
|       x-axis "Relevant categories" [category1, "category 2", category3, category4] | ||||
|       y-axis Animals 0 --> 160 | ||||
|       bar "dogs" [0, 20, 40, 30] | ||||
|       bar "cats" [20, 40, 0, 30] | ||||
|       bar "birds" [30, 60, 50, 30] | ||||
|       `, | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|  | ||||
|       it('should render line diagram for 3 datasets', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta horizontal | ||||
|       title "Basic xychart with multiple datasets" | ||||
|       x-axis "Relevant categories" [category1, "category 2", category3, category4] | ||||
|       y-axis Animals 0 --> 160 | ||||
|       line "dogs" [0, 20, 40, 30] | ||||
|       line "cats" [20, 40, 0, 30] | ||||
|       line "birds" [30, 60, 50, 30] | ||||
|       `, | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|  | ||||
|       it('should render a mix of multiple bar and line plots', () => { | ||||
|         imgSnapshotTest( | ||||
|           ` | ||||
|       xychart-beta horizontal | ||||
|         line [23, 46, 77, 34] | ||||
|         line [45, 32, 33, 12] | ||||
|         bar [87, 54, 99, 85] | ||||
|         line [78, 88, 22, 4] | ||||
|         line [22, 29, 75, 33] | ||||
|         bar [52, 96, 35, 10] | ||||
|       `, | ||||
|           {} | ||||
|         ); | ||||
|         cy.get('svg'); | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -1,52 +0,0 @@ | ||||
| <!doctype html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="utf-8" /> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|     <title>Architecture Mermaid Test Page</title> | ||||
|     <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" /> | ||||
|     <style> | ||||
|       div.mermaid { | ||||
|         /* font-family: 'trebuchet ms', verdana, arial; */ | ||||
|         font-family: 'Courier New', Courier, monospace !important; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|  | ||||
|   <body> | ||||
|     <h2>External Icons Demo</h2> | ||||
|     <pre class="mermaid"> | ||||
|     architecture-beta | ||||
|       service s3(logos:aws-s3)[Cloud Store] | ||||
|       service ec2(logos:aws-ec2)[Server] | ||||
|       service api(logos:aws-api-gateway)[Api Gateway] | ||||
|       service fa(fa:image)[Font Awesome Icon] | ||||
|     </pre> | ||||
|  | ||||
|     <script type="module"> | ||||
|       import mermaid from './mermaid.esm.mjs'; | ||||
|       mermaid.initialize({ | ||||
|         startOnLoad: false, | ||||
|         logLevel: 0, | ||||
|       }); | ||||
|       mermaid.registerIconPacks([ | ||||
|         { | ||||
|           name: 'logos', | ||||
|           loader: () => | ||||
|             fetch('https://unpkg.com/@iconify-json/logos/icons.json').then((res) => res.json()), | ||||
|         }, | ||||
|         { | ||||
|           name: 'fa', | ||||
|           loader: () => | ||||
|             fetch('https://unpkg.com/@iconify-json/fa6-regular/icons.json').then((res) => | ||||
|               res.json() | ||||
|             ), | ||||
|         }, | ||||
|       ]); | ||||
|       await mermaid.run(); | ||||
|       if (window.Cypress) { | ||||
|         window.rendered = true; | ||||
|       } | ||||
|     </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://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, | ||||
|   | ||||
| @@ -27,7 +27,7 @@ const code3 = `flowchart TD | ||||
| A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />) | ||||
| B(<b>Bold text!</b>)`; | ||||
|  | ||||
| if (/test-html-escaping/.exec(location.href)) { | ||||
| if (location.href.match('test-html-escaping')) { | ||||
|   code = code3; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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,866 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" /> | ||||
|     <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" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|  | ||||
|     <style> | ||||
|       body { | ||||
|         font-family: 'Arial'; | ||||
|       } | ||||
|  | ||||
|       table { | ||||
|         width: 100%; | ||||
|         border-collapse: collapse; | ||||
|         table-layout: fixed; | ||||
|       } | ||||
|  | ||||
|       th, | ||||
|       td { | ||||
|         border: 1px solid black; | ||||
|         padding: 10px; | ||||
|         text-align: center; | ||||
|         vertical-align: middle; | ||||
|       } | ||||
|  | ||||
|       .separator { | ||||
|         height: 20px; | ||||
|         background-color: #f0f0f0; | ||||
|       } | ||||
|  | ||||
|       .vertical-header { | ||||
|         text-align: center; | ||||
|       } | ||||
|  | ||||
|       .collapsible { | ||||
|         background-color: #f9f9f9; | ||||
|         color: #444; | ||||
|         cursor: pointer; | ||||
|         padding: 18px; | ||||
|         width: 100%; | ||||
|         border: none; | ||||
|         text-align: left; | ||||
|         outline: none; | ||||
|         font-size: 15px; | ||||
|       } | ||||
|  | ||||
|       .active, | ||||
|       .collapsible:hover { | ||||
|         background-color: #ccc; | ||||
|       } | ||||
|  | ||||
|       .collapsible:after { | ||||
|         content: '\002B'; | ||||
|         color: #777; | ||||
|         font-weight: bold; | ||||
|         float: right; | ||||
|         margin-left: 2px; | ||||
|       } | ||||
|  | ||||
|       .active:after { | ||||
|         content: '\2212'; | ||||
|       } | ||||
|  | ||||
|       .content { | ||||
|         padding: 0 5px; | ||||
|         max-height: 0; | ||||
|         overflow: hidden; | ||||
|         transition: max-height 0.2s ease-out; | ||||
|         background-color: #f1f1f1; | ||||
|       } | ||||
|  | ||||
|       .content .pre-scrollable { | ||||
|         max-height: 200px; | ||||
|         overflow-y: scroll; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|  | ||||
|   <body> | ||||
|     <table> | ||||
|       <tr> | ||||
|         <th></th> | ||||
|         <!-- Placeholder for the top left corner --> | ||||
|         <th>Dagre</th> | ||||
|         <th>Dagre with rough</th> | ||||
|         <th>ELK</th> | ||||
|         <th>ELK with rough</th> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Stadium shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|               id1([This is the text in the box]) | ||||
|             </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram1" class="mermaid"> | ||||
| flowchart LR | ||||
|     id1([This is the text in the box]) | ||||
|  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram2" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn"} }%% | ||||
| flowchart LR | ||||
|     id1([This is the text in the box]) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram3" class="mermaid"> | ||||
| %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
| flowchart LR | ||||
|     id1([This is the text in the box]) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram4" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
| flowchart LR | ||||
|     id1([This is the text in the box]) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Sub-Routine shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|       flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram5" class="mermaid"> | ||||
| flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram6" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn"} }%% | ||||
| flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram7" class="mermaid"> | ||||
| %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
| flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram8" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
| flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Cylindrical shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1[(Database)] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram9" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1[(Database)] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram10" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1[(Database)] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram11" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1[(Database)] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram12" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1[(Database)] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Circle shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1((This is the text in the circle)) | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram13" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1((This is the text in the circle)) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram14" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1((This is the text in the circle)) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram15" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1((This is the text in the circle)) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram16" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1((This is the text in the circle)) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Double Circle shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart TD | ||||
|     id1(((This is the text in the circle))) | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram17" class="mermaid"> | ||||
|           flowchart TD | ||||
|     id1(((This is the text in the circle))) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram18" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart TD | ||||
|     id1(((This is the text in the circle))) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram19" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1(((This is the text in the circle))) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram20" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1(((This is the text in the circle))) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Asymmetric shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1>This is the text in the box] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram21" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1>This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram22" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1>This is the text in the box]   | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram23" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1>This is the text in the box]   | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram24" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1>This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Rhombus/Diamond/Question shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1{This is the text in the box} | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram25" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1{This is the text in the box} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram26" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1{This is the text in the box} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram27" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1{This is the text in the box} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram28" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1{This is the text in the box} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Hexagon shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1{{This is the text in the box}} | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram29" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1{{This is the text in the box}} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram31" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1{{This is the text in the box}} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram32" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1{{This is the text in the box}} | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Parallelogram shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart TD | ||||
|     id1[/This is the text in the box/] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram33" class="mermaid"> | ||||
|           flowchart TD | ||||
|     id1[/This is the text in the box/] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram34" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart TD | ||||
|     id1[/This is the text in the box/]   | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram35" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1[/This is the text in the box/]  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram36" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1[/This is the text in the box/] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Parallelogram Alt shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart TD | ||||
|     id1[\This is the text in the box\] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram37" class="mermaid"> | ||||
|           flowchart TD | ||||
|     id1[\This is the text in the box\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram38" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart TD | ||||
|     id1[\This is the text in the box\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram39" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1[\This is the text in the box\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram40" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     id1[\This is the text in the box\] | ||||
|  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Trapezoid shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart TD | ||||
|     A[/Christmas\] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram41" class="mermaid"> | ||||
|           flowchart TD | ||||
|     A[/Christmas\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram42" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart TD | ||||
|     A[/Christmas\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram43" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     A[/Christmas\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram44" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     A[/Christmas\] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Trapezoid Alt shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart TD | ||||
|     A[\Christmas/] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram45" class="mermaid"> | ||||
|           flowchart TD | ||||
|     A[\Christmas/] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram46" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart TD | ||||
|     A[\Christmas/] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram47" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     A[\Christmas/] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram48" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart TD | ||||
|     A[\Christmas/]   | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Rect with rounded corner</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1(This is the text in the box) | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram49" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1(This is the text in the box) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram50" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1(This is the text in the box) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram51" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1(This is the text in the box) | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram52" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1(This is the text in the box)  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|  | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Rect with sharp corner</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|               flowchart LR | ||||
|     id1[This is the text in the box] | ||||
|     </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram53" class="mermaid"> | ||||
|           flowchart LR | ||||
|     id1[This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram54" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn"} }%% | ||||
|           flowchart LR | ||||
|     id1[This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram55" class="mermaid"> | ||||
|           %%{init: {"handDrawn": false, "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1[This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram56" class="mermaid"> | ||||
|           %%{init: {"look": "handDrawn", "layout": "elk"} }%% | ||||
|           flowchart LR | ||||
|     id1[This is the text in the box] | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|       <!-- Separator row --> | ||||
|       <tr class="separator"> | ||||
|         <td colspan="5"></td> | ||||
|         <!-- This cell spans all columns including the vertical header --> | ||||
|       </tr> | ||||
|     </table> | ||||
|  | ||||
|     <script type="module"> | ||||
|       import mermaid from './mermaid.esm.mjs'; | ||||
|       import layouts from './mermaid-layout-elk.esm.mjs'; | ||||
|       mermaid.registerLayoutLoaders(layouts); | ||||
|       mermaid.parseError = function (err, hash) {}; | ||||
|  | ||||
|       mermaid.initialize({ | ||||
|         handDrawn: false, | ||||
|         mergeEdges: true, | ||||
|         layout: 'dagre', | ||||
|         flowchart: { titleTopMargin: 10 }, | ||||
|         // fontFamily: 'Caveat', | ||||
|         fontFamily: 'Kalam', | ||||
|         sequence: { | ||||
|           actorFontFamily: 'courier', | ||||
|           noteFontFamily: 'courier', | ||||
|           messageFontFamily: 'courier', | ||||
|         }, | ||||
|         fontSize: 16, | ||||
|         logLevel: 0, | ||||
|       }); | ||||
|       function callback() { | ||||
|         alert('It worked'); | ||||
|       } | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         console.error('In parse error:'); | ||||
|         console.error(err); | ||||
|       }; | ||||
|  | ||||
|       let coll = document.getElementsByClassName('collapsible'); | ||||
|       for (const element of coll) { | ||||
|         element.addEventListener('click', function () { | ||||
|           this.classList.toggle('active'); | ||||
|           let content = this.nextElementSibling; | ||||
|           if (content.style.maxHeight) { | ||||
|             content.style.maxHeight = null; | ||||
|           } else { | ||||
|             content.style.maxHeight = content.scrollHeight + 'px'; | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
| @@ -1,191 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" /> | ||||
|     <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" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|  | ||||
|     <style> | ||||
|       body { | ||||
|         font-family: 'Arial'; | ||||
|       } | ||||
|  | ||||
|       table { | ||||
|         width: 100%; | ||||
|         border-collapse: collapse; | ||||
|         table-layout: fixed; | ||||
|       } | ||||
|  | ||||
|       th, | ||||
|       td { | ||||
|         border: 1px solid black; | ||||
|         padding: 10px; | ||||
|         text-align: center; | ||||
|         vertical-align: middle; | ||||
|       } | ||||
|  | ||||
|       .separator { | ||||
|         height: 20px; | ||||
|         background-color: #f0f0f0; | ||||
|       } | ||||
|  | ||||
|       .vertical-header { | ||||
|         text-align: center; | ||||
|       } | ||||
|  | ||||
|       .collapsible { | ||||
|         background-color: #f9f9f9; | ||||
|         color: #444; | ||||
|         cursor: pointer; | ||||
|         padding: 18px; | ||||
|         width: 100%; | ||||
|         border: none; | ||||
|         text-align: left; | ||||
|         outline: none; | ||||
|         font-size: 15px; | ||||
|       } | ||||
|  | ||||
|       .active, | ||||
|       .collapsible:hover { | ||||
|         background-color: #ccc; | ||||
|       } | ||||
|  | ||||
|       .collapsible:after { | ||||
|         content: '\002B'; | ||||
|         color: #777; | ||||
|         font-weight: bold; | ||||
|         float: right; | ||||
|         margin-left: 2px; | ||||
|       } | ||||
|  | ||||
|       .active:after { | ||||
|         content: '\2212'; | ||||
|       } | ||||
|  | ||||
|       .content { | ||||
|         padding: 0 5px; | ||||
|         max-height: 0; | ||||
|         overflow: hidden; | ||||
|         transition: max-height 0.2s ease-out; | ||||
|         background-color: #f1f1f1; | ||||
|       } | ||||
|  | ||||
|       .content .pre-scrollable { | ||||
|         max-height: 200px; | ||||
|         overflow-y: scroll; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|  | ||||
|   <body> | ||||
|     <table> | ||||
|       <tr> | ||||
|         <th></th> | ||||
|         <!-- Placeholder for the top left corner --> | ||||
|         <th>State rough</th> | ||||
|         <th>Flowchart rough</th> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <th class="vertical-header"> | ||||
|           <button class="collapsible">Stadium shape</button> | ||||
|           <div class="content"> | ||||
|             <div class="pre-scrollable"> | ||||
|               <pre> | ||||
|       flowchart LR | ||||
|     id1([This is the text in the box]) | ||||
|  | ||||
|   </pre | ||||
|               > | ||||
|             </div> | ||||
|           </div> | ||||
|         </th> | ||||
|         <td> | ||||
|           <pre id="diagram1" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn"} }%% | ||||
| stateDiagram-v2 | ||||
|     stateA | ||||
|  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|         <td> | ||||
|           <pre id="diagram2" class="mermaid"> | ||||
| %%{init: {"look": "handDrawn"} }%% | ||||
| flowchart LR | ||||
|     id1[[This is the text in the box]] | ||||
|  | ||||
|  | ||||
|       </pre | ||||
|           > | ||||
|         </td> | ||||
|       </tr> | ||||
|     </table> | ||||
|  | ||||
|     <script type="module"> | ||||
|       import mermaid from './mermaid.esm.mjs'; | ||||
|       import layouts from './mermaid-layout-elk.esm.mjs'; | ||||
|       mermaid.registerLayoutLoaders(layouts); | ||||
|       mermaid.parseError = function (err, hash) {}; | ||||
|  | ||||
|       mermaid.initialize({ | ||||
|         handDrawn: false, | ||||
|         mergeEdges: true, | ||||
|         layout: 'dagre', | ||||
|         flowchart: { titleTopMargin: 10 }, | ||||
|         // fontFamily: 'Caveat', | ||||
|         fontFamily: 'Kalam', | ||||
|         sequence: { | ||||
|           actorFontFamily: 'courier', | ||||
|           noteFontFamily: 'courier', | ||||
|           messageFontFamily: 'courier', | ||||
|         }, | ||||
|         fontSize: 16, | ||||
|         logLevel: 0, | ||||
|       }); | ||||
|       function callback() { | ||||
|         alert('It worked'); | ||||
|       } | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         console.error('In parse error:'); | ||||
|         console.error(err); | ||||
|       }; | ||||
|  | ||||
|       let coll = document.getElementsByClassName('collapsible'); | ||||
|       for (const element of coll) { | ||||
|         element.addEventListener('click', function () { | ||||
|           this.classList.toggle('active'); | ||||
|           let content = this.nextElementSibling; | ||||
|           if (content.style.maxHeight) { | ||||
|             content.style.maxHeight = null; | ||||
|           } else { | ||||
|             content.style.maxHeight = content.scrollHeight + 'px'; | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     </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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user