mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			sidv/biome
			...
			release/10
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5b3912f9ec | ||
| 
						 | 
					01ff8c52b2 | ||
| 
						 | 
					d9618daab6 | ||
| 
						 | 
					a65bcc55af | ||
| 
						 | 
					80dcf2eaad | ||
| 
						 | 
					cdff69fe13 | ||
| 
						 | 
					2ce5801568 | ||
| 
						 | 
					2efe338cb5 | ||
| 
						 | 
					7509b066f1 | ||
| 
						 | 
					85ec96a72d | ||
| 
						 | 
					9301a5788a | ||
| 
						 | 
					2bedd0ef87 | ||
| 
						 | 
					92a07ffe40 | ||
| 
						 | 
					4dd4997c4d | ||
| 
						 | 
					fc61512a0a | ||
| 
						 | 
					402abdf883 | 
@@ -1,30 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Shared common options for both ESBuild and Vite
 | 
			
		||||
 */
 | 
			
		||||
export const packageOptions = {
 | 
			
		||||
  parser: {
 | 
			
		||||
    name: 'mermaid-parser',
 | 
			
		||||
    packageName: 'parser',
 | 
			
		||||
    file: 'index.ts',
 | 
			
		||||
  },
 | 
			
		||||
  mermaid: {
 | 
			
		||||
    name: 'mermaid',
 | 
			
		||||
    packageName: 'mermaid',
 | 
			
		||||
    file: 'mermaid.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-example-diagram': {
 | 
			
		||||
    name: 'mermaid-example-diagram',
 | 
			
		||||
    packageName: 'mermaid-example-diagram',
 | 
			
		||||
    file: 'detector.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-zenuml': {
 | 
			
		||||
    name: 'mermaid-zenuml',
 | 
			
		||||
    packageName: 'mermaid-zenuml',
 | 
			
		||||
    file: 'detector.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-flowchart-elk': {
 | 
			
		||||
    name: 'mermaid-flowchart-elk',
 | 
			
		||||
    packageName: 'mermaid-flowchart-elk',
 | 
			
		||||
    file: 'detector.ts',
 | 
			
		||||
  },
 | 
			
		||||
} as const;
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
import { generate } from 'langium-cli';
 | 
			
		||||
 | 
			
		||||
export async function generateLangium() {
 | 
			
		||||
  await generate({ file: `./packages/parser/langium-config.json` });
 | 
			
		||||
}
 | 
			
		||||
@@ -1,124 +0,0 @@
 | 
			
		||||
import { load, JSON_SCHEMA } from 'js-yaml';
 | 
			
		||||
import assert from 'node:assert';
 | 
			
		||||
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
 | 
			
		||||
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * All of the keys in the mermaid config that have a mermaid diagram config.
 | 
			
		||||
 */
 | 
			
		||||
const MERMAID_CONFIG_DIAGRAM_KEYS = [
 | 
			
		||||
  'flowchart',
 | 
			
		||||
  'sequence',
 | 
			
		||||
  'gantt',
 | 
			
		||||
  'journey',
 | 
			
		||||
  'class',
 | 
			
		||||
  'state',
 | 
			
		||||
  'er',
 | 
			
		||||
  'pie',
 | 
			
		||||
  'quadrantChart',
 | 
			
		||||
  'xyChart',
 | 
			
		||||
  'requirement',
 | 
			
		||||
  'mindmap',
 | 
			
		||||
  'timeline',
 | 
			
		||||
  'gitGraph',
 | 
			
		||||
  'c4',
 | 
			
		||||
  'sankey',
 | 
			
		||||
  'block',
 | 
			
		||||
  'packet',
 | 
			
		||||
] as const;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate default values from the JSON Schema.
 | 
			
		||||
 *
 | 
			
		||||
 * AJV does not support nested default values yet (or default values with $ref),
 | 
			
		||||
 * so we need to manually find them (this may be fixed in ajv v9).
 | 
			
		||||
 *
 | 
			
		||||
 * @param mermaidConfigSchema - The Mermaid JSON Schema to use.
 | 
			
		||||
 * @returns The default mermaid config object.
 | 
			
		||||
 */
 | 
			
		||||
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
 | 
			
		||||
  const ajv = new Ajv2019({
 | 
			
		||||
    useDefaults: true,
 | 
			
		||||
    allowUnionTypes: true,
 | 
			
		||||
    strict: true,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  ajv.addKeyword({
 | 
			
		||||
    keyword: 'meta:enum', // used by jsonschema2md
 | 
			
		||||
    errors: false,
 | 
			
		||||
  });
 | 
			
		||||
  ajv.addKeyword({
 | 
			
		||||
    keyword: 'tsType', // used by json-schema-to-typescript
 | 
			
		||||
    errors: false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
 | 
			
		||||
  // (may be fixed in v9) so we need to manually use sub-schemas
 | 
			
		||||
  const mermaidDefaultConfig = {};
 | 
			
		||||
 | 
			
		||||
  assert.ok(mermaidConfigSchema.$defs);
 | 
			
		||||
  const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
 | 
			
		||||
 | 
			
		||||
  for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
 | 
			
		||||
    const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
 | 
			
		||||
    const [root, defs, defName] = subSchemaRef.split('/');
 | 
			
		||||
    assert.strictEqual(root, '#');
 | 
			
		||||
    assert.strictEqual(defs, '$defs');
 | 
			
		||||
    const subSchema = {
 | 
			
		||||
      $schema: mermaidConfigSchema.$schema,
 | 
			
		||||
      $defs: mermaidConfigSchema.$defs,
 | 
			
		||||
      ...mermaidConfigSchema.$defs[defName],
 | 
			
		||||
    } as JSONSchemaType<BaseDiagramConfig>;
 | 
			
		||||
 | 
			
		||||
    const validate = ajv.compile(subSchema);
 | 
			
		||||
 | 
			
		||||
    mermaidDefaultConfig[key] = {};
 | 
			
		||||
 | 
			
		||||
    for (const required of subSchema.required ?? []) {
 | 
			
		||||
      if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
 | 
			
		||||
        mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!validate(mermaidDefaultConfig[key])) {
 | 
			
		||||
      throw new Error(
 | 
			
		||||
        `schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
 | 
			
		||||
          validate.errors,
 | 
			
		||||
          undefined,
 | 
			
		||||
          2
 | 
			
		||||
        )}`
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const validate = ajv.compile(mermaidConfigSchema);
 | 
			
		||||
 | 
			
		||||
  if (!validate(mermaidDefaultConfig)) {
 | 
			
		||||
    throw new Error(
 | 
			
		||||
      `Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
 | 
			
		||||
        validate.errors,
 | 
			
		||||
        undefined,
 | 
			
		||||
        2
 | 
			
		||||
      )}`
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return mermaidDefaultConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const loadSchema = (src: string, filename: string): JSONSchemaType<MermaidConfig> => {
 | 
			
		||||
  const jsonSchema = load(src, {
 | 
			
		||||
    filename,
 | 
			
		||||
    // only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
 | 
			
		||||
    // e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
 | 
			
		||||
    schema: JSON_SCHEMA,
 | 
			
		||||
  }) as JSONSchemaType<MermaidConfig>;
 | 
			
		||||
  return jsonSchema;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getDefaults = (schema: JSONSchemaType<MermaidConfig>) => {
 | 
			
		||||
  return `export default ${JSON.stringify(generateDefaults(schema), undefined, 2)};`;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getSchema = (schema: JSONSchemaType<MermaidConfig>) => {
 | 
			
		||||
  return `export default ${JSON.stringify(schema, undefined, 2)};`;
 | 
			
		||||
};
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
import { packageOptions } from './common.js';
 | 
			
		||||
import { execSync } from 'child_process';
 | 
			
		||||
 | 
			
		||||
const buildType = (packageName: string) => {
 | 
			
		||||
  console.log(`Building types for ${packageName}`);
 | 
			
		||||
  try {
 | 
			
		||||
    const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`);
 | 
			
		||||
    out.length > 0 && console.log(out.toString());
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error(e);
 | 
			
		||||
    e.stdout.length > 0 && console.error(e.stdout.toString());
 | 
			
		||||
    e.stderr.length > 0 && console.error(e.stderr.toString());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
for (const { packageName } of Object.values(packageOptions)) {
 | 
			
		||||
  buildType(packageName);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								.commitlintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.commitlintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
{
 | 
			
		||||
  "extends": ["@commitlint/config-conventional"]
 | 
			
		||||
}
 | 
			
		||||
@@ -53,7 +53,6 @@ GENERICTYPE
 | 
			
		||||
getBoundarys
 | 
			
		||||
grammr
 | 
			
		||||
graphtype
 | 
			
		||||
iife
 | 
			
		||||
interp
 | 
			
		||||
introdcued
 | 
			
		||||
INVTRAPEND
 | 
			
		||||
@@ -75,13 +74,11 @@ loglevel
 | 
			
		||||
LOGMSG
 | 
			
		||||
lookaheads
 | 
			
		||||
mdast
 | 
			
		||||
metafile
 | 
			
		||||
minlen
 | 
			
		||||
Mstartx
 | 
			
		||||
MULT
 | 
			
		||||
NODIR
 | 
			
		||||
NSTR
 | 
			
		||||
outdir
 | 
			
		||||
Qcontrolx
 | 
			
		||||
reinit
 | 
			
		||||
rels
 | 
			
		||||
 
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
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, defaultOptions, getBuildConfig } from './util.js';
 | 
			
		||||
 | 
			
		||||
const shouldVisualize = process.argv.includes('--visualize');
 | 
			
		||||
 | 
			
		||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
 | 
			
		||||
  const commonOptions = { ...defaultOptions, entryName } as const;
 | 
			
		||||
  const buildConfigs = [
 | 
			
		||||
    // package.mjs
 | 
			
		||||
    { ...commonOptions },
 | 
			
		||||
    // package.min.mjs
 | 
			
		||||
    {
 | 
			
		||||
      ...commonOptions,
 | 
			
		||||
      minify: true,
 | 
			
		||||
      metafile: shouldVisualize,
 | 
			
		||||
    },
 | 
			
		||||
    // package.core.mjs
 | 
			
		||||
    { ...commonOptions, core: true },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  if (entryName === 'mermaid') {
 | 
			
		||||
    const iifeOptions: MermaidBuildOptions = { ...commonOptions, format: 'iife' };
 | 
			
		||||
    buildConfigs.push(
 | 
			
		||||
      // mermaid.js
 | 
			
		||||
      { ...iifeOptions },
 | 
			
		||||
      // mermaid.min.js
 | 
			
		||||
      { ...iifeOptions, minify: true, metafile: shouldVisualize }
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const results = await Promise.all(buildConfigs.map((option) => build(getBuildConfig(option))));
 | 
			
		||||
 | 
			
		||||
  if (shouldVisualize) {
 | 
			
		||||
    for (const { metafile } of results) {
 | 
			
		||||
      if (!metafile) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      const fileName = Object.keys(metafile.outputs)
 | 
			
		||||
        .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));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const handler = (e) => {
 | 
			
		||||
  console.error(e);
 | 
			
		||||
  process.exit(1);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const main = async () => {
 | 
			
		||||
  await generateLangium();
 | 
			
		||||
  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) {
 | 
			
		||||
    await buildPackage(pkg).catch(handler);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void main();
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
import { readFile } from 'node:fs/promises';
 | 
			
		||||
import { transformJison } from '../.build/jisonTransformer.js';
 | 
			
		||||
import type { Plugin } from 'esbuild';
 | 
			
		||||
 | 
			
		||||
export const jisonPlugin: Plugin = {
 | 
			
		||||
  name: 'jison',
 | 
			
		||||
  setup(build) {
 | 
			
		||||
    build.onLoad({ filter: /\.jison$/ }, async (args) => {
 | 
			
		||||
      // Load the file from the file system
 | 
			
		||||
      const source = await readFile(args.path, 'utf8');
 | 
			
		||||
      const contents = transformJison(source);
 | 
			
		||||
      return { contents, warnings: [] };
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
import type { JSONSchemaType } from 'ajv/dist/2019.js';
 | 
			
		||||
import type { MermaidConfig } from '../packages/mermaid/src/config.type.js';
 | 
			
		||||
import { readFile } from 'node:fs/promises';
 | 
			
		||||
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ESBuild plugin that handles JSON Schemas saved as a `.schema.yaml` file.
 | 
			
		||||
 *
 | 
			
		||||
 * Use `my-example.schema.yaml?only-defaults=true` to only load the default values.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export const jsonSchemaPlugin = {
 | 
			
		||||
  name: 'json-schema-plugin',
 | 
			
		||||
  setup(build) {
 | 
			
		||||
    let schema: JSONSchemaType<MermaidConfig> | undefined = undefined;
 | 
			
		||||
    let content = '';
 | 
			
		||||
 | 
			
		||||
    build.onLoad({ filter: /config\.schema\.yaml$/ }, async (args) => {
 | 
			
		||||
      // Load the file from the file system
 | 
			
		||||
      const source = await readFile(args.path, 'utf8');
 | 
			
		||||
      const resolvedSchema: JSONSchemaType<MermaidConfig> =
 | 
			
		||||
        content === source && schema ? schema : loadSchema(source, args.path);
 | 
			
		||||
      if (content !== source) {
 | 
			
		||||
        content = source;
 | 
			
		||||
        schema = resolvedSchema;
 | 
			
		||||
      }
 | 
			
		||||
      const contents = args.suffix.includes('only-defaults')
 | 
			
		||||
        ? getDefaults(resolvedSchema)
 | 
			
		||||
        : getSchema(resolvedSchema);
 | 
			
		||||
      return { contents, warnings: [] };
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default jsonSchemaPlugin;
 | 
			
		||||
@@ -1,102 +0,0 @@
 | 
			
		||||
import express from 'express';
 | 
			
		||||
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 { packageOptions } from '../.build/common.js';
 | 
			
		||||
 | 
			
		||||
const configs = Object.values(packageOptions).map(({ packageName }) =>
 | 
			
		||||
  getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName })
 | 
			
		||||
);
 | 
			
		||||
const mermaidIIFEConfig = getBuildConfig({
 | 
			
		||||
  ...defaultOptions,
 | 
			
		||||
  minify: false,
 | 
			
		||||
  core: false,
 | 
			
		||||
  entryName: 'mermaid',
 | 
			
		||||
  format: 'iife',
 | 
			
		||||
});
 | 
			
		||||
configs.push(mermaidIIFEConfig);
 | 
			
		||||
 | 
			
		||||
const contexts = await Promise.all(configs.map((config) => context(config)));
 | 
			
		||||
 | 
			
		||||
const rebuildAll = async () => {
 | 
			
		||||
  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, next: NextFunction) {
 | 
			
		||||
  const headers = {
 | 
			
		||||
    'Content-Type': 'text/event-stream',
 | 
			
		||||
    Connection: 'keep-alive',
 | 
			
		||||
    'Cache-Control': 'no-cache',
 | 
			
		||||
  };
 | 
			
		||||
  response.writeHead(200, headers);
 | 
			
		||||
  const clientId = Date.now();
 | 
			
		||||
  clients.push({
 | 
			
		||||
    id: clientId,
 | 
			
		||||
    response,
 | 
			
		||||
  });
 | 
			
		||||
  request.on('close', () => {
 | 
			
		||||
    clients = clients.filter((client) => client.id !== clientId);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let timeoutId: NodeJS.Timeout | undefined = undefined;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Debounce file change events to avoid rebuilding multiple times.
 | 
			
		||||
 */
 | 
			
		||||
function handleFileChange() {
 | 
			
		||||
  if (timeoutId !== undefined) {
 | 
			
		||||
    clearTimeout(timeoutId);
 | 
			
		||||
  }
 | 
			
		||||
  timeoutId = setTimeout(async () => {
 | 
			
		||||
    await rebuildAll();
 | 
			
		||||
    sendEventsToAll();
 | 
			
		||||
    timeoutId = undefined;
 | 
			
		||||
  }, 100);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sendEventsToAll() {
 | 
			
		||||
  clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function createServer() {
 | 
			
		||||
  await generateLangium();
 | 
			
		||||
  handleFileChange();
 | 
			
		||||
  const app = express();
 | 
			
		||||
  chokidar
 | 
			
		||||
    .watch('**/src/**/*.{js,ts,langium,yaml,json}', {
 | 
			
		||||
      ignoreInitial: true,
 | 
			
		||||
      ignored: [/node_modules/, /dist/, /docs/, /coverage/],
 | 
			
		||||
    })
 | 
			
		||||
    .on('all', async (event, path) => {
 | 
			
		||||
      // Ignore other events.
 | 
			
		||||
      if (!['add', 'change'].includes(event)) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (/\.langium$/.test(path)) {
 | 
			
		||||
        await generateLangium();
 | 
			
		||||
      }
 | 
			
		||||
      console.log(`${path} changed. Rebuilding...`);
 | 
			
		||||
      handleFileChange();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  app.use(cors());
 | 
			
		||||
  app.get('/events', eventsHandler);
 | 
			
		||||
  for (const { packageName } of Object.values(packageOptions)) {
 | 
			
		||||
    app.use(express.static(`./packages/${packageName}/dist`));
 | 
			
		||||
  }
 | 
			
		||||
  app.use(express.static('demos'));
 | 
			
		||||
  app.use(express.static('cypress/platform'));
 | 
			
		||||
 | 
			
		||||
  app.listen(9000, () => {
 | 
			
		||||
    console.log(`Listening on http://localhost:9000`);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
createServer();
 | 
			
		||||
							
								
								
									
										101
									
								
								.esbuild/util.ts
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								.esbuild/util.ts
									
									
									
									
									
								
							@@ -1,101 +0,0 @@
 | 
			
		||||
import { resolve } from 'path';
 | 
			
		||||
import { fileURLToPath } from 'url';
 | 
			
		||||
import type { BuildOptions } from 'esbuild';
 | 
			
		||||
import { readFileSync } from 'fs';
 | 
			
		||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
 | 
			
		||||
import { packageOptions } from '../.build/common.js';
 | 
			
		||||
import { jisonPlugin } from './jisonPlugin.js';
 | 
			
		||||
 | 
			
		||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
 | 
			
		||||
 | 
			
		||||
export interface MermaidBuildOptions {
 | 
			
		||||
  minify: boolean;
 | 
			
		||||
  core: boolean;
 | 
			
		||||
  metafile: boolean;
 | 
			
		||||
  format: 'esm' | 'iife';
 | 
			
		||||
  entryName: keyof typeof packageOptions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName'> = {
 | 
			
		||||
  minify: false,
 | 
			
		||||
  metafile: false,
 | 
			
		||||
  core: false,
 | 
			
		||||
  format: 'esm',
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
const buildOptions = (override: BuildOptions): BuildOptions => {
 | 
			
		||||
  return {
 | 
			
		||||
    bundle: true,
 | 
			
		||||
    minify: true,
 | 
			
		||||
    keepNames: true,
 | 
			
		||||
    platform: 'browser',
 | 
			
		||||
    tsconfig: 'tsconfig.json',
 | 
			
		||||
    resolveExtensions: ['.ts', '.js', '.json', '.jison', '.yaml'],
 | 
			
		||||
    external: ['require', 'fs', 'path'],
 | 
			
		||||
    outdir: 'dist',
 | 
			
		||||
    plugins: [jisonPlugin, jsonSchemaPlugin],
 | 
			
		||||
    sourcemap: 'external',
 | 
			
		||||
    ...override,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
 | 
			
		||||
  if (core) {
 | 
			
		||||
    fileName += '.core';
 | 
			
		||||
  } else if (format === 'esm') {
 | 
			
		||||
    fileName += '.esm';
 | 
			
		||||
  }
 | 
			
		||||
  if (minify) {
 | 
			
		||||
    fileName += '.min';
 | 
			
		||||
  }
 | 
			
		||||
  return fileName;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
 | 
			
		||||
  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({
 | 
			
		||||
    absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
 | 
			
		||||
    entryPoints: {
 | 
			
		||||
      [outFileName]: `src/${file}`,
 | 
			
		||||
    },
 | 
			
		||||
    metafile,
 | 
			
		||||
    minify,
 | 
			
		||||
    logLevel: 'info',
 | 
			
		||||
    chunkNames: `chunks/${outFileName}/[name]-[hash]`,
 | 
			
		||||
    define: {
 | 
			
		||||
      'import.meta.vitest': 'undefined',
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (core) {
 | 
			
		||||
    const { dependencies } = JSON.parse(
 | 
			
		||||
      readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
 | 
			
		||||
    );
 | 
			
		||||
    // Core build is used to generate file without bundled dependencies.
 | 
			
		||||
    // This is used by downstream projects to bundle dependencies themselves.
 | 
			
		||||
    // Ignore dependencies and any dependencies of dependencies
 | 
			
		||||
    external.push(...Object.keys(dependencies));
 | 
			
		||||
    output.external = external;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (format === 'iife') {
 | 
			
		||||
    output.format = 'iife';
 | 
			
		||||
    output.splitting = false;
 | 
			
		||||
    output.globalName = '__esbuild_esm_mermaid';
 | 
			
		||||
    // Workaround for removing the .default access in esbuild IIFE.
 | 
			
		||||
    // https://github.com/mermaid-js/mermaid/pull/4109#discussion_r1292317396
 | 
			
		||||
    output.footer = {
 | 
			
		||||
      js: 'globalThis.mermaid = globalThis.__esbuild_esm_mermaid.default;',
 | 
			
		||||
    };
 | 
			
		||||
    output.outExtension = { '.js': '.js' };
 | 
			
		||||
  } else {
 | 
			
		||||
    output.format = 'esm';
 | 
			
		||||
    output.splitting = true;
 | 
			
		||||
    output.outExtension = { '.js': '.mjs' };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return output;
 | 
			
		||||
};
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
.gitignore
 | 
			
		||||
							
								
								
									
										8
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
dist/**
 | 
			
		||||
.github/**
 | 
			
		||||
docs/Setup.md
 | 
			
		||||
cypress.config.js
 | 
			
		||||
cypress/plugins/index.js
 | 
			
		||||
coverage
 | 
			
		||||
*.json
 | 
			
		||||
node_modules
 | 
			
		||||
@@ -14,7 +14,7 @@ module.exports = {
 | 
			
		||||
    },
 | 
			
		||||
    tsconfigRootDir: __dirname,
 | 
			
		||||
    sourceType: 'module',
 | 
			
		||||
    ecmaVersion: 2022,
 | 
			
		||||
    ecmaVersion: 2020,
 | 
			
		||||
    allowAutomaticSingleRunInference: true,
 | 
			
		||||
    project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
 | 
			
		||||
    parser: '@typescript-eslint/parser',
 | 
			
		||||
@@ -23,7 +23,7 @@ module.exports = {
 | 
			
		||||
    'eslint:recommended',
 | 
			
		||||
    'plugin:@typescript-eslint/recommended',
 | 
			
		||||
    'plugin:json/recommended',
 | 
			
		||||
    'plugin:markdown/recommended-legacy',
 | 
			
		||||
    'plugin:markdown/recommended',
 | 
			
		||||
    'plugin:@cspell/recommended',
 | 
			
		||||
    'prettier',
 | 
			
		||||
  ],
 | 
			
		||||
@@ -53,7 +53,6 @@ module.exports = {
 | 
			
		||||
    '@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',
 | 
			
		||||
      {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/codecov.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/codecov.yaml
									
									
									
									
										vendored
									
									
								
							@@ -15,4 +15,3 @@ coverage:
 | 
			
		||||
      # Turing off for now as code coverage isn't stable and causes unnecessary build failures.
 | 
			
		||||
      # default:
 | 
			
		||||
      #   threshold: 2%
 | 
			
		||||
    patch: off
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/lychee.toml
									
									
									
									
										vendored
									
									
								
							@@ -41,10 +41,7 @@ exclude = [
 | 
			
		||||
"https://bundlephobia.com",
 | 
			
		||||
 | 
			
		||||
# Chrome webstore migration issue. Temporary
 | 
			
		||||
"https://chromewebstore.google.com",
 | 
			
		||||
 | 
			
		||||
# Drupal 403
 | 
			
		||||
"https://(www.)?drupal.org"
 | 
			
		||||
"https://chromewebstore.google.com"
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
# Exclude all private IPs from checking.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-docs.yml
									
									
									
									
										vendored
									
									
								
							@@ -18,7 +18,7 @@ jobs:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@v4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -18,7 +18,7 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							@@ -33,7 +33,7 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      # Initializes the CodeQL tools for scanning.
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@v3
 | 
			
		||||
        uses: github/codeql-action/init@v2
 | 
			
		||||
        with:
 | 
			
		||||
          config-file: ./.github/codeql/codeql-config.yml
 | 
			
		||||
          languages: ${{ matrix.language }}
 | 
			
		||||
@@ -45,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@v3
 | 
			
		||||
        uses: github/codeql-action/autobuild@v2
 | 
			
		||||
 | 
			
		||||
      # ℹ️ 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
 | 
			
		||||
@@ -59,4 +59,4 @@ jobs:
 | 
			
		||||
      #   make release
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@v3
 | 
			
		||||
        uses: github/codeql-action/analyze@v2
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
								
							@@ -17,4 +17,4 @@ jobs:
 | 
			
		||||
      - name: 'Checkout Repository'
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      - name: 'Dependency Review'
 | 
			
		||||
        uses: actions/dependency-review-action@v4
 | 
			
		||||
        uses: actions/dependency-review-action@v3
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/e2e-applitools.yml
									
									
									
									
										vendored
									
									
								
							@@ -32,7 +32,7 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										120
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,9 @@
 | 
			
		||||
# We use github cache to save snapshots between runs.
 | 
			
		||||
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
 | 
			
		||||
# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
 | 
			
		||||
# These are then downloaded before running the E2E, providing the reference snapshots.
 | 
			
		||||
# If there are any errors, the diff image is uploaded to artifacts, and the user is notified.
 | 
			
		||||
 | 
			
		||||
name: E2E
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
@@ -11,19 +17,9 @@ permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  # For PRs and MergeQueues, the target commit is used, and for push events to non-develop branches, github.event.previous is used if available. Otherwise, 'develop' is used.
 | 
			
		||||
  targetHash: >-
 | 
			
		||||
    ${{ 
 | 
			
		||||
      github.event.pull_request.base.sha || 
 | 
			
		||||
      github.event.merge_group.base_sha || 
 | 
			
		||||
      (
 | 
			
		||||
        (
 | 
			
		||||
          (github.event_name == 'push' && github.ref == 'refs/heads/develop') || 
 | 
			
		||||
          github.event.before == '0000000000000000000000000000000000000000'
 | 
			
		||||
        ) && 'develop'
 | 
			
		||||
      ) || 
 | 
			
		||||
      github.event.before
 | 
			
		||||
    }}
 | 
			
		||||
  # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
 | 
			
		||||
  targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before)  }}
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  cache:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
@@ -32,7 +28,7 @@ jobs:
 | 
			
		||||
      options: --user 1001
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
@@ -52,19 +48,14 @@ jobs:
 | 
			
		||||
        with:
 | 
			
		||||
          ref: ${{ env.targetHash }}
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@v4
 | 
			
		||||
        id: cypress-snapshot-gen
 | 
			
		||||
        if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
 | 
			
		||||
        uses: cypress-io/github-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          # just perform install
 | 
			
		||||
          runTests: false
 | 
			
		||||
 | 
			
		||||
      - name: Calculate bundle size
 | 
			
		||||
        if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true'}}
 | 
			
		||||
        run: |
 | 
			
		||||
          pnpm run build:viz
 | 
			
		||||
          mkdir -p cypress/snapshots/stats/base
 | 
			
		||||
          mv stats cypress/snapshots/stats/base
 | 
			
		||||
          start: pnpm run dev
 | 
			
		||||
          wait-on: 'http://localhost:9000'
 | 
			
		||||
          browser: chrome
 | 
			
		||||
 | 
			
		||||
  e2e:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
@@ -79,7 +70,7 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
@@ -90,35 +81,20 @@ jobs:
 | 
			
		||||
      # These cached snapshots are downloaded, providing the reference snapshots.
 | 
			
		||||
      - name: Cache snapshots
 | 
			
		||||
        id: cache-snapshot
 | 
			
		||||
        uses: actions/cache/restore@v4
 | 
			
		||||
        uses: actions/cache/restore@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: ./cypress/snapshots
 | 
			
		||||
          key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        uses: cypress-io/github-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          runTests: false
 | 
			
		||||
 | 
			
		||||
      - name: Output size diff
 | 
			
		||||
        if: ${{ matrix.containers == 1 }}
 | 
			
		||||
        run: |
 | 
			
		||||
          pnpm run build:viz
 | 
			
		||||
          mv stats cypress/snapshots/stats/head
 | 
			
		||||
          echo '## Bundle size difference' >> "$GITHUB_STEP_SUMMARY"
 | 
			
		||||
          echo '' >> "$GITHUB_STEP_SUMMARY"
 | 
			
		||||
          npx tsx scripts/size.ts >> "$GITHUB_STEP_SUMMARY"
 | 
			
		||||
 | 
			
		||||
      # Install NPM dependencies, cache them correctly
 | 
			
		||||
      # and run all Cypress tests
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@v6
 | 
			
		||||
        uses: cypress-io/github-action@v4
 | 
			
		||||
        id: cypress
 | 
			
		||||
        # If CYPRESS_RECORD_KEY is set, run in parallel on all containers
 | 
			
		||||
        # Otherwise (e.g. if running from fork), we run on a single container only
 | 
			
		||||
        if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
 | 
			
		||||
        with:
 | 
			
		||||
          install: false
 | 
			
		||||
          start: pnpm run dev:coverage
 | 
			
		||||
          wait-on: 'http://localhost:9000'
 | 
			
		||||
          browser: chrome
 | 
			
		||||
@@ -130,13 +106,9 @@ jobs:
 | 
			
		||||
          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@v4
 | 
			
		||||
        uses: codecov/codecov-action@v3
 | 
			
		||||
        # 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:
 | 
			
		||||
@@ -146,3 +118,55 @@ jobs:
 | 
			
		||||
          fail_ci_if_error: false
 | 
			
		||||
          verbose: true
 | 
			
		||||
          token: 6845cc80-77ee-4e17-85a1-026cd95e0766
 | 
			
		||||
 | 
			
		||||
      # We upload the artifacts into numbered archives to prevent overwriting
 | 
			
		||||
      - name: Upload Artifacts
 | 
			
		||||
        uses: actions/upload-artifact@v4
 | 
			
		||||
        if: ${{ always() }}
 | 
			
		||||
        with:
 | 
			
		||||
          name: snapshots-${{ matrix.containers }}
 | 
			
		||||
          retention-days: 1
 | 
			
		||||
          path: ./cypress/snapshots
 | 
			
		||||
 | 
			
		||||
  combineArtifacts:
 | 
			
		||||
    needs: e2e
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    if: ${{ always() }}
 | 
			
		||||
    steps:
 | 
			
		||||
      # Download all snapshot artifacts and merge them into a single folder
 | 
			
		||||
      - name: Download All Artifacts
 | 
			
		||||
        uses: actions/download-artifact@v4
 | 
			
		||||
        with:
 | 
			
		||||
          path: snapshots
 | 
			
		||||
          pattern: snapshots-*
 | 
			
		||||
          merge-multiple: true
 | 
			
		||||
 | 
			
		||||
      # For successful push events, we save the snapshots cache
 | 
			
		||||
      - name: Save snapshots cache
 | 
			
		||||
        id: cache-upload
 | 
			
		||||
        if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }}
 | 
			
		||||
        uses: actions/cache/save@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: ./snapshots
 | 
			
		||||
          key: ${{ runner.os }}-snapshots-${{ github.event.after }}
 | 
			
		||||
 | 
			
		||||
      - name: Flatten images to a folder
 | 
			
		||||
        if: ${{ needs.e2e.result == 'failure'  }}
 | 
			
		||||
        run: |
 | 
			
		||||
          mkdir errors
 | 
			
		||||
          cd snapshots
 | 
			
		||||
          find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \;
 | 
			
		||||
 | 
			
		||||
      - name: Upload Error snapshots
 | 
			
		||||
        if: ${{ needs.e2e.result == 'failure' }}
 | 
			
		||||
        uses: actions/upload-artifact@v4
 | 
			
		||||
        id: upload-artifacts
 | 
			
		||||
        with:
 | 
			
		||||
          name: error-snapshots
 | 
			
		||||
          retention-days: 10
 | 
			
		||||
          path: errors/
 | 
			
		||||
 | 
			
		||||
      - name: Notify Users
 | 
			
		||||
        if: ${{ needs.e2e.result == 'failure' }}
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/link-checker.yml
									
									
									
									
										vendored
									
									
								
							@@ -29,7 +29,7 @@ jobs:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - name: Restore lychee cache
 | 
			
		||||
        uses: actions/cache@v4
 | 
			
		||||
        uses: actions/cache@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: .lycheecache
 | 
			
		||||
          key: cache-lychee-${{ github.sha }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							@@ -19,7 +19,7 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
@@ -37,9 +37,9 @@ jobs:
 | 
			
		||||
      - name: Run Linting
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: |
 | 
			
		||||
          if ! pnpm run lint:ci; then
 | 
			
		||||
          if ! pnpm run lint; then
 | 
			
		||||
              # print a nice error message on lint failure
 | 
			
		||||
              ERROR_MESSAGE='Running `pnpm run lint:ci` failed.'
 | 
			
		||||
              ERROR_MESSAGE='Running `pnpm run lint` failed.'
 | 
			
		||||
              ERROR_MESSAGE+=' Running `pnpm -w run lint:fix` may fix this issue. '
 | 
			
		||||
              ERROR_MESSAGE+=" If this error doesn't occur on your local machine,"
 | 
			
		||||
              ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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@v6
 | 
			
		||||
        uses: release-drafter/release-drafter@v5
 | 
			
		||||
        with:
 | 
			
		||||
          config-name: pr-labeler.yml
 | 
			
		||||
          disable-autolabeler: false
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							@@ -25,7 +25,7 @@ jobs:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@v4
 | 
			
		||||
@@ -37,13 +37,13 @@ jobs:
 | 
			
		||||
        run: pnpm install --frozen-lockfile
 | 
			
		||||
 | 
			
		||||
      - name: Setup Pages
 | 
			
		||||
        uses: actions/configure-pages@v4
 | 
			
		||||
        uses: actions/configure-pages@v3
 | 
			
		||||
 | 
			
		||||
      - name: Run Build
 | 
			
		||||
        run: pnpm --filter mermaid run docs:build:vitepress
 | 
			
		||||
 | 
			
		||||
      - name: Upload artifact
 | 
			
		||||
        uses: actions/upload-pages-artifact@v3
 | 
			
		||||
        uses: actions/upload-pages-artifact@v1
 | 
			
		||||
        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@v4
 | 
			
		||||
        uses: actions/deploy-pages@v2
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/release-draft.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release-draft.yml
									
									
									
									
										vendored
									
									
								
							@@ -16,7 +16,7 @@ jobs:
 | 
			
		||||
      pull-requests: read # required to read PR titles/labels
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Draft Release
 | 
			
		||||
        uses: release-drafter/release-drafter@v6
 | 
			
		||||
        uses: release-drafter/release-drafter@v5
 | 
			
		||||
        with:
 | 
			
		||||
          disable-autolabeler: true
 | 
			
		||||
        env:
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ jobs:
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 0
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
        uses: actions/setup-node@v4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							@@ -11,7 +11,7 @@ jobs:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: fregante/setup-git-user@v2
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							@@ -11,7 +11,7 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
        # uses version from "packageManager" field in package.json
 | 
			
		||||
 | 
			
		||||
      - name: Setup Node.js
 | 
			
		||||
@@ -39,7 +39,7 @@ jobs:
 | 
			
		||||
          pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts --coverage
 | 
			
		||||
 | 
			
		||||
      - name: Upload Coverage to Codecov
 | 
			
		||||
        uses: codecov/codecov-action@v4
 | 
			
		||||
        uses: codecov/codecov-action@v3
 | 
			
		||||
        # Run step only pushes to develop and pull_requests
 | 
			
		||||
        if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
 | 
			
		||||
        with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/update-browserlist.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,7 +9,7 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: pnpm/action-setup@v2
 | 
			
		||||
      - uses: pnpm/action-setup@v4
 | 
			
		||||
      - run: npx update-browserslist-db@latest
 | 
			
		||||
      - name: Commit changes
 | 
			
		||||
        uses: EndBug/add-and-commit@v9
 | 
			
		||||
@@ -19,7 +19,7 @@ jobs:
 | 
			
		||||
          message: 'chore: update browsers list'
 | 
			
		||||
          push: false
 | 
			
		||||
      - name: Create Pull Request
 | 
			
		||||
        uses: peter-evans/create-pull-request@v6
 | 
			
		||||
        uses: peter-evans/create-pull-request@v5
 | 
			
		||||
        with:
 | 
			
		||||
          branch: update-browserslist
 | 
			
		||||
          title: Update Browserslist
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -46,9 +46,4 @@ stats/
 | 
			
		||||
 | 
			
		||||
demos/dev/**
 | 
			
		||||
!/demos/dev/example.html
 | 
			
		||||
!/demos/dev/reload.js
 | 
			
		||||
tsx-0/**
 | 
			
		||||
vite.config.ts.timestamp-*
 | 
			
		||||
 | 
			
		||||
# autogenereated by langium-cli
 | 
			
		||||
generated/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.husky/commit-msg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								.husky/commit-msg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# . "$(dirname "$0")/_/husky.sh"
 | 
			
		||||
 | 
			
		||||
# npx --no-install commitlint --edit $1
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
. "$(dirname "$0")/_/husky.sh"
 | 
			
		||||
 | 
			
		||||
NODE_OPTIONS="--max_old_space_size=8192" pnpm run pre-commit
 | 
			
		||||
pnpm run pre-commit
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,10 @@
 | 
			
		||||
export default {
 | 
			
		||||
  '!(docs/**/*)*.{ts,js,html,md,mts}': [
 | 
			
		||||
    'biome check --no-errors-on-unmatched --files-ignore-unknown=true --write',
 | 
			
		||||
    'eslint --cache --cache-strategy content --fix',
 | 
			
		||||
    // don't cache prettier yet, since we use `prettier-plugin-jsdoc`,
 | 
			
		||||
    // and prettier doesn't invalidate cache on plugin updates"
 | 
			
		||||
    // https://prettier.io/docs/en/cli.html#--cache
 | 
			
		||||
    'prettier --write',
 | 
			
		||||
  ],
 | 
			
		||||
  '.cspell/*.txt': ['tsx scripts/fixCSpell.ts'],
 | 
			
		||||
  '**/*.jison': ['pnpm -w run lint:jison'],
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
20.12.2
 | 
			
		||||
v20.11.1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
dist
 | 
			
		||||
cypress/platform/xss3.html
 | 
			
		||||
.cache
 | 
			
		||||
.pnpm-store
 | 
			
		||||
coverage
 | 
			
		||||
# Autogenerated by PNPM
 | 
			
		||||
pnpm-lock.yaml
 | 
			
		||||
stats
 | 
			
		||||
**/.vitepress/components.d.ts
 | 
			
		||||
**/.vitepress/cache
 | 
			
		||||
.nyc_output
 | 
			
		||||
# Autogenerated by `pnpm run --filter mermaid types:build-config`
 | 
			
		||||
packages/mermaid/src/config.type.ts
 | 
			
		||||
# Ignore the files creates in /demos/dev except for example.html
 | 
			
		||||
demos/dev/**
 | 
			
		||||
!/demos/dev/example.html
 | 
			
		||||
							
								
								
									
										7
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "endOfLine": "auto",
 | 
			
		||||
  "printWidth": 100,
 | 
			
		||||
  "singleQuote": true,
 | 
			
		||||
  "useTabs": false,
 | 
			
		||||
  "tabWidth": 2
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +1,13 @@
 | 
			
		||||
import { build, type InlineConfig, type PluginOption } from 'vite';
 | 
			
		||||
import { build, InlineConfig, type PluginOption } from 'vite';
 | 
			
		||||
import { resolve } from 'path';
 | 
			
		||||
import { fileURLToPath } from 'url';
 | 
			
		||||
import jisonPlugin from './jisonPlugin.js';
 | 
			
		||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
 | 
			
		||||
import { readFileSync } from 'fs';
 | 
			
		||||
import typescript from '@rollup/plugin-typescript';
 | 
			
		||||
import { visualizer } from 'rollup-plugin-visualizer';
 | 
			
		||||
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
 | 
			
		||||
import istanbul from 'vite-plugin-istanbul';
 | 
			
		||||
import { packageOptions } from '../.build/common.js';
 | 
			
		||||
import { generateLangium } from '../.build/generateLangium.js';
 | 
			
		||||
 | 
			
		||||
const visualize = process.argv.includes('--visualize');
 | 
			
		||||
const watch = process.argv.includes('--watch');
 | 
			
		||||
@@ -37,6 +36,24 @@ const visualizerOptions = (packageName: string, core = false): PluginOption[] =>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const packageOptions = {
 | 
			
		||||
  mermaid: {
 | 
			
		||||
    name: 'mermaid',
 | 
			
		||||
    packageName: 'mermaid',
 | 
			
		||||
    file: 'mermaid.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-example-diagram': {
 | 
			
		||||
    name: 'mermaid-example-diagram',
 | 
			
		||||
    packageName: 'mermaid-example-diagram',
 | 
			
		||||
    file: 'detector.ts',
 | 
			
		||||
  },
 | 
			
		||||
  'mermaid-zenuml': {
 | 
			
		||||
    name: 'mermaid-zenuml',
 | 
			
		||||
    packageName: 'mermaid-zenuml',
 | 
			
		||||
    file: 'detector.ts',
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface BuildOptions {
 | 
			
		||||
  minify: boolean | 'esbuild';
 | 
			
		||||
  core?: boolean;
 | 
			
		||||
@@ -48,15 +65,41 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
 | 
			
		||||
  const external: (string | RegExp)[] = ['require', 'fs', 'path'];
 | 
			
		||||
  console.log(entryName, packageOptions[entryName]);
 | 
			
		||||
  const { name, file, packageName } = packageOptions[entryName];
 | 
			
		||||
  const output: OutputOptions = [
 | 
			
		||||
  let output: OutputOptions = [
 | 
			
		||||
    {
 | 
			
		||||
      name,
 | 
			
		||||
      format: 'esm',
 | 
			
		||||
      sourcemap,
 | 
			
		||||
      entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name,
 | 
			
		||||
      format: 'umd',
 | 
			
		||||
      sourcemap,
 | 
			
		||||
      entryFileNames: `${name}${minify ? '.min' : ''}.js`,
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  if (core) {
 | 
			
		||||
    const { dependencies } = JSON.parse(
 | 
			
		||||
      readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
 | 
			
		||||
    );
 | 
			
		||||
    // Core build is used to generate file without bundled dependencies.
 | 
			
		||||
    // This is used by downstream projects to bundle dependencies themselves.
 | 
			
		||||
    // Ignore dependencies and any dependencies of dependencies
 | 
			
		||||
    // Adapted from the RegEx used by `rollup-plugin-node`
 | 
			
		||||
    external.push(new RegExp('^(?:' + Object.keys(dependencies).join('|') + ')(?:/.+)?$'));
 | 
			
		||||
    // This needs to be an array. Otherwise vite will build esm & umd with same name and overwrite esm with umd.
 | 
			
		||||
    output = [
 | 
			
		||||
      {
 | 
			
		||||
        name,
 | 
			
		||||
        format: 'esm',
 | 
			
		||||
        sourcemap,
 | 
			
		||||
        entryFileNames: `${name}.core.mjs`,
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const config: InlineConfig = {
 | 
			
		||||
    configFile: false,
 | 
			
		||||
    build: {
 | 
			
		||||
@@ -86,7 +129,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
 | 
			
		||||
      // @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'],
 | 
			
		||||
        exclude: ['node_modules', 'test/', '__mocks__'],
 | 
			
		||||
        extension: ['.js', '.ts'],
 | 
			
		||||
        requireEnv: true,
 | 
			
		||||
        forceBuildInstrument: coverage,
 | 
			
		||||
@@ -106,28 +149,24 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
 | 
			
		||||
 | 
			
		||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
 | 
			
		||||
  await build(getBuildConfig({ minify: false, entryName }));
 | 
			
		||||
  await build(getBuildConfig({ minify: 'esbuild', entryName }));
 | 
			
		||||
  await build(getBuildConfig({ minify: false, core: true, entryName }));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const main = async () => {
 | 
			
		||||
  const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
 | 
			
		||||
  for (const pkg of packageNames.filter(
 | 
			
		||||
    (pkg) => !mermaidOnly || pkg === 'mermaid' || pkg === 'parser'
 | 
			
		||||
  )) {
 | 
			
		||||
  for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
 | 
			
		||||
    await buildPackage(pkg);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
await generateLangium();
 | 
			
		||||
 | 
			
		||||
if (watch) {
 | 
			
		||||
  await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));
 | 
			
		||||
  build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
 | 
			
		||||
  if (!mermaidOnly) {
 | 
			
		||||
    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' }));
 | 
			
		||||
  await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
 | 
			
		||||
  await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
 | 
			
		||||
} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import { transformJison } from '../.build/jisonTransformer.js';
 | 
			
		||||
 | 
			
		||||
import { transformJison } from './jisonTransformer.js';
 | 
			
		||||
const fileRegex = /\.(jison)$/;
 | 
			
		||||
 | 
			
		||||
export default function jison() {
 | 
			
		||||
  return {
 | 
			
		||||
    name: 'jison',
 | 
			
		||||
 | 
			
		||||
    transform(src: string, id: string) {
 | 
			
		||||
      if (fileRegex.test(id)) {
 | 
			
		||||
        return {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,110 @@
 | 
			
		||||
import type { PluginOption } from 'vite';
 | 
			
		||||
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
 | 
			
		||||
import { load, JSON_SCHEMA } from 'js-yaml';
 | 
			
		||||
import assert from 'node:assert';
 | 
			
		||||
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
 | 
			
		||||
import { PluginOption } from 'vite';
 | 
			
		||||
 | 
			
		||||
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * All of the keys in the mermaid config that have a mermaid diagram config.
 | 
			
		||||
 */
 | 
			
		||||
const MERMAID_CONFIG_DIAGRAM_KEYS = [
 | 
			
		||||
  'flowchart',
 | 
			
		||||
  'sequence',
 | 
			
		||||
  'gantt',
 | 
			
		||||
  'journey',
 | 
			
		||||
  'class',
 | 
			
		||||
  'state',
 | 
			
		||||
  'er',
 | 
			
		||||
  'pie',
 | 
			
		||||
  'quadrantChart',
 | 
			
		||||
  'xyChart',
 | 
			
		||||
  'requirement',
 | 
			
		||||
  'mindmap',
 | 
			
		||||
  'timeline',
 | 
			
		||||
  'gitGraph',
 | 
			
		||||
  'c4',
 | 
			
		||||
  'sankey',
 | 
			
		||||
  'block',
 | 
			
		||||
] as const;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate default values from the JSON Schema.
 | 
			
		||||
 *
 | 
			
		||||
 * AJV does not support nested default values yet (or default values with $ref),
 | 
			
		||||
 * so we need to manually find them (this may be fixed in ajv v9).
 | 
			
		||||
 *
 | 
			
		||||
 * @param mermaidConfigSchema - The Mermaid JSON Schema to use.
 | 
			
		||||
 * @returns The default mermaid config object.
 | 
			
		||||
 */
 | 
			
		||||
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
 | 
			
		||||
  const ajv = new Ajv2019({
 | 
			
		||||
    useDefaults: true,
 | 
			
		||||
    allowUnionTypes: true,
 | 
			
		||||
    strict: true,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  ajv.addKeyword({
 | 
			
		||||
    keyword: 'meta:enum', // used by jsonschema2md
 | 
			
		||||
    errors: false,
 | 
			
		||||
  });
 | 
			
		||||
  ajv.addKeyword({
 | 
			
		||||
    keyword: 'tsType', // used by json-schema-to-typescript
 | 
			
		||||
    errors: false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
 | 
			
		||||
  // (may be fixed in v9) so we need to manually use sub-schemas
 | 
			
		||||
  const mermaidDefaultConfig = {};
 | 
			
		||||
 | 
			
		||||
  assert.ok(mermaidConfigSchema.$defs);
 | 
			
		||||
  const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
 | 
			
		||||
 | 
			
		||||
  for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
 | 
			
		||||
    const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
 | 
			
		||||
    const [root, defs, defName] = subSchemaRef.split('/');
 | 
			
		||||
    assert.strictEqual(root, '#');
 | 
			
		||||
    assert.strictEqual(defs, '$defs');
 | 
			
		||||
    const subSchema = {
 | 
			
		||||
      $schema: mermaidConfigSchema.$schema,
 | 
			
		||||
      $defs: mermaidConfigSchema.$defs,
 | 
			
		||||
      ...mermaidConfigSchema.$defs[defName],
 | 
			
		||||
    } as JSONSchemaType<BaseDiagramConfig>;
 | 
			
		||||
 | 
			
		||||
    const validate = ajv.compile(subSchema);
 | 
			
		||||
 | 
			
		||||
    mermaidDefaultConfig[key] = {};
 | 
			
		||||
 | 
			
		||||
    for (const required of subSchema.required ?? []) {
 | 
			
		||||
      if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
 | 
			
		||||
        mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!validate(mermaidDefaultConfig[key])) {
 | 
			
		||||
      throw new Error(
 | 
			
		||||
        `schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
 | 
			
		||||
          validate.errors,
 | 
			
		||||
          undefined,
 | 
			
		||||
          2
 | 
			
		||||
        )}`
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const validate = ajv.compile(mermaidConfigSchema);
 | 
			
		||||
 | 
			
		||||
  if (!validate(mermaidDefaultConfig)) {
 | 
			
		||||
    throw new Error(
 | 
			
		||||
      `Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
 | 
			
		||||
        validate.errors,
 | 
			
		||||
        undefined,
 | 
			
		||||
        2
 | 
			
		||||
      )}`
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return mermaidDefaultConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
 | 
			
		||||
@@ -16,13 +121,32 @@ export default function jsonSchemaPlugin(): PluginOption {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const jsonSchema = loadSchema(src, idAsUrl.pathname);
 | 
			
		||||
      return {
 | 
			
		||||
        code: idAsUrl.searchParams.get('only-defaults')
 | 
			
		||||
          ? getDefaults(jsonSchema)
 | 
			
		||||
          : getSchema(jsonSchema),
 | 
			
		||||
        map: null, // no source map
 | 
			
		||||
      };
 | 
			
		||||
      if (idAsUrl.searchParams.get('only-defaults')) {
 | 
			
		||||
        const jsonSchema = load(src, {
 | 
			
		||||
          filename: idAsUrl.pathname,
 | 
			
		||||
          // only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
 | 
			
		||||
          // e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
 | 
			
		||||
          schema: JSON_SCHEMA,
 | 
			
		||||
        }) as JSONSchemaType<MermaidConfig>;
 | 
			
		||||
        return {
 | 
			
		||||
          code: `export default ${JSON.stringify(generateDefaults(jsonSchema), undefined, 2)};`,
 | 
			
		||||
          map: null, // no source map
 | 
			
		||||
        };
 | 
			
		||||
      } else {
 | 
			
		||||
        return {
 | 
			
		||||
          code: `export default ${JSON.stringify(
 | 
			
		||||
            load(src, {
 | 
			
		||||
              filename: idAsUrl.pathname,
 | 
			
		||||
              // only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
 | 
			
		||||
              // e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
 | 
			
		||||
              schema: JSON_SCHEMA,
 | 
			
		||||
            }),
 | 
			
		||||
            undefined,
 | 
			
		||||
            2
 | 
			
		||||
          )};`,
 | 
			
		||||
          map: null, // provide source map if available
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import express from 'express';
 | 
			
		||||
import cors from 'cors';
 | 
			
		||||
import { createServer as createViteServer } from 'vite';
 | 
			
		||||
import { packageOptions } from '../.build/common.js';
 | 
			
		||||
 | 
			
		||||
async function createServer() {
 | 
			
		||||
  const app = express();
 | 
			
		||||
@@ -15,9 +14,9 @@ async function createServer() {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  app.use(cors());
 | 
			
		||||
  for (const { packageName } of Object.values(packageOptions)) {
 | 
			
		||||
    app.use(express.static(`./packages/${packageName}/dist`));
 | 
			
		||||
  }
 | 
			
		||||
  app.use(express.static('./packages/mermaid/dist'));
 | 
			
		||||
  app.use(express.static('./packages/mermaid-zenuml/dist'));
 | 
			
		||||
  app.use(express.static('./packages/mermaid-example-diagram/dist'));
 | 
			
		||||
  app.use(vite.middlewares);
 | 
			
		||||
  app.use(express.static('demos'));
 | 
			
		||||
  app.use(express.static('cypress/platform'));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,2 @@
 | 
			
		||||
FROM node:20.12.2-alpine3.19 AS base
 | 
			
		||||
FROM node:20.11.1-alpine3.19 AS base
 | 
			
		||||
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "drips": {
 | 
			
		||||
    "ethereum": {
 | 
			
		||||
      "ownedBy": "0x0831DDFe60d009d9448CC976157b539089aB821E"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -35,7 +35,6 @@ Try Live Editor previews of future releases: <a href="https://develop.git.mermai
 | 
			
		||||
[](https://www.npmjs.com/package/mermaid)
 | 
			
		||||
[](https://discord.gg/AgrbSrBer3)
 | 
			
		||||
[](https://twitter.com/mermaidjs_)
 | 
			
		||||
[](https://argos-ci.com)
 | 
			
		||||
 | 
			
		||||
<img src="./img/header.png" alt="" />
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								__mocks__/c4Renderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								__mocks__/c4Renderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked C4Context diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const drawPersonOrSystemArray = vi.fn();
 | 
			
		||||
export const drawBoundary = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  drawPersonOrSystemArray,
 | 
			
		||||
  drawBoundary,
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										16
									
								
								__mocks__/classRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								__mocks__/classRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked class diagram v2 renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										13
									
								
								__mocks__/classRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								__mocks__/classRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked class diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1
									
								
								__mocks__/dagre-d3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								__mocks__/dagre-d3.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
// DO NOT delete this file. It is used by vitest to mock the dagre-d3 module.
 | 
			
		||||
							
								
								
									
										3
									
								
								__mocks__/entity-decode/browser.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								__mocks__/entity-decode/browser.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
module.exports = function (txt: string) {
 | 
			
		||||
  return txt;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										16
									
								
								__mocks__/erRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								__mocks__/erRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked er diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										24
									
								
								__mocks__/flowRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								__mocks__/flowRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked flow (flowchart) diagram v2 renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
export const addVertices = vi.fn();
 | 
			
		||||
export const addEdges = vi.fn();
 | 
			
		||||
export const getClasses = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return {};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  addVertices,
 | 
			
		||||
  addEdges,
 | 
			
		||||
  getClasses,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										16
									
								
								__mocks__/ganttRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								__mocks__/ganttRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked gantt diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										13
									
								
								__mocks__/gitGraphRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								__mocks__/gitGraphRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked git (graph) diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										15
									
								
								__mocks__/journeyRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								__mocks__/journeyRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked pie (picChart) diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										8
									
								
								__mocks__/pieRenderer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								__mocks__/pieRenderer.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked pie (picChart) diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
const draw = vi.fn().mockImplementation(() => '');
 | 
			
		||||
 | 
			
		||||
export const renderer = { draw };
 | 
			
		||||
							
								
								
									
										13
									
								
								__mocks__/requirementRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								__mocks__/requirementRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked requirement diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										13
									
								
								__mocks__/sankeyRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								__mocks__/sankeyRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked Sankey diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										23
									
								
								__mocks__/sequenceRenderer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								__mocks__/sequenceRenderer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked sequence diagram renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const bounds = vi.fn();
 | 
			
		||||
export const drawActors = vi.fn();
 | 
			
		||||
export const drawActorsPopup = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  bounds,
 | 
			
		||||
  drawActors,
 | 
			
		||||
  drawActorsPopup,
 | 
			
		||||
  setConf,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										22
									
								
								__mocks__/stateRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								__mocks__/stateRenderer-v2.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Mocked state diagram v2 renderer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { vi } from 'vitest';
 | 
			
		||||
 | 
			
		||||
export const setConf = vi.fn();
 | 
			
		||||
export const getClasses = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return {};
 | 
			
		||||
});
 | 
			
		||||
export const stateDomId = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return 'mocked-stateDiagram-stateDomId';
 | 
			
		||||
});
 | 
			
		||||
export const draw = vi.fn().mockImplementation(() => {
 | 
			
		||||
  return '';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  setConf,
 | 
			
		||||
  getClasses,
 | 
			
		||||
  draw,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										229
									
								
								biome.json
									
									
									
									
									
								
							
							
						
						
									
										229
									
								
								biome.json
									
									
									
									
									
								
							@@ -1,229 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json",
 | 
			
		||||
  "files": {
 | 
			
		||||
    "ignore": [
 | 
			
		||||
      "**/contributor-names.json",
 | 
			
		||||
      "**/generated/",
 | 
			
		||||
      "**/knsv*.html",
 | 
			
		||||
      "**/local*.html",
 | 
			
		||||
      "**/stats/",
 | 
			
		||||
      "**/user-avatars/*",
 | 
			
		||||
      "./.vscode/**",
 | 
			
		||||
      "cypress/platform/current.html",
 | 
			
		||||
      "cypress/platform/experimental.html",
 | 
			
		||||
      "cypress/platform/xss3.html",
 | 
			
		||||
      "cypress/screenshots/",
 | 
			
		||||
      "cypress/snapshots/",
 | 
			
		||||
      "demos/dev/**",
 | 
			
		||||
      "packages/mermaid/src/config.type.ts"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "formatter": {
 | 
			
		||||
    "enabled": true,
 | 
			
		||||
    "formatWithErrors": false,
 | 
			
		||||
    "indentStyle": "space",
 | 
			
		||||
    "indentWidth": 2,
 | 
			
		||||
    "lineEnding": "lf",
 | 
			
		||||
    "lineWidth": 100,
 | 
			
		||||
    "attributePosition": "auto"
 | 
			
		||||
  },
 | 
			
		||||
  "organizeImports": { "enabled": false },
 | 
			
		||||
  "linter": {
 | 
			
		||||
    "enabled": true,
 | 
			
		||||
    "rules": {
 | 
			
		||||
      "recommended": false,
 | 
			
		||||
      "complexity": {
 | 
			
		||||
        "noBannedTypes": "error",
 | 
			
		||||
        "noExtraBooleanCast": "error",
 | 
			
		||||
        "noMultipleSpacesInRegularExpressionLiterals": "error",
 | 
			
		||||
        "noUselessCatch": "error",
 | 
			
		||||
        "noUselessThisAlias": "error",
 | 
			
		||||
        "noUselessTypeConstraint": "error",
 | 
			
		||||
        "noWith": "error",
 | 
			
		||||
        "useFlatMap": "error"
 | 
			
		||||
      },
 | 
			
		||||
      "correctness": {
 | 
			
		||||
        "noConstAssign": "error",
 | 
			
		||||
        "noConstantCondition": "error",
 | 
			
		||||
        "noEmptyCharacterClassInRegex": "error",
 | 
			
		||||
        "noEmptyPattern": "error",
 | 
			
		||||
        "noGlobalObjectCalls": "error",
 | 
			
		||||
        "noInnerDeclarations": "error",
 | 
			
		||||
        "noInvalidConstructorSuper": "error",
 | 
			
		||||
        "noNewSymbol": "error",
 | 
			
		||||
        "noNonoctalDecimalEscape": "error",
 | 
			
		||||
        "noPrecisionLoss": "error",
 | 
			
		||||
        "noSelfAssign": "error",
 | 
			
		||||
        "noSetterReturn": "error",
 | 
			
		||||
        "noSwitchDeclarations": "error",
 | 
			
		||||
        "noUndeclaredVariables": "error",
 | 
			
		||||
        "noUnreachable": "error",
 | 
			
		||||
        "noUnreachableSuper": "error",
 | 
			
		||||
        "noUnsafeFinally": "error",
 | 
			
		||||
        "noUnsafeOptionalChaining": "error",
 | 
			
		||||
        "noUnusedLabels": "error",
 | 
			
		||||
        "noUnusedVariables": "off",
 | 
			
		||||
        "useArrayLiterals": "off",
 | 
			
		||||
        "useIsNan": "error",
 | 
			
		||||
        "useValidForDirection": "error",
 | 
			
		||||
        "useYield": "error"
 | 
			
		||||
      },
 | 
			
		||||
      "style": {
 | 
			
		||||
        "noNamespace": "error",
 | 
			
		||||
        "useAsConstAssertion": "error",
 | 
			
		||||
        "useBlockStatements": "error",
 | 
			
		||||
        "useForOf": "error",
 | 
			
		||||
        "useImportType": "error",
 | 
			
		||||
        "useNamingConvention": {
 | 
			
		||||
          "level": "off",
 | 
			
		||||
          "options": { "strictCase": false }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "suspicious": {
 | 
			
		||||
        "noAssignInExpressions": "warn",
 | 
			
		||||
        "noAsyncPromiseExecutor": "error",
 | 
			
		||||
        "noCatchAssign": "error",
 | 
			
		||||
        "noClassAssign": "error",
 | 
			
		||||
        "noCompareNegZero": "error",
 | 
			
		||||
        "noConsoleLog": "off",
 | 
			
		||||
        "noControlCharactersInRegex": "error",
 | 
			
		||||
        "noDebugger": "error",
 | 
			
		||||
        "noDuplicateCase": "error",
 | 
			
		||||
        "noDuplicateClassMembers": "error",
 | 
			
		||||
        "noDuplicateObjectKeys": "error",
 | 
			
		||||
        "noDuplicateParameters": "error",
 | 
			
		||||
        "noEmptyBlockStatements": "off",
 | 
			
		||||
        "noExplicitAny": "off",
 | 
			
		||||
        "noExtraNonNullAssertion": "error",
 | 
			
		||||
        "noFallthroughSwitchClause": "error",
 | 
			
		||||
        "noFunctionAssign": "error",
 | 
			
		||||
        "noGlobalAssign": "error",
 | 
			
		||||
        "noImportAssign": "error",
 | 
			
		||||
        "noMisleadingCharacterClass": "error",
 | 
			
		||||
        "noMisleadingInstantiator": "error",
 | 
			
		||||
        "noPrototypeBuiltins": "off",
 | 
			
		||||
        "noRedeclare": "error",
 | 
			
		||||
        "noShadowRestrictedNames": "error",
 | 
			
		||||
        "noUnsafeDeclarationMerging": "error",
 | 
			
		||||
        "noUnsafeNegation": "error",
 | 
			
		||||
        "useGetterReturn": "error",
 | 
			
		||||
        "useIsArray": "error",
 | 
			
		||||
        "useValidTypeof": "error"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "javascript": {
 | 
			
		||||
    "formatter": {
 | 
			
		||||
      "jsxQuoteStyle": "double",
 | 
			
		||||
      "quoteProperties": "asNeeded",
 | 
			
		||||
      "trailingCommas": "es5",
 | 
			
		||||
      "semicolons": "always",
 | 
			
		||||
      "arrowParentheses": "always",
 | 
			
		||||
      "bracketSpacing": true,
 | 
			
		||||
      "bracketSameLine": false,
 | 
			
		||||
      "quoteStyle": "single",
 | 
			
		||||
      "attributePosition": "auto"
 | 
			
		||||
    },
 | 
			
		||||
    "globals": [
 | 
			
		||||
      "it",
 | 
			
		||||
      "describe",
 | 
			
		||||
      "beforeEach",
 | 
			
		||||
      "beforeAll",
 | 
			
		||||
      "afterEach",
 | 
			
		||||
      "cy",
 | 
			
		||||
      "expect",
 | 
			
		||||
      "context",
 | 
			
		||||
      "Cypress"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "overrides": [
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["cypress/**", "demos/**", "**/scripts"],
 | 
			
		||||
      "linter": { "rules": { "suspicious": { "noConsoleLog": "off" } } }
 | 
			
		||||
    },
 | 
			
		||||
    { "include": ["*.{js,jsx,mjs,cjs}"], "linter": { "rules": {} } },
 | 
			
		||||
    { "include": ["*.{ts,tsx}"], "linter": { "rules": {} } },
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["*.spec.{ts,js}", "cypress/**", "demos/**", "**/docs/**"],
 | 
			
		||||
      "linter": {
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "correctness": { "noUnusedVariables": "off" },
 | 
			
		||||
          "style": {
 | 
			
		||||
            "useNamingConvention": "off"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["*.spec.{ts,js}", "tests/**", "cypress/**/*.js"],
 | 
			
		||||
      "linter": {
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "style": {
 | 
			
		||||
            "useNamingConvention": "off"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["*.html", "*.md", "**/*.md/*"],
 | 
			
		||||
      "linter": {
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "correctness": {
 | 
			
		||||
            "noUndeclaredVariables": "off",
 | 
			
		||||
            "noUnusedVariables": "off"
 | 
			
		||||
          },
 | 
			
		||||
          "style": { "noVar": "error" }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    { "include": ["*.md"] },
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["**/*.md/**"],
 | 
			
		||||
      "linter": {
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "correctness": {
 | 
			
		||||
            "noUndeclaredVariables": "off",
 | 
			
		||||
            "noUnusedVariables": "off"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "include": ["*.ts", "*.tsx", "*.mts", "*.cts"],
 | 
			
		||||
      "linter": {
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "correctness": {
 | 
			
		||||
            "noConstAssign": "off",
 | 
			
		||||
            "noGlobalObjectCalls": "off",
 | 
			
		||||
            "noInvalidConstructorSuper": "off",
 | 
			
		||||
            "noNewSymbol": "off",
 | 
			
		||||
            "noSetterReturn": "off",
 | 
			
		||||
            "noUndeclaredVariables": "off",
 | 
			
		||||
            "noUnreachable": "off",
 | 
			
		||||
            "noUnreachableSuper": "off"
 | 
			
		||||
          },
 | 
			
		||||
          "style": {
 | 
			
		||||
            "noArguments": "error",
 | 
			
		||||
            "noVar": "error",
 | 
			
		||||
            "useConst": "error"
 | 
			
		||||
          },
 | 
			
		||||
          "suspicious": {
 | 
			
		||||
            "noDuplicateClassMembers": "off",
 | 
			
		||||
            "noDuplicateObjectKeys": "off",
 | 
			
		||||
            "noDuplicateParameters": "off",
 | 
			
		||||
            "noFunctionAssign": "off",
 | 
			
		||||
            "noImportAssign": "off",
 | 
			
		||||
            "noRedeclare": "off",
 | 
			
		||||
            "noUnsafeNegation": "off",
 | 
			
		||||
            "useGetterReturn": "off"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "vcs": {
 | 
			
		||||
    "enabled": true,
 | 
			
		||||
    "clientKind": "git",
 | 
			
		||||
    "useIgnoreFile": true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,8 +2,6 @@ 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';
 | 
			
		||||
 | 
			
		||||
export default eyesPlugin(
 | 
			
		||||
  defineConfig({
 | 
			
		||||
    projectId: 'n2sma2',
 | 
			
		||||
@@ -19,17 +17,10 @@ export default eyesPlugin(
 | 
			
		||||
          }
 | 
			
		||||
          return launchOptions;
 | 
			
		||||
        });
 | 
			
		||||
        addMatchImageSnapshotPlugin(on, config);
 | 
			
		||||
        // copy any needed variables from process.env to config.env
 | 
			
		||||
        config.env.useAppli = process.env.USE_APPLI ? true : false;
 | 
			
		||||
        config.env.useArgos = !!process.env.CI;
 | 
			
		||||
 | 
			
		||||
        if (config.env.useArgos) {
 | 
			
		||||
          registerArgosTask(on, config, {
 | 
			
		||||
            token: 'fc3a35cf5200db928d65b2047861582d9444032b',
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          addMatchImageSnapshotPlugin(on, config);
 | 
			
		||||
        }
 | 
			
		||||
        // do not forget to return the changed config object!
 | 
			
		||||
        return config;
 | 
			
		||||
      },
 | 
			
		||||
 
 | 
			
		||||
@@ -95,22 +95,8 @@ export const openURLAndVerifyRendering = (
 | 
			
		||||
  options: CypressMermaidConfig,
 | 
			
		||||
  validation?: any
 | 
			
		||||
): void => {
 | 
			
		||||
  const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
 | 
			
		||||
 | 
			
		||||
  cy.visit(url);
 | 
			
		||||
  cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
  cy.get('svg').should('be.visible');
 | 
			
		||||
 | 
			
		||||
  if (validation) {
 | 
			
		||||
    cy.get('svg').should(validation);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  verifyScreenshot(name);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const verifyScreenshot = (name: string): void => {
 | 
			
		||||
  const useAppli: boolean = Cypress.env('useAppli');
 | 
			
		||||
  const useArgos: boolean = Cypress.env('useArgos');
 | 
			
		||||
  const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
 | 
			
		||||
 | 
			
		||||
  if (useAppli) {
 | 
			
		||||
    cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`);
 | 
			
		||||
@@ -120,12 +106,21 @@ export const verifyScreenshot = (name: string): void => {
 | 
			
		||||
      batchName: Cypress.spec.name,
 | 
			
		||||
      batchId: batchId + Cypress.spec.name,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cy.visit(url);
 | 
			
		||||
  cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
  cy.get('svg').should('be.visible');
 | 
			
		||||
 | 
			
		||||
  if (validation) {
 | 
			
		||||
    cy.get('svg').should(validation);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (useAppli) {
 | 
			
		||||
    cy.log(`Check eyes ${Cypress.spec.name}`);
 | 
			
		||||
    cy.eyesCheckWindow('Click!');
 | 
			
		||||
    cy.log(`Closing eyes ${Cypress.spec.name}`);
 | 
			
		||||
    cy.eyesClose();
 | 
			
		||||
  } else if (useArgos) {
 | 
			
		||||
    cy.argosScreenshot(name);
 | 
			
		||||
  } else {
 | 
			
		||||
    cy.matchImageSnapshot(name);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { renderGraph, verifyScreenshot } from '../../helpers/util.ts';
 | 
			
		||||
import { renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
describe('Configuration', () => {
 | 
			
		||||
  describe('arrowMarkerAbsolute', () => {
 | 
			
		||||
    it('should handle default value false of arrowMarkerAbsolute', () => {
 | 
			
		||||
@@ -118,52 +118,11 @@ describe('Configuration', () => {
 | 
			
		||||
    it('should not taint the initial configuration when using multiple directives', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/regression/issue-1874.html';
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
      verifyScreenshot(
 | 
			
		||||
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
      cy.matchImageSnapshot(
 | 
			
		||||
        'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives'
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('suppressErrorRendering', () => {
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
      cy.on('uncaught:exception', (err, runnable) => {
 | 
			
		||||
        return !err.message.includes('Parse error on line');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not render error diagram if suppressErrorRendering is set', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/suppressError.html?suppressErrorRendering=true';
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
      cy.get('#test')
 | 
			
		||||
        .find('svg')
 | 
			
		||||
        .should(($svg) => {
 | 
			
		||||
          // all failing diagrams should not appear!
 | 
			
		||||
          expect($svg).to.have.length(2);
 | 
			
		||||
          // none of the diagrams should be error diagrams
 | 
			
		||||
          expect($svg).to.not.contain('Syntax error');
 | 
			
		||||
        });
 | 
			
		||||
      verifyScreenshot(
 | 
			
		||||
        'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set'
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should render error diagram if suppressErrorRendering is not set', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/suppressError.html';
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
      cy.get('#test')
 | 
			
		||||
        .find('svg')
 | 
			
		||||
        .should(($svg) => {
 | 
			
		||||
          // all five diagrams should be rendered
 | 
			
		||||
          expect($svg).to.have.length(5);
 | 
			
		||||
          // some of the diagrams should be error diagrams
 | 
			
		||||
          expect($svg).to.contain('Syntax error');
 | 
			
		||||
        });
 | 
			
		||||
      verifyScreenshot(
 | 
			
		||||
        'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set'
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
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',
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
describe('IIFE', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('http://localhost:9000/iife.html');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render when using mermaid.min.js', () => {
 | 
			
		||||
    cy.window().should('have.property', 'rendered', true);
 | 
			
		||||
    cy.get('svg').should('be.visible');
 | 
			
		||||
    cy.get('#d2').should('contain', 'Hello');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										16
									
								
								cypress/integration/other/webpackUsage.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								cypress/integration/other/webpackUsage.spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
describe('Sequencediagram', () => {
 | 
			
		||||
  it('should render a simple sequence diagrams', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/webpackUsage.html';
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('body').find('svg').should('have.length', 1);
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle html escapings properly', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('body').find('svg').should('have.length', 1);
 | 
			
		||||
 | 
			
		||||
    cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -10,6 +10,7 @@ describe('XSS', () => {
 | 
			
		||||
    cy.wait(1000).then(() => {
 | 
			
		||||
      cy.get('.mermaid').should('exist');
 | 
			
		||||
    });
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should not allow tags in the css', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ describe('C4 diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple C4Container diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -49,6 +50,7 @@ describe('C4 diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple C4Component diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -67,6 +69,7 @@ describe('C4 diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple C4Dynamic diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -90,6 +93,7 @@ describe('C4 diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple C4Deployment diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -113,5 +117,6 @@ describe('C4 diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2: should render a simple class diagrams with cardinality', () => {
 | 
			
		||||
@@ -60,6 +61,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3: should render a simple class diagram with different visibilities', () => {
 | 
			
		||||
@@ -77,6 +79,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('4: should render a simple class diagram with comments', () => {
 | 
			
		||||
@@ -106,6 +109,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('5: should render a simple class diagram with abstract method', () => {
 | 
			
		||||
@@ -117,6 +121,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6: should render a simple class diagram with static method', () => {
 | 
			
		||||
@@ -128,6 +133,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('7: should render a simple class diagram with Generic class', () => {
 | 
			
		||||
@@ -147,6 +153,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8: should render a simple class diagram with Generic class and relations', () => {
 | 
			
		||||
@@ -167,6 +174,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('9: should render a simple class diagram with clickable link', () => {
 | 
			
		||||
@@ -188,6 +196,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('10: should render a simple class diagram with clickable callback', () => {
 | 
			
		||||
@@ -209,6 +218,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('11: should render a simple class diagram with return type on method', () => {
 | 
			
		||||
@@ -223,6 +233,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('12: should render a simple class diagram with generic types', () => {
 | 
			
		||||
@@ -238,6 +249,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('13: should render a simple class diagram with css classes applied', () => {
 | 
			
		||||
@@ -255,6 +267,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('14: should render a simple class diagram with css classes applied directly', () => {
 | 
			
		||||
@@ -270,6 +283,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('15: should render a simple class diagram with css classes applied to multiple classes', () => {
 | 
			
		||||
@@ -284,6 +298,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('16: should render multiple class diagrams', () => {
 | 
			
		||||
@@ -336,6 +351,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      ],
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // it('17: should render a class diagram when useMaxWidth is true (default)', () => {
 | 
			
		||||
@@ -405,6 +421,7 @@ describe('Class diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render class diagram with newlines in title', () => {
 | 
			
		||||
@@ -422,6 +439,7 @@ describe('Class diagram', () => {
 | 
			
		||||
          +quack()
 | 
			
		||||
        }
 | 
			
		||||
      `);
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render class diagram with many newlines in title', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -218,6 +218,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        `,
 | 
			
		||||
      { loglevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities with keys', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -844,42 +844,3 @@ end
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('Title and arrow styling #4813', () => {
 | 
			
		||||
  it('should render a flowchart with title', () => {
 | 
			
		||||
    const titleString = 'Test Title';
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `---
 | 
			
		||||
      title: ${titleString}
 | 
			
		||||
      ---
 | 
			
		||||
      flowchart LR
 | 
			
		||||
      A-->B
 | 
			
		||||
      A-->C`,
 | 
			
		||||
      { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const title = svg[0].querySelector('text');
 | 
			
		||||
      expect(title.textContent).to.contain(titleString);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Render with stylized arrows', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
      A-->B
 | 
			
		||||
      B-.-oC
 | 
			
		||||
      C==xD
 | 
			
		||||
      D ~~~ A`,
 | 
			
		||||
      { flowchart: { defaultRenderer: 'elk' } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const edges = svg[0].querySelectorAll('.edges path');
 | 
			
		||||
      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');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -760,51 +760,6 @@ A ~~~ B
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3258: Should render subgraphs with main graph nodeSpacing and rankSpacing', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
      title: Subgraph nodeSpacing and rankSpacing example
 | 
			
		||||
      ---
 | 
			
		||||
      flowchart LR
 | 
			
		||||
        X --> Y
 | 
			
		||||
        subgraph X
 | 
			
		||||
          direction LR
 | 
			
		||||
          A
 | 
			
		||||
          C
 | 
			
		||||
        end
 | 
			
		||||
        subgraph Y
 | 
			
		||||
          B
 | 
			
		||||
          D
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { nodeSpacing: 1, rankSpacing: 1 } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3258: Should render subgraphs with large nodeSpacing and rankSpacing', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `---
 | 
			
		||||
      title: Subgraph nodeSpacing and rankSpacing example
 | 
			
		||||
      config:
 | 
			
		||||
        flowchart: 
 | 
			
		||||
          nodeSpacing: 250
 | 
			
		||||
          rankSpacing: 250
 | 
			
		||||
      ---
 | 
			
		||||
      flowchart LR
 | 
			
		||||
        X --> Y
 | 
			
		||||
        subgraph X
 | 
			
		||||
          direction LR
 | 
			
		||||
          A
 | 
			
		||||
          C
 | 
			
		||||
        end
 | 
			
		||||
        subgraph Y
 | 
			
		||||
          B
 | 
			
		||||
          D
 | 
			
		||||
        end
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Markdown strings flowchart (#4220)', () => {
 | 
			
		||||
    describe('html labels', () => {
 | 
			
		||||
      it('With styling and classes', () => {
 | 
			
		||||
@@ -949,18 +904,6 @@ end
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should not auto wrap when markdownAutoWrap is false', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `flowchart TD
 | 
			
		||||
    angular_velocity["\`**angular_velocity**
 | 
			
		||||
      *angular_displacement / duration*
 | 
			
		||||
      [rad/s, 1/s]
 | 
			
		||||
      {vector}\`"]
 | 
			
		||||
    frequency["frequency\n(1 / period_duration)\n[Hz, 1/s]"]`,
 | 
			
		||||
        { markdownAutoWrap: false }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  describe('Subgraph title margins', () => {
 | 
			
		||||
    it('Should render subgraphs with title margins set (LR)', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -101,12 +101,12 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      title Adding GANTT diagram to mermaid
 | 
			
		||||
      excludes weekdays 2014-01-10
 | 
			
		||||
      todayMarker off
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
      section team's critical event
 | 
			
		||||
      deadline A           :milestone, crit, deadlineA, 2024-02-01, 0
 | 
			
		||||
      deadline B           :milestone, crit, deadlineB, 2024-02-15, 0
 | 
			
		||||
      boss on leave        :bossaway, 2024-01-28, 2024-02-11
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
      section new intern
 | 
			
		||||
      onboarding           :onboarding, 2024-01-02, 1w
 | 
			
		||||
      literature review    :litreview, 2024-01-02, 10d
 | 
			
		||||
@@ -573,28 +573,7 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram exculding friday and saturday', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gantt
 | 
			
		||||
      title A Gantt Diagram
 | 
			
		||||
      dateFormat  YYYY-MM-DD
 | 
			
		||||
      excludes weekends
 | 
			
		||||
      weekend friday
 | 
			
		||||
      section Section1
 | 
			
		||||
      A task :a1, 2024-02-28, 10d`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram exculding saturday and sunday', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `gantt
 | 
			
		||||
      title A Gantt Diagram
 | 
			
		||||
      dateFormat  YYYY-MM-DD
 | 
			
		||||
      excludes weekends
 | 
			
		||||
      weekend saturday
 | 
			
		||||
      section Section1
 | 
			
		||||
      A task :a1, 2024-02-28, 10d`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render when compact is true', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
 
 | 
			
		||||
@@ -1013,524 +1013,4 @@ gitGraph TB:
 | 
			
		||||
      { gitGraph: { parallelCommits: true } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  describe('Git-Graph Bottom-to-Top Orientation Tests', () => {
 | 
			
		||||
    it('50: should render a simple gitgraph with commit on main branch | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('51: should render a simple gitgraph with commit on main branch with Id | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "One"
 | 
			
		||||
         commit id: "Two"
 | 
			
		||||
         commit id: "Three"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('52: should render a simple gitgraph with different commitTypes on main branch | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "Normal Commit"
 | 
			
		||||
         commit id: "Reverse Commit" type: REVERSE
 | 
			
		||||
         commit id: "Highlight Commit" type: HIGHLIGHT
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('53: should render a simple gitgraph with tags commitTypes on main branch | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "Normal Commit with tag" tag: "v1.0.0"
 | 
			
		||||
         commit id: "Reverse Commit with tag" type: REVERSE tag: "RC_1"
 | 
			
		||||
         commit id: "Highlight Commit" type: HIGHLIGHT  tag: "8.8.4"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('54: should render a simple gitgraph with two branches | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         branch develop
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
         commit id: "4"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "5"
 | 
			
		||||
         commit id: "6"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('55: should render a simple gitgraph with two branches and merge commit | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         branch develop
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
         commit id: "4"
 | 
			
		||||
         checkout main
 | 
			
		||||
         merge develop
 | 
			
		||||
         commit id: "5"
 | 
			
		||||
         commit id: "6"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('56: should render a simple gitgraph with three branches and tagged merge commit | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         branch nice_feature
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "4"
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         branch very_nice_feature
 | 
			
		||||
         checkout very_nice_feature
 | 
			
		||||
         commit id: "5"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "6"
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         commit id: "7"
 | 
			
		||||
         checkout main
 | 
			
		||||
         merge nice_feature id: "12345" tag: "my merge commit"
 | 
			
		||||
         checkout very_nice_feature
 | 
			
		||||
         commit id: "8"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "9"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('57: should render a simple gitgraph with more than 8 branches &  overriding variables | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
 | 
			
		||||
          'gitBranchLabel0': '#ffffff',
 | 
			
		||||
          'gitBranchLabel1': '#ffffff',
 | 
			
		||||
          'gitBranchLabel2': '#ffffff',
 | 
			
		||||
          'gitBranchLabel3': '#ffffff',
 | 
			
		||||
          'gitBranchLabel4': '#ffffff',
 | 
			
		||||
          'gitBranchLabel5': '#ffffff',
 | 
			
		||||
          'gitBranchLabel6': '#ffffff',
 | 
			
		||||
          'gitBranchLabel7': '#ffffff',
 | 
			
		||||
    } } }%%
 | 
			
		||||
    gitGraph BT:
 | 
			
		||||
      checkout main
 | 
			
		||||
      branch branch1
 | 
			
		||||
      branch branch2
 | 
			
		||||
      branch branch3
 | 
			
		||||
      branch branch4
 | 
			
		||||
      branch branch5
 | 
			
		||||
      branch branch6
 | 
			
		||||
      branch branch7
 | 
			
		||||
      branch branch8
 | 
			
		||||
      branch branch9
 | 
			
		||||
      checkout branch1
 | 
			
		||||
      commit id: "1"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('58: should render a simple gitgraph with rotated labels | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
 | 
			
		||||
          'rotateCommitLabel': true
 | 
			
		||||
    } } }%%
 | 
			
		||||
          gitGraph BT:
 | 
			
		||||
          commit id: "75f7219e83b321cd3fdde7dcf83bc7c1000a6828"
 | 
			
		||||
          commit id: "0db4784daf82736dec4569e0dc92980d328c1f2e"
 | 
			
		||||
          commit id: "7067e9973f9eaa6cd4a4b723c506d1eab598e83e"
 | 
			
		||||
          commit id: "66972321ad6c199013b5b31f03b3a86fa3f9817d"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('59: should render a simple gitgraph with horizontal labels | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
 | 
			
		||||
          'rotateCommitLabel': false
 | 
			
		||||
    } } }%%
 | 
			
		||||
          gitGraph BT:
 | 
			
		||||
          commit id: "Alpha"
 | 
			
		||||
          commit id: "Beta"
 | 
			
		||||
          commit id: "Gamma"
 | 
			
		||||
          commit id: "Delta"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('60: should render a simple gitgraph with cherry pick commit | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      gitGraph BT:
 | 
			
		||||
         commit id: "ZERO"
 | 
			
		||||
         branch develop
 | 
			
		||||
         commit id:"A"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"ONE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"B"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"TWO"
 | 
			
		||||
         cherry-pick id:"A"
 | 
			
		||||
         commit id:"THREE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"C"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('61: should render a gitgraph with cherry pick commit with custom tag | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      gitGraph BT:
 | 
			
		||||
         commit id: "ZERO"
 | 
			
		||||
         branch develop
 | 
			
		||||
         commit id:"A"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"ONE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"B"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"TWO"
 | 
			
		||||
         cherry-pick id:"A" tag: "snapshot"
 | 
			
		||||
         commit id:"THREE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"C"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('62: should render a gitgraph with cherry pick commit with no tag | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      gitGraph BT:
 | 
			
		||||
         commit id: "ZERO"
 | 
			
		||||
         branch develop
 | 
			
		||||
         commit id:"A"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"ONE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"B"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"TWO"
 | 
			
		||||
         cherry-pick id:"A" tag: ""
 | 
			
		||||
         commit id:"THREE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"C"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('63: should render a simple gitgraph with two cherry pick commit | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      gitGraph BT:
 | 
			
		||||
         commit id: "ZERO"
 | 
			
		||||
         branch develop
 | 
			
		||||
         commit id:"A"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"ONE"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"B"
 | 
			
		||||
         branch featureA
 | 
			
		||||
         commit id:"FIX"
 | 
			
		||||
         commit id: "FIX-2"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"TWO"
 | 
			
		||||
         cherry-pick id:"A"
 | 
			
		||||
         commit id:"THREE"
 | 
			
		||||
         cherry-pick id:"FIX"
 | 
			
		||||
         checkout develop
 | 
			
		||||
         commit id:"C"
 | 
			
		||||
         merge featureA
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('64: should render commits for more than 8 branches | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        gitGraph BT:
 | 
			
		||||
        checkout main
 | 
			
		||||
        %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
        commit id: "1-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        branch branch1
 | 
			
		||||
        commit id: "2-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch1
 | 
			
		||||
        branch branch2
 | 
			
		||||
        commit id: "3-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch2
 | 
			
		||||
        branch branch3
 | 
			
		||||
        commit id: "4-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch3
 | 
			
		||||
        branch branch4
 | 
			
		||||
        commit id: "5-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch4
 | 
			
		||||
        branch branch5
 | 
			
		||||
        commit id: "6-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch5
 | 
			
		||||
        branch branch6
 | 
			
		||||
        commit id: "7-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch6
 | 
			
		||||
        branch branch7
 | 
			
		||||
        commit id: "8-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch7
 | 
			
		||||
        branch branch8
 | 
			
		||||
        commit id: "9-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge branch8
 | 
			
		||||
        branch branch9
 | 
			
		||||
        commit id: "10-abcdefg"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('65: should render a simple gitgraph with three branches,custom merge commit id,tag,type | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         branch nice_feature
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "4"
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         branch very_nice_feature
 | 
			
		||||
         checkout very_nice_feature
 | 
			
		||||
         commit id: "5"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "6"
 | 
			
		||||
         checkout nice_feature
 | 
			
		||||
         commit id: "7"
 | 
			
		||||
         checkout main
 | 
			
		||||
         merge nice_feature id: "customID" tag: "customTag" type: REVERSE
 | 
			
		||||
         checkout very_nice_feature
 | 
			
		||||
         commit id: "8"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id: "9"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('66: should render a simple gitgraph with a title | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `---
 | 
			
		||||
  title: simple gitGraph
 | 
			
		||||
  ---
 | 
			
		||||
  gitGraph BT:
 | 
			
		||||
    commit id: "1-abcdefg"
 | 
			
		||||
  `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('67: should render a simple gitgraph overlapping commits | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
         commit id:"s1"
 | 
			
		||||
         commit id:"s2"
 | 
			
		||||
         branch branch1
 | 
			
		||||
         commit id:"s3"
 | 
			
		||||
         commit id:"s4"
 | 
			
		||||
         checkout main
 | 
			
		||||
         commit id:"s5"
 | 
			
		||||
         checkout branch1
 | 
			
		||||
         commit id:"s6"
 | 
			
		||||
         commit id:"s7"
 | 
			
		||||
         merge main
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('68: should render a simple gitgraph with two branches from same commit | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
        commit id:"1-abcdefg"
 | 
			
		||||
        commit id:"2-abcdefg"
 | 
			
		||||
        branch feature-001
 | 
			
		||||
        commit id:"3-abcdefg"
 | 
			
		||||
        commit id:"4-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        branch feature-002
 | 
			
		||||
        commit id:"5-abcdefg"
 | 
			
		||||
        checkout feature-001
 | 
			
		||||
        merge feature-002
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('69: should render GitGraph with branch that is not used immediately | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
        commit id:"1-abcdefg"
 | 
			
		||||
        branch x
 | 
			
		||||
        checkout main
 | 
			
		||||
        commit id:"2-abcdefg"
 | 
			
		||||
        checkout x
 | 
			
		||||
        commit id:"3-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge x
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('70: should render GitGraph with branch and sub-branch neither of which used immediately | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
        commit id:"1-abcdefg"
 | 
			
		||||
        branch x
 | 
			
		||||
        checkout main
 | 
			
		||||
        commit id:"2-abcdefg"
 | 
			
		||||
        checkout x
 | 
			
		||||
        commit id:"3-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        merge x
 | 
			
		||||
        checkout x
 | 
			
		||||
        branch y
 | 
			
		||||
        checkout x
 | 
			
		||||
        commit id:"4-abcdefg"
 | 
			
		||||
        checkout y
 | 
			
		||||
        commit id:"5-abcdefg"
 | 
			
		||||
        checkout x
 | 
			
		||||
        merge y
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('71: should render GitGraph with parallel commits | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
        commit id:"1-abcdefg"
 | 
			
		||||
        commit id:"2-abcdefg"
 | 
			
		||||
        branch develop
 | 
			
		||||
        commit id:"3-abcdefg"
 | 
			
		||||
        commit id:"4-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        branch feature
 | 
			
		||||
        commit id:"5-abcdefg"
 | 
			
		||||
        commit id:"6-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        commit id:"7-abcdefg"
 | 
			
		||||
        commit id:"8-abcdefg"
 | 
			
		||||
        `,
 | 
			
		||||
        { gitGraph: { parallelCommits: true } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('72: should render GitGraph with unconnected branches and parallel commits | Vertical Branch - Bottom-to-top', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph BT:
 | 
			
		||||
        branch dev
 | 
			
		||||
        branch v2
 | 
			
		||||
        branch feat
 | 
			
		||||
        commit id:"1-abcdefg"
 | 
			
		||||
        commit id:"2-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        commit id:"3-abcdefg"
 | 
			
		||||
        checkout dev
 | 
			
		||||
        commit id:"4-abcdefg"
 | 
			
		||||
        checkout v2
 | 
			
		||||
        commit id:"5-abcdefg"
 | 
			
		||||
        checkout main
 | 
			
		||||
        commit id:"6-abcdefg"
 | 
			
		||||
        `,
 | 
			
		||||
        { gitGraph: { parallelCommits: true } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('73: should render a simple gitgraph with three branches and tagged merge commit using switch instead of checkout', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `gitGraph
 | 
			
		||||
         commit id: "1"
 | 
			
		||||
         commit id: "2"
 | 
			
		||||
         branch nice_feature
 | 
			
		||||
         switch nice_feature
 | 
			
		||||
         commit id: "3"
 | 
			
		||||
         switch main
 | 
			
		||||
         commit id: "4"
 | 
			
		||||
         switch nice_feature
 | 
			
		||||
         branch very_nice_feature
 | 
			
		||||
         switch very_nice_feature
 | 
			
		||||
         commit id: "5"
 | 
			
		||||
         switch main
 | 
			
		||||
         commit id: "6"
 | 
			
		||||
         switch nice_feature
 | 
			
		||||
         commit id: "7"
 | 
			
		||||
         switch main
 | 
			
		||||
         merge nice_feature id: "12345" tag: "my merge commit"
 | 
			
		||||
         switch very_nice_feature
 | 
			
		||||
         commit id: "8"
 | 
			
		||||
         switch main
 | 
			
		||||
         commit id: "9"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('74: should render commits for more than 8 branches using switch instead of checkout', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        gitGraph
 | 
			
		||||
        switch main
 | 
			
		||||
        %% Make sure to manually set the ID of all commits, for consistent visual tests
 | 
			
		||||
        commit id: "1-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        branch branch1
 | 
			
		||||
        commit id: "2-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch1
 | 
			
		||||
        branch branch2
 | 
			
		||||
        commit id: "3-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch2
 | 
			
		||||
        branch branch3
 | 
			
		||||
        commit id: "4-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch3
 | 
			
		||||
        branch branch4
 | 
			
		||||
        commit id: "5-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch4
 | 
			
		||||
        branch branch5
 | 
			
		||||
        commit id: "6-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch5
 | 
			
		||||
        branch branch6
 | 
			
		||||
        commit id: "7-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch6
 | 
			
		||||
        branch branch7
 | 
			
		||||
        commit id: "8-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch7
 | 
			
		||||
        branch branch8
 | 
			
		||||
        commit id: "9-abcdefg"
 | 
			
		||||
        switch main
 | 
			
		||||
        merge branch8
 | 
			
		||||
        branch branch9
 | 
			
		||||
        commit id: "10-abcdefg"
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,67 +0,0 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('packet structure', () => {
 | 
			
		||||
  it('should render a simple packet diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet-beta
 | 
			
		||||
  title Hello world
 | 
			
		||||
  0-10: "hello"
 | 
			
		||||
`
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a complex packet diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `packet-beta
 | 
			
		||||
        0-15: "Source Port"
 | 
			
		||||
        16-31: "Destination Port"
 | 
			
		||||
        32-63: "Sequence Number"
 | 
			
		||||
        64-95: "Acknowledgment Number"
 | 
			
		||||
        96-99: "Data Offset"
 | 
			
		||||
        100-105: "Reserved"
 | 
			
		||||
        106: "URG"
 | 
			
		||||
        107: "ACK"
 | 
			
		||||
        108: "PSH"
 | 
			
		||||
        109: "RST"
 | 
			
		||||
        110: "SYN"
 | 
			
		||||
        111: "FIN"
 | 
			
		||||
        112-127: "Window"
 | 
			
		||||
        128-143: "Checksum"
 | 
			
		||||
        144-159: "Urgent Pointer"
 | 
			
		||||
        160-191: "(Options and Padding)"
 | 
			
		||||
        192-223: "data"
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a complex packet diagram with showBits false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      ---
 | 
			
		||||
      title: "Packet Diagram"
 | 
			
		||||
      config:
 | 
			
		||||
        packet:
 | 
			
		||||
          showBits: false
 | 
			
		||||
      ---
 | 
			
		||||
      packet-beta
 | 
			
		||||
        0-15: "Source Port"
 | 
			
		||||
        16-31: "Destination Port"
 | 
			
		||||
        32-63: "Sequence Number"
 | 
			
		||||
        64-95: "Acknowledgment Number"
 | 
			
		||||
        96-99: "Data Offset"
 | 
			
		||||
        100-105: "Reserved"
 | 
			
		||||
        106: "URG"
 | 
			
		||||
        107: "ACK"
 | 
			
		||||
        108: "PSH"
 | 
			
		||||
        109: "RST"
 | 
			
		||||
        110: "SYN"
 | 
			
		||||
        111: "FIN"
 | 
			
		||||
        112-127: "Window"
 | 
			
		||||
        128-143: "Checksum"
 | 
			
		||||
        144-159: "Urgent Pointer"
 | 
			
		||||
        160-191: "(Options and Padding)"
 | 
			
		||||
        192-223: "data"
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.ts';
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
describe('Quadrant Chart', () => {
 | 
			
		||||
  it('should render if only chart type is provided', () => {
 | 
			
		||||
@@ -8,6 +8,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a complete quadrant chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -29,6 +30,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render without points', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -44,6 +46,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render y-axix on right side', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -60,6 +63,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render x-axix on bottom', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -76,6 +80,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should able to render x-axix on bottom and y-axis on right', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -92,6 +97,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render without title', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -106,6 +112,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should use all the config', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -128,6 +135,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should use all the theme variable', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -150,6 +158,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render x-axis labels in the center, if x-axis has two labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -171,6 +180,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render y-axis labels in the center, if y-axis has two labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -192,6 +202,7 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render both axes labels on the left and bottom, if both axes have only one label', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -213,52 +224,6 @@ describe('Quadrant Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('it should render data points with styles', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  quadrantChart
 | 
			
		||||
    title Reach and engagement of campaigns
 | 
			
		||||
    x-axis Reach -->
 | 
			
		||||
    y-axis Engagement -->
 | 
			
		||||
    quadrant-1 We should expand
 | 
			
		||||
    quadrant-2 Need to promote
 | 
			
		||||
    quadrant-3 Re-evaluate
 | 
			
		||||
    quadrant-4 May be improved
 | 
			
		||||
    Campaign A: [0.3, 0.6] radius: 20
 | 
			
		||||
    Campaign B: [0.45, 0.23]     color: #ff0000  
 | 
			
		||||
    Campaign C: [0.57, 0.69]  stroke-color: #ff00ff  
 | 
			
		||||
    Campaign D: [0.78, 0.34]        stroke-width: 3px    
 | 
			
		||||
    Campaign E: [0.40, 0.34] radius: 20,   color: #ff0000  , stroke-color  : #ff00ff,     stroke-width    :   3px   
 | 
			
		||||
    Campaign F: [0.35, 0.78] stroke-width: 3px , color: #ff0000, radius: 20, stroke-color:     #ff00ff
 | 
			
		||||
    Campaign G: [0.22, 0.22] stroke-width: 3px  , color: #309708  ,  radius  : 20  ,  stroke-color:    #5060ff
 | 
			
		||||
    Campaign H: [0.22, 0.44]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('it should render data points with styles + classes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  quadrantChart
 | 
			
		||||
    title Reach and engagement of campaigns
 | 
			
		||||
    x-axis Reach -->
 | 
			
		||||
    y-axis Engagement -->
 | 
			
		||||
    quadrant-1 We should expand
 | 
			
		||||
    quadrant-2 Need to promote
 | 
			
		||||
    quadrant-3 Re-evaluate
 | 
			
		||||
    quadrant-4 May be improved
 | 
			
		||||
    Campaign A:::class1: [0.3, 0.6] radius: 20
 | 
			
		||||
    Campaign B: [0.45, 0.23] color: #ff0000
 | 
			
		||||
    Campaign C: [0.57, 0.69] stroke-color: #ff00ff
 | 
			
		||||
    Campaign D:::class2: [0.78, 0.34] stroke-width: 3px
 | 
			
		||||
    Campaign E:::class2: [0.40, 0.34] radius: 20, color: #ff0000, stroke-color: #ff00ff, stroke-width: 3px
 | 
			
		||||
    Campaign F:::class1: [0.35, 0.78]
 | 
			
		||||
    classDef class1 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
 | 
			
		||||
    classDef class2 color: #f00fff, radius : 10
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -44,5 +44,6 @@ describe('Requirement diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
// <reference types="Cypress" />
 | 
			
		||||
/// <reference types="Cypress" />
 | 
			
		||||
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
 | 
			
		||||
 | 
			
		||||
@@ -68,19 +68,6 @@ context('Sequence diagram', () => {
 | 
			
		||||
      { sequence: { actorFontFamily: 'courier' } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render bidirectional arrows', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      Alice<<->>John: Hello John, how are you?
 | 
			
		||||
      Alice<<-->>John: Hi Alice, I can hear you!
 | 
			
		||||
      John<<->>Alice: This also works the other way
 | 
			
		||||
      John<<-->>Alice: Yes
 | 
			
		||||
      Alice->John: Test
 | 
			
		||||
      John->>Alice: Still works
 | 
			
		||||
      `
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle different line breaks', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -388,7 +375,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should have actor-top and actor-bottom classes on top and bottom actor box and symbol and actor-box and actor-man classes for text tags', () => {
 | 
			
		||||
    it('should have actor-top and actor-bottom classes on top and bottom actor box and symbol', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
@@ -407,9 +394,6 @@ context('Sequence diagram', () => {
 | 
			
		||||
      cy.get('.actor-man').should('have.class', 'actor-bottom');
 | 
			
		||||
      cy.get('.actor.actor-bottom').should('not.have.class', 'actor-top');
 | 
			
		||||
      cy.get('.actor-man.actor-bottom').should('not.have.class', 'actor-top');
 | 
			
		||||
 | 
			
		||||
      cy.get('text.actor-box').should('include.text', 'Alice');
 | 
			
		||||
      cy.get('text.actor-man').should('include.text', 'Bob');
 | 
			
		||||
    });
 | 
			
		||||
    it('should render long notes left of actor', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
@@ -477,18 +461,6 @@ context('Sequence diagram', () => {
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render notes over actors and participant', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
        actor Alice
 | 
			
		||||
        participant Charlie
 | 
			
		||||
        note over Alice: some note
 | 
			
		||||
        note over Charlie: other note
 | 
			
		||||
      `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render long messages from an actor to the left to one to the right', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
@@ -835,10 +807,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
 | 
			
		||||
        Bob->>Alice: Short as well
 | 
			
		||||
      `,
 | 
			
		||||
        {
 | 
			
		||||
          logLevel: 0,
 | 
			
		||||
          sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' },
 | 
			
		||||
        }
 | 
			
		||||
        { logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@@ -889,10 +858,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        a->>j: Hello John, how are you?
 | 
			
		||||
        j-->>a: Great!
 | 
			
		||||
      `,
 | 
			
		||||
        {
 | 
			
		||||
          logLevel: 0,
 | 
			
		||||
          sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' },
 | 
			
		||||
        }
 | 
			
		||||
        { logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a simple state diagrams', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -19,6 +20,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a long descriptions instead of id when available', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -30,6 +32,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a long descriptions with additional descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -41,6 +44,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a single state with short descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -51,6 +55,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a transition descriptions with new lines', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -64,6 +69,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a state with a note', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -77,6 +83,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a state with on the left side when so specified', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -90,6 +97,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a state with a note together with another state', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -105,6 +113,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a note with multiple lines in it', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -147,6 +156,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a simple state diagrams 2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -159,6 +169,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a simple state diagrams with labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -174,6 +185,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render state descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -186,6 +198,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render composite states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -204,6 +217,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render multiple composite states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -273,6 +287,7 @@ describe('State diagram', () => {
 | 
			
		||||
    `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render concurrency states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -296,6 +311,7 @@ describe('State diagram', () => {
 | 
			
		||||
    `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a state with states in it', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a long descriptions instead of id when available', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -21,6 +22,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a long descriptions with additional descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -32,6 +34,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a single state with short descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -42,6 +45,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a transition descriptions with new lines', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -55,6 +59,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a state with a note', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -68,6 +73,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a state with on the left side when so specified', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -81,6 +87,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a state with a note together with another state', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -96,6 +103,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a note with multiple lines in it', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -138,6 +146,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple state diagrams 2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -150,6 +159,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a simple state diagrams with labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -165,6 +175,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render state descriptions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -177,6 +188,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render composite states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -195,6 +207,7 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render multiple composit states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -264,6 +277,7 @@ describe('State diagram', () => {
 | 
			
		||||
    `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render concurrency states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -287,6 +301,7 @@ describe('State diagram', () => {
 | 
			
		||||
    `,
 | 
			
		||||
      { logLevel: 0, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a state with states in it', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ describe('themeCSS balancing, it', () => {
 | 
			
		||||
          `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow unbalanced CSS definitions 2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -20,6 +21,7 @@ describe('themeCSS balancing, it', () => {
 | 
			
		||||
          `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -43,6 +45,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a flowchart diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -67,6 +70,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a new flowchart diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -92,6 +96,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a sequence diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -120,6 +125,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      it('should render a class diagram', () => {
 | 
			
		||||
@@ -169,6 +175,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a state diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -203,6 +210,7 @@ stateDiagram
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a state diagram (v2)', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -237,6 +245,7 @@ stateDiagram-v2
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a er diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -257,6 +266,7 @@ erDiagram
 | 
			
		||||
          `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a user journey diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -277,6 +287,7 @@ erDiagram
 | 
			
		||||
                        `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a gantt diagram', () => {
 | 
			
		||||
        cy.clock(new Date('2014-01-06').getTime());
 | 
			
		||||
@@ -315,6 +326,7 @@ erDiagram
 | 
			
		||||
       `,
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Should render a complete chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -34,6 +35,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('y-axis title not required', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -46,6 +48,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Should render a chart without y-axis with different range', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -57,6 +60,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('x axis title not required', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -68,6 +72,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Multiple plots can be rendered', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -82,6 +87,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Decimals and negative numbers are supported', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -92,6 +98,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render spark line with "plotReservedSpacePercent"', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -109,6 +116,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render spark bar without displaying other property', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -135,6 +143,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Should use all the config from directive', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -149,6 +158,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Should use all the config from yaml', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -189,6 +199,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render with show axis title false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -210,6 +221,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render with show axis label false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -231,6 +243,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render with show axis tick false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -252,6 +265,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render with show axis line false', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -273,6 +287,7 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Render all the theme color', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -302,17 +317,6 @@ describe('XY Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should use the correct distances between data points', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      xychart-beta
 | 
			
		||||
        x-axis 0 --> 2
 | 
			
		||||
        line [0, 1, 0, 1]
 | 
			
		||||
        bar [1, 0, 1, 0]
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"
 | 
			
		||||
@@ -33,9 +33,7 @@
 | 
			
		||||
        background-image: radial-gradient(#fff 1%, transparent 11%),
 | 
			
		||||
          radial-gradient(#fff 1%, transparent 11%);
 | 
			
		||||
        background-size: 20px 20px;
 | 
			
		||||
        background-position:
 | 
			
		||||
          0 0,
 | 
			
		||||
          10px 10px;
 | 
			
		||||
        background-position: 0 0, 10px 10px;
 | 
			
		||||
        background-repeat: repeat;
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
 
 | 
			
		||||
@@ -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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <script type="module" src="./viewer.js"></script>
 | 
			
		||||
    <script src="./viewer.js" type="module"></script>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="UTF-8" />
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,8 @@ example-diagram
 | 
			
		||||
    <!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
 | 
			
		||||
    <!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
 | 
			
		||||
    <script type="module">
 | 
			
		||||
      import exampleDiagram from './mermaid-example-diagram.esm.mjs';
 | 
			
		||||
      import exampleDiagram from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
 | 
			
		||||
      // import example from '../../packages/mermaid-example-diagram/src/detector';
 | 
			
		||||
      import mermaid from './mermaid.esm.mjs';
 | 
			
		||||
 | 
			
		||||
      await mermaid.registerExternalDiagrams([exampleDiagram]);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <body>
 | 
			
		||||
    <pre class="mermaid">
 | 
			
		||||
      flowchart-elk
 | 
			
		||||
      a[hello] --> b[world]
 | 
			
		||||
      b --> c{test}
 | 
			
		||||
      c --> one
 | 
			
		||||
      c --> two
 | 
			
		||||
      c --> three
 | 
			
		||||
    </pre>
 | 
			
		||||
 | 
			
		||||
    <script type="module">
 | 
			
		||||
      import mermaid from './mermaid.esm.mjs';
 | 
			
		||||
      import elk from './mermaid-flowchart-elk.esm.min.mjs';
 | 
			
		||||
      if (window.location.search.includes('elk')) {
 | 
			
		||||
        await mermaid.registerExternalDiagrams([elk]);
 | 
			
		||||
      }
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
      });
 | 
			
		||||
      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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://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.5.2/css/font-awesome.min.css"
 | 
			
		||||
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
 | 
			
		||||
    />
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://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