Themeable rendering for Claude Code replies: colored tables, code, math and Mermaid diagrams drawn on the terminal's cell grid.

Claude Code replies drawn on the terminal's cell grid: themed tables and code, and Mermaid diagrams as real box-drawing art.
cellsmith is a Claude Code mod that redraws assistant replies. Tables, code, headings, lists, links and tool calls get a color theme, and every mermaid block becomes a diagram: Pele lays it out, and cellsmith's engine, pelext, draws the layout with box-drawing lines, block fills and real text. It needs nothing but text and true color, so it works in any modern terminal: Windows Terminal, kitty, Ghostty, WezTerm, iTerm2, Rio, VS Code.
[!NOTE]
- A fork of prismantis. cellsmith started as prismantis 0.14.0 by Nahum Litvin and keeps its themes, tables, code, math, tool rows and copy buttons. The diagram engine is new.
- Agent-coded. Everything cellsmith adds (code, tests and these docs) was written and reviewed entirely by AI coding agents.

mono, and copy buttons on everything./plugin to turn it off. Claude Code's own renderer comes back the moment you do.⧉ html (the clipboard helper) or turn on LaTeX (RaTeX's renderer).
Requires Claude Code 2.1.287 or later. In Claude Code:
/plugin marketplace add 4our4ace/cellsmith
/plugin install cellsmith@cellsmith
or from a shell, claude plugin marketplace add 4our4ace/cellsmith and claude plugin install cellsmith@cellsmith. Run /reload-plugins (or start a new session) and the next reply draws with cellsmith.
If you use prismantis, turn it off, since both draw replies:
claude plugin disable prismantis@prismantis
To update, run this, then /reload in every open session. A session keeps the version it loaded until it reloads.
claude plugin marketplace update cellsmith && claude plugin update cellsmith@cellsmith
To uninstall:
claude plugin uninstall cellsmith@cellsmith
For LaTeX math, install RaTeX's renderer and set latex to true; see LaTeX math. Until then formulas draw as text.
| Feature | What you get |
|---|---|
| Themes | /cellsmith theme <name> switches on the spot. 16 themes and 20 color slots you can override |
| Tables | colored headers, rules, column alignment, colored numbers, sized to the terminal |
| Code | a language header and copy button, Prism highlighting in two dozen languages, shell lines colored like a prompt |
| Diagrams and charts | flowcharts, sequence, state, class and ER diagrams, bar and line charts, one color per box, participant and bar |
| LaTeX math | $$ and `math formulas typeset as images in kitty and Ghostty by RaTeX, text everywhere else |
| Layout | back-to-back tables and diagrams sit side by side and wrap on narrow terminals |
| Copy buttons | ⧉ md, ⧉ art and ⧉ html on tables, [ ⧉ copy ] on code, lists and quotes, /cellsmith copy without a mouse |
| Tool rows | Ran gh pr view 12, Read ~/src/app.ts, groups summed up as Ran 3 commands, read 2 files, with status dots; toolOutput: quiet hides what Claude only read and says in plain words what each call did |
| Turn footer | ✻ Baked for 6m 20s with the duration in the number color |
| Slash commands | command output (/cost, /context, plugin commands) gets the same tables and code styling |
| Diagram hints | a short model-only note on each prompt so Claude reaches for diagrams and charts when they help |
| Text | bold, italic, strikethrough, inline code, links, versions, durations, percentages and paths in their own colors |
| Headings, lists, quotes | 4 heading styles, nested lists, task lists, quotes with an accent bar |
| Your prompts | what you type draws in a bubble, an accent bar or a chevron, so you find your turns when you scroll back |
| Right to left | Hebrew and Arabic read right to left, with bullets, quote bars and table columns mirrored |
| Other mods | $.cellsmith.markdown draws any markdown the way replies are drawn, for mod authors |

Dark: catppuccin-mocha (default), dracula, nord, tokyo-night, gruvbox-dark, rose-pine, everforest, github-dark, one-dark, solarized-dark.
Light: catppuccin-latte, gruvbox-light, rose-pine-dawn, github-light, solarized-light.
mono drops the palette for bold and dim, and diagrams tell their series apart with shades (▓▒░); alerts keep their colors. Switch with /cellsmith theme nord, or run /cellsmith for the help screen with every theme. Every palette is MIT licensed and credited in THIRD_PARTY_NOTICES.md.
Header cells take the tableHeader color, and the default box style puts a double line under the header. tableStyle picks box (the default, every cell boxed), rules, grid or minimal; see Looks. :---: and ---: alignment is honored, numbers in cells get the number color, and columns shrink to fit the terminal.
Each code block gets a header row: the language on the left, a copy button on the right. The code sits indented below with no frame, so selecting it with the mouse copies only the code.
bash, sh, zsh, fish, powershell, unlabeled) color the command word, --flags, quoted strings and # comments, and restart after |, && and ;.Code blocks tagged mermaid draw as colored terminal graphics:
xychart-beta), gantt charts, timelines, mindmaps, quadrant charts, git graphs and sankey diagramsHow it draws: Pele lays the diagram out with a measurer that counts one character as one terminal cell, so every box is sized for the grid. cellsmith reads Pele's SVG and draws each shape the way a terminal shows it best. Straight lines, the elbows of edges and loops become rounded box-drawing lines, node outlines keep their corners with ╱╲ slopes, fills become quarter and eighth blocks, the few curves left become braille dots, and labels stay text. Both axes are remapped so every distinct line and label gets its own row and column, which keeps edges apart and labels off borders without changing the drawing's shape. A left-to-right flowchart too wide for the window is laid out top-down.
A diagram draws once its fence closes. Diagrams Pele cannot draw, or that don't fit the window, fall back to the box-art engine inherited from prismantis and then to code. mermaidAscii draws every diagram with that engine and + - | only.
Display math, $$…$$ on lines of its own or a `math block, draws as a typeset image in the theme's diagram text color, one formula per line. With copy buttons on, its ⧉ copy button copies the formula's LaTeX, since selecting an image copies blank cells. It needs RaTeX's PNG renderer, a single binary that typesets KaTeX syntax in a few milliseconds without TeX, a browser or Node:
gh release download -R erweixin/RaTeX -p 'ratex-cli-*-aarch64-apple-darwin.tar.gz'
tar -xzf ratex-cli-*.tar.gz
mkdir -p ~/.local/bin
install ratex-cli-*/render ~/.local/bin/ratex-render
Pick the archive for your platform (x86_64-apple-darwin, x86_64-unknown-linux-musl, ...). Any directory on your PATH works, but the file must be named ratex-render.
LaTeX is off until you set latex to true. Then cellsmith runs ratex-render once in kitty and Ghostty, outside tmux, and keeps LaTeX on only if that test formula comes back. If a later run fails, formulas already drawn stay and new ones stay text until you /reload. A reply shown before the test finishes draws its formulas as text, then redraws them as images. Anywhere else, without the renderer, or with latex off, formulas draw as text in a math code block. So does a formula the renderer rejects, or one too wide for the terminal even at one row. While LaTeX is on, the diagram hints note also tells Claude that $$ math renders. Inline $…$ draws as italic text without its dollar signs, with common commands such as \rho, \cdot and \le shown as symbols; amounts like $5 stay as written.
Formula text matches the reply text. A terminal image fills whole rows, so a formula that falls between two row counts is rendered again with more padding rather than stretched.
When tables and diagrams follow each other, they share a row and wrap once the terminal runs out of width, as in the screenshot at the top.
⧉ md copies the original Markdown and ⧉ art a boxed table that pastes well into Slack. ⧉ html copies a formatted table (headers, alignment, inline formatting) plus a tab-separated plain-text copy.[ ⧉ copy ] on each. Code copies without its fences, lists as markdown, quotes without their > markers.⧉ source copies the mermaid code, ⧉ art the drawn art.⧉ copy reply, which copies the reply as Claude wrote it. Selecting right-to-left text on screen copies letters in drawn order, not reading order./cellsmith copy copies the last reply, /cellsmith copy code its last code block.⧉ html shows in a local macOS terminal or a Linux graphical session. macOS needs nothing extra. Linux needs CopyQ running (see its Wayland caveats). On Ubuntu:
sudo apt install -y copyq && copyq --start-server && copyq config autostart true
Clicking works where the terminal passes clicks through, as fullscreen mode does. Terminals with copy-on-select, such as Warp, may grab the word "copy" instead.
Each tool call draws as one line: a verb and its target, Ran with a colored shell command, Read and Edited with the path. A status dot shows done, running or failed, and output still draws below.
Collapsed groups draw one line too: Ran 3 commands, read 2 files · last: npm test, with · N failed in the flag color when any call failed. Expand a group (ctrl+o or --verbose): shell calls keep their colored command with the output boxed below, and other calls use Claude Code's own rows. ctrl+o on a reply shows the original text.
toolStyle keeps tool rows apart from what Claude says: chat (the default) dims them on the right, capped at 60% of the width; tree-dim tucks them under the sentence with ⎿, dimmed; tree-bold is tree-dim with one-line sentences in bold; classic keeps a bold verb and status dot at full brightness. See Looks.
toolOutput picks how much of a call shows. The default, full, is what Claude Code shows. quiet, set in /config or as "toolOutput": "quiet" in settings.json, shows what Claude did, not what it read. Read, Grep, Glob, web fetches and shell commands made only of read-only programs (cat, grep, rg, ls, find, git log, gh pr view, …) draw their row and nothing under it, and the row says it in plain words: Read src/report.py lines 1–10, Searched src/ for "TODO", Listed tests. A shell call with no such form shows the description Claude gave it and the programs it ran: Run the unit tests · python3. Other shell commands show their first 3 lines and a count, without the approval line, also when Claude Code folded the call into a collapsed group. Edits keep Claude Code's diff. A failed call shows the last real line of its error instead of Exit code 1; a refused call (a permission rule, the auto mode classifier) shows its full reason. A command counts as read-only only when every part of it is, after a quote-aware split on ;, &&, ||, |, & and newlines, with no redirect into a file, no $(…), no heredoc and no write flags (sed -i, find -delete, …); in doubt, the result shows. Needs toolRows on.

The line that closes a turn keeps Claude Code's word and colors the duration: ✻ Baked for 6m 20s. Terminal only, since that's the only surface that draws it.
Output from slash commands, built-in or from other plugins, is drawn like a reply, copy buttons included. Errors keep Claude Code's own red line.
Claude rarely writes a chart unless it knows the terminal can draw one. With diagramHints on (the default), each prompt you type carries a short note that only the model reads. It says tables, alerts, code, mermaid diagrams and xychart-beta charts render here, and asks for commands in fenced blocks, since only those get a copy button.
The note costs about 200 tokens per prompt, and about 60 more while LaTeX math is on, when it also says $$ formulas render. It's off whenever mermaid is off, and skipped for headless claude -p runs and background notifications.
Bold, italic, strikethrough, inline code, links and bare URLs, clickable as terminal hyperlinks. Numbers, versions (v2.14.0), durations (250ms, 3h), sizes (16Gi) and percentages (99.9%) take the number color, and paths like ~/src/app.ts the path color.
headingStyle picks banner (the default: a box around H1, a heavy rule under H2), bold, underline or uppercase; see Looks. Terminals have one font size, so headings stand out through style and color.
Lists keep their numbers and nest with • and ◦. Quotes get an accent bar, and GitHub alerts (> [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION]) draw as colored boxes.
Task lists draw as [ ] and [✓], with done items dimmed and struck through. taskStyle switches to ticks (○ ✓), box (□ ✓) or progress, which adds a done-count bar above each list; see Looks.
What you type, at the prompt or through Remote Control, draws in the theme's colors. promptStyle picks bubble (the default, a rounded box), bar (an accent bar) or chevron (a bold ›), and off keeps Claude Code's own; see Looks. Task notifications and teammate messages are left alone.
Hebrew and Arabic blocks are right aligned, with bullets, numbers and quote bars on the right and table columns mirrored. Code, numbers, paths and links stay left to right inside them. Terminals treat right-to-left letters differently, so cellsmith detects yours and sends the letters the way it needs them. /cellsmith demo-rtl shows every element, and the rtl option forces a terminal's handling or turns it off.
Five options change how things look, not what is drawn. Each screenshot is a real session with one style of each, captioned in this order: promptStyle · toolStyle · taskStyle · tableStyle · headingStyle.
bubble · chat · checks · box · banner (the defaults) | bar · tree-dim · ticks · rules · bold |
|---|---|
![]() | ![]() |
chevron · tree-bold · box · grid · underline | bubble · classic · progress · minimal · uppercase |
![]() | ![]() |
Open /config and look for the cellsmith rows, or set values in ~/.claude/settings.json:
{
"pluginConfigs": {
"cellsmith@cellsmith": {
"options": {
"theme": "tokyo-night",
"tableStyle": "grid",
"headingStyle": "banner",
"tableHeaderColor": "#ffcc00",
"numberColor": "cyan"
}
}
}
}
Options sit under options, keyed by the plugin's install name. Project settings are not read for plugin options.
| Option | Values | Default |
|---|---|---|
enabled | true, false | true |
theme | see Themes | catppuccin-mocha |
tableStyle | box, rules, grid, minimal | box |
taskStyle | checks ([ ] [✓], done struck through), ticks (○ ✓), box (□ ✓), progress (ticks with a done-count bar) | checks |
promptStyle | bubble, bar, chevron, off | bubble |
headingStyle | banner, bold, underline, uppercase | banner |
highlightNumbers | true, false | true |
highlightPaths | true, false | true |
toolRows | true, false | true |
toolStyle | chat, tree-dim, tree-bold, classic | chat |
toolOutput | full, quiet | full |
copyButtons | true, false | true |
diagramHints | true, false | true |
rtl | auto, a terminal (warp, kitty, apple-terminal, iterm, ghostty, wezterm, vscode, alacritty, windows-terminal, gnome, konsole), off | auto |
mermaid | true, false | true |
mermaidAscii | true, false | false |
latex | true, false | false |
<token>Color | any color, see below | theme |
A color is hex (#a6e3a1, #fc0), rgb(166,227,161), ansi256(114) or a name (green, cyanBright). Values that don't parse are ignored. Every token has a <token>Color option and a row in /config:
| Token | Colors |
|---|---|
accent | reply bullet, H3+ headings, quote bar, running tool dots |
heading | H1 and H2 |
strong | bold text |
emphasis | italic text, variables, attribute names |
inlineCode | inline code |
codeText | code block text |
codeCommand | shell commands, functions, class names, keys |
codeFlag | --flags, keywords, failures |
codeString | strings |
codeComment | comments, the code block's language label |
link | links, URLs, properties, tags |
path | file paths, regexes |
number | numbers, versions, durations, done dots |
quote | quote text |
rule | rules, chart gridlines |
tableHeader | table header cells |
tableRule | table rules |
bullet | list bullets and numbers |
diagram | diagram lines |
diagramText | diagram labels and LaTeX formulas |
/reload. A session keeps what it loaded.mermaid is off. Widen the terminal or split the diagram.⧉ html on tables: you're over SSH, in the desktop app or VS Code, or on Linux with no graphical session. ⧉ md and ⧉ art still work.⧉ html copied plain text only: CopyQ isn't running, or the clipboard helper failed. The toast says why./cellsmith copy.COLORTERM. WSL doesn't pass it through from Windows Terminal. Set COLORTERM=truecolor in your shell profile and start a new session.codeText.PELE_DIAGRAMS in ../scripts/build-vendor.mjs to bundle it.To change the code, read AGENTS.md instead.
claude plugin marketplace add 4our4ace/cellsmith, then claude plugin install cellsmith@cellsmith. Needs Claude Code 2.1.287+. Changes apply after /reload./cellsmith theme <name> is the only setter at runtime. Every other option is a key under pluginConfigs["cellsmith@cellsmith"].options in ~/.claude/settings.json (or a row in /config), then /reload. Options and defaults are in the Configure table; the machine-readable source is userConfig in .claude-plugin/plugin.json. Color values that don't parse are ignored.⧉ html clipboard helper (/usr/bin/osascript on macOS, copyq on Linux, 5 second timeout, only on a click), and ratex-render while latex is on. With diagramHints on, it adds about 200 tokens of model-only context to each typed prompt."enabled": false, or disable the plugin in /plugin.$.cellsmith.markdown({ surface, text, columns }), typed in types/index.d.ts. See Other mods.Clone the repository and add the clone as the marketplace instead (claude plugin marketplace add ./cellsmith). A local marketplace is read live, so after an edit /reload-plugins picks it up. To try a change without
hooks/register.tsx 395 lines1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register, RenderElement, RenderSurface } from 'claude-code'
3
4import type { Formula } from './latex'
5import { LATEX_DPR, LATEX_FONT_PX, fitsImage, keepFormulas, mathOf, padFor, pickFormula, pngSize, ratexColor, renderedOf } from './latex'
6import type { Block } from './markdown'
7import { parse } from './markdown'
8import type { ClipboardBackend } from './clipboard'
9import { clipboardCommand } from './clipboard'
10import { boxArt, mermaidText, peleArt, peleText, shortenEdgeLabels, warmPele } from './mermaid'
11import type { Drawn } from './render'
12import { isReadOnlyCall, remember, rememberCall, renderBlocks, renderExpandedShell, renderFailure, renderShellResult, renderToolGroup, renderToolRow, renderTurnDuration, renderUserPrompt, width } from './render'
13import { helpText, rtlShowcaseText, showcaseText } from './help'
14import { PRESET_NAMES } from './presets'
15import type { Style } from './theme'
16import { resolveStyle } from './theme'
17import type { Terminal } from './rtl'
18import { TERMINALS, hasRtl } from './rtl'
19
20const HINT = [
21 'Replies in this session are drawn by the cellsmith mod, which runs inside Claude Code and is not a command or tool to call: when the user asks to show something with cellsmith, write it as markdown in the reply.',
22 'Markdown tables, GitHub alerts (> [!WARNING], > [!NOTE]), fenced code with a language tag, and ```mermaid blocks render as colored terminal graphics:',
23 'flowcharts, sequence, class, state and ER diagrams, pie and xychart-beta bar or line charts, gantt charts, timelines, mindmaps, quadrant charts and git graphs.',
24 'When a reply carries a numeric series or a flow that is easier to see than read, add one small diagram or chart with short labels.',
25 'Skip diagrams for simple answers.',
26 'Put any command or snippet the user may run or copy in a fenced block with a language tag, never inline code: fenced blocks get a copy button, inline code does not.',
27].join(' ')
28
29const LATEX_HINT = 'This terminal typesets LaTeX math: a formula in $$…$$ on lines of its own, or in a ```math block, renders as an image (KaTeX syntax). Inline $…$ does not render, so write inline math as plain text or Unicode.'
30
31const detectTerminal = async ($: EngineInterface): Promise<Terminal | null> => {
32 const program = await $.env.get('TERM_PROGRAM')
33 const term = await $.env.get('TERM')
34 if ((await $.env.get('KITTY_WINDOW_ID')) || term === 'xterm-kitty') return 'kitty'
35 if (program === 'Apple_Terminal') return 'apple-terminal'
36 if (program === 'WarpTerminal') return 'warp'
37 if (program === 'ghostty') return 'ghostty'
38 if (program === 'WezTerm') return 'wezterm'
39 if (program === 'vscode') return 'vscode'
40 if (program === 'iTerm.app') return 'iterm'
41 if (term === 'alacritty' || (await $.env.get('ALACRITTY_WINDOW_ID'))) return 'alacritty'
42 if (await $.env.get('WT_SESSION')) return 'windows-terminal'
43 if (await $.env.get('VTE_VERSION')) return 'gnome'
44 if (await $.env.get('KONSOLE_VERSION')) return 'konsole'
45 return null
46}
47
48const applyRtl = async ($: EngineInterface, style: Style): Promise<Terminal | null> => {
49 if (style.rtl === 'off') return null
50 if (style.rtl !== 'auto') return style.rtl
51 const terminal = await detectTerminal($)
52 style.reorder = terminal !== null
53 if (terminal) style.shape = TERMINALS[terminal]
54 return terminal
55}
56
57const expandedCalls = new Set<string>()
58const readOnlyCalls = new Set<string>()
59
60const markExpanded = (id: string) => {
61 expandedCalls.delete(id)
62 expandedCalls.add(id)
63 if (expandedCalls.size > 500) expandedCalls.delete(expandedCalls.values().next().value!)
64}
65
66const columnsOf = (viewport?: { columns?: number }) => Math.max(20, (viewport?.columns ?? 100) - 4)
67
68const formulas = atom({ plugin: 'cellsmith', key: 'formulas' } as const, {})
69const latexDir = atom({ plugin: 'cellsmith', key: 'dir' } as const, '')
70
71type Typeset = Exclude<Formula, { error: true }> & { tex: string }
72
73const showsImages = async ($: EngineInterface): Promise<boolean> => {
74 if (await $.env.get('TMUX')) return false
75 const terminal = await detectTerminal($)
76 return terminal === 'kitty' || terminal === 'ghostty'
77}
78
79type Latex = { command: string; dir: string }
80type LatexSession = { style: Style; color: string; pending: Set<string>; wanted: Set<string>; batch: string[]; engine?: Promise<Latex | null>; ready?: Latex | null; stopped?: boolean; queue: Promise<void> }
81
82const formulaKey = (latex: LatexSession, tex: string) => `${latex.color}\0${tex}`
83
84const typeset = async ($: EngineInterface, latex: LatexSession, engine: Latex, texs: string[], fontSize = LATEX_FONT_PX, dpr = LATEX_DPR): Promise<Formula[]> => {
85 const { stdout } = await $.process.run(
86 [engine.command, '--output-dir', engine.dir, '--color', latex.color, '--background-color', 'transparent', '--font-size', String(fontSize), '--dpr', String(dpr)],
87 { stdin: `${texs.join('\n')}\n`, timeoutMs: 2000 },
88 )
89 const rendered = renderedOf(stdout)
90 return Promise.all(texs.map(async (_, i): Promise<Formula> => {
91 if (!rendered.has(i + 1)) return { error: true }
92 const png = await $.fs.read(`${engine.dir}/${String(i + 1).padStart(4, '0')}.png`, { as: 'bytes' }).then(r => r.base64, () => '')
93 const size = png ? pngSize(png) : null
94 return size && fitsImage(png) ? { png, ...size } : { error: true }
95 }))
96}
97
98const withPadding = async ($: EngineInterface, latex: LatexSession, engine: Latex, texs: string[], results: Formula[]): Promise<Formula[]> => {
99 const padded: Formula[] = []
100 for (const [i, result] of results.entries()) {
101 const pad = 'png' in result ? padFor(result) : null
102 const [again] = pad ? await typeset($, latex, engine, [texs[i]!], pad.fontSize, pad.dpr).catch((): Formula[] => []) : []
103 padded.push(again && 'png' in again && 'png' in result ? { ...result, padded: again } : result)
104 }
105 return padded
106}
107
108const startLatex = async ($: EngineInterface, latex: LatexSession): Promise<Latex | null> => {
109 if (!latex.style.latex || !(await $.session.surfaces()).includes('terminal') || !(await showsImages($))) return null
110 const tmp = (await $.env.get('TMPDIR')) ?? (await $.env.get('TEMP')) ?? '/tmp'
111 const suffix = (await read($, latexDir)) || crypto.randomUUID()
112 await update($, latexDir, () => suffix)
113 const engine = { command: 'ratex-render', dir: `${tmp.replace(/[\\/]+$/, '')}/cellsmith-latex-${await $.session.id()}-${suffix}` }
114 const [check] = await typeset($, latex, engine, ['x^2'])
115 return check && 'png' in check ? engine : null
116}
117
118const latexEngine = ($: EngineInterface, latex: LatexSession): Promise<Latex | null> =>
119 (latex.engine ??= startLatex($, latex)
120 .catch(() => null)
121 .then(engine => {
122 latex.ready = engine
123 if (engine) $.ui.invalidate('ui.render')
124 return engine
125 }))
126
127const stopLatex = (latex: LatexSession) => {
128 latex.stopped = true
129 latex.pending.clear()
130 latex.batch = []
131}
132
133const typesetLater = async ($: EngineInterface, latex: LatexSession, texs: string[]): Promise<void> => {
134 const engine = await latexEngine($, latex)
135 if (!engine || latex.stopped) return
136 const results = await typeset($, latex, engine, texs).then(
137 done => withPadding($, latex, engine, texs, done),
138 () => null,
139 )
140 if (!results) return stopLatex(latex)
141 const fresh = texs.map((tex, i) => [formulaKey(latex, tex), results[i]!] as const)
142 await update($, formulas, store => keepFormulas(store, fresh, latex.wanted))
143 latex.wanted.clear()
144 for (const tex of texs) latex.pending.delete(formulaKey(latex, tex))
145}
146
147const mathOfBlocks = async ($: EngineInterface, latex: LatexSession, surface: string, blocks: Block[]): Promise<Map<number, Typeset>> => {
148 const maths = [...blocks.entries()].flatMap(([i, block]) => {
149 const tex = mathOf(block)
150 return tex === null ? [] : [{ i, tex, key: formulaKey(latex, tex) }]
151 })
152 if (surface !== 'terminal' || maths.length === 0) return new Map()
153 void latexEngine($, latex)
154 if (!latex.ready) return new Map()
155 for (const { key } of maths) latex.wanted.add(key)
156 const store = (await read($, formulas)) as Record<string, Formula>
157 const missing = latex.stopped ? [] : [...new Map(maths.map(({ key, tex }) => [key, tex]))].filter(([key]) => !store[key] && !latex.pending.has(key))
158 if (missing.length) {
159 if (latex.batch.length === 0) {
160 $.clock.after(0, () => {
161 const texs = latex.batch
162 latex.batch = []
163 latex.queue = latex.queue.then(() => typesetLater($, latex, texs)).catch(() => stopLatex(latex))
164 })
165 }
166 for (const [key, tex] of missing) {
167 latex.pending.add(key)
168 latex.batch.push(tex)
169 }
170 }
171 return new Map(maths.flatMap(({ i, tex, key }) => {
172 const formula = store[key]
173 return formula && 'png' in formula ? [[i, { tex, ...formula }] as const] : []
174 }))
175}
176
177const locate = async ($: EngineInterface, style: Style) => {
178 style.cwd = await $.session.root().catch(() => style.cwd)
179 style.home ||= (await $.env.get('HOME').catch(() => undefined)) ?? ''
180}
181
182const htmlBackend = async ($: EngineInterface): Promise<ClipboardBackend | null> => {
183 if (await $.env.get('SSH_CONNECTION') || await $.env.get('SSH_TTY')) return null
184 const helper = await $.fs.stat('/usr/bin/osascript').catch(() => null)
185 if (helper?.kind === 'file') return 'macos'
186 return await $.env.get('WAYLAND_DISPLAY') || await $.env.get('DISPLAY') ? 'linux' : null
187}
188
189type Probes = { terminal?: Promise<Terminal | null>; htmlCopy?: Promise<ClipboardBackend | null> }
190
191const warmDiagrams = ($: EngineInterface, style: Style, step = 0) =>
192 $.clock.after(step ? 100 : 1000, () => {
193 if (warmPele(style, step) !== undefined) void warmDiagrams($, style, step + 1)
194 })
195
196const probe = async ($: EngineInterface, style: Style, probes: Probes): Promise<Terminal | null> => {
197 probes.terminal ??= applyRtl($, style)
198 const terminal = await probes.terminal
199 probes.htmlCopy ??= htmlBackend($)
200 style.htmlCopy = await probes.htmlCopy
201 return terminal
202}
203
204const copyTable = async ($: EngineInterface, backend: ClipboardBackend, html: string, text: string): Promise<string | null> => {
205 const command = clipboardCommand(backend, html, text)
206 const result = await $.process.run(command.argv, { stdin: command.stdin, timeoutMs: 5000 }).catch(() => null)
207 if (!result) return command.failure
208 return result.exitCode === 0 ? null : result.stderr.trim() || command.failure
209}
210
211const drawMarkdown = ($: EngineInterface, el: ReturnType<EngineInterface['ui']['resolve']>, style: Style, blocks: ReturnType<typeof parse>, columns: number, math: Map<number, Typeset> = new Map(), reply?: string): RenderElement[] => {
212 const { Button } = el
213 const copy = (text: string | (() => string), key: string, label = '⧉ copy', html?: () => string) => {
214 const copied = async (surface: RenderSurface): Promise<string> => {
215 const content = typeof text === 'function' ? text() : text
216 const backend = style.htmlCopy
217 const failure = html && backend ? await copyTable($, backend, html(), content) : undefined
218 if (failure === null) return 'Copied formatted table'
219 const result = await $.ui.copy({ text: content, surface })
220 if (!result.isCopied) return `Copy failed: ${result.reason}`
221 return failure ? `Copied as plain text (${failure})` : 'Copied'
222 }
223 return style.copyButtons && (!html || style.htmlCopy) ? (
224 <Button
225 key={key}
226 variant="primary"
227 label={label}
228 onPress={async press => $.ui.toast(await copied(press.surface).catch(() => 'Copy failed'))}
229 />
230 ) : null
231 }
232 const drawn: Drawn = new Map()
233 if (style.mermaid) {
234 for (const [i, block] of blocks.entries()) {
235 if (block.kind !== 'code' || block.lang.toLowerCase() !== 'mermaid' || block.isOpen) continue
236 const source = block.lines.join('\n')
237 const pele = style.mermaidAscii ? null : peleText(source, style, columns - 2)
238 if (pele) {
239 drawn.set(i, { element: peleArt(el, pele, `b${i}`), art: pele.art })
240 continue
241 }
242 for (const max of [Infinity, 24, 12]) {
243 const art = mermaidText(max === Infinity ? source : shortenEdgeLabels(source, max), style.mermaidAscii, columns)
244 if (art === null || !art.split('\n').every(l => width(l) <= columns - 2)) continue
245 drawn.set(i, { element: boxArt(el, style, art, `b${i}`), art })
246 break
247 }
248 }
249 }
250 const Image = 'Image' in el ? el.Image : null
251 if (Image) {
252 for (const [i, formula] of math) {
253 const picked = pickFormula(formula, columns)
254 if (picked) drawn.set(i, { element: <Image key={`b${i}`} source={{ png: picked.picture.png }} columns={picked.fit.columns} rows={picked.fit.rows} alt={formula.tex} /> })
255 }
256 }
257 const elements = renderBlocks(el, style, blocks, columns, drawn, copy)
258 const button = reply === undefined ? null : copy(reply, 'reply', '⧉ copy reply')
259 return button ? [...elements, <el.Box key="reply" alignSelf="flex-end">{button}</el.Box>] : elements
260}
261
262export const register: Register = (on, options) => {
263 on('engine.create', async (_$, e, next) => ({ ...(await next(e)), cellsmith: { markdown: async () => undefined } }))
264 if (options.enabled === false) return
265 const style = resolveStyle(options)
266 const parsed = new Map<string, ReturnType<typeof parse>>()
267 const parseCached = (text: string, cache = parsed, limit?: number) => remember(cache, text, () => parse(text, { numbers: style.highlightNumbers, paths: style.highlightPaths }), limit)
268 const shared = new Map<string, ReturnType<typeof parse>>()
269 let terminal: Terminal | null = null
270 const fit = (viewport?: { isFullscreen?: boolean }): Style => (terminal === 'apple-terminal' && viewport?.isFullscreen ? { ...style, shape: 'inverse' } : style)
271 const latex: LatexSession = { style, color: ratexColor(style.theme.diagramText ?? style.theme.codeText ?? '#808080'), pending: new Set(), wanted: new Set(), batch: [], queue: Promise.resolve() }
272 const forSurface = (base: Style, surface: RenderSurface): Style => (surface === 'terminal' || !base.htmlCopy ? base : { ...base, htmlCopy: null })
273 const fullWidth = (text: string) => (style.reorder && hasRtl(text) ? { width: '100%' as const } : {})
274 const probes: Probes = {}
275
276 const quiet = style.toolOutput === 'quiet'
277 if (options.toolRows !== false) {
278 on('ui.render', { component: 'ToolGroup' }, async ($, e, next) => {
279 await locate($, style)
280 if (quiet) for (const call of e.props.calls) if (call.tool_use_id && isReadOnlyCall(call.tool, call.input)) rememberCall(readOnlyCalls, call.tool_use_id)
281 if (e.props.isExpanded) {
282 for (const call of e.props.calls) if (call.tool_use_id) markExpanded(call.tool_use_id)
283 return next(e)
284 }
285 return renderToolGroup($.ui.resolve(e), fit(e.viewport), e.props.calls, e.props.isActive, e.viewport?.columns)
286 })
287 on('ui.render', { component: 'ToolUse' }, async ($, e, next) => {
288 await locate($, style)
289 if (quiet && isReadOnlyCall(e.props.tool, e.props.input)) rememberCall(readOnlyCalls, e.props.tool_use_id)
290 if (!expandedCalls.has(e.props.tool_use_id)) return renderToolRow($.ui.resolve(e), fit(e.viewport), e.props, e.viewport?.columns)
291 return e.props.tool === 'Bash' || e.props.tool === 'PowerShell' ? renderExpandedShell($.ui.resolve(e), fit(e.viewport), e.props) : next(e)
292 })
293 if (quiet) {
294 on('ui.render', { component: 'ToolResult' }, async ($, e, next) => {
295 await locate($, style)
296 const el = $.ui.resolve(e)
297 const shell = e.props.tool === 'Bash' || e.props.tool === 'PowerShell'
298 const out = (e.props.output ?? {}) as Record<string, unknown>
299 if (shell && (out.backgroundTaskId || out.isImage || out.interrupted)) return next(e)
300 if (e.props.isErrored) return renderFailure(el, fit(e.viewport), e.props.output) ?? next(e)
301 if (readOnlyCalls.has(e.props.tool_use_id)) return <el.Box />
302 return shell ? renderShellResult(el, fit(e.viewport), e.props.output) : next(e)
303 })
304 }
305 }
306
307 on('session.start', async ($, e, next) => {
308 terminal = await probe($, style, probes)
309 void latexEngine($, latex)
310 const started = await next(e)
311 if (!style.mermaidAscii) void warmDiagrams($, style)
312 await $.command
313 .register({ name: 'cellsmith', description: 'Switch the cellsmith theme, copy the last reply, or show the demo', argumentHint: '[theme <name> | copy [code] | demo]' })
314 .catch(() => undefined)
315 return started
316 })
317
318 on('command.run', { command: 'cellsmith' }, async ($, e) => {
319 const [sub, name] = e.args.trim().split(/\s+/)
320 if (sub === 'demo') return { text: showcaseText(PRESET_NAMES) }
321 if (sub === 'copy') {
322 const reply = (await $.session.messages()).findLast(m => m.role === 'assistant' && m.text.trim())
323 if (!reply) return { text: 'Nothing to copy yet.' }
324 const code = name === 'code' ? parseCached(reply.text).findLast(b => b.kind === 'code') : undefined
325 if (name === 'code' && code?.kind !== 'code') return { text: 'The last reply has no code block.' }
326 const result = await $.ui.copy({ text: code?.kind === 'code' ? code.lines.join('\n') : reply.text })
327 return { text: result.isCopied ? `Copied the last ${code ? 'code block' : 'reply'}.` : `Copy failed: ${result.reason}` }
328 }
329 if (sub === 'demo-rtl') {
330 terminal = await probe($, style, probes)
331 return { text: rtlShowcaseText() }
332 }
333 if (sub !== 'theme' || !name) return { text: helpText(PRESET_NAMES) }
334 if (!(PRESET_NAMES as readonly string[]).includes(name)) return { text: `Unknown theme "${name}". Themes: ${PRESET_NAMES.join(', ')}` }
335 const result = await $.config.set({ key: `${$.plugin.name}.theme`, value: name })
336 return { text: result.deny ? `Could not switch theme: ${result.deny}` : `Theme set to ${name}.` }
337 })
338
339 on('ui.render', { component: 'TurnDuration' }, ($, e) => renderTurnDuration($.ui.resolve(e), style, e.props.word, e.props.durationMs))
340
341 on('prompt.submit', async ($, e, next) => {
342 terminal = await probe($, style, probes)
343 if (!style.diagramHints || (e.origin.kind !== 'composer' && e.origin.kind !== 'bridge')) return next(e)
344 void latexEngine($, latex)
345 const hints = latex.ready && !latex.stopped ? [HINT, LATEX_HINT] : [HINT]
346 return next({ ...e, context: [...(e.context ?? []), ...hints] })
347 })
348
349 on('ui.render', { component: 'CommandOutput' }, async ($, e, next) => {
350 if (e.props.isErrored) return next(e)
351 if (e.props.text.includes('\u001b')) return next(e)
352 const blocks = parseCached(e.props.text)
353 if (blocks.length === 0) return next(e)
354 const el = $.ui.resolve(e)
355 const { Box } = el
356 const math = await mathOfBlocks($, latex, e.surface, blocks)
357 return <Box flexDirection="column" rowGap={1} {...fullWidth(e.props.text)}>{drawMarkdown($, el, forSurface(fit(e.viewport), e.surface), blocks, columnsOf(e.viewport), math)}</Box>
358 })
359
360 on('ui.render', { component: 'UserMessage' }, ($, e, next) => {
361 const kind = e.props.origin.kind
362 const own = kind === 'composer' || kind === 'bridge' || (kind === 'unclassified' && !e.props.from && !e.props.task)
363 if (style.promptStyle === 'off' || !own) return next(e)
364 return renderUserPrompt($.ui.resolve(e), fit(e.viewport), e.props.text, columnsOf(e.viewport))
365 })
366
367 on('ui.render', { component: 'AssistantMessage' }, async ($, e, next) => {
368 const blocks = parseCached(e.props.text)
369 if (blocks.length === 0) return next(e)
370 const el = $.ui.resolve(e)
371 const { Box, Text } = el
372 const narration = style.toolStyle === 'tree-bold' && blocks.length === 1 && blocks[0]!.kind === 'paragraph'
373 const math = await mathOfBlocks($, latex, e.surface, blocks)
374 const surfaceStyle = forSurface(fit(e.viewport), e.surface)
375 return (
376 <Box flexDirection="row">
377 <Box width={2} flexShrink={0}>
378 <Text color={style.theme.accent}>{e.props.isFirstOfReply ? '●' : ' '}</Text>
379 </Box>
380 <Box flexDirection="column" rowGap={1} flexGrow={1}>
381 {drawMarkdown($, el, narration ? { ...surfaceStyle, narration } : surfaceStyle, blocks, columnsOf(e.viewport), math, blocks.length > 1 || hasRtl(e.props.text) ? e.props.text : undefined)}
382 </Box>
383 </Box>
384 )
385 })
386
387 on('cellsmith.markdown', ($, e, next) => {
388 const blocks = parseCached(e.text, shared, 20)
389 if (blocks.length === 0) return next(e)
390 const el = $.ui.resolve({ surface: e.surface, component: 'AssistantMessage' })
391 const { Box } = el
392 return { value: <Box flexDirection="column" rowGap={1} {...fullWidth(e.text)}>{drawMarkdown($, el, { ...style, copyButtons: false }, blocks, Math.max(20, e.columns || 0))}</Box> }
393 })
394}
395hooks/latex.ts 99 lines1import type { Block } from './markdown'
2
3type Picture = { png: string; width: number; height: number }
4
5export type Formula = (Picture & { padded?: Picture }) | { error: true }
6
7type Size = { width: number; height: number }
8type Fit = { columns: number; rows: number }
9
10export const LATEX_FONT_PX = 80
11export const LATEX_DPR = 1
12const PX_PER_ROW = LATEX_FONT_PX * LATEX_DPR
13const CELL_RATIO = 0.5
14const RATEX_MARGIN_PX = 10
15const MAX_IMAGE_BYTES = 2 * 1024 * 1024
16
17const ANSI16 = ['000000', 'cd0000', '00cd00', 'cdcd00', '0000ee', 'cd00cd', '00cdcd', 'e5e5e5', '7f7f7f', 'ff0000', '00ff00', 'ffff00', '5c5cff', 'ff00ff', '00ffff', 'ffffff']
18const ANSI_NAMES = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
19
20const hex = (...rgb: number[]): string => `#${rgb.map(n => Math.max(0, Math.min(255, n)).toString(16).padStart(2, '0')).join('')}`
21
22const ansi256 = (n: number): string => {
23 if (n < 16) return `#${ANSI16[n]}`
24 const level = (v: number) => (v ? 55 + v * 40 : 0)
25 if (n < 232) return hex(level(Math.floor((n - 16) / 36)), level(Math.floor((n - 16) / 6) % 6), level((n - 16) % 6))
26 const gray = 8 + (n - 232) * 10
27 return hex(gray, gray, gray)
28}
29
30export const ratexColor = (color: string): string => {
31 const c = color.trim()
32 const rgb = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(c)
33 if (rgb) return hex(...rgb.slice(1).map(Number))
34 const ansi = /^ansi256\((\d+)\)$/i.exec(c)
35 if (ansi) return ansi256(Number(ansi[1]))
36 const name = /^(black|red|green|yellow|blue|magenta|cyan|white|gray|grey)(bright)?$/i.exec(c)
37 if (!name?.[2]) return c
38 const base = name[1]!.toLowerCase()
39 return `#${ANSI16[base === 'gray' || base === 'grey' ? 8 : ANSI_NAMES.indexOf(base) + 8]}`
40}
41
42const MAX_FORMULAS = 50
43
44export const keepFormulas = <T,>(store: Record<string, T>, fresh: readonly (readonly [string, T])[], wanted: ReadonlySet<string>): Record<string, T> => {
45 const added = new Set(fresh.map(([key]) => key))
46 const entries = [...Object.entries(store).filter(([key]) => !added.has(key)), ...fresh]
47 const spare = entries.filter(([key]) => !wanted.has(key) && !added.has(key)).map(([key]) => key)
48 const dropped = new Set(spare.slice(0, Math.max(0, entries.length - MAX_FORMULAS)))
49 return Object.fromEntries(entries.filter(([key]) => !dropped.has(key)))
50}
51
52export const fitsImage = (base64: string): boolean => (base64.length * 3) / 4 <= MAX_IMAGE_BYTES
53
54const naturalRows = (size: Size): number => size.height / PX_PER_ROW
55
56export const padFor = (size: Size): { rows: number; fontSize: number; dpr: number } | null => {
57 const natural = naturalRows(size)
58 const below = Math.floor(natural)
59 const above = Math.max(1, Math.ceil(natural))
60 if ((below >= 1 && below / natural >= 0.9) || above / natural <= 1.05) return null
61 const dpr = LATEX_DPR + (above * PX_PER_ROW - size.height) / (2 * RATEX_MARGIN_PX)
62 return { rows: above, fontSize: PX_PER_ROW / dpr, dpr }
63}
64
65export const mathOf = (block: Block): string | null => {
66 if (block.kind !== 'code' || block.lang.toLowerCase() !== 'math' || block.isOpen) return null
67 const tex = block.lines.map(line => line.replace(/(^|[^\\])%.*$/, '$1')).join(' ').replace(/\s+/g, ' ').trim()
68 return tex === '' || tex.startsWith('#') ? null : tex
69}
70
71export const pngSize = (base64: string): Size | null => {
72 const head = atob(base64.slice(0, 32))
73 if (!head.startsWith('\x89PNG')) return null
74 const word = (at: number) => [0, 1, 2, 3].reduce((n, i) => n * 256 + head.charCodeAt(at + i), 0)
75 return { width: word(16), height: word(20) }
76}
77
78const rowsOf = (size: Size): number => Math.min(255, Math.max(1, Math.round(naturalRows(size))))
79
80const fitFormula = (size: Size, columns: number): Fit | null => {
81 const aspect = size.width / size.height / CELL_RATIO
82 const room = Math.min(255, columns - 2)
83 let rows = rowsOf(size)
84 while (rows > 1 && Math.round(aspect * rows) > room) rows--
85 const width = Math.max(1, Math.round(aspect * rows))
86 return width <= room ? { columns: width, rows } : null
87}
88
89export const pickFormula = (formula: Exclude<Formula, { error: true }>, columns: number): { picture: Picture; fit: Fit } | null => {
90 if (formula.padded) {
91 const fit = fitFormula(formula.padded, columns)
92 if (fit && fit.rows === rowsOf(formula.padded)) return { picture: formula.padded, fit }
93 }
94 const fit = fitFormula(formula, columns)
95 return fit ? { picture: formula, fit } : null
96}
97
98export const renderedOf = (stdout: string): Set<number> => new Set([...stdout.matchAll(/^OK\s+(\d+)\s/gm)].map(m => Number(m[1])))
99hooks/markdown.ts 255 lines1export type Inline =
2 | { kind: 'text'; text: string }
3 | { kind: 'strong'; children: Inline[] }
4 | { kind: 'emphasis'; children: Inline[] }
5 | { kind: 'strike'; children: Inline[] }
6 | { kind: 'code'; text: string }
7 | { kind: 'math'; text: string }
8 | { kind: 'link'; text: string; href: string }
9 | { kind: 'number'; text: string }
10 | { kind: 'path'; text: string }
11 | { kind: 'dim'; text: string }
12
13export type Block = { raw: string } & (
14 | { kind: 'heading'; level: number; inline: Inline[] }
15 | { kind: 'paragraph'; inline: Inline[] }
16 | { kind: 'list'; ordered: boolean; items: { marker: string; depth: number; task?: boolean; inline: Inline[] }[] }
17 | { kind: 'code'; lang: string; lines: string[]; isOpen?: true }
18 | { kind: 'quote'; inline: Inline[] }
19 | { kind: 'alert'; level: AlertLevel; inline: Inline[] }
20 | { kind: 'rule' }
21 | { kind: 'table'; header: Inline[][]; align: ('left' | 'right' | 'center')[]; rows: Inline[][][] }
22)
23
24type Draft = Block extends infer B ? (B extends unknown ? Omit<B, 'raw'> : never) : never
25
26export type AlertLevel = 'note' | 'tip' | 'important' | 'warning' | 'caution'
27const ALERT = /^\[!(note|tip|important|warning|caution)\]\s*(.*)$/i
28
29export type Highlight = { numbers: boolean; paths: boolean }
30
31const MAX_INLINE = 4000
32const TABLE_SEP = /^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/
33const LIST_ITEM = /^(\s*)([-*+]|\d+[.)])\s+(.*)$/
34const FENCE = /^\s*(`{3,}|~{3,})\s*([\w+-]*)/
35
36const splitRow = (line: string): string[] => {
37 const trimmed = line.trim().replace(/^\|/, '').replace(/(?<!\\)\|$/, '')
38 const cells: string[] = []
39 let cell = ''
40 for (let i = 0; i < trimmed.length; i++) {
41 const ch = trimmed[i]
42 if (ch === '\\' && trimmed[i + 1] === '|') {
43 cell += '|'
44 i++
45 } else if (ch === '|') {
46 cells.push(cell.trim())
47 cell = ''
48 } else {
49 cell += ch
50 }
51 }
52 cells.push(cell.trim())
53 return cells
54}
55
56const INLINE = /(`+)(?!`)(.+?)(?<!`)\1(?!`)|\[([^\]]+)\]\(([^)\s]+)\)|\*\*([^*]+?)\*\*|(?<![\w_])__([^_]+?)__(?![\w_])|~~([^~]+?)~~|(?<![\w*])\*([^*\s][^*]*?)\*(?!\w)|(?<![\w_])_([^_\s][^_]*?)_(?!\w)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])|(?<![\\$\w])\$(?=\S)((?:\\.|[^$\n\\])+?)(?<=\S)\$(?![\w$])/g
57const NUMBER = /(?<![\w.#/-])(v?\d+(?:[.,:]\d+)*(?:%|ms|s|m|h|d|Gi|Mi|GB|MB|KB|x)?)(?![\w/])/g
58const PATH = /(?<![\w/.:])((?:~|\.{1,2})?\/[\w.@+-]+(?:\/[\w.@+-]*)*)/g
59
60const decorate = (text: string, hl: Highlight): Inline[] => {
61 if (!hl.numbers && !hl.paths) return [{ kind: 'text', text }]
62 const marks: { start: number; end: number; kind: 'number' | 'path' }[] = []
63 if (hl.paths) for (const m of text.matchAll(PATH)) marks.push({ start: m.index, end: m.index + m[0].length, kind: 'path' })
64 if (hl.numbers) {
65 for (const m of text.matchAll(NUMBER)) {
66 const start = m.index
67 if (!marks.some(p => start < p.end && start + m[0].length > p.start)) {
68 marks.push({ start, end: start + m[0].length, kind: 'number' })
69 }
70 }
71 }
72 marks.sort((a, b) => a.start - b.start)
73 const out: Inline[] = []
74 let at = 0
75 for (const m of marks) {
76 if (m.start > at) out.push({ kind: 'text', text: text.slice(at, m.start) })
77 out.push({ kind: m.kind, text: text.slice(m.start, m.end) })
78 at = m.end
79 }
80 if (at < text.length) out.push({ kind: 'text', text: text.slice(at) })
81 return out
82}
83
84export const parseInline = (text: string, hl: Highlight): Inline[] => {
85 if (text.length > MAX_INLINE) return [{ kind: 'text', text }]
86 const out: Inline[] = []
87 let at = 0
88 for (const m of text.matchAll(INLINE)) {
89 if (m.index > at) out.push(...decorate(text.slice(at, m.index), hl))
90 if (m[2] !== undefined) out.push({ kind: 'code', text: m[2] })
91 else if (m[3] !== undefined) out.push({ kind: 'link', text: m[3], href: m[4] ?? "" })
92 else if (m[5] !== undefined || m[6] !== undefined) out.push({ kind: 'strong', children: parseInline(m[5] ?? m[6] ?? "", hl) })
93 else if (m[7] !== undefined) out.push({ kind: 'strike', children: parseInline(m[7], hl) })
94 else if (m[8] !== undefined || m[9] !== undefined) out.push({ kind: 'emphasis', children: parseInline(m[8] ?? m[9] ?? "", hl) })
95 else if (m[10] !== undefined) out.push({ kind: 'link', text: m[10], href: m[10] })
96 else if (m[11] !== undefined) out.push(...(isTex(m[11]) ? [{ kind: 'math' as const, text: texText(m[11]) }] : decorate(m[0], hl)))
97 at = m.index + m[0].length
98 }
99 if (at < text.length) out.push(...decorate(text.slice(at), hl))
100 return out
101}
102
103const TEX: Record<string, string> = {
104 alpha: 'α', beta: 'β', gamma: 'γ', delta: 'δ', Delta: 'Δ', epsilon: 'ε', theta: 'θ', lambda: 'λ', mu: 'μ', pi: 'π', rho: 'ρ', sigma: 'σ', Sigma: 'Σ', tau: 'τ', phi: 'φ', omega: 'ω', Omega: 'Ω',
105 cdot: '·', times: '×', div: '÷', pm: '±', le: '≤', leq: '≤', ge: '≥', geq: '≥', neq: '≠', ne: '≠', approx: '≈', infty: '∞', to: '→', rightarrow: '→', Rightarrow: '⇒', sum: 'Σ', sqrt: '√', lceil: '⌈', rceil: '⌉', lfloor: '⌊', rfloor: '⌋',
106}
107
108const isTex = (tex: string) => /[\\^_={}]/.test(tex) || /^[A-Za-z]$/.test(tex)
109
110const texText = (tex: string) =>
111 tex
112 .replace(/\\(?:text|mathrm|mathit|operatorname)\{([^{}]*)\}/g, '$1')
113 .replace(/\\([A-Za-z]+)/g, (all, name: string) => TEX[name] ?? all)
114 .replace(/\\[,;:! ]/g, ' ')
115 .replace(/[{}]/g, '')
116
117export const inlineText = (inline: Inline[]): string =>
118 inline.map(n => ('children' in n ? inlineText(n.children) : n.text)).join('')
119
120const mathAt = (lines: string[], start: number): { lines: string[]; end: number } | null => {
121 const trimmed = (n: number) => (lines[n] ?? '').trim()
122 const first = trimmed(start)
123 if (!first.startsWith('$$')) return null
124 const open = first.slice(2)
125 let end = start
126 if (!(open.length >= 2 && open.endsWith('$$'))) {
127 end = start + 1
128 while (end < lines.length && !trimmed(end).endsWith('$$')) {
129 if (trimmed(end) === '') return null
130 end++
131 }
132 if (end === lines.length) return null
133 }
134 const body = end === start ? [open.slice(0, -2)] : [open, ...lines.slice(start + 1, end), trimmed(end).slice(0, -2)]
135 const tex = body.filter(line => line.trim() !== '').map((line, i, all) => (i === 0 || i === all.length - 1 ? line.trim() : line))
136 return tex.length ? { lines: tex, end } : null
137}
138
139export const displayText = (inline: Inline[]): string =>
140 inline.map(n => (n.kind === 'link' && n.text !== n.href ? `${n.text} (${n.href})` : 'children' in n ? displayText(n.children) : n.text)).join('')
141
142export const isWebLink = (href: string): boolean => /^(https?:|mailto:)/i.test(href)
143
144export const parse = (source: string, hl: Highlight): Block[] => {
145 const lines = source.replace(/\r\n?/g, '\n').split('\n')
146 const at = (n: number) => lines[n] ?? ''
147 const blocks: Block[] = []
148 const add = (block: Draft, from: number, to: number) => blocks.push({ ...block, raw: lines.slice(from, to).join('\n') } as Block)
149 let paraStart = 0
150 let para: string[] = []
151
152 const flush = (end: number) => {
153 if (para.length) add({ kind: 'paragraph', inline: parseInline(para.join(' '), hl) }, paraStart, end)
154 para = []
155 }
156
157 for (let i = 0; i < lines.length; i++) {
158 const line = at(i)
159 const fence = FENCE.exec(line)
160 if (fence) {
161 flush(i)
162 const start = i
163 const run = fence[1] ?? '```'
164 const closer = new RegExp(`^\\s*\\${run[0]}{${run.length},}\\s*$`)
165 const body: string[] = []
166 i++
167 while (i < lines.length && !closer.test(at(i))) body.push(at(i++))
168 add({ kind: 'code', lang: fence[2] ?? '', lines: body, ...(i < lines.length ? {} : { isOpen: true as const }) }, start, i + 1)
169 continue
170 }
171 const math = mathAt(lines, i)
172 if (math) {
173 flush(i)
174 add({ kind: 'code', lang: 'math', lines: math.lines }, i, math.end + 1)
175 i = math.end
176 continue
177 }
178 if (line.trim() === '') {
179 flush(i)
180 continue
181 }
182 const heading = /^(#{1,6})\s+(.*?)\s*#*\s*$/.exec(line)
183 if (heading) {
184 flush(i)
185 add({ kind: 'heading', level: (heading[1] ?? '#').length, inline: parseInline(heading[2] ?? '', hl) }, i, i + 1)
186 continue
187 }
188 if (/^\s*([-*_])(\s*\1){2,}\s*$/.test(line)) {
189 flush(i)
190 add({ kind: 'rule' }, i, i + 1)
191 continue
192 }
193 if (line.includes('|') && i + 1 < lines.length && TABLE_SEP.test(at(i + 1))) {
194 flush(i)
195 const start = i
196 const header = splitRow(line)
197 const align = splitRow(at(i + 1)).map(c =>
198 c.startsWith(':') && c.endsWith(':') ? 'center' : c.endsWith(':') ? 'right' : 'left',
199 )
200 i += 2
201 const rows: Inline[][][] = []
202 while (i < lines.length && at(i).includes('|') && at(i).trim() !== '') {
203 const cells = splitRow(at(i++))
204 rows.push(header.map((_, c) => parseInline(cells[c] ?? '', hl)))
205 }
206 add({ kind: 'table', header: header.map(c => parseInline(c, { numbers: false, paths: false })), align, rows }, start, i)
207 i--
208 continue
209 }
210 if (/^\s*>/.test(line)) {
211 flush(i)
212 const start = i
213 const body: string[] = []
214 while (i < lines.length && /^\s*>/.test(at(i))) body.push(at(i++).replace(/^\s*>\s?/, ''))
215 const alert = ALERT.exec(body[0] ?? '')
216 if (alert) add({ kind: 'alert', level: alert[1]!.toLowerCase() as AlertLevel, inline: parseInline([alert[2]!, ...body.slice(1)].join(' ').trim(), hl) }, start, i)
217 else add({ kind: 'quote', inline: parseInline(body.join(' '), hl) }, start, i)
218 i--
219 continue
220 }
221 const item = LIST_ITEM.exec(line)
222 if (item) {
223 flush(i)
224 const start = i
225 const ordered = /\d/.test(item[2] ?? '')
226 const items: { marker: string; depth: number; task?: boolean; inline: Inline[] }[] = []
227 const contentIndent: number[] = []
228 while (i < lines.length) {
229 const it = LIST_ITEM.exec(at(i))
230 if (it) {
231 contentIndent.push((it[1] ?? '').replace(/\t/g, ' ').length + (it[2] ?? '').length + 1)
232 const task = /^\[([ xX])\]\s+(.*)$/.exec(it[3] ?? '')
233 items.push({ marker: it[2] ?? '-', depth: Math.floor((it[1] ?? '').replace(/\t/g, ' ').length / 2), ...(task ? { task: task[1] !== ' ' } : {}), inline: parseInline(task ? task[2]! : it[3] ?? '', hl) })
234 } else if (/^\s{2,}\S/.test(at(i)) && items.length) {
235 const indent = (at(i).match(/^\s*/)?.[0] ?? '').replace(/\t/g, ' ').length
236 let owner = items.length - 1
237 while (owner > 0 && contentIndent[owner]! > indent) owner--
238 const target = items[owner]!
239 target.inline = [...target.inline, { kind: 'text', text: ' ' }, ...parseInline(at(i).trim(), hl)]
240 } else {
241 break
242 }
243 i++
244 }
245 add({ kind: 'list', ordered, items }, start, i)
246 i--
247 continue
248 }
249 if (!para.length) paraStart = i
250 para.push(line.trim())
251 }
252 flush(lines.length)
253 return blocks
254}
255hooks/clipboard.ts 31 lines1export const MAC_TABLE_COPY = `
2ObjC.import('AppKit')
3var input = $.NSFileHandle.fileHandleWithStandardInput.readDataToEndOfFile
4var payload = JSON.parse(ObjC.unwrap($.NSString.alloc.initWithDataEncoding(input, $.NSUTF8StringEncoding)))
5var item = $.NSPasteboardItem.alloc.init
6if (!item.setStringForType(payload.html, $.NSPasteboardTypeHTML) ||
7 !item.setStringForType(payload.text, $.NSPasteboardTypeString)) throw new Error('Cannot encode table')
8var pasteboard = $.NSPasteboard.generalPasteboard
9if (!pasteboard || !pasteboard.writeObjects) throw new Error('macOS clipboard is unavailable to this session')
10pasteboard.clearContents
11if (!pasteboard.writeObjects($.NSArray.arrayWithObject(item))) throw new Error('Cannot write clipboard')
12if (ObjC.unwrap(pasteboard.stringForType($.NSPasteboardTypeHTML)) !== payload.html ||
13 ObjC.unwrap(pasteboard.stringForType($.NSPasteboardTypeString)) !== payload.text) throw new Error('Clipboard verification failed')
14`
15
16export const LINUX_TABLE_COPY = `
17var table = JSON.parse(str(arguments[1]))
18copy('text/html', table.html, 'text/plain', table.text)
19if (str(clipboard('text/html')) !== table.html ||
20 str(clipboard('text/plain')) !== table.text) throw new Error('Clipboard verification failed')
21`
22
23export type ClipboardBackend = 'macos' | 'linux'
24
25export const clipboardCommand = (backend: ClipboardBackend, html: string, text: string) => ({
26 stdin: JSON.stringify({ html, text }),
27 ...backend === 'macos'
28 ? { argv: ['/usr/bin/osascript', '-l', 'JavaScript', '-e', MAC_TABLE_COPY], failure: 'macOS clipboard helper failed' }
29 : { argv: ['copyq', 'eval', LINUX_TABLE_COPY, '-'], failure: 'CopyQ failed; install and start CopyQ in the graphical session' },
30})
31hooks/mermaid.tsx 229 lines1import type { ElementTable, RenderElement } from 'claude-code'
2
3import { ratexColor } from './latex'
4import { cells, graphemes, remember, width } from './render'
5import type { Style, Theme } from './theme'
6import { renderMermaidAscii, setChartSize } from './vendor/mermaid-text.js'
7import { loadPele } from './vendor/pele.js'
8import type { PeleArt, PelePalette } from './vendor/pelext.js'
9import { drawPele } from './vendor/pelext.js'
10
11const MAX_LINES = 80
12const PAD = '\uFDD0'
13const textCache = new Map<string, string | null>()
14const peleCache = new Map<string, PeleArt | null>()
15const palettes = new WeakMap<Theme, { palette: PelePalette; key: string }>()
16let pele: ReturnType<typeof loadPele> | null = null
17const renderPele = (source: string, options?: Record<string, unknown>) => (pele ??= loadPele()).render(source, options)
18
19export const pelePalette = (theme: Theme, canvas: string): PelePalette => {
20 const series = [...new Set([theme.link, theme.number, theme.heading, theme.emphasis, theme.path, theme.codeFlag, theme.accent, theme.codeString].filter((c): c is string => !!c))]
21 return { canvas, text: theme.diagramText ?? theme.codeText, muted: theme.quote ?? theme.codeComment, line: theme.diagram, border: theme.diagram, accent: theme.accent, critical: theme.codeFlag, highlight: theme.emphasis ?? theme.accent, series, hues: series }
22}
23
24const paletteOf = (style: Style) => {
25 const known = palettes.get(style.theme)
26 if (known) return known
27 const theme = Object.fromEntries(Object.entries(style.theme).map(([k, v]) => [k, v === undefined ? v : ratexColor(v)]))
28 const palette = pelePalette(theme, style.canvas ?? '#1e1e2e')
29 const made = { palette, key: JSON.stringify(palette) }
30 palettes.set(style.theme, made)
31 return made
32}
33
34export const peleText = (source: string, style: Style, columns: number): PeleArt | null => {
35 if (source.length > 8000 || source.split('\n').length > MAX_LINES) return null
36 const { palette, key } = paletteOf(style)
37 return remember(peleCache, `${columns}:${key}:${source}`, () => drawPele(renderPele, source, palette, columns), 50)
38}
39
40const WARMUP = [
41 'flowchart TD\n A[Start] --> B{Ready?}\n B -->|yes| C[Go]\n B -.-> D((Wait))',
42 'sequenceDiagram\n A->>B: ask\n B-->>A: answer',
43 'classDiagram\n class A {\n +go() void\n }\n A <|-- B',
44 'stateDiagram-v2\n [*] --> A\n A --> B: go\n B --> [*]',
45 'erDiagram\n A ||--o{ B : has\n A {\n int id PK\n }',
46]
47
48export const warmPele = (style: Style, step: number): PeleArt | null | undefined => {
49 const source = WARMUP[step]
50 return source === undefined ? undefined : drawPele(renderPele, source, paletteOf(style).palette, 80)
51}
52
53export const peleArt = ({ Box, Text }: ElementTable, art: PeleArt, key: string): RenderElement => (
54 <Box key={key} flexDirection="column" paddingLeft={2}>
55 {art.rows.map((spans, i) => (
56 <Text key={`${key}.${i}`}>
57 {spans.length ? spans.map((s, j) => (s.fg || s.bg || s.bold || s.inverse ? <Text key={`s${j}`} color={s.fg} backgroundColor={s.bg} bold={s.bold} inverse={s.inverse}>{s.text}</Text> : s.text)) : ' '}
58 </Text>
59 ))}
60 </Box>
61)
62
63export const chartSize = (columns: number, source = '') => {
64 const labels = (/^\s*x-axis\b[^[\n]*\[([^\]\n]*)\]/m.exec(source)?.[1] ?? '').split(',').map(s => s.trim().replace(/^"|"$/g, ''))
65 const fit = labels.length * (Math.max(...labels.map(l => l.length)) + 2)
66 const width = Math.max(24, Math.min(60, Math.max(Math.floor(columns / 6), fit), columns - 12))
67 return { width, height: Math.max(8, Math.min(20, Math.round(width * 0.3))) }
68}
69
70const padWide = (source: string) => (/^[\x00-\x7F]*$/.test(source) ? source : graphemes(source).map(g => (g.length === 1 && width(g) === 2 ? g + PAD : g)).join(''))
71
72const unquoteCategories = (source: string) =>
73 source.replace(/^(\s*x-axis\b[^[\n]*\[)([^\]\n]*)\]/m, (_, head: string, items: string) => `${head}${items.replace(/"([^"]*)"/g, (_q, s: string) => s.replaceAll(',', ' '))}]`)
74
75const labelBars = (art: string, source: string): string => {
76 const series = source.match(/^\s*(bar|line)\b.*$/gm) ?? []
77 const values = /^\s*bar\b[^[\n]*\[([^\]\n]*)\]/m.exec(source)?.[1]?.split(',').map(v => v.trim())
78 if (series.length !== 1 || !values || /^\s*xychart(-beta)?\s+horizontal/m.test(source)) return art
79 const grid = art.split('\n').map(l => [...l])
80 const axis = grid.findLastIndex(row => row.includes('┬'))
81 const ticks = grid[axis]?.flatMap((ch, x) => (ch === '┬' ? [x] : [])) ?? []
82 if (ticks.length !== values.length) return art
83 ticks.forEach((x, k) => {
84 const top = grid.findIndex(row => row[x] === '█')
85 const y = top === -1 ? axis - 1 : top - 1
86 const text = [...values[k]!]
87 const from = x - Math.floor((text.length - 1) / 2)
88 const row = grid[y]
89 if (!row || y < 0) return
90 while (row.length < from + text.length) row.push(' ')
91 if (!text.every((_, i) => /[ ·]/.test(row[from + i] ?? ' '))) return
92 text.forEach((ch, i) => (row[from + i] = ch))
93 })
94 return grid.map(row => row.join('').trimEnd()).join('\n')
95}
96
97const SIDEWAYS = /^(\s*(?:flowchart|graph)[ \t]+)(LR|RL)\b/
98
99export const mermaidText = (source: string, ascii: boolean, columns: number): string | null => {
100 if (source.length > 8000 || source.split('\n').length > MAX_LINES) return null
101 const art = draw(source, ascii, columns)
102 const fits = (a: string) => a.split('\n').every(l => width(l) <= columns - 2)
103 if (art === null || fits(art) || !SIDEWAYS.test(source)) return art
104 return draw(source.replace(SIDEWAYS, '$1TD'), ascii, columns) ?? art
105}
106
107const evenTicks = (art: string) => {
108 const rows = art.split('\n').flatMap((line, i) => (/^\s*-?[\d.,]+[kMG%]?\s*[┤┼+|]/.test(line) ? [i] : []))
109 return rows.slice(2).every((row, i) => row - rows[i + 1]! === rows[1]! - rows[0]!)
110}
111
112const draw = (source: string, ascii: boolean, columns: number): string | null => {
113 const isChart = /^\s*xychart/.test(source)
114 const padded = padWide(source)
115 const size = chartSize(columns, isChart ? padded : '')
116 const key = `${ascii}:${isChart ? size.width : 0}:${source}`
117 return remember(textCache, key, () => {
118 try {
119 const render = () => renderMermaidAscii(unquoteCategories(padded.replace(/^(\s*%%[^\n]*\n)+/, '')).replace(/(-->|-\.->|==>|---|-\.-|===)[ \t]+\|/g, '$1|'), { useAscii: ascii, colorMode: 'none', paddingX: 3, paddingY: 1 }).replace(/[ \t]+$/gm, '').trimEnd().replace(/▶/g, '►').replace(/◀/g, '◄')
120 let art = ''
121 for (const height of isChart ? [0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8].map(d => size.height + d).filter(h => h >= 6) : [0]) {
122 if (isChart) setChartSize(size.width, height)
123 art = render()
124 if (!isChart || evenTicks(art)) break
125 }
126 if (isChart && !evenTicks(art)) {
127 setChartSize(size.width, size.height)
128 art = render()
129 }
130 return (isChart ? labelBars(art, padded) : art.split('\n').filter(l => !/^[\s│|]*$/.test(l)).join('\n')).replaceAll(PAD, '')
131 } catch {
132 return null
133 }
134 })
135}
136
137const LINE = /[─-╿◇]/
138const ARROW = /[►◄▲▼]/
139
140const paint = (art: string, style: Style): (string | undefined)[][] => {
141 const t = style.theme
142 const grid = art.split('\n').map(cells)
143 const cell = (r: number, c: number) => grid[r]?.[c] ?? ''
144 const color: (string | undefined)[][] = grid.map(row => row.map(() => undefined))
145 const palette = [...new Set([t.link, t.number, t.heading, t.emphasis, t.path, t.codeFlag, t.accent])].filter((c): c is string => c !== undefined)
146 const next = (i: number) => palette[i % palette.length]
147 const labels = new Map<string, string | undefined>()
148
149 const rects: { r: number; c: number; r2: number; c2: number }[] = []
150 for (let r = 0; r < grid.length; r++) {
151 for (let c = 0; c < (grid[r]?.length ?? 0); c++) {
152 if (!/[┌╭(]/.test(cell(r, c))) continue
153 let c2 = c + 1
154 while (/[─┬┴┼▲▼]/.test(cell(r, c2))) c2++
155 if (!/[┐╮)]/.test(cell(r, c2)) || c2 === c + 1) continue
156 let r2 = r + 1
157 while (/[│├┤┼►◄]/.test(cell(r2, c))) r2++
158 if (!/[└╰(]/.test(cell(r2, c)) || !/[┘╯)]/.test(cell(r2, c2))) continue
159 rects.push({ r, c, r2, c2 })
160 }
161 }
162 const inside = (a: (typeof rects)[number], b: (typeof rects)[number]) => a !== b && b.r > a.r && b.r2 < a.r2 && b.c > a.c && b.c2 < a.c2
163 for (const box of rects.filter(a => !rects.some(b => inside(a, b)))) {
164 const { r, c, r2, c2 } = box
165 const label = grid.slice(r + 1, r2).map(row => row.slice(c + 1, c2).join('')).join(' ').trim()
166 if (!labels.has(label)) labels.set(label, next(labels.size))
167 const hue = labels.get(label)
168 for (let y = r; y <= r2; y++) for (let x = c; x <= c2; x++) if (cell(y, x).trim()) color[y]![x] = hue
169 }
170
171 const bars = [...new Set(grid.flatMap(row => row.flatMap((ch, c) => (ch === '█' && row[c - 1] !== '█' ? [c] : []))))].sort((a, b) => a - b)
172 const ticks = grid.findLast(row => row.includes('┬'))?.filter(ch => ch === '┬').length ?? 0
173 const tops = bars.map(x => grid.findIndex(row => row[x] === '█'))
174 const single = bars.length > 1 && bars.length <= ticks
175 const barColor = (i: number) => (single ? (tops[i] === Math.min(...tops) ? t.emphasis ?? t.accent : t.quote) : next(i))
176 grid.forEach((row, r) =>
177 row.forEach((ch, c) => {
178 if (color[r]![c] !== undefined) return
179 if (ch === '█') {
180 let start = c
181 while (row[start - 1] === '█') start--
182 color[r]![c] = barColor(bars.indexOf(start))
183 } else if (ch === '·') color[r]![c] = t.rule
184 else if (ARROW.test(ch)) color[r]![c] = t.accent
185 else if (LINE.test(ch)) color[r]![c] = t.diagram
186 else if (/^\d+[┤┼]/.test(row.slice(c).join(''))) color[r]![c] = t.number
187 else color[r]![c] = t.diagramText
188 }),
189 )
190 return color
191}
192
193const painted = new WeakMap<Theme, Map<string, (string | undefined)[][]>>()
194
195export const boxArt = ({ Box, Text }: ElementTable, style: Style, art: string, key: string): RenderElement => {
196 const cache = painted.get(style.theme) ?? new Map<string, (string | undefined)[][]>()
197 painted.set(style.theme, cache)
198 const colors = remember(cache, art, () => paint(art, style))
199 return (
200 <Box key={key} flexDirection="column" paddingLeft={2}>
201 {art.split('\n').map((line, i) => {
202 const chars = cells(line)
203 const parts: RenderElement[] = []
204 let at = 0
205 while (at < chars.length) {
206 const hue = colors[i]?.[at]
207 let end = at + 1
208 while (end < chars.length && colors[i]?.[end] === hue) end++
209 parts.push(<Text key={`t${parts.length}`} color={hue}>{chars.slice(at, end).join('')}</Text>)
210 at = end
211 }
212 return <Text key={`${key}.${i}`}>{parts.length ? parts : ' '}</Text>
213 })}
214 </Box>
215 )
216}
217
218const EDGE_LABEL = /(-[-.=]+\s*)"([^"\n]+)"(\s*[-.=]+>)|\|([^|\n]+)\|/g
219
220const cap = (label: string, max: number) => {
221 const flat = label.replace(/<br\s*\/?>/gi, ' ').replace(/\s+/g, ' ').trim()
222 const chars = graphemes(flat)
223 return chars.length > max ? `${chars.slice(0, max - 1).join('').trimEnd()}…` : flat
224}
225
226export const shortenEdgeLabels = (source: string, max: number): string =>
227 source.replace(EDGE_LABEL, (_, open, quoted, close, piped) =>
228 quoted !== undefined ? `${open}"${cap(quoted, max)}"${close}` : `|${cap(piped, max)}|`)
229hooks/render.tsx 1155 lines1import type { ElementTable, RenderElement } from 'claude-code'
2
3import { tableHtml, tableText } from './html'
4import type { Block, Inline } from './markdown'
5import { displayText, inlineText } from './markdown'
6import { commentTail, commentVisual, flow, hasRtl, terminalLine } from './rtl'
7import type { Style, Theme } from './theme'
8import type { PrismToken } from './vendor/prism.js'
9import { languages, tokenize } from './vendor/prism.js'
10
11const WIDE = /[\u1100-\u115F\u2E80-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFF60\uFFE0-\uFFE6]|\p{Extended_Pictographic}/u
12const segmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter() : undefined
13
14export const graphemes = (s: string): string[] => (segmenter ? [...segmenter.segment(s)].map(g => g.segment) : [...s])
15
16export const cells = (s: string): string[] => (/^[ -~]*$/.test(s) ? [...s] : graphemes(s).flatMap(g => (WIDE.test(g) ? [g, ''] : [g])))
17
18export const width = (s: string): number =>
19 /^[ -~]*$/.test(s) ? s.length : graphemes(s).reduce((w, g) => (/^\p{M}+$/u.test(g) ? w : w + (WIDE.test(g) ? 2 : 1)), 0)
20
21const wrapRanges = (text: string, w: number): [number, number][] => {
22 if (width(text) <= w) return [[0, text.length]]
23 const out: [number, number][] = []
24 let line: [number, number] | undefined
25 let used = 0
26 for (const word of text.matchAll(/\S+/g)) {
27 let start = word.index
28 const end = start + word[0].length
29 let size = width(word[0])
30 while (size > w) {
31 if (line) out.push(line)
32 line = undefined
33 let cut = start
34 let taken = 0
35 for (const g of graphemes(text.slice(start, end))) {
36 const step = width(g)
37 if (cut > start && taken + step > w) break
38 cut += g.length
39 taken += step
40 }
41 out.push([start, cut])
42 start = cut
43 size -= taken
44 }
45 if (start === end) continue
46 const joined = line ? used + width(text.slice(line[1], start)) + size : Infinity
47 if (line && joined <= w) {
48 line = [line[0], end]
49 used = joined
50 } else {
51 if (line) out.push(line)
52 line = [start, end]
53 used = size
54 }
55 }
56 if (line) out.push(line)
57 return out.length ? out : [[0, 0]]
58}
59
60const sliceInline = (nodes: Inline[], from: number, to: number): Inline[] => {
61 const out: Inline[] = []
62 let at = 0
63 for (const n of nodes) {
64 const length = inlineText([n]).length
65 const a = Math.max(from - at, 0)
66 const b = Math.min(to - at, length)
67 at += length
68 if (a >= b) continue
69 if ('children' in n) out.push({ ...n, children: sliceInline(n.children, a, b) })
70 else out.push({ ...n, text: n.text.slice(a, b) })
71 }
72 return out
73}
74
75const hasLink = (nodes: Inline[]): boolean => nodes.some(n => n.kind === 'link' || ('children' in n && hasLink(n.children)))
76
77const mostLines = (text: string, w: number): number => (text.match(/\S+/g)?.length ?? 0) + Math.ceil(width(text) / w)
78
79const wrapInline = (nodes: Inline[], w: number): Inline[][] => {
80 const text = inlineText(nodes)
81 return width(text) <= w ? [nodes] : wrapRanges(text, w).map(([a, b]) => sliceInline(nodes, a, b))
82}
83
84const flowOf = (style: Style, nodes: Inline[], columns: number) => (style.reorder ? flow(nodes, columns, width, style.shape) : null)
85
86const renderInline = (el: ElementTable, style: Style, nodes: Inline[], keyBase: string): RenderElement[] => {
87 const { Text } = el
88 const t = style.theme
89 return nodes.map((n, i) => {
90 const key = `${keyBase}.${i}`
91 switch (n.kind) {
92 case 'text':
93 return <Text key={key}>{n.text}</Text>
94 case 'strong':
95 return <Text key={key} bold color={t.strong}>{renderInline(el, style, n.children, key)}</Text>
96 case 'emphasis':
97 return <Text key={key} italic color={t.emphasis}>{renderInline(el, style, n.children, key)}</Text>
98 case 'strike':
99 return <Text key={key} strikethrough dimColor>{renderInline(el, style, n.children, key)}</Text>
100 case 'code':
101 return <Text key={key} color={t.inlineCode}>{n.text}</Text>
102 case 'math':
103 return <Text key={key} italic color={t.emphasis}>{n.text}</Text>
104 case 'link':
105 return /^(https:|http:\/\/localhost\b)/i.test(n.href)
106 ? n.text === n.href ? <el.Link key={key} href={n.href} /> : <el.Link key={key} href={n.href}><Text color={t.link} underline>{n.text}</Text></el.Link>
107 : <Text key={key} color={t.link} underline>{n.text}</Text>
108 case 'number':
109 return <Text key={key} color={t.number}>{n.text}</Text>
110 case 'path':
111 return <Text key={key} color={t.path}>{n.text}</Text>
112 case 'dim':
113 return <Text key={key} dimColor>{n.text}</Text>
114 }
115 })
116}
117
118const renderFlow = (el: ElementTable, style: Style, lines: Inline[][], key: string, props: { italic?: boolean; color?: string; bold?: boolean } = {}) => {
119 const { Text } = el
120 return lines.map((line, i) => <Text key={`${key}.${i}`} {...props}>{renderInline(el, style, line, `${key}.${i}`)}</Text>)
121}
122
123const PRISM_COLORS: Record<string, keyof Theme> = {
124 comment: 'codeComment', prolog: 'codeComment', doctype: 'codeComment', cdata: 'codeComment',
125 string: 'codeString', char: 'codeString', 'template-string': 'codeString', 'attr-value': 'codeString', url: 'codeString',
126 number: 'number', boolean: 'number', constant: 'number', symbol: 'number', inserted: 'number',
127 keyword: 'codeFlag', important: 'codeFlag', atrule: 'codeFlag', rule: 'codeFlag', deleted: 'codeFlag',
128 function: 'codeCommand', 'class-name': 'codeCommand', builtin: 'codeCommand', key: 'codeCommand', selector: 'codeCommand',
129 property: 'link', tag: 'link', 'attr-name': 'emphasis', variable: 'emphasis', regex: 'path',
130}
131
132type Segment = { text: string; color?: string; italic: boolean }
133
134const flatten = (tokens: PrismToken[], style: Style, color?: string, italic = false): Segment[] =>
135 tokens.flatMap(token => {
136 if (typeof token === 'string') return [{ text: token, color, italic }]
137 const names = [token.type, ...(Array.isArray(token.alias) ? token.alias : token.alias ? [token.alias] : [])]
138 const slot = names.map(n => PRISM_COLORS[n]).find(Boolean)
139 const inner = Array.isArray(token.content) ? token.content : [token.type === 'comment' && typeof token.content === 'string' && style.reorder ? commentVisual(token.content, style.shape) : token.content]
140 return flatten(inner, style, slot ? style.theme[slot] : color, italic || token.type === 'comment')
141 })
142
143export const remember = <T,>(cache: Map<string, T>, key: string, make: () => T, limit = 200): T => {
144 const hit = cache.get(key)
145 if (hit !== undefined) {
146 cache.delete(key)
147 cache.set(key, hit)
148 return hit
149 }
150 const value = make()
151 cache.set(key, value)
152 if (cache.size > limit) cache.delete(cache.keys().next().value!)
153 return value
154}
155
156const highlighted = new WeakMap<Theme, Map<string, Segment[][]>>()
157
158const grammarFor = (lang: string) => {
159 const name = lang.toLowerCase()
160 const grammar = Object.hasOwn(languages, name) ? languages[name] : undefined
161 return grammar !== null && typeof grammar === 'object' ? grammar : undefined
162}
163
164export const highlightBlock = ({ Text }: ElementTable, style: Style, lines: string[], lang: string, key: string): RenderElement[] | null => {
165 const grammar = grammarFor(lang)
166 if (!grammar) return null
167 const code = lines.join('\n')
168 const cache = highlighted.get(style.theme) ?? new Map<string, Segment[][]>()
169 highlighted.set(style.theme, cache)
170 const rows = remember(cache, `${style.reorder ? style.shape : ''}\0${lang}\0${code}`, () => {
171 const out: Segment[][] = [[]]
172 for (const seg of flatten(tokenize(code, grammar), style)) {
173 seg.text.split('\n').forEach((piece, i) => {
174 if (i > 0) out.push([])
175 if (piece) out[out.length - 1]!.push({ ...seg, text: piece })
176 })
177 }
178 return out
179 })
180 return rows.map((row, r) => (
181 <Text key={`${key}.${r}`} color={style.theme.codeText}>
182 {row.length ? row.map((s, i) => <Text key={`${key}.${r}.${i}`} color={s.color} italic={s.italic}>{s.text}</Text>) : ' '}
183 </Text>
184 ))
185}
186
187const isShellLang = (lang: string) => lang === '' || /^(sh|bash|zsh|shell|console|fish|powershell|ps1)$/i.test(lang)
188
189export const codeLine = (el: ElementTable, style: Style, line: string, lang: string, key: string): RenderElement => {
190 const { Text } = el
191 const t = style.theme
192 const isShell = isShellLang(lang)
193 if (/[\u2500-\u257F]/.test(line)) return <Text key={key} color={t.codeText}>{line}</Text>
194 const comment = style.reorder ? commentTail(line, style.shape) : null
195 if (comment) {
196 return (
197 <Text key={key} color={t.codeText}>
198 {comment.head ? codeLine(el, style, comment.head, lang, `${key}.h`) : null}
199 <Text color={t.codeComment}>{comment.marker + comment.tail}</Text>
200 </Text>
201 )
202 }
203 if (!isShell) return <Text key={key} color={t.codeText}>{line || ' '}</Text>
204 if (/^\s*#/.test(line)) return <Text key={key} color={t.codeComment}>{line}</Text>
205 const parts = line.split(/("[^"]*"|'[^']*'|\s+)/).filter(p => p !== '')
206 let seenCommand = false
207 return (
208 <Text key={key} color={t.codeText}>
209 {parts.map((p, i) => {
210 if (/^\s+$/.test(p)) return <Text key={`${key}.${i}`}>{p}</Text>
211 if (/^["']/.test(p)) return <Text key={`${key}.${i}`} color={t.codeString}>{p}</Text>
212 if (/^--?[\w-]/.test(p)) return <Text key={`${key}.${i}`} color={t.codeFlag}>{p}</Text>
213 if (!seenCommand && !/^[$>|&;]+$/.test(p)) {
214 seenCommand = true
215 return <Text key={`${key}.${i}`} color={t.codeCommand}>{p}</Text>
216 }
217 if (/^(\||&&|;|\|\|)$/.test(p)) seenCommand = false
218 return <Text key={`${key}.${i}`}>{p}</Text>
219 })}
220 </Text>
221 )
222}
223
224const longestWord = (text: string): number => Math.max(0, ...text.split(/\s+/).map(width))
225
226export const columnWidths = (natural: number[], available: number, gap: number, words: number[] = []): number[] => {
227 const room = Math.max(natural.length, available - gap * (natural.length - 1))
228 const total = natural.reduce((a, b) => a + b, 0)
229 if (total <= room) return natural
230 const minimum = natural.map((w, c) => Math.min(w, Math.max(1, words[c] ?? 1)))
231 const widths = natural.map(() => 0)
232 let open = natural.map((_, c) => c)
233 let left = room
234 for (let fixed = [-1]; fixed.length; ) {
235 const share = Math.floor(left / open.length)
236 const claim = (c: number) => (natural[c]! <= share ? natural[c]! : minimum[c]!)
237 const minimumsFit = open.reduce((a, c) => a + minimum[c]!, 0) <= left
238 const needed = open.reduce((a, c) => a + claim(c), 0)
239 fixed = open.filter(c => natural[c]! <= share)
240 if (minimumsFit && (!fixed.length || needed > left)) fixed = open.filter(c => minimum[c]! > share)
241 fixed.forEach(c => (widths[c] = claim(c), left -= widths[c]!))
242 open = open.filter(c => !fixed.includes(c))
243 }
244 open.forEach((c, i) => (widths[c] = Math.max(1, Math.floor(left / open.length) + (i < left % open.length ? 1 : 0))))
245 while (widths.reduce((a, b) => a + b, 0) > room) {
246 const widest = widths.indexOf(Math.max(...widths))
247 if (widths[widest]! <= 1) break
248 widths[widest]!--
249 }
250 return widths
251}
252
253const isRtlTable = (style: Style, block: Extract<Block, { kind: 'table' }>): boolean => {
254 const cells = [...block.header, ...block.rows.flat()].filter(cell => displayText(cell).trim() !== '')
255 return cells.filter(cell => flowOf(style, cell, Infinity)?.base === 'R').length * 2 > cells.length
256}
257
258const ART_WIDTH = 100
259
260export const tableArt = (block: Extract<Block, { kind: 'table' }>): string => {
261 const cells = [block.header, ...block.rows].map(r => block.header.map((_, c) => displayText(r[c] ?? [])))
262 const widths = columnWidths(
263 block.header.map((_, c) => Math.max(...cells.map(r => width(r[c]!)))),
264 ART_WIDTH - 4,
265 3,
266 block.header.map((_, c) => Math.max(...cells.map(r => longestWord(r[c]!)))),
267 )
268 const pad = (text: string, c: number, align: 'left' | 'right' | 'center') => {
269 const room = widths[c]! - width(text)
270 const left = align === 'right' ? room : align === 'center' ? Math.floor(room / 2) : 0
271 return ' '.repeat(left) + text + ' '.repeat(room - left)
272 }
273 const line = (l: string, m: string, r: string) => l + widths.map(w => '─'.repeat(w + 2)).join(m) + r
274 const row = (r: string[], header: boolean) => {
275 const lines = r.map((text, c) => wrapRanges(text, widths[c]!).map(([a, b]) => text.slice(a, b)))
276 return Array.from({ length: Math.max(...lines.map(l => l.length)) }, (_, i) =>
277 `│ ${lines.map((l, c) => pad(l[i] ?? '', c, header ? 'center' : block.align[c] ?? 'left')).join(' │ ')} │`)
278 }
279 const art = [line('┌', '┬', '┐'), ...row(cells[0]!, true), ...cells.slice(1).flatMap(r => [line('├', '┼', '┤'), ...row(r, false)]), line('└', '┴', '┘')]
280 return ['```', ...art, '```'].join('\n')
281}
282
283const renderTable = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'table' }>, columns: number, key: string, rtl: boolean) => {
284 const { Box, Text } = el
285 const t = style.theme
286 const box = style.tableStyle === 'box'
287 const gap = box ? 0 : style.tableStyle === 'grid' ? 3 : 2
288 const natural = block.header.map((h, c) =>
289 Math.max(width(displayText(h)), ...block.rows.map(r => width(displayText(r[c] ?? [])))),
290 )
291 const words = block.header.map((h, c) =>
292 Math.max(longestWord(displayText(h)), ...block.rows.map(r => longestWord(displayText(r[c] ?? [])))),
293 )
294 const widths = box ? columnWidths(natural, columns - 4, 3, words) : columnWidths(natural, columns, gap, words)
295 const order = natural.map((_, c) => c)
296 if (rtl) order.reverse()
297 const ruleChar = style.tableStyle === 'grid' ? '━' : '─'
298 const justify = (c: number) =>
299 block.align[c] === 'right' ? 'flex-end' : block.align[c] === 'center' ? 'center' : 'flex-start'
300
301 const rule = (k: string, heavy: boolean) => (
302 <Box key={k} flexDirection="row" columnGap={gap}>
303 {order.map(c => (
304 <Text key={`${k}.${c}`} color={t.tableRule} dimColor={!heavy && !t.tableRule}>
305 {(heavy ? ruleChar : '─').repeat(widths[c]!)}
306 </Text>
307 ))}
308 </Box>
309 )
310
311 const bar = (k: string, text: string, lines = 1) => (
312 <Text key={k} color={t.tableRule} dimColor={!t.tableRule}>{Array.from({ length: lines }, () => text).join('\n')}</Text>
313 )
314 const clipped = (lines: number) => (k: string, text: string) => (
315 <Box key={k} minWidth={width(text)}>
316 <Box position="absolute" top={0} bottom={0} left={0} minWidth={width(text)} overflow="hidden">
317 {bar(`${k}.b`, text, lines)}
318 </Box>
319 </Box>
320 )
321 const edge = (k: string, [left, fill, mid, right]: string) =>
322 bar(k, left + order.map(c => fill!.repeat(widths[c]! + 2)).join(mid) + right)
323
324 const terminalRow = (cells: Inline[][], k: string, isHeader: boolean) => {
325 const parts: Inline[] = box ? [{ kind: 'dim', text: '│ ' }] : []
326 order.forEach((c, i) => {
327 if (i > 0) parts.push(box ? { kind: 'dim', text: ' │ ' } : { kind: 'text', text: ' '.repeat(gap) })
328 const cell = flowOf({ ...style, shape: 'visual' }, cells[c] ?? [], Infinity)
329 const content = cell ? cell.lines[0]! : (cells[c] ?? [])
330 const pad = Math.max(0, widths[c]! - width(inlineText(content)))
331 const side = cell?.base === 'R' && block.align[c] !== 'center' ? 'flex-end' : justify(c)
332 const before = side === 'flex-end' ? pad : side === 'center' ? Math.floor(pad / 2) : 0
333 parts.push({ kind: 'text', text: ' '.repeat(before) }, ...(isHeader ? [{ kind: 'strong' as const, children: content }] : content), { kind: 'text', text: ' '.repeat(pad - before) })
334 })
335 if (box) parts.push({ kind: 'dim', text: ' │' })
336 return <Text key={k}>{renderInline(el, style, terminalLine(parts), k)}</Text>
337 }
338
339 const row = (cells: Inline[][], k: string, isHeader: boolean, border: (k: string, text: string) => RenderElement = bar) => rtl && style.shape === 'inverse' ? terminalRow(cells, k, isHeader) : (
340 <Box key={k} flexDirection="row" columnGap={gap} alignItems="stretch">
341 {box && border(`${k}.l`, '│ ')}
342 {order.map((c, i) => {
343 const w = widths[c]!
344 const cell = flowOf(style, cells[c] ?? [], Infinity)
345 const content = cell ? cell.lines[0]! : (cells[c] ?? [])
346 const side = cell?.base === 'R' && block.align[c] !== 'center' ? 'flex-end' : justify(c)
347 const cellBox = (
348 <Box key={`${k}.${c}`} width={w} flexShrink={0} justifyContent={side}>
349 {isHeader
350 ? <Text bold color={t.tableHeader}>{inlineText(content)}</Text>
351 : <Text>{renderInline(el, style, content, `${k}.${c}`)}</Text>}
352 </Box>
353 )
354 return box && i > 0 ? [border(`${k}.${c}s`, ' │ '), cellBox] : cellBox
355 })}
356 {box && border(`${k}.r`, ' │')}
357 </Box>
358 )
359
360 const wrappedRow = (cells: Inline[][], k: string, isHeader: boolean) => {
361 if (!isHeader && cells.some(hasLink)) return [row(cells, k, isHeader, clipped(Math.max(1, ...widths.map((w, c) => mostLines(displayText(cells[c] ?? []), w)))))]
362 const wrapped = widths.map((w, c) => {
363 const content = cells[c] ?? []
364 if (natural[c]! <= w) return [content]
365 return wrapInline(isHeader ? [{ kind: 'text', text: inlineText(content) }] : content, w)
366 })
367 return Array.from({ length: Math.max(...wrapped.map(l => l.length)) }, (_, i) =>
368 row(wrapped.map(l => l[i] ?? []), `${k}.${i}`, isHeader))
369 }
370
371 if (box) {
372 const lines: RenderElement[] = [edge(`${key}.t`, '┌─┬┐'), ...wrappedRow(block.header, `${key}.h`, true), edge(`${key}.hr`, '╞═╪╡')]
373 block.rows.forEach((r, i) => {
374 if (i > 0) lines.push(edge(`${key}.r${i}r`, '├─┼┤'))
375 lines.push(...wrappedRow(r, `${key}.r${i}`, false))
376 })
377 lines.push(edge(`${key}.b`, '└─┴┘'))
378 return <Box key={key} flexDirection="column" {...(rtl ? { alignSelf: 'flex-end' as const } : {})}>{lines}</Box>
379 }
380
381 const body: RenderElement[] = [row(block.header, `${key}.h`, true), rule(`${key}.hr`, true)]
382 block.rows.forEach((r, i) => {
383 body.push(row(r, `${key}.r${i}`, false))
384 if (style.tableStyle !== 'minimal' && i < block.rows.length - 1) body.push(rule(`${key}.r${i}r`, false))
385 })
386 return <Box key={key} flexDirection="column" {...(rtl ? { alignSelf: 'flex-end' as const } : {})}>{body}</Box>
387}
388
389const renderHeading = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'heading' }>, key: string) => {
390 const rtl = flowOf(style, block.inline, Infinity)
391 if (!rtl) return drawHeading(el, style, block, block.inline, key)
392 const heading = drawHeading(el, style, block, rtl.lines[0]!, key)
393 return rtl.base === 'R' ? <el.Box key={key} alignSelf="flex-end">{heading}</el.Box> : heading
394}
395
396const drawHeading = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'heading' }>, inline: Inline[], key: string) => {
397 const { Box, Text } = el
398 const t = style.theme
399 const color = block.level <= 2 ? t.heading : t.accent ?? t.heading
400 const label = inlineText(inline)
401 switch (style.headingStyle) {
402 case 'uppercase':
403 return <Text key={key} bold color={color}>{block.level === 1 ? label.toUpperCase() : label}</Text>
404 case 'underline':
405 return <Text key={key} bold underline={block.level <= 2} color={color}>{label}</Text>
406 case 'banner':
407 if (block.level === 1) return <Box key={key} alignSelf="flex-start" borderStyle="bold" borderColor={color} paddingX={1}><Text bold color={color}>{renderInline(el, style, inline, key)}</Text></Box>
408 return block.level === 2
409 ? <Box key={key} flexDirection="column" alignSelf="flex-start"><Text bold color={color}>{renderInline(el, style, inline, key)}</Text><Text color={color}>{'━'.repeat(width(label))}</Text></Box>
410 : <Text key={key} bold color={block.level === 3 ? color : t.strong}>{renderInline(el, style, inline, key)}</Text>
411 default:
412 return <Text key={key} bold color={color}>{renderInline(el, style, inline, key)}</Text>
413 }
414}
415
416const ALERT_COLOR = { note: 'blue', tip: 'green', important: 'magenta', warning: 'yellow', caution: 'red' } as const
417
418const renderParagraph = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'paragraph' }>, columns: number, key: string) => {
419 const { Box, Text } = el
420 const rtl = flowOf(style, block.inline, columns)
421 if (rtl?.base === 'R') return <Box key={key} flexDirection="column" alignItems="flex-end">{renderFlow(el, style, rtl.lines, key)}</Box>
422 return <Text key={key} bold={style.narration}>{renderInline(el, style, rtl ? rtl.lines[0]! : block.inline, key)}</Text>
423}
424
425const renderQuote = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'quote' }>, columns: number, key: string) => {
426 const { Box, Text } = el
427 const t = style.theme
428 const rtl = flowOf(style, block.inline, columns - 2)
429 if (rtl?.base === 'R') {
430 return (
431 <Box key={key} flexDirection="row" justifyContent="flex-end">
432 <Box flexDirection="column" alignItems="flex-end">{renderFlow(el, style, rtl.lines, key, { italic: true, color: t.quote })}</Box>
433 <Text color={t.accent}> │</Text>
434 </Box>
435 )
436 }
437 return (
438 <Box key={key} flexDirection="row">
439 <Text color={t.accent}>│ </Text>
440 <Text italic color={t.quote}>{renderInline(el, style, rtl ? rtl.lines[0]! : block.inline, key)}</Text>
441 </Box>
442 )
443}
444
445const renderAlert = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'alert' }>, columns: number, key: string) => {
446 const { Box, Text } = el
447 const color = ALERT_COLOR[block.level]
448 const title = <Text bold color={color}>{block.level[0]!.toUpperCase() + block.level.slice(1)}</Text>
449 const rtl = flowOf(style, block.inline, columns - 4)
450 if (rtl?.base === 'R') {
451 return (
452 <Box key={key} flexDirection="column" alignSelf="flex-end" alignItems="flex-end" borderStyle="round" borderColor={color} paddingX={1}>
453 {title}
454 {renderFlow(el, style, rtl.lines, key)}
455 </Box>
456 )
457 }
458 const inline = rtl ? rtl.lines[0]! : block.inline
459 return (
460 <Box key={key} flexDirection="column" alignSelf="flex-start" borderStyle="round" borderColor={color} paddingX={1}>
461 {title}
462 {inline.length ? <Text>{renderInline(el, style, inline, key)}</Text> : null}
463 </Box>
464 )
465}
466
467const TASK_GLYPHS = { checks: ['[ ]', '[✓]'], ticks: ['○', '✓'], box: ['□', '✓'], progress: ['○', '✓'] } as const
468
469const renderList = (el: ElementTable, style: Style, block: Extract<Block, { kind: 'list' }>, columns: number, key: string) => {
470 const { Box, Text } = el
471 const t = style.theme
472 const tasks = block.items.filter(item => item.task !== undefined)
473 const done = tasks.filter(item => item.task).length
474 const filled = tasks.length ? Math.round((done / tasks.length) * 20) : 0
475 const strike = style.taskStyle === 'checks' || style.taskStyle === 'box'
476 const tick = style.taskStyle === 'ticks' || style.taskStyle === 'progress'
477 return (
478 <Box key={key} flexDirection="column">
479 {style.taskStyle === 'progress' && tasks.length > 0 && (
480 <Text>
481 <Text color={t.accent}>{'━'.repeat(filled)}</Text>
482 <Text color={t.bullet} dimColor>{'─'.repeat(20 - filled)}</Text>
483 <Text color={t.bullet}>{` ${done}/${tasks.length} done`}</Text>
484 </Text>
485 )}
486 {block.items.map((item, i) => {
487 const k = `${key}.${i}`
488 const glyph = item.task !== undefined ? TASK_GLYPHS[style.taskStyle][item.task ? 1 : 0] : /\d/.test(item.marker) ? item.marker : item.depth ? '◦' : '•'
489 const glyphColor = item.task && tick ? t.accent : t.bullet
490 const rtl = flowOf(style, item.inline, columns - item.depth * 2 - glyph.length - 1)
491 if (rtl?.base === 'R') {
492 return (
493 <Box key={k} flexDirection="row" justifyContent="flex-end" paddingRight={item.depth * 2}>
494 <Box flexDirection="column" alignItems="flex-end">{renderFlow(el, style, rtl.lines, k)}</Box>
495 <Text color={glyphColor}>{` ${glyph}`}</Text>
496 </Box>
497 )
498 }
499 return (
500 <Box key={k} flexDirection="row" paddingLeft={item.depth * 2}>
501 <Text color={glyphColor}>{`${glyph} `}</Text>
502 <Text dimColor={item.task === true} strikethrough={item.task === true && strike}>{renderInline(el, style, rtl ? rtl.lines[0]! : item.inline, k)}</Text>
503 </Box>
504 )
505 })}
506 </Box>
507 )
508}
509
510export type CopyButton = (text: string | (() => string), key: string, label?: string, html?: () => string) => RenderElement | null
511export type Drawn = Map<number, { element: RenderElement; art?: string }>
512
513const copySource = (block: Block): string | undefined =>
514 block.kind === 'code' ? block.lines.join('\n') : block.kind === 'table' || block.kind === 'list' ? block.raw : block.kind === 'quote' || block.kind === 'alert' ? block.raw.split('\n').map(line => line.replace(/^\s*>\s?/, '')).join('\n') : undefined
515
516export const renderBlocks = (el: ElementTable, style: Style, blocks: Block[], columns: number, drawn: Drawn = new Map(), copy?: CopyButton): RenderElement[] => {
517 const { Box, Text } = el
518 const t = style.theme
519 const rtlTables = blocks.map(block => style.reorder && block.kind === 'table' && isRtlTable(style, block))
520 const rendered = blocks.map((block, b) => {
521 const key = `b${b}`
522 switch (block.kind) {
523 case 'heading':
524 return renderHeading(el, style, block, key)
525 case 'paragraph':
526 return renderParagraph(el, style, block, columns, key)
527 case 'quote':
528 return renderQuote(el, style, block, columns, key)
529 case 'alert':
530 return renderAlert(el, style, block, columns, key)
531 case 'rule':
532 return <Text key={key} color={t.rule} dimColor={!t.rule}>{'─'.repeat(Math.max(8, Math.min(columns, 80)))}</Text>
533 case 'code':
534 return drawn.get(b)?.element ?? (
535 <Box key={key} flexDirection="column" alignSelf="flex-start">
536 <Box flexDirection="row" justifyContent="space-between" columnGap={4}>
537 <Text color={t.codeComment}>{`── ${block.lang || 'code'}`}</Text>
538 {copy?.(block.lines.join('\n'), `copy${b}`) ?? null}
539 </Box>
540 <Box flexDirection="column" paddingLeft={2}>
541 {(isShellLang(block.lang) ? null : highlightBlock(el, style, block.lines, block.lang, key)) ?? block.lines.map((line, i) => codeLine(el, style, line, block.lang, `${key}.${i}`))}
542 </Box>
543 </Box>
544 )
545 case 'list':
546 return renderList(el, style, block, columns, key)
547 case 'table':
548 return renderTable(el, style, block, columns, key, rtlTables[b]!)
549 }
550 })
551 const copied = rendered.map((element, b) => {
552 const block = blocks[b]
553 const text = block ? copySource(block) : undefined
554 const isPlainCode = block?.kind === 'code' && !drawn.has(b)
555 const art = drawn.get(b)?.art ?? (block?.kind === 'table' ? () => tableArt(block) : undefined)
556 const first = text === undefined || isPlainCode ? null : copy?.(text, `copy${b}`, block?.kind === 'table' ? '⧉ md' : art === undefined ? undefined : '⧉ source')
557 const second = first && art !== undefined ? copy?.(art, `art${b}`, '⧉ art') : null
558 const html = first && block?.kind === 'table' ? copy?.(() => tableText(block), `html${b}`, '⧉ html', () => tableHtml(block)) : null
559 const button = second ? (
560 <el.Box key={`copies${b}`} flexDirection="row" columnGap={1}>
561 {first}
562 {second}
563 {html}
564 </el.Box>
565 ) : first
566 if (!button) return element
567 const { Box } = el
568 const rtl = style.reorder && block !== undefined && hasRtl(block.raw)
569 return block?.kind === 'quote' || block?.kind === 'alert' ? (
570 <Box key={`c${b}`} flexDirection="row" columnGap={2} {...(rtl ? { justifyContent: 'flex-end' as const } : {})}>
571 {element}
572 {button}
573 </Box>
574 ) : (
575 <Box key={`c${b}`} flexDirection="column" {...(rtl && (block?.kind === 'list' || rtlTables[b]) ? {} : { alignSelf: 'flex-start' as const })}>
576 <Box justifyContent="flex-end">{button}</Box>
577 {element}
578 </Box>
579 )
580 })
581 const isFigure = (b: number) => blocks[b]?.kind === 'table' || drawn.get(b)?.art !== undefined
582 const out: RenderElement[] = []
583 for (let b = 0; b < rendered.length; b++) {
584 if (!isFigure(b) || !isFigure(b + 1)) {
585 out.push(copied[b]!)
586 continue
587 }
588 const start = b
589 while (isFigure(b + 1)) b++
590 out.push(
591 <Box key={`row${start}`} flexDirection="row" flexWrap="wrap" columnGap={4} rowGap={1}>
592 {copied.slice(start, b + 1).map((figure, i) => <Box key={`f${start + i}`} flexShrink={0}>{figure}</Box>)}
593 </Box>,
594 )
595 }
596 return out
597}
598
599export type ToolRow = { tool: string; input: unknown; isRunning: boolean; isErrored: boolean; isInterrupted: boolean }
600
601const VERBS: Record<string, string> = {
602 Bash: 'Ran', PowerShell: 'Ran', Read: 'Read', Write: 'Wrote', Edit: 'Edited', MultiEdit: 'Edited', NotebookEdit: 'Edited',
603 Grep: 'Searched', Glob: 'Listed', WebFetch: 'Fetched', WebSearch: 'Searched the web for', Agent: 'Delegated', Task: 'Delegated',
604}
605
606const field = (input: unknown, ...keys: string[]): string | undefined => {
607 if (input === null || typeof input !== 'object') return undefined
608 for (const k of keys) {
609 const v = (input as Record<string, unknown>)[k]
610 if (typeof v === 'string' && v.trim() !== '') return v
611 }
612 return undefined
613}
614
615const TARGET_FIELDS = ['file_path', 'notebook_path', 'path', 'pattern', 'url', 'query', 'description']
616
617const statusColor = (t: Theme, row: ToolRow) =>
618 row.isErrored ? t.codeFlag : row.isInterrupted ? t.codeComment : row.isRunning ? t.accent : t.number
619
620const toolDim = (style: Style) => style.toolStyle !== "classic"
621
622const toolGutter = ({ Box, Text }: ElementTable, style: Style, color: string | undefined, running: boolean) =>
623 style.toolStyle.startsWith("tree")
624 ? <Box width={4} flexShrink={0}><Text color={color}>{' ⎿ '}</Text></Box>
625 : <Box width={2} flexShrink={0}><Text color={color}>{running ? '◌' : '●'}</Text></Box>
626
627const toolLayout = (el: ElementTable, style: Style, columns: number, label: string, color: string | undefined, running: boolean, text: RenderElement) => {
628 const { Box, Text } = el
629 if (style.toolStyle !== "chat") return <Box flexDirection="row">{toolGutter(el, style, color, running)}{text}</Box>
630 const w = Math.min(width(label) + 2, Math.max(20, Math.floor(columns * 0.6)))
631 return (
632 <Box flexDirection="row" justifyContent="flex-end" width="100%">
633 <Box width={w} flexDirection="row">{text}<Text color={color}>{running ? " ◌" : " ●"}</Text></Box>
634 </Box>
635 )
636}
637
638type Places = Pick<Style, 'cwd' | 'home'>
639
640export const shortPath = (style: Places, path: string): string => {
641 for (const [root, prefix] of [[style.cwd, ''], [style.home, '~/']] as const) {
642 const base = root.replace(/\/+$/, '')
643 if (base !== '' && path.startsWith(`${base}/`)) return prefix + path.slice(base.length + 1)
644 }
645 return path
646}
647
648const compactPath = (path: string): string => {
649 const parts = path.split('/')
650 if (!path.startsWith('/') || parts.length <= 6) return path
651 return [...parts.slice(0, 3), '…', ...parts.slice(-2)].join('/')
652}
653
654export const shortTarget = (places: Places, path: string): string => (path === places.cwd ? '.' : path === places.home ? '~' : compactPath(shortPath(places, path)))
655
656
657const PATH_FIELDS = ['file_path', 'notebook_path', 'path']
658
659const targetOf = (style: Style, input: unknown, fields: string[]): { target?: string; isPathField: boolean } => {
660 const target = field(input, ...fields)
661 const isPathField = target !== undefined && PATH_FIELDS.some(k => field(input, k) === target)
662 return { target: isPathField ? shortPath(style, target!) : target, isPathField }
663}
664
665const RESULT_LINES = 3
666
667export const renderShellResult = (el: ElementTable, style: Style, output: unknown): RenderElement => {
668 const { Box, Text } = el
669 const out = output !== null && typeof output === 'object' ? (output as Record<string, unknown>) : {}
670 const shown = [...lines(out.stdout), ...lines(out.stderr)]
671 const head = shown.slice(0, RESULT_LINES).map(l => shortenPaths(l, style))
672 return (
673 <Box flexDirection="row">
674 <Text dimColor>{' ⎿ '}</Text>
675 <Box flexDirection="column">
676 {head.length === 0 ? <Text dimColor>(No output)</Text> : head.map((l, i) => <Text key={`l${i}`} wrap="truncate-end">{l === '' ? ' ' : l}</Text>)}
677 {shown.length > head.length ? <Text dimColor>{`… +${shown.length - head.length} lines`}</Text> : null}
678 </Box>
679 </Box>
680 )
681}
682
683const NOISE_LINES = /^((Error:\s*)?Exit code \d+|at\s+(\S+\s+\()?\S+:\d+(:\d+)?\)?|Node\.js v\d.*|exit status \d+|\.\.\. \d+ more)$/i
684
685const REFUSAL = /^(Error:\s*)?(The user doesn't want to proceed|Permission (for|to) .*\bdenied|The server-side auto mode classifier|\S+ hook error:)/i
686
687export const refusalReason = (output: unknown): string | undefined => {
688 if (typeof output !== 'string' || /^(Error:\s*)?Exit code \d+/m.test(output) || !REFUSAL.test(output)) return undefined
689 return output.replace(/\s+/g, ' ').trim()
690}
691
692export const CALLS_REMEMBERED = 2000
693
694export const rememberCall = (calls: Set<string>, id: string, limit = CALLS_REMEMBERED): void => {
695 calls.delete(id)
696 calls.add(id)
697 if (calls.size > limit) calls.delete(calls.values().next().value!)
698}
699
700export const errorReason = (output: unknown): string | undefined => {
701 const out = output !== null && typeof output === 'object' ? (output as Record<string, unknown>) : {}
702 const text = typeof output === 'string' ? output : typeof out.stderr === 'string' && out.stderr.trim() ? out.stderr : out.stdout
703 if (typeof text !== 'string') return undefined
704 return text.split('\n').map(l => l.trim()).filter(l => l !== '' && !NOISE_LINES.test(l)).at(-1)
705}
706
707export const renderFailure = (el: ElementTable, style: Style, output: unknown, key?: string): RenderElement | undefined => {
708 const refusal = refusalReason(output)
709 const reason = refusal ?? errorReason(output)
710 if (reason === undefined) return undefined
711 const chat = style.toolStyle === 'chat'
712 return (
713 <el.Box key={key} flexDirection="row" width="100%" justifyContent={chat ? 'flex-end' : 'flex-start'}>
714 <el.Text color={style.theme.codeFlag} wrap={refusal === undefined ? 'truncate-middle' : 'wrap'}>{`${chat ? '' : ' ⎿ '}${refusal ?? shortenPaths(reason, style)}`}</el.Text>
715 </el.Box>
716 )
717}
718
719const callLabel = (call: ToolRow, style: Style): string => {
720 const isShell = call.tool === 'Bash' || call.tool === 'PowerShell'
721 if (isShell) {
722 const command = field(call.input, 'command') ?? ''
723 const plain = call.tool === 'Bash' ? describeShell(command, style) : undefined
724 if (plain) return plain
725 const description = field(call.input, 'description')
726 if (description === undefined) return `Ran ${shortenPaths(command.split('\n')[0]!, style)}`
727 const programs = call.tool === 'Bash' ? programsOf(command) : []
728 return programs.length ? `${description} · ${programs.join(', ')}` : description
729 }
730 if (call.tool === 'Grep') {
731 const pattern = field(call.input, 'pattern')
732 const path = field(call.input, 'path')
733 if (pattern !== undefined) return `Searched ${path === undefined ? '.' : shortTarget(style, path)} for "${pattern}"`
734 }
735 const verb = call.tool === 'Skill' ? 'Loaded skill' : VERBS[call.tool] ?? call.tool.replace(/^mcp__([^_]+)__/, '$1 ')
736 const target = field(call.input, 'skill', ...TARGET_FIELDS)
737 const args = call.tool === 'Skill' ? field(call.input, 'args') : undefined
738 return target === undefined ? verb : `${verb} ${shortTarget(style, target)}${args ? ` ${args}` : ''}`
739}
740
741const quietToolRow = (el: ElementTable, style: Style, row: ToolRow, columns: number): RenderElement => {
742 const t = style.theme
743 const dot = statusColor(t, row)
744 const what = callLabel(row, style)
745 const label = `${what}${row.isInterrupted ? ' interrupted' : row.isErrored ? ' failed' : ''}`
746 return toolLayout(el, style, columns, label, dot, row.isRunning, (
747 <el.Text wrap="truncate-end" dimColor={toolDim(style)}>
748 {what}
749 {row.isInterrupted ? <el.Text dimColor> interrupted</el.Text> : row.isErrored ? <el.Text color={t.codeFlag}> failed</el.Text> : null}
750 </el.Text>
751 ))
752}
753
754export const renderToolRow = (el: ElementTable, style: Style, row: ToolRow, columns = 100): RenderElement => {
755 if (style.toolOutput === 'quiet') return quietToolRow(el, style, row, columns)
756 const { Text } = el
757 const t = style.theme
758 const isShell = row.tool === 'Bash' || row.tool === 'PowerShell'
759 const verb = VERBS[row.tool] ?? row.tool.replace(/^mcp__([^_]+)__/, '$1 ')
760 const found = isShell ? { target: field(row.input, 'command')?.split('\n')[0], isPathField: false } : targetOf(style, row.input, TARGET_FIELDS)
761 const target = found.target
762 const dot = statusColor(t, row)
763 const isPath = target !== undefined && (found.isPathField || /^(~|\.{0,2}\/|[A-Za-z]:\\)/.test(target))
764
765 const label = `${verb}${target === undefined ? "" : ` ${target}`}${row.isInterrupted ? " interrupted" : row.isErrored ? " failed" : ""}`
766 return toolLayout(el, style, columns, label, dot, row.isRunning, (
767 <Text wrap="truncate-end" dimColor={toolDim(style)}>
768 <Text bold={!toolDim(style)} dimColor={toolDim(style)}>{verb}</Text>
769 {target === undefined ? null : <Text> </Text>}
770 {target === undefined ? null : isShell ? codeLine(el, style, target, 'bash', 'cmd') : <Text color={isPath ? t.path : t.inlineCode} dimColor={toolDim(style)}>{target}</Text>}
771 {row.isInterrupted ? <Text dimColor> interrupted</Text> : row.isErrored ? <Text color={t.codeFlag}> failed</Text> : null}
772 </Text>
773 ))
774}
775
776const READ_TOOLS = new Set(['Read', 'Grep', 'Glob', 'LS', 'NotebookRead', 'WebFetch', 'WebSearch', 'Skill'])
777
778const READ_COMMANDS = new Set([
779 'awk', 'basename', 'cat', 'cd', 'column', 'cut', 'diff', 'dirname', 'du', 'echo', 'file', 'find', 'grep', 'head', 'jq', 'less',
780 'ls', 'nl', 'pdftotext', 'printf', 'pwd', 'readlink', 'realpath', 'rg', 'sed', 'sort', 'stat', 'tail', 'test', 'tr', 'tree',
781 'true', 'uniq', 'wc', 'which',
782])
783
784const READ_SUBCOMMANDS: Record<string, RegExp> = {
785 git: /^(log|show|diff|status|blame|grep|ls-files|rev-parse|branch --show-current)\b/,
786 gh: /^((pr|issue|run|release) (view|list|diff|checks)|search)\b/,
787}
788
789const flagValue = (args: string[], i: number, flag: string): string => {
790 const arg = args[i]!
791 return arg === flag ? (args[i + 1] ?? '') : arg.slice(flag.length).replace(/^=/, '')
792}
793
794const ghApiReadsOnly = (rest: string[]): boolean =>
795 !rest.some((a, i) => {
796 if (/^(-[fF]|--field|--raw-field|--input)/.test(a)) return true
797 if (!/^(-X|--method)/.test(a)) return false
798 return !/^GET$/i.test(flagValue(rest, i, a.startsWith('--') ? '--method' : '-X'))
799 })
800
801type ShellPart = { words: string[]; piped: boolean }
802
803const HEREDOC = /<<(?!<)-?\s*(['"]?)([A-Za-z_][\w-]*)\1/g
804
805const dropHeredocBodies = (command: string): string => {
806 const lines = command.split('\n')
807 const out: string[] = []
808 for (let i = 0; i < lines.length; i++) {
809 const line = lines[i]!
810 out.push(line)
811 for (const [, , end] of line.matchAll(HEREDOC)) {
812 while (i + 1 < lines.length && lines[i + 1]!.trim() !== end) i++
813 i++
814 }
815 }
816 return out.join('\n')
817}
818
819const parseShell = (source: string): { segments: ShellPart[]; redirects: boolean } => {
820 const command = dropHeredocBodies(source)
821 const segments: ShellPart[] = [{ words: [], piped: false }]
822 let word = ''
823 let quote = ''
824 let started = false
825 let redirects = false
826 const current = () => segments[segments.length - 1]!
827 const endWord = () => {
828 if (started) current().words.push(word)
829 word = ''
830 started = false
831 }
832 const endSegment = (piped: boolean) => {
833 endWord()
834 if (current().words.length) segments.push({ words: [], piped })
835 else current().piped = piped
836 }
837 for (let i = 0; i < command.length; i++) {
838 const ch = command[i]!
839 if (quote) {
840 if (ch === quote) quote = ''
841 else if (ch === '\\' && quote === '"' && /[$`"\\\n]/.test(command[i + 1] ?? '')) word += command[++i]
842 else word += ch
843 } else if (ch === '"' || ch === "'") {
844 quote = ch
845 started = true
846 } else if (ch === '\\' && command[i + 1] === '\n') {
847 i++
848 } else if (ch === '\\' && i + 1 < command.length) {
849 word += command[++i]
850 started = true
851 } else if (ch === '\n' || ch === ';') {
852 endSegment(false)
853 } else if (ch === '&' && command[i + 1] === '&') {
854 i++
855 endSegment(false)
856 } else if (ch === '&' && command[i + 1] !== '>' && command[i - 1] !== '|' && command[i - 1] !== '>') {
857 endSegment(false)
858 } else if (ch === '|') {
859 const or = command[i + 1] === '|'
860 if (or) i++
861 endSegment(!or)
862 } else if (ch === '>' || ch === '<') {
863 const harmless = ch === '>' && /^(&\d|\s*\/dev\/null)/.exec(command.slice(i + 1))
864 if (harmless) i += harmless[0].length
865 else redirects = true
866 if (/^(\d|&)$/.test(word)) {
867 word = ''
868 started = false
869 }
870 endWord()
871 } else if (/\s/.test(ch)) {
872 endWord()
873 } else {
874 word += ch
875 started = true
876 }
877 }
878 endWord()
879 return { segments: segments.filter(s => s.words.length), redirects }
880}
881
882const isAssignment = (word: string) => /^[A-Za-z_][A-Za-z0-9_]*=/.test(word)
883
884const LEADING_KEYWORDS = new Set(['do', 'then', 'else', 'elif', 'if', 'while', 'until', '!', '{', '(', 'time'])
885const HEADER_KEYWORDS = new Set(['for', 'select', 'done', 'fi', 'esac', '}', ')'])
886
887const commandWords = (words: string[]) => {
888 let i = 0
889 while (i < words.length && (isAssignment(words[i]!) || LEADING_KEYWORDS.has(words[i]!))) i++
890 return HEADER_KEYWORDS.has(words[i] ?? '') ? [] : words.slice(i)
891}
892
893const readsOnly = ({ words }: ShellPart): boolean => {
894 const [name, ...rest] = commandWords(words)
895 if (name === undefined) return true
896 const args = rest.join(' ')
897 if (name === 'gh' && rest[0] === 'api') return ghApiReadsOnly(rest.slice(1))
898 if (name in READ_SUBCOMMANDS) return READ_SUBCOMMANDS[name]!.test(args) && !(name === 'git' && rest.some(a => /^--output\b/.test(a)))
899 if (!READ_COMMANDS.has(name)) return false
900 if (name === 'sed') {
901 const [script, ...files] = rest.filter(a => a !== '-n')
902 return script !== undefined && /^\d+(,\d+)?p$/.test(script) && files.every(f => !f.startsWith('-'))
903 }
904 if (name === 'find') return !rest.some(a => /^-(delete|exec|execdir|ok|okdir|fprint|fprint0|fprintf|fls)$/.test(a))
905 if (name === 'awk') return !rest.some(a => /^(-f|--file)/.test(a)) && !/system\s*\(|getline|[|>]/.test(args)
906 if (name === 'sort') return !rest.some(a => /^(-[A-Za-z]*o|--output)/.test(a))
907 if (name === 'uniq') return operandsOf(name, rest).length < 2
908 if (name === 'tree') return !rest.some(a => /^(-o|--output)/.test(a))
909 if (name === 'rg') return !rest.some(a => /^--pre/.test(a))
910 if (name === 'pdftotext') return rest.at(-1) === '-'
911 return true
912}
913
914export const isReadOnlyCall = (tool: string, input: unknown): boolean => {
915 if (READ_TOOLS.has(tool)) return true
916 if (tool !== 'Bash' && tool !== 'PowerShell') return false
917 const command = field(input, 'command')
918 if (command === undefined) return false
919 if (/\$\(|`|<<|\btee\b/.test(command)) return false
920 const shell = parseShell(command)
921 return !shell.redirects && shell.segments.every(readsOnly)
922}
923
924const TRIVIAL_PROGRAMS = new Set(['cd', 'echo', 'export', 'printf', 'pwd', 'set', 'test', 'true'])
925
926export const programsOf = (command: string, limit = 3): string[] => {
927 const names: string[] = []
928 for (const part of parseShell(command).segments) {
929 const name = commandWords(part.words)[0]?.split('/').pop()
930 if (name && !TRIVIAL_PROGRAMS.has(name) && !names.includes(name)) names.push(name)
931 }
932 return names.length > limit ? [...names.slice(0, limit), '…'] : names
933}
934
935export const shortenPaths = (text: string, places: Places): string => {
936 const prefix = (path: string) => new RegExp(`(?<![\\w.~:/-])${path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/`, 'g')
937 let out = text
938 if (places.cwd) out = out.replace(prefix(places.cwd), '')
939 if (places.home) out = out.replace(prefix(places.home), '~/')
940 return out.replace(/(?<![\w.~:/-])\/[^\s'"`;|&<>()]+/g, compactPath)
941}
942
943const VALUE_FLAGS: Record<string, Set<string>> = {
944 grep: new Set(['-A', '-B', '-C', '-m', '-e', '-f', '--max-count', '--include', '--exclude', '--exclude-dir']),
945 rg: new Set(['-A', '-B', '-C', '-m', '-e', '-f', '-g', '-t', '--type', '--glob', '--max-count', '--max-depth']),
946 tree: new Set(['-L', '-P', '-I']),
947 uniq: new Set(['-f', '-s', '-w']),
948}
949
950const operandsOf = (name: string, args: string[]): string[] => {
951 const valued = VALUE_FLAGS[name]
952 const out: string[] = []
953 for (let i = 0; i < args.length; i++) {
954 const a = args[i]!
955 if (valued?.has(a)) i++
956 else if (!a.startsWith('-')) out.push(a)
957 }
958 return out
959}
960
961const describeCommand = (name: string, args: string[], places: Places): string | undefined => {
962 const files = (list: string[]) => list.map(f => shortTarget(places, f)).join(', ')
963 const ops = operandsOf(name, args)
964 if (TRIVIAL_PROGRAMS.has(name)) return ''
965 if (name === 'sed') {
966 const range = args.find(a => /^\d+(,\d+)?p$/.test(a))
967 const targets = ops.filter(a => a !== range)
968 if (!range || !targets.length) return undefined
969 const [from, to] = range.slice(0, -1).split(',')
970 return `Read ${files(targets)} lines ${from}${to ? `–${to}` : ''}`
971 }
972 if (name === 'cat' || name === 'less' || name === 'nl') return ops.length ? `Read ${files(ops)}` : undefined
973 if (name === 'pdftotext') return ops.length ? `Read ${files(ops.slice(0, 1))}` : undefined
974 if (name === 'head' || name === 'tail') {
975 const targets = ops.filter(a => !/^\d+$/.test(a))
976 return targets.length ? `Read ${name === 'head' ? 'start' : 'end'} of ${files(targets)}` : undefined
977 }
978 if (name === 'grep' || name === 'rg') {
979 const e = args.indexOf('-e')
980 const pattern = e >= 0 ? args[e + 1] : ops[0]
981 const paths = e >= 0 ? ops : ops.slice(1)
982 return pattern === undefined ? undefined : `Searched ${paths.length ? files(paths) : '.'} for "${pattern}"`
983 }
984 if (name === 'ls' || name === 'tree') return `Listed ${ops.length ? files(ops) : '.'}`
985 if (name === 'find') return `Listed ${args[0] && !args[0].startsWith('-') ? files([args[0]]) : '.'}`
986 if (name === 'wc') return ops.length ? `Counted ${files(ops)}` : undefined
987 return undefined
988}
989
990export const describeShell = (command: string, places: Places = { cwd: '', home: '' }): string | undefined => {
991 if (!isReadOnlyCall('Bash', { command })) return undefined
992 const vars = new Map<string, string>()
993 const expand = (w: string) => w.replace(/\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g, (m, v: string) => vars.get(v) ?? m)
994 const parts: string[] = []
995 for (const segment of parseShell(command).segments) {
996 const words = commandWords(segment.words)
997 if (!words.length) {
998 for (const w of segment.words.filter(isAssignment)) vars.set(w.slice(0, w.indexOf('=')), expand(w.slice(w.indexOf('=') + 1)))
999 continue
1000 }
1001 if (segment.piped) continue
1002 const [name, ...args] = words.map(expand)
1003 if (args.some(a => /\$\{?[A-Za-z_]/.test(a))) return undefined
1004 const text = describeCommand(name!, args, places)
1005 if (text === undefined) return undefined
1006 if (text) parts.push(text)
1007 }
1008 return parts.length ? parts.join(' · ') : undefined
1009}
1010
1011const OUTPUT_LINES = 120
1012
1013const lines = (value: unknown): string[] => (typeof value === 'string' && value !== '' ? value.replace(/\n$/, '').split('\n') : [])
1014
1015export const renderExpandedShell = (el: ElementTable, style: Style, row: ToolRow & { output?: unknown }): RenderElement => {
1016 const { Box, Text } = el
1017 const t = style.theme
1018 const command = (field(row.input, 'command') ?? '').split('\n')
1019 const out = row.output !== null && typeof row.output === 'object' ? (row.output as Record<string, unknown>) : {}
1020 const stdout = lines(out.stdout)
1021 const stderr = lines(out.stderr)
1022 const shown = [...stdout.map(text => ({ text, color: undefined as string | undefined })), ...stderr.map(text => ({ text, color: t.codeFlag as string | undefined }))]
1023 const visible = shown.slice(0, OUTPUT_LINES)
1024 const dot = statusColor(t, row)
1025 return (
1026 <Box flexDirection="column">
1027 <Box flexDirection="row">
1028 <Box width={2} flexShrink={0}>
1029 <Text color={dot}>{row.isRunning ? '◌' : '●'}</Text>
1030 </Box>
1031 <Box flexDirection="column">
1032 {command.map((line, i) => (
1033 <Text key={`c${i}`}>
1034 {i === 0 ? <Text bold>{`${row.tool}(`}</Text> : null}
1035 {codeLine(el, style, line, 'bash', `cmd${i}`)}
1036 {i === command.length - 1 ? <Text bold>)</Text> : null}
1037 </Text>
1038 ))}
1039 </Box>
1040 </Box>
1041 {row.isRunning ? null : (
1042 <Box paddingLeft={2}>
1043 <Box flexDirection="column" alignSelf="flex-start" borderStyle="round" borderColor={t.codeComment} paddingX={1}>
1044 {visible.length === 0 ? <Text dimColor>(No output)</Text> : visible.map((l, i) => <Text key={`o${i}`} color={l.color}>{l.text === '' ? ' ' : l.text}</Text>)}
1045 {shown.length > visible.length ? <Text dimColor>{`\u2026 +${shown.length - visible.length} lines`}</Text> : null}
1046 </Box>
1047 </Box>
1048 )}
1049 </Box>
1050 )
1051}
1052
1053const GROUPS: [RegExp, string, string][] = [
1054 [/^(Bash|PowerShell)$/, 'ran', 'command'],
1055 [/^Read$/, 'read', 'file'],
1056 [/^(Write|Edit|MultiEdit|NotebookEdit)$/, 'edited', 'file'],
1057 [/^(Grep|Glob)$/, 'searched', 'pattern'],
1058 [/^(WebFetch|WebSearch)$/, 'fetched', 'page'],
1059 [/^(Agent|Task)$/, 'delegated', 'task'],
1060]
1061
1062export const groupSummary = (calls: readonly { tool: string }[]): string => {
1063 const counts = new Map<string, number>()
1064 for (const call of calls) {
1065 const [, verb, noun] = GROUPS.find(([re]) => re.test(call.tool)) ?? [, 'used', call.tool.replace(/^mcp__([^_]+)__/, '$1 ')]
1066 const label = `${verb} ${noun}`
1067 counts.set(label, (counts.get(label) ?? 0) + 1)
1068 }
1069 const parts = [...counts].map(([label, n]) => {
1070 const [verb, ...noun] = label.split(' ')
1071 const name = noun.join(' ')
1072 return `${verb} ${n} ${n === 1 ? name : name.endsWith('h') ? `${name}es` : `${name}s`}`
1073 })
1074 const text = parts.join(', ')
1075 return text.charAt(0).toUpperCase() + text.slice(1)
1076}
1077
1078const quietToolGroup = (el: ElementTable, style: Style, calls: readonly (ToolRow & { output?: unknown })[], isActive: boolean, columns: number): RenderElement => {
1079 const t = style.theme
1080 const failed = calls.filter(c => c.isErrored)
1081 const running = isActive && calls.some(c => c.isRunning)
1082 const dot = failed.length ? t.codeFlag : running ? t.accent : t.number
1083 const labels = calls.map(c => callLabel(c, style)).filter((l, i, all) => l !== all[i - 1])
1084 const label = labels.join(' · ')
1085 const reasons = failed.map((c, i) => renderFailure(el, style, c.output, `r${i}`)).filter((r): r is RenderElement => r !== undefined)
1086 const isShell = (c: ToolRow) => c.tool === 'Bash' || c.tool === 'PowerShell'
1087 const results = calls.flatMap((c, i) => (c.isErrored || c.output === undefined || !isShell(c) || isReadOnlyCall(c.tool, c.input) ? [] : [<el.Box key={`o${i}`}>{renderShellResult(el, style, c.output)}</el.Box>]))
1088 const row = toolLayout(el, style, columns, label, dot, running, (
1089 <el.Text wrap="truncate-end" dimColor={toolDim(style)}>{label}</el.Text>
1090 ))
1091 if (!reasons.length && !results.length) return row
1092 return (
1093 <el.Box flexDirection="column">
1094 {row}
1095 {reasons}
1096 {results}
1097 </el.Box>
1098 )
1099}
1100
1101export const renderToolGroup = (el: ElementTable, style: Style, calls: readonly (ToolRow & { output?: unknown })[], isActive: boolean, columns = 100): RenderElement => {
1102 if (style.toolOutput === 'quiet') return quietToolGroup(el, style, calls, isActive, columns)
1103 const { Text } = el
1104 const t = style.theme
1105 const failed = calls.filter(c => c.isErrored).length
1106 const running = isActive && calls.some(c => c.isRunning)
1107 const dot = failed ? t.codeFlag : running ? t.accent : t.number
1108 const last = calls[calls.length - 1]
1109 const lastTarget = last ? targetOf(style, last.input, ['command', ...TARGET_FIELDS]).target?.split('\n')[0] : undefined
1110 const summary = groupSummary(calls)
1111 const label = `${summary}${failed ? ` · ${failed} failed` : ""}${lastTarget ? ` · last: ${lastTarget}` : ""}`
1112 return toolLayout(el, style, columns, label, dot, running, (
1113 <Text wrap="truncate-end" dimColor={toolDim(style)}>
1114 <Text bold={!toolDim(style)} dimColor={toolDim(style)}>{summary}</Text>
1115 {failed ? <Text color={t.codeFlag}>{` · ${failed} failed`}</Text> : null}
1116 {lastTarget ? <Text dimColor>{` · last: ${lastTarget}`}</Text> : null}
1117 </Text>
1118 ))
1119}
1120
1121export const formatDuration = (ms: number): string => {
1122 const s = Math.round(ms / 1000)
1123 if (s < 60) return `${Math.max(s, 0)}s`
1124 if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`
1125 return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`
1126}
1127
1128export const renderTurnDuration = ({ Text }: ElementTable, style: Style, word: string, durationMs: number): RenderElement => (
1129 <Text color={style.theme.codeComment}>
1130 {`✻ ${word} for `}
1131 <Text color={style.theme.number}>{formatDuration(durationMs)}</Text>
1132 </Text>
1133)
1134
1135export const renderUserPrompt = (el: ElementTable, style: Style, text: string, columns: number): RenderElement => {
1136 const { Box, Text } = el
1137 const t = style.theme
1138 const color = style.promptStyle === 'chevron' ? t.accent : t.heading
1139 const lines = text.split('\n').map(line => flowOf(style, [{ kind: 'text', text: line }], columns - 4))
1140 const rtl = lines.some(l => l?.base === 'R')
1141 const body = (
1142 <Box flexDirection="column" {...(rtl ? { alignItems: 'flex-end' as const } : {})}>
1143 {text.split('\n').map((line, i) => {
1144 const flow = lines[i]
1145 return flow ? renderFlow(el, style, flow.lines, `p${i}`, { color, bold: style.promptStyle === 'chevron' }) : <Text key={`p${i}`} color={color} bold={style.promptStyle === 'chevron'}>{line}</Text>
1146 })}
1147 </Box>
1148 )
1149 if (style.promptStyle === 'bubble') {
1150 return <Box borderStyle="round" borderColor={t.accent} paddingX={1} alignSelf={rtl ? 'flex-end' : 'flex-start'}>{body}</Box>
1151 }
1152 const mark = <Text color={t.accent} bold>{style.promptStyle === 'bar' ? (rtl ? ' ▐' : '▌ ') : rtl ? ' ‹' : '› '}</Text>
1153 return <Box flexDirection="row" {...(rtl ? { justifyContent: 'flex-end' as const } : {})}>{rtl ? body : mark}{rtl ? mark : body}</Box>
1154}
1155hooks/help.ts 209 lines1export const showcaseText = (themes: readonly string[]): string => `
2# cellsmith
3
4Colored markdown for Claude Code replies: **bold**, *italic*, ~~struck~~, \`inline code\`, a [link](https://github.com/4our4ace/cellsmith) and a bare URL https://github.com/4our4ace/cellsmith/issues, both clickable, numbers like 99.9% and 250ms, paths like ~/src/app.ts.
5
6## Commands
7
8| Command | Does |
9|---------|------|
10| \`/cellsmith\` | This screen |
11| \`/cellsmith theme <name>\` | Switch theme on the spot |
12| \`/cellsmith copy\` | Copy the last reply, or \`copy code\` for its last code block |
13| \`/config\` | Edit any option |
14
15> [!NOTE]
16> ${themes.length} themes ship with it. \`mono\` uses no color, only bold and dim.
17
18### Pick a theme
19
20\`\`\`bash
21/cellsmith theme nord
22/cellsmith theme github-light
23\`\`\`
24
251. Dark: ${themes.filter(t => !/latte|light|dawn/.test(t) && t !== 'mono').join(', ')}
262. Light: ${themes.filter(t => /latte|light|dawn/.test(t)).join(', ')}
273. Plain
28 - mono
29
30> [!TIP]
31> Any color slot beats the theme. Set \`headingColor\` or \`numberColor\` to a hex value in \`/config\`.
32
33## Everything it draws
34
35### Copy tables
36
37Use \`⧉ md\` for Markdown, \`⧉ art\` for chat, or \`⧉ html\` for a formatted table. \`⧉ html\` shows in a local macOS or Linux terminal and writes HTML and tab-separated plain text together; Linux needs CopyQ running. If that fails, it copies the plain text alone.
38
39| Item | Quantity | Status |
40|:-----|---------:|:------:|
41| **Apples** | 3 | *Ready* |
42| Oranges | 5 | Pending |
43
44### Alerts
45
46> [!IMPORTANT]
47> After updating the plugin, open sessions need \`/reload\`.
48
49> [!WARNING]
50> Terminals that copy on select (Warp) can turn a click on a copy button into a selection. Use the keyboard shortcut.
51> Selecting a typeset formula copies blank cells. Its copy button copies the LaTeX.
52
53> [!CAUTION]
54> Claude Code refuses trees over 20000 nodes. A code block past about 500 highlighted lines falls back to plain text.
55
56### Task lists
57
58- [x] Parse the reply
59- [x] Draw it
60 - [x] Tables and code
61 - [ ] Diagrams on the desktop app
62- [ ] Ship the next release
63
64### Your prompts
65
66Scroll up: what you typed draws in a bubble. \`promptStyle\` switches to \`bar\`, \`chevron\` or \`off\` in \`/config\`.
67
68### Tool rows
69
70Tool calls draw as one line, dimmed on the right by default. Set \`toolStyle\` in \`/config\` to \`chat\`, \`tree-dim\`, \`tree-bold\` or \`classic\`. \`toolOutput: quiet\` in \`/config\` hides what Claude only read and says in plain words what each call did: \`Read src/app.ts lines 1–40\`, \`Searched src/ for "TODO"\`.
71
72### Quotes and rules
73
74> A quote keeps its text when you copy it, without the \`> \` markers.
75
76---
77
78### Code
79
80\`\`\`json
81{ "theme": "dracula", "headingStyle": "banner", "mermaid": true }
82\`\`\`
83
84#### Math
85
86$$
87\\int_0^\\infty e^{-x^2}\\,dx = \\frac{\\sqrt{\\pi}}{2}
88$$
89
90#### Diagrams
91
92\`\`\`mermaid
93flowchart LR
94 R[Reply] --> P[Parse]
95 P --> D[Draw]
96 D --> S[Screen]
97\`\`\`
98
99\`\`\`mermaid
100sequenceDiagram
101 participant U as You
102 participant C as Claude
103 participant P as cellsmith
104 U->>C: prompt
105 C->>P: markdown
106 P-->>U: colored reply
107\`\`\`
108
109\`\`\`mermaid
110xychart-beta
111 title "Color options per group"
112 x-axis [text, head, num, code, diag]
113 y-axis "options" 0 --> 8
114 bar [7, 3, 2, 6, 2]
115\`\`\`
116
117\`\`\`mermaid
118pie title Where a reply's time goes
119 "Parse" : 15
120 "Layout" : 45
121 "Draw" : 40
122\`\`\`
123
124\`\`\`mermaid
125gantt
126 title Release
127 dateFormat YYYY-MM-DD
128 section Build
129 Engine :a1, 2026-10-18, 3d
130 Tests :after a1, 2d
131 section Ship
132 Install :2026-10-23, 1d
133\`\`\`
134`
135
136export const helpText = (themes: readonly string[]): string => `
137## Commands
138
139| Command | Does |
140|---------|------|
141| \`/cellsmith theme <name>\` | Switch theme on the spot |
142| \`/cellsmith copy\` | Copy the last reply, or \`copy code\` for its last code block |
143| \`/cellsmith demo\` | Full showcase, every element and diagram |
144| \`/cellsmith demo-rtl\` | Hebrew right-to-left showcase |
145
146### ${themes.length} themes
147
148- Dark: ${themes.filter(t => !/latte|light|dawn/.test(t) && t !== 'mono').join(', ')}
149- Light: ${themes.filter(t => /latte|light|dawn/.test(t)).join(', ')}
150- Plain: mono, no color, only bold and dim
151
152Forked from [prismantis](https://github.com/NahumLitvin/prismantis), diagrams laid out by [Pele](https://pele.run)
153
154> [!TIP]
155> Any color slot beats the theme. Set \`headingColor\` or \`numberColor\` to a hex value in \`/config\`.
156
157### Task lists
158
159- [x] Tables, diagrams and charts drawn in the terminal
160- [x] Copy tables as Markdown, art or HTML (macOS/Linux)
161- [ ] Pick a \`taskStyle\` in \`/config\`: checks, ticks, box or progress
162
163\`\`\`mermaid
164flowchart LR
165 R[Reply] --> P[Parse]
166 P --> D[Draw]
167 D --> S[Screen]
168\`\`\`
169
170\`\`\`mermaid
171xychart-beta
172 title "Color options per group"
173 x-axis [text, head, num, code, diag]
174 y-axis "options" 0 --> 8
175 bar [7, 3, 2, 6, 2]
176\`\`\`
177
178> [!CAUTION]
179> Claude Code refuses trees over 20000 nodes. A code block past about 500 highlighted lines falls back to plain text.
180`
181
182export const rtlShowcaseText = (): string => `
183# עברית מימין לשמאל
184
185**שלום חברים**, זו הדגמה של עברית עם מונחים באנגלית כמו \`kubectl\`, מספרים כמו 99.9% ו-250ms, נתיב כמו ~/src/app.ts וגם [קישור](https://github.com/4our4ace/cellsmith).
186
187## רשימות
188
189- פרוסים בשני אזורים (us-east ו-eu-west)
190- מחליפים ערכת נושא עם \`/cellsmith theme nord\`
191
1921. מתקינים את התוסף
1932. שואלים שאלה בעברית
194
195> עברית נקראת מימין לשמאל, גם בטרמינל בלי תמיכה בכיווניות
196
197> [!TIP]
198> כל ערכת נושא עובדת גם בעברית
199
200| שירות | אזור | גרסה |
201| :--- | :--- | ---: |
202| שער | us-east | 2.14.0 |
203| חיוב | eu-west | 1.8.3 |
204
205\`\`\`bash
206ls -la # רשימת הקבצים בתיקייה
207\`\`\`
208`
209hooks/presets.ts 118 lines1import type { Theme } from './theme'
2
3export const PRESETS = {
4 'catppuccin-mocha': {
5 accent: '#cba6f7', heading: '#f9e2af', tableHeader: '#f9e2af', strong: '#ffffff', emphasis: '#f5c2e7',
6 inlineCode: '#89dceb', codeText: '#cdd6f4', codeCommand: '#89b4fa', codeFlag: '#f38ba8', codeString: '#a6e3a1',
7 codeComment: '#6c7086', link: '#89b4fa', path: '#89dceb', number: '#a6e3a1', quote: '#9399b2',
8 rule: '#45475a', tableRule: '#585b70', bullet: '#cba6f7', diagram: '#89b4fa', diagramText: '#cdd6f4',
9 },
10 'catppuccin-latte': {
11 accent: '#8839ef', heading: '#df8e1d', tableHeader: '#df8e1d', strong: '#11111b', emphasis: '#ea76cb',
12 inlineCode: '#04a5e5', codeText: '#4c4f69', codeCommand: '#1e66f5', codeFlag: '#d20f39', codeString: '#40a02b',
13 codeComment: '#9ca0b0', link: '#1e66f5', path: '#209fb5', number: '#40a02b', quote: '#6c6f85',
14 rule: '#bcc0cc', tableRule: '#acb0be', bullet: '#8839ef', diagram: '#1e66f5', diagramText: '#4c4f69',
15 },
16 dracula: {
17 accent: '#bd93f9', heading: '#bd93f9', tableHeader: '#f1fa8c', strong: '#f8f8f2', emphasis: '#ff79c6',
18 inlineCode: '#8be9fd', codeText: '#f8f8f2', codeCommand: '#50fa7b', codeFlag: '#ff79c6', codeString: '#f1fa8c',
19 codeComment: '#6272a4', link: '#8be9fd', path: '#ffb86c', number: '#bd93f9', quote: '#6272a4',
20 rule: '#44475a', tableRule: '#6272a4', bullet: '#ff79c6', diagram: '#bd93f9', diagramText: '#f8f8f2',
21 },
22 nord: {
23 accent: '#88c0d0', heading: '#88c0d0', tableHeader: '#ebcb8b', strong: '#eceff4', emphasis: '#b48ead',
24 inlineCode: '#8fbcbb', codeText: '#d8dee9', codeCommand: '#88c0d0', codeFlag: '#81a1c1', codeString: '#a3be8c',
25 codeComment: '#4c566a', link: '#88c0d0', path: '#8fbcbb', number: '#b48ead', quote: '#81a1c1',
26 rule: '#3b4252', tableRule: '#4c566a', bullet: '#88c0d0', diagram: '#81a1c1', diagramText: '#d8dee9',
27 },
28 'tokyo-night': {
29 accent: '#bb9af7', heading: '#7dcfff', tableHeader: '#e0af68', strong: '#c0caf5', emphasis: '#f7768e',
30 inlineCode: '#7dcfff', codeText: '#a9b1d6', codeCommand: '#7aa2f7', codeFlag: '#bb9af7', codeString: '#9ece6a',
31 codeComment: '#565f89', link: '#73daca', path: '#2ac3de', number: '#ff9e64', quote: '#9aa5ce',
32 rule: '#414868', tableRule: '#565f89', bullet: '#bb9af7', diagram: '#7aa2f7', diagramText: '#c0caf5',
33 },
34 'gruvbox-dark': {
35 accent: '#d3869b', heading: '#fabd2f', tableHeader: '#fabd2f', strong: '#fbf1c7', emphasis: '#d3869b',
36 inlineCode: '#8ec07c', codeText: '#ebdbb2', codeCommand: '#83a598', codeFlag: '#fe8019', codeString: '#b8bb26',
37 codeComment: '#928374', link: '#83a598', path: '#8ec07c', number: '#d3869b', quote: '#a89984',
38 rule: '#3c3836', tableRule: '#504945', bullet: '#fe8019', diagram: '#83a598', diagramText: '#ebdbb2',
39 },
40 'gruvbox-light': {
41 accent: '#8f3f71', heading: '#b57614', tableHeader: '#b57614', strong: '#282828', emphasis: '#8f3f71',
42 inlineCode: '#427b58', codeText: '#3c3836', codeCommand: '#076678', codeFlag: '#af3a03', codeString: '#79740e',
43 codeComment: '#928374', link: '#076678', path: '#427b58', number: '#8f3f71', quote: '#7c6f64',
44 rule: '#ebdbb2', tableRule: '#a89984', bullet: '#af3a03', diagram: '#076678', diagramText: '#3c3836',
45 },
46 'rose-pine': {
47 accent: '#c4a7e7', heading: '#c4a7e7', tableHeader: '#f6c177', strong: '#e0def4', emphasis: '#ebbcba',
48 inlineCode: '#9ccfd8', codeText: '#e0def4', codeCommand: '#9ccfd8', codeFlag: '#eb6f92', codeString: '#f6c177',
49 codeComment: '#6e6a86', link: '#c4a7e7', path: '#9ccfd8', number: '#ebbcba', quote: '#908caa',
50 rule: '#26233a', tableRule: '#6e6a86', bullet: '#eb6f92', diagram: '#c4a7e7', diagramText: '#e0def4',
51 },
52 'rose-pine-dawn': {
53 accent: '#907aa9', heading: '#907aa9', tableHeader: '#ea9d34', strong: '#464261', emphasis: '#d7827e',
54 inlineCode: '#56949f', codeText: '#464261', codeCommand: '#56949f', codeFlag: '#b4637a', codeString: '#ea9d34',
55 codeComment: '#9893a5', link: '#907aa9', path: '#286983', number: '#d7827e', quote: '#797593',
56 rule: '#f2e9e1', tableRule: '#9893a5', bullet: '#b4637a', diagram: '#907aa9', diagramText: '#464261',
57 },
58 everforest: {
59 accent: '#a7c080', heading: '#e69875', tableHeader: '#dbbc7f', strong: '#d3c6aa', emphasis: '#d699b6',
60 inlineCode: '#83c092', codeText: '#d3c6aa', codeCommand: '#7fbbb3', codeFlag: '#e67e80', codeString: '#a7c080',
61 codeComment: '#859289', link: '#7fbbb3', path: '#83c092', number: '#d699b6', quote: '#9da9a0',
62 rule: '#475258', tableRule: '#7a8478', bullet: '#e69875', diagram: '#7fbbb3', diagramText: '#d3c6aa',
63 },
64 'github-dark': {
65 accent: '#d2a8ff', heading: '#79c0ff', tableHeader: '#ffa657', strong: '#e6edf3', emphasis: '#d2a8ff',
66 inlineCode: '#79c0ff', codeText: '#e6edf3', codeCommand: '#d2a8ff', codeFlag: '#ff7b72', codeString: '#a5d6ff',
67 codeComment: '#7d8590', link: '#58a6ff', path: '#7ee787', number: '#79c0ff', quote: '#7d8590',
68 rule: '#30363d', tableRule: '#8b949e', bullet: '#ff7b72', diagram: '#58a6ff', diagramText: '#e6edf3',
69 },
70 'github-light': {
71 accent: '#8250df', heading: '#0550ae', tableHeader: '#953800', strong: '#1f2328', emphasis: '#8250df',
72 inlineCode: '#0550ae', codeText: '#1f2328', codeCommand: '#8250df', codeFlag: '#cf222e', codeString: '#0a3069',
73 codeComment: '#6e7781', link: '#0969da', path: '#116329', number: '#0550ae', quote: '#656d76',
74 rule: '#d0d7de', tableRule: '#6e7781', bullet: '#cf222e', diagram: '#0969da', diagramText: '#1f2328',
75 },
76 'one-dark': {
77 accent: '#c678dd', heading: '#e06c75', tableHeader: '#e5c07b', strong: '#d19a66', emphasis: '#c678dd',
78 inlineCode: '#56b6c2', codeText: '#abb2bf', codeCommand: '#61afef', codeFlag: '#e06c75', codeString: '#98c379',
79 codeComment: '#5c6370', link: '#61afef', path: '#56b6c2', number: '#d19a66', quote: '#828997',
80 rule: '#3a3f4b', tableRule: '#5c6370', bullet: '#c678dd', diagram: '#61afef', diagramText: '#abb2bf',
81 },
82 'solarized-dark': {
83 accent: '#6c71c4', heading: '#b58900', tableHeader: '#b58900', strong: '#eee8d5', emphasis: '#d33682',
84 inlineCode: '#2aa198', codeText: '#93a1a1', codeCommand: '#268bd2', codeFlag: '#cb4b16', codeString: '#859900',
85 codeComment: '#586e75', link: '#268bd2', path: '#2aa198', number: '#859900', quote: '#657b83',
86 rule: '#073642', tableRule: '#586e75', bullet: '#6c71c4', diagram: '#268bd2', diagramText: '#93a1a1',
87 },
88 'solarized-light': {
89 accent: '#6c71c4', heading: '#b58900', tableHeader: '#b58900', strong: '#073642', emphasis: '#d33682',
90 inlineCode: '#2aa198', codeText: '#586e75', codeCommand: '#268bd2', codeFlag: '#cb4b16', codeString: '#859900',
91 codeComment: '#93a1a1', link: '#268bd2', path: '#2aa198', number: '#859900', quote: '#839496',
92 rule: '#eee8d5', tableRule: '#93a1a1', bullet: '#6c71c4', diagram: '#268bd2', diagramText: '#586e75',
93 },
94 mono: {} as Theme,
95} satisfies Record<string, Theme>
96
97export type PresetName = keyof typeof PRESETS
98export const PRESET_NAMES = Object.keys(PRESETS) as PresetName[]
99
100export const CANVAS: Record<PresetName, string> = {
101 'catppuccin-mocha': '#1e1e2e',
102 'catppuccin-latte': '#eff1f5',
103 dracula: '#282a36',
104 nord: '#2e3440',
105 'tokyo-night': '#1a1b26',
106 'gruvbox-dark': '#282828',
107 'gruvbox-light': '#fbf1c7',
108 'rose-pine': '#191724',
109 'rose-pine-dawn': '#faf4ed',
110 everforest: '#2d353b',
111 'github-dark': '#0d1117',
112 'github-light': '#ffffff',
113 'one-dark': '#282c34',
114 'solarized-dark': '#002b36',
115 'solarized-light': '#fdf6e3',
116 mono: '#000000',
117}
118hooks/theme.ts 79 lines1import type { PluginOptions } from 'claude-code'
2
3import type { ClipboardBackend } from './clipboard'
4import { CANVAS, PRESETS } from './presets'
5import type { Shape, Terminal } from './rtl'
6import { TERMINALS } from './rtl'
7
8export const TOKENS = [
9 'accent', 'heading', 'strong', 'emphasis', 'inlineCode', 'codeText', 'codeCommand', 'codeFlag', 'codeString', 'codeComment',
10 'link', 'path', 'number', 'quote', 'rule', 'tableHeader', 'tableRule', 'bullet', 'diagram', 'diagramText',
11] as const
12
13export type Theme = Partial<Record<(typeof TOKENS)[number], string>>
14
15export type Style = {
16 theme: Theme
17 canvas?: string
18 headingStyle: 'bold' | 'underline' | 'uppercase' | 'banner'
19 tableStyle: 'box' | 'rules' | 'grid' | 'minimal'
20 taskStyle: 'checks' | 'ticks' | 'box' | 'progress'
21 promptStyle: 'bubble' | 'bar' | 'chevron' | 'off'
22 toolStyle: 'chat' | 'tree-dim' | 'tree-bold' | 'classic'
23 toolOutput: 'full' | 'quiet'
24 narration?: boolean
25 highlightNumbers: boolean
26 highlightPaths: boolean
27 mermaid: boolean
28 mermaidAscii: boolean
29 copyButtons: boolean
30 htmlCopy: ClipboardBackend | null
31 diagramHints: boolean
32 rtl: 'auto' | Terminal | 'off'
33 reorder: boolean
34 shape: Shape
35 latex: boolean
36 cwd: string
37 home: string
38}
39
40const COLOR = /^(#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)|ansi256\(\d{1,3}\)|(black|red|green|yellow|blue|magenta|cyan|white|gray|grey)(Bright)?)$/i
41
42export const isColor = (value: unknown): value is string => typeof value === 'string' && COLOR.test(value.trim())
43
44const pick = <T extends string>(value: unknown, allowed: readonly T[], fallback: T): T =>
45 allowed.includes(value as T) ? (value as T) : fallback
46
47export const resolveStyle = (options: PluginOptions): Style => {
48 const base: Theme = (PRESETS as Record<string, Theme>)[String(options.theme)] ?? PRESETS['catppuccin-mocha']
49 const fromFields = Object.fromEntries(
50 TOKENS.filter(k => isColor(options[`${k}Color`])).map(k => [k, String(options[`${k}Color`]).trim()]),
51 )
52
53 const rtl = pick(options.rtl, ['auto', 'off', ...(Object.keys(TERMINALS) as Terminal[])], 'auto')
54
55 return {
56 theme: { ...base, ...fromFields },
57 canvas: (CANVAS as Record<string, string>)[String(options.theme)] ?? CANVAS['catppuccin-mocha'],
58 headingStyle: pick(options.headingStyle, ['bold', 'underline', 'uppercase', 'banner'] as const, 'banner'),
59 tableStyle: pick(options.tableStyle, ['box', 'rules', 'grid', 'minimal'] as const, 'box'),
60 taskStyle: pick(options.taskStyle, ['checks', 'ticks', 'box', 'progress'] as const, 'checks'),
61 promptStyle: pick(options.promptStyle, ['bubble', 'bar', 'chevron', 'off'] as const, 'bubble'),
62 toolStyle: pick(options.toolStyle, ['chat', 'tree-dim', 'tree-bold', 'classic'] as const, 'chat'),
63 toolOutput: pick(options.toolOutput, ['full', 'quiet'] as const, 'full'),
64 highlightNumbers: options.highlightNumbers !== false,
65 highlightPaths: options.highlightPaths !== false,
66 mermaid: options.mermaid !== false,
67 mermaidAscii: options.mermaidAscii === true,
68 copyButtons: options.copyButtons !== false,
69 htmlCopy: null,
70 diagramHints: options.diagramHints !== false && options.mermaid !== false,
71 rtl,
72 reorder: rtl !== 'auto' && rtl !== 'off',
73 shape: rtl === 'auto' || rtl === 'off' ? 'visual' : TERMINALS[rtl],
74 latex: options.latex === true,
75 cwd: '',
76 home: '',
77 }
78}
79hooks/rtl.ts 232 lines1import type { Inline } from './markdown'
2
3type Dir = 'R' | 'L'
4export type Flow = { base: Dir; lines: Inline[][] }
5export type Shape = 'visual' | 'words' | 'logical' | 'inverse'
6
7export const TERMINALS = {
8 warp: 'visual',
9 ghostty: 'visual',
10 wezterm: 'visual',
11 vscode: 'visual',
12 alacritty: 'visual',
13 'windows-terminal': 'visual',
14 'apple-terminal': 'logical',
15 kitty: 'words',
16 iterm: 'logical',
17 gnome: 'logical',
18 konsole: 'logical',
19} as const satisfies Record<string, Shape>
20
21export type Terminal = keyof typeof TERMINALS
22
23type Fmt = { wrap: ('strong' | 'emphasis' | 'strike')[]; leaf: 'text' | 'code' | 'math' | 'number' | 'path' | 'link' | 'dim' }
24type Unit = { ch: string; fmt: Fmt }
25
26const R = /[--ٟ٪-ۯۺ-ݿࢠ-ࣿיִ-﷿ﹰ-]/
27const L = /[A-Za-z0-9À-ɏ٠-٩۰-۹]/
28const LATIN = /[A-Za-zÀ-ɏ]/
29const MARK = /\p{M}/u
30const MIRROR: Record<string, string> = { '(': ')', ')': '(', '[': ']', ']': '[', '{': '}', '}': '{', '<': '>', '>': '<' }
31const DIGIT = /[0-9\u0660-\u0669\u06F0-\u06F9]/
32const TERMINATOR = /[%\u2030\u00B0$\u20AC\u00A3\u00A5\u20AA]/
33const COMMENT = /^(.*?)((?:^|\s)(?:#|\/\/)\s+)(.*)$/
34
35const classify = (ch: string): Dir | null => (R.test(ch) ? 'R' : L.test(ch) ? 'L' : null)
36
37const units = (text: string, fmt: Fmt): Unit[] => {
38 const out: Unit[] = []
39 for (const cp of text) {
40 const last = out.at(-1)
41 if (last && MARK.test(cp)) last.ch += cp
42 else out.push({ ch: cp, fmt })
43 }
44 return out
45}
46
47const flatten = (nodes: Inline[], wrap: Fmt['wrap'] = []): Unit[] =>
48 nodes.flatMap(n => {
49 switch (n.kind) {
50 case 'strong':
51 case 'emphasis':
52 case 'strike':
53 return flatten(n.children, [...wrap, n.kind])
54 case 'link':
55 return n.text === n.href
56 ? units(n.text, { wrap, leaf: 'link' })
57 : [...units(n.text, { wrap, leaf: 'link' }), ...units(` (${n.href})`, { wrap, leaf: 'dim' })]
58 default:
59 return units(n.text, { wrap, leaf: n.kind })
60 }
61 })
62
63const sameFmt = (a: Fmt, b: Fmt) => a.leaf === b.leaf && a.wrap.length === b.wrap.length && a.wrap.every((k, i) => k === b.wrap[i])
64
65const leafNode = (leaf: Fmt['leaf'], text: string): Inline => (leaf === 'link' ? { kind: 'link', text, href: text } : { kind: leaf, text })
66
67const rebuild = (all: Unit[]): Inline[] => {
68 const out: Inline[] = []
69 let i = 0
70 while (i < all.length) {
71 const fmt = all[i]!.fmt
72 let text = ''
73 let j = i
74 while (j < all.length && sameFmt(all[j]!.fmt, fmt)) text += all[j++]!.ch
75 out.push(fmt.wrap.reduceRight<Inline>((inner, kind) => ({ kind, children: [inner] }), leafNode(fmt.leaf, text)))
76 i = j
77 }
78 return out
79}
80
81const baseOf = (all: Unit[]): Dir => {
82 const words = all.map(u => u.ch).join('').split(/\s+/)
83 const rw = words.filter(w => R.test(w)).length
84 const lw = words.filter(w => LATIN.test(w) && !R.test(w)).length
85 if (rw !== lw) return rw > lw ? 'R' : 'L'
86 return all.map(u => classify(u.ch)).find(Boolean) ?? 'R'
87}
88
89const reorder = (all: Unit[], base: Dir): Unit[] => {
90 const strong = all.map((u, i) => {
91 const own = classify(u.ch)
92 if (own) return own
93 if (u.fmt.leaf === 'code' || u.fmt.leaf === 'math' || u.fmt.leaf === 'path') return 'L'
94 return TERMINATOR.test(u.ch) && (DIGIT.test(all[i - 1]?.ch ?? '') || DIGIT.test(all[i + 1]?.ch ?? '')) ? 'L' : null
95 })
96 const prev: (Dir | null)[] = []
97 let seen: Dir | null = null
98 strong.forEach((s, i) => {
99 seen = s ?? seen
100 prev[i] = seen
101 })
102 const next: (Dir | null)[] = []
103 seen = null
104 for (let i = strong.length - 1; i >= 0; i--) {
105 seen = strong[i] ?? seen
106 next[i] = seen
107 }
108 const dir = strong.map((s, i): Dir => s ?? ((prev[i] ?? base) === (next[i] ?? base) ? (prev[i] ?? base) : base))
109 const runs: { d: Dir; u: Unit[] }[] = []
110 all.forEach((u, i) => {
111 const last = runs.at(-1)
112 if (last && last.d === dir[i]) last.u.push(u)
113 else runs.push({ d: dir[i]!, u: [u] })
114 })
115 const out = runs.map(r => (r.d === 'R' ? r.u.map(u => ({ ...u, ch: MIRROR[u.ch] ?? u.ch })).reverse() : r.u))
116 return (base === 'R' ? out.reverse() : out).flat()
117}
118
119const bidiClass = (ch: string): string =>
120 R.test(ch) ? 'R' : /[٠-٩]/.test(ch) ? 'AN' : /[0-9۰-۹]/.test(ch) ? 'EN' : /\p{L}/u.test(ch) ? 'L' : /[+-]/.test(ch) ? 'ES' : /[#$%°£€¥₪‰¢]/.test(ch) ? 'ET' : /[,.:/]/.test(ch) ? 'CS' : 'N'
121
122const terminalBidi = (all: Unit[]): Unit[] => {
123 const t = all.map(u => bidiClass(u.ch))
124 t.forEach((c, i) => {
125 if ((c === 'ES' || c === 'CS') && t[i - 1] === 'EN' && t[i + 1] === 'EN') t[i] = 'EN'
126 else if (c === 'CS' && t[i - 1] === 'AN' && t[i + 1] === 'AN') t[i] = 'AN'
127 })
128 for (let i = 1; i < t.length; i++) if (t[i] === 'ET' && t[i - 1] === 'EN') t[i] = 'EN'
129 for (let i = t.length - 2; i >= 0; i--) if (t[i] === 'ET' && t[i + 1] === 'EN') t[i] = 'EN'
130 let strong = 'L'
131 const w = t.map(c => {
132 if (c === 'L' || c === 'R') strong = c
133 return c === 'EN' && strong === 'L' ? 'L' : c === 'ES' || c === 'ET' || c === 'CS' ? 'N' : c
134 })
135 const rtlSide = (c?: string) => c !== undefined && c !== 'L'
136 const levels = w.map((c, i) => {
137 if (c !== 'N') return c === 'L' ? 0 : c === 'R' ? 1 : 2
138 let a = i
139 while (w[a] === 'N') a--
140 let b = i
141 while (w[b] === 'N') b++
142 return rtlSide(w[a]) && rtlSide(w[b]) ? 1 : 0
143 })
144 let out = all.map((u, i) => ({ u: levels[i]! % 2 ? { ...u, ch: MIRROR[u.ch] ?? u.ch } : u, l: levels[i]! }))
145 for (let l = 2; l >= 1; l--) {
146 const done: typeof out = []
147 let run: typeof out = []
148 for (const x of out) {
149 if (x.l >= l) run.push(x)
150 else {
151 done.push(...run.reverse(), x)
152 run = []
153 }
154 }
155 out = [...done, ...run.reverse()]
156 }
157 return out.map(x => x.u)
158}
159
160export const terminalLine = (nodes: Inline[]): Inline[] => rebuild(terminalBidi(flatten(nodes)))
161
162const wrapUnits = (all: Unit[], max: number, measure: (s: string) => number): Unit[][] => {
163 const tokens: Unit[][] = []
164 all.forEach((u, i) => {
165 if (i === 0 || (u.ch !== ' ' && all[i - 1]!.ch === ' ')) tokens.push([])
166 tokens.at(-1)!.push(u)
167 })
168 const lines: Unit[][] = [[]]
169 let used = 0
170 const trim = (line: Unit[]) => {
171 while (line.at(-1)?.ch === ' ') line.pop()
172 }
173 for (const token of tokens) {
174 let core = token.length
175 while (core > 0 && token[core - 1]!.ch === ' ') core--
176 const w = token.slice(0, core).reduce((sum, u) => sum + measure(u.ch), 0)
177 if (lines.at(-1)!.length && used + w > max) {
178 trim(lines.at(-1)!)
179 lines.push([])
180 used = 0
181 }
182 lines.at(-1)!.push(...token)
183 used += w + (token.length - core)
184 }
185 trim(lines.at(-1)!)
186 return lines
187}
188
189const clusters = (text: string): string[] => units(text, { wrap: [], leaf: 'text' }).map(u => u.ch)
190
191const RUN = new RegExp(`(?:${R.source}|\\p{M})+`, 'gu')
192
193const shapeText = (text: string, shape: Shape): string =>
194 !R.test(text) ? text : shape === 'words' ? text.replace(RUN, run => clusters(run).reverse().join('')) : shape === 'inverse' ? terminalBidi(units(text, { wrap: [], leaf: 'text' })).map(u => u.ch).join('') : text
195
196const shapeNodes = (nodes: Inline[], shape: Shape): Inline[] =>
197 nodes.map(n => {
198 if ('children' in n) return { ...n, children: shapeNodes(n.children, shape) }
199 if (n.kind === 'link') return { ...n, text: shapeText(n.text, shape), href: shapeText(n.href, shape) }
200 return { ...n, text: shapeText(n.text, shape) }
201 })
202
203const containsRtl = (nodes: Inline[]): boolean => nodes.some(n => ('children' in n ? containsRtl(n.children) : R.test(n.text)))
204
205export const flow = (nodes: Inline[], columns: number, measure: (s: string) => number, shape: Shape = 'visual'): Flow | null => {
206 if (!containsRtl(nodes)) return null
207 const all = flatten(nodes)
208 const base = baseOf(all)
209 const logical = base === 'R' ? wrapUnits(all, columns, measure) : [all]
210 const lines = logical.map(line => rebuild(shape === 'logical' ? line : shape === 'inverse' ? terminalBidi(reorder(line, base)) : reorder(line, base)))
211 return { base, lines: shape === 'words' ? lines.map(line => shapeNodes(line, shape)) : lines }
212}
213
214const visualText = (text: string): string => {
215 if (!R.test(text)) return text
216 const all = units(text, { wrap: [], leaf: 'text' })
217 return reorder(all, baseOf(all)).map(u => u.ch).join('')
218}
219
220export const commentTail = (line: string, shape: Shape = 'visual'): { head: string; marker: string; tail: string } | null => {
221 if (shape === 'logical' || !R.test(line)) return null
222 const m = COMMENT.exec(line)
223 return m && R.test(m[3]!) ? { head: m[1]!, marker: m[2]!, tail: shapeText(visualText(m[3]!), shape) } : null
224}
225
226export const commentVisual = (text: string, shape: Shape = 'visual'): string => {
227 const c = commentTail(text, shape)
228 return c ? c.head + c.marker + c.tail : text
229}
230
231export const hasRtl = (text: string): boolean => R.test(text)
232hooks/vendor/mermaid-text.js 13 lines1function normalizeBrTags(label){return(label.startsWith('"')&&label.endsWith('"')?label.slice(1,-1):label).replace(/<br\s*\/?>/gi,`
2`).replace(/\\n/g,`
3`).replace(/<\/?(?:sub|sup|small|mark)\s*>/gi,"").replace(/\*\*(.+?)\*\*/g,"<b>$1</b>").replace(/(?<!\*)\*([^\s*](?:[^*]*[^\s*])?)\*(?!\*)/g,"<i>$1</i>").replace(/~~(.+?)~~/g,"<s>$1</s>")}function parseMermaid(text){let lines=text.split(`
4`).map(l=>l.trim()).filter(l=>l.length>0&&!l.startsWith("%%"));if(lines.length===0)throw new Error("Empty mermaid diagram");let header=lines[0];return/^stateDiagram(-v2)?\s*$/i.test(header)?parseStateDiagram(lines):parseFlowchart(lines)}function parseFlowchart(lines){let headerMatch=lines[0].match(/^(?:graph|flowchart)\s+(TD|TB|LR|BT|RL)\s*$/i);if(!headerMatch)throw new Error(`Invalid mermaid header: "${lines[0]}". Expected "graph TD", "flowchart LR", "stateDiagram-v2", etc.`);let graph={direction:headerMatch[1].toUpperCase(),nodes:new Map,edges:[],subgraphs:[],classDefs:new Map,classAssignments:new Map,nodeStyles:new Map,linkStyles:new Map},subgraphStack=[];for(let i=1;i<lines.length;i++){let line=lines[i],classDefMatch=line.match(/^classDef\s+(\w+)\s+(.+)$/);if(classDefMatch){let name=classDefMatch[1],propsStr=classDefMatch[2],props=parseStyleProps(propsStr);graph.classDefs.set(name,props);continue}let classAssignMatch=line.match(/^class\s+([\w,-]+)\s+(\w+)$/);if(classAssignMatch){let nodeIds=classAssignMatch[1].split(",").map(s=>s.trim()),className=classAssignMatch[2];for(let id of nodeIds)graph.classAssignments.set(id,className);continue}let styleMatch=line.match(/^style\s+([\w,-]+)\s+(.+)$/);if(styleMatch){let nodeIds=styleMatch[1].split(",").map(s=>s.trim()),props=parseStyleProps(styleMatch[2]);for(let id of nodeIds)graph.nodeStyles.set(id,{...graph.nodeStyles.get(id),...props});continue}let linkStyleMatch=line.match(/^linkStyle\s+(default|[\d,\s]+)\s+(.+)$/);if(linkStyleMatch){let target=linkStyleMatch[1].trim(),props=parseStyleProps(linkStyleMatch[2]);if(target==="default")graph.linkStyles.set("default",{...graph.linkStyles.get("default"),...props});else{let indices=target.split(",").map(s=>parseInt(s.trim(),10));for(let idx of indices)isNaN(idx)||graph.linkStyles.set(idx,{...graph.linkStyles.get(idx),...props})}continue}let dirMatch=line.match(/^direction\s+(TD|TB|LR|BT|RL)\s*$/i);if(dirMatch&&subgraphStack.length>0){subgraphStack[subgraphStack.length-1].direction=dirMatch[1].toUpperCase();continue}let subgraphMatch=line.match(/^subgraph\s+(.+)$/);if(subgraphMatch){let rest=subgraphMatch[1].trim(),bracketMatch=rest.match(/^([\w-]+)\s*\[(.+)\]$/),id,label;bracketMatch?(id=bracketMatch[1],label=normalizeBrTags(bracketMatch[2])):(label=normalizeBrTags(rest),id=rest.replace(/\s+/g,"_").replace(/[^\w]/g,""));let sg={id,label,nodeIds:[],children:[]};subgraphStack.push(sg);continue}if(line==="end"){let completed=subgraphStack.pop();completed&&(subgraphStack.length>0?subgraphStack[subgraphStack.length-1].children.push(completed):graph.subgraphs.push(completed));continue}parseEdgeLine(line,graph,subgraphStack)}return graph}function parseStateDiagram(lines){let graph={direction:"TD",nodes:new Map,edges:[],subgraphs:[],classDefs:new Map,classAssignments:new Map,nodeStyles:new Map,linkStyles:new Map},compositeStack=[],compositeStateIds=new Set,startCount=0,endCount=0;for(let i=1;i<lines.length;i++){let line=lines[i],dirMatch=line.match(/^direction\s+(TD|TB|LR|BT|RL)\s*$/i);if(dirMatch){compositeStack.length>0?compositeStack[compositeStack.length-1].direction=dirMatch[1].toUpperCase():graph.direction=dirMatch[1].toUpperCase();continue}let linkStyleMatch=line.match(/^linkStyle\s+(default|[\d,\s]+)\s+(.+)$/);if(linkStyleMatch){let target=linkStyleMatch[1].trim(),props=parseStyleProps(linkStyleMatch[2]);if(target==="default")graph.linkStyles.set("default",{...graph.linkStyles.get("default"),...props});else{let indices=target.split(",").map(s=>parseInt(s.trim(),10));for(let idx of indices)isNaN(idx)||graph.linkStyles.set(idx,{...graph.linkStyles.get(idx),...props})}continue}let compositeMatch=line.match(/^state\s+(?:"([^"]+)"\s+as\s+)?([\w\p{L}]+)\s*\{$/u);if(compositeMatch){let label=compositeMatch[1]??compositeMatch[2],id=compositeMatch[2],sg={id,label,nodeIds:[],children:[]};compositeStack.push(sg),compositeStateIds.add(id),graph.nodes.delete(id);continue}if(line==="}"){let completed=compositeStack.pop();completed&&(compositeStack.length>0?compositeStack[compositeStack.length-1].children.push(completed):graph.subgraphs.push(completed));continue}let stateAliasMatch=line.match(/^state\s+"([^"]+)"\s+as\s+([\w\p{L}]+)\s*$/u);if(stateAliasMatch){let label=normalizeBrTags(stateAliasMatch[1]),id=stateAliasMatch[2];registerStateNode(graph,compositeStack,{id,label,shape:"rounded"});continue}let transitionMatch=line.match(/^(\[\*\]|[\w\p{L}-]+)\s*(-->)\s*(\[\*\]|[\w\p{L}-]+)(?:\s*:\s*(.+))?$/u);if(transitionMatch){let sourceId=transitionMatch[1],targetId=transitionMatch[3],rawTransitionLabel=transitionMatch[4]?.trim(),edgeLabel=rawTransitionLabel?normalizeBrTags(rawTransitionLabel):void 0;sourceId==="[*]"?(startCount++,sourceId=`_start${startCount>1?startCount:""}`,registerStateNode(graph,compositeStack,{id:sourceId,label:"",shape:"state-start"})):compositeStateIds.has(sourceId)||ensureStateNode(graph,compositeStack,sourceId),targetId==="[*]"?(endCount++,targetId=`_end${endCount>1?endCount:""}`,registerStateNode(graph,compositeStack,{id:targetId,label:"",shape:"state-end"})):compositeStateIds.has(targetId)||ensureStateNode(graph,compositeStack,targetId),graph.edges.push({source:sourceId,target:targetId,label:edgeLabel,style:"solid",hasArrowStart:!1,hasArrowEnd:!0});continue}let stateDescMatch=line.match(/^([\w\p{L}-]+)\s*:\s*(.+)$/u);if(stateDescMatch){let id=stateDescMatch[1],label=normalizeBrTags(stateDescMatch[2].trim());registerStateNode(graph,compositeStack,{id,label,shape:"rounded"});continue}}return graph}function registerStateNode(graph,compositeStack,node){if(!graph.nodes.has(node.id)&&graph.nodes.set(node.id,node),compositeStack.length>0){let current=compositeStack[compositeStack.length-1];current.nodeIds.includes(node.id)||current.nodeIds.push(node.id)}}function ensureStateNode(graph,compositeStack,id){if(!graph.nodes.has(id))registerStateNode(graph,compositeStack,{id,label:id,shape:"rounded"});else if(compositeStack.length>0){let current=compositeStack[compositeStack.length-1];current.nodeIds.includes(id)||current.nodeIds.push(id)}}function parseStyleProps(propsStr){let cleaned=propsStr.replace(/;\s*$/,""),props={};for(let pair of cleaned.split(",")){let colonIdx=pair.indexOf(":");if(colonIdx>0){let key=pair.slice(0,colonIdx).trim(),val=pair.slice(colonIdx+1).trim();key&&val&&(props[key]=val)}}return props}var ARROW_REGEX=/^(<)?(-->|-.->|==>|---|-\.-|===)(?:\|([^|]*)\|)?/,TEXT_ARROW_REGEX=/^(<)?(--|-\.|==)\s+(.+?)\s+(-->|---|\.\->|-\.\-|==>|===)/,NODE_PATTERNS=[{regex:/^([\w-]+)\(\(\((.+?)\)\)\)/,shape:"doublecircle"},{regex:/^([\w-]+)\(\[(.+?)\]\)/,shape:"stadium"},{regex:/^([\w-]+)\(\((.+?)\)\)/,shape:"circle"},{regex:/^([\w-]+)\[\[(.+?)\]\]/,shape:"subroutine"},{regex:/^([\w-]+)\[\((.+?)\)\]/,shape:"cylinder"},{regex:/^([\w-]+)\[\/(.+?)\\\]/,shape:"trapezoid"},{regex:/^([\w-]+)\[\\(.+?)\/\]/,shape:"trapezoid-alt"},{regex:/^([\w-]+)>(.+?)\]/,shape:"asymmetric"},{regex:/^([\w-]+)\{\{(.+?)\}\}/,shape:"hexagon"},{regex:/^([\w-]+)\[(.+?)\]/,shape:"rectangle"},{regex:/^([\w-]+)\((.+?)\)/,shape:"rounded"},{regex:/^([\w-]+)\{(.+?)\}/,shape:"diamond"}],BARE_NODE_REGEX=/^([\w-]+)/,CLASS_SHORTHAND_REGEX=/^:::([\w][\w-]*)/;function parseEdgeLine(line,graph,subgraphStack){let remaining=line.trim(),firstGroup=consumeNodeGroup(remaining,graph,subgraphStack);if(!firstGroup||firstGroup.ids.length===0)return;remaining=firstGroup.remaining.trim();let prevGroupIds=firstGroup.ids;for(;remaining.length>0;){let hasArrowStart,style,hasArrowEnd,edgeLabel,arrowMatch=remaining.match(ARROW_REGEX);if(arrowMatch){hasArrowStart=!!arrowMatch[1];let arrowOp=arrowMatch[2],rawEdgeLabel=arrowMatch[3]?.trim();edgeLabel=rawEdgeLabel?normalizeBrTags(rawEdgeLabel):void 0,remaining=remaining.slice(arrowMatch[0].length).trim(),style=arrowStyleFromOp(arrowOp),hasArrowEnd=arrowOp.endsWith(">")}else{let textMatch=remaining.match(TEXT_ARROW_REGEX);if(!textMatch)break;hasArrowStart=!!textMatch[1];let rawLabel=textMatch[3].trim();edgeLabel=rawLabel?normalizeBrTags(rawLabel):void 0;let openOp=textMatch[2],closeOp=textMatch[4];remaining=remaining.slice(textMatch[0].length).trim(),style=textArrowStyleFromOps(openOp,closeOp),hasArrowEnd=closeOp.endsWith(">")}let nextGroup=consumeNodeGroup(remaining,graph,subgraphStack);if(!nextGroup||nextGroup.ids.length===0)break;remaining=nextGroup.remaining.trim();for(let sourceId of prevGroupIds)for(let targetId of nextGroup.ids)graph.edges.push({source:sourceId,target:targetId,label:edgeLabel,style,hasArrowStart,hasArrowEnd});prevGroupIds=nextGroup.ids}}function consumeNodeGroup(text,graph,subgraphStack){let first=consumeNode(text,graph,subgraphStack);if(!first)return null;let ids=[first.id],remaining=first.remaining.trim();for(;remaining.startsWith("&");){remaining=remaining.slice(1).trim();let next=consumeNode(remaining,graph,subgraphStack);if(!next)break;ids.push(next.id),remaining=next.remaining.trim()}return{ids,remaining}}function consumeNode(text,graph,subgraphStack){let id=null,remaining=text;for(let{regex,shape}of NODE_PATTERNS){let match=text.match(regex);if(match){id=match[1];let label=normalizeBrTags(match[2]);registerNode(graph,subgraphStack,{id,label,shape}),remaining=text.slice(match[0].length);break}}if(id===null){let bareMatch=text.match(BARE_NODE_REGEX);bareMatch&&(id=bareMatch[1],graph.nodes.has(id)||registerNode(graph,subgraphStack,{id,label:id,shape:"rectangle"}),remaining=text.slice(bareMatch[0].length))}if(id===null)return null;let classMatch=remaining.match(CLASS_SHORTHAND_REGEX);return classMatch&&(graph.classAssignments.set(id,classMatch[1]),remaining=remaining.slice(classMatch[0].length)),{id,remaining}}function registerNode(graph,subgraphStack,node){!graph.nodes.has(node.id)&&graph.nodes.set(node.id,node),trackInSubgraph(subgraphStack,node.id)}function trackInSubgraph(subgraphStack,nodeId){if(subgraphStack.length>0){let current=subgraphStack[subgraphStack.length-1];current.nodeIds.includes(nodeId)||current.nodeIds.push(nodeId)}}function arrowStyleFromOp(op){return op==="-.->"||op==="-.-"?"dotted":op==="==>"||op==="==="?"thick":"solid"}function textArrowStyleFromOps(openOp,closeOp){return openOp==="-."||closeOp===".->"||closeOp==="-.-"?"dotted":openOp==="=="||closeOp==="==>"||closeOp==="==="?"thick":"solid"}var Up={x:1,y:0},Down={x:1,y:2},Left={x:0,y:1},Right={x:2,y:1},UpperRight={x:2,y:0},UpperLeft={x:0,y:0},LowerRight={x:2,y:2},LowerLeft={x:0,y:2},Middle={x:1,y:1};function gridCoordEquals(a,b){return a.x===b.x&&a.y===b.y}function drawingCoordEquals(a,b){return a.x===b.x&&a.y===b.y}function gridCoordDirection(c,dir){return{x:c.x+dir.x,y:c.y+dir.y}}function gridKey(c){return`${c.x},${c.y}`}var EMPTY_STYLE={name:"",styles:{}};var DEFAULT_ASCII_THEME={fg:"#27272a",border:"#a1a1aa",line:"#71717a",arrow:"#52525b",corner:"#71717a",junction:"#a1a1aa"};function detectColorMode(){let proc=globalThis.process;if(proc){if(!proc.stdout?.isTTY)return"none";let colorTerm=proc.env?.COLORTERM?.toLowerCase()??"",term=proc.env?.TERM?.toLowerCase()??"";return colorTerm==="truecolor"||colorTerm==="24bit"?"truecolor":term.includes("256color")||term.includes("256")?"ansi256":term&&term!=="dumb"?"ansi16":"none"}return typeof document<"u"?"html":"none"}function parseHex(hex){let h=hex.replace("#","");return h.length===3?{r:parseInt(h[0]+h[0],16),g:parseInt(h[1]+h[1],16),b:parseInt(h[2]+h[2],16)}:{r:parseInt(h.substring(0,2),16),g:parseInt(h.substring(2,4),16),b:parseInt(h.substring(4,6),16)}}var ESC="\x1B[",RESET=`${ESC}0m`;function truecolorFg(hex){let{r,g,b}=parseHex(hex);return`${ESC}38;2;${r};${g};${b}m`}function rgbTo256(r,g,b){let avg=(r+g+b)/3;if(Math.max(Math.abs(r-avg),Math.abs(g-avg),Math.abs(b-avg))<10){let gray=Math.round(avg/255*23);return 232+Math.min(23,Math.max(0,gray))}let toIndex=v=>v<48?0:v<115?1:Math.min(5,Math.floor((v-35)/40)),ri=toIndex(r),gi=toIndex(g),bi=toIndex(b);return 16+36*ri+6*gi+bi}function ansi256Fg(hex){let{r,g,b}=parseHex(hex),index=rgbTo256(r,g,b);return`${ESC}38;5;${index}m`}function ansi16Fg(hex){let{r,g,b}=parseHex(hex),luma=.299*r+.587*g+.114*b,bright=luma>100?0:60,code;return r>180&&g<100&&b<100?code=31:g>180&&r<100&&b<100?code=32:r>150&&g>150&&b<100?code=33:b>180&&r<100&&g<100?code=34:r>150&&b>150&&g<100?code=35:g>150&&b>150&&r<100?code=36:luma>200?code=37:luma<50?code=30:code=37,`${ESC}${code+bright}m`}function escapeHtml(text){return text.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function htmlSpan(hex,text){return`<span style="color:${hex}">${escapeHtml(text)}</span>`}function getRoleColor(role,theme){switch(role){case"text":return theme.fg;case"border":return theme.border;case"line":return theme.line;case"arrow":return theme.arrow;case"corner":return theme.corner??theme.line;case"junction":return theme.junction??theme.border;default:return theme.fg}}function getAnsiColor(role,theme,mode){if(mode==="none")return"";let hex=getRoleColor(role,theme);switch(mode){case"truecolor":return truecolorFg(hex);case"ansi256":return ansi256Fg(hex);case"ansi16":return ansi16Fg(hex);default:return""}}function colorizeLine(chars,roles,theme,mode){if(mode==="none")return chars.join("");if(mode==="html")return colorizeLineHtml(chars,roles,theme);let result="",currentRole=null,buffer="";for(let i=0;i<chars.length;i++){let char=chars[i],role=roles[i]??null;if(char===" "){buffer.length>0&&(currentRole!==null?result+=getAnsiColor(currentRole,theme,mode)+buffer+RESET:result+=buffer,buffer="",currentRole=null),result+=char;continue}if(role===currentRole){buffer+=char;continue}buffer.length>0&&(currentRole!==null?result+=getAnsiColor(currentRole,theme,mode)+buffer+RESET:result+=buffer),buffer=char,currentRole=role}return buffer.length>0&¤tRole!==null?result+=getAnsiColor(currentRole,theme,mode)+buffer+RESET:buffer.length>0&&(result+=buffer),result}function colorizeLineHtml(chars,roles,theme){let result="",currentRole=null,buffer="",flush=()=>{buffer.length!==0&&(currentRole!==null?result+=htmlSpan(getRoleColor(currentRole,theme),buffer):result+=escapeHtml(buffer),buffer="",currentRole=null)};for(let i=0;i<chars.length;i++){let char=chars[i],role=roles[i]??null;if(char===" "){flush(),result+=" ";continue}if(role===currentRole){buffer+=char;continue}flush(),buffer=char,currentRole=role}return flush(),result}function colorizeText(text,hex,mode){if(mode==="none"||text.length===0)return text;if(mode==="html")return htmlSpan(hex,text);let code;switch(mode){case"truecolor":code=truecolorFg(hex);break;case"ansi256":code=ansi256Fg(hex);break;case"ansi16":code=ansi16Fg(hex);break;default:return text}return`${code}${text}${RESET}`}function mkCanvas(x,y){let canvas=[];for(let i=0;i<=x;i++){let col=[];for(let j=0;j<=y;j++)col.push(" ");canvas.push(col)}return canvas}function copyCanvas(source){let[maxX,maxY]=getCanvasSize(source);return mkCanvas(maxX,maxY)}function mkRoleCanvas(x,y){let roleCanvas=[];for(let i=0;i<=x;i++){let col=[];for(let j=0;j<=y;j++)col.push(null);roleCanvas.push(col)}return roleCanvas}function increaseRoleCanvasSize(roleCanvas,newX,newY){let currX=roleCanvas.length-1,currY=(roleCanvas[0]?.length??1)-1,targetX=Math.max(newX,currX),targetY=Math.max(newY,currY),grown=mkRoleCanvas(targetX,targetY);for(let x=0;x<grown.length;x++)for(let y=0;y<grown[0].length;y++)x<roleCanvas.length&&y<roleCanvas[0].length&&(grown[x][y]=roleCanvas[x][y]);return roleCanvas.length=0,roleCanvas.push(...grown),roleCanvas}function setRole(roleCanvas,x,y,role){(x>=roleCanvas.length||y>=(roleCanvas[0]?.length??0))&&increaseRoleCanvasSize(roleCanvas,x,y),roleCanvas[x][y]=role}function getCanvasSize(canvas){return[canvas.length-1,(canvas[0]?.length??1)-1]}function increaseSize(canvas,newX,newY){let[currX,currY]=getCanvasSize(canvas),targetX=Math.max(newX,currX),targetY=Math.max(newY,currY),grown=mkCanvas(targetX,targetY);for(let x=0;x<grown.length;x++)for(let y=0;y<grown[0].length;y++)x<canvas.length&&y<canvas[0].length&&(grown[x][y]=canvas[x][y]);return canvas.length=0,canvas.push(...grown),canvas}var JUNCTION_CHARS=new Set(["\u2500","\u2502","\u250C","\u2510","\u2514","\u2518","\u251C","\u2524","\u252C","\u2534","\u253C","\u2574","\u2575","\u2576","\u2577"]);function clearLabelGaps(canvas,label){for(let y=0;y<(label[0]?.length??0);y++){let xs=label.map((col,x)=>col[y]!==" "?x:-1).filter(x=>x>=0);if(xs.length!==0)for(let x=xs[0];x<=xs[xs.length-1];x++)label[x][y]===" "&&!isAlphanumeric(canvas[x][y])&&(canvas[x][y]=" ")}}function isJunctionChar(c){return JUNCTION_CHARS.has(c)}function isAlphanumeric(c){return/^[a-zA-Z0-9]$/.test(c)}var JUNCTION_MAP={"\u2500":{"\u2502":"\u253C","\u250C":"\u252C","\u2510":"\u252C","\u2514":"\u2534","\u2518":"\u2534","\u251C":"\u253C","\u2524":"\u253C","\u252C":"\u252C","\u2534":"\u2534"},"\u2502":{"\u2500":"\u253C","\u250C":"\u251C","\u2510":"\u2524","\u2514":"\u251C","\u2518":"\u2524","\u251C":"\u251C","\u2524":"\u2524","\u252C":"\u253C","\u2534":"\u253C"},"\u250C":{"\u2500":"\u252C","\u2502":"\u251C","\u2510":"\u252C","\u2514":"\u251C","\u2518":"\u253C","\u251C":"\u251C","\u2524":"\u253C","\u252C":"\u252C","\u2534":"\u253C"},"\u2510":{"\u2500":"\u252C","\u2502":"\u2524","\u250C":"\u252C","\u2514":"\u253C","\u2518":"\u2524","\u251C":"\u253C","\u2524":"\u2524","\u252C":"\u252C","\u2534":"\u253C"},"\u2514":{"\u2500":"\u2534","\u2502":"\u251C","\u250C":"\u251C","\u2510":"\u253C","\u2518":"\u2534","\u251C":"\u251C","\u2524":"\u253C","\u252C":"\u253C","\u2534":"\u2534"},"\u2518":{"\u2500":"\u2534","\u2502":"\u2524","\u250C":"\u253C","\u2510":"\u2524","\u2514":"\u2534","\u251C":"\u253C","\u2524":"\u2524","\u252C":"\u253C","\u2534":"\u2534"},"\u251C":{"\u2500":"\u253C","\u2502":"\u251C","\u250C":"\u251C","\u2510":"\u253C","\u2514":"\u251C","\u2518":"\u253C","\u2524":"\u253C","\u252C":"\u253C","\u2534":"\u253C"},"\u2524":{"\u2500":"\u253C","\u2502":"\u2524","\u250C":"\u253C","\u2510":"\u2524","\u2514":"\u253C","\u2518":"\u2524","\u251C":"\u253C","\u252C":"\u253C","\u2534":"\u253C"},"\u252C":{"\u2500":"\u252C","\u2502":"\u253C","\u250C":"\u252C","\u2510":"\u252C","\u2514":"\u253C","\u2518":"\u253C","\u251C":"\u253C","\u2524":"\u253C","\u2534":"\u253C"},"\u2534":{"\u2500":"\u2534","\u2502":"\u253C","\u250C":"\u253C","\u2510":"\u253C","\u2514":"\u2534","\u2518":"\u2534","\u251C":"\u253C","\u2524":"\u253C","\u252C":"\u253C"}};function mergeJunctions(c1,c2){return JUNCTION_MAP[c1]?.[c2]??c1}function mergeCanvases(base,offset,useAscii,...overlays){let[maxX,maxY]=getCanvasSize(base);for(let overlay of overlays){let[oX,oY]=getCanvasSize(overlay);maxX=Math.max(maxX,oX+offset.x),maxY=Math.max(maxY,oY+offset.y)}let merged=mkCanvas(maxX,maxY);for(let x=0;x<=maxX;x++)for(let y=0;y<=maxY;y++)x<base.length&&y<base[0].length&&(merged[x][y]=base[x][y]);for(let overlay of overlays)for(let x=0;x<overlay.length;x++)for(let y=0;y<overlay[0].length;y++){let c=overlay[x][y];if(c!==" "){let mx=x+offset.x,my=y+offset.y,current=merged[mx][my];!useAscii&&isJunctionChar(c)&&isJunctionChar(current)?merged[mx][my]=mergeJunctions(current,c):isAlphanumeric(current)&&isAlphanumeric(c)||(merged[mx][my]=c)}}return merged}function canvasToString(canvas,options){let[maxX,maxY]=getCanvasSize(canvas),lines=[],roleCanvas=options?.roleCanvas,colorMode=options?.colorMode??"none",theme=options?.theme??DEFAULT_ASCII_THEME;for(let y=0;y<=maxY;y++)if(colorMode==="none"||!roleCanvas){let line="";for(let x=0;x<=maxX;x++)line+=canvas[x][y];lines.push(line)}else{let chars=[],roles=[];for(let x=0;x<=maxX;x++)chars.push(canvas[x][y]),roles.push(roleCanvas[x]?.[y]??null);lines.push(colorizeLine(chars,roles,theme,colorMode))}return lines.join(`
5`)}var VERTICAL_FLIP_MAP={"\u25B2":"\u25BC","\u25BC":"\u25B2","\u25E4":"\u25E3","\u25E3":"\u25E4","\u25E5":"\u25E2","\u25E2":"\u25E5","^":"v",v:"^","\u250C":"\u2514","\u2514":"\u250C","\u2510":"\u2518","\u2518":"\u2510","\u252C":"\u2534","\u2534":"\u252C","\u2575":"\u2577","\u2577":"\u2575"};function flipCanvasVertically(canvas){for(let col of canvas)col.reverse();for(let col of canvas)for(let y=0;y<col.length;y++){let flipped=VERTICAL_FLIP_MAP[col[y]];flipped&&(col[y]=flipped)}return canvas}function flipRoleCanvasVertically(roleCanvas){for(let col of roleCanvas)col.reverse();return roleCanvas}function drawText(canvas,start,text,forceOverwrite=!1){increaseSize(canvas,start.x+text.length,start.y);for(let i=0;i<text.length;i++){let x=start.x+i,current=canvas[x][start.y];(forceOverwrite||current===" ")&&(canvas[x][start.y]=text[i])}}function setCanvasSizeToGrid(canvas,columnWidth,rowHeight){let maxX=0,maxY=0;for(let w of columnWidth.values())maxX+=w;for(let h of rowHeight.values())maxY+=h;increaseSize(canvas,maxX-1,maxY-1)}function setRoleCanvasSizeToGrid(roleCanvas,columnWidth,rowHeight){let maxX=0,maxY=0;for(let w of columnWidth.values())maxX+=w;for(let h of rowHeight.values())maxY+=h;increaseRoleCanvasSize(roleCanvas,maxX-1,maxY-1)}function convertToAsciiGraph(parsed,config){let nodeMap=new Map,index=0;for(let[id,mNode]of parsed.nodes){let asciiNode={name:id,displayLabel:mNode.label,shape:mNode.shape,index,gridCoord:null,drawingCoord:null,drawing:null,drawn:!1,styleClassName:"",styleClass:EMPTY_STYLE};nodeMap.set(id,asciiNode),index++}let nodes=[...nodeMap.values()],edges=[];for(let mEdge of parsed.edges){let from=nodeMap.get(mEdge.source),to=nodeMap.get(mEdge.target);!from||!to||edges.push({from,to,text:mEdge.label??"",path:[],labelLine:[],startDir:{x:0,y:0},endDir:{x:0,y:0},style:mEdge.style,hasArrowStart:mEdge.hasArrowStart,hasArrowEnd:mEdge.hasArrowEnd})}let subgraphs=[];for(let mSg of parsed.subgraphs)convertSubgraph(mSg,null,nodeMap,subgraphs);deduplicateSubgraphNodes(parsed.subgraphs,subgraphs,nodeMap,parsed);for(let[nodeId,className]of parsed.classAssignments){let node=nodeMap.get(nodeId),classDef=parsed.classDefs.get(className);node&&classDef&&(node.styleClassName=className,node.styleClass={name:className,styles:classDef})}return{nodes,edges,canvas:mkCanvas(0,0),roleCanvas:mkRoleCanvas(0,0),grid:new Map,columnWidth:new Map,rowHeight:new Map,subgraphs,config,offsetX:0,offsetY:0,bundles:[]}}function convertSubgraph(mSg,parent,nodeMap,allSubgraphs){let normalizedDirection;mSg.direction&&(normalizedDirection=mSg.direction==="LR"||mSg.direction==="RL"?"LR":"TD");let sg={name:mSg.label,nodes:[],parent,children:[],minX:0,minY:0,maxX:0,maxY:0,direction:normalizedDirection};for(let nodeId of mSg.nodeIds){let node=nodeMap.get(nodeId);node&&sg.nodes.push(node)}allSubgraphs.push(sg);for(let childMSg of mSg.children){let child=convertSubgraph(childMSg,sg,nodeMap,allSubgraphs);sg.children.push(child);for(let childNode of child.nodes)sg.nodes.includes(childNode)||sg.nodes.push(childNode)}return sg}function deduplicateSubgraphNodes(mermaidSubgraphs,asciiSubgraphs,nodeMap,parsed){let sgMap=new Map;buildSgMap(mermaidSubgraphs,asciiSubgraphs,sgMap);let nodeOwner=new Map;function claimNodes(mSg){let asciiSg=sgMap.get(mSg);if(asciiSg){for(let child of mSg.children)claimNodes(child);for(let nodeId of mSg.nodeIds)nodeOwner.has(nodeId)||nodeOwner.set(nodeId,asciiSg)}}for(let mSg of mermaidSubgraphs)claimNodes(mSg);for(let asciiSg of asciiSubgraphs)asciiSg.nodes=asciiSg.nodes.filter(node=>{let nodeId;for(let[id,n]of nodeMap)if(n===node){nodeId=id;break}if(!nodeId)return!1;let owner=nodeOwner.get(nodeId);return owner?isAncestorOrSelf(asciiSg,owner):!0})}function isAncestorOrSelf(candidate,target){let current=target;for(;current!==null;){if(current===candidate)return!0;current=current.parent}return!1}function buildSgMap(mSgs,aSgs,result){let flatMermaid=[];function flatten(sgs){for(let sg of sgs)flatMermaid.push(sg),flatten(sg.children)}flatten(mSgs);for(let i=0;i<flatMermaid.length&&i<aSgs.length;i++)result.set(flatMermaid[i],aSgs[i])}var MinHeap=class{items=[];get length(){return this.items.length}push(item){this.items.push(item),this.bubbleUp(this.items.length-1)}pop(){if(this.items.length===0)return;let top=this.items[0],last=this.items.pop();return this.items.length>0&&(this.items[0]=last,this.sinkDown(0)),top}bubbleUp(i){for(;i>0;){let parent=i-1>>1;if(this.items[i].priority<this.items[parent].priority)[this.items[i],this.items[parent]]=[this.items[parent],this.items[i]],i=parent;else break}}sinkDown(i){let n=this.items.length;for(;;){let smallest=i,left=2*i+1,right=2*i+2;if(left<n&&this.items[left].priority<this.items[smallest].priority&&(smallest=left),right<n&&this.items[right].priority<this.items[smallest].priority&&(smallest=right),smallest!==i)[this.items[i],this.items[smallest]]=[this.items[smallest],this.items[i]],i=smallest;else break}}};function heuristic(a,b){let absX=Math.abs(a.x-b.x),absY=Math.abs(a.y-b.y);return absX===0||absY===0?absX+absY:absX+absY+1}var MOVE_DIRS=[{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}];function isFreeInGrid(grid,c){return c.x<0||c.y<0?!1:!grid.has(gridKey(c))}function getPath(grid,from,to){let pq=new MinHeap;pq.push({coord:from,priority:0});let costSoFar=new Map;costSoFar.set(gridKey(from),0);let cameFrom=new Map;for(cameFrom.set(gridKey(from),null);pq.length>0;){let current=pq.pop().coord;if(gridCoordEquals(current,to)){let path=[],c=current;for(;c!==null;)path.unshift(c),c=cameFrom.get(gridKey(c))??null;return path}let currentCost=costSoFar.get(gridKey(current));for(let dir of MOVE_DIRS){let next={x:current.x+dir.x,y:current.y+dir.y};if(!isFreeInGrid(grid,next)&&!gridCoordEquals(next,to))continue;let newCost=currentCost+1,nextKey=gridKey(next),existingCost=costSoFar.get(nextKey);if(existingCost===void 0||newCost<existingCost){costSoFar.set(nextKey,newCost);let priority=newCost+heuristic(next,to);pq.push({coord:next,priority}),cameFrom.set(nextKey,current)}}}return null}function mergePath(path){if(path.length<=2)return path;let toRemove=new Set,step0=path[0],step1=path[1];for(let idx=2;idx<path.length;idx++){let step2=path[idx],prevDx=step1.x-step0.x,prevDy=step1.y-step0.y,dx=step2.x-step1.x,dy=step2.y-step1.y;prevDx===dx&&prevDy===dy&&toRemove.add(idx-1),step0=step1,step1=step2}return path.filter((_,i)=>!toRemove.has(i))}function getOpposite(d){return d===Up?Down:d===Down?Up:d===Left?Right:d===Right?Left:d===UpperRight?LowerLeft:d===UpperLeft?LowerRight:d===LowerRight?UpperLeft:d===LowerLeft?UpperRight:Middle}function dirEquals(a,b){return a.x===b.x&&a.y===b.y}function determineDirection(from,to){return from.x===to.x?from.y<to.y?Down:Up:from.y===to.y?from.x<to.x?Right:Left:from.x<to.x?from.y<to.y?LowerRight:UpperRight:from.y<to.y?LowerLeft:UpperLeft}function selfReferenceDirection(graphDirection){return graphDirection==="LR"?[Right,Down,Down,Right]:[Down,Right,Right,Down]}function determineStartAndEndDir(edge,graphDirection){if(edge.from===edge.to)return selfReferenceDirection(graphDirection);let d=determineDirection(edge.from.gridCoord,edge.to.gridCoord),preferredDir,preferredOppositeDir,alternativeDir,alternativeOppositeDir,isBackwards=graphDirection==="LR"?dirEquals(d,Left)||dirEquals(d,UpperLeft)||dirEquals(d,LowerLeft):dirEquals(d,Up)||dirEquals(d,UpperLeft)||dirEquals(d,UpperRight);return dirEquals(d,LowerRight)?graphDirection==="LR"?(preferredDir=Down,preferredOppositeDir=Left,alternativeDir=Right,alternativeOppositeDir=Up):(preferredDir=Right,preferredOppositeDir=Up,alternativeDir=Down,alternativeOppositeDir=Left):dirEquals(d,UpperRight)?graphDirection==="LR"?(preferredDir=Up,preferredOppositeDir=Left,alternativeDir=Right,alternativeOppositeDir=Down):(preferredDir=Right,preferredOppositeDir=Down,alternativeDir=Up,alternativeOppositeDir=Left):dirEquals(d,LowerLeft)?graphDirection==="LR"?(preferredDir=Down,preferredOppositeDir=Down,alternativeDir=Left,alternativeOppositeDir=Up):(preferredDir=Left,preferredOppositeDir=Up,alternativeDir=Down,alternativeOppositeDir=Right):dirEquals(d,UpperLeft)?graphDirection==="LR"?(preferredDir=Down,preferredOppositeDir=Down,alternativeDir=Left,alternativeOppositeDir=Down):(preferredDir=Right,preferredOppositeDir=Right,alternativeDir=Up,alternativeOppositeDir=Right):isBackwards?graphDirection==="LR"&&dirEquals(d,Left)?(preferredDir=Down,preferredOppositeDir=Down,alternativeDir=Left,alternativeOppositeDir=Right):graphDirection==="TD"&&dirEquals(d,Up)?(preferredDir=Right,preferredOppositeDir=Right,alternativeDir=Up,alternativeOppositeDir=Down):(preferredDir=d,preferredOppositeDir=getOpposite(d),alternativeDir=d,alternativeOppositeDir=getOpposite(d)):(preferredDir=d,preferredOppositeDir=getOpposite(d),alternativeDir=d,alternativeOppositeDir=getOpposite(d)),[preferredDir,preferredOppositeDir,alternativeDir,alternativeOppositeDir]}function determinePath(graph,edge){let sourceSg=getNodeSubgraph(graph,edge.from),targetSg=getNodeSubgraph(graph,edge.to),effectiveDir=sourceSg&&sourceSg===targetSg&&sourceSg.direction?sourceSg.direction:graph.config.graphDirection,[preferredDir,preferredOppositeDir,alternativeDir,alternativeOppositeDir]=determineStartAndEndDir(edge,effectiveDir),prefFrom=gridCoordDirection(edge.from.gridCoord,preferredDir),prefTo=gridCoordDirection(edge.to.gridCoord,preferredOppositeDir),preferredPath=getPath(graph.grid,prefFrom,prefTo),altFrom=gridCoordDirection(edge.from.gridCoord,alternativeDir),altTo=gridCoordDirection(edge.to.gridCoord,alternativeOppositeDir),alternativePath=getPath(graph.grid,altFrom,altTo);if(preferredPath!==null&&alternativePath!==null){preferredPath=mergePath(preferredPath),alternativePath=mergePath(alternativePath),preferredPath.length<=alternativePath.length?(edge.startDir=preferredDir,edge.endDir=preferredOppositeDir,edge.path=preferredPath):(edge.startDir=alternativeDir,edge.endDir=alternativeOppositeDir,edge.path=alternativePath);return}if(preferredPath!==null){edge.startDir=preferredDir,edge.endDir=preferredOppositeDir,edge.path=mergePath(preferredPath);return}if(alternativePath!==null){edge.startDir=alternativeDir,edge.endDir=alternativeOppositeDir,edge.path=mergePath(alternativePath);return}edge.startDir=preferredDir,edge.endDir=preferredOppositeDir,edge.path=[prefFrom,prefTo]}function determineLabelLine(graph,edge){if(edge.text.length===0)return;let lenLabel=edge.text.length,pathLen=edge.path.length,isVerticalFlow=graph.config.graphDirection==="TD",segments=[];for(let i=1;i<pathLen;i++){let p1=edge.path[i-1],p2=edge.path[i],line=[p1,p2],width=calculateLineWidth(graph,line),isVertical=p1.x===p2.x;segments.push({line,width,index:i,isVertical})}let suitableSegments=segments.filter(s=>s.width>=lenLabel&&s.index>1),largestLine;if(suitableSegments.length>0)suitableSegments.sort((a,b)=>b.index-a.index),largestLine=suitableSegments[0].line;else{let fallbackSegments=segments.filter(s=>s.width>=lenLabel);fallbackSegments.length>0?(fallbackSegments.sort((a,b)=>b.index-a.index),largestLine=fallbackSegments[0].line):(segments.sort((a,b)=>b.width-a.width),largestLine=segments[0]?.line??[edge.path[0],edge.path[1]])}let minX=Math.min(largestLine[0].x,largestLine[1].x),maxX=Math.max(largestLine[0].x,largestLine[1].x),middleX=minX+Math.floor((maxX-minX)/2),current=graph.columnWidth.get(middleX)??0;graph.columnWidth.set(middleX,Math.max(current,lenLabel+2)),edge.labelLine=[largestLine[0],largestLine[1]]}function calculateLineWidth(graph,line){let total=0,startX=Math.min(line[0].x,line[1].x),endX=Math.max(line[0].x,line[1].x);for(let x=startX;x<=endX;x++)total+=graph.columnWidth.get(x)??0;return total}function analyzeEdgeBundles(graph){if(graph.config.graphDirection!=="TD")return[];let bundles=[],bundledEdges=new Set,edgesByTarget=new Map;for(let edge of graph.edges){if(edge.from===edge.to)continue;let existing=edgesByTarget.get(edge.to)??[];existing.push(edge),edgesByTarget.set(edge.to,existing)}for(let[target,edges]of edgesByTarget){if(edges.length<2||!canBundle(edges,graph)||edges.some(e=>bundledEdges.has(e)))continue;let bundle={type:"fan-in",edges:[...edges],sharedNode:target,otherNodes:edges.map(e=>e.from),junctionPoint:null,sharedPath:[],junctionDir:Middle,sharedNodeDir:Middle};for(let edge of edges)edge.bundle=bundle,bundledEdges.add(edge);bundles.push(bundle)}let edgesBySource=new Map;for(let edge of graph.edges){if(edge.from===edge.to||bundledEdges.has(edge))continue;let existing=edgesBySource.get(edge.from)??[];existing.push(edge),edgesBySource.set(edge.from,existing)}for(let[source,edges]of edgesBySource){if(edges.length<2||!canBundle(edges,graph))continue;let bundle={type:"fan-out",edges:[...edges],sharedNode:source,otherNodes:edges.map(e=>e.to),junctionPoint:null,sharedPath:[],junctionDir:Middle,sharedNodeDir:Middle};for(let edge of edges)edge.bundle=bundle,bundledEdges.add(edge);bundles.push(bundle)}return bundles}function canBundle(edges,graph){if(edges.length<2)return!1;let firstStyle=edges[0].style,firstFromSg=getNodeSubgraph(graph,edges[0].from),firstToSg=getNodeSubgraph(graph,edges[0].to);for(let edge of edges){if(edge.style!==firstStyle||edge.text.length>0)return!1;let fromSg=getNodeSubgraph(graph,edge.from),toSg=getNodeSubgraph(graph,edge.to);if(fromSg!==firstFromSg||toSg!==firstToSg||fromSg!==toSg)return!1}return!0}function calculateJunctionPoint(graph,bundle){let dir=graph.config.graphDirection,sharedCoord=bundle.sharedNode.gridCoord,otherCoords=bundle.otherNodes.map(n=>n.gridCoord);if(bundle.type==="fan-in"){let minX=Math.min(...otherCoords.map(c=>c.x)),maxX=Math.max(...otherCoords.map(c=>c.x)),minY=Math.min(...otherCoords.map(c=>c.y)),maxY=Math.max(...otherCoords.map(c=>c.y));if(dir==="TD"){let junctionY=sharedCoord.y-1,centerX=Math.floor((minX+maxX)/2)+1;return{x:sharedCoord.x+1,y:junctionY}}else{let junctionX=sharedCoord.x-1,junctionY=sharedCoord.y+1;return{x:junctionX,y:junctionY}}}else{let minX=Math.min(...otherCoords.map(c=>c.x)),maxX=Math.max(...otherCoords.map(c=>c.x)),minY=Math.min(...otherCoords.map(c=>c.y)),maxY=Math.max(...otherCoords.map(c=>c.y));if(dir==="TD"){let junctionY=sharedCoord.y+3;return{x:sharedCoord.x+1,y:junctionY}}else{let junctionX=sharedCoord.x+3,junctionY=sharedCoord.y+1;return{x:junctionX,y:junctionY}}}}function routeBundledEdges(graph,bundle){let dir=graph.config.graphDirection;bundle.junctionPoint=calculateJunctionPoint(graph,bundle);let junction=bundle.junctionPoint;if(bundle.type==="fan-in"){bundle.junctionDir=dir==="TD"?Up:Left,bundle.sharedNodeDir=dir==="TD"?Down:Right;let targetCoord=bundle.sharedNode.gridCoord,targetEntry=dir==="TD"?{x:targetCoord.x+1,y:targetCoord.y}:{x:targetCoord.x,y:targetCoord.y+1},sharedPath=getPath(graph.grid,junction,targetEntry);bundle.sharedPath=sharedPath?mergePath(sharedPath):[junction,targetEntry];for(let edge of bundle.edges){let sourceCoord=edge.from.gridCoord,sourceExit=dir==="TD"?{x:sourceCoord.x+1,y:sourceCoord.y+2}:{x:sourceCoord.x+2,y:sourceCoord.y+1},pathToJunction=getPath(graph.grid,sourceExit,junction);edge.pathToJunction=pathToJunction?mergePath(pathToJunction):[sourceExit,junction],edge.startDir=dir==="TD"?Down:Right,edge.endDir=dir==="TD"?Up:Left,edge.path=[...edge.pathToJunction,...bundle.sharedPath.slice(1)]}}else{bundle.junctionDir=dir==="TD"?Down:Right,bundle.sharedNodeDir=dir==="TD"?Up:Left;let sourceCoord=bundle.sharedNode.gridCoord,sourceExit=dir==="TD"?{x:sourceCoord.x+1,y:sourceCoord.y+2}:{x:sourceCoord.x+2,y:sourceCoord.y+1},sharedPath=getPath(graph.grid,sourceExit,junction);bundle.sharedPath=sharedPath?mergePath(sharedPath):[sourceExit,junction];for(let edge of bundle.edges){let targetCoord=edge.to.gridCoord,targetEntry=dir==="TD"?{x:targetCoord.x+1,y:targetCoord.y}:{x:targetCoord.x,y:targetCoord.y+1},pathToJunction=getPath(graph.grid,junction,targetEntry);edge.pathToJunction=pathToJunction?mergePath(pathToJunction):[junction,targetEntry],edge.startDir=dir==="TD"?Down:Right,edge.endDir=dir==="TD"?Up:Left,edge.path=[...bundle.sharedPath,...edge.pathToJunction.slice(1)]}}}function processBundles(graph){for(let bundle of graph.bundles)routeBundledEdges(graph,bundle)}function splitLines(label){return label.split(`
6`)}function maxLineWidth(label){let lines=splitLines(label);return Math.max(...lines.map(l=>l.length),0)}function lineCount(label){return splitLines(label).length}var SHAPE_CORNERS={rectangle:{unicode:{tl:"\u250C",tr:"\u2510",bl:"\u2514",br:"\u2518"},ascii:{tl:"+",tr:"+",bl:"+",br:"+"}},rounded:{unicode:{tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F"},ascii:{tl:".",tr:".",bl:"'",br:"'"}},circle:{unicode:{tl:"\u25EF",tr:"\u25EF",bl:"\u25EF",br:"\u25EF"},ascii:{tl:"o",tr:"o",bl:"o",br:"o"}},doublecircle:{unicode:{tl:"\u25CE",tr:"\u25CE",bl:"\u25CE",br:"\u25CE"},ascii:{tl:"@",tr:"@",bl:"@",br:"@"}},diamond:{unicode:{tl:"\u25C7",tr:"\u25C7",bl:"\u25C7",br:"\u25C7"},ascii:{tl:"<",tr:">",bl:"<",br:">"}},hexagon:{unicode:{tl:"\u231C",tr:"\u231D",bl:"\u231E",br:"\u231F"},ascii:{tl:"*",tr:"*",bl:"*",br:"*"}},stadium:{unicode:{tl:"(",tr:")",bl:"(",br:")"},ascii:{tl:"(",tr:")",bl:"(",br:")"}},subroutine:{unicode:{tl:"\u255F",tr:"\u2562",bl:"\u255F",br:"\u2562"},ascii:{tl:"|",tr:"|",bl:"|",br:"|"}},cylinder:{unicode:{tl:"\u256D",tr:"\u256E",bl:"\u2570",br:"\u256F"},ascii:{tl:".",tr:".",bl:"'",br:"'"}},asymmetric:{unicode:{tl:"\u25B7",tr:"\u2510",bl:"\u25B7",br:"\u2518"},ascii:{tl:">",tr:"+",bl:">",br:"+"}},trapezoid:{unicode:{tl:"/",tr:"\\",bl:"\u2514",br:"\u2518"},ascii:{tl:"/",tr:"\\",bl:"+",br:"+"}},"trapezoid-alt":{unicode:{tl:"\u250C",tr:"\u2510",bl:"\\",br:"/"},ascii:{tl:"+",tr:"+",bl:"\\",br:"/"}},"state-start":{unicode:{tl:"\u25CF",tr:"\u25CF",bl:"\u25CF",br:"\u25CF"},ascii:{tl:"*",tr:"*",bl:"*",br:"*"}},"state-end":{unicode:{tl:"\u25C9",tr:"\u25C9",bl:"\u25C9",br:"\u25C9"},ascii:{tl:"@",tr:"@",bl:"@",br:"@"}}};function getCorners(shape,useAscii){let corners=SHAPE_CORNERS[shape]??SHAPE_CORNERS.rectangle;return useAscii?corners.ascii:corners.unicode}function getBoxDimensions(label,options){let lines=splitLines(label),maxLineWidth2=Math.max(...lines.map(l=>l.length),0),lineCount2=lines.length,innerWidth=2*options.padding+maxLineWidth2,width=innerWidth+2,rawInnerHeight=lineCount2+2*options.padding,innerHeight=rawInnerHeight%2===0?rawInnerHeight+1:rawInnerHeight,height=innerHeight+2;return{width,height,labelArea:{x:1+options.padding,y:1+options.padding,width:maxLineWidth2,height:lineCount2},gridColumns:[1,innerWidth,1],gridRows:[1,innerHeight,1]}}function renderBox(label,dimensions,corners,useAscii){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),from={x:0,y:0},to={x:width-1,y:height-1},hLine=useAscii?"-":"\u2500",vLine=useAscii?"|":"\u2502";for(let x=from.x+1;x<to.x;x++)canvas[x][from.y]=hLine,canvas[x][to.y]=hLine;for(let y=from.y+1;y<to.y;y++)canvas[from.x][y]=vLine,canvas[to.x][y]=vLine;canvas[from.x][from.y]=corners.tl,canvas[to.x][from.y]=corners.tr,canvas[from.x][to.y]=corners.bl,canvas[to.x][to.y]=corners.br;let lines=splitLines(label),w=width-1,h=height-1,startY=Math.floor(h/2)-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let line=lines[i],textX=Math.floor(w/2)-Math.ceil(line.length/2)+1;for(let j=0;j<line.length;j++){let x=textX+j,y=startY+i;x>=0&&x<canvas.length&&y>=0&&y<canvas[0].length&&(canvas[x][y]=line[j])}}return canvas}function getBoxAttachmentPoint(dir,dimensions,baseCoord){let{width,height}=dimensions,centerX=baseCoord.x+Math.floor(width/2),centerY=baseCoord.y+Math.floor(height/2);return dirEquals(dir,Up)?{x:centerX,y:baseCoord.y}:dirEquals(dir,Down)?{x:centerX,y:baseCoord.y+height-1}:dirEquals(dir,Left)?{x:baseCoord.x,y:centerY}:dirEquals(dir,Right)?{x:baseCoord.x+width-1,y:centerY}:dirEquals(dir,UpperLeft)?{x:baseCoord.x,y:baseCoord.y}:dirEquals(dir,UpperRight)?{x:baseCoord.x+width-1,y:baseCoord.y}:dirEquals(dir,LowerLeft)?{x:baseCoord.x,y:baseCoord.y+height-1}:dirEquals(dir,LowerRight)?{x:baseCoord.x+width-1,y:baseCoord.y+height-1}:{x:centerX,y:centerY}}var rectangleRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("rectangle",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var diamondRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("diamond",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var circleRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("circle",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var stateStartRenderer={getDimensions(_label,_options){return{width:5,height:3,labelArea:{x:2,y:1,width:1,height:1},gridColumns:[1,3,1],gridRows:[1,1,1]}},render(_label,dimensions,options){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),centerX=Math.floor(width/2);return options.useAscii?(canvas[0][0]=".",canvas[1][0]="-",canvas[2][0]="-",canvas[3][0]="-",canvas[4][0]=".",canvas[0][1]="|",canvas[centerX][1]="*",canvas[4][1]="|",canvas[0][2]="'",canvas[1][2]="-",canvas[2][2]="-",canvas[3][2]="-",canvas[4][2]="'"):(canvas[0][0]="\u256D",canvas[1][0]="\u2500",canvas[2][0]="\u2500",canvas[3][0]="\u2500",canvas[4][0]="\u256E",canvas[0][1]="\u2502",canvas[centerX][1]="\u25CF",canvas[4][1]="\u2502",canvas[0][2]="\u2570",canvas[1][2]="\u2500",canvas[2][2]="\u2500",canvas[3][2]="\u2500",canvas[4][2]="\u256F"),canvas},getAttachmentPoint(dir,dimensions,baseCoord){let{width,height}=dimensions,centerX=baseCoord.x+Math.floor(width/2),centerY=baseCoord.y+Math.floor(height/2);return dirEquals(dir,Up)?{x:centerX,y:baseCoord.y}:dirEquals(dir,Down)?{x:centerX,y:baseCoord.y+height-1}:dirEquals(dir,Left)?{x:baseCoord.x,y:centerY}:dirEquals(dir,Right)?{x:baseCoord.x+width-1,y:centerY}:{x:centerX,y:centerY}}},stateEndRenderer={getDimensions(_label,_options){return{width:5,height:3,labelArea:{x:2,y:1,width:1,height:1},gridColumns:[1,3,1],gridRows:[1,1,1]}},render(_label,dimensions,options){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),centerX=Math.floor(width/2);return options.useAscii?(canvas[0][0]="#",canvas[1][0]="=",canvas[2][0]="=",canvas[3][0]="=",canvas[4][0]="#",canvas[0][1]="#",canvas[centerX][1]="*",canvas[4][1]="#",canvas[0][2]="#",canvas[1][2]="=",canvas[2][2]="=",canvas[3][2]="=",canvas[4][2]="#"):(canvas[0][0]="\u2554",canvas[1][0]="\u2550",canvas[2][0]="\u2550",canvas[3][0]="\u2550",canvas[4][0]="\u2557",canvas[0][1]="\u2551",canvas[centerX][1]="\u25CE",canvas[4][1]="\u2551",canvas[0][2]="\u255A",canvas[1][2]="\u2550",canvas[2][2]="\u2550",canvas[3][2]="\u2550",canvas[4][2]="\u255D"),canvas},getAttachmentPoint(dir,dimensions,baseCoord){let{width,height}=dimensions,centerX=baseCoord.x+Math.floor(width/2),centerY=baseCoord.y+Math.floor(height/2);return dirEquals(dir,Up)?{x:centerX,y:baseCoord.y}:dirEquals(dir,Down)?{x:centerX,y:baseCoord.y+height-1}:dirEquals(dir,Left)?{x:baseCoord.x,y:centerY}:dirEquals(dir,Right)?{x:baseCoord.x+width-1,y:centerY}:{x:centerX,y:centerY}}};var roundedRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("rounded",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var stadiumRenderer={getDimensions(label,options){let lines=splitLines(label),maxLineWidth2=Math.max(...lines.map(l=>l.length),0),lineCount2=lines.length,innerWidth=2*options.padding+maxLineWidth2,width=innerWidth+4,innerHeight=lineCount2+2*options.padding,height=Math.max(innerHeight+2,3);return{width,height,labelArea:{x:2+options.padding,y:1+options.padding,width:maxLineWidth2,height:lineCount2},gridColumns:[2,innerWidth,2],gridRows:[1,innerHeight,1]}},render(label,dimensions,options){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),centerY=Math.floor(height/2),hChar=options.useAscii?"-":"\u2500";if(height===3)canvas[0][centerY]="(",canvas[width-1][centerY]=")";else if(options.useAscii){for(let y=0;y<height;y++)canvas[0][y]="(",canvas[width-1][y]=")";for(let x=1;x<width-1;x++)canvas[x][0]=hChar,canvas[x][height-1]=hChar}else{canvas[0][0]="\u256D";for(let x=1;x<width-1;x++)canvas[x][0]=hChar;canvas[width-1][0]="\u256E";for(let y=1;y<height-1;y++)canvas[0][y]="\u2502",canvas[width-1][y]="\u2502";canvas[0][height-1]="\u2570";for(let x=1;x<width-1;x++)canvas[x][height-1]=hChar;canvas[width-1][height-1]="\u256F"}let lines=splitLines(label),startY=centerY-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let line=lines[i],textX=Math.floor(width/2)-Math.floor(line.length/2);for(let j=0;j<line.length;j++){let x=textX+j,y=startY+i;x>0&&x<width-1&&y>=0&&y<height&&(canvas[x][y]=line[j])}}return canvas},getAttachmentPoint:getBoxAttachmentPoint};var hexagonRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("hexagon",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var subroutineRenderer={getDimensions(label,options){let lines=splitLines(label),maxLineWidth2=Math.max(...lines.map(l=>l.length),0),lineCount2=lines.length,innerWidth=2*options.padding+maxLineWidth2,width=innerWidth+4,innerHeight=lineCount2+2*options.padding,height=innerHeight+2;return{width,height,labelArea:{x:2+options.padding,y:1+options.padding,width:maxLineWidth2,height:lineCount2},gridColumns:[2,innerWidth,2],gridRows:[1,innerHeight,1]}},render(label,dimensions,options){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),hChar=options.useAscii?"-":"\u2500",vChar=options.useAscii?"|":"\u2502";canvas[0][0]=options.useAscii?"+":"\u250C",canvas[1][0]=options.useAscii?"+":"\u252C";for(let x=2;x<width-2;x++)canvas[x][0]=hChar;canvas[width-2][0]=options.useAscii?"+":"\u252C",canvas[width-1][0]=options.useAscii?"+":"\u2510";for(let y=1;y<height-1;y++)canvas[0][y]=vChar,canvas[1][y]=vChar,canvas[width-2][y]=vChar,canvas[width-1][y]=vChar;canvas[0][height-1]=options.useAscii?"+":"\u2514",canvas[1][height-1]=options.useAscii?"+":"\u2534";for(let x=2;x<width-2;x++)canvas[x][height-1]=hChar;canvas[width-2][height-1]=options.useAscii?"+":"\u2534",canvas[width-1][height-1]=options.useAscii?"+":"\u2518";let lines=splitLines(label),startY=Math.floor(height/2)-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let line=lines[i],textX=Math.floor(width/2)-Math.floor(line.length/2);for(let j=0;j<line.length;j++){let x=textX+j,y=startY+i;x>1&&x<width-2&&y>0&&y<height-1&&(canvas[x][y]=line[j])}}return canvas},getAttachmentPoint:getBoxAttachmentPoint},doublecircleRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("doublecircle",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint},cylinderRenderer={getDimensions(label,options){let lines=splitLines(label),maxLineWidth2=Math.max(...lines.map(l=>l.length),0),lineCount2=lines.length,innerWidth=2*options.padding+maxLineWidth2,width=innerWidth+2,innerHeight=lineCount2+2*options.padding+2,height=innerHeight+2;return{width,height,labelArea:{x:1+options.padding,y:2+options.padding,width:maxLineWidth2,height:lineCount2},gridColumns:[1,innerWidth,1],gridRows:[2,innerHeight-2,2]}},render(label,dimensions,options){let{width,height}=dimensions,canvas=mkCanvas(width-1,height-1),hChar=options.useAscii?"-":"\u2500",vChar=options.useAscii?"|":"\u2502";canvas[0][0]=options.useAscii?".":"\u256D";for(let x=1;x<width-1;x++)canvas[x][0]=hChar;canvas[width-1][0]=options.useAscii?".":"\u256E",canvas[0][1]=vChar;for(let x=1;x<width-1;x++)canvas[x][1]=hChar;canvas[width-1][1]=vChar;for(let y=2;y<height-2;y++)canvas[0][y]=vChar,canvas[width-1][y]=vChar;canvas[0][height-2]=vChar;for(let x=1;x<width-1;x++)canvas[x][height-2]=hChar;canvas[width-1][height-2]=vChar,canvas[0][height-1]=options.useAscii?"'":"\u2570";for(let x=1;x<width-1;x++)canvas[x][height-1]=hChar;canvas[width-1][height-1]=options.useAscii?"'":"\u256F";let lines=splitLines(label),startY=Math.floor(height/2)-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let line=lines[i],textX=Math.floor(width/2)-Math.floor(line.length/2);for(let j=0;j<line.length;j++){let x=textX+j,y=startY+i;x>0&&x<width-1&&y>1&&y<height-2&&(canvas[x][y]=line[j])}}return canvas},getAttachmentPoint:getBoxAttachmentPoint},asymmetricRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("asymmetric",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint},trapezoidRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("trapezoid",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint},trapezoidAltRenderer={getDimensions:getBoxDimensions,render(label,dimensions,options){let corners=getCorners("trapezoid-alt",options.useAscii);return renderBox(label,dimensions,corners,options.useAscii)},getAttachmentPoint:getBoxAttachmentPoint};var shapeRegistry=new Map([["rectangle",rectangleRenderer],["rounded",roundedRenderer],["diamond",diamondRenderer],["stadium",stadiumRenderer],["circle",circleRenderer],["subroutine",subroutineRenderer],["doublecircle",doublecircleRenderer],["hexagon",hexagonRenderer],["cylinder",cylinderRenderer],["asymmetric",asymmetricRenderer],["trapezoid",trapezoidRenderer],["trapezoid-alt",trapezoidAltRenderer],["state-start",stateStartRenderer],["state-end",stateEndRenderer]]);function getShapeRenderer(shape){return shapeRegistry.get(shape)??rectangleRenderer}function getShapeDimensions(shape,label,options){return getShapeRenderer(shape).getDimensions(label,options)}function getShapeAttachmentPoint(shape,dir,dimensions,baseCoord){return getShapeRenderer(shape).getAttachmentPoint(dir,dimensions,baseCoord)}function drawNode(node,graph){return drawBoxWithGridDimensions(node,graph)}function drawBoxWithGridDimensions(node,graph){let gc=node.gridCoord,useAscii=graph.config.useAscii,w=0;for(let i=0;i<2;i++)w+=graph.columnWidth.get(gc.x+i)??0;let h=0;for(let i=0;i<2;i++)h+=graph.rowHeight.get(gc.y+i)??0;let from={x:0,y:0},to={x:w,y:h},box=mkCanvas(Math.max(from.x,to.x),Math.max(from.y,to.y)),corners=getCorners(node.shape,useAscii),isDoubleBox=node.shape==="state-end",hChar=useAscii?isDoubleBox?"=":"-":isDoubleBox?"\u2550":"\u2500",vChar=useAscii?isDoubleBox?"\u2016":"|":isDoubleBox?"\u2551":"\u2502",effectiveCorners=isDoubleBox?useAscii?{tl:"#",tr:"#",bl:"#",br:"#"}:{tl:"\u2554",tr:"\u2557",bl:"\u255A",br:"\u255D"}:corners;for(let x=from.x+1;x<to.x;x++)box[x][from.y]=hChar;for(let x=from.x+1;x<to.x;x++)box[x][to.y]=hChar;for(let y=from.y+1;y<to.y;y++)box[from.x][y]=vChar;for(let y=from.y+1;y<to.y;y++)box[to.x][y]=vChar;box[from.x][from.y]=effectiveCorners.tl,box[to.x][from.y]=effectiveCorners.tr,box[from.x][to.y]=effectiveCorners.bl,box[to.x][to.y]=effectiveCorners.br;let label=node.displayLabel,lines=splitLines(label),startY=from.y+Math.floor(h/2)-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let line=lines[i],textX=from.x+Math.floor(w/2)-Math.ceil(line.length/2)+1;for(let j=0;j<line.length;j++)textX+j>=0&&textX+j<box.length&&startY+i>=0&&startY+i<box[0].length&&(box[textX+j][startY+i]=line[j])}return box}function drawBox(node,graph){return drawNode(node,graph)}function drawMultiBox(sections,useAscii,padding=1){let maxTextWidth=0;for(let section of sections)for(let line of section)maxTextWidth=Math.max(maxTextWidth,line.length);let boxWidth=maxTextWidth+2*padding+2,totalLines=0;for(let section of sections)totalLines+=Math.max(section.length,1);let numDividers=sections.length-1,boxHeight=totalLines+numDividers+2,hLine=useAscii?"-":"\u2500",vLine=useAscii?"|":"\u2502",tl=useAscii?"+":"\u250C",tr=useAscii?"+":"\u2510",bl=useAscii?"+":"\u2514",br=useAscii?"+":"\u2518",divL=useAscii?"+":"\u251C",divR=useAscii?"+":"\u2524",canvas=mkCanvas(boxWidth-1,boxHeight-1);canvas[0][0]=tl;for(let x=1;x<boxWidth-1;x++)canvas[x][0]=hLine;canvas[boxWidth-1][0]=tr,canvas[0][boxHeight-1]=bl;for(let x=1;x<boxWidth-1;x++)canvas[x][boxHeight-1]=hLine;canvas[boxWidth-1][boxHeight-1]=br;for(let y=1;y<boxHeight-1;y++)canvas[0][y]=vLine,canvas[boxWidth-1][y]=vLine;let row=1;for(let s=0;s<sections.length;s++){let section=sections[s],lines=section.length>0?section:[""];for(let line of lines){let startX=1+padding;for(let i=0;i<line.length;i++)canvas[startX+i][row]=line[i];row++}if(s<sections.length-1){canvas[0][row]=divL;for(let x=1;x<boxWidth-1;x++)canvas[x][row]=hLine;canvas[boxWidth-1][row]=divR,row++}}return canvas}var LINE_CHARS={solid:{h:{unicode:"\u2500",ascii:"-"},v:{unicode:"\u2502",ascii:"|"}},dotted:{h:{unicode:"\u2504",ascii:"."},v:{unicode:"\u2506",ascii:":"}},thick:{h:{unicode:"\u2501",ascii:"="},v:{unicode:"\u2503",ascii:"\u2016"}}};function drawLine(canvas,from,to,offsetFrom,offsetTo,useAscii,style="solid"){let dir=determineDirection(from,to),drawnCoords=[],chars=LINE_CHARS[style],hChar=useAscii?chars.h.ascii:chars.h.unicode,vChar=useAscii?chars.v.ascii:chars.v.unicode;if(dirEquals(dir,Up))for(let y=from.y-offsetFrom;y>=to.y-offsetTo;y--)drawnCoords.push({x:from.x,y}),canvas[from.x][y]=vChar;else if(dirEquals(dir,Down))for(let y=from.y+offsetFrom;y<=to.y+offsetTo;y++)drawnCoords.push({x:from.x,y}),canvas[from.x][y]=vChar;else if(dirEquals(dir,Left))for(let x=from.x-offsetFrom;x>=to.x-offsetTo;x--)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;else if(dirEquals(dir,Right))for(let x=from.x+offsetFrom;x<=to.x+offsetTo;x++)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;else if(dirEquals(dir,UpperLeft)){for(let x=from.x-offsetFrom;x>=to.x;x--)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;for(let y=from.y-1;y>=to.y-offsetTo;y--)drawnCoords.push({x:to.x,y}),canvas[to.x][y]=vChar}else if(dirEquals(dir,UpperRight)){for(let x=from.x+offsetFrom;x<=to.x;x++)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;for(let y=from.y-1;y>=to.y-offsetTo;y--)drawnCoords.push({x:to.x,y}),canvas[to.x][y]=vChar}else if(dirEquals(dir,LowerLeft)){for(let x=from.x-offsetFrom;x>=to.x;x--)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;for(let y=from.y+1;y<=to.y+offsetTo;y++)drawnCoords.push({x:to.x,y}),canvas[to.x][y]=vChar}else if(dirEquals(dir,LowerRight))if(to.x-from.x<=1)for(let y=from.y+offsetFrom;y<=to.y+offsetTo;y++)drawnCoords.push({x:from.x,y}),canvas[from.x][y]=vChar;else{for(let x=from.x+offsetFrom;x<=to.x;x++)drawnCoords.push({x,y:from.y}),canvas[x][from.y]=hChar;for(let y=from.y+1;y<=to.y+offsetTo;y++)drawnCoords.push({x:to.x,y}),canvas[to.x][y]=vChar}return drawnCoords}function drawArrow(graph,edge){if(edge.path.length===0){let empty=copyCanvas(graph.canvas);return[empty,empty,empty,empty,empty,empty]}let labelCanvas=drawArrowLabel(graph,edge),[pathCanvas,linesDrawn,lineDirs]=drawPath(graph,edge.path,edge.style),boxStartCanvas=drawBoxStart(graph,edge.path,linesDrawn[0],edge.from.shape),arrowHeadEndCanvas;edge.hasArrowEnd?arrowHeadEndCanvas=drawArrowHead(graph,linesDrawn[linesDrawn.length-1],lineDirs[lineDirs.length-1]):arrowHeadEndCanvas=copyCanvas(graph.canvas);let arrowHeadStartCanvas;if(edge.hasArrowStart&&linesDrawn.length>0){let firstPoint=linesDrawn[0][0],startDir=reverseDirection(lineDirs[0]),arrowPos={x:firstPoint.x,y:firstPoint.y};dirEquals(lineDirs[0],Right)?arrowPos.x=firstPoint.x-1:dirEquals(lineDirs[0],Left)?arrowPos.x=firstPoint.x+1:dirEquals(lineDirs[0],Down)?arrowPos.y=firstPoint.y-1:dirEquals(lineDirs[0],Up)&&(arrowPos.y=firstPoint.y+1),arrowHeadStartCanvas=drawArrowHead(graph,[firstPoint,arrowPos],startDir)}else arrowHeadStartCanvas=copyCanvas(graph.canvas);let cornersCanvas=drawCorners(graph,edge.path);return[pathCanvas,boxStartCanvas,arrowHeadEndCanvas,arrowHeadStartCanvas,cornersCanvas,labelCanvas]}function reverseDirection(dir){return dirEquals(dir,Up)?Down:dirEquals(dir,Down)?Up:dirEquals(dir,Left)?Right:dirEquals(dir,Right)?Left:dirEquals(dir,UpperLeft)?LowerRight:dirEquals(dir,UpperRight)?LowerLeft:dirEquals(dir,LowerLeft)?UpperRight:dirEquals(dir,LowerRight)?UpperLeft:Middle}function drawPath(graph,path,style="solid"){let canvas=copyCanvas(graph.canvas),previousCoord=path[0],linesDrawn=[],lineDirs=[];for(let i=1;i<path.length;i++){let nextCoord=path[i],prevDC=gridToDrawingCoord(graph,previousCoord),nextDC=gridToDrawingCoord(graph,nextCoord);if(drawingCoordEquals(prevDC,nextDC)){previousCoord=nextCoord;continue}let dir=determineDirection(previousCoord,nextCoord),segment=drawLine(canvas,prevDC,nextDC,1,-1,graph.config.useAscii,style);segment.length===0&&segment.push(prevDC),linesDrawn.push(segment),lineDirs.push(dir),previousCoord=nextCoord}return[canvas,linesDrawn,lineDirs]}function drawBoxStart(graph,path,firstLine,sourceShape){let canvas=copyCanvas(graph.canvas);if(graph.config.useAscii||sourceShape==="state-start"||sourceShape==="state-end")return canvas;let from=firstLine[0],dir=determineDirection(path[0],path[1]);return dirEquals(dir,Up)?canvas[from.x][from.y+1]="\u2534":dirEquals(dir,Down)?canvas[from.x][from.y-1]="\u252C":dirEquals(dir,Left)?canvas[from.x+1][from.y]="\u2524":dirEquals(dir,Right)&&(canvas[from.x-1][from.y]="\u251C"),canvas}function drawArrowHead(graph,lastLine,fallbackDir){let canvas=copyCanvas(graph.canvas);if(lastLine.length===0)return canvas;let from=lastLine[0],lastPos=lastLine[lastLine.length-1],dir=determineDirection(from,lastPos);(lastLine.length===1||dirEquals(dir,Middle))&&(dir=fallbackDir);let char;return graph.config.useAscii?dirEquals(dir,Up)?char="^":dirEquals(dir,Down)?char="v":dirEquals(dir,Left)?char="<":dirEquals(dir,Right)?char=">":dirEquals(fallbackDir,Up)?char="^":dirEquals(fallbackDir,Down)?char="v":dirEquals(fallbackDir,Left)?char="<":dirEquals(fallbackDir,Right)?char=">":char="*":dirEquals(dir,Up)?char="\u25B2":dirEquals(dir,Down)?char="\u25BC":dirEquals(dir,Left)?char="\u25C4":dirEquals(dir,Right)?char="\u25BA":dirEquals(dir,UpperRight)?char="\u25E5":dirEquals(dir,UpperLeft)?char="\u25E4":dirEquals(dir,LowerRight)?char="\u25E2":dirEquals(dir,LowerLeft)?char="\u25E3":dirEquals(fallbackDir,Up)?char="\u25B2":dirEquals(fallbackDir,Down)?char="\u25BC":dirEquals(fallbackDir,Left)?char="\u25C4":dirEquals(fallbackDir,Right)?char="\u25BA":dirEquals(fallbackDir,UpperRight)?char="\u25E5":dirEquals(fallbackDir,UpperLeft)?char="\u25E4":dirEquals(fallbackDir,LowerRight)?char="\u25E2":dirEquals(fallbackDir,LowerLeft)?char="\u25E3":char="\u25CF",canvas[lastPos.x][lastPos.y]=char,canvas}function drawCorners(graph,path){let canvas=copyCanvas(graph.canvas);for(let idx=1;idx<path.length-1;idx++){let coord=path[idx],dc=gridToDrawingCoord(graph,coord),prevDir=determineDirection(path[idx-1],coord),nextDir=determineDirection(coord,path[idx+1]),corner;graph.config.useAscii?corner="+":dirEquals(prevDir,Right)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Left)?corner="\u2510":dirEquals(prevDir,Right)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Left)?corner="\u2518":dirEquals(prevDir,Left)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Right)?corner="\u250C":dirEquals(prevDir,Left)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Right)?corner="\u2514":corner="+",canvas[dc.x][dc.y]=corner}return canvas}function drawArrowLabel(graph,edge){let canvas=copyCanvas(graph.canvas);if(edge.text.length===0)return canvas;let drawingLine=lineToDrawing(graph,edge.labelLine),isUpwardEdge;if(edge.path.length>=2){let startY=edge.path[0].y,endY=edge.path[edge.path.length-1].y;endY<startY?isUpwardEdge=!0:endY>startY&&(isUpwardEdge=!1)}return drawTextOnLine(canvas,drawingLine,edge.text,isUpwardEdge),canvas}function drawTextOnLine(canvas,line,label,isUpwardEdge){if(line.length<2)return;let minX=Math.min(line[0].x,line[1].x),maxX=Math.max(line[0].x,line[1].x),minY=Math.min(line[0].y,line[1].y),maxY=Math.max(line[0].y,line[1].y),middleX=minX+Math.floor((maxX-minX)/2),middleY=minY+Math.floor((maxY-minY)/2);if(isUpwardEdge!==void 0&&minX===maxX){let segmentHeight=maxY-minY,offset=Math.max(1,Math.floor(segmentHeight/4));isUpwardEdge?middleY=middleY+offset:middleY=middleY-offset}let lines=splitLines(label),startY=middleY-Math.floor((lines.length-1)/2);for(let i=0;i<lines.length;i++){let lineText=lines[i],startX=middleX-Math.floor(lineText.length/2);drawText(canvas,{x:startX,y:startY+i},lineText)}}function getNodeAttachmentPoint(graph,node,dir){let gc=node.gridCoord,w=0;for(let i=0;i<2;i++)w+=graph.columnWidth.get(gc.x+i)??0;let h=0;for(let i=0;i<2;i++)h+=graph.rowHeight.get(gc.y+i)??0;let gridDimensions={width:w+1,height:h+1,labelArea:{x:0,y:0,width:0,height:0},gridColumns:[0,0,0],gridRows:[0,0,0]},baseCoord=node.drawingCoord;return getShapeAttachmentPoint(node.shape,dir,gridDimensions,baseCoord)}function drawBundledEdgeSegment(graph,edge,bundle){let empty=copyCanvas(graph.canvas);if(!edge.pathToJunction||edge.pathToJunction.length===0)return[empty,empty,empty,empty,empty,empty];let pathCanvas=copyCanvas(graph.canvas),useAscii=graph.config.useAscii,drawingPath=edge.pathToJunction.map((gc,idx)=>bundle.type==="fan-in"&&idx===0?getNodeAttachmentPoint(graph,edge.from,edge.startDir):bundle.type==="fan-out"&&idx===edge.pathToJunction.length-1?getNodeAttachmentPoint(graph,edge.to,edge.endDir):gridToDrawingCoord(graph,gc));for(let i=1;i<drawingPath.length;i++){let from=drawingPath[i-1],to=drawingPath[i];drawingCoordEquals(from,to)||drawLine(pathCanvas,from,to,1,-1,useAscii,edge.style)}let cornersCanvas=copyCanvas(graph.canvas);for(let idx=1;idx<edge.pathToJunction.length-1;idx++){let coord=edge.pathToJunction[idx],dc=gridToDrawingCoord(graph,coord),prevDir=determineDirection(edge.pathToJunction[idx-1],coord),nextDir=determineDirection(coord,edge.pathToJunction[idx+1]),corner;useAscii?corner="+":dirEquals(prevDir,Right)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Left)?corner="\u2510":dirEquals(prevDir,Right)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Left)?corner="\u2518":dirEquals(prevDir,Left)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Right)?corner="\u250C":dirEquals(prevDir,Left)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Right)?corner="\u2514":corner="+",cornersCanvas[dc.x][dc.y]=corner}let boxStartCanvas=copyCanvas(graph.canvas);if(bundle.type==="fan-in"&&edge.pathToJunction.length>=2){let firstPoint=drawingPath[0],dir=determineDirection(edge.pathToJunction[0],edge.pathToJunction[1]);useAscii||(dirEquals(dir,Up)?boxStartCanvas[firstPoint.x][firstPoint.y]="\u2534":dirEquals(dir,Down)?boxStartCanvas[firstPoint.x][firstPoint.y]="\u252C":dirEquals(dir,Left)?boxStartCanvas[firstPoint.x][firstPoint.y]="\u2524":dirEquals(dir,Right)&&(boxStartCanvas[firstPoint.x][firstPoint.y]="\u251C"))}let labelCanvas=copyCanvas(graph.canvas);return[pathCanvas,boxStartCanvas,empty,empty,cornersCanvas,labelCanvas]}function drawBundleSharedPath(graph,bundle){let pathCanvas=copyCanvas(graph.canvas),cornersCanvas=copyCanvas(graph.canvas);if(bundle.sharedPath.length<2)return[pathCanvas,cornersCanvas];let useAscii=graph.config.useAscii,style=bundle.edges[0]?.style??"solid",graphDir=graph.config.graphDirection,drawingPath=bundle.sharedPath.map((gc,idx)=>{if(bundle.type==="fan-in"&&idx===bundle.sharedPath.length-1){let entryDir=graphDir==="TD"?Up:Left;return getNodeAttachmentPoint(graph,bundle.sharedNode,entryDir)}if(bundle.type==="fan-out"&&idx===0){let exitDir=graphDir==="TD"?Down:Right;return getNodeAttachmentPoint(graph,bundle.sharedNode,exitDir)}return gridToDrawingCoord(graph,gc)});for(let i=1;i<drawingPath.length;i++){let from=drawingPath[i-1],to=drawingPath[i];drawingCoordEquals(from,to)||drawLine(pathCanvas,from,to,1,-1,useAscii,style)}for(let idx=1;idx<bundle.sharedPath.length-1;idx++){let coord=bundle.sharedPath[idx],dc=gridToDrawingCoord(graph,coord),prevDir=determineDirection(bundle.sharedPath[idx-1],coord),nextDir=determineDirection(coord,bundle.sharedPath[idx+1]),corner;useAscii?corner="+":dirEquals(prevDir,Right)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Left)?corner="\u2510":dirEquals(prevDir,Right)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Left)?corner="\u2518":dirEquals(prevDir,Left)&&dirEquals(nextDir,Down)||dirEquals(prevDir,Up)&&dirEquals(nextDir,Right)?corner="\u250C":dirEquals(prevDir,Left)&&dirEquals(nextDir,Up)||dirEquals(prevDir,Down)&&dirEquals(nextDir,Right)?corner="\u2514":corner="+",cornersCanvas[dc.x][dc.y]=corner}return[pathCanvas,cornersCanvas]}function drawBundleArrowhead(graph,bundle){let canvas=copyCanvas(graph.canvas);if(bundle.sharedPath.length<2)return canvas;let lastIdx=bundle.sharedPath.length-1,secondLast=bundle.sharedPath[lastIdx-1],last=bundle.sharedPath[lastIdx],dir=determineDirection(secondLast,last),graphDir=graph.config.graphDirection,entryDir=graphDir==="TD"?Up:Left,dc=getNodeAttachmentPoint(graph,bundle.sharedNode,entryDir);graphDir==="TD"?dc.y-=1:dc.x-=1;let char;return graph.config.useAscii?dirEquals(dir,Up)?char="^":dirEquals(dir,Down)?char="v":dirEquals(dir,Left)?char="<":dirEquals(dir,Right)?char=">":char="v":dirEquals(dir,Up)?char="\u25B2":dirEquals(dir,Down)?char="\u25BC":dirEquals(dir,Left)?char="\u25C4":dirEquals(dir,Right)?char="\u25BA":char="\u25BC",canvas[dc.x][dc.y]=char,canvas}function drawBundledEdgeArrowhead(graph,edge){let canvas=copyCanvas(graph.canvas);if(!edge.pathToJunction||edge.pathToJunction.length<2)return canvas;let lastIdx=edge.pathToJunction.length-1,secondLast=edge.pathToJunction[lastIdx-1],last=edge.pathToJunction[lastIdx],dir=determineDirection(secondLast,last),graphDir=graph.config.graphDirection,entryDir=graphDir==="TD"?Up:Left,dc=getNodeAttachmentPoint(graph,edge.to,entryDir);graphDir==="TD"?dc.y-=1:dc.x-=1;let char;return graph.config.useAscii?dirEquals(dir,Up)?char="^":dirEquals(dir,Down)?char="v":dirEquals(dir,Left)?char="<":dirEquals(dir,Right)?char=">":char="v":dirEquals(dir,Up)?char="\u25B2":dirEquals(dir,Down)?char="\u25BC":dirEquals(dir,Left)?char="\u25C4":dirEquals(dir,Right)?char="\u25BA":char="\u25BC",canvas[dc.x][dc.y]=char,canvas}function drawJunctionCharacter(graph,bundle){let canvas=copyCanvas(graph.canvas);if(!bundle.junctionPoint)return canvas;let dc=gridToDrawingCoord(graph,bundle.junctionPoint),useAscii=graph.config.useAscii,hasUp=!1,hasDown=!1,hasLeft=!1,hasRight=!1;if(bundle.sharedPath.length>=2){let junctionIdx=bundle.type==="fan-in"?0:bundle.sharedPath.length-1,adjacentIdx=bundle.type==="fan-in"?1:bundle.sharedPath.length-2,sharedDir=determineDirection(bundle.sharedPath[junctionIdx],bundle.sharedPath[adjacentIdx]);dirEquals(sharedDir,Down)?hasDown=!0:dirEquals(sharedDir,Up)?hasUp=!0:dirEquals(sharedDir,Right)?hasRight=!0:dirEquals(sharedDir,Left)&&(hasLeft=!0)}for(let edge of bundle.edges)if(edge.pathToJunction&&edge.pathToJunction.length>=2){let junctionIdx=bundle.type==="fan-in"?edge.pathToJunction.length-1:0,adjacentIdx=bundle.type==="fan-in"?edge.pathToJunction.length-2:1,arrivalDir=determineDirection(edge.pathToJunction[adjacentIdx],edge.pathToJunction[junctionIdx]);dirEquals(arrivalDir,Down)?hasUp=!0:dirEquals(arrivalDir,Up)?hasDown=!0:dirEquals(arrivalDir,Right)?hasLeft=!0:dirEquals(arrivalDir,Left)&&(hasRight=!0)}let char;return useAscii?char="+":hasUp&&hasDown&&hasLeft&&hasRight?char="\u253C":hasDown&&hasLeft&&hasRight&&!hasUp?char="\u252C":hasUp&&hasLeft&&hasRight&&!hasDown?char="\u2534":hasUp&&hasDown&&hasRight&&!hasLeft?char="\u251C":hasUp&&hasDown&&hasLeft&&!hasRight?char="\u2524":hasLeft&&hasRight?char="\u2500":hasUp&&hasDown?char="\u2502":hasDown&&hasRight?char="\u250C":hasDown&&hasLeft?char="\u2510":hasUp&&hasRight?char="\u2514":hasUp&&hasLeft?char="\u2518":char="\u253C",canvas[dc.x][dc.y]=char,canvas}function drawSubgraphBox(sg,graph){let width=sg.maxX-sg.minX,height=sg.maxY-sg.minY;if(width<=0||height<=0)return mkCanvas(0,0);let from={x:0,y:0},to={x:width,y:height},canvas=mkCanvas(width,height);if(graph.config.useAscii){for(let x=from.x+1;x<to.x;x++)canvas[x][from.y]="-";for(let x=from.x+1;x<to.x;x++)canvas[x][to.y]="-";for(let y=from.y+1;y<to.y;y++)canvas[from.x][y]="|";for(let y=from.y+1;y<to.y;y++)canvas[to.x][y]="|";canvas[from.x][from.y]="+",canvas[to.x][from.y]="+",canvas[from.x][to.y]="+",canvas[to.x][to.y]="+"}else{for(let x=from.x+1;x<to.x;x++)canvas[x][from.y]="\u2500";for(let x=from.x+1;x<to.x;x++)canvas[x][to.y]="\u2500";for(let y=from.y+1;y<to.y;y++)canvas[from.x][y]="\u2502";for(let y=from.y+1;y<to.y;y++)canvas[to.x][y]="\u2502";canvas[from.x][from.y]="\u250C",canvas[to.x][from.y]="\u2510",canvas[from.x][to.y]="\u2514",canvas[to.x][to.y]="\u2518"}return canvas}function drawSubgraphLabel(sg,graph){let width=sg.maxX-sg.minX,height=sg.maxY-sg.minY;if(width<=0||height<=0)return[mkCanvas(0,0),{x:0,y:0}];let canvas=mkCanvas(width,height),lines=splitLines(sg.name);for(let i=0;i<lines.length;i++){let line=lines[i],labelY=1+i,labelX=Math.floor(width/2)-Math.floor(line.length/2);labelX<1&&(labelX=1);for(let j=0;j<line.length;j++)labelX+j<width&&labelY<height&&(canvas[labelX+j][labelY]=line[j])}return[canvas,{x:sg.minX,y:sg.minY}]}function sortSubgraphsByDepth(subgraphs){function getDepth(sg){return sg.parent===null?0:1+getDepth(sg.parent)}let sorted=[...subgraphs];return sorted.sort((a,b)=>getDepth(a)-getDepth(b)),sorted}function fillRolesFromCanvas(roleCanvas,canvas,offset,role){for(let x=0;x<canvas.length;x++)for(let y=0;y<(canvas[0]?.length??0);y++){let char=canvas[x]?.[y];if(char&&char!==" "){let rx=x+offset.x,ry=y+offset.y;rx>=0&&ry>=0&&setRole(roleCanvas,rx,ry,role)}}}function fillRolesFromCanvases(roleCanvas,canvases,offset,role){for(let canvas of canvases)fillRolesFromCanvas(roleCanvas,canvas,offset,role)}function fillRolesForNodeBox(roleCanvas,canvas,offset){let isBorderChar=c=>/^[┌┐└┘├┤┬┴┼│─╭╮╰╯+\-|.':]$/.test(c);for(let x=0;x<canvas.length;x++)for(let y=0;y<(canvas[0]?.length??0);y++){let char=canvas[x]?.[y];if(char&&char!==" "){let rx=x+offset.x,ry=y+offset.y;rx>=0&&ry>=0&&setRole(roleCanvas,rx,ry,isBorderChar(char)?"border":"text")}}}function drawGraph(graph){let useAscii=graph.config.useAscii,zero={x:0,y:0},sortedSgs=sortSubgraphsByDepth(graph.subgraphs);for(let sg of sortedSgs){let sgCanvas=drawSubgraphBox(sg,graph),offset={x:sg.minX,y:sg.minY};graph.canvas=mergeCanvases(graph.canvas,offset,useAscii,sgCanvas),fillRolesFromCanvas(graph.roleCanvas,sgCanvas,offset,"border")}for(let node of graph.nodes)!node.drawn&&node.drawingCoord&&node.drawing&&(graph.canvas=mergeCanvases(graph.canvas,node.drawingCoord,useAscii,node.drawing),fillRolesForNodeBox(graph.roleCanvas,node.drawing,node.drawingCoord),node.drawn=!0);let lineCanvases=[],cornerCanvases=[],arrowHeadEndCanvases=[],arrowHeadStartCanvases=[],boxStartCanvases=[],labelCanvases=[],junctionCanvases=[],processedBundles=new Set;for(let edge of graph.edges)if(edge.bundle&&edge.pathToJunction){let bundle=edge.bundle,[pathC,boxStartC,,,cornersC,labelC]=drawBundledEdgeSegment(graph,edge,bundle);if(lineCanvases.push(pathC),cornerCanvases.push(cornersC),boxStartCanvases.push(boxStartC),labelCanvases.push(labelC),!processedBundles.has(bundle)){processedBundles.add(bundle);let[sharedPathC,sharedCornersC]=drawBundleSharedPath(graph,bundle);if(lineCanvases.push(sharedPathC),cornerCanvases.push(sharedCornersC),bundle.type==="fan-in"){let arrowHeadC=drawBundleArrowhead(graph,bundle);arrowHeadEndCanvases.push(arrowHeadC)}let junctionC=drawJunctionCharacter(graph,bundle);junctionCanvases.push(junctionC)}if(bundle.type==="fan-out"&&edge.hasArrowEnd){let arrowHeadC=drawBundledEdgeArrowhead(graph,edge);arrowHeadEndCanvases.push(arrowHeadC)}}else{let[pathC,boxStartC,arrowHeadEndC,arrowHeadStartC,cornersC,labelC]=drawArrow(graph,edge);lineCanvases.push(pathC),cornerCanvases.push(cornersC),arrowHeadEndCanvases.push(arrowHeadEndC),arrowHeadStartCanvases.push(arrowHeadStartC),boxStartCanvases.push(boxStartC),labelCanvases.push(labelC)}graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...lineCanvases),fillRolesFromCanvases(graph.roleCanvas,lineCanvases,zero,"line"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...cornerCanvases),fillRolesFromCanvases(graph.roleCanvas,cornerCanvases,zero,"corner"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...junctionCanvases),fillRolesFromCanvases(graph.roleCanvas,junctionCanvases,zero,"junction"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...arrowHeadEndCanvases),fillRolesFromCanvases(graph.roleCanvas,arrowHeadEndCanvases,zero,"arrow"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...boxStartCanvases),fillRolesFromCanvases(graph.roleCanvas,boxStartCanvases,zero,"junction"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...arrowHeadStartCanvases),fillRolesFromCanvases(graph.roleCanvas,arrowHeadStartCanvases,zero,"arrow"),graph.canvas=mergeCanvases(graph.canvas,zero,useAscii,...labelCanvases);for(let label of labelCanvases)clearLabelGaps(graph.canvas,label);fillRolesFromCanvases(graph.roleCanvas,labelCanvases,zero,"text");for(let sg of graph.subgraphs){if(sg.nodes.length===0)continue;let[labelCanvas,offset]=drawSubgraphLabel(sg,graph);graph.canvas=mergeCanvases(graph.canvas,offset,useAscii,labelCanvas),fillRolesFromCanvas(graph.roleCanvas,labelCanvas,offset,"text")}return graph.canvas}function gridToDrawingCoord(graph,c,dir){let target=dir?{x:c.x+dir.x,y:c.y+dir.y}:c,x=0;for(let col=0;col<target.x;col++)x+=graph.columnWidth.get(col)??0;let y=0;for(let row=0;row<target.y;row++)y+=graph.rowHeight.get(row)??0;let colW=graph.columnWidth.get(target.x)??0,rowH=graph.rowHeight.get(target.y)??0;return{x:x+Math.floor(colW/2)+graph.offsetX,y:y+Math.floor(rowH/2)+graph.offsetY}}function lineToDrawing(graph,line){return line.map(c=>gridToDrawingCoord(graph,c))}function reserveSpotInGrid(graph,node,requested,effectiveDir){let dir=effectiveDir??getEffectiveDirection2(graph,node);if(graph.grid.has(gridKey(requested)))return dir==="LR"?reserveSpotInGrid(graph,node,{x:requested.x,y:requested.y+4},dir):reserveSpotInGrid(graph,node,{x:requested.x+4,y:requested.y},dir);for(let dx=0;dx<3;dx++)for(let dy=0;dy<3;dy++){let reserved={x:requested.x+dx,y:requested.y+dy};graph.grid.set(gridKey(reserved),node)}return node.gridCoord=requested,requested}function setColumnWidth(graph,node){let gc=node.gridCoord,padding=graph.config.boxBorderPadding,shapeDims=getShapeDimensions(node.shape,node.displayLabel,{useAscii:graph.config.useAscii,padding}),colWidths=shapeDims.gridColumns,rowHeights=shapeDims.gridRows;for(let idx=0;idx<colWidths.length;idx++){let xCoord=gc.x+idx,current=graph.columnWidth.get(xCoord)??0;graph.columnWidth.set(xCoord,Math.max(current,colWidths[idx]))}for(let idx=0;idx<rowHeights.length;idx++){let yCoord=gc.y+idx,current=graph.rowHeight.get(yCoord)??0;graph.rowHeight.set(yCoord,Math.max(current,rowHeights[idx]))}if(gc.x>0){let current=graph.columnWidth.get(gc.x-1)??0;graph.columnWidth.set(gc.x-1,Math.max(current,graph.config.paddingX))}if(gc.y>0){let basePadding=graph.config.paddingY;hasIncomingEdgeFromOutsideSubgraph(graph,node)&&(basePadding+=4);let current=graph.rowHeight.get(gc.y-1)??0;graph.rowHeight.set(gc.y-1,Math.max(current,basePadding))}}function increaseGridSizeForPath(graph,path){for(let c of path)graph.columnWidth.has(c.x)||graph.columnWidth.set(c.x,Math.floor(graph.config.paddingX/2)),graph.rowHeight.has(c.y)||graph.rowHeight.set(c.y,Math.floor(graph.config.paddingY/2))}function isNodeInAnySubgraph(graph,node){return graph.subgraphs.some(sg=>sg.nodes.includes(node))}function getNodeSubgraph(graph,node){let innermost=null;for(let sg of graph.subgraphs)sg.nodes.includes(node)&&(!innermost||isAncestorOrSelf2(innermost,sg))&&(innermost=sg);return innermost}function isAncestorOrSelf2(candidate,target){let current=target;for(;current!==null;){if(current===candidate)return!0;current=current.parent}return!1}function getEffectiveDirection2(graph,node){let sg=getNodeSubgraph(graph,node);return sg?.direction?sg.direction:graph.config.graphDirection}function hasIncomingEdgeFromOutsideSubgraph(graph,node){let nodeSg=getNodeSubgraph(graph,node);if(!nodeSg)return!1;let hasExternalEdge=!1;for(let edge of graph.edges)if(edge.to===node&&getNodeSubgraph(graph,edge.from)!==nodeSg){hasExternalEdge=!0;break}if(!hasExternalEdge)return!1;for(let otherNode of nodeSg.nodes){if(otherNode===node||!otherNode.gridCoord)continue;let otherHasExternal=!1;for(let edge of graph.edges)if(edge.to===otherNode&&getNodeSubgraph(graph,edge.from)!==nodeSg){otherHasExternal=!0;break}if(otherHasExternal&&otherNode.gridCoord.y<node.gridCoord.y)return!1}return!0}function calculateSubgraphBoundingBox(graph,sg){if(sg.nodes.length===0)return;let minX=1e6,minY=1e6,maxX=-1e6,maxY=-1e6;for(let child of sg.children)calculateSubgraphBoundingBox(graph,child),child.nodes.length>0&&(minX=Math.min(minX,child.minX),minY=Math.min(minY,child.minY),maxX=Math.max(maxX,child.maxX),maxY=Math.max(maxY,child.maxY));for(let node of sg.nodes){if(!node.drawingCoord||!node.drawing)continue;let nodeMinX=node.drawingCoord.x,nodeMinY=node.drawingCoord.y,nodeMaxX=nodeMinX+node.drawing.length-1,nodeMaxY=nodeMinY+node.drawing[0].length-1;minX=Math.min(minX,nodeMinX),minY=Math.min(minY,nodeMinY),maxX=Math.max(maxX,nodeMaxX),maxY=Math.max(maxY,nodeMaxY)}let subgraphPadding=2,subgraphLabelSpace=2;sg.minX=minX-subgraphPadding,sg.minY=minY-subgraphPadding-subgraphLabelSpace,sg.maxX=maxX+subgraphPadding,sg.maxY=maxY+subgraphPadding}function ensureSubgraphSpacing(graph){let rootSubgraphs=graph.subgraphs.filter(sg=>sg.parent===null&&sg.nodes.length>0);for(let i=0;i<rootSubgraphs.length;i++)for(let j=i+1;j<rootSubgraphs.length;j++){let sg1=rootSubgraphs[i],sg2=rootSubgraphs[j];sg1.minX<sg2.maxX&&sg1.maxX>sg2.minX&&(sg1.maxY>=sg2.minY-1&&sg1.minY<sg2.minY?sg2.minY=sg1.maxY+1+1:sg2.maxY>=sg1.minY-1&&sg2.minY<sg1.minY&&(sg1.minY=sg2.maxY+1+1)),sg1.minY<sg2.maxY&&sg1.maxY>sg2.minY&&(sg1.maxX>=sg2.minX-1&&sg1.minX<sg2.minX?sg2.minX=sg1.maxX+1+1:sg2.maxX>=sg1.minX-1&&sg2.minX<sg1.minX&&(sg1.minX=sg2.maxX+1+1))}}function calculateSubgraphBoundingBoxes(graph){for(let sg of graph.subgraphs)calculateSubgraphBoundingBox(graph,sg);ensureSubgraphSpacing(graph)}function offsetDrawingForSubgraphs(graph){if(graph.subgraphs.length===0)return;let minX=0,minY=0;for(let sg of graph.subgraphs)minX=Math.min(minX,sg.minX),minY=Math.min(minY,sg.minY);let offsetX=-minX,offsetY=-minY;if(!(offsetX===0&&offsetY===0)){graph.offsetX=offsetX,graph.offsetY=offsetY;for(let sg of graph.subgraphs)sg.minX+=offsetX,sg.minY+=offsetY,sg.maxX+=offsetX,sg.maxY+=offsetY;for(let node of graph.nodes)node.drawingCoord&&(node.drawingCoord.x+=offsetX,node.drawingCoord.y+=offsetY)}}function createMapping(graph){let dir=graph.config.graphDirection,highestPositionPerLevel=new Array(100).fill(0),nodesFound=new Set,initialRoots=[];for(let node of graph.nodes){nodesFound.has(node.name)||initialRoots.push(node),nodesFound.add(node.name);for(let child of getChildren(graph,node))nodesFound.add(child.name)}let rootNodes=initialRoots.filter(node=>{let nodeSg=getNodeSubgraph(graph,node);if(!nodeSg)return!0;for(let edge of graph.edges)if(edge.to===node&&getNodeSubgraph(graph,edge.from)!==nodeSg)return!1;return!0}),hasExternalRoots=!1,hasSubgraphRootsWithEdges=!1;for(let node of rootNodes)isNodeInAnySubgraph(graph,node)?getChildren(graph,node).length>0&&(hasSubgraphRootsWithEdges=!0):hasExternalRoots=!0;let shouldSeparate=dir==="LR"&&hasExternalRoots&&hasSubgraphRootsWithEdges,externalRootNodes,subgraphRootNodes=[];shouldSeparate?(externalRootNodes=rootNodes.filter(n=>!isNodeInAnySubgraph(graph,n)),subgraphRootNodes=rootNodes.filter(n=>isNodeInAnySubgraph(graph,n))):externalRootNodes=rootNodes;for(let node of externalRootNodes){let requested=dir==="LR"?{x:0,y:highestPositionPerLevel[0]}:{x:highestPositionPerLevel[0],y:0};reserveSpotInGrid(graph,graph.nodes[node.index],requested),highestPositionPerLevel[0]=highestPositionPerLevel[0]+4}if(shouldSeparate&&subgraphRootNodes.length>0)for(let node of subgraphRootNodes){let requested=dir==="LR"?{x:4,y:highestPositionPerLevel[4]}:{x:highestPositionPerLevel[4],y:4};reserveSpotInGrid(graph,graph.nodes[node.index],requested),highestPositionPerLevel[4]=highestPositionPerLevel[4]+4}let placedCount=externalRootNodes.length+subgraphRootNodes.length;for(;placedCount<graph.nodes.length;){let prevCount=placedCount;for(let node of graph.nodes){if(node.gridCoord===null)continue;let gc=node.gridCoord;for(let child of getChildren(graph,node)){if(child.gridCoord!==null)continue;let parentSg=getNodeSubgraph(graph,node),childSg=getNodeSubgraph(graph,child),edgeDir=parentSg&&parentSg===childSg&&parentSg.direction?parentSg.direction:graph.config.graphDirection,childLevel=edgeDir==="LR"?gc.x+4:gc.y+4,highestPosition;edgeDir!==graph.config.graphDirection?highestPosition=edgeDir==="LR"?gc.y:gc.x:highestPosition=highestPositionPerLevel[childLevel];let requested=edgeDir==="LR"?{x:childLevel,y:highestPosition}:{x:highestPosition,y:childLevel};reserveSpotInGrid(graph,graph.nodes[child.index],requested,edgeDir),edgeDir===graph.config.graphDirection&&(highestPositionPerLevel[childLevel]=highestPosition+4),placedCount++}}if(placedCount===prevCount)break}for(let node of graph.nodes)setColumnWidth(graph,node);graph.bundles=analyzeEdgeBundles(graph),processBundles(graph);for(let edge of graph.edges){if(edge.bundle&&edge.path.length>0){increaseGridSizeForPath(graph,edge.path),determineLabelLine(graph,edge);continue}determinePath(graph,edge),increaseGridSizeForPath(graph,edge.path),determineLabelLine(graph,edge)}for(let node of graph.nodes)node.drawingCoord=gridToDrawingCoord(graph,node.gridCoord),node.drawing=drawBox(node,graph);setCanvasSizeToGrid(graph.canvas,graph.columnWidth,graph.rowHeight),setRoleCanvasSizeToGrid(graph.roleCanvas,graph.columnWidth,graph.rowHeight),calculateSubgraphBoundingBoxes(graph),offsetDrawingForSubgraphs(graph)}function getEdgesFromNode(graph,node){return graph.edges.filter(e=>e.from.name===node.name)}function getChildren(graph,node){return getEdgesFromNode(graph,node).map(e=>e.to)}function parseSequenceDiagram(lines){let diagram={actors:[],messages:[],blocks:[],notes:[]},actorIds=new Set,blockStack=[];for(let i=1;i<lines.length;i++){let line=lines[i],actorMatch=line.match(/^(participant|actor)\s+(\S+?)(?:\s+as\s+(.+))?$/);if(actorMatch){let type=actorMatch[1],id=actorMatch[2],rawLabel=actorMatch[3]?.trim()??id,label=normalizeBrTags(rawLabel);actorIds.has(id)||(actorIds.add(id),diagram.actors.push({id,label,type}));continue}let noteMatch=line.match(/^Note\s+(left of|right of|over)\s+([^:]+):\s*(.+)$/i);if(noteMatch){let posStr=noteMatch[1].toLowerCase(),actorsStr=noteMatch[2].trim(),text=normalizeBrTags(noteMatch[3].trim()),noteActorIds=actorsStr.split(",").map(s=>s.trim());for(let aid of noteActorIds)ensureActor(diagram,actorIds,aid);let position="over";posStr==="left of"?position="left":posStr==="right of"&&(position="right"),diagram.notes.push({actorIds:noteActorIds,text,position,afterIndex:diagram.messages.length-1});continue}let blockMatch=line.match(/^(loop|alt|opt|par|critical|break|rect)\s*(.*)$/);if(blockMatch){let blockType=blockMatch[1],rawBlockLabel=blockMatch[2]?.trim()??"",label=normalizeBrTags(rawBlockLabel);blockStack.push({type:blockType,label,startIndex:diagram.messages.length,dividers:[]});continue}let dividerMatch=line.match(/^(else|and)\s*(.*)$/);if(dividerMatch&&blockStack.length>0){let rawDividerLabel=dividerMatch[2]?.trim()??"",label=normalizeBrTags(rawDividerLabel);blockStack[blockStack.length-1].dividers.push({index:diagram.messages.length,label});continue}if(line==="end"&&blockStack.length>0){let completed=blockStack.pop();diagram.blocks.push({type:completed.type,label:completed.label,startIndex:completed.startIndex,endIndex:Math.max(diagram.messages.length-1,completed.startIndex),dividers:completed.dividers});continue}let msgMatch=line.match(/^(\S+?)\s*(--?>?>|--?[)x]|--?>>|--?>)\s*([+-]?)(\S+?)\s*:\s*(.+)$/);if(msgMatch){let from=msgMatch[1],arrow=msgMatch[2],activationMark=msgMatch[3],to=msgMatch[4],label=normalizeBrTags(msgMatch[5].trim());ensureActor(diagram,actorIds,from),ensureActor(diagram,actorIds,to);let lineStyle=arrow.startsWith("--")?"dashed":"solid",arrowHead=arrow.includes(">>")||arrow.includes("x")?"filled":"open",msg={from,to,label,lineStyle,arrowHead};activationMark==="+"&&(msg.activate=!0),activationMark==="-"&&(msg.deactivate=!0),diagram.messages.push(msg);continue}let simpleMsgMatch=line.match(/^(\S+?)\s*(->>|-->>|-\)|--\)|-x|--x|->|-->)\s*([+-]?)(\S+?)\s*:\s*(.+)$/);if(simpleMsgMatch){let from=simpleMsgMatch[1],arrow=simpleMsgMatch[2],activationMark=simpleMsgMatch[3],to=simpleMsgMatch[4],label=normalizeBrTags(simpleMsgMatch[5].trim());ensureActor(diagram,actorIds,from),ensureActor(diagram,actorIds,to);let lineStyle=arrow.startsWith("--")?"dashed":"solid",arrowHead=arrow.includes(">>")||arrow.includes("x")?"filled":"open",msg={from,to,label,lineStyle,arrowHead};activationMark==="+"&&(msg.activate=!0),activationMark==="-"&&(msg.deactivate=!0),diagram.messages.push(msg);continue}}return diagram}function ensureActor(diagram,actorIds,id){actorIds.has(id)||(actorIds.add(id),diagram.actors.push({id,label:id,type:"participant"}))}function renderSequenceAscii(text,config,colorMode,theme){let lines=text.split(`
7`).map(l=>l.trim()).filter(l=>l.length>0&&!l.startsWith("%%")),diagram=parseSequenceDiagram(lines);if(diagram.actors.length===0)return"";let useAscii=config.useAscii,H=useAscii?"-":"\u2500",V=useAscii?"|":"\u2502",TL=useAscii?"+":"\u250C",TR=useAscii?"+":"\u2510",BL=useAscii?"+":"\u2514",BR=useAscii?"+":"\u2518",JT=useAscii?"+":"\u252C",JB=useAscii?"+":"\u2534",JL=useAscii?"+":"\u251C",JR=useAscii?"+":"\u2524",actorIdx=new Map;diagram.actors.forEach((a,i)=>actorIdx.set(a.id,i));let boxPad=1,halfBox=diagram.actors.map(a=>maxLineWidth(a.label)+2*boxPad+2).map(w=>Math.ceil(w/2)),actorBoxHeights=diagram.actors.map(a=>lineCount(a.label)+2),actorBoxH=Math.max(...actorBoxHeights,3),adjMaxWidth=new Array(Math.max(diagram.actors.length-1,0)).fill(0);for(let msg of diagram.messages){let fi=actorIdx.get(msg.from),ti=actorIdx.get(msg.to);if(fi===ti)continue;let lo=Math.min(fi,ti),hi=Math.max(fi,ti),needed=maxLineWidth(msg.label)+4,numGaps=hi-lo,perGap=Math.ceil(needed/numGaps);for(let g=lo;g<hi;g++)adjMaxWidth[g]=Math.max(adjMaxWidth[g],perGap)}let llX=[halfBox[0]];for(let i=1;i<diagram.actors.length;i++){let gap=Math.max(halfBox[i-1]+halfBox[i]+2,adjMaxWidth[i-1]+2,10);llX[i]=llX[i-1]+gap}let msgArrowY=[],msgLabelY=[],blockStartY=new Map,blockEndY=new Map,divYMap=new Map,notePositions=[],curY=actorBoxH;for(let m=0;m<diagram.messages.length;m++){for(let b=0;b<diagram.blocks.length;b++)diagram.blocks[b].startIndex===m&&(curY+=2,blockStartY.set(b,curY-1));for(let b=0;b<diagram.blocks.length;b++)for(let d=0;d<diagram.blocks[b].dividers.length;d++)diagram.blocks[b].dividers[d].index===m&&(curY+=1,divYMap.set(`${b}:${d}`,curY),curY+=1);curY+=1;let msg=diagram.messages[m],isSelf=msg.from===msg.to,msgLineCount=lineCount(msg.label);isSelf?(msgLabelY[m]=curY+1,msgArrowY[m]=curY,curY+=2+msgLineCount):(msgLabelY[m]=curY,msgArrowY[m]=curY+msgLineCount,curY+=msgLineCount+1);for(let n=0;n<diagram.notes.length;n++)if(diagram.notes[n].afterIndex===m){curY+=1;let note=diagram.notes[n],nLines=splitLines(note.text),nWidth=Math.max(...nLines.map(l=>l.length))+4,nHeight=nLines.length+2,aIdx=actorIdx.get(note.actorIds[0])??0,nx;if(note.position==="left")nx=llX[aIdx]-nWidth-1;else if(note.position==="right")nx=llX[aIdx]+2;else if(note.actorIds.length>=2){let aIdx2=actorIdx.get(note.actorIds[1])??aIdx;nx=Math.floor((llX[aIdx]+llX[aIdx2])/2)-Math.floor(nWidth/2)}else nx=llX[aIdx]-Math.floor(nWidth/2);nx=Math.max(0,nx),notePositions.push({x:nx,y:curY,width:nWidth,height:nHeight,lines:nLines}),curY+=nHeight}for(let b=0;b<diagram.blocks.length;b++)diagram.blocks[b].endIndex===m&&(curY+=1,blockEndY.set(b,curY),curY+=1)}curY+=1;let footerY=curY,totalH=footerY+actorBoxH,lastLL=llX[llX.length-1]??0,lastHalf=halfBox[halfBox.length-1]??0,totalW=lastLL+lastHalf+2;for(let m=0;m<diagram.messages.length;m++){let msg=diagram.messages[m];if(msg.from===msg.to){let fi=actorIdx.get(msg.from),selfRight=llX[fi]+6+2+msg.label.length;totalW=Math.max(totalW,selfRight+1)}}for(let np of notePositions)totalW=Math.max(totalW,np.x+np.width+1);let canvas=mkCanvas(totalW,totalH-1),rc=mkRoleCanvas(totalW,totalH-1);function setC(x,y,ch,role){x>=0&&x<canvas.length&&y>=0&&y<(canvas[0]?.length??0)&&(canvas[x][y]=ch,setRole(rc,x,y,role))}function drawActorBox(cx,topY,label){let lines2=splitLines(label),maxW=maxLineWidth(label),w=maxW+2*boxPad+2,h=lines2.length+2,left=cx-Math.floor(w/2);setC(left,topY,TL,"border");for(let x=1;x<w-1;x++)setC(left+x,topY,H,"border");setC(left+w-1,topY,TR,"border");for(let i=0;i<lines2.length;i++){let row=topY+1+i;setC(left,row,V,"border"),setC(left+w-1,row,V,"border");let line=lines2[i],ls=left+1+boxPad+Math.floor((maxW-line.length)/2);for(let j=0;j<line.length;j++)setC(ls+j,row,line[j],"text")}let bottomY=topY+h-1;setC(left,bottomY,BL,"border");for(let x=1;x<w-1;x++)setC(left+x,bottomY,H,"border");setC(left+w-1,bottomY,BR,"border")}for(let i=0;i<diagram.actors.length;i++){let x=llX[i];for(let y=actorBoxH;y<=footerY;y++)setC(x,y,V,"line")}for(let i=0;i<diagram.actors.length;i++){let actor=diagram.actors[i];drawActorBox(llX[i],0,actor.label),drawActorBox(llX[i],footerY,actor.label),useAscii||(setC(llX[i],actorBoxH-1,JT,"junction"),setC(llX[i],footerY,JB,"junction"))}for(let m=0;m<diagram.messages.length;m++){let msg=diagram.messages[m],fi=actorIdx.get(msg.from),ti=actorIdx.get(msg.to),fromX=llX[fi],toX=llX[ti],isSelf=fi===ti,isDashed=msg.lineStyle==="dashed",isFilled=msg.arrowHead==="filled",lineChar=isDashed?useAscii?".":"\u254C":H;if(isSelf){let y0=msgArrowY[m],loopW=Math.max(4,4);setC(fromX,y0,JL,"junction");for(let x=fromX+1;x<fromX+loopW;x++)setC(x,y0,lineChar,"line");setC(fromX+loopW,y0,useAscii?"+":"\u2510","corner"),setC(fromX+loopW,y0+1,V,"line");let labelX=fromX+loopW+2;for(let i=0;i<msg.label.length;i++)labelX+i<totalW&&setC(labelX+i,y0+1,msg.label[i],"text");let arrowChar=isFilled?useAscii?"<":"\u25C0":useAscii?"<":"\u25C1";setC(fromX,y0+2,arrowChar,"arrow");for(let x=fromX+1;x<fromX+loopW;x++)setC(x,y0+2,lineChar,"line");setC(fromX+loopW,y0+2,useAscii?"+":"\u2518","corner")}else{let labelY=msgLabelY[m],arrowY=msgArrowY[m],leftToRight=fromX<toX,midX=Math.floor((fromX+toX)/2),msgLines=splitLines(msg.label);for(let lineIdx=0;lineIdx<msgLines.length;lineIdx++){let line=msgLines[lineIdx],labelStart=midX-Math.floor(line.length/2),y=labelY+lineIdx;for(let i=0;i<line.length;i++){let lx=labelStart+i;lx>=0&&lx<totalW&&setC(lx,y,line[i],"text")}}if(leftToRight){for(let x=fromX+1;x<toX;x++)setC(x,arrowY,lineChar,"line");setC(toX,arrowY,isFilled?useAscii?">":"\u25B6":useAscii?">":"\u25B7","arrow")}else{for(let x=toX+1;x<fromX;x++)setC(x,arrowY,lineChar,"line");setC(toX,arrowY,isFilled?useAscii?"<":"\u25C0":useAscii?"<":"\u25C1","arrow")}}}for(let b=0;b<diagram.blocks.length;b++){let block=diagram.blocks[b],topY=blockStartY.get(b),botY=blockEndY.get(b);if(topY===void 0||botY===void 0)continue;let minLX=totalW,maxLX=0;for(let m=block.startIndex;m<=block.endIndex&&!(m>=diagram.messages.length);m++){let msg=diagram.messages[m],f=actorIdx.get(msg.from)??0,t=actorIdx.get(msg.to)??0;minLX=Math.min(minLX,llX[Math.min(f,t)]),maxLX=Math.max(maxLX,llX[Math.max(f,t)])}let bLeft=Math.max(0,minLX-4),bRight=Math.min(totalW-1,maxLX+4);setC(bLeft,topY,TL,"border");for(let x=bLeft+1;x<bRight;x++)setC(x,topY,H,"border");setC(bRight,topY,TR,"border");let hdrLabel=block.label?`${block.type} [${block.label}]`:block.type,hdrLines=splitLines(hdrLabel);for(let lineIdx=0;lineIdx<hdrLines.length&&topY+lineIdx<botY;lineIdx++){let line=hdrLines[lineIdx];for(let i=0;i<line.length&&bLeft+1+i<bRight;i++)setC(bLeft+1+i,topY+lineIdx,line[i],"text")}setC(bLeft,botY,BL,"border");for(let x=bLeft+1;x<bRight;x++)setC(x,botY,H,"border");setC(bRight,botY,BR,"border");for(let y=topY+1;y<botY;y++)setC(bLeft,y,V,"border"),setC(bRight,y,V,"border");for(let d=0;d<block.dividers.length;d++){let dY=divYMap.get(`${b}:${d}`);if(dY===void 0)continue;let dashChar=isDashedH();setC(bLeft,dY,JL,"junction");for(let x=bLeft+1;x<bRight;x++)setC(x,dY,dashChar,"line");setC(bRight,dY,JR,"junction");let dLabel=block.dividers[d].label;if(dLabel){let dStr=`[${dLabel}]`;for(let i=0;i<dStr.length&&bLeft+1+i<bRight;i++)setC(bLeft+1+i,dY,dStr[i],"text")}}}for(let np of notePositions){increaseSize(canvas,np.x+np.width,np.y+np.height),increaseRoleCanvasSize(rc,np.x+np.width,np.y+np.height),setC(np.x,np.y,TL,"border");for(let x=1;x<np.width-1;x++)setC(np.x+x,np.y,H,"border");setC(np.x+np.width-1,np.y,TR,"border");for(let l=0;l<np.lines.length;l++){let ly=np.y+1+l;setC(np.x,ly,V,"border"),setC(np.x+np.width-1,ly,V,"border");for(let i=0;i<np.lines[l].length;i++)setC(np.x+2+i,ly,np.lines[l][i],"text")}let by=np.y+np.height-1;setC(np.x,by,BL,"border");for(let x=1;x<np.width-1;x++)setC(np.x+x,by,H,"border");setC(np.x+np.width-1,by,BR,"border")}return canvasToString(canvas,{roleCanvas:rc,colorMode,theme});function isDashedH(){return useAscii?"-":"\u254C"}}function parseClassDiagram(lines){let diagram={classes:[],relationships:[],namespaces:[]},classMap=new Map,currentNamespace=null,currentClass=null,braceDepth=0;for(let i=1;i<lines.length;i++){let line=lines[i];if(currentClass&&braceDepth>0){if(line==="}"){braceDepth--,braceDepth===0&&(currentClass=null);continue}let annotMatch=line.match(/^<<(\w+)>>$/);if(annotMatch){currentClass.annotation=annotMatch[1];continue}let member=parseMember(line);member&&(member.isMethod?currentClass.methods.push(member.member):currentClass.attributes.push(member.member));continue}let nsMatch=line.match(/^namespace\s+(\S+)\s*\{$/);if(nsMatch){currentNamespace={name:nsMatch[1],classIds:[]};continue}if(line==="}"&¤tNamespace){diagram.namespaces.push(currentNamespace),currentNamespace=null;continue}let classBlockMatch=line.match(/^class\s+(\S+?)(?:\s*~(\w+)~)?\s*\{$/);if(classBlockMatch){let id=classBlockMatch[1],generic=classBlockMatch[2],cls=ensureClass(classMap,id);generic&&(cls.label=`${id}<${generic}>`),currentClass=cls,braceDepth=1,currentNamespace&¤tNamespace.classIds.push(id);continue}let classOnlyMatch=line.match(/^class\s+(\S+?)(?:\s*~(\w+)~)?\s*$/);if(classOnlyMatch){let id=classOnlyMatch[1],generic=classOnlyMatch[2],cls=ensureClass(classMap,id);generic&&(cls.label=`${id}<${generic}>`),currentNamespace&¤tNamespace.classIds.push(id);continue}let inlineAnnotMatch=line.match(/^class\s+(\S+?)\s*\{\s*<<(\w+)>>\s*\}$/);if(inlineAnnotMatch){let cls=ensureClass(classMap,inlineAnnotMatch[1]);cls.annotation=inlineAnnotMatch[2];continue}let inlineAttrMatch=line.match(/^(\S+?)\s*:\s*(.+)$/);if(inlineAttrMatch){let rest=inlineAttrMatch[2];if(!rest.match(/<\|--|--|\*--|o--|-->|\.\.>|\.\.\|>/)){let cls=ensureClass(classMap,inlineAttrMatch[1]),member=parseMember(rest);member&&(member.isMethod?cls.methods.push(member.member):cls.attributes.push(member.member));continue}}let rel=parseRelationship(line);if(rel){ensureClass(classMap,rel.from),ensureClass(classMap,rel.to),diagram.relationships.push(rel);continue}}return diagram.classes=[...classMap.values()],diagram}function ensureClass(classMap,id){let cls=classMap.get(id);return cls||(cls={id,label:id,attributes:[],methods:[]},classMap.set(id,cls)),cls}function parseMember(line){let trimmed=line.trim().replace(/;$/,"");if(!trimmed)return null;let visibility="",rest=trimmed;/^[+\-#~]/.test(rest)&&(visibility=rest[0],rest=rest.slice(1).trim());let methodMatch=rest.match(/^(.+?)\(([^)]*)\)(?:\s*(.+))?$/);if(methodMatch){let name2=methodMatch[1].trim(),params=methodMatch[2]?.trim()||void 0,type2=methodMatch[3]?.trim(),isStatic2=name2.endsWith("$")||rest.includes("$"),isAbstract2=name2.endsWith("*")||rest.includes("*");return{member:{visibility,name:name2.replace(/[$*]$/,""),type:type2||void 0,isStatic:isStatic2,isAbstract:isAbstract2,isMethod:!0,params},isMethod:!0}}let parts=rest.split(/\s+/),name,type;parts.length>=2?(type=parts[0],name=parts.slice(1).join(" ")):name=parts[0]??rest;let isStatic=name.endsWith("$"),isAbstract=name.endsWith("*");return{member:{visibility,name:name.replace(/[$*]$/,""),type:type||void 0,isStatic,isAbstract,isMethod:!1},isMethod:!1}}function parseRelationship(line){let match=line.match(/^(\S+?)\s+(?:"([^"]*?)"\s+)?(<\|--|<\|\.\.|\*--|o--|-->|--\*|--o|--\|>|\.\.>|\.\.\|>|<--|<\.\.?|--)\s+(?:"([^"]*?)"\s+)?(\S+?)(?:\s*:\s*(.+))?$/);if(!match)return null;let from=match[1],rawFromCardinality=match[2],fromCardinality=rawFromCardinality?normalizeBrTags(rawFromCardinality):void 0,arrow=match[3].trim(),rawToCardinality=match[4],toCardinality=rawToCardinality?normalizeBrTags(rawToCardinality):void 0,to=match[5],rawLabel=match[6]?.trim(),label=rawLabel?normalizeBrTags(rawLabel):void 0,parsed=parseArrow(arrow);return parsed?{from,to,type:parsed.type,markerAt:parsed.markerAt,label,fromCardinality,toCardinality}:null}function parseArrow(arrow){switch(arrow.trim()){case"<|--":return{type:"inheritance",markerAt:"from"};case"--|>":return{type:"inheritance",markerAt:"to"};case"<|..":return{type:"realization",markerAt:"from"};case"..|>":return{type:"realization",markerAt:"to"};case"*--":return{type:"composition",markerAt:"from"};case"--*":return{type:"composition",markerAt:"to"};case"o--":return{type:"aggregation",markerAt:"from"};case"--o":return{type:"aggregation",markerAt:"to"};case"-->":return{type:"association",markerAt:"to"};case"<--":return{type:"association",markerAt:"from"};case"..>":return{type:"dependency",markerAt:"to"};case"<..":return{type:"dependency",markerAt:"from"};case"--":return{type:"association",markerAt:"to"};default:return null}}function classifyBoxChar(ch){return/^[┌┐└┘├┤┬┴┼│─╭╮╰╯+\-|]$/.test(ch)?"border":"text"}function formatMember(m){let vis=m.visibility||"",type=m.type?`: ${m.type}`:"";return`${vis}${m.name}${type}`}function buildClassSections(cls){let header=[];cls.annotation&&header.push(`<<${cls.annotation}>>`);let nameLines=splitLines(cls.label);header.push(...nameLines);let attrs=cls.attributes.map(formatMember),methods=cls.methods.map(formatMember);return attrs.length===0&&methods.length===0?[header]:methods.length===0?[header,attrs]:[header,attrs,methods]}function getRelMarker(type,markerAt){return{type,markerAt,dashed:type==="dependency"||type==="realization"}}function getMarkerShape(type,useAscii,direction){switch(type){case"inheritance":case"realization":return direction==="down"?useAscii?"^":"\u25B3":direction==="up"?useAscii?"v":"\u25BD":direction==="left"?useAscii?">":"\u25C1":useAscii?"<":"\u25B7";case"composition":return useAscii?"*":"\u25C6";case"aggregation":return useAscii?"o":"\u25C7";case"association":case"dependency":return direction==="down"?useAscii?"v":"\u25BC":direction==="up"?useAscii?"^":"\u25B2":direction==="left"?useAscii?"<":"\u25C0":useAscii?">":"\u25B6"}}function renderClassAscii(text,config,colorMode,theme){let lines=text.split(`
8`).map(l=>l.trim()).filter(l=>l.length>0&&!l.startsWith("%%")),diagram=parseClassDiagram(lines);if(diagram.classes.length===0)return"";let useAscii=config.useAscii,hGap=4,vGap=3,classSections=new Map,classBoxW=new Map,classBoxH=new Map;for(let cls of diagram.classes){let sections=buildClassSections(cls);classSections.set(cls.id,sections);let maxTextW=0;for(let section of sections)for(let line of section)maxTextW=Math.max(maxTextW,line.length);let boxW=maxTextW+4,totalLines=0;for(let section of sections)totalLines+=Math.max(section.length,1);let boxH=totalLines+(sections.length-1)+2;classBoxW.set(cls.id,boxW),classBoxH.set(cls.id,boxH)}let classById=new Map;for(let cls of diagram.classes)classById.set(cls.id,cls);let parents=new Map,children=new Map;for(let rel of diagram.relationships){let isHierarchical=rel.type==="inheritance"||rel.type==="realization",parentId=isHierarchical&&rel.markerAt==="to"?rel.to:rel.from,childId=isHierarchical&&rel.markerAt==="to"?rel.from:rel.to;parents.has(childId)||parents.set(childId,new Set),parents.get(childId).add(parentId),children.has(parentId)||children.set(parentId,new Set),children.get(parentId).add(childId)}let level=new Map,queue=diagram.classes.filter(c=>!parents.has(c.id)||parents.get(c.id).size===0).map(c=>c.id);for(let id of queue)level.set(id,0);let levelCap=diagram.classes.length-1,qi=0;for(;qi<queue.length;){let id=queue[qi++],childSet=children.get(id);if(childSet)for(let childId of childSet){let newLevel=(level.get(id)??0)+1;newLevel>levelCap||(!level.has(childId)||level.get(childId)<newLevel)&&(level.set(childId,newLevel),queue.push(childId))}}for(let cls of diagram.classes)level.has(cls.id)||level.set(cls.id,0);let maxLevel=Math.max(...level.values(),0),levelGroups=Array.from({length:maxLevel+1},()=>[]);for(let cls of diagram.classes)levelGroups[level.get(cls.id)].push(cls.id);let placed=new Map,currentY=0;for(let lv=0;lv<=maxLevel;lv++){let group=levelGroups[lv];if(group.length===0)continue;let currentX=0,maxH=0;for(let id of group){let cls=classById.get(id),w=classBoxW.get(id),h=classBoxH.get(id);placed.set(id,{cls,sections:classSections.get(id),x:currentX,y:currentY,width:w,height:h}),currentX+=w+hGap,maxH=Math.max(maxH,h)}currentY+=maxH+vGap}let totalW=0,totalH=0;for(let p of placed.values())totalW=Math.max(totalW,p.x+p.width),totalH=Math.max(totalH,p.y+p.height);totalW+=4,totalH+=2;let canvas=mkCanvas(totalW-1,totalH-1),rc=mkRoleCanvas(totalW-1,totalH-1);function setC(x,y,ch,role){x>=0&&x<canvas.length&&y>=0&&y<(canvas[0]?.length??0)&&(canvas[x][y]=ch,setRole(rc,x,y,role))}for(let p of placed.values()){let boxCanvas=drawMultiBox(p.sections,useAscii);for(let bx=0;bx<boxCanvas.length;bx++)for(let by=0;by<boxCanvas[0].length;by++){let ch=boxCanvas[bx][by];if(ch!==" "){let cx=p.x+bx,cy=p.y+by;cx<totalW&&cy<totalH&&setC(cx,cy,ch,classifyBoxChar(ch))}}}let boxOccupancy=[];for(let p of placed.values())boxOccupancy.push({x1:p.x,x2:p.x+p.width-1,y1:p.y,y2:p.y+p.height-1});function isInsideBox(x,y,excludeIds){for(let[id,p]of placed.entries())if(!excludeIds?.has(id)&&x>=p.x&&x<=p.x+p.width-1&&y>=p.y&&y<=p.y+p.height-1)return!0;return!1}function findClearColumn(startX,y1,y2,excludeIds){let clear=!0;for(let y=Math.min(y1,y2);y<=Math.max(y1,y2);y++)if(isInsideBox(startX,y,excludeIds)){clear=!1;break}if(clear)return startX;for(let offset=1;offset<totalW+10;offset++){let rightX=startX+offset;clear=!0;for(let y=Math.min(y1,y2);y<=Math.max(y1,y2);y++)if(isInsideBox(rightX,y,excludeIds)){clear=!1;break}if(clear)return rightX;let leftX=startX-offset;if(leftX>=0){clear=!0;for(let y=Math.min(y1,y2);y<=Math.max(y1,y2);y++)if(isInsideBox(leftX,y,excludeIds)){clear=!1;break}if(clear)return leftX}}return totalW+2}let H=useAscii?"-":"\u2500",V=useAscii?"|":"\u2502",dashH=useAscii?".":"\u254C",dashV=useAscii?":":"\u250A";for(let rel of diagram.relationships){let fromP=placed.get(rel.from),toP=placed.get(rel.to);if(!fromP||!toP)continue;let marker=getRelMarker(rel.type,rel.markerAt),lineH=marker.dashed?dashH:H,lineV=marker.dashed?dashV:V,excludeIds=new Set([rel.from,rel.to]),fromCX=fromP.x+Math.floor(fromP.width/2),fromBY=fromP.y+fromP.height-1,toCX=toP.x+Math.floor(toP.width/2),toTY=toP.y;if(fromBY<toTY){let routeX=findClearColumn(fromCX,fromBY+1,toTY-1,excludeIds),needsDetour=routeX!==fromCX;if(routeX>=totalW&&increaseSize(canvas,routeX+2,totalH),needsDetour){let exitY=fromBY+1,entryY=toTY-1,lx1=Math.min(fromCX,routeX),rx1=Math.max(fromCX,routeX);for(let x=lx1;x<=rx1;x++)setC(x,exitY,lineH,"line");!useAscii&&exitY<(canvas[0]?.length??0)&&(fromCX<routeX?(setC(fromCX,exitY,"\u2514","corner"),setC(routeX,exitY,"\u2510","corner")):(setC(fromCX,exitY,"\u2518","corner"),setC(routeX,exitY,"\u250C","corner")));for(let y=exitY+1;y<=entryY;y++)setC(routeX,y,lineV,"line");if(routeX!==toCX){let lx2=Math.min(routeX,toCX),rx2=Math.max(routeX,toCX);for(let x=lx2;x<=rx2;x++)setC(x,entryY,lineH,"line");!useAscii&&entryY<(canvas[0]?.length??0)&&(routeX<toCX?(setC(routeX,entryY,"\u2514","corner"),setC(toCX,entryY,"\u2510","corner")):(setC(routeX,entryY,"\u2518","corner"),setC(toCX,entryY,"\u250C","corner")))}if(marker.markerAt==="to"){let markerChar=getMarkerShape(marker.type,useAscii,"down");setC(toCX,entryY,markerChar,"arrow")}if(marker.markerAt==="from"){let markerChar=getMarkerShape(marker.type,useAscii,"down");setC(fromCX,fromBY+1,markerChar,"arrow")}}else{let midY=fromBY+Math.floor((toTY-fromBY)/2);for(let y=fromBY+1;y<=midY;y++)setC(fromCX,y,lineV,"line");if(fromCX!==toCX&&midY<(canvas[0]?.length??0)){let lx=Math.min(fromCX,toCX),rx=Math.max(fromCX,toCX);for(let x=lx;x<=rx;x++)setC(x,midY,lineH,"line");useAscii||(setC(fromCX,midY,fromCX<toCX?"\u2514":"\u2518","corner"),setC(toCX,midY,fromCX<toCX?"\u2510":"\u250C","corner"))}for(let y=midY+1;y<toTY;y++)setC(toCX,y,lineV,"line");marker.markerAt==="to"&&setC(toCX,toTY-1,getMarkerShape(marker.type,useAscii,"down"),"arrow"),marker.markerAt==="from"&&setC(fromCX,fromBY+1,getMarkerShape(marker.type,useAscii,"down"),"arrow")}}else if(toP.y+toP.height-1<fromP.y){let fromTY=fromP.y,toBY=toP.y+toP.height-1,midY=toBY+Math.floor((fromTY-toBY)/2);for(let y=fromTY-1;y>=midY;y--)setC(fromCX,y,lineV,"line");if(fromCX!==toCX){let lx=Math.min(fromCX,toCX),rx=Math.max(fromCX,toCX);for(let x=lx;x<=rx;x++)setC(x,midY,lineH,"line");!useAscii&&midY>=0&&midY<totalH&&(setC(fromCX,midY,fromCX<toCX?"\u250C":"\u2510","corner"),setC(toCX,midY,fromCX<toCX?"\u2518":"\u2514","corner"))}for(let y=midY-1;y>toBY;y--)setC(toCX,y,lineV,"line");if(marker.markerAt==="from"){let markerChar=getMarkerShape(marker.type,useAscii,"up"),my=fromTY-1;for(let i=0;i<markerChar.length;i++)setC(fromCX-Math.floor(markerChar.length/2)+i,my,markerChar[i],"arrow")}if(marker.markerAt==="to"){let markerDir=marker.type==="inheritance"||marker.type==="realization"?"down":"up",markerChar=getMarkerShape(marker.type,useAscii,markerDir),my=toBY+1;for(let i=0;i<markerChar.length;i++)setC(toCX-Math.floor(markerChar.length/2)+i,my,markerChar[i],"arrow")}}else{let detourY=Math.max(fromBY,toP.y+toP.height-1)+2;increaseSize(canvas,totalW,detourY+1),increaseRoleCanvasSize(rc,totalW,detourY+1);for(let y=fromBY+1;y<=detourY;y++)setC(fromCX,y,lineV,"line");let lx=Math.min(fromCX,toCX),rx=Math.max(fromCX,toCX);for(let x=lx;x<=rx;x++)setC(x,detourY,lineH,"line");for(let y=detourY-1;y>=toP.y+toP.height;y--)setC(toCX,y,lineV,"line");if(marker.markerAt==="from"){let markerChar=getMarkerShape(marker.type,useAscii,"down"),my=fromBY+1;for(let i=0;i<markerChar.length;i++)setC(fromCX-Math.floor(markerChar.length/2)+i,my,markerChar[i],"arrow")}if(marker.markerAt==="to"){let markerChar=getMarkerShape(marker.type,useAscii,"up"),my=toP.y+toP.height;for(let i=0;i<markerChar.length;i++)setC(toCX-Math.floor(markerChar.length/2)+i,my,markerChar[i],"arrow")}}if(rel.label){let lines2=splitLines(rel.label),maxLabelWidth=Math.max(...lines2.map(l=>l.length))+2,baseMidY,idealMidX;if(fromBY<toTY)baseMidY=Math.floor((fromBY+1+toTY-1)/2),idealMidX=Math.floor((fromCX+toCX)/2);else if(toP.y+toP.height-1<fromP.y){let toBY=toP.y+toP.height-1;baseMidY=Math.floor((toBY+1+fromP.y-1)/2),idealMidX=Math.floor((fromCX+toCX)/2)}else baseMidY=Math.max(fromBY,toP.y+toP.height-1)+2,idealMidX=Math.floor((fromCX+toCX)/2);let labelY=baseMidY,halfHeight=Math.floor(lines2.length/2),labelInBox=!1;for(let i=0;i<lines2.length;i++){let y=labelY-halfHeight+i,idealLabelStart=idealMidX-Math.floor(maxLabelWidth/2),labelStart=Math.max(0,idealLabelStart);for(let x=labelStart;x<labelStart+maxLabelWidth;x++)if(isInsideBox(x,y,excludeIds)){labelInBox=!0;break}if(labelInBox)break}if(labelInBox){let gapTop=fromBY+1,gapBottom=toTY-1;for(let y=gapTop;y<=gapBottom;y++){let clearRow=!0,idealLabelStart=idealMidX-Math.floor(maxLabelWidth/2),labelStart=Math.max(0,idealLabelStart);for(let x=labelStart;x<labelStart+maxLabelWidth;x++)if(isInsideBox(x,y,excludeIds)){clearRow=!1;break}if(clearRow){labelY=y;break}}}let startY=labelY-halfHeight;for(let lineIdx=0;lineIdx<lines2.length;lineIdx++){let paddedLine=` ${lines2[lineIdx]} `,idealLabelStart=idealMidX-Math.floor(paddedLine.length/2),labelStart=Math.max(0,idealLabelStart),y=startY+lineIdx,labelEnd=labelStart+paddedLine.length;labelEnd>0&&y>=0&&(increaseSize(canvas,Math.max(labelEnd,1),Math.max(y+1,1)),increaseRoleCanvasSize(rc,Math.max(labelEnd,1),Math.max(y+1,1)));for(let i=0;i<paddedLine.length;i++){let lx=labelStart+i;lx>=0&&y>=0&&setC(lx,y,paddedLine[i],"text")}}}}return canvasToString(canvas,{roleCanvas:rc,colorMode,theme})}function parseErDiagram(lines){let diagram={entities:[],relationships:[]},entityMap=new Map,currentEntity=null;for(let i=1;i<lines.length;i++){let line=lines[i];if(currentEntity){if(line==="}"){currentEntity=null;continue}let attr=parseAttribute(line);attr&¤tEntity.attributes.push(attr);continue}let entityBlockMatch=line.match(/^(\S+)\s*\{$/);if(entityBlockMatch){let id=entityBlockMatch[1];currentEntity=ensureEntity(entityMap,id);continue}let rel=parseRelationshipLine(line);if(rel){ensureEntity(entityMap,rel.entity1),ensureEntity(entityMap,rel.entity2),diagram.relationships.push(rel);continue}}return diagram.entities=[...entityMap.values()],diagram}function ensureEntity(entityMap,id){let entity=entityMap.get(id);return entity||(entity={id,label:id,attributes:[]},entityMap.set(id,entity)),entity}function parseAttribute(line){let match=line.match(/^(\S+)\s+(\S+)(?:\s+(.+))?$/);if(!match)return null;let type=match[1],name=match[2],rest=match[3]?.trim()??"",keys=[],comment,commentMatch=rest.match(/"([^"]*)"/);commentMatch&&(comment=normalizeBrTags(commentMatch[1]));let restWithoutComment=rest.replace(/"[^"]*"/,"").trim();for(let part of restWithoutComment.split(/\s+/)){let upper=part.toUpperCase();(upper==="PK"||upper==="FK"||upper==="UK")&&keys.push(upper)}return{type,name,keys,comment}}function parseRelationshipLine(line){let match=line.match(/^(\S+)\s+([|o}{]+(?:--|\.\.)[|o}{]+)\s+(\S+)\s*:\s*(.+)$/);if(!match)return null;let entity1=match[1],cardinalityStr=match[2],entity2=match[3],rawLabel=match[4].trim().replace(/^["']|["']$/g,""),label=normalizeBrTags(rawLabel),lineMatch=cardinalityStr.match(/^([|o}{]+)(--|\.\.?)([|o}{]+)$/);if(!lineMatch)return null;let leftStr=lineMatch[1],lineStyle=lineMatch[2],rightStr=lineMatch[3],cardinality1=parseCardinality(leftStr),cardinality2=parseCardinality(rightStr),identifying=lineStyle==="--";return!cardinality1||!cardinality2?null:{entity1,entity2,cardinality1,cardinality2,label,identifying}}function parseCardinality(str){let sorted=str.split("").sort().join("");return sorted==="||"?"one":sorted==="o|"?"zero-one":sorted==="|}"||sorted==="{|"?"many":sorted==="{o"||sorted==="o{"?"zero-many":null}function classifyBoxChar2(ch){return/^[┌┐└┘├┤┬┴┼│─╭╮╰╯+\-|]$/.test(ch)?"border":"text"}function formatAttribute(attr){return`${attr.keys.length>0?attr.keys.join(",")+" ":" "}${attr.type} ${attr.name}`}function buildEntitySections(entity){let header=splitLines(entity.label),attrs=entity.attributes.map(formatAttribute);return attrs.length===0?[header]:[header,attrs]}function getCrowsFootChars(card,useAscii,isRight=!1){if(useAscii)switch(card){case"one":return"|";case"zero-one":return"o|";case"many":return isRight?"<":">";case"zero-many":return isRight?"o<":">o"}else switch(card){case"one":return"\u2502";case"zero-one":return"\u25CB\u2502";case"many":return isRight?"\u255F":"\u2562";case"zero-many":return isRight?"\u25CB\u255F":"\u2562\u25CB"}}function findConnectedComponents(diagram){let visited=new Set,components=[],neighbors=new Map;for(let ent of diagram.entities)neighbors.set(ent.id,new Set);for(let rel of diagram.relationships)neighbors.get(rel.entity1)?.add(rel.entity2),neighbors.get(rel.entity2)?.add(rel.entity1);function dfs(startId,component){let stack=[startId];for(;stack.length>0;){let nodeId=stack.pop();if(!visited.has(nodeId)){visited.add(nodeId),component.add(nodeId);for(let neighbor of neighbors.get(nodeId)??[])visited.has(neighbor)||stack.push(neighbor)}}}for(let ent of diagram.entities)if(!visited.has(ent.id)){let component=new Set;dfs(ent.id,component),component.size>0&&components.push(component)}return components}function renderErAscii(text,config,colorMode,theme){let lines=text.split(`
9`).map(l=>l.trim()).filter(l=>l.length>0&&!l.startsWith("%%")),diagram=parseErDiagram(lines);if(diagram.entities.length===0)return"";let useAscii=config.useAscii,hGap=6,vGap=4,componentGap=6,entitySections=new Map,entityBoxW=new Map,entityBoxH=new Map,entityById=new Map;for(let ent of diagram.entities){entityById.set(ent.id,ent);let sections=buildEntitySections(ent);entitySections.set(ent.id,sections);let maxTextW=0;for(let section of sections)for(let line of section)maxTextW=Math.max(maxTextW,line.length);let boxW=maxTextW+4,totalLines=0;for(let section of sections)totalLines+=Math.max(section.length,1);let boxH=totalLines+(sections.length-1)+2;entityBoxW.set(ent.id,boxW),entityBoxH.set(ent.id,boxH)}let components=findConnectedComponents(diagram),placed=new Map,currentY=0;for(let component of components){let componentEntities=diagram.entities.filter(e=>component.has(e.id)),maxPerRow=Math.max(2,Math.ceil(Math.sqrt(componentEntities.length))),currentX=0,maxRowH=0,colCount=0,componentStartY=currentY;for(let ent of componentEntities){let w=entityBoxW.get(ent.id),h=entityBoxH.get(ent.id);colCount>=maxPerRow&&(currentY+=maxRowH+vGap,currentX=0,maxRowH=0,colCount=0),placed.set(ent.id,{entity:ent,sections:entitySections.get(ent.id),x:currentX,y:currentY,width:w,height:h}),currentX+=w+hGap,maxRowH=Math.max(maxRowH,h),colCount++}currentY+=maxRowH+componentGap}let totalW=0,totalH=0;for(let p of placed.values())totalW=Math.max(totalW,p.x+p.width),totalH=Math.max(totalH,p.y+p.height);totalW+=4,totalH+=2;let canvas=mkCanvas(totalW-1,totalH-1),rc=mkRoleCanvas(totalW-1,totalH-1);function setC(x,y,ch,role){x>=0&&x<canvas.length&&y>=0&&y<(canvas[0]?.length??0)&&(canvas[x][y]=ch,setRole(rc,x,y,role))}for(let p of placed.values()){let boxCanvas=drawMultiBox(p.sections,useAscii);for(let bx=0;bx<boxCanvas.length;bx++)for(let by=0;by<boxCanvas[0].length;by++){let ch=boxCanvas[bx][by];if(ch!==" "){let cx=p.x+bx,cy=p.y+by;cx<totalW&&cy<totalH&&setC(cx,cy,ch,classifyBoxChar2(ch))}}}let H=useAscii?"-":"\u2500",V=useAscii?"|":"\u2502",dashH=useAscii?".":"\u254C",dashV=useAscii?":":"\u250A";for(let rel of diagram.relationships){let e1=placed.get(rel.entity1),e2=placed.get(rel.entity2);if(!e1||!e2)continue;let lineH=rel.identifying?H:dashH,lineV=rel.identifying?V:dashV,e1CX=e1.x+Math.floor(e1.width/2),e1CY=e1.y+Math.floor(e1.height/2),e2CX=e2.x+Math.floor(e2.width/2),e2CY=e2.y+Math.floor(e2.height/2);if(Math.abs(e1CY-e2CY)<Math.max(e1.height,e2.height)){let[left,right]=e1CX<e2CX?[e1,e2]:[e2,e1],[leftCard,rightCard]=e1CX<e2CX?[rel.cardinality1,rel.cardinality2]:[rel.cardinality2,rel.cardinality1],startX=left.x+left.width,endX=right.x-1,lineY=left.y+Math.floor(left.height/2);for(let x=startX;x<=endX;x++)setC(x,lineY,lineH,"line");let leftChars=getCrowsFootChars(leftCard,useAscii,!1);for(let i=0;i<leftChars.length;i++)setC(startX+i,lineY,leftChars[i],"arrow");let rightChars=getCrowsFootChars(rightCard,useAscii,!0);for(let i=0;i<rightChars.length;i++)setC(endX-rightChars.length+1+i,lineY,rightChars[i],"arrow");if(rel.label){let lines2=splitLines(rel.label),gapMid=Math.floor((startX+endX)/2);for(let lineIdx=0;lineIdx<lines2.length;lineIdx++){let line=lines2[lineIdx],labelStart=Math.max(startX,gapMid-Math.floor(line.length/2)),labelY=lineY+1+lineIdx;increaseSize(canvas,Math.max(labelStart+line.length,1),Math.max(labelY+1,1)),increaseRoleCanvasSize(rc,Math.max(labelStart+line.length,1),Math.max(labelY+1,1));for(let i=0;i<line.length;i++){let lx=labelStart+i;lx>=startX&&lx<=endX&&setC(lx,labelY,line[i],"text")}}}}else{let[upper,lower]=e1CY<e2CY?[e1,e2]:[e2,e1],[upperCard,lowerCard]=e1CY<e2CY?[rel.cardinality1,rel.cardinality2]:[rel.cardinality2,rel.cardinality1],startY=upper.y+upper.height,endY=lower.y-1,lineX=upper.x+Math.floor(upper.width/2);for(let y=startY;y<=endY;y++)setC(lineX,y,lineV,"line");let lowerCX=lower.x+Math.floor(lower.width/2);if(lineX!==lowerCX){let midY=Math.floor((startY+endY)/2),lx=Math.min(lineX,lowerCX),rx=Math.max(lineX,lowerCX);for(let x=lx;x<=rx;x++)setC(x,midY,lineH,"line");for(let y=midY+1;y<=endY;y++)setC(lowerCX,y,lineV,"line")}let upperChars=getCrowsFootChars(upperCard,useAscii,!1);for(let i=0;i<upperChars.length;i++)setC(lineX-Math.floor(upperChars.length/2)+i,startY,upperChars[i],"arrow");let targetX=lineX!==lowerCX?lowerCX:lineX,lowerChars=getCrowsFootChars(lowerCard,useAscii,!0);for(let i=0;i<lowerChars.length;i++)setC(targetX-Math.floor(lowerChars.length/2)+i,endY,lowerChars[i],"arrow");if(rel.label){let lines2=splitLines(rel.label),startLabelY=Math.floor((startY+endY)/2)-Math.floor((lines2.length-1)/2);for(let lineIdx=0;lineIdx<lines2.length;lineIdx++){let line=lines2[lineIdx],labelX=lineX+2,y=startLabelY+lineIdx;if(y>=0)for(let i=0;i<line.length;i++){let lx=labelX+i;lx>=0&&(increaseSize(canvas,lx+1,y+1),increaseRoleCanvasSize(rc,lx+1,y+1),setC(lx,y,line[i],"text"))}}}}}return canvasToString(canvas,{roleCanvas:rc,colorMode,theme})}function parseXYChart(lines){let xAxis={},yAxis={},series=[],title,horizontal=!1;for(let line of lines){if(/^xychart(-beta)?\b/i.test(line)){/\bhorizontal\b/i.test(line)&&(horizontal=!0);continue}let titleMatch=line.match(/^title\s+"([^"]+)"/);if(titleMatch){title=titleMatch[1];continue}let xCatMatch=line.match(/^x-axis\s+(?:"([^"]*)"\s*)?\[([^\]]+)\]/);if(xCatMatch){xCatMatch[1]&&(xAxis.title=xCatMatch[1]),xAxis.categories=xCatMatch[2].split(",").map(s=>s.trim());continue}let xRangeMatch=line.match(/^x-axis\s+(?:"([^"]*)"\s+)?(-?\d+(?:\.\d+)?)\s*-->\s*(-?\d+(?:\.\d+)?)/);if(xRangeMatch){xRangeMatch[1]&&(xAxis.title=xRangeMatch[1]),xAxis.range={min:parseFloat(xRangeMatch[2]),max:parseFloat(xRangeMatch[3])};continue}let yRangeMatch=line.match(/^y-axis\s+(?:"([^"]*)"\s+)?(-?\d+(?:\.\d+)?)\s*-->\s*(-?\d+(?:\.\d+)?)/);if(yRangeMatch){yRangeMatch[1]&&(yAxis.title=yRangeMatch[1]),yAxis.range={min:parseFloat(yRangeMatch[2]),max:parseFloat(yRangeMatch[3])};continue}let yTitleOnly=line.match(/^y-axis\s+"([^"]+)"\s*$/);if(yTitleOnly){yAxis.title=yTitleOnly[1];continue}let barMatch=line.match(/^bar\s+\[([^\]]+)\]/);if(barMatch){series.push({type:"bar",data:parseNumericArray(barMatch[1])});continue}let lineMatch=line.match(/^line\s+\[([^\]]+)\]/);if(lineMatch){series.push({type:"line",data:parseNumericArray(lineMatch[1])});continue}}if(!yAxis.range&&series.length>0){let allValues=series.flatMap(s=>s.data),min=Math.min(...allValues),max=Math.max(...allValues),span=max-min||1;min=min-span*.1,max=max+span*.1,min>0&&min<span*.5&&(min=0),yAxis.range={min,max}}return yAxis.range||(yAxis.range={min:0,max:100}),{title,horizontal,xAxis,yAxis,series}}function parseNumericArray(str){return str.split(",").map(s=>parseFloat(s.trim()))}var CHART_ACCENT_FALLBACK="#3b82f6";function hexToHsl(hex){let h=hex.replace("#",""),ri=parseInt(h.substring(0,2),16)/255,gi=parseInt(h.substring(2,4),16)/255,bi=parseInt(h.substring(4,6),16)/255,max=Math.max(ri,gi,bi),min=Math.min(ri,gi,bi),l=(max+min)/2;if(max===min)return[0,0,l*100];let d=max-min,s=l>.5?d/(2-max-min):d/(max+min),hue;return max===ri?hue=((gi-bi)/d+(gi<bi?6:0))/6:max===gi?hue=((bi-ri)/d+2)/6:hue=((ri-gi)/d+4)/6,[hue*360,s*100,l*100]}function hslToHex(h,s,l){let si=s/100,li=l/100,c=(1-Math.abs(2*li-1))*si,x=c*(1-Math.abs(h/60%2-1)),m=li-c/2,r,g,b;h<60?(r=c,g=x,b=0):h<120?(r=x,g=c,b=0):h<180?(r=0,g=c,b=x):h<240?(r=0,g=x,b=c):h<300?(r=x,g=0,b=c):(r=c,g=0,b=x);let toHex=v=>Math.round((v+m)*255).toString(16).padStart(2,"0");return`#${toHex(r)}${toHex(g)}${toHex(b)}`}function isValidHex(color){return/^#[0-9a-fA-F]{6}$/.test(color)}function isDarkBackground(bgHex){return hexToHsl(bgHex)[2]<50}function getSeriesColor(index,accentColor,bgColor){if(index===0)return accentColor;let safeAccent=isValidHex(accentColor)?accentColor:CHART_ACCENT_FALLBACK,safeBg=bgColor&&isValidHex(bgColor)?bgColor:void 0,[h,s]=hexToHsl(safeAccent),chartS=Math.max(55,Math.min(85,s)),tier=Math.ceil(index/2),oddIndex=index%2===1,dark=safeBg&&isDarkBackground(safeBg)?!oddIndex:oddIndex,l=dark?Math.max(25,48-tier*13):Math.min(78,55+tier*11),hShift=(dark?-8:12)*tier,newH=((h+hShift)%360+360)%360;return hslToHex(newH,chartS,l)}var PLOT_WIDTH=60,PLOT_HEIGHT=20,UNI={hLine:"\u2500",vLine:"\u2502",origin:"\u253C",yTick:"\u2524",xTick:"\u252C",bar:"\u2588",grid:"\xB7",cornerTL:"\u256D",cornerTR:"\u256E",cornerBL:"\u2570",cornerBR:"\u256F"},ASC={hLine:"-",vLine:"|",origin:"+",yTick:"+",xTick:"+",bar:"#",grid:".",cornerTL:"+",cornerTR:"+",cornerBL:"+",cornerBR:"+"};function getSeriesColors(total,theme){let accent=theme.accent??CHART_ACCENT_FALLBACK;return total<=1?[accent]:Array.from({length:total},(_,i)=>getSeriesColor(i,accent,theme.bg))}function roleToHex(role,theme){switch(role){case"text":return theme.fg;case"border":return theme.border;case"line":return theme.line;case"arrow":return theme.arrow;case"corner":return theme.corner??theme.line;case"junction":return theme.junction??theme.border;default:return theme.fg}}function renderXYChartAscii(text,config,colorMode,theme){let lines=text.split(`
10`).map(l=>l.trim()).filter(l=>l.length>0&&!l.startsWith("%%")),chart=parseXYChart(lines),ch=config.useAscii?ASC:UNI;return chart.horizontal?renderHorizontal(chart,ch,colorMode,theme):renderVertical(chart,ch,colorMode,theme)}function renderVertical(chart,ch,colorMode,theme){let dataCount=getDataCount(chart);if(dataCount===0)return"";let yRange=chart.yAxis.range,yTicks=niceTickValues(yRange.min,yRange.max),yLabels=yTicks.map(v=>formatTickValue(v)),yGutter=Math.max(...yLabels.map(l=>l.length))+1,plotW=Math.max(PLOT_WIDTH,dataCount*6),plotH=PLOT_HEIGHT,bandW=Math.floor(plotW/dataCount),catLabels=getCategoryLabels(chart,dataCount),hasTitle=!!chart.title,hasXTitle=!!chart.xAxis.title,hasLegend=chart.series.length>1,titleRow=hasTitle?0:-1,plotTop=(hasTitle?2:0)+(hasLegend?1:0),plotLeft=yGutter+1,totalW=plotLeft+bandW*dataCount+2,xAxisRow=plotTop+plotH,xLabelRow=xAxisRow+1,xTitleRow=hasXTitle?xLabelRow+1:-1,totalH=xLabelRow+1+(hasXTitle?1:0)+0,canvas=createCanvas(totalW,totalH),roles=createRoleCanvas(totalW,totalH),hexColors=createHexCanvas(totalW,totalH),seriesColors=getSeriesColors(chart.series.length,theme),valueToRow=v=>{let t=(v-yRange.min)/(yRange.max-yRange.min||1);return Math.round(t*(plotH-1))},bandCenter=i=>plotLeft+Math.floor(bandW*(i+.5));hasTitle&&titleRow>=0&&writeText(canvas,roles,titleRow,Math.floor(totalW/2-chart.title.length/2),chart.title,"text"),hasLegend&&drawLegend(canvas,roles,hexColors,chart,hasTitle?1:0,totalW,ch,seriesColors);for(let row=0;row<plotH;row++){let displayRow=plotTop+(plotH-1-row);set(canvas,roles,displayRow,plotLeft-1,ch.vLine,"border")}set(canvas,roles,xAxisRow,plotLeft-1,ch.origin,"border");for(let tick of yTicks){let row=valueToRow(tick);if(row<0||row>=plotH)continue;let displayRow=plotTop+(plotH-1-row),label=formatTickValue(tick);set(canvas,roles,displayRow,plotLeft-1,row===0?ch.origin:ch.yTick,"border");let labelStart=yGutter-label.length;writeText(canvas,roles,displayRow,Math.max(0,labelStart),label,"text")}for(let c=plotLeft;c<plotLeft+bandW*dataCount;c++)set(canvas,roles,xAxisRow,c,ch.hLine,"border");for(let i=0;i<dataCount;i++){let cx=bandCenter(i);set(canvas,roles,xAxisRow,cx,ch.xTick,"border");let label=catLabels[i],labelStart=cx-Math.floor(label.length/2);writeText(canvas,roles,xLabelRow,Math.max(0,labelStart),label,"text")}if(hasXTitle&&xTitleRow>=0){let title=chart.xAxis.title;writeText(canvas,roles,xTitleRow,Math.floor(totalW/2-title.length/2),title,"text")}for(let tick of yTicks){let row=valueToRow(tick);if(row<0||row>=plotH)continue;let displayRow=plotTop+(plotH-1-row);for(let c=plotLeft;c<plotLeft+bandW*dataCount;c++)get(canvas,displayRow,c)===" "&&set(canvas,roles,displayRow,c,ch.grid,"line")}let barEntries=[];for(let si=0;si<chart.series.length;si++)chart.series[si].type==="bar"&&barEntries.push({data:chart.series[si].data,globalIdx:si});if(barEntries.length>0){let barCount=barEntries.length,usable=Math.max(1,bandW-2),singleBarW=Math.max(1,Math.min(Math.floor(usable/barCount),8)),groupW=singleBarW*barCount+(barCount-1),baseRow=valueToRow(Math.max(0,yRange.min));for(let bIdx=0;bIdx<barEntries.length;bIdx++){let entry=barEntries[bIdx],hexColor=seriesColors[entry.globalIdx];for(let i=0;i<entry.data.length;i++){let bx=bandCenter(i)-Math.floor(groupW/2)+bIdx*(singleBarW+1),valRow=valueToRow(entry.data[i]),fromRow=Math.min(baseRow,valRow),toRow=Math.max(baseRow,valRow);for(let row=fromRow;row<=toRow;row++){let displayRow=plotTop+(plotH-1-row);for(let c=bx;c<bx+singleBarW;c++)set(canvas,roles,displayRow,c,ch.bar,"arrow",hexColors,hexColor)}}}}let lineEntries=[];for(let si=0;si<chart.series.length;si++)chart.series[si].type==="line"&&lineEntries.push({data:chart.series[si].data,globalIdx:si});for(let entry of lineEntries){if(entry.data.length===0)continue;let hexColor=seriesColors[entry.globalIdx];drawStaircaseLine(canvas,roles,entry.data,bandCenter,valueToRow,plotTop,plotH,plotLeft,bandW*dataCount,ch,hexColors,hexColor)}return canvasToString2(canvas,roles,hexColors,colorMode,theme)}function renderHorizontal(chart,ch,colorMode,theme){let dataCount=getDataCount(chart);if(dataCount===0)return"";let yRange=chart.yAxis.range,valueTicks=niceTickValues(yRange.min,yRange.max),catLabels=getCategoryLabels(chart,dataCount),catGutter=Math.max(...catLabels.map(l=>l.length))+1,plotW=Math.max(PLOT_WIDTH,40),bandH=Math.max(2,Math.floor(PLOT_HEIGHT/dataCount)),plotH=bandH*dataCount,hasTitle=!!chart.title,hasYTitle=!!chart.yAxis.title,hasLegend=chart.series.length>1,plotTop=(hasTitle?2:0)+(hasLegend?1:0),plotLeft=catGutter+1,totalW=plotLeft+plotW+2,totalH=plotTop+plotH+2+(hasYTitle?1:0),xAxisRow=plotTop+plotH,canvas=createCanvas(totalW,totalH),roles=createRoleCanvas(totalW,totalH),hexColors=createHexCanvas(totalW,totalH),seriesColors=getSeriesColors(chart.series.length,theme),valueToCol=v=>{let t=(v-yRange.min)/(yRange.max-yRange.min||1);return plotLeft+Math.round(t*(plotW-1))},bandMid=i=>plotTop+Math.floor(bandH*(i+.5));hasTitle&&writeText(canvas,roles,0,Math.floor(totalW/2-chart.title.length/2),chart.title,"text"),hasLegend&&drawLegend(canvas,roles,hexColors,chart,hasTitle?1:0,totalW,ch,seriesColors);for(let r=plotTop;r<plotTop+plotH;r++)set(canvas,roles,r,plotLeft-1,ch.vLine,"border");set(canvas,roles,xAxisRow,plotLeft-1,ch.origin,"border");for(let i=0;i<dataCount;i++){let my=bandMid(i),label=catLabels[i],labelStart=catGutter-label.length;writeText(canvas,roles,my,Math.max(0,labelStart),label,"text")}for(let c=plotLeft;c<plotLeft+plotW;c++)set(canvas,roles,xAxisRow,c,ch.hLine,"border");for(let tick of valueTicks){let cx=valueToCol(tick);if(cx<plotLeft||cx>=plotLeft+plotW)continue;set(canvas,roles,xAxisRow,cx,ch.xTick,"border");let label=formatTickValue(tick);writeText(canvas,roles,xAxisRow+1,cx-Math.floor(label.length/2),label,"text")}if(hasYTitle){let title=chart.yAxis.title;writeText(canvas,roles,totalH-1,Math.floor(totalW/2-title.length/2),title,"text")}for(let tick of valueTicks){let cx=valueToCol(tick);if(!(cx<plotLeft||cx>=plotLeft+plotW))for(let r=plotTop;r<plotTop+plotH;r++)get(canvas,r,cx)===" "&&set(canvas,roles,r,cx,ch.grid,"line")}let barEntries=[];for(let si=0;si<chart.series.length;si++)chart.series[si].type==="bar"&&barEntries.push({data:chart.series[si].data,globalIdx:si});if(barEntries.length>0){let barCount=barEntries.length,singleBarH=1,groupH=singleBarH*barCount+(barCount-1),baseCol=valueToCol(Math.max(0,yRange.min));for(let bIdx=0;bIdx<barEntries.length;bIdx++){let entry=barEntries[bIdx],hexColor=seriesColors[entry.globalIdx];for(let i=0;i<entry.data.length;i++){let by=bandMid(i)-Math.floor(groupH/2)+bIdx*(singleBarH+1),valCol=valueToCol(entry.data[i]),fromCol=Math.min(baseCol,valCol),toCol=Math.max(baseCol,valCol);for(let r=by;r<by+singleBarH;r++)for(let c=fromCol;c<=toCol;c++)set(canvas,roles,r,c,ch.bar,"arrow",hexColors,hexColor)}}}let lineEntries=[];for(let si=0;si<chart.series.length;si++)chart.series[si].type==="line"&&lineEntries.push({data:chart.series[si].data,globalIdx:si});for(let entry of lineEntries){if(entry.data.length===0)continue;let hexColor=seriesColors[entry.globalIdx];drawHorizontalStaircaseLine(canvas,roles,entry.data,bandMid,valueToCol,plotTop,plotH,plotLeft,plotW,ch,hexColors,hexColor)}return canvasToString2(canvas,roles,hexColors,colorMode,theme)}function drawStaircaseLine(canvas,roles,data,bandCenter,valueToRow,plotTop,plotH,plotLeft,plotTotalW,ch,hexCanvas,hexColor){if(data.length===0)return;let points=data.map((v,i)=>({col:bandCenter(i),row:valueToRow(v)})),drawAt=(col,row,char)=>{let displayRow=plotTop+(plotH-1-row);displayRow>=0&&col>=plotLeft&&col<plotLeft+plotTotalW&&set(canvas,roles,displayRow,col,char,"arrow",hexCanvas,hexColor)};if(points.length===1){drawAt(points[0].col,points[0].row,ch.hLine);return}for(let i=0;i<points.length-1;i++){let p1=points[i],p2=points[i+1];if(p1.row===p2.row){for(let c=p1.col;c<=p2.col;c++)drawAt(c,p1.row,ch.hLine);continue}let midCol=Math.round((p1.col+p2.col)/2),goingUp=p2.row>p1.row;for(let c=p1.col;c<midCol;c++)drawAt(c,p1.row,ch.hLine);goingUp?drawAt(midCol,p1.row,ch.cornerBR):drawAt(midCol,p1.row,ch.cornerTR);let minRow=Math.min(p1.row,p2.row),maxRow=Math.max(p1.row,p2.row);for(let row=minRow+1;row<maxRow;row++)drawAt(midCol,row,ch.vLine);goingUp?drawAt(midCol,p2.row,ch.cornerTL):drawAt(midCol,p2.row,ch.cornerBL);for(let c=midCol+1;c<=p2.col;c++)drawAt(c,p2.row,ch.hLine);if(i===0){let leadStart=Math.max(plotLeft,p1.col-Math.floor((p2.col-p1.col)/4));for(let c=leadStart;c<p1.col;c++)drawAt(c,p1.row,ch.hLine)}if(i===points.length-2){let trailEnd=Math.min(plotLeft+plotTotalW-1,p2.col+Math.floor((p2.col-p1.col)/4));for(let c=p2.col+1;c<=trailEnd;c++)drawAt(c,p2.row,ch.hLine)}}}function drawHorizontalStaircaseLine(canvas,roles,data,bandMid,valueToCol,plotTop,plotH,plotLeft,plotW,ch,hexCanvas,hexColor){if(data.length===0)return;let points=data.map((v,i)=>({row:bandMid(i),col:valueToCol(v)})),drawAt=(row,col,char)=>{row>=plotTop&&row<plotTop+plotH&&col>=plotLeft&&col<plotLeft+plotW&&set(canvas,roles,row,col,char,"arrow",hexCanvas,hexColor)};if(points.length===1){drawAt(points[0].row,points[0].col,ch.vLine);return}for(let i=0;i<points.length-1;i++){let p1=points[i],p2=points[i+1];if(p1.col===p2.col){for(let r=p1.row;r<=p2.row;r++)drawAt(r,p1.col,ch.vLine);continue}let midRow=Math.round((p1.row+p2.row)/2),goingRight=p2.col>p1.col;for(let r=p1.row;r<midRow;r++)drawAt(r,p1.col,ch.vLine);goingRight?drawAt(midRow,p1.col,ch.cornerBL):drawAt(midRow,p1.col,ch.cornerBR);let minCol=Math.min(p1.col,p2.col),maxCol=Math.max(p1.col,p2.col);for(let c=minCol+1;c<maxCol;c++)drawAt(midRow,c,ch.hLine);goingRight?drawAt(midRow,p2.col,ch.cornerTR):drawAt(midRow,p2.col,ch.cornerTL);for(let r=midRow+1;r<=p2.row;r++)drawAt(r,p2.col,ch.vLine)}}function drawLegend(canvas,roles,hexCanvas,chart,row,totalW,ch,seriesColors){let items=[],barIdx=0,lineIdx=0;for(let si=0;si<chart.series.length;si++)chart.series[si].type==="bar"?(items.push({symbol:ch.bar,label:`Bar ${barIdx+1}`,globalIdx:si}),barIdx++):(items.push({symbol:ch.hLine,label:`Line ${lineIdx+1}`,globalIdx:si}),lineIdx++);let totalLen=0;for(let i=0;i<items.length;i++)i>0&&(totalLen+=2),totalLen+=2+items[i].label.length;let col=Math.max(0,Math.floor(totalW/2-totalLen/2));for(let i=0;i<items.length;i++){i>0&&(col+=2);let item=items[i];set(canvas,roles,row,col,item.symbol,"arrow",hexCanvas,seriesColors[item.globalIdx]),col+=1,col+=1,writeText(canvas,roles,row,col,item.label,"text"),col+=item.label.length}}function createCanvas(width,height){return Array.from({length:width},()=>Array.from({length:height},()=>" "))}function createRoleCanvas(width,height){return Array.from({length:width},()=>Array.from({length:height}).fill(null))}function createHexCanvas(width,height){return Array.from({length:width},()=>Array.from({length:height}).fill(null))}function set(canvas,roles,row,col,char,role,hexCanvas,hex){col>=0&&col<canvas.length&&row>=0&&row<canvas[0].length&&(canvas[col][row]=char,roles[col][row]=role,hexCanvas&&hex&&(hexCanvas[col][row]=hex))}function get(canvas,row,col){return col>=0&&col<canvas.length&&row>=0&&row<canvas[0].length?canvas[col][row]:" "}function writeText(canvas,roles,row,startCol,text,role){for(let i=0;i<text.length;i++)set(canvas,roles,row,startCol+i,text[i],role)}function canvasToString2(canvas,roles,hexCanvas,colorMode,theme){if(canvas.length===0)return"";let height=canvas[0].length,width=canvas.length,lines=[];for(let row=0;row<height;row++){let chars=[],rowRoles=[],rowHex=[];for(let col=0;col<width;col++)chars.push(canvas[col][row]),rowRoles.push(roles[col][row]),rowHex.push(hexCanvas[col][row]);let end=chars.length-1;for(;end>=0&&chars[end]===" ";)end--;end<0?lines.push(""):lines.push(colorizeRow(chars.slice(0,end+1),rowRoles.slice(0,end+1),rowHex.slice(0,end+1),theme,colorMode))}for(;lines.length>0&&lines[lines.length-1]==="";)lines.pop();return lines.join(`
11`)}function colorizeRow(chars,roles,hexOverrides,theme,mode){if(mode==="none")return chars.join("");let result="",currentColor=null,buffer="";for(let i=0;i<chars.length;i++){let char=chars[i];if(char===" "){buffer.length>0&&(result+=currentColor?colorizeText(buffer,currentColor,mode):buffer,buffer="",currentColor=null),result+=" ";continue}let hexOvr=hexOverrides[i]??null,roleVal=roles[i]??null,color=hexOvr??(roleVal?roleToHex(roleVal,theme):null);color===currentColor?buffer+=char:(buffer.length>0&&(result+=currentColor?colorizeText(buffer,currentColor,mode):buffer),buffer=char,currentColor=color)}return buffer.length>0&&(result+=currentColor?colorizeText(buffer,currentColor,mode):buffer),result}function getDataCount(chart){if(chart.xAxis.categories)return chart.xAxis.categories.length;for(let s of chart.series)if(s.data.length>0)return s.data.length;return 0}function getCategoryLabels(chart,count){if(chart.xAxis.categories)return chart.xAxis.categories;if(chart.xAxis.range){let{min,max}=chart.xAxis.range,step=count>1?(max-min)/(count-1):0;return Array.from({length:count},(_,i)=>formatTickValue(min+step*i))}return Array.from({length:count},(_,i)=>String(i+1))}function niceTickValues(min,max){let range=max-min;if(range<=0)return[min];let rawInterval=range/6,magnitude=Math.pow(10,Math.floor(Math.log10(rawInterval))),residual=rawInterval/magnitude,niceInterval;residual<=1.5?niceInterval=magnitude:residual<=3?niceInterval=2*magnitude:residual<=7?niceInterval=5*magnitude:niceInterval=10*magnitude;let start=Math.ceil(min/niceInterval)*niceInterval,ticks=[];for(let v=start;v<=max+niceInterval*.001;v+=niceInterval)ticks.push(Math.round(v*1e10)/1e10);return ticks}function formatTickValue(v){return Number.isInteger(v)?String(v):v.toFixed(Math.abs(v)<10?1:0)}var setChartSize=(width,height)=>{PLOT_WIDTH=width,PLOT_HEIGHT=height};function detectDiagramType(text){let firstLine=text.trim().split(`
12`)[0]?.trim().toLowerCase()??"";return/^xychart(-beta)?\b/.test(firstLine)?"xychart":/^sequencediagram\s*$/.test(firstLine)?"sequence":/^classdiagram\s*$/.test(firstLine)?"class":/^erdiagram\s*$/.test(firstLine)?"er":"flowchart"}function renderMermaidASCII(text,options={}){let config={useAscii:options.useAscii??!1,paddingX:options.paddingX??5,paddingY:options.paddingY??5,boxBorderPadding:options.boxBorderPadding??1,graphDirection:"TD"},colorMode=options.colorMode==="auto"||options.colorMode===void 0?detectColorMode():options.colorMode,theme={...DEFAULT_ASCII_THEME,...options.theme};switch(detectDiagramType(text)){case"xychart":return renderXYChartAscii(text,config,colorMode,theme);case"sequence":return renderSequenceAscii(text,config,colorMode,theme);case"class":return renderClassAscii(text,config,colorMode,theme);case"er":return renderErAscii(text,config,colorMode,theme);default:{let parsed=parseMermaid(text);parsed.direction==="LR"||parsed.direction==="RL"?config.graphDirection="LR":config.graphDirection="TD";let graph=convertToAsciiGraph(parsed,config);return createMapping(graph),drawGraph(graph),parsed.direction==="BT"&&(flipCanvasVertically(graph.canvas),flipRoleCanvasVertically(graph.roleCanvas)),canvasToString(graph.canvas,{roleCanvas:graph.roleCanvas,colorMode,theme})}}}var renderMermaidAscii=renderMermaidASCII;export{renderMermaidAscii,setChartSize};
13hooks/vendor/pele.js 95 lines1export const loadPele = () => {
2var pele=(()=>{var gs=Object.defineProperty;var Dd=Object.getOwnPropertyDescriptor;var Id=Object.getOwnPropertyNames;var Nd=Object.prototype.hasOwnProperty;var Ld=(e,t)=>{for(var r in t)gs(e,r,{get:t[r],enumerable:!0})},Od=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Id(t))!Nd.call(e,n)&&n!==r&&gs(e,n,{get:()=>t[n],enumerable:!(i=Dd(t,n))||i.enumerable});return e};var Rd=e=>Od(gs({},"__esModule",{value:!0}),e);var _g={};Ld(_g,{render:()=>Ms});var zr=class{constructor(e){this.message=e}message},ln=64;function ja(e,t,r){t==="__proto__"?Object.defineProperty(e,t,{value:r,enumerable:!0,writable:!0,configurable:!0}):e[t]=r}var zd=class{lines;i=0;constructor(e){this.lines=e.replace(/\r\n?/g,`
3`).split(`
4`)}skipBlank(){for(;this.i<this.lines.length;){let e=this.lines[this.i].trim();if(e!==""&&e[0]!=="#"&&e!=="---")break;this.i++}}indent(){let e=this.lines[this.i],t=0;for(;t<e.length&&e[t]===" ";)t++;if(e[t]===" ")throw new Error("YAML: tabs are not allowed for indentation");return t}},Fd=/^[-+]?(?:0|[1-9][0-9]*)$/,Wd=/^[-+]?0x[0-9a-fA-F]+$/,Pd=/^[-+]?0o[0-7]+$/,Hd=/^[-+]?0b[01]+$/,Yd=/^[-+]?(?:[0-9][0-9]*(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][-+]?[0-9]+)?$/,Gd=/[\s#:,[\]{}&*!|>'"%@`]/;function ca(e){return e===" "||e===" "||e===`
5`||e==="\r"}function ms(e){let t=e[0],r,i;if(t==='"'||t==="'"){let l=1;for(;;){if(l>=e.length)return null;let s=e[l];if(t==='"'&&s==="\\")l+=2;else if(s===t){if(t==='"'||e[l+1]!=="'")break;l+=2}else l++}for(r=l+1,i=r;ca(e[i]);)i++;if(e[i]!==":")return null}else{if(t===void 0||Gd.test(t)||t==="-"&&(e.length<2||ca(e[1])||e[1]===":"||e[1]==="#"))return null;for(i=1;i<e.length&&e[i]!==":"&&e[i]!=="#";)i++;if(e[i]!==":")return null;for(r=i;ca(e[r-1]);)r--}let n=i+1;if(n<e.length&&!ca(e[n]))return null;for(;ca(e[n]);)n++;return{key:e.slice(0,r),length:n}}function $s(e){let t=e.trim();if(t===""||t==="~"||t==="null"||t==="Null"||t==="NULL")return null;if(t==="true"||t==="True"||t==="TRUE")return!0;if(t==="false"||t==="False"||t==="FALSE")return!1;if(Fd.test(t)||Yd.test(t))return Number(t);if(Wd.test(t)||Pd.test(t)||Hd.test(t)){let r=t[0]==="-",i=Number(r||t[0]==="+"?t.slice(1):t);return r?-i:i}return/^[-+]?\.(?:inf|Inf|INF)$/.test(t)?t[0]==="-"?-1/0:1/0:/^\.(?:nan|NaN|NAN)$/.test(t)?NaN:t}var an={0:"\0",a:"\x07",b:"\b",t:" ",n:`
6`,v:"\v",f:"\f",r:"\r",e:"\x1B"," ":" ",'"':'"',"/":"/","\\":"\\",N:"\x85",_:"\xA0",L:"\u2028",P:"\u2029"};function Xa(e){if(!e.includes(`
7`))return e;let t=e.split(`
8`),r=t.length-1;for(let i=0;i<=r;i++){let n=t[i],l=0,s=n.length;if(i>0)for(;l<s&&(n.charCodeAt(l)===32||n.charCodeAt(l)===9);)l++;if(i<r)for(;s>l&&(n.charCodeAt(s-1)===32||n.charCodeAt(s-1)===9);)s--;t[i]=n.slice(l,s)}return t.join(`
9`).replace(/\n+/g,i=>i.length===1?" ":`
10`.repeat(i.length-1))}function Bd(e){let t="",r=Xa(e.replace(/\\\n[ \t]*/g,""));for(let i=0;i<r.length;i++){let n=r[i];if(n!=="\\"){t+=n;continue}let l=r[++i];if(l==="x"||l==="u"||l==="U"){let s=l==="x"?2:l==="u"?4:8;t+=String.fromCodePoint(parseInt(r.slice(i+1,i+1+s),16)),i+=s}else if(l in an)t+=an[l];else throw new Error("YAML: unknown escape sequence")}return t}function $r(e,t,r){for(;t<e.length;){let i=e[t];if(i===" "||i===`
11`||i===" "||i==="\r"||r&&i===",")t++;else if(i==="#"&&(t===0||/\s/.test(e[t-1]))){let n=e.indexOf(`
12`,t);t=n===-1?e.length:n}else break}return t}function sn(e,t){if(!t)throw new Error("YAML: missed comma between flow collection entries");if(e===",")throw new Error("YAML: expected the node content, but found ','")}function Fr(e,t,r,i=0){if(i>ln)throw new Error("YAML: nesting is too deep");t=$r(e,t,!1);let n=e[t];if(n==="{"){let s={};t++;let a=!0;for(;;){if(t=$r(e,t,!1),t>=e.length)throw new zr("YAML: unexpected end of the stream within a flow collection");if(e[t]==="}")return[s,t+1];sn(e[t],a);let d;[d,t]=Fr(e,t,":,}",i+1),t=$r(e,t,!1);let c=null;e[t]===":"&&([c,t]=Fr(e,t+1,",}",i+1)),ja(s,String(d),c),t=$r(e,t,!1),a=e[t]===",",a&&t++}}if(n==="["){let s=[];t++;let a=!0;for(;;){if(t=$r(e,t,!1),t>=e.length)throw new zr("YAML: unexpected end of the stream within a flow collection");if(e[t]==="]")return[s,t+1];sn(e[t],a);let d;[d,t]=Fr(e,t,",]",i+1),s.push(d),t=$r(e,t,!1),a=e[t]===",",a&&t++}}if(n==='"'){let s=t+1;for(;s<e.length&&e[s]!=='"';)s+=e[s]==="\\"?2:1;if(s>=e.length)throw new zr("YAML: unexpected end of the stream within a double quoted scalar");return[Bd(e.slice(t+1,s)),s+1]}if(n==="'"){let s=t+1;for(;s<e.length;){if(e[s]==="'"){if(e[s+1]!=="'")break;s++}s++}if(s>=e.length)throw new zr("YAML: unexpected end of the stream within a single quoted scalar");return[Xa(e.slice(t+1,s)).replace(/''/g,"'"),s+1]}let l=t;for(;l<e.length;){let s=e[l];if(r.includes(s)&&(s!==":"||l+1>=e.length||/[\s,[\]{}]/.test(e[l+1])))break;if(s==="#"&&l>t&&/\s/.test(e[l-1])){let a=e.indexOf(`
13`,l);return[$s(Xa(e.slice(t,l).trim())),a===-1?e.length:a]}l++}return[$s(Xa(e.slice(t,l).trim())),l]}function da(e){let t="";for(let r=0;r<e.length;r++){let i=e[r];if(t)i==="\\"&&t==='"'?r++:i===t&&(t="");else if(i==='"'||i==="'")t=i;else if(i==="#"&&(r===0||e[r-1]===" "||e[r-1]===" "))return e.slice(0,r)}return e}function Ud(e,t,r){let i=t[0]===">",n=t.includes("-")?"-":t.includes("+")?"+":"",l=/[1-9]/.exec(t),s=l?r+Number(l[0]):-1,a=[];for(;e.i<e.lines.length;){let p=e.lines[e.i];if(p.trim()===""){a.push(""),e.i++;continue}let u=p.length-p.trimStart().length;if(s===-1){if(u<=r)break;s=u}if(u<s)break;a.push(p.slice(s)),e.i++}let d=0;for(;a.length>0&&a[a.length-1]==="";)a.pop(),d++;let c;if(i){c="";for(let p=0;p<a.length;p++){let u=a[p];if(p>0){let h=a[p-1];u===""?c+=`
14`:h!==""&&(c+=/^[ \t]/.test(h)||/^[ \t]/.test(u)?`
15`:" ")}c+=u}}else c=a.join(`
16`);return a.length===0?n==="+"?`
17`.repeat(d):"":n==="-"?c:n==="+"?c+`
18`.repeat(d+1):c+`
19`}function ys(e,t,r){let i=t[0];if((i==="|"||i===">")&&/^[|>][-+0-9]*\s*(?:#.*)?$/.test(t))return Ud(e,t,r);if(i==="{"||i==="["||i==='"'||i==="'"){let l=e.i,s=t,a=0,d=1;for(;;)try{let[c,p]=Fr(s,0,""),u=0;for(let $=s.indexOf(`
20`);$!==-1&&$<p;$=s.indexOf(`
21`,$+1))u++;let h=s.indexOf(`
22`,p);if(da(s.slice(p,h===-1?s.length:h)).trim()!=="")throw new Error("YAML: unexpected content after a value");return e.i=l+u,c}catch(c){if(!(c instanceof zr))throw c;if(l+a>=e.lines.length)throw new Error(c.message);let p=e.lines.slice(l+a,l+a+d);s+=`
23`+p.join(`
24`),a+=p.length,d*=2}}let n=da(t).trim();for(;e.i<e.lines.length;){let l=e.lines[e.i];if(l.trim()===""){let a=e.i;for(;a<e.lines.length&&e.lines[a].trim()==="";)a++;if(a>=e.lines.length||e.lines[a].length-e.lines[a].trimStart().length<=r)break;n+=`
25`.repeat(a-e.i),e.i=a;continue}if(l.length-l.trimStart().length<=r)break;let s=da(l).trim();n+=(n.endsWith(`
26`)?"":" ")+s,e.i++}return $s(n)}function Va(e,t,r=0){if(r>ln)throw new Error("YAML: nesting is too deep");if(e.skipBlank(),e.i>=e.lines.length)return null;let i=e.indent();if(i<t)return null;let n=e.lines[e.i].slice(i);if(n==="-"||n.startsWith("- ")){let s=[];for(;e.i<e.lines.length&&(e.skipBlank(),!(e.i>=e.lines.length||e.indent()!==i));){let a=e.lines[e.i].slice(i);if(a!=="-"&&!a.startsWith("- "))break;let d=a.slice(1),c=d.length-d.trimStart().length+1,p=da(d).trim();p===""?(e.i++,s.push(Va(e,i+1,r+1))):ms(p)!==null?(e.lines[e.i]=" ".repeat(i+c)+d.trimStart(),s.push(Va(e,i+c,r+1))):(e.i++,s.push(ys(e,d.trim(),i)))}return s}if(ms(n)===null)return e.i++,ys(e,n.trim(),i-1);let l={};for(;e.i<e.lines.length&&(e.skipBlank(),!(e.i>=e.lines.length));){let s=e.indent();if(s<i)break;if(s>i)throw new Error("YAML: bad indentation of a mapping entry");let a=e.lines[e.i].slice(i),d=ms(a);if(!d)throw new Error("YAML: can not read a block mapping entry");let c=String(Fr(d.key,0,"")[0]),p=a.slice(d.length);if(e.i++,da(p).trim()==="")if(e.skipBlank(),e.i<e.lines.length){let u=e.indent(),h=e.lines[e.i].slice(u),$=h==="-"||h.startsWith("- ");ja(l,c,u>i||$&&u===i?Va(e,$?i:i+1,r+1):null)}else ja(l,c,null);else ja(l,c,ys(e,p.trim(),i))}return l}function Wr(e){let t=e.trim();if(t[0]==="{"||t[0]==="[")try{let[n,l]=Fr(t,0,"");if($r(t,l,!1)===t.length)return n}catch(n){throw n instanceof zr?new Error(n.message):n}let r=new zd(e),i=Va(r,0);if(r.skipBlank(),r.i<r.lines.length&&r.lines[r.i].trim()!=="...")throw new Error("YAML: end of the stream or a document separator is expected");return i}function Le(e){return e<128?e===32||e>=9&&e<=13:e===160||e===5760||e>=8192&&e<=8202||e===8232||e===8233||e===8239||e===8287||e===12288||e===65279}function ha(e){return e===10||e===13||e===8232||e===8233}function ot(e){return e>=48&&e<=57}function Pr(e){return e>=65&&e<=90||e>=97&&e<=122}function Pe(e){return e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||e===95}var He=class extends Error{code;type;mermaidType;line;column;snippet;constructor(e,t="syntax",r={}){super(e),this.name="PeleError",this.code=t,this.type=r.type??null,this.mermaidType=r.mermaidType??null,this.line=r.line??0,this.column=r.column??0,this.snippet=r.snippet??""}};function xs(e,t){let r=1,i=0;for(let a=e.indexOf(`
27`);a!==-1&&a<t;a=e.indexOf(`
28`,a+1))r++,i=a+1;let n=e.indexOf(`
29`,t);n===-1&&(n=e.length);let l=t-i+1,s=e.slice(i,n);return{line:r,column:l,snippet:s+`
30`+"-".repeat(l-1)+"^"}}function Ve(e,t,r,i,n=!1){let l=xs(t,r),s=n?`Lexical error on line ${l.line}. Unrecognized text.`:`Parse error on line ${l.line}:`,a=n?`${s}
31${l.snippet}`:`${s}
32${l.snippet}
33${i}`;return new He(a,"syntax",{type:e,...l})}var qd="amp:38,lt:60,gt:62,quot:34,apos:39,nbsp:160,iexcl:161,cent:162,pound:163,curren:164,yen:165,sect:167,copy:169,laquo:171,not:172,reg:174,deg:176,plusmn:177,sup2:178,sup3:179,micro:181,para:182,middot:183,sup1:185,raquo:187,frac14:188,frac12:189,frac34:190,iquest:191,times:215,divide:247,ndash:8211,mdash:8212,lsquo:8216,rsquo:8217,sbquo:8218,ldquo:8220,rdquo:8221,bdquo:8222,dagger:8224,Dagger:8225,bull:8226,hellip:8230,permil:8240,prime:8242,Prime:8243,lsaquo:8249,rsaquo:8250,euro:8364,trade:8482,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,radic:8730,infin:8734,and:8743,or:8744,cap:8745,cup:8746,int:8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830,check:10003,cross:10007,equals:61,colon:58,semi:59,num:35,percnt:37,lpar:40,rpar:41,lbrack:91,rbrack:93,lbrace:123,rbrace:125,vert:124,sol:47,bsol:92,quest:63,excl:33,ast:42,plus:43,comma:44,period:46,dollar:36,commat:64,grave:96,hat:94,lowbar:95,tilde:126,Alpha:913,Beta:914,Gamma:915,Delta:916,Epsilon:917,Zeta:918,Eta:919,Theta:920,Iota:921,Kappa:922,Lambda:923,Mu:924,Nu:925,Xi:926,Omicron:927,Pi:928,Rho:929,Sigma:931,Tau:932,Upsilon:933,Phi:934,Chi:935,Psi:936,Omega:937,alpha:945,beta:946,gamma:947,delta:948,epsilon:949,zeta:950,eta:951,theta:952,iota:953,kappa:954,lambda:955,mu:956,nu:957,xi:958,omicron:959,pi:960,rho:961,sigmaf:962,sigma:963,tau:964,upsilon:965,phi:966,chi:967,psi:968,omega:969",Ka;function hn(e){if(!Ka){Ka=new Map;for(let t of qd.split(",")){let r=t.indexOf(":");Ka.set(t.slice(0,r),String.fromCodePoint(Number(t.slice(r+1))))}}return Ka.get(e)}function ws(e,t){return e>0&&e<=1114111&&(e<55296||e>57343)?String.fromCodePoint(e):t}var jd=/&(?:#(\d+)|#[xX]([0-9a-fA-F]+)|(\w+));/g,nn="\uFB02\xB0",Xd="\xB6\xDF";function Vd(e){let t="",r=0,i=e.indexOf(nn);for(;i!==-1;){let n=e.indexOf("\xB6",i+2);if(n===-1)break;if(e[n+1]==="\xDF"){let l=e[i+2]==="\xB0",s=e.slice(i+(l?3:2),n),a=e.slice(i,n+2);t+=e.slice(r,i)+(l?ws(Number(s),a):hn(s)??"&"+s+";"),r=n+2}i=e.indexOf(nn,n+1)}return r===0?e:t+e.slice(r)}function nt(e){return e.includes(Xd)&&(e=Vd(e)),e.includes("&")&&(e=e.replace(jd,(t,r,i,n)=>r?ws(Number(r),t):i?ws(parseInt(i,16),t):hn(n)??t)),e}var fa,ua=new Map;function fn(e,t){let r=fa,i=ua;fa=e,ua=new Map;try{return t()}finally{fa=r,ua=i}}function Za(e){if(fa===void 0)return"";let t=ua.get(e);return t===void 0&&(t=fa(e)??"",ua.set(e,t)),t}var Kd="7q7q9vfgfgopij5b9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg7q7qg8g8g8fgs7ijijk2k2ijgzlmk27qdwijfgn5k2lmijlmk2ijgzk2ijq8ijijgz7q7q7qd1fg99fgfgdwfgfg7qfgfg6666dw66n5fgfgfgfg99dw7qfgdwk2dwdwdw9a789ag8",Zd="7q99d6fgfgopk26m9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg9999g8g8g8gzr3k2k2k2k2ijgzlmk27qfgk2gzn5k2lmijlmk2ijgzk2ijq8ijijgz997q99g8fg99fggzfggzfg99gzgz7q7qfg7qopgzgzgzgzatfg99gzfglmfgfgdwat7satg8";function on(e){let t=new Uint16Array(95);for(let r=0;r<95;r++)t[r]=parseInt(e.substr(r*2,2),36);return t}var Qd,Jd;function eh(e){return e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=55296&&e<=56319}function th(e){return e>=768&&e<=879||e>=8203&&e<=8207||e>=56320&&e<=57343||e>=65024&&e<=65039||e===65279}var rh={width(e,t,r){let i=(r&4)!==0,n=r&1?Jd??=on(Zd):Qd??=on(Kd),l=0;for(let s=0;s<e.length;s++){let a=e.charCodeAt(s);if(!(a<32))if(a<127)l+=i?600:n[a-32];else{if(th(a))continue;eh(a)?l+=i?1200:1e3:l+=i?600:580}}return l*t/1e3}};function ah(){let e=globalThis;try{if(e.OffscreenCanvas)return new e.OffscreenCanvas(1,1).getContext("2d");if(e.document)return e.document.createElement("canvas").getContext("2d")}catch{return null}return null}var ih=2e4;function cn(){let e=globalThis;return e.document?.fonts??e.fonts}function sh(e,t,r){try{return e?.check(t,r)??!0}catch{return!0}}function lh(e,t="monospace"){let r=ah();if(!r)return null;let i=new Map,n="",l=cn()?.size;return{width(s,a,d){let c=cn();c?.size!==l&&(l=c?.size,i.clear());let p=(d&2?"italic ":"")+(d&1?"bold ":"")+a+"px "+(d&4?t:e),u=i.get(p);u||i.set(p,u=new Map);let h=u.get(s);return h===void 0&&(p!==n&&(r.font=n=p),h=r.measureText(s).width,sh(c,p,s)&&(u.size>=ih&&u.clear(),u.set(s,h))),h}}}var dn=new Map;function tt(e="sans-serif",t="monospace"){let r=e+`
34`+t,i=dn.get(r);return i||(i=lh(e,t)??rh,dn.set(r,i)),i}var nh=[["flowchart","flowchart-elk",/^\s*flowchart-elk/],["mindmap","mindmap",/^\s*mindmap/],["architecture","architecture",/^\s*architecture/],["agentflow","agentflow",/^\s*agentflow-beta\b/],["c4","c4",/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/],["kanban","kanban",/^\s*kanban/],["class","classDiagram",/^\s*classDiagram/],["er","er",/^\s*erDiagram/],["gantt","gantt",/^\s*gantt/],["info","info",/^\s*info/],["pie","pie",/^\s*pie/],["requirement","requirement",/^\s*requirement(Diagram)?/],["sequence","sequence",/^\s*sequenceDiagram/],["swimlane","swimlane",/^\s*swimlane-beta\b/],["flowchart","flowchart-v2",/^\s*(graph|flowchart)/],["timeline","timeline",/^\s*timeline/],["gitGraph","gitGraph",/^\s*gitGraph/],["state","stateDiagram",/^\s*stateDiagram/],["journey","journey",/^\s*journey/],["quadrantChart","quadrantChart",/^\s*quadrantChart/],["sankey","sankey",/^\s*sankey(-beta)?/],["packet","packet",/^\s*packet(-beta)?/],["xychart","xychart",/^\s*xychart(-beta)?/],["block","block",/^\s*block(-beta)?/],["eventmodeling","eventmodeling",/^\s*eventmodeling/],["treeView","treeView",/^\s*treeView-beta/],["radar","radar",/^\s*radar-beta/],["ishikawa","ishikawa",/^\s*ishikawa(-beta)?\b/i],["treemap","treemap",/^\s*treemap/],["railroad","railroad",/^\s*railroad-beta/i],["railroad","railroadEbnf",/^\s*railroad-ebnf-beta/i],["railroad","railroadAbnf",/^\s*railroad-abnf-beta/i],["railroad","railroadPeg",/^\s*railroad-peg-beta/i],["venn","venn",/^\s*venn-beta/],["wardley","wardley",/^\s*wardley-beta/i],["cynefin","cynefin",/^\s*cynefin-beta(?:[\s:]|$)/],["usecase","usecase",/^\s*usecase-beta(?:\s|$)/]];function oh(e){for(let[t,r,i]of nh)if(i.test(e))return{type:t,mermaidType:r};return null}var ch=/^\s*%%(?!{)[^\n]+\n?/gm,Hr=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,dh=/<(\w+)([^>]*)>/g,hh=/="([^"]*)"/g,fh=new Set(["__proto__","constructor","prototype"]);function uh(e){return(e.includes("%%")?e.replace(ch,""):e).trimStart()}function Qa(e){return e===`
35`||e==="\r"}function bs(e){return e!==void 0&&/\s/.test(e)}function ph(e){let t=0;for(;t<e.length&&bs(e[t])&&!Qa(e[t]);)t++;let r=e.slice(0,t);if(!e.startsWith("---",t))return;let i=[];for(let u=t+3;u<e.length&&bs(e[u]);u++)Qa(e[u])&&i.push(u);if(i.length===0)return;let n=r+"---",l=u=>{if(!Qa(e[u])||!e.startsWith(n,u+1))return-1;let h=-1;for(let $=u+1+n.length;$<e.length&&bs(e[$]);$++)Qa(e[$])&&(h=$);return h},s=`
36`+n,a=-1;for(let u=e.lastIndexOf(s);u>i[0];u=e.lastIndexOf(s,u-1))if(l(u)!==-1){a=u;break}if(a===-1)return;let d=i[0];for(let u of i)u<a&&(d=u);let c=d+1,p=c>0?c-1:0;for(let u=e.indexOf(s,p);u!==-1&&u<=a;u=e.indexOf(s,u+1)){if(u<c)continue;let h=l(u);if(h!==-1)return{indent:r,body:e.slice(c,u),length:h+1}}}function wr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ja(e,t){for(let r of Object.keys(t)){if(fh.has(r))continue;let i=t[r],n=e[r];wr(i)&&wr(n)?Ja(n,i):wr(i)?e[r]=Ja({},i):e[r]=i}return e}function gh(e,t){if(!e.includes("%%{"))return e;let r=e.trim().replace(/'/g,'"');Hr.lastIndex=0;let i;for(;(i=Hr.exec(r))!==null;){i.index===Hr.lastIndex&&Hr.lastIndex++;let n=i[1]??i[2];if(n==="wrap")t.wrap=!0;else if((n==="init"||n==="initialize")&&i[4])try{let l=JSON.parse(i[4].trim());wr(l)&&Ja(t,l)}catch{}}return Hr.lastIndex=0,e.replace(Hr,"")}function mh(e){let t=e.includes("\r")?e.replace(/\r\n?/g,`
37`):e,r=t.includes("<")?t.lastIndexOf(">"):-1;r>0&&(t=t.slice(0,r+1).replace(dh,(a,d,c)=>"<"+d+c.replace(hh,"='$1'")+">")+t.slice(r+1));let i={},n,l=0,s=t.includes("---")?ph(t):void 0;if(s){let a=s.indent?s.body.split(`
38`).map(c=>c.startsWith(s.indent)?c.slice(s.indent.length):c).join(`
39`):s.body,d;try{d=Wr(a)}catch(c){throw new He(`Front matter is not valid YAML. ${c.message}`,"syntax")}if(wr(d)&&(d.title&&(n=String(d.title)),wr(d.config)&&Ja(i,d.config),d.displayMode)){let c=wr(i.gantt)?i.gantt:i.gantt={};c.displayMode=String(d.displayMode)}for(let c=t.indexOf(`
40`);c!==-1&&c<s.length;c=t.indexOf(`
41`,c+1))l++;t=t.slice(s.length)}return t=gh(t,i),{text:uh(t),title:n,config:i,withComments:t,lineOffset:l}}var yh=/#\w+;/g,$h=/^\+?\d+$/,ks=new RegExp("[\\n\\r\u2028\u2029]","g");function un(e,t){let r=e.indexOf(t);if(r===-1)return e;let i="",n=0;for(;r!==-1;){ks.lastIndex=r;let l=ks.test(e)?ks.lastIndex-1:e.length,s=!1,a=-1;for(let d=r+t.length;d<l;d++){let c=e.charCodeAt(d);if(c===58)s=!0;else if(c===35){if(s){a=d;break}}else Le(c)&&(s=!1)}if(a!==-1){let d=e.lastIndexOf(";",l-1);d>a&&(i+=e.slice(n,d),n=d+1)}r=l>=e.length?-1:e.indexOf(t,l+1)}return n===0?e:i+e.slice(n)}function wh(e){return e.includes("#")?un(un(e,"style"),"classDef").replace(yh,t=>{let r=t.substring(1,t.length-1);return($h.test(r)?"\uFB02\xB0\xB0":"\uFB02\xB0")+r+"\xB6\xDF"}):e}var Yg=Math.random().toString(36).slice(2,7);var pn=new Map;function vs(...e){for(let t of e)pn.set(t.type,t)}var xh=5e4,bh=4e6,kh=5e3;function vh(e){try{return e()}catch(t){throw t instanceof RangeError?new He("Diagram is nested too deeply.","limit"):t}}function gn(e,t){try{return t()}catch(r){throw r instanceof RangeError?new He("Diagram is nested too deeply.","limit",e):(r instanceof He&&(r.type??=e.type,r.mermaidType??=e.mermaidType),r)}}var Mh=new WeakMap;function Ah(e,t=xh,r=kh,i){if(e.length>t)throw new He(`Diagram source is longer than the limit of ${t} characters.`,"limit");let n=mh(e),l=oh(n.text);if(l===null)throw new He("No diagram type detected for the given text.","unsupported-diagram");let s=pn.get(l.type);if(s===void 0)throw new He(`Diagram type "${l.type}" is not supported yet.`,"unsupported-diagram",l);let a=i?{...i,...n.config}:n.config,d=s.keepComments?n.withComments:n.text,c=gn(l,()=>s.parse(wh(d)+`
42`,a,n.title,n.lineOffset,{maxEdges:r}));return{...l,diagram:s,model:c,config:a}}function Th(e,t){if(typeof e=="string")return Ah(e,t.limit,t.maxEdges,t.config);let r=Mh.get(e);if(r===void 0)throw new TypeError("render() takes diagram text or a model that parse() returned.");return r}function Ms(e,t={}){return vh(()=>{let{type:r,mermaidType:i,diagram:n,model:l,config:s}=Th(e,t),a=s[n.section??r],d=typeof a=="object"&&a!==null&&!Array.isArray(a)&&a.useMaxWidth===!1,c=t.responsive??!d,p=t.icons,u=p&&(g=>p(nt(g))),h=gn({type:r,mermaidType:i},()=>fn(u,()=>n.render(l,s,{...t,responsive:c,icons:u}))),$=t.outputLimit??bh;if(h.svg.length>$)throw new He(`Diagram output is longer than the limit of ${$} characters.`,"limit",{type:r,mermaidType:i});for(let g of h.links)g.id=nt(g.id);return{type:r,mermaidType:i,...h}})}var Ch=[["rect","proc","process","rectangle","squareRect"],["rounded","event","roundedRect"],["stadium","terminal","pill"],["fr-rect","subprocess","subproc","framed-rectangle","subroutine"],["cyl","db","database","cylinder"],["datastore","data-store"],["folder","directory"],["bucket"],["console"],["browser"],["person"],["circle","circ"],["bang"],["cloud"],["diam","decision","diamond","question"],["hex","hexagon","prepare"],["lean-r","lean-right","in-out","lean_right"],["lean-l","lean-left","out-in","lean_left"],["trap-b","priority","trapezoid-bottom","trapezoid"],["trap-t","manual","trapezoid-top","inv-trapezoid","inv_trapezoid"],["dbl-circ","double-circle","doublecircle"],["text"],["notch-rect","card","notched-rectangle"],["lin-rect","lined-rectangle","lined-process","lin-proc","shaded-process"],["sm-circ","start","small-circle","stateStart"],["fr-circ","stop","framed-circle","stateEnd"],["fork","join","forkJoin"],["hourglass","collate"],["brace","comment","brace-l"],["brace-r"],["braces"],["bolt","com-link","lightning-bolt"],["doc","document"],["delay","half-rounded-rectangle"],["h-cyl","das","horizontal-cylinder"],["lin-cyl","disk","lined-cylinder"],["curv-trap","curved-trapezoid","display"],["div-rect","div-proc","divided-rectangle","divided-process"],["tri","extract","triangle"],["win-pane","internal-storage","window-pane"],["f-circ","junction","filled-circle"],["notch-pent","loop-limit","notched-pentagon"],["flip-tri","manual-file","flipped-triangle"],["sl-rect","manual-input","sloped-rectangle"],["docs","documents","st-doc","stacked-document"],["st-rect","procs","processes","stacked-rectangle"],["bow-rect","stored-data","bow-tie-rectangle"],["cross-circ","summary","crossed-circle"],["tag-doc","tagged-document"],["tag-rect","tagged-rectangle","tag-proc","tagged-process"],["flag","paper-tape"],["odd","rect_left_inv_arrow"],["lin-doc","lined-document"]],Eh=["state","choice","note","composite","rectWithTitle","labelRect","block_arrow","collapsedGroup","iconSquare","iconCircle","icon","iconRounded","imageSquare","anchor","kanbanItem","mindmapCircle","defaultMindmapNode","classBox","erBox","requirementBox","usecaseActor","usecaseActorHollow","usecaseActorAwesome","usecaseActorIcon","usecaseBusiness","usecaseEllipse","usecaseJsonTable"],Sh=new Map([["square","rect"],["round","rounded"],["ellipse","ellipse"],["hexagon","hex"],["diamond","diam"]]),ei=new Map;for(let e of Ch)for(let t of e)ei.set(t,e[0]);for(let e of Eh)ei.set(e,e);function mn(e){return ei.has(e)}function yn(e){return e===void 0?"rect":Sh.get(e)??ei.get(e)??"rect"}var _h="4q 0 b 0 5 0 6 m 2 u 2 cp 5 b f 4 8 0 2 0 3m 4 2 1 3 3 9 0 2 2 2 0 2 j 2 2a 2 3u 9 4d a 11 3 0 8 12 21 q 6 2 1a 16 10 1 2 2q 2 0 g 1 8 1 b 2 3 0 h 0 2 t u 2g c 0 p w a 1 5 0 6 l 5 0 a 0 4 0 o o 20 0 2 a 2g 1h 4 0 j 0 8 9 g 6 2 6 6 7 3 1 3 l 2 6 2 0 4 3 4 0 h 0 e 1 2 2 f 1 k 5 5 1 3 l 2 6 2 1 2 1 2 1 w 3 2 0 k 2 h 8 2 2 2 l 2 6 2 1 2 4 4 0 j 0 g 1 10 7 3 1 3 l 2 6 2 1 2 4 4 0 v 1 2 2 g 0 i 0 2 5 4 2 2 3 4 1 2 0 2 1 4 1 4 2 4 b n 0 1h 7 2 2 2 m 2 9 2 4 4 0 r 1 7 1 10 7 2 2 2 m 2 9 2 4 4 0 x 0 2 1 g 1 j 7 2 2 2 14 3 0 h 0 i 1 p 5 6 h 4 n 2 8 2 0 3 6 1n 1b 2 1 d 6 1n 1 2 0 3 1 2 0 3 0 7 3 2 6 2 2 2 0 2 0 3 1 2 3 2 1 a 0 3 4 2 0 m 3 x 0 1s 7 2 z s 4 38 16 l 0 h 5 5 3 4 0 4 1 8 2 5 c d 0 i 11 2 0 6 0 3 16 2 98 2 3 3 6 2 0 2 3 3 14 2 3 3 w 2 3 3 6 2 0 2 3 3 e 2 1k 2 3 3 1u 12 f h 2c d h7 3 g 2 p 6 22 m c 2 3 f h f h f c 2 2 g 1f 10 0 5 0 1w 2f 9 14 2 0 6 1x b s 1g t 3 4 c 17 m 6 1l m a 1g 2b 0 2m 1a i 6 1k t e 1 b 17 r z 16 2 b z 30 3 2 3 4 1 a 5b 1t 7p 3 5 3 11 3 5 3 7 2 0 2 0 2 0 2 u 3 1g 2 6 2 0 4 2 2 6 4 3 3 5 5 c 6 2 2 6 39 0 e 0 h c 2u 0 5 0 3 9 2 0 4 4 7 0 2 0 2 0 2 3 2 a 3 3 6 4 5 0 1h 1 22k 1a 2 1a 2 3o 7 3 4 1 d 11 2 0 6 0 3 1j 8 0 h m a 6 2 6 2 6 2 6 2 6 2 6 2 6 2 6 29 0 d2 1 17 4 6 1 5 2d 7 2 2 2h 2 3 6 14 4 2l i q 1i f e9 52t 23 g5o 1g wc 1w 19 3 7g 4 f b 1 l 1a h o 9 1x 1e 8 3 2u 3 3 2 3 d a 26 9 2 2 2 3 2 m u 1f f 1d 1r 5 4 0 f r b m q s 8 1a t 0 1d 14 o 2 2 7 l m 4 0 6 1b 2 0 4 1 3 4 3 0 2 0 p 2 3 a 8 2 d 5 3 5 3 5 a 6 2 6 42 y u 8mb d m 5 1c 6it a5 3 2x 13 6 d 4 6 0 2 9 2 c 2 4 2 0 2 1 2 1 2 2z y a2 j 1r 3 1h 15 b 39 4 2 3q 11 p 7 p c 2g 4 5 3 5 3 5 3 2",Dh;function Ih(){let e=_h.split(" "),t=new Uint16Array(e.length),r=0;for(let i=0;i<e.length;i+=2){let n=r+parseInt(e[i],36);r=n+parseInt(e[i+1],36),t[i]=n,t[i+1]=r}return t}function ti(e){if(e<170||e>65500)return!1;let t=Dh??=Ih(),r=0,i=(t.length>>1)-1;for(;r<=i;){let n=r+i>>1;if(e<t[n*2])i=n-1;else if(e>t[n*2+1])r=n+1;else return!0}return!1}var Nh=/[&<>"\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/,Lh=/[&<>"]|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]+/g,Oh={"&":"&","<":"<",">":">",'"':"""};function Be(e){return Nh.test(e)?e.replace(Lh,t=>Oh[t]??""):e}function Oe(e){return Be(nt(e))}var Cs=[];for(let e=0;e<100;e++)Cs.push(e===0?"":e%10===0?"."+e/10:"."+(e<10?"0"+e:e));function o(e){let t=Math.round(e*100);if(t===0)return"0";if(t>0){if(t<1e11){let r=Math.floor(t/100);return r+Cs[t-r*100]}}else if(t>-1e11){let r=-t,i=Math.floor(r/100);return"-"+i+Cs[r-i*100]}return String(t/100)}function Ne(e,t,r,i,n){let l=e.lines;if(l.length===0)return"";let s=e.lineHeight,a=e.size*.35,d=r-e.height/2+s/2+a;if(l.length===1&&l[0].length===1&&l[0][0].icon===void 0&&l[0][0].style===0)return`<text${i} x="${o(t)}" y="${o(d)}" text-anchor="middle">${Be(l[0][0].text)}</text>`;let c=Ss(e);i=_s(i,c);let p="",u="";for(let h=0;h<l.length;h++){let $=l[h],g=!1;for(let T of $)T.icon!==void 0&&(g=!0);if(g){let T=t-e.widths[h]/2;for(let D of $){if(D.icon!==void 0){let _=e.size*1.1,F=n?.(D.icon)??"";u+=`<svg class="pele-icon" data-icon="${Oe(D.icon)}" x="${o(T)}" y="${o(d-a-_/2)}" width="${o(_)}" height="${o(_)}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${F}</svg>`}else D.text!==""&&(p+=`<tspan x="${o(T)}" y="${o(d)}" text-anchor="start"${ri(D.style&~c)}>${Be(D.text)}</tspan>`);T+=D.width}}else{for(let T=0;T<$.length;T++){let D=$[T],_=T===0?` x="${o(t)}" y="${o(d)}"`:"";p+=`<tspan${_}${ri(D.style&~c)}>${Be(D.text)}</tspan>`}$.length===0&&(p+=`<tspan x="${o(t)}" y="${o(d)}"> </tspan>`)}d+=s}return`<text${i} text-anchor="middle" xml:space="preserve">${p}</text>${u}`}var An=' font-weight="var(--_w)"',Tn=' font-style="italic"';function ri(e){return(e&1?An:"")+(e&2?Tn:"")}function Ss(e){let t=3,r=!1;for(let i of e.lines)for(let n of i)n.icon!==void 0||n.text===""||(t&=n.style,r=!0);return r?t:0}function _s(e,t){return e+(t&1&&!e.includes(' font-weight="')?An:"")+(t&2&&!e.includes(' font-style="')?Tn:"")}var Rh="--_bg:var(--pele-bg,#fff);--_fg:var(--pele-fg,#1f1f1f);--_m:var(--pele-muted,#6e6e6e);--_l:var(--pele-line,#1f1f1f);--_s:var(--pele-surface,#f3f3f3);--_a:var(--pele-surface-alt,#e6e6e6);--_b:var(--pele-border,#8a8a8a);--_c:var(--pele-accent,#5b7bd5);color:var(--_fg)";var Ke="var(--pele-radius,4px)",Cn="var(--pele-critical,#e45756)",$n=String.raw`(?:"[^"'\\\n<>{}();:@]*"|'[^"'\\\n<>{}();:@]*'|[\p{L}\p{N}_-][\p{L}\p{N}_ .-]*)`,zh=new RegExp(String.raw`^\s*${$n}(?:\s*,\s*${$n})*\s*$`,"u");function wn(e,t){return e&&zh.test(e)?e:t}function Fh(e,t,r){return`;--_fm:var(--pele-font-mono,${wn(r,"monospace")});font:${e}px sans-serif;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;font-family:var(--pele-font,${wn(t,"sans-serif")})`}var Wh=new Set(["fill","fill-opacity","stroke","stroke-width","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-opacity","opacity","rx","ry"]),Ph=new Set(["color","font-size","font-family","font-weight","font-style","text-decoration","letter-spacing","word-spacing","opacity"]),Hh=/url\s*\(|expression\s*\(|javascript:|[<>{};\\]|@import|image-set|\/\*/i,xn={shape:"",line:"",text:"",stroke:void 0,bold:!1,italic:!1,fontSize:void 0};function ct(e){if(e.length===0)return xn;let t=new Map,r=new Map;for(let c of e){let p=c.indexOf(":");if(p<=0)continue;let u=c.slice(0,p).trim().toLowerCase(),h=c.slice(p+1).replace(/!important/gi,"").trim();h===""||Hh.test(h)||(Wh.has(u)&&t.set(u,h),Ph.has(u)&&r.set(u==="color"?"fill":u,h))}if(t.size===0&&r.size===0)return xn;let i="",n="";for(let[c,p]of t)i+=`${c}:${p};`,c!=="fill"&&c!=="fill-opacity"&&(n+=`${c}:${p};`);let l="";for(let[c,p]of r)l+=`${c}:${p};`;let s=r.get("font-weight"),a=r.get("font-size"),d=a&&/^[\d.]+(px)?$/.test(a)?parseFloat(a):void 0;return{shape:i?` style="${Be(i)}"`:"",line:n?` style="${Be(n)}"`:"",text:l?` style="${Be(l)}"`:"",stroke:t.get("stroke"),bold:s==="bold"||s==="bolder"||Number(s)>=600,italic:r.get("font-style")==="italic",fontSize:d!==void 0&&d>0&&d<=200?d:void 0}}var Yh=/[^\w-]+/g;function Mt(e){let t=e.replace(Yh," ").trim();return t===""?"":" "+t}var Gh=["#4c78a8","#f58518","#54a24b","#e45756","#72b7b2","#eeca3b","#b279a2","#9d755d"];function it(e){let t=(e%8+8)%8;return`var(--pele-series-${t+1},${Gh[t]})`}var As=` rx="${Ke}"`,Bh=/<rect\b[^>]*>/g;function Uh(e){return e.includes(As)?e.replace(Bh,t=>{let r=t.indexOf(As);if(r<0)return t;let i=t.slice(0,r)+t.slice(r+As.length),n=i.indexOf(' style="');if(n>=0)return`${i.slice(0,n+8)}rx:var(--_r);${i.slice(n+8)}`;let l=i.endsWith("/>")?i.length-2:i.length-1;return`${i.slice(0,l)} style="rx:var(--_r)"${i.slice(l)}`}):e}var qh=[["--_tw","title"],["--_hw","heading"],["--_w","bold"]];function Je(e,t,r,i,n,l,s){let a=Be(n.idPrefix??"pele"),d="",c="";l.accTitle&&(d+=`<title id="${a}-title">${Oe(l.accTitle)}</title>`,c+=` aria-labelledby="${a}-title"`),l.accDescr&&(d+=`<desc id="${a}-desc">${Oe(l.accDescr)}</desc>`,c+=` aria-describedby="${a}-desc"`);let p=n.responsive===!1?"":"max-width:100%;height:auto;";s=Uh(s);let u=s.includes("var(--_r)")?`;--_r:${Ke}`:"";for(let[h,$]of qh)s.includes(`var(${h})`)&&(u+=`;${h}:var(--pele-${$}-weight,bold)`);return`<svg xmlns="http://www.w3.org/2000/svg" class="pele pele-${e}" viewBox="0 0 ${t} ${r}" width="${t}" height="${r}" style="${p}${Rh}${u}${Be(Fh(i,n.fontFamily,n.fontFamilyMono))}" fill="var(--_fg)" role="graphics-document document" aria-roledescription="${e}"${c}>`+d+s+"</svg>"}var jh=1.5,Xh=/<br\s*\/?>|\\n|\n/gi,bn=/<\/?([a-zA-Z][\w-]*)(?:\s[^<>]*)?\/?>/y,kn=/(fa[bklrs]?):fa-([\w-]+)/g,Vh=/[<\\\n*_]|fa[bklrs]?:fa-/,Es="\\u2e80-\\u9fff\\uf900-\\ufaff\\uff00-\\uff60",vn="\u3001\u3002\uFF0C\uFF0E\uFF1A\uFF1B\uFF01\uFF1F\uFF09\uFF3D\uFF5D\u300D\u300F\u3011\u3015\u3009\u300B\u3019\u3017\u30FC\u2026\u2025\u30FB\u309D\u309E\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308E\u30A1\u30A3\u30A5\u30A7\u30A9\u30C3\u30E3\u30E5\u30E7\u30EE,.:;!?)\\]}",Kh="\uFF08\uFF3B\uFF5B\u300C\u300E\u3010\u3014\u3008\u300A\u3018\u3016([{",Zh=new RegExp(`[${Es}]`),Qh=new RegExp(`\\s*(?:[${Kh}]*[${Es}][${vn}]*|[^\\s${Es}]+[${vn}]*)\\s*|\\s+`,"g"),Jh={lines:[],widths:[],width:0,height:0,size:0,lineHeight:0};function ef(e){let t=e.split(`
43`),r=1/0;for(let i of t){if(i.trim()==="")continue;let n=i.length-i.trimStart().length;n<r&&(r=n)}return r===1/0||r===0?e:t.map(i=>i.slice(Math.min(r,i.length-i.trimStart().length))).join(`
44`)}function Ts(e,t,r){if(t==="")return;let i=nt(t),n=e[e.length-1];n&&n.style===r&&n.icon===void 0?n.text+=i:e.push({text:i,style:r,width:0})}function tf(e,t,r){if(!t.includes(":fa-")){Ts(e,t,r);return}let i=0;kn.lastIndex=0;let n;for(;(n=kn.exec(t))!==null;){let l=`${n[1]}:fa-${n[2]}`;if(Ts(e,t.slice(i,n.index),r),i=n.index+n[0].length,Za(l)!=="")e.push({text:"",style:r,icon:l,width:0});else if(t[i]===" ")i++;else if(i===t.length){let s=e[e.length-1];s&&s.icon===void 0&&(s.text=s.text.trimEnd())}}Ts(e,t.slice(i),r)}function rf(e,t,r,i){let n=i,l=0,s="",a=0,d=t.length,c=()=>{tf(e,s,n),s=""};for(;a<d;){let p=t[a];if(p==="<"){bn.lastIndex=a;let u=bn.exec(t);if(u&&u.index===a){let h=u[1].toLowerCase(),$=t[a+1]==="/",g=h==="b"||h==="strong"?1:h==="i"||h==="em"?2:0;g&&(c(),n=$?n&~g|i&g:n|g),a+=u[0].length;continue}}else if(r&&(p==="*"||p==="_")){let u=t[a+1]===p,h=u?1:2,$=u?2:1,g=(l&h)===0,T=a>0?t[a-1]:" ",D=a+$<d?t[a+$]:" ",_=g&&D.trim()!==""&&t.indexOf(u?p+p:p,a+$)!==-1,F=!g&&T.trim()!=="",k=p==="_"&&/\w/.test(T)&&/\w/.test(D);if((_||F)&&!k){c(),l=_?l|h:l&~h,n=_?n|h:n&~h|i&h,a+=$;continue}}s+=p,a++}c()}function af(e,t,r){let i=0;for(let n of e)n.width=n.icon!==void 0?r*1.25:t.width(n.text,r,n.style),i+=n.width;return i}function Mn(e,t,r,i,n,l){let s=[],a=0,d=()=>{let c=s[s.length-1];if(c&&c.icon===void 0){let p=c.text.trimEnd();if(p!==c.text){c.text=p;let u=t.width(p,r,c.style);a+=u-c.width,c.width=u}}n.push(s),l.push(a),s=[],a=0};for(let c of e){if(c.icon!==void 0){let p=r*1.25;a>0&&a+p>i&&d(),s.push({...c,width:p}),a+=p;continue}for(let p of c.text.match(Qh)??[]){let u=p;a>0&&a+t.width(u.trimEnd(),r,c.style)>i&&(d(),u=u.trimStart());let h=s[s.length-1];if(h&&h.style===c.style&&h.icon===void 0){h.text+=u,h.width=t.width(h.text,r,h.style),a=0;for(let $ of s)a+=$.width}else{let $=t.width(u,r,c.style);s.push({text:u,style:c.style,width:$}),a+=$}}}(s.length>0||n.length===0)&&d()}function Fe(e,t,r,i,n,l=0){if(e===void 0||e==="")return Jh;let s=Math.round(i*jh);if(!Vh.test(e)&&!e.includes("&")&&!e.includes("\uFB02")){let u=e.trim(),h=r.width(u,i,l);if(h<=n||!(u.includes(" ")||Zh.test(u)))return{lines:[[{text:u,style:l,width:h}]],widths:[h],width:h,height:s,size:i,lineHeight:s};let $=[],g=[];Mn([{text:u,style:l,width:h}],r,i,n,$,g);let T=0;for(let D of g)D>T&&(T=D);return{lines:$,widths:g,width:T,height:$.length*s,size:i,lineHeight:s}}let a=t?ef(e.replace(/\r\n?/g,`
45`)).trim():e.trim(),d=[],c=[],p=0;for(let u of a.split(Xh)){let h=[];rf(h,u.trim(),t,l);let $=af(h,r,i);$>n?Mn(h,r,i,n,d,c):(d.push(h),c.push($))}for(let u of c)u>p&&(p=u);return{lines:d,widths:c,width:p,height:d.length*s,size:i,lineHeight:s}}function Yr(e,t){for(let r=0;r<t.length;r+=3){let i=Math.round(t[r+1]),n=e.get(i);n?n.push(t[r]):e.set(i,[t[r]])}}function Gr(e,t,r,i){if(t===0)return e.x;let n=e.y-e.h/2,l=e.x-e.w/2,s=t/2,a=[l+i-6+s,e.x,l+e.w-i+6-s],d=r.get(Math.round(n));if(d===void 0)return a[0];let c=a[0],p=-1;for(let u of a){let h=1/0;for(let $ of d)$>l&&$<l+e.w&&(h=Math.min(h,Math.abs($-u)-s));if(h>=6)return u;h>p+.5&&(p=h,c=u)}return c}function ai(e,t,r,i){let n=t>0?i.get(Math.round(e.y-e.h/2)):void 0;if(n===void 0)return!1;let l=e.x-e.w/2;for(let s of n)if(s>l&&s<l+e.w&&Math.abs(s-r)<t/2+4)return!0;return!1}function ii(e,t,r,i,n,l,s,a){let d=1;for(let p=l[s].parent;p>=0&&d<8;p=l[p].parent)d++;let c=`color-mix(in srgb,var(--_a) ${o(100*(1-.5**d))}%,var(--_bg))`;return`<g class="pele-cluster-title" data-id="${n}">`+Ne(e,t,r,` fill="none" stroke="${c}" stroke-width="5" stroke-linejoin="round"`,a)+Ne(e,t,r,i,a)+"</g>"}function ni(e,t,r=0){return{w:e,h:t,kind:r,pin:0,span:0,x:0,y:0,rank:0}}function oi(e,t,r=1,i=0,n=0){return{tail:e,head:t,minlen:r,labelW:i,labelH:n,tailDx:0,headDx:0,tailFixed:!1,headFixed:!1,reversed:!1,points:[],labelX:0,labelY:0}}var sf=24,En=2e4,Ds=16,Sn=8,lf=.125,_n=3,nf=18,of=10,cf=14,df=2,hf=28,Dn=12,ff=12,uf=8,pf=4,In=.5,Vt=.5,Nn=12,gf=40,Ln=400;function Br(e){return e===1||e===2}function On(e,t,r,i){for(let n=t+1;n<r;n++){let l=e[n],s=i[l],a=n-1;for(;a>=t&&(i[e[a]]>s||i[e[a]]===s&&e[a]>l);)e[a+1]=e[a],a--;e[a+1]=l}}function Rn(e,t,r){let i=e.length;if(i===0)return{width:0,height:0};let n=t.length,l=1;if(n>0){let N=new Set;for(let U of t){let J=Math.min(U.tail,U.head),le=Math.max(U.tail,U.head),fe=J*i+le;if(U.labelW>0||N.has(fe)){l=2;break}N.add(fe)}}Is(e,t),Ns(e,t,l);let s=new Int32Array(n),a=0;for(let N=0;N<n;N++){let U=t[N];s[N]=Math.abs(e[U.head].rank-e[U.tail].rank),s[N]>1&&(a+=s[N]-1)}let d=new Uint8Array(n);if(a>En){let N=[];for(let U=0;U<n;U++)s[U]>1&&N.push(U);N.sort((U,J)=>s[J]-s[U]||U-J);for(let U of N){if(a<=En)break;d[U]=1,a-=s[U]-1}}let c=i+a,p=new Float64Array(c),u=new Float64Array(c),h=new Uint8Array(c),$=new Int32Array(c),g=0;for(let N=0;N<i;N++){let U=e[N];p[N]=U.w,u[N]=U.h,h[N]=U.kind,$[N]=U.rank,U.rank>g&&(g=U.rank)}let T=0;for(let N=0;N<n;N++)d[N]||(T+=s[N]);let D=new Int32Array(T),_=new Int32Array(T),F=new Float64Array(T),k=new Float64Array(T),I=new Int32Array(n).fill(-1),E=new Uint8Array(g+1),m=new Int32Array(n).fill(-1),y=!1;for(let N=0;N<i;N++)e[N].span>0&&e[N].kind===0&&(y=!0);let C=y?new Uint8Array(T):void 0,L=y?new Uint8Array(T):void 0,S=new Int32Array(n).fill(-1),Z=new Int32Array(n).fill(-1),H=!1;{let N=i,U=0;for(let J=0;J<n;J++){if(d[J])continue;let le=t[J],fe=le.reversed?le.head:le.tail,we=le.reversed?le.tail:le.head,Ee=le.reversed?le.headDx:le.tailDx,Ae=le.reversed?le.tailDx:le.headDx;(Ee!==0||Ae!==0)&&(H=!0);let De=$[fe],Ie=$[we],ye=-1;le.labelW>0&&(ye=De+(Ie-De>>1),l===2&&Ie-De>=4?(ye&1)===1&&(ye+=le.reversed?1:-1):l===2&&(ye&1)===0&&(ye+=le.reversed?1:-1));let Me=fe;Ie-De>1&&(I[J]=N),S[J]=U,C&&!(le.reversed?le.headFixed:le.tailFixed)&&(C[U]=le.reversed?2:1);for(let Se=De+1;Se<Ie;Se++){let q=N++;$[q]=Se,Se===ye?(p[q]=le.labelW,u[q]=le.labelH,h[q]=2,m[J]=q,E[Se]|=le.reversed?2:1):h[q]=1,D[U]=Me,_[U]=q,F[U]=Me===fe?Ee:0,U++,Me=q}D[U]=Me,_[U]=we,F[U]=Me===fe?Ee:0,k[U]=Ae,L&&!(le.reversed?le.tailFixed:le.headFixed)&&(L[U]=le.reversed?1:2),Z[J]=U,U++}}let R=new Int32Array(c+1),P=new Int32Array(c+1);for(let N=0;N<T;N++)R[D[N]+1]++,P[_[N]+1]++;for(let N=0;N<c;N++)R[N+1]+=R[N],P[N+1]+=P[N];let w=new Int32Array(T),b=new Int32Array(T);{let N=R.slice(0,c),U=P.slice(0,c);for(let J=0;J<T;J++)w[N[D[J]]++]=J,b[U[_[J]]++]=J}let M=new Int32Array(g+2);for(let N=0;N<c;N++)M[$[N]+1]++;for(let N=0;N<=g;N++)M[N+1]+=M[N];let f=new Int32Array(c),x=new Int32Array(c);{let N=new Int32Array(c),U=M.slice(0,g+1);for(let fe=0;fe<c;fe++)N[U[$[fe]]++]=fe;U.set(M.subarray(0,g+1));let J=new Uint8Array(c),le=[];for(let fe=0;fe<c;fe++)if(!J[N[fe]])for(le.push(N[fe]);le.length>0;){let we=le.pop();if(!J[we]){J[we]=1,f[U[$[we]]++]=we;for(let Ee=R[we+1]-1;Ee>=R[we];Ee--){let Ae=_[w[Ee]];J[Ae]||le.push(Ae)}}}}let A=!1;for(let N=0;N<i;N++)e[N].pin!==0&&(A=!0);if(A)for(let N=0;N<=g;N++){let U=Array.from(f.subarray(M[N],M[N+1])),J=new Map;U.forEach((fe,we)=>J.set(fe,we));let le=fe=>fe<i?e[fe].pin:0;U.sort((fe,we)=>le(fe)-le(we)||J.get(fe)-J.get(we)),f.set(U,M[N])}let z=()=>{for(let N=0;N<=g;N++){let U=M[N];for(let J=U,le=M[N+1];J<le;J++)x[f[J]]=J-U}};z();let v={n:c,real:i,maxRank:g,W:p,KIND:h,RANK:$,EF:D,ET:_,EFD:F,ETD:k,succStart:R,succE:w,predStart:P,predE:b,layerStart:M,order:f,pos:x,offsets:H};T>0&&g>0&&(Af(v,e),z()),C&&L&&mf(v,e,C,L);let G=Tf(v,r),ee=bf(v);if(C&&L){let N=yf(v,C,L);$f(v,e,G,N,r,ee),wf(v,e,G,C,L,N,ee),xf(v,G,ee,r);for(let U=0;U<n;U++){if(d[U])continue;let J=t[U],le=F[S[U]],fe=k[Z[U]];J.tailDx=J.reversed?fe:le,J.headDx=J.reversed?le:fe}}let he=new Uint8Array(c);ee&&!r.tracks&&vf(v,G,ee,I,s,r.apart?0:r.edgeSep,he),r.tracks||Mf(v,G,I,s,r.edgeSep,he);let ue=new Int32Array(n+1),V=r.tracks||C&&!r.straight?{from:[],to:[],rank:[],lower:[],track:[],levels:[],wide:[]}:void 0,Y=new Int32Array(g+1);if(V){for(let N=0;N<n;N++){if(ue[N]=V.from.length,d[N])continue;let U=I[N],J=!1;for(let we=U,Ee=U<0?U:U+s[N]-1;we<Ee;we++){let Ae=ee!==void 0&&ee[$[we]]===1;!r.tracks&&Ae!==(he[we]===1)&&(J=!0)}if(J)continue;let le=G[D[S[N]]]+F[S[N]],fe=$[D[S[N]]];for(let we=U,Ee=U<0?U:U+s[N]-1;we<Ee;we++)ee&&ee[$[we]]||(V.from.push(le),V.to.push(G[we]),V.rank.push(fe),V.lower.push(we),le=G[we],fe=$[we]);V.from.push(le),V.to.push(G[_[Z[N]]]+k[Z[N]]),V.rank.push(fe),V.lower.push(-1)}ue[n]=V.from.length}let de=(N,U)=>{let J=!1;for(let le=M[N];le<M[N+1];le++){let fe=h[f[le]];if(fe===U)J=!0;else if(fe!==1)return!1}return J},te=de(0,3)?l:0,xe=de(g,4)?l:0,me=new Float64Array(g+1);for(let N=0;N<T;N++){let U=Math.abs(G[D[N]]+F[N]-G[_[N]]-k[N]);U>me[$[D[N]]]&&(me[$[D[N]]]=U)}let ae=new Float64Array(g+1),O=new Float64Array(g+1),B=N=>(N<te||N>=g-xe?r.portSep:r.rankSep)/l,Q=new Float64Array(g+1);for(let N=0;N<g;N++)Q[N]=V?B(N):Math.max(B(N),Math.min(_n*r.rankSep/l,me[N]*lf));let se=new Uint8Array(g+1).fill(1);for(let N=0;N<i;N++)se[$[N]]=0;for(let N=1;N<g;N++){if(r.tracks||!se[N]||E[N]!==1&&E[N]!==2)continue;let U=Math.min((r.headRoom??0)/2,Q[E[N]===1?N-1:N]/2);Q[N-1]+=E[N]===1?-U:U,Q[N]+=E[N]===1?U:-U}let ie=N=>h[N]===1&&se[$[N]]&&!r.tracks?(O[$[N]]-ae[$[N]])/4:0,re=r.tracks?nf:hf,ne=r.tracks?of:Dn,X=r.tracks?cf:Dn,j=new Int32Array(g+1);if(V){let N=new Float64Array(g+1);for(let J=0;J<g;J++){if(ee&&ee[J])continue;let le=J+1;for(N[J]=Q[J];le<g&&ee&&ee[le];)N[J]+=Q[le++];j[J]=le}for(let J=0;J<V.from.length;J++)V.wide.push(Math.abs(V.from[J]-V.to[J])>df*N[V.rank[J]]?1:0);let U=new Float64Array(g+1);kf(V,Y,!r.tracks,N,U);for(let J=0;J<g;J++)Y[J]>0?Q[J]+=Math.max(0,2*re+(Y[J]-1)*ne-N[J]):U[J]>0&&(Q[J]+=Math.max(0,Math.min(_n*r.rankSep,U[J])-N[J]))}let oe=0;for(let N=0;N<=g;N++){let U=0;for(let J=M[N];J<M[N+1];J++)u[f[J]]>U&&(U=u[f[J]]);ae[N]=oe,O[N]=oe+U,oe+=U+Q[N]}let $e=oe,ge=(N,U=V.track[N])=>{let J=V.rank[N],le=O[J],fe=ae[j[J]],we=r.tracks?Y[J]:V.levels[N],Ee=we>1?Math.min(X,(fe-le-2*re)/(we-1)):0;return(le+fe)/2+(U-(we-1)/2)*Ee},Te=1/0,pe=-1/0;for(let N=0;N<c;N++){let U=p[N]/2;G[N]-U<Te&&(Te=G[N]-U),G[N]+U>pe&&(pe=G[N]+U)}let W=new Uint8Array(g+1),K=new Uint8Array(g+1);for(let N=0;N<i;N++)h[N]!==0||!C||(P[N+1]>P[N]&&(W[$[N]]=1),R[N+1]>R[N]&&(K[$[N]]=1));for(let N=0;N<i;N++){let U=e[N],J=U.rank;U.x=G[N]-Te,h[N]===0&&K[J]&&!W[J]?U.y=O[J]-U.h/2:h[N]===0&&W[J]&&!K[J]?U.y=ae[J]+U.h/2:U.y=(ae[J]+O[J])/2}for(let N=0;N<n;N++){let U=t[N],J=e[U.reversed?U.head:U.tail],le=e[U.reversed?U.tail:U.head],fe=[J.x+(U.reversed?U.headDx:U.tailDx),J.y+J.h/2],we=I[N];if(V&&ue[N+1]>ue[N])for(let Ae=ue[N];Ae<ue[N+1];Ae++){if(V.track[Ae]>=0&&(r.tracks||V.wide[Ae]===1)){let Ie=ge(Ae);fe.push(V.from[Ae]-Te,Ie,V.to[Ae]-Te,Ie)}else V.track[Ae]>0&&fe.push(V.from[Ae]-Te,ge(Ae,V.track[Ae]-1));let De=V.lower[Ae];De<0||(fe.push(G[De]-Te,ae[$[De]]+ie(De)),O[$[De]]>ae[$[De]]&&fe.push(G[De]-Te,O[$[De]]-ie(De)))}else if(we>=0)for(let Ae=we,De=we+s[N]-1;Ae<De;Ae++){if(he[Ae])continue;let Ie=G[Ae]-Te,ye=ae[$[Ae]],Me=O[$[Ae]];fe.push(Ie,ye+ie(Ae)),Me>ye&&fe.push(Ie,Me-ie(Ae))}if(fe.push(le.x+(U.reversed?U.tailDx:U.headDx),le.y-le.h/2),U.reversed)for(let Ae=0,De=fe.length-2;Ae<De;Ae+=2,De-=2){let Ie=fe[Ae],ye=fe[Ae+1];fe[Ae]=fe[De],fe[Ae+1]=fe[De+1],fe[De]=Ie,fe[De+1]=ye}U.points=fe;let Ee=m[N];Ee>=0?(U.labelX=G[Ee]-Te,U.labelY=(ae[$[Ee]]+O[$[Ee]])/2):U.labelW>0&&(U.labelX=(fe[0]+fe[fe.length-2])/2,U.labelY=(fe[1]+fe[fe.length-1])/2)}return{width:pe-Te,height:$e}}function Is(e,t){let r=e.length,i=t.length,n=new Int32Array(r+1);for(let c=0;c<i;c++){let p=t[c];p.reversed=e[p.head].kind===3||e[p.tail].kind===4,p.reversed||n[p.tail+1]++}for(let c=0;c<r;c++)n[c+1]+=n[c];let l=new Int32Array(n[r]);{let c=n.slice(0,r);for(let p=0;p<i;p++)t[p].reversed||(l[c[t[p].tail]++]=p)}let s=new Uint8Array(r),a=n.slice(0,r),d=[];for(let c=0;c<r;c++)if(s[c]===0)for(d.push(c),s[c]=1;d.length>0;){let p=d[d.length-1];if(a[p]<n[p+1]){let u=t[l[a[p]++]],h=u.head;s[h]===1?u.reversed=!0:s[h]===0&&(s[h]=1,d.push(h))}else s[p]=2,d.pop()}}function Ns(e,t,r){let i=e.length,n=t.length,l=new Int32Array(n),s=new Int32Array(n),a=new Int32Array(n),d=new Int32Array(i+1),c=new Int32Array(i+1);for(let k=0;k<n;k++){let I=t[k],E=I.reversed?I.head:I.tail,m=I.reversed?I.tail:I.head;l[k]=E,s[k]=m,a[k]=Math.max(1,I.minlen)*r,d[E+1]++,c[m+1]++}for(let k=0;k<i;k++)d[k+1]+=d[k],c[k+1]+=c[k];let p=new Int32Array(n),u=new Int32Array(n);{let k=d.slice(0,i),I=c.slice(0,i);for(let E=0;E<n;E++)p[k[l[E]]++]=E,u[I[s[E]]++]=E}let h=new Int32Array(i),$=new Int32Array(i);for(let k=0;k<i;k++)$[k]=c[k+1]-c[k];let g=new Int32Array(i),T=0;for(let k=0;k<i;k++)$[k]===0&&(g[T++]=k);for(let k=0;k<T;k++){let I=g[k];for(let E=d[I];E<d[I+1];E++){let m=p[E],y=s[m];h[I]+a[m]>h[y]&&(h[y]=h[I]+a[m]),--$[y]===0&&(g[T++]=y)}}for(let k=0;k<8;k++){let I=!1;for(let E=T-1;E>=0;E--){let m=g[E],y=c[m+1]-c[m],C=d[m+1]-d[m];if(y===0&&C===0)continue;let L=-1/0,S=1/0;for(let H=c[m];H<c[m+1];H++){let R=u[H];L=Math.max(L,h[l[R]]+a[R])}for(let H=d[m];H<d[m+1];H++){let R=p[H];S=Math.min(S,h[s[R]]-a[R])}let Z=h[m];C>y&&S!==1/0?Z=S:y>C&&L!==-1/0&&(Z=L),Z!==h[m]&&(h[m]=Z,I=!0)}if(!I)break}let D=1/0,_=-1/0,F=!1;for(let k=0;k<i;k++){let I=e[k].kind;I===3&&(F=!0),!(I===3||I===4)&&(h[k]<D&&(D=h[k]),h[k]>_&&(_=h[k]))}D===1/0&&(D=0,_=0);for(let k=0;k<i;k++)e[k].kind===3?h[k]=D-r:e[k].kind===4&&(h[k]=_+r);F&&(D-=r);for(let k=0;k<i;k++)e[k].rank=h[k]-D}function zn(e,t,r,i,n,l,s){let a=r===0?e.predStart:e.succStart,d=r===0?e.predE:e.succE,c=r===0?e.EF:e.ET,p=e.pos;l.length=0;for(let g=a[t];g<a[t+1];g++)n[d[g]]!==0&&l.push(d[g]);if(l.length<2)return 0;l.sort((g,T)=>p[c[g]]-p[c[T]]||g-T);let u=g=>{let T=0;s.length=l.length,s[0]=0;for(let D=1;D<l.length;D++){let _=n[l[D]]===n[l[D-1]];s[D]=g(_&&n[l[D]]===1,_),T+=s[D]}return T},h=u(()=>1);if(i/h<Sn&&(h=u(g=>g?.5:1)),i/h<Sn&&(h=u((g,T)=>T?0:1)),h===0)return 0;let $=Math.min(Ds,i/h);for(let g=1;g<l.length;g++)s[g]*=$;return h*$}function mf(e,t,r,i){let{real:n,W:l,EFD:s,ETD:a}=e,d=[],c=[];for(let p=0;p<n;p++){let u=Math.min(t[p].span,l[p]);if(!(u<=0||t[p].kind!==0))for(let h=0;h<2;h++){let $=zn(e,p,h,u,h===0?i:r,d,c);if($===0)continue;let g=h===0?a:s,T=-$/2;for(let D=0;D<d.length;D++)T+=c[D],g[d[D]]=T}}}function li(e,t,r,i){if(!t)return r;let{KIND:n,RANK:l,EF:s,ET:a,succStart:d,succE:c,predStart:p,predE:u}=e;for(let h=0;h<1e5;h++){let $=i===0?s[r]:a[r];if(n[$]!==1||!t[l[$]])break;r=i===0?u[p[$]]:c[d[$]]}return r}function yf(e,t,r){let i=[new Int32Array(e.n),new Int32Array(e.n)];for(let n=0;n<e.EF.length;n++)r[n]!==0&&i[0][e.ET[n]]++,t[n]!==0&&i[1][e.EF[n]]++;return i}function Fn(e,t){return Math.max(.25,Math.min(.5,4*Math.abs(t)/(Math.abs(e)||1)))}function $f(e,t,r,i,n,l){let s=n.edgeSep,{n:a,real:d,maxRank:c,KIND:p,RANK:u,W:h,EF:$,ET:g,EFD:T,ETD:D,succStart:_,succE:F,predStart:k,predE:I,layerStart:E,order:m,pos:y}=e,C=P=>p[P]===2||p[P]===1&&!(l!==void 0&&l[u[P]]===1),L=(P,w)=>{let b=w===0?$[P]:g[P];return[w===0?r[b]+T[P]:r[b]+D[P],b<d&&t[b].kind===0?i[1-w][b]:0]},S=P=>{let w=E[u[P]],b=w+y[P],M=f=>h[f]/2+h[P]/2+(p[f]===0?n.nodeSep/2+s/2:p[f]===p[P]?s:s/2);return[b>w?r[m[b-1]]+M(m[b-1]):-1/0,b+1<E[u[P]+1]?r[m[b+1]]-M(m[b+1]):1/0]},Z=(P,w,b,M,f)=>{let x=(w[1]!==b[1]?w[1]<b[1]:Math.abs(w[0]-P)<=Math.abs(b[0]-P))?[w[0],b[0]]:[b[0],w[0]];return x.find(A=>A>=M&&A<=f)??Math.max(M,Math.min(f,x[0]))},H=new Uint8Array(a),R=[];for(let P=1;P<c;P++)for(let w=E[P];w<E[P+1];w++){if(!C(m[w])||H[m[w]])continue;let b=m[w];for(;Br(p[$[I[k[b]]]]);)b=$[I[k[b]]];let M=b,f=-1/0,x=1/0;R.length=0;for(let A=b;Br(p[A]);A=g[F[_[A]]]){if(M=A,!C(A))continue;H[A]=1,R.push(A);let[z,v]=S(A);z>f&&(f=z),v<x&&(x=v)}if(f<=x){let A=Z(r[R[0]],L(I[k[b]],0),L(F[_[M]],1),f,x);for(let z of R)r[z]=A;continue}for(let A of R){let[z,v]=S(A);z>v||(r[A]=Z(r[A],L(li(e,l,I[k[A]],0),0),L(li(e,l,F[_[A]],1),1),z,v))}}}function wf(e,t,r,i,n,l,s){let{real:a,W:d,EF:c,ET:p,EFD:u,ETD:h,succStart:$,succE:g,predStart:T,predE:D,pos:_}=e,F=[],k=[],I=[],E=[],m=[],y=(C,L,S,Z,H)=>{if(l[L][S]<2)return 0;C=li(e,s,C,L);let R=L===0?c[C]:p[C],P=L===0?r[R]+u[C]:r[R]+h[C];if(H&&Math.abs(P-r[S])<=Z/2+Vt)return Math.max(-Z/2,Math.min(Z/2,P-r[S]));let w=P,b=0;R<a&&t[R].kind===0&&(L===0?i:n)[C]!==0&&l[1-L][R]>=2&&(b=Math.max(0,Math.min(t[R].span,d[R])),b>0&&(w=r[R]));let M=Math.max(r[S]-Z/2,w-b/2),f=Math.min(r[S]+Z/2,w+b/2);if(M>f+Vt){let A=Math.max(0,Z/2-gf);return Math.max(-A,Math.min(A,P-r[S]))}let x=(r[S]*b+w*Z)/(b+Z);return Math.max(M,Math.min(f,x))-r[S]};for(let C=0,L=!0;L&&C<6;C++){L=!1;for(let S=0;S<a;S++){let Z=Math.min(t[S].span,d[S]);if(!(Z<=0||t[S].kind!==0))for(let H=0;H<2;H++){let R=H===0?n:i,P=H===0?h:u,w=H===0?c:p,b=H===0?T:$,M=H===0?D:g;if(zn(e,S,H,Z,R,F,k),F.length===0)continue;F.length===1&&(k[0]=0),I.length=0;for(let A=b[S];A<b[S+1];A++)I.push(M[A]);I.sort((A,z)=>_[w[A]]-_[w[z]]||A-z);let f=0,x=-Z/2;for(let A=0;A<=I.length;A++){let z=A<I.length&&R[I[A]]===0;if(A<I.length&&!z)continue;let v=0;for(let ee=A-1;ee>=0&&R[I[ee]]!==0;ee--)v++;let G=z?P[I[A]]-Ds:Z/2;if(v>0){E.length=0,m.length=0;let ee=0;for(let V=0;V<v;V++){V>0&&(ee+=k[f+V]),E.push(y(F[f+V],H,S,Z,C>0)-ee),m.push(1);let Y=V>0&&k[f+V]===0;for(;E.length>1&&(Y||E[E.length-2]/m[m.length-2]>E[E.length-1]/m[m.length-1]);){Y=!1;let de=E.pop(),te=m.pop();E[E.length-1]+=de,m[m.length-1]+=te}}let he=ee,ue=0;ee=0;for(let V=0;V<E.length;V++){let Y=G-he<x?(x+G-he)/2:Math.max(x,Math.min(G-he,E[V]/m[V]));for(let de=0;de<m[V];de++,ue++)ue>0&&(ee+=k[f+ue]),Math.abs(P[F[f+ue]]-Y-ee)>.01&&(L=!0),P[F[f+ue]]=Y+ee}f+=v}z&&(x=P[I[A]]+Ds)}}}}}function xf(e,t,r,i){let{n,KIND:l,RANK:s,EF:a,ET:d,EFD:c,ETD:p,layerStart:u,order:h,pos:$}=e,g=S=>r!==void 0&&l[S]===1&&r[s[S]]===1,T=[],D=[],_=[],F=[];for(let S=0;S<a.length;S++){if(g(a[S]))continue;let Z=li(e,r,S,1);T.push(a[S]),D.push(d[Z]),_.push(c[S]),F.push(p[Z])}let k=S=>t[D[S]]+F[S]-t[T[S]]-_[S],I=new Int32Array(n),E=[];for(let S=0;S<n;S++)I[S]=S,E.push([S]);let m=(S,Z)=>{let H=I[S],R=I[Z];if(H!==R){E[H].length<E[R].length&&([H,R]=[R,H]);for(let P of E[R])I[P]=H,E[H].push(P);E[R]=[]}},y=[];for(let S=0;S<T.length;S++){let Z=Math.abs(k(S));Z<.01?m(T[S],D[S]):Z<=Nn&&y.push(S)}if(y.length===0)return;y.sort((S,Z)=>Math.abs(k(S))-Math.abs(k(Z))||S-Z);let C=S=>Wn(e,i,S),L=(S,Z)=>{for(let H of E[S]){let R=u[s[H]],P=u[s[H]+1],w=R+$[H];if(w>R&&I[h[w-1]]!==S&&t[H]+Z-t[h[w-1]]<C(H)+C(h[w-1])-.01||w+1<P&&I[h[w+1]]!==S&&t[h[w+1]]-t[H]-Z<C(H)+C(h[w+1])-.01)return!1}return!0};for(let S of y){let Z=k(S);if(Math.abs(Z)<.01){m(T[S],D[S]);continue}if(Math.abs(Z)>Nn||I[T[S]]===I[D[S]])continue;let H=I[T[S]],R=I[D[S]],P=E[H].length<=E[R].length?H:R;for(let w of[P,P===H?R:H]){let b=w===H?Z:-Z;if(L(w,b)){for(let M of E[w])t[M]+=b;m(T[S],D[S]);break}}}}function bf(e){let{maxRank:t,KIND:r,layerStart:i,order:n}=e,l=new Uint8Array(t+1),s=!1;for(let a=1;a<t;a++){let d=i[a+1]>i[a];for(let c=i[a];d&&c<i[a+1];c++)r[n[c]]!==1&&(d=!1);d&&(l[a]=1,s=!0)}return s?l:void 0}function kf(e,t,r,i,n){let{from:l,to:s,rank:a,track:d,levels:c,wide:p}=e,u=l.length,h=new Map;for(let H=0;H<u;H++){if(d.push(-1),c.push(0),Math.abs(l[H]-s[H])<Vt)continue;let R=h.get(a[H]);R?R.push(H):h.set(a[H],[H])}let $=new Float64Array(u),g=new Float64Array(u);for(let H=0;H<u;H++)$[H]=Math.min(l[H],s[H]),g[H]=Math.max(l[H],s[H]);let T=(H,R)=>H>=$[R]-Vt&&H<=g[R]+Vt?1:0,D=(H,R)=>Math.abs(l[H]-l[R])<Vt||Math.abs(s[H]-s[R])<Vt,_=(H,R)=>$[H]<g[R]-Vt&&$[R]<g[H]-Vt,F=(H,R)=>_(H,R)&&!D(H,R),k=(H,R)=>_(H,R)||T(s[H],R)+T(l[R],H)+T(s[R],H)+T(l[H],R)>0,I=(H,R)=>T(s[H],R)+T(l[R],H),E=H=>{H.sort((v,G)=>g[G]-$[G]-(g[v]-$[v])||$[v]-$[G]||v-G);let R=H.length,P=[],w=H.map((v,G)=>G),b=v=>{for(;w[v]!==v;)v=w[v]=w[w[v]];return v},M=H;if(R<=Ln){let v=new Int32Array(R),G=[];for(let ue=0;ue<R;ue++)P.push([]),G.push([]);for(let ue=0;ue<R;ue++)for(let V=ue+1;V<R;V++){let Y=H[ue],de=H[V];if(!k(Y,de))continue;w[b(ue)]=b(V);let te=I(Y,de),xe=I(de,Y);if(te===xe)continue;let me=te<xe?ue:V,ae=te<xe?V:ue;P[ae].push(me),G[me].push(ae),v[ae]++}let ee=new Uint8Array(R),he=[];for(let ue=0;ue<R;ue++){let V=-1;for(let Y=0;Y<R&&!(!ee[Y]&&((V<0||v[Y]<v[V])&&(V=Y),v[Y]===0));Y++);ee[V]=1,he.push(V);for(let Y of G[V])v[Y]--}M=he.map(ue=>H[ue])}let f=new Map;H.forEach((v,G)=>f.set(v,G));let x=[];for(let v of M){let G=0;for(let ee of P[f.get(v)]??[])d[H[ee]]>=G&&(G=d[H[ee]]+1);for(;;G++){let ee=x[G]??=[],he=!0;for(let ue of ee)F(v,ue)&&(he=!1);if(he){ee.push(v);break}}d[v]=G}let A=new Map,z=new Map;return H.forEach((v,G)=>{let ee=b(G);A.set(ee,Math.min(A.get(ee)??1/0,d[v])),z.set(ee,Math.max(z.get(ee)??-1/0,d[v]))}),H.forEach((v,G)=>{let ee=b(G);c[v]=z.get(ee)-A.get(ee)+1,r&&(d[v]-=A.get(ee))}),x.length},m=16,y=(H,R,P)=>{let w=Fn(s[H]-l[H],R);for(let b=0;b<=m;b++){let M=b/m,f=1-M;P[2*b]=l[H]+(s[H]-l[H])*M*M*(3-2*M),P[2*b+1]=R*(3*w*M*f*f+3*(1-w)*M*M*f+M*M*M)}},C=new Float64Array(2*m+2),L=new Float64Array(2*m+2),S=(H,R)=>{let P=1/0;for(let w=0;w<=m;w++){let b=H[2*w],M=H[2*w+1];for(let f=0;f<m;f++){let x=R[2*f+2]-R[2*f],A=R[2*f+3]-R[2*f+1],z=Math.max(0,Math.min(1,((b-R[2*f])*x+(M-R[2*f+1])*A)/(x*x+A*A||1))),v=Math.hypot(b-R[2*f]-z*x,M-R[2*f+1]-z*A);v<P&&(P=v)}}return P},Z=(H,R,P)=>{let w=Math.max(P/2,P-2*ff);return y(H,w,C),y(R,w,L),Math.min(S(C,L),S(L,C))};for(let[H,R]of h){if(!r){t[H]=E(R);continue}if(R.length>Ln)continue;let P=R.filter(v=>p[v]===1);E(P);let w=new Set(P.filter(v=>c[v]>1));for(let v=0;v<R.length;v++)for(let G=v+1;G<R.length;G++){let ee=R[v],he=R[G];w.has(ee)&&w.has(he)||!F(ee,he)||l[ee]<s[ee]!=l[he]<s[he]||Z(ee,he,i[H])<(p[ee]===1||p[he]===1?uf:pf)&&w.add(ee).add(he)}for(let v of P)d[v]=-1,c[v]=0;if(w.size===0)continue;let b=0,M=0,f=[...w];for(let v=0;v<f.length;v++)for(let G=v+1;G<f.length;G++){let ee=f[v],he=f[G];_(ee,he)&&(l[ee]<s[ee]!=l[he]<s[he]?b++:D(ee,he)||M++)}if(b>M){for(let v of R)(g[v]-$[v])*In>n[H]&&(n[H]=(g[v]-$[v])*In);continue}let x=v=>{for(let G of w)if(k(v,G))return!0;return!1},A=R.filter(v=>w.has(v)||p[v]!==1&&x(v));E(A);let z=0;for(let v of A)c[v]>z&&(z=c[v]);t[H]=z}}function vf(e,t,r,i,n,l,s){let{maxRank:a,EF:d,ET:c,EFD:p,ETD:u,succStart:h,succE:$,predStart:g,predE:T,layerStart:D,order:_}=e,F=new Float64Array(t.length),k=new Float64Array(t.length),I=new Float64Array(t.length);for(let m=0;m<i.length;m++){let y=i[m];if(y<0)continue;let C=y+n[m]-1,L=e.RANK[y];for(let S=y;S<C;S++){if(!r[L+S-y])continue;let Z=S;for(;Z+1<C&&r[L+Z+1-y];)Z++;let H=T[g[S]],R=$[h[Z]],P=t[d[H]]+p[H],w=t[c[R]]+u[R],b=Z-S+2;for(let M=S;M<=Z;M++)F[M]=P+(w-P)*(M-S+1)/b,k[M]=P,I[M]=w;S=Z}}let E=[];for(let m=1;m<a;m++){if(!r[m])continue;let y=D[m],C=D[m+1],L=Array.from(_.subarray(y,C)).sort((S,Z)=>k[S]-k[Z]||I[S]-I[Z]||S-Z);for(let S=0;S<L.length;){E.length=0;let Z=S;for(;Z<L.length&&Math.abs(k[L[Z]]-k[L[S]])<1&&Math.abs(I[L[Z]]-I[L[S]])<1;Z++)E.push(L[Z]);E.sort((H,R)=>e.pos[H]-e.pos[R]);for(let H=0;H<E.length;H++){let R=E[H];t[R]=F[R]+(H-(E.length-1)/2)*l,(E.length===1||l===0)&&(s[R]=1)}S=Z}}}function Mf(e,t,r,i,n,l){let{maxRank:s,W:a,KIND:d,RANK:c,EF:p,ET:u,EFD:h,ETD:$,succStart:g,succE:T,predStart:D,predE:_,layerStart:F,order:k}=e,I=new Uint8Array(s+1),E=!1;for(let m=1;m<s;m++){let y=!1,C=!1;for(let L=F[m];L<F[m+1];L++){let S=d[k[L]];S===2?y=!0:S!==1&&(C=!0)}y&&!C&&(I[m]=1,E=!0)}if(E)for(let m=0;m<r.length;m++){let y=r[m];if(!(y<0))for(let C=y,L=y+i[m]-1;C<L;C++){if(d[C]!==1||!I[c[C]])continue;let S=C,Z=C;for(;S>y&&l[S-1];)S--;for(;Z+1<L&&l[Z+1];)Z++;let H=_[D[S]],R=T[g[Z]],P=t[p[H]]+h[H],w=t[u[R]]+$[R],b=Math.min(P,w)-n,M=Math.max(P,w)+n,f=!0,x=c[C];for(let z=F[x];f&&z<F[x+1];z++){let v=k[z];d[v]===2&&t[v]+a[v]/2>b&&t[v]-a[v]/2<M&&(f=!1)}if(!f)continue;l[C]=1;let A=Z-S+2;for(let z=S;z<=Z;z++)t[z]=P+(w-P)*(z-S+1)/A}}}function Af(e,t){let{n:r,real:i,maxRank:n,W:l,EF:s,ET:a,EFD:d,ETD:c,succStart:p,succE:u,predStart:h,predE:$,layerStart:g,order:T,pos:D,offsets:_}=e,F=0;for(let v=0;v<=n;v++)F=Math.max(F,g[v+1]-g[v]);let k=_?new Int32Array(s.length):void 0,I=1;for(;I<(k?F+s.length:F);)I<<=1;let E=new Int32Array(2*I),m=new Int32Array(s.length),y=()=>{let v=0;for(let G=0;G<n;G++){let ee=g[G+2]-g[G+1];if(k){let V=0;for(let Y=g[G+1];Y<g[G+2];Y++){let de=h[T[Y]],te=h[T[Y]+1],xe=!1;for(let me=de+1;me<te;me++)c[$[me]]!==c[$[de]]&&(xe=!0);if(xe){let me=Array.from($.subarray(de,te));me.sort((ae,O)=>c[ae]-c[O]);for(let ae=0;ae<me.length;ae++)ae>0&&c[me[ae]]!==c[me[ae-1]]&&V++,k[me[ae]]=V}else for(let me=de;me<te;me++)k[$[me]]=V;V++}ee=V}if(ee<2)continue;let he=0;for(let V=g[G];V<g[G+1];V++){let Y=T[V],de=p[Y],te=p[Y+1],xe=he;for(let O=de;O<te;O++)m[he++]=k?k[u[O]]:D[a[u[O]]];let me=he-xe;if(me<2)continue;let ae=!1;if(k)for(let O=de+1;O<te;O++)d[u[O]]!==d[u[de]]&&(ae=!0);if(k&&ae){let O=Array.from(u.subarray(de,te));O.sort((B,Q)=>d[B]-d[Q]||k[B]-k[Q]);for(let B=0;B<me;B++)m[xe+B]=k[O[B]]}else if(me<=12)for(let O=xe+1;O<he;O++){let B=m[O],Q=O-1;for(;Q>=xe&&m[Q]>B;)m[Q+1]=m[Q],Q--;m[Q+1]=B}else m.subarray(xe,he).sort()}if(he<2)continue;let ue=1;for(;ue<ee;)ue<<=1;E.fill(0,0,2*ue);for(let V=0;V<he;V++){let Y=m[V]+ue;for(E[Y]++;Y>1;)(Y&1)===0&&(v+=E[Y+1]),Y>>=1,E[Y]++}}return v},C=y();if(C===0)return;let L=T.slice(),S=new Float64Array(r),Z=new Int32Array(F),H=(v,G)=>S[v]-S[G]||D[v]-D[G],R=(v,G)=>S[v]-S[G]||D[G]-D[v],P=(v,G)=>{let ee=v?h:p,he=v?$:u,ue=v?s:a,V=v?d:c;for(let Y=1;Y<=n;Y++){let de=v?Y:n-Y,te=g[de],xe=g[de+1],me=0;for(let O=te;O<xe;O++){let B=T[O],Q=B<i?t[B].pin:0;if(Q!==0){S[B]=Q*1e9,Z[me++]=B;continue}let se=ee[B],ie=ee[B+1];if(se===ie){S[B]=-1;continue}let re=0;for(let ne=se;ne<ie;ne++){let X=ue[he[ne]];re+=D[X],_&&l[X]>0&&(re+=V[he[ne]]/l[X])}S[B]=re/(ie-se),Z[me++]=B}if(me<2)continue;Z.subarray(0,me).sort(G?R:H);let ae=0;for(let O=te;O<xe;O++)S[T[O]]!==-1&&(T[O]=Z[ae++]);for(let O=te;O<xe;O++)D[T[O]]=O-te}},w=()=>{let v=0;for(let G=0;G<=n;G++)for(let ee=g[G];ee<g[G+1];ee++)if(!(T[ee]>=i))for(let he=ee+1;he<g[G+1];he++)T[he]<T[ee]&&v++;return v},b=()=>{for(let v=0;v<=n;v++)for(let G=g[v];G<g[v+1];G++)D[T[G]]=G-g[v]},M=T.slice(),f=C,x=r<=600,A=L,z=1/0;for(let v=0;v<(x?2:1);v++){v>0&&(T.set(M),b());let G=f,ee=M.slice();for(let ue=0,V=0;V<4&&ue<sf;ue++,V++){P((ue+v)%2===0,ue%4>=2);let Y=y();if(Y<G&&(G=Y,ee.set(T),V=0,Y===0))break}T.set(ee);let he=x?w():0;(v===0||G<C||G===C&&he<z)&&(C=G,A=ee,z=he)}if(T.set(A),b(),L.set(A),!!x){for(let v=0;v<i;v++)if(t[v].pin!==0)return;if(z!==0){for(let v=0;v<=n;v++)T.subarray(g[v],g[v+1]).reverse();b(),(y()>C||w()>=z)&&T.set(L)}}}function Wn(e,t,r){return e.W[r]/2+(e.KIND[r]===0?t.nodeSep:t.edgeSep)/2}function Tf(e,t){let{n:r,maxRank:i,W:n,KIND:l,EF:s,ET:a,EFD:d,ETD:c,succStart:p,succE:u,predStart:h,predE:$,layerStart:g,order:T,pos:D}=e,_=s.length,F=new Float64Array(r);for(let v=0;v<r;v++)F[v]=Wn(e,t,v);let k=new Int32Array(_);for(let v=0;v<_;v++)k[v]=D[a[v]];for(let v=0;v<r;v++)p[v+1]-p[v]>1&&On(u,p[v],p[v+1],k);for(let v=0;v<_;v++)k[v]=D[s[v]];for(let v=0;v<r;v++)h[v+1]-h[v]>1&&On($,h[v],h[v+1],k);let I=new Uint8Array(_);for(let v=1;v<=i;v++){let G=g[v]-g[v-1],ee=g[v],he=g[v+1],ue=0,V=ee;for(let Y=ee;Y<he;Y++){let de=T[Y],te=-1;if(Br(l[de])){let me=s[$[h[de]]];Br(l[me])&&(te=me)}let xe=te>=0?D[te]:G;if(te>=0||Y===he-1){for(let me=V;me<=Y;me++){let ae=T[me],O=Br(l[ae]);for(let B=h[ae];B<h[ae+1];B++){let Q=$[B],se=D[s[Q]];(se<ue||xe<se)&&!(O&&Br(l[s[Q]]))&&(I[Q]=1)}}V=Y+1,ue=xe}}}let E=[],m=new Int32Array(r),y=new Int32Array(r),C=new Float64Array(r),L=new Int32Array(r),S=new Int32Array(r),Z=new Float64Array(r),H=new Int32Array(r),R=new Int32Array(r+1),P=new Int32Array(r),w=new Int32Array(r),b=new Int32Array(r);for(let v=0;v<4;v++){let G=v<2,ee=(v&1)===1,he=G?h:p,ue=G?$:u,V=G?s:a,Y=G?c:d,de=G?d:c;for(let O=0;O<r;O++)m[O]=O,y[O]=O,C[O]=0;for(let O=0;O<=i;O++){let B=G?O:i-O,Q=g[B],se=g[B+1],ie=G?B-1:B+1,re=ie>=0&&ie<=i?g[ie+1]-g[ie]-1:0,ne=-1;for(let X=ee?se-1:Q;ee?X>=Q:X<se;ee?X--:X++){let j=T[X],oe=he[j],$e=he[j+1]-oe;if($e===0)continue;let ge=oe+($e-1>>1),Te=oe+($e>>1);for(let pe=0;pe<2&&!(pe===1&&ge===Te);pe++){let W=ue[pe===0!==ee?ge:Te],K=V[W],N=ee?re-D[K]:D[K];y[j]===j&&ne<N&&I[W]===0&&(y[K]=j,y[j]=m[j]=m[K],C[j]=C[K]+de[W]-Y[W],ne=N)}}}let te=0;H.fill(0),R.fill(0);for(let O=0;O<=i;O++){let B=g[O],Q=g[O+1];for(let se=B+1;se<Q;se++){let ie=ee?T[se]:T[se-1],re=ee?T[se-1]:T[se],ne=F[ie]+F[re];L[te]=m[ie],S[te]=m[re],Z[te]=ee?ne-C[ie]+C[re]:ne+C[ie]-C[re],H[m[re]]++,R[m[ie]+1]++,te++}}for(let O=0;O<r;O++)R[O+1]+=R[O];w.set(R.subarray(0,r));for(let O=0;O<te;O++)P[w[L[O]]++]=O;let xe=new Float64Array(r),me=0;for(let O=0;O<r;O++)m[O]===O&&H[O]===0&&(b[me++]=O);for(let O=0;O<me;O++){let B=b[O];for(let Q=R[B];Q<R[B+1];Q++){let se=P[Q],ie=S[se];xe[B]+Z[se]>xe[ie]&&(xe[ie]=xe[B]+Z[se]),--H[ie]===0&&(b[me++]=ie)}}for(let O=me-1;O>=0;O--){let B=b[O],Q=1/0;for(let se=R[B];se<R[B+1];se++){let ie=P[se],re=xe[S[ie]]-Z[ie];re<Q&&(Q=re)}Q!==1/0&&Q>xe[B]&&(xe[B]=Q)}let ae=new Float64Array(r);for(let O=0;O<r;O++)ae[O]=(ee?-xe[m[O]]:xe[m[O]])+C[O];E.push(ae)}let M=0,f=1/0,x=[],A=[];for(let v=0;v<4;v++){let G=1/0,ee=-1/0,he=E[v];for(let ue=0;ue<r;ue++){let V=n[ue]/2;he[ue]-V<G&&(G=he[ue]-V),he[ue]+V>ee&&(ee=he[ue]+V)}x.push(G),A.push(ee),ee-G<f&&(f=ee-G,M=v)}for(let v=0;v<4;v++){let G=(v&1)===0?x[M]-x[v]:A[M]-A[v];if(G!==0){let ee=E[v];for(let he=0;he<r;he++)ee[he]+=G}}let z=new Float64Array(r);for(let v=0;v<r;v++){let G=E[0][v],ee=E[1][v],he=E[2][v],ue=E[3][v],V;G>ee&&(V=G,G=ee,ee=V),he>ue&&(V=he,he=ue,ue=V),G>he&&(V=G,G=he,he=V),ee>ue&&(V=ee,ee=ue,ue=V),ee>he&&(V=ee,ee=he,he=V),z[v]=(ee+he)/2}return z}var At=8,Cf=12,si=.62,pa=6;function ci(){let e=new Map;return{add(t,r,i){let n=Nt(i);r>=0&&n>0&&n+pa>(e.get(t*4+r)??0)&&e.set(t*4+r,n+pa)},of:(t,r)=>r>=0?e.get(t*4+r)??0:0}}function lr(e,t,r,i,n=r>0?r+pa:0,l=i>0?i+pa:0){let s=t==="linear",a=t==="step"||t==="stepBefore"||t==="stepAfter",d=[],c=[],p=[],u=(f,x,A,z)=>Math.abs(f-A)<.01&&Math.abs(x-z)<.01;for(let f=0;f<e.length;f+=3){let x=e[f],A=e[f+1],z=e[f+2],v=d.length-1;if(a&&v>=0&&Math.abs(x-d[v])>=.01&&Math.abs(A-c[v])>=.01){let G=d[v],ee=c[v],he=t==="stepBefore"?ee:t==="stepAfter"?A:(ee+A)/2,ue=t==="stepBefore"?G:t==="stepAfter"?x:(G+x)/2,V=z===0?[G,he,x,he]:[ue,ee,ue,A];for(let Y=0;Y<4;Y+=2)u(V[Y],V[Y+1],G,ee)||u(V[Y],V[Y+1],x,A)||(d.push(V[Y]),c.push(V[Y+1]),p.push(z))}d.push(x),c.push(A),p.push(z)}let h=d.length-1,$=f=>Math.abs(d[f]-d[f-1])<.01||Math.abs(c[f]-c[f-1])<.01,g=f=>s||$(f),T=(f,x,A)=>{if(!g(Math.max(f,x)))return A===0?[0,Math.sign(c[x]-c[f])||1]:[Math.sign(d[x]-d[f])||1,0];let z=d[x]-d[f],v=c[x]-c[f],G=Math.hypot(z,v)||1;return[z/G,v/G]},[D,_]=T(0,1,p[1]),[F,k]=T(h-1,h,p[h]),I=d[0],E=c[0],m=d[h],y=c[h];d[0]+=D*r,c[0]+=_*r,d[h]-=F*i,c[h]-=k*i;let C=f=>Math.abs(d[f]-d[f-1])+Math.abs(c[f]-c[f-1]),L=f=>!s&&f>0&&f<h&&$(f)&&$(f+1)&&C(f)>=.01&&C(f+1)>=.01&&Math.abs(d[f]-d[f-1])<.01!=Math.abs(d[f+1]-d[f])<.01,S=(f,x,A)=>Math.abs(d[f]-d[f-1])*Math.abs(x)+Math.abs(c[f]-c[f-1])*Math.abs(A),Z=(f,x,A)=>{let z=Math.min(Math.max(0,f-pa-x),A/4);return z+Math.min(f-x-z,(A-z)/4)},H=l>i&&(!g(h)||L(h-1))?Z(l,i,S(h,F,k)):0,R=n>r&&(!g(1)||L(1))?Z(n,r,S(1,D,_)):0;H>=1&&(d.splice(h,0,d[h]-F*H),c.splice(h,0,c[h]-k*H),p.splice(h,0,p[h]),h++),R>=1&&(d.splice(1,0,d[0]+D*R),c.splice(1,0,c[0]+_*R),p.splice(1,0,p[1]),h++);let P=`M${o(d[0])},${o(c[0])}`,w=d[0],b=c[0],M=(f,x)=>{u(f,x,w,b)||(P+=`L${o(f)},${o(x)}`,w=f,b=x)};for(let f=1;f<=h;f++){let x=d[f],A=c[f];if(!g(f)){let V=p[f]===0,Y=V?A-b:x-w,de=Math.abs(Y)*Fn(V?x-w:A-b,Y),te=V?0:Math.sign(Y)*de,xe=V?Math.sign(Y)*de:0;P+=`C${o(w+te)},${o(b+xe)} ${o(x-te)},${o(A-xe)} ${o(x)},${o(A)}`,w=x,b=A;continue}if(!L(f)){if(f<h&&$(f)&&$(f+1)&&(x-d[f-1])*(d[f+1]-x)+(A-c[f-1])*(c[f+1]-A)>0)continue;M(x,A);continue}let z=L(f-1)?C(f)/2:C(f),v=L(f+1)?C(f+1)/2:C(f+1);a&&(z=v=Math.min(Cf,z,v));let[G,ee]=T(f-1,f,p[f]),[he,ue]=T(f,f+1,p[f+1]);M(x-G*z,A-ee*z),w=x+he*v,b=A+ue*v,a?P+=`Q${o(x)},${o(A)} ${o(w)},${o(b)}`:P+=`C${o(x-G*z*(1-si))},${o(A-ee*z*(1-si))} ${o(x+he*v*(1-si))},${o(A+ue*v*(1-si))} ${o(w)},${o(b)}`}return{d:P,sx:I,sy:E,sdx:-D,sdy:-_,ex:m,ey:y,edx:F,edy:k}}function Nt(e){return e==="arrow_point"?At-1:e==="arrow_circle"?At:e==="arrow_cross"?4:0}function St(e,t,r,i,n,l){let s=-n,a=i;if(e==="arrow_point"){let d=t-i*At,c=r-n*At,p=At*.42;return`<path class="pele-marker" d="M${o(t)},${o(r)}L${o(d+s*p)},${o(c+a*p)}L${o(d-s*p)},${o(c-a*p)}Z" fill="${l}" stroke="none"/>`}if(e==="arrow_circle")return`<circle class="pele-marker" cx="${o(t-i*4)}" cy="${o(r-n*4)}" r="3.5" fill="${l}" stroke="none"/>`;if(e==="arrow_cross"){let d=t-i*4,c=r-n*4,p=3.5,u=(i+s)*p,h=(n+a)*p,$=(i-s)*p,g=(n-a)*p;return`<path class="pele-marker" d="M${o(d-u)},${o(c-h)}L${o(d+u)},${o(c+h)}M${o(d-$)},${o(c-g)}L${o(d+$)},${o(c+g)}"/>`}return""}function nr(e,t,r,i,n,l){let s=t.width+8,a=t.height;return`<g class="pele-edge-label" data-id="${Oe(e)}"><rect x="${o(r-s/2)}" y="${o(i-a/2)}" width="${o(s)}" height="${o(a)}" rx="3" fill="var(--_bg)"/>`+Ne(t,r,i,n,l)+"</g>"}function Pn(e,t,r,i,n,l,s,a){let d=(n?t:r)/2,c=Math.min(d-4,8+i*6),p=l+i*8,u=Math.hypot(p,c)||1,h=(T,D)=>n?`${o(e.x+D)},${o(e.y+r/2+T)}`:`${o(e.x+t/2+T)},${o(e.y+D)}`,$=p/u*s,g=c/u*s;return n?(a.labelX=e.x,a.labelY=e.y+r/2+p+4+a.labelH/2):(a.labelX=e.x+t/2+p+4+a.labelW/2,a.labelY=e.y),{d:`M${h(0,-c)}C${h(p,-c*2)} ${h(p,c*2)} ${h($,c+g)}`,sx:n?e.x-c:e.x+t/2,sy:n?e.y+r/2:e.y-c,sdx:n?0:-1,sdy:n?-1:0,ex:n?e.x+c:e.x+t/2,ey:n?e.y+r/2:e.y+c,edx:n?-c/u:-p/u,edy:n?-p/u:-c/u}}function Ft(e){return e==="BT"||e==="LR"||e==="RL"?e:"TB"}var Ef=4e4;function di(e,t,r,i){for(let n of e)n.x+=r,n.y+=i;for(let n of t){for(let l=0;l<n.route.length;l+=3)n.route[l]+=r,n.route[l+1]+=i;n.labelX+=r,n.labelY+=i}}function wt(e,t,r=-1){return{w:e,h:t,parent:r,isGroup:!1,dir:void 0,padX:0,padTop:0,padBottom:0,minW:0,seq:0,span:0,x:0,y:0}}function Hn(e){return e==="TB"?0:e==="BT"?2:e==="LR"?3:1}function Ls(e){return e+2&3}function or(e,t,r,i){let n=e.length,l=new Map,s=[],a=(m,y)=>{let C={id:m,dir:y,items:[],edges:[],ports:[],portOf:new Map,routes:new Map,x:0,y:0};return l.set(m,C),C},d=a(-1,r),c=[];for(let m=0;m<n;m++)c.push([]);let p=[];for(let m=0;m<n;m++){let y=e[m].parent;y>=0&&y<n&&y!==m&&e[y].isGroup?c[y].push(m):(e[m].parent=-1,p.push(m))}d.items=p,s.push(d);let u=new Int32Array(n),h=new Uint8Array(n),$=m=>{for(let y=m;y<s.length;y++){let C=s[y];for(let L of C.items)if(h[L]=1,u[L]=C.id<0?0:u[C.id]+1,e[L].isGroup){let S=a(L,e[L].dir??C.dir);S.items=c[L],s.push(S)}}};$(0);for(let m=0;m<n;m++){if(h[m])continue;let y=e[m].parent;if(c[y]=c[y].filter(C=>C!==m),e[m].parent=-1,d.items.push(m),h[m]=1,u[m]=0,e[m].isGroup){let C=s.length,L=a(m,e[m].dir??r);L.items=c[m],s.push(L),$(C)}}for(let m=s.length-1;m>0;m--){let y=s[m],C=1/0;for(let L of y.items)e[L].seq<C&&(C=e[L].seq);C!==1/0&&(e[y.id].seq=C)}for(let m of s)m.items.sort((y,C)=>e[y].seq-e[C].seq||y-C);let g=0;for(let m of t){let y=m.src,C=m.dst,L=0;for(;u[y]>u[C];L++)y=e[y].parent;for(;u[C]>u[y];L++)C=e[C].parent;for(;y!==C&&e[y].parent!==e[C].parent;L+=2)y=e[y].parent,C=e[C].parent;y!==C&&(g+L>Ef?(m.src=y,m.dst=C):g+=L)}let T=[],D=[];for(let m=0;m<t.length;m++){let y=t[m];if(y.route=[],y.src===y.dst){T.push(m);continue}let C=y.src,L=y.dst,S=[],Z=[];for(;u[C]>u[L];)S.push(C),C=e[C].parent;for(;u[L]>u[C];)Z.push(L),L=e[L].parent;if(C===L){D.push(m);continue}for(;e[C].parent!==e[L].parent;)S.push(C),Z.push(L),C=e[C].parent,L=e[L].parent;l.get(e[C].parent).edges.push({e:m,a:C,b:L});for(let[H,R]of[[S,!0],[Z,!1]])for(let P of H){let w=l.get(e[P].parent),b={e:m,inner:P,out:R,side:0,px:0,py:0,route:[]};w.ports.push(b),w.portOf.set(m*2+(R?0:1),b)}}let _=new Int32Array(n),F=(m,y,C)=>(C?y.src:y.dst)!==m,k=(m,y)=>{let C=m.dir==="TB"||m.dir==="BT",L=Hn(m.dir),S=[],Z=[];m.items.forEach((w,b)=>{_[w]=b;let M=e[w],f=y?ni(C?M.w:M.h,C?M.h:M.w):ni(0,0);f.span=M.isGroup?Math.min(M.span,f.w-2*M.padX):M.span,S.push(f)});let H=(w,b,M)=>e[w].isGroup&&F(w,t[b],M),R=(w,b,M)=>{if(!y||!e[w].isGroup||!F(w,t[b],M))return 0;let f=l.get(w).portOf.get(b*2+(M?0:1));return C?f.px-e[w].w/2:f.py-e[w].h/2};for(let w of m.edges){let b=t[w.e],M=oi(_[w.a],_[w.b],b.minlen);y&&(M.labelW=C?b.labelW:b.labelH,M.labelH=C?b.labelH:b.labelW,M.tailDx=R(w.a,w.e,!0),M.headDx=R(w.b,w.e,!1),M.tailFixed=H(w.a,w.e,!0),M.headFixed=H(w.b,w.e,!1)),Z.push(M)}let P=new Int32Array(m.ports.length).fill(-1);return m.ports.forEach((w,b)=>{if(w.side===L||w.side===Ls(L)){let M=S.length;S.push(ni(0,0,w.side===L?3:4)),P[b]=M;let f=w.out?oi(_[w.inner],M):oi(M,_[w.inner]);w.out?(f.tailDx=R(w.inner,w.e,!0),f.tailFixed=H(w.inner,w.e,!0)):(f.headDx=R(w.inner,w.e,!1),f.headFixed=H(w.inner,w.e,!1)),Z.push(f)}else S[_[w.inner]].pin=w.side===0||w.side===3?-1:1}),{lnodes:S,ledges:Z,dummies:P}};for(let m of s){for(let Z of m.ports)e[Z.inner].isGroup&&F(Z.inner,t[Z.e],Z.out)&&(l.get(Z.inner).portOf.get(Z.e*2+(Z.out?0:1)).side=Z.side);if(m.edges.length===0)continue;let y=!1;for(let Z of m.edges){let H=t[Z.e];(e[Z.a].isGroup&&H.src!==Z.a||e[Z.b].isGroup&&H.dst!==Z.b)&&(y=!0)}if(!y)continue;let{lnodes:C,ledges:L}=k(m,!1);Is(C,L),Ns(C,L,1);let S=Hn(m.dir);m.edges.forEach((Z,H)=>{let R=t[Z.e],P=!L[H].reversed;e[Z.a].isGroup&&R.src!==Z.a&&(l.get(Z.a).portOf.get(Z.e*2).side=P?Ls(S):S),e[Z.b].isGroup&&R.dst!==Z.b&&(l.get(Z.b).portOf.get(Z.e*2+1).side=P?S:Ls(S))})}let I={width:0,height:0};for(let m=s.length-1;m>=0;m--){let y=s[m],C=y.id>=0?e[y.id]:void 0,L=y.dir==="TB"||y.dir==="BT",S=y.dir==="BT"||y.dir==="RL",{lnodes:Z,ledges:H,dummies:R}=k(y,!0),P=Rn(Z,H,i),w=L?P.width:P.height,b=L?P.height:P.width,M=C?C.padX:0,f=C?C.padTop:0,x=Math.max(w+2*M,C?C.minW:0),A=b+f+(C?C.padBottom:0),z=(x-w)/2,v=f,G=(Y,de)=>z+(L?Y:S?P.height-de:de),ee=(Y,de)=>v+(L?S?P.height-de:de:Y),he=L?0:1,ue=Y=>{let de=[];for(let te=0;te<Y.length;te+=2)de.push(G(Y[te],Y[te+1]),ee(Y[te],Y[te+1]),he);return de};y.items.forEach((Y,de)=>{e[Y].x=G(Z[de].x,Z[de].y),e[Y].y=ee(Z[de].x,Z[de].y)}),y.edges.forEach((Y,de)=>{let te=H[de];y.routes.set(Y.e,ue(te.points));let xe=t[Y.e];xe.labelW>0&&(xe.labelX=G(te.labelX,te.labelY),xe.labelY=ee(te.labelX,te.labelY))});let V=y.edges.length;y.ports.forEach((Y,de)=>{let te=e[Y.inner];if(R[de]>=0){let Q=ue(H[V++].points),se=Y.out?Q.length-3:0,ie=Q[se],re=Q[se+1];Y.side===0?re=0:Y.side===2?re=A:Y.side===3?ie=0:ie=x,Y.out?Q.push(ie,re,he):Q.unshift(ie,re,he),Y.px=ie,Y.py=re,Y.route=Q;return}let xe=te.x,me=te.y;if(te.isGroup&&F(Y.inner,t[Y.e],Y.out)){let Q=l.get(Y.inner).portOf.get(Y.e*2+(Y.out?0:1));xe+=Q.px-te.w/2,me+=Q.py-te.h/2}else Y.side===0?me-=te.h/2:Y.side===2?me+=te.h/2:Y.side===3?xe-=te.w/2:xe+=te.w/2;let ae=xe,O=me;Y.side===0?O=0:Y.side===2?O=A:Y.side===3?ae=0:ae=x;let B=Y.side===0||Y.side===2?0:1;Y.px=ae,Y.py=O,Y.route=Y.out?[xe,me,B,ae,O,B]:[ae,O,B,xe,me,B]}),C?(C.w=x,C.h=A):I={width:x,height:A}}for(let m of s){let y=m.x,C=m.y;for(let L of m.items){let S=e[L];if(S.x+=y,S.y+=C,S.isGroup){let Z=l.get(L);Z.x=S.x-S.w/2,Z.y=S.y-S.h/2}}}let E=(m,y,C,L)=>{for(let S=0;S<y.length;S+=3){let Z=y[S]+C,H=y[S+1]+L,R=m.length;R>=3&&Math.abs(m[R-3]-Z)<.01&&Math.abs(m[R-2]-H)<.01||m.push(Z,H,y[S+2])}};for(let m of s)for(let y of m.edges){let C=t[y.e],L=[],S=[];for(let H=C.src;e[H].parent!==m.id;H=e[H].parent)S.push(l.get(e[H].parent));for(let H of S)E(L,H.portOf.get(y.e*2).route,H.x,H.y);E(L,m.routes.get(y.e),m.x,m.y);let Z=[];for(let H=C.dst;e[H].parent!==m.id;H=e[H].parent)Z.push(l.get(e[H].parent));for(let H=Z.length-1;H>=0;H--)E(L,Z[H].portOf.get(y.e*2+1).route,Z[H].x,Z[H].y);C.route=L,C.labelW>0&&(C.labelX+=m.x,C.labelY+=m.y)}for(let m of D){let y=t[m],C=e[y.src],L=e[y.dst];y.route=[C.x,C.y,0,L.x,L.y,0],y.labelX=(C.x+L.x)/2,y.labelY=(C.y+L.y)/2}for(let m of T){let y=t[m],C=e[y.src];y.labelX=C.x+C.w/2+28+y.labelW/2,y.labelY=C.y}return I}var ga="about:blank",Sf=/^([^\w]*)(javascript|data|vbscript)/im,Yn=/&#(\w+)(^\w|;)?/g,Gn=/&(newline|tab);/gi,Os=/[\u0000-\u001F\u007F-\u009F -]/gim,_f=/^.+(:|:)/gim,Bn=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g;function Un(e){try{return decodeURIComponent(e)}catch{return e}}function xr(e){if(!e)return ga;let t=Un(e.trim()),r,i=0;do{if(++i>32)return ga;t=t.replace(Os,"").replace(Yn,(d,c)=>String.fromCharCode(c)).replace(Gn,"").replace(Os,"").replace(Bn,"").trim(),t=Un(t),r=t.match(Os)||t.match(Yn)||t.match(Gn)||t.match(Bn)}while(r&&r.length>0);if(!t)return ga;if(t[0]==="."||t[0]==="/")return t;let n=t.trimStart(),l=n.match(_f);if(!l)return t;let s=l[0].toLowerCase().trim();if(Sf.test(s))return ga;let a=n.replace(/\\/g,"/");if(s==="mailto:"||s.includes("://"))return a;if(s==="http:"||s==="https:"){let d;try{d=new URL(a)}catch{return ga}return d.protocol=d.protocol.toLowerCase(),d.hostname=d.hostname.toLowerCase(),d.toString()}return a}function br(e){return xr(nt(e))}var Df=["http","https","mailto","tel"],If=["http","https"],Nf=/^([a-z][a-z0-9+.-]*):/i,Lf=/^[\\/]{2}/;function qn(e,t){if(Lf.test(e))return;let r=Nf.exec(e);return!r||t.includes(r[1].toLowerCase())?e:void 0}function ma(e,t){return t.links===!1?void 0:qn(e,t.linkSchemes??Df)}function jn(e,t){return t.images===!1?void 0:qn(e,t.imageSchemes??If)}function cr(e,t,r,i,n,l=""){let s=ma(t,n);return s===void 0?e:(i.push({id:r,href:s,internal:!1}),`<a href="${Be(s)}"${l}${ya(n)}>${e}</a>`)}function ya(e){let t=e.linkRel??"noopener";return t?` rel="${Be(t)}"`:""}var Ue=18,qe=12,qr=12,_t=(e,t,r)=>(r?t:e)-2*qr,$a=e=>(t,r,i)=>i?0:t-2*e(r)-2*qr;function pi(e,t,r){let i=Math.min(1,Math.abs(e)/t);return r*(1-Math.sqrt(1-i*i))}var kr=(e,t,r,i)=>r&1?pi(i,t/2,e/2):pi(i,e/2,t/2),vr=(e,t,r)=>(r?t:e)*.6,Xn=(e,t,r,i)=>r&1?0:pi(i,e/2,Math.min(12,Math.max(6,e/14))),Mr=(e,t)=>()=>({w:e,h:t,dy:0});function Vn(e,t,r){let i=Math.max(1.6*e+40,80),n=(t+10)/(1-(e+8)/i),l=n/2-10-t/2;return{w:i,h:n,dy:r?-l:l}}function Ur(e,t){return`<path d="${e}"${t}/>`}var hi=(e,t,r)=>r&1?t/8:0,wa=(e,t)=>({w:Math.max(e+2*Ue,2*Ue+12),h:t+2*qe,dy:0});function Tt(e,t){let r="";for(let i=0;i<e.length;i+=2)r+=(i?" ":"")+o(e[i])+","+o(e[i+1]);return`<polygon points="${r}"${t}/>`}function kt(e,t,r,i=""){return`<rect x="${o(-e/2)}" y="${o(-t/2)}" width="${o(e)}" height="${o(t)}"${i}${r}/>`}var Wt=` rx="${Ke}"`,Kn={rect:{size:wa,span:_t,draw:(e,t,r)=>kt(e,t,r,Wt)},rounded:{size:wa,span:_t,draw:(e,t,r)=>kt(e,t,r,` rx="${o(Math.min(12,t/2))}"`)},stadium:{inset:(e,t,r,i)=>r&1?pi(i,t/2,t/2):0,span:(e,t,r)=>r?t*.6:e-t,size:(e,t)=>{let r=t+2*qe;return{w:e+r*.5+2*Ue-8,h:r,dy:0}},draw:(e,t,r)=>kt(e,t,r,` rx="${o(t/2)}"`)},"fr-rect":{span:_t,size:(e,t)=>({w:e+2*Ue+16,h:t+2*qe,dy:0}),draw:(e,t,r,i)=>{let n=e/2-8;return kt(e,t,r,Wt)+`<path d="M${o(-n)},${o(-t/2)}V${o(t/2)}M${o(n)},${o(-t/2)}V${o(t/2)}" fill="none"${i}/>`}},cyl:{inset:Xn,span:(e,t,r)=>r?t-2*qr-12:e*.6,size:(e,t)=>{let r=Math.max(e+2*Ue,56),i=Math.min(12,Math.max(6,r/14));return{w:r,h:t+2*qe+2*i,dy:i/2}},draw:(e,t,r,i)=>{let n=e/2,l=Math.min(12,Math.max(6,e/14)),s=-t/2+l,a=t/2-l;return`<path d="M${o(-n)},${o(s)}A${o(n)},${o(l)} 0 0 1 ${o(n)},${o(s)}V${o(a)}A${o(n)},${o(l)} 0 0 1 ${o(-n)},${o(a)}Z"${r}/><path d="M${o(-n)},${o(s)}A${o(n)},${o(l)} 0 0 0 ${o(n)},${o(s)}" fill="none"${i}/>`}},circle:{inset:kr,span:vr,size:(e,t)=>{let r=Math.max(Math.sqrt(e*e+t*t)+16,44);return{w:r,h:r,dy:0}},draw:(e,t,r)=>`<circle r="${o(e/2)}"${r}/>`},"dbl-circ":{inset:kr,span:vr,size:(e,t)=>{let r=Math.max(Math.sqrt(e*e+t*t)+26,54);return{w:r,h:r,dy:0}},draw:(e,t,r,i)=>`<circle r="${o(e/2)}"${r}/><circle r="${o(e/2-5)}" fill="none"${i}/>`},ellipse:{inset:kr,span:vr,size:(e,t)=>({w:e*1.3+2*Ue,h:t*1.2+2*qe,dy:0}),draw:(e,t,r)=>`<ellipse rx="${o(e/2)}" ry="${o(t/2)}"${r}/>`},diam:{inset:(e,t,r,i)=>r&1?Math.abs(i)*e/t:Math.abs(i)*t/e,span:(e,t,r)=>(r?t:e)*.6,size:(e,t)=>{let r=e+16,i=t+8;return{w:r+1.6*i,h:r/1.6+i,dy:0}},draw:(e,t,r)=>Tt([0,-t/2,e/2,0,0,t/2,-e/2,0],r)},hex:{inset:(e,t,r,i)=>r&1?Math.abs(i)/2:0,span:(e,t,r)=>r?t*.5:e-t/2-qr,size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/2,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2+i,-t/2,e/2-i,-t/2,e/2,0,e/2-i,t/2,-e/2+i,t/2,-e/2,0],r)}},odd:{inset:(e,t,r)=>r===3?t/4:0,span:$a(()=>0),size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/4,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2,-t/2,e/2,-t/2,e/2,t/2,-e/2,t/2,-e/2+i,0],r)}},"lean-r":{inset:hi,span:$a(e=>e/4),size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/2,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2+i,-t/2,e/2,-t/2,e/2-i,t/2,-e/2,t/2],r)}},"lean-l":{inset:hi,span:$a(e=>e/4),size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/2,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2,-t/2,e/2-i,-t/2,e/2,t/2,-e/2+i,t/2],r)}},"trap-b":{inset:hi,span:$a(e=>e/4),size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/2,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2+i,-t/2,e/2-i,-t/2,e/2,t/2,-e/2,t/2],r)}},"trap-t":{inset:hi,span:$a(e=>e/4),size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/2,h:r,dy:0}},draw:(e,t,r)=>{let i=t/4;return Tt([-e/2,-t/2,e/2,-t/2,e/2-i,t/2,-e/2+i,t/2],r)}},text:{span:_t,size:(e,t)=>({w:e+8,h:t+8,dy:0}),draw:(e,t)=>kt(e,t,' fill="none" stroke="none"')},"sm-circ":{noLabel:!0,inset:kr,span:vr,size:Mr(14,14),draw:(e,t,r)=>`<circle r="${o(e/2)}"${r}/>`},"f-circ":{noLabel:!0,inset:kr,span:vr,size:Mr(14,14),draw:(e,t,r,i)=>`<circle r="${o(e/2)}" fill="var(--_l)"${i}/>`},"fr-circ":{noLabel:!0,inset:kr,span:vr,size:Mr(18,18),draw:(e,t,r,i)=>`<circle r="${o(e/2)}"${r}/><circle r="${o(e/2-4)}" fill="var(--_l)"${i}/>`},fork:{noLabel:!0,span:(e,t,r)=>(r?t:e)-8,size:Mr(72,8),draw:(e,t,r,i)=>kt(e,t,` fill="var(--_l)"${i}`,' rx="2"')},"notch-rect":{size:wa,span:_t,draw:(e,t,r)=>Tt([-e/2+10,-t/2,e/2,-t/2,e/2,t/2,-e/2,t/2,-e/2,-t/2+10],r)},"lin-rect":{span:_t,size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe,dy:0}),draw:(e,t,r,i)=>kt(e,t,r,Wt)+`<path d="M${o(-e/2+8)},${o(-t/2)}V${o(t/2)}" fill="none"${i}/>`},"div-rect":{span:_t,size:(e,t)=>({w:e+2*Ue,h:t+2*qe+8,dy:4}),draw:(e,t,r,i)=>kt(e,t,r,Wt)+`<path d="M${o(-e/2)},${o(-t/2+8)}H${o(e/2)}" fill="none"${i}/>`},"win-pane":{span:_t,size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe+8,dy:4}),draw:(e,t,r,i)=>kt(e,t,r,Wt)+`<path d="M${o(-e/2+8)},${o(-t/2)}V${o(t/2)}M${o(-e/2)},${o(-t/2+8)}H${o(e/2)}" fill="none"${i}/>`},tri:{inset:(e,t,r)=>r&1?e/4:0,size:(e,t)=>Vn(e,t,!1),draw:(e,t,r)=>Tt([0,-t/2,e/2,t/2,-e/2,t/2],r)},"flip-tri":{inset:(e,t,r)=>r&1?e/4:0,size:(e,t)=>Vn(e,t,!0),draw:(e,t,r)=>Tt([-e/2,-t/2,e/2,-t/2,0,t/2],r)},"sl-rect":{inset:(e,t,r)=>r===0?5:0,size:(e,t)=>({w:e+2*Ue,h:t+2*qe+10,dy:5}),draw:(e,t,r)=>Tt([-e/2,-t/2+10,e/2,-t/2,e/2,t/2,-e/2,t/2],r)},"notch-pent":{span:_t,size:(e,t)=>({w:e+2*Ue,h:t+2*qe,dy:0}),draw:(e,t,r)=>Tt([-e/2+10,-t/2,e/2-10,-t/2,e/2,-t/2+10,e/2,t/2,-e/2,t/2,-e/2,-t/2+10],r)},hourglass:{noLabel:!0,inset:(e,t,r)=>r&1?e/2:0,size:Mr(32,40),draw:(e,t,r)=>Tt([-e/2,-t/2,e/2,-t/2,-e/2,t/2,e/2,t/2],r)},delay:{size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r/4,h:r,dy:0}},draw:(e,t,r)=>{let i=t/2;return`<path d="M${o(-e/2)},${o(-i)}H${o(e/2-i)}A${o(i)},${o(i)} 0 0 1 ${o(e/2-i)},${o(i)}H${o(-e/2)}Z"${r}/>`}},"h-cyl":{size:(e,t)=>{let r=t+2*qe,i=Math.min(12,r/4);return{w:e+2*Ue+2*i,h:r,dy:0}},draw:(e,t,r,i)=>{let n=t/2,l=Math.min(12,t/4),s=-e/2+l,a=e/2-l;return`<path d="M${o(s)},${o(-n)}H${o(a)}A${o(l)},${o(n)} 0 0 1 ${o(a)},${o(n)}H${o(s)}A${o(l)},${o(n)} 0 0 1 ${o(s)},${o(-n)}Z"${r}/><path d="M${o(a)},${o(-n)}A${o(l)},${o(n)} 0 0 0 ${o(a)},${o(n)}" fill="none"${i}/>`}},"cross-circ":{noLabel:!0,inset:kr,span:vr,size:Mr(44,44),draw:(e,t,r,i)=>{let n=e/2,l=n*Math.SQRT1_2;return`<circle r="${o(n)}"${r}/><path d="M${o(-l)},${o(-l)}L${o(l)},${o(l)}M${o(l)},${o(-l)}L${o(-l)},${o(l)}" fill="none"${i}/>`}},"st-rect":{span:(e,t,r)=>(r?t:e)-2*qr-8,size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe+8,dy:4}),draw:(e,t,r)=>{let i=e-8,n=t-8,l="";for(let s=0;s<3;s++){let a=-e/2+(2-s)*4,d=-t/2+s*4;l+=`<rect x="${o(a)}" y="${o(d)}" width="${o(i)}" height="${o(n)}"${Wt}${r}/>`}return l}},doc:{inset:(e,t,r)=>r===2?10:0,size:(e,t)=>({w:e+2*Ue,h:t+2*qe+10,dy:-5}),draw:(e,t,r)=>ui(e,t,r)},flag:{inset:(e,t,r)=>r&1?0:8,size:(e,t)=>({w:e+2*Ue,h:t+2*qe+16,dy:0}),draw:(e,t,r)=>{let i=e/2,n=t/2-8,l=e/4;return`<path d="M${o(-i)},${o(-n)}q${o(l)},-10 ${o(2*l)},0t${o(2*l)},0V${o(n)}q${o(-l)},10 ${o(-2*l)},0t${o(-2*l)},0Z"${r}/>`}},datastore:{size:wa,span:_t,draw:(e,t,r,i)=>kt(e,t,r.replace('stroke="var(--_b)"','stroke="none"'))+`<path d="M${o(-e/2)},${o(-t/2)}H${o(e/2)}M${o(-e/2)},${o(t/2)}H${o(e/2)}" fill="none"${i}/>`},folder:{size:(e,t)=>({w:Math.max(e+2*Ue,64),h:t+2*qe+8,dy:4}),draw:(e,t,r)=>{let i=e/2,n=t/2,l=Math.min(e*.4,48);return Ur(`M${o(-i)},${o(-n)}H${o(-i+l)}L${o(-i+l+8)},${o(-n+8)}H${o(i)}V${o(n)}H${o(-i)}Z`,r)}},bucket:{size:(e,t)=>({w:e+2*Ue+20,h:t+2*qe+10,dy:3}),inset:(e,t,r)=>r&1?t/12:0,draw:(e,t,r,i)=>{let n=e/2,l=t/2,s=5,a=t/6;return Ur(`M${o(-n)},${o(-l+s)}A${o(n)},${o(s)} 0 0 1 ${o(n)},${o(-l+s)}L${o(n-a)},${o(l-s)}A${o(n-a)},${o(s)} 0 0 1 ${o(-n+a)},${o(l-s)}Z`,r)+`<path d="M${o(-n)},${o(-l+s)}A${o(n)},${o(s)} 0 0 0 ${o(n)},${o(-l+s)}" fill="none"${i}/>`}},console:{span:_t,size:(e,t)=>({w:Math.max(e+2*Ue,72),h:t+2*qe+12,dy:6}),draw:(e,t,r,i)=>kt(e,t,r,Wt)+`<path d="M${o(-e/2)},${o(-t/2+12)}H${o(e/2)}M${o(-e/2+7)},${o(-t/2+4)}l3,2.5l-3,2.5M${o(-e/2+13)},${o(-t/2+9)}h4" fill="none"${i}/>`},browser:{span:_t,size:(e,t)=>({w:Math.max(e+2*Ue,72),h:t+2*qe+12,dy:6}),draw:(e,t,r,i)=>{let n="";for(let l=0;l<3;l++)n+=`<circle cx="${o(-e/2+8+l*7)}" cy="${o(-t/2+6)}" r="1.5" fill="none"${i}/>`;return kt(e,t,r,Wt)+`<path d="M${o(-e/2)},${o(-t/2+12)}H${o(e/2)}" fill="none"${i}/>`+n}},person:{size:(e,t)=>({w:Math.max(e+2*Ue,56),h:t+2*qe+26,dy:13}),draw:(e,t,r)=>{let i=-t/2;return`<rect x="${o(-e/2)}" y="${o(i+26)}" width="${o(e)}" height="${o(t-26)}" rx="12"${r}/><circle cy="${o(i+14)}" r="13"${r}/>`}},bang:{size:(e,t)=>({w:e+2*Ue+28,h:t+2*qe+24,dy:0}),inset:()=>3,draw:(e,t,r)=>{let i=[];for(let n=0;n<28;n++){let l=Math.PI*n/14-Math.PI/2,s=n%2===0?1:.82;i.push(Math.cos(l)*(e/2)*s,Math.sin(l)*(t/2)*s)}return Tt(i,r)}},cloud:{size:(e,t)=>({w:e+2*Ue+32,h:t+2*qe+24,dy:0}),inset:(e,t,r)=>r&1?2:1,draw:(e,t,r)=>{let i=e/2,n=t/2,l=n*.55;return Ur(`M${o(-i+l)},${o(n)}A${o(l)},${o(l)} 0 0 1 ${o(-i+l*.6)},${o(-n*.1)}A${o(i*.42)},${o(n*.7)} 0 0 1 ${o(-i*.1)},${o(-n*.72)}A${o(i*.4)},${o(n*.62)} 0 0 1 ${o(i*.62)},${o(-n*.42)}A${o(l*1.05)},${o(l*1.05)} 0 0 1 ${o(i-l)},${o(n)}Z`,r)}},brace:{size:(e,t)=>({w:e+2*Ue+12,h:t+2*qe,dy:0}),draw:(e,t,r,i)=>kt(e,t,' fill="none" stroke="none"')+fi(-e/2+12,t,-1,i)},"brace-r":{size:(e,t)=>({w:e+2*Ue+12,h:t+2*qe,dy:0}),draw:(e,t,r,i)=>kt(e,t,' fill="none" stroke="none"')+fi(e/2-12,t,1,i)},braces:{size:(e,t)=>({w:e+2*Ue+24,h:t+2*qe,dy:0}),draw:(e,t,r,i)=>kt(e,t,' fill="none" stroke="none"')+fi(-e/2+12,t,-1,i)+fi(e/2-12,t,1,i)},bolt:{noLabel:!0,size:Mr(36,56),inset:(e,t,r)=>r&1?e/4:0,draw:(e,t,r)=>Tt([e*.15,-t/2,-e/2,t*.08,-e*.05,t*.08,-e*.15,t/2,e/2,-t*.08,e*.05,-t*.08],r)},"lin-cyl":{inset:Xn,span:(e,t,r)=>r?t-2*qr-20:e*.6,size:(e,t)=>{let r=Math.max(e+2*Ue,56),i=Math.min(12,Math.max(6,r/14));return{w:r,h:t+2*qe+2*i+8,dy:i/2+4}},draw:(e,t,r,i)=>{let n=e/2,l=Math.min(12,Math.max(6,e/14)),s=-t/2+l,a=t/2-l,d=c=>`M${o(-n)},${o(c)}A${o(n)},${o(l)} 0 0 0 ${o(n)},${o(c)}`;return Ur(`M${o(-n)},${o(s)}A${o(n)},${o(l)} 0 0 1 ${o(n)},${o(s)}V${o(a)}A${o(n)},${o(l)} 0 0 1 ${o(-n)},${o(a)}Z`,r)+`<path d="${d(s)}${d(s+8)}" fill="none"${i}/>`}},"curv-trap":{size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r*.6,h:r,dy:0}},draw:(e,t,r)=>{let i=e/2,n=t/2,l=t*.3;return Ur(`M${o(-i+l)},${o(-n)}H${o(i-l)}A${o(l)},${o(n)} 0 0 1 ${o(i-l)},${o(n)}H${o(-i+l)}L${o(-i)},0Z`,r)}},docs:{size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe+18,dy:-1}),inset:(e,t,r)=>r===2?10:0,draw:(e,t,r)=>{let i="";for(let n=0;n<3;n++)i+=`<g transform="translate(${(1-n)*4},${(n-1)*4})">${ui(e-8,t-8,r)}</g>`;return i}},"bow-rect":{size:(e,t)=>{let r=t+2*qe;return{w:e+2*Ue+r*.4,h:r,dy:0}},inset:(e,t,r)=>r===1?t*.2:0,draw:(e,t,r)=>{let i=e/2,n=t/2,l=t*.2;return Ur(`M${o(-i+l)},${o(-n)}H${o(i)}A${o(l)},${o(n)} 0 0 0 ${o(i)},${o(n)}H${o(-i+l)}A${o(l)},${o(n)} 0 0 1 ${o(-i+l)},${o(-n)}Z`,r)}},"tag-rect":{size:wa,span:_t,draw:(e,t,r,i)=>kt(e,t,r,Wt)+`<path d="M${o(e/2-12)},${o(t/2)}L${o(e/2)},${o(t/2-12)}" fill="none"${i}/>`},"tag-doc":{size:(e,t)=>({w:e+2*Ue,h:t+2*qe+10,dy:-5}),inset:(e,t,r)=>r===2?10:0,draw:(e,t,r,i)=>ui(e,t,r)+`<path d="M${o(e/2-12)},${o(t/2-14)}L${o(e/2)},${o(t/2-26)}" fill="none"${i}/>`},"lin-doc":{size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe+10,dy:-5}),inset:(e,t,r)=>r===2?10:0,draw:(e,t,r,i)=>ui(e,t,r)+`<path d="M${o(-e/2+8)},${o(-t/2)}V${o(t/2-6)}" fill="none"${i}/>`},collapsedGroup:{size:(e,t)=>({w:e+2*Ue+8,h:t+2*qe+8,dy:-2}),draw:(e,t,r)=>`<rect x="${o(-e/2+6)}" y="${o(-t/2+8)}" width="${o(e-12)}" height="${o(t-8)}"${Wt}${r}/><rect x="${o(-e/2)}" y="${o(-t/2)}" width="${o(e)}" height="${o(t-4)}"${Wt}${r}/>`}};function fi(e,t,r,i){let n=t/2,l=6*r;return`<path d="M${o(e)},${o(-n)}q${o(l)},0 ${o(l)},6V-6q0,6 ${o(l)},6q${o(-l)},0 ${o(-l)},6V${o(n-6)}q0,6 ${o(-l)},6" fill="none"${i}/>`}function ui(e,t,r){let i=e/2,n=-t/2,l=t/2-10,s=e/4;return`<path d="M${o(-i)},${o(n)}H${o(i)}V${o(l)}q${o(-s)},-12 ${o(-2*s)},0t${o(-2*s)},0Z"${r}/>`}var Zn=Kn.rect,xa=new Map(Object.entries(Kn));function gi(e,t,r){return(xa.get(e)??Zn).size(t,r)}function ba(e,t,r,i,n){return(xa.get(e)??Zn).draw(t,r,i,n)}function jr(e,t,r,i,n=0){return xa.get(e)?.inset?.(t,r,i,n)??0}function Qn(e,t,r,i){return Math.max(0,xa.get(e)?.span?.(t,r,i)??0)}function Jn(e){return xa.get(e)?.noLabel!==!0}function Lt(e,t,r){let i=e[t]-r.x,n=e[t+1]-r.y;return Math.abs(Math.abs(n)-r.h/2)<.5?n<0?0:2:Math.abs(Math.abs(i)-r.w/2)<.5?i<0?3:1:-1}function Rs(e,t,r,i){if(i.isGroup)return;let n=Lt(e,t,i);if(n===0||n===2){let l=jr(r.shape,r.w,r.h,n,e[t]-i.x)+(i.h-r.h)/2;e[t+1]+=n===0?l:-l}else if(n>=0){let l=jr(r.shape,r.w,r.h,n,e[t+1]-i.y)+(i.w-r.w)/2;e[t]+=n===3?l:-l}}function mi(e,t,r,i){let n=i(t,!1),l=e.maxWidth;if(l===void 0||!(l>0)||n.width<=l)return n;let s=Math.min(r,t),a=t;n=i(a,!0);for(let d=0;d<3&&n.width>l&&a>s;d++)a=Math.max(s,a-(n.width-l)),n=i(a,!0);return n}function Pt(e){let t=e.maxWidth;return t!==void 0&&t>0?Math.max(80,t-2*(e.padding??8)):4e3}function Xr(e,t,r,i=0){let n=e.maxWidth;return n===void 0||!(n>0)?t:Math.max(Math.min(r,t),Math.min(t,n-i))}var Of=640;function Ct(e,t){let r=t(!1),i=e.maxWidth;if(e.autoDirection===!1||i===void 0||!(i>0)||r.width<=i)return r;let n=e.directionBreakpoint;if(i>=(n!==void 0&&n>0?n:Of))return r;let l=t(!0);return l.width<r.width?l:r}function dr(e){return e==="LR"||e==="RL"}function Vr(e,t){let r=t(!1),i=e.maxWidth;if(i===void 0||!(i>0)||r.width<=i)return r;let n=t(!0);return n.width<r.width?n:r}function zs(e){return e==="markdown"||e==="string"||e==="text"?e:"markdown"}function eo(e){return e.startsWith('"')&&e.endsWith('"')?e.substring(1,e.length-1):e}function Rf(e,t){let r=0;for(let i=0;i<t.length;i++)t[i]===e&&r++;return r}function zf(e){let t=e.trim(),r="arrow_open";switch(t[0]){case"<":r="arrow_point",t=t.slice(1);break;case"x":r="arrow_cross",t=t.slice(1);break;case"o":r="arrow_circle",t=t.slice(1);break}let i="normal";return t.includes("=")&&(i="thick"),t.includes(".")&&(i="dotted"),{type:r,stroke:i}}function Ff(e){let t=e.trim(),r=t.slice(0,-1),i="arrow_open";switch(t.slice(-1)){case"x":i="arrow_cross",t.startsWith("x")&&(i="double_"+i,r=r.slice(1));break;case">":i="arrow_point",t.startsWith("<")&&(i="double_"+i,r=r.slice(1));break;case"o":i="arrow_circle",t.startsWith("o")&&(i="double_"+i,r=r.slice(1));break}let n="normal",l=r.length-1;r.startsWith("=")&&(n="thick"),r.startsWith("~")&&(n="invisible");let s=Rf(".",r);return s&&(n="dotted",l=s),{type:i,stroke:n,length:l}}var Wf=class{type="flowchart";direction;nodes=new Map;edges=[];subgraphs=[];classes=new Map;tooltips=new Map;defaultEdgeStyle;defaultInterpolate;title;accTitle;accDescr;subgraphLookup=new Map;members=new Set;edgeById=new Map;pairCount=new Map;subCount=0;options;constructor(e={}){this.options=e}addVertex(e,t,r,i,n,l,s={},a){if(!e||e.trim().length===0)return;let d;if(a!==void 0){let $=a.includes(`
46`)?a+`
47`:`{
48`+a+`
49}`,g;try{g=Wr($)}catch(T){throw new He(`Metadata of "${e}" is not valid YAML. ${T.message}`,"syntax",{type:"flowchart"})}d=g!==null&&typeof g=="object"&&!Array.isArray(g)?g:void 0}let c=this.subgraphLookup.get(e);if(c&&d){c.metadata={...c.metadata,...d};return}let p=this.edgeById.get(e);if(p){d?.animate!==void 0&&(p.animate=d.animate),d?.animation!==void 0&&(p.animation=d.animation),d?.curve!==void 0&&(p.interpolate=d.curve);return}let u=this.nodes.get(e);if(u===void 0&&(t===void 0&&r===void 0&&i!==void 0&&i!==null&&this.options.warn?.(`Style applied to unknown node "${e}". This may indicate a typo. The node will be created automatically.`),u={id:e,labelType:"text",styles:[],classes:[]},this.nodes.set(e,u)),t!==void 0?(u.labelType=t.type,u.text=eo(t.text.trim())):u.text===void 0&&(u.text=e),r!==void 0&&(u.type=r),i!=null)for(let $ of i)u.styles.push($);if(n!=null)for(let $ of n)u.classes.push($);if(l!==void 0&&(u.dir=l),u.props===void 0?u.props=s:s!==void 0&&Object.assign(u.props,s),d===void 0)return;if(d.shape){let $=String(d.shape);if($!==$.toLowerCase()||$.includes("_"))throw new He(`No such shape: ${$}. Shape names should be lowercase.`,"semantic",{type:"flowchart"});if(!mn($))throw new He(`No such shape: ${$}.`,"semantic",{type:"flowchart"});u.type=$}let h=typeof d.label=="string"?d.label:void 0;d.label&&(u.text=String(d.label),u.labelType=zs(d.labelType)),d.icon&&(u.icon=String(d.icon),!h?.trim()&&u.text===e&&(u.text="")),d.form&&(u.form=String(d.form)),d.pos&&(u.pos=String(d.pos)),d.img&&(u.img=String(d.img),!h?.trim()&&u.text===e&&(u.text="")),d.constraint&&(u.constraint=String(d.constraint)),d.w&&(u.assetWidth=Number(d.w)),d.h&&(u.assetHeight=Number(d.h))}addSingleLink(e,t,r,i){let n={start:e,end:t,type:void 0,text:"",labelType:"text",classes:[],isUserDefinedId:!1,interpolate:this.defaultInterpolate},l=r?.text;if(l!==void 0&&(n.text=eo(l.text.trim()),n.labelType=zs(l.type)),r!==void 0&&(n.type=r.type,n.stroke=r.stroke,n.length=r.length>10?10:r.length),i&&!this.edgeById.has(i))n.id=i,n.isUserDefinedId=!0;else{let d=this.pairCount.get(e+"\0"+t)??0;n.id=`L_${e}_${t}_${d===0?0:d+1}`}let s=this.options.maxEdges;if(s!==void 0&&this.edges.length>=s)throw new He(`Edge limit exceeded. ${this.edges.length} edges found, but the limit is ${s}.`,"limit",{type:"flowchart"});this.edges.push(n);let a=e+"\0"+t;this.pairCount.set(a,(this.pairCount.get(a)??0)+1),this.edgeById.has(n.id)||this.edgeById.set(n.id,n)}addLink(e,t,r){let i=typeof r?.id=="string"?r.id.replace("@",""):void 0,n=e[e.length-1],l=t[0];for(let s of e)for(let a of t)this.addSingleLink(s,a,r,s===n&&a===l?i:void 0)}updateLinkInterpolate(e,t){for(let r of e)r==="default"?this.defaultInterpolate=t:this.edgeAt(r).interpolate=t}updateLink(e,t){for(let r of e){if(r==="default"){this.defaultEdgeStyle=t;continue}let i=this.edgeAt(r);i.style=t,t.length>0&&!t.some(n=>n?.startsWith("fill"))&&t.push("fill:none")}}edgeAt(e){let t=this.edges[Number(e)];if(t===void 0)throw new He(`The index ${e} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${this.edges.length-1}. (Help: Ensure that the index is within the range of existing edges.)`,"semantic",{type:"flowchart"});return t}addClass(e,t){let r=t.join().replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");for(let i of e.split(",")){let n=this.classes.get(i);n===void 0&&(n={id:i,styles:[],textStyles:[]},this.classes.set(i,n));for(let l of r)l.includes("color")&&n.textStyles.push(l.replace("fill","bgFill")),n.styles.push(l)}}setDirection(e){let t=e.trim();t.includes("<")&&(t="RL"),t.includes("^")&&(t="BT"),t.includes(">")&&(t="LR"),t.includes("v")&&(t="TB"),t==="TD"&&(t="TB"),this.direction=t}setClass(e,t){for(let r of e.split(","))this.nodes.get(r)?.classes.push(t),this.edgeById.get(r)?.classes.push(t),this.subgraphLookup.get(r)?.classes.push(t)}setTooltip(e,t){if(t!==void 0)for(let r of e.split(","))this.tooltips.set(r,t)}setLink(e,t,r){let i=t.trim();for(let n of e.split(",")){let l=this.nodes.get(n);l!==void 0&&(l.link=i?br(i):void 0,l.linkTarget=r)}this.setClass(e,"clickable")}setClickEvent(e,t,r){this.setClass(e,"clickable")}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
50`)}addSubGraph(e,t,r){let i=e?.text.trim(),n=r?.text??"";e!==void 0&&e===r&&/\s/.test(n)&&(i=void 0);let l=new Set,s=[],a;for(let u of t)if(typeof u=="string")u.trim()!==""&&!l.has(u)&&(l.add(u),s.push(u));else if(Array.isArray(u))for(let h of u)h.trim()!==""&&!l.has(h)&&(l.add(h),s.push(h));else a=u.value;a??=this.options.inheritDir?this.direction??this.options.direction:void 0,i??="subGraph"+this.subCount,n=n||"",this.subCount++;let d={id:i,nodes:s,title:n.trim(),classes:[],dir:a,labelType:zs(r?.type)},c=this.members;d.nodes=s.filter(u=>!c.has(u)&&u!==i);for(let u of d.nodes)c.add(u);let p=this.subgraphLookup.get(i);if(p)for(let u of d.nodes)p.nodes.push(u);else this.subgraphs.push(d);return this.subgraphLookup.set(i,p??d),i}exists(e,t){for(let r of e)if(r.nodes.includes(t))return!0;return!1}makeUniq(e,t){let r=new Set;for(let i of t)for(let n of i.nodes)r.add(n);return{nodes:e.nodes.filter(i=>!r.has(i))}}destructLink(e,t){let r=Ff(e);if(!t)return r;let i=zf(t);if(i.stroke!==r.stroke)return{type:"INVALID",stroke:"INVALID"};if(i.type==="arrow_open")i.type=r.type;else{if(i.type!==r.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return i.type==="double_arrow"&&(i.type="double_arrow_point"),i.length=r.length,i}subgraph(e){return this.subgraphLookup.get(e)}},to=["$end","INVALID","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","SHAPE_DATA","CALLBACKNAME","CALLBACKARGS","MD_STR","STR","STYLE","DEFAULT","LINKSTYLE","INTERPOLATE","CLASSDEF","CLASS","HREF","CLICK","GRAPH","subgraph","end","LINK_TARGET","NODIR","DIR","direction_tb","direction_bt","direction_rl","direction_lr","direction_td","LINK_ID","NUM","BRKT","STYLE_SEPARATOR","COLON","AMP","SEMI","COMMA","MULT","LINK","START_LINK","EDGE_TEXT","-)","TEXT","(-","STADIUMEND","STADIUMSTART","SUBROUTINEEND","SUBROUTINESTART","VERTEX_WITH_PROPS_START","TAGEND","CYLINDEREND","CYLINDERSTART","DOUBLECIRCLEEND","DOUBLECIRCLESTART","TRAPEND","INVTRAPEND","TRAPSTART","INVTRAPSTART","TAGSTART","UP","SEP","DOWN","NODE_STRING","MINUS","UNICODE_TEXT","PIPE","PE","PS","SQE","SQS","DIAMOND_STOP","DIAMOND_START","NEWLINE","SPACE","EOF"],oo=new Uint8Array(128);for(let e of"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'*+.`?\\_/")oo[e.charCodeAt(0)]=1;var Pf=/accTitle\s*:\s*/y,Hf=/accDescr\s*:\s*/y,Yf=/accDescr\s*\{\s*/y,Gf=/call\s+/y,Bf=/click\s+/y,Uf=/(?:\r?\n)*\s*\n/y,qf=/\s*(?:LR|RL|TB|BT|TD|BR)\b/y,jf=/\s*[<>^]/y,Xf=/\s*v\b/y,Vf=[/.*direction\s+TB[^\n]*/y,/.*direction\s+BT[^\n]*/y,/.*direction\s+RL[^\n]*/y,/.*direction\s+LR[^\n]*/y,/.*direction\s+TD[^\n]*/y],Fs=/[\n\r\u2028\u2029]/g,ro=/\s*[xo<]?--+[-xo>]\s*/y,Kf=/\s*[xo<]?--\s*/y,ao=/\s*[xo<]?==+[=xo>]\s*/y,Zf=/\s*[xo<]?==\s*/y,Ws=/\s*[xo<]?-?\.+-[xo>]?\s*/y,Qf=/\s*[xo<]?-\.\s*/y,io=/\s*~~~+\s*/y,Jf=/(?:\r?\n)+/y,eu=/[^\S\n\r]+/y,tu=/\(\s*\)/y,ru=/\n\s*/g;function au(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=!0,c=e.indexOf("direction"),p=e.indexOf("@"),u=-1,h=0,$=0,g=-1,T=-1,D=-1,_=(b,M,f)=>{r.push(b),i.push(e.slice(M,f)),n.push(M),a=f},F=b=>{l.push(s),s=b},k=()=>{l.length>0&&(s=l.pop())},I=(b,M)=>(b.lastIndex=M,b.test(e)?b.lastIndex:-1),E=b=>e.startsWith(b,a)&&!Pe(e.charCodeAt(a+b.length)),m=b=>{let M=b;if(b>=T&&b<=D)M=D;else if(Le(e.charCodeAt(b))){for(;M<t&&Le(e.charCodeAt(M));)M++;T=b,D=M}let f=e.charCodeAt(M);return f===120||f===111||f===60?e.charCodeAt(M+1):f},y=b=>{let M=b;if(b>=T&&b<=D)M=D;else if(Le(e.charCodeAt(b))){for(;M<t&&Le(e.charCodeAt(M));)M++;T=b,D=M}return e.charCodeAt(M)===126},C=()=>{e.charCodeAt(a+1)===96?(F(2),a+=2):(F(1),a++)},L=()=>{if(!y(a))return!1;let b=I(io,a);return b<0?!1:(_(40,a,b),!0)},S=b=>{let M=e.charCodeAt(a+1);return b===40?(M===45?(F(8),_(45,a,a+2)):M===91?(F(7),_(47,a,a+2)):M===40&&e.charCodeAt(a+2)===40?(F(7),_(55,a,a+3)):(F(7),_(69,a,a+1)),!0):b===91?(M===91?(F(7),_(49,a,a+2)):M===40?(F(7),_(53,a,a+2)):M===47?(F(9),_(58,a,a+2)):M===92?(F(9),_(59,a,a+2)):(F(7),_(71,a,a+1)),!0):b===124?(F(7),_(67,a,a+1),!0):b===123?(F(7),_(73,a,a+1),!0):!1},Z=b=>{d&&(d=!1,F(6)),_(20,a,a+b)},H=()=>{let b=a;for(;b<t;){let M=e.charCodeAt(b);if(M<128&&oo[M]===1)b++;else if(M===45&&b+1<t){let f=e.charCodeAt(b+1);if(f===62||f===45||f===46)break;b++}else break}return b===a?!1:(_(64,a,b),!0)},R=b=>{let M=m(a),f;if(M===45){if((f=I(ro,a))>=0)return _(40,a,f),!0;if((f=I(Kf,a))>=0)return F(10),_(41,a,f),!0;if((f=I(Ws,a))>=0)return _(40,a,f),!0;if((f=I(Qf,a))>=0)return F(12),_(41,a,f),!0}else if(M===61){if((f=I(ao,a))>=0)return _(40,a,f),!0;if((f=I(Zf,a))>=0)return F(11),_(41,a,f),!0}else if(M===46&&(f=I(Ws,a))>=0)return _(40,a,f),!0;return b!==45&&b!==61&&b!==46&&L()},P=b=>{let M;switch(b){case 97:if(e.startsWith("acc",a)){if((M=I(Pf,a))>=0)return F(3),_(2,a,M),!0;if((M=I(Hf,a))>=0)return F(4),_(4,a,M),!0;if((M=I(Yf,a))>=0)return F(5),a=M,!0}break;case 64:if(e.charCodeAt(a+1)===123)return F(16),r.push(7),i.push(""),n.push(a),a+=2,!0;break;case 99:if((M=I(Gf,a))>=0)return F(14),a=M,!0;if(E("classDef"))return _(16,a,a+8),!0;if(E("class"))return _(17,a,a+5),!0;if((M=I(Bf,a))>=0)return F(13),a=M,!0;break;case 34:return C(),!0;case 115:if(E("style"))return _(12,a,a+5),!0;if(E("swimlane-beta"))return Z(13),!0;if(E("subgraph"))return _(21,a,a+8),!0;break;case 100:if(E("default"))return _(13,a,a+7),!0;break;case 108:if(E("linkStyle"))return _(14,a,a+9),!0;break;case 105:if(E("interpolate"))return _(15,a,a+11),!0;break;case 104:if(e.startsWith("href",a)&&Le(e.charCodeAt(a+4)))return _(18,a,a+5),!0;break;case 102:if(E("flowchart-elk"))return Z(13),!0;if(E("flowchart"))return Z(9),!0;break;case 103:if(E("graph"))return Z(5),!0;break;case 101:if(E("end")){for(M=a+3;M<t&&Le(e.charCodeAt(M));)M++;return _(22,a,M),!0}break;case 95:if(E("_self"))return _(23,a,a+5),!0;if(E("_blank"))return _(23,a,a+6),!0;if(E("_parent"))return _(23,a,a+7),!0;if(E("_top"))return _(23,a,a+4),!0;break}if(c!==-1&&a>=h&&(c<a&&(c=e.indexOf("direction",a)),c!==-1&&(u<a&&(Fs.lastIndex=a,u=Fs.test(e)?Fs.lastIndex-1:t),c<u))){for(let f=0;f<5;f++)if((M=I(Vf[f],a))>=0)return _(26+f,a,M),!0;h=u}if(p!==-1&&b!==34&&!Le(b)){if(a>=$){p<a&&(p=e.indexOf("@",a));let f=a;for(;f<t;){let x=e.charCodeAt(f);if(x===34||Le(x))break;f++}if($=f,g=-1,p!==-1&&p<f)for(let x=Math.min(f,t-1)-1;x>=p;x--){if(e.charCodeAt(x)!==64)continue;let A=e.charCodeAt(x+1);if(A!==123&&A!==34){g=x;break}}}if(g>a)return _(31,a,g+1),!0}if(b>=48&&b<=57){let f=a+1;for(;f<t;){let x=e.charCodeAt(f);if(x<48||x>57)break;f++}return _(32,a,f),!0}switch(b){case 35:return _(33,a,a+1),!0;case 58:return e.charCodeAt(a+1)===58&&e.charCodeAt(a+2)===58?_(34,a,a+3):_(35,a,a+1),!0;case 38:return _(36,a,a+1),!0;case 59:return _(37,a,a+1),!0;case 44:return _(38,a,a+1),!0;case 42:return _(39,a,a+1),!0;case 120:case 111:return R(b)||H();case 60:return R(b)||_(60,a,a+1),!0;case 45:return R(b)||H()||_(65,a,a+1),!0;case 61:return R(b);case 46:return R(b)||H();case 126:return L();case 40:return S(b);case 91:return e.charCodeAt(a+1)===124?(_(50,a,a+2),!0):S(b);case 124:case 123:return S(b);case 62:return F(7),_(51,a,a+1),!0;case 94:return _(61,a,a+1),!0;case 92:return e.charCodeAt(a+1)===124?(_(62,a,a+2),!0):H();case 118:return Pe(e.charCodeAt(a+1))?H():(_(63,a,a+1),!0)}return Le(b)?R(b)?!0:(M=I(Jf,a))>=0?(_(74,a,M),!0):(M=I(eu,a))>=0?(_(75,a,M),!0):!1:b<128?H():ti(b)?(_(66,a,a+1),!0):!1},w=(b,M,f,x)=>{if(b===34)return C(),!0;let A=m(a);if(A===f||A===x){let v=I(M,a);if(v>=0)return k(),_(40,a,v),!0}if(b===f&&(f!==45||e.charCodeAt(a+1)===45))return!1;let z=a+1;for(;z<t;){let v=e.charCodeAt(z);if(v===34)break;if(v===f){if(f!==45||e.charCodeAt(z+1)===45)break}else if(v===120||v===111||v===60||v===x||Le(v)){let G=m(z);if((G===f||G===x)&&I(M,z)>=0)break}z++}return _(42,a,z),!0};e:for(;;){if(a>=t){let f=-1;switch(s){case 0:f=76;break;case 3:f=3;break;case 4:f=5;break;case 5:f=6;break;case 13:f=19;break;case 14:f=8;break;case 15:f=9;break}f!==-1&&_(f,t,t);break}let b=e.charCodeAt(a),M=!0;switch(s){case 0:M=P(b);break;case 1:if(b===34)e.charCodeAt(a+1)===96?(F(2),a+=2):(k(),a++);else{let f=e.indexOf('"',a);_(11,a,f===-1?t:f)}break;case 2:if(b===96)e.charCodeAt(a+1)===34?(k(),a+=2):M=!1;else if(b===34)C();else{let f=a+1;for(;f<t;){let x=e.charCodeAt(f);if(x===96||x===34)break;f++}_(10,a,f)}break;case 3:case 4:{let f=e.indexOf(`
51`,a);f===-1&&(f=t);let x=s===3?3:5;k(),_(x,a,f);break}case 5:if(b===125)k(),a++;else{let f=e.indexOf("}",a);f===-1&&(f=t),_(6,a,f)}break;case 6:{let f;b===34?C():(f=I(Uf,a))>=0?(k(),_(24,a,f)):(f=I(qf,a))>=0||(f=I(jf,a))>=0||(f=I(Xf,a))>=0?(k(),_(25,a,f)):M=L()||S(b);break}case 7:{let f=e.charCodeAt(a+1);switch(b){case 34:C();break;case 40:case 91:case 123:S(b);break;case 93:k(),f===41?_(46,a,a+2):f===93?_(48,a,a+2):_(70,a,a+1);break;case 41:k(),f===93?_(52,a,a+2):f===41&&e.charCodeAt(a+2)===41?_(54,a,a+3):_(68,a,a+1);break;case 124:k(),_(67,a,a+1);break;case 125:k(),_(72,a,a+1);break;default:{if((b===126||Le(b))&&L())break;let x=a+1;for(;x<t;){let A=e.charCodeAt(x);if(A===91||A===93||A===40||A===41||A===123||A===125||A===124||A===34)break;x++}_(44,a,x)}}break}case 8:{let f=e.charCodeAt(a+1);if(b===34)C();else{if((b===126||Le(b))&&L())break;if((b===45||b===47||b===41)&&f===41)k(),_(43,a,a+2);else if(b===40||b===91||b===123)S(b);else if(b===41||b===93||b===125)M=!1;else{let x=a+1;for(;x<t;){let A=e.charCodeAt(x);if(A===34||A===40||A===41||A===91||A===93||A===123||A===125||(A===45||A===47)&&e.charCodeAt(x+1)===41||(A===126||Le(A))&&y(x)&&I(io,x)>=0)break;x++}_(44,a,x)}}break}case 9:{let f=e.charCodeAt(a+1);if(b===34){C();break}if((b===126||Le(b))&&L())break;switch(b){case 40:f===45||f===91||f===40&&e.charCodeAt(a+2)===40?S(b):f===93?(k(),_(56,a,a+2)):S(b);break;case 91:case 123:S(b);break;case 92:f===93?(k(),_(56,a,a+2)):_(44,a,a+1);break;case 47:f===93?(k(),_(57,a,a+2)):_(44,a,a+1);break;case 93:case 41:f===93?(k(),_(56,a,a+2)):M=!1;break;case 125:M=!1;break;default:{if((b===63||b===61)&&f===93){k(),_(56,a,a+2);break}let x=a+1;for(;x<t;){let A=e.charCodeAt(x);if(A===92||A===91||A===93||A===40||A===41||A===123||A===125||A===47)break;x++}_(44,a,x)}}break}case 10:M=w(b,ro,45,-1);break;case 11:M=w(b,ao,61,-1);break;case 12:M=w(b,Ws,46,45);break;case 13:if(b===34)C();else if(Le(b))k(),a++;else{let f=a+1;for(;f<t&&!Le(e.charCodeAt(f));)f++;_(19,a,f)}break;case 14:if(b===40){let f=I(tu,a);k(),f>=0?a=f:(F(15),a++)}else{let f=e.indexOf("(",a);f===-1&&(f=t),_(8,a,f)}break;case 15:if(b===41)k(),a++;else{let f=e.indexOf(")",a);f===-1&&(f=t),_(9,a,f)}break;case 16:if(b===34)F(17),_(7,a,a+1);else if(b===125)k(),a++;else if(b===94)M=!1;else{let f=a+1;for(;f<t;){let x=e.charCodeAt(f);if(x===125||x===94||x===34)break;f++}_(7,a,f)}break;case 17:if(b===34)k(),_(7,a,a+1);else{let f=e.indexOf('"',a);f===-1&&(f=t),r.push(7),i.push(e.slice(a,f).replace(ru,"<br/>")),n.push(a),a=f}break}if(!M)return r.push(1),i.push(""),n.push(a),{types:r,texts:i,starts:n};continue e}return r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n}}var yi=new Uint8Array(77);for(let e of[32,64,63,65,13,38,35,36,33,39,66])yi[e]=1;var Gs=new Uint8Array(77);for(let e of[32,66,64,25,63,65,38,35,36,33,39])Gs[e]=1;var Bs=new Uint8Array(77);for(let e of[32,64,75,65,36,66,35,39,33,12,14,16,17,19,20,25,21,22,63,61,41])Bs[e]=1;var Us=new Uint8Array(77);for(let e of[32,64,35,75,33,12])Us[e]=1;var so="'UNICODE_TEXT', 'TEXT', 'TAGSTART'",ka=[],iu=/}\s*\n/g;function su(e,t){let r=e.includes("}")?e.replace(iu,`}
52`):e,{types:i,texts:n,starts:l}=au(r),s=0,a,d=w=>{let b=i[s];throw b===1?Ve("flowchart",r,l[s],"",!0):Ve("flowchart",r,l[s],`Expecting ${w}, got '${to[b]}'`)},c=(w,b="")=>(i[s]!==w&&d(`'${to[w]}'${b?", "+b:""}`),n[s++]),p=()=>{let w=i[s];w!==74&&w!==37&&w!==76&&d("'SEMI', 'NEWLINE', 'EOF'"),s++},u=()=>{yi[i[s]]===0&&d("'NODE_STRING'");let w=n[s++];for(;yi[i[s]]===1;)w+=n[s++];return w},h=()=>{Gs[i[s]]===0&&d("'NODE_STRING'");let w=n[s++];for(;Gs[i[s]]===1;)w+=n[s++];return w},$=()=>{let w=i[s],b;if(w===11)b="string";else if(w===10)b="markdown";else if(w===44||w===60||w===51||w===66)b="text";else return d(`${so}, 'TAGEND', 'STR', 'MD_STR'`);let M=n[s++];for(;;){let f=i[s];if(f!==44&&f!==60&&f!==51&&f!==66)break;M+=n[s++]}return{text:M,type:b}},g=w=>{c(w,so)},T=()=>{let w=i[s],b;if(w===11)b="string";else if(w===10)b="markdown";else if(w===42||w===66)b="text";else return d("'EDGE_TEXT', 'STR', 'MD_STR'");let M=n[s++];for(;i[s]===42||i[s]===66;)M+=n[s++];return{text:M,type:b}},D=()=>{let w=i[s],b;if(w===11)b="text";else if(w===10)b="markdown";else if(Bs[w]===1)b="text";else return d("'NODE_STRING', 'STR', 'MD_STR'");let M=n[s++];for(;Bs[i[s]]===1;)M+=n[s++];return{text:M,type:b}},_=()=>{let w=n[s++];for(;i[s]===7;)w+=n[s++];return w},F=()=>{let w=u(),b;switch(i[s]){case 71:s++,b=$(),g(70),t.addVertex(w,b,"square");break;case 55:s++,b=$(),g(54),t.addVertex(w,b,"doublecircle");break;case 69:s++,i[s]===69?(s++,b=$(),g(68),c(68),t.addVertex(w,b,"circle")):(b=$(),g(68),t.addVertex(w,b,"round"));break;case 45:s++,b=$(),g(43),t.addVertex(w,b,"ellipse");break;case 47:s++,b=$(),g(46),t.addVertex(w,b,"stadium");break;case 49:s++,b=$(),g(48),t.addVertex(w,b,"subroutine");break;case 50:{s++;let M=c(64);c(35);let f=c(64);c(67),b=$(),g(70),t.addVertex(w,b,"rect",void 0,void 0,void 0,{[M]:f});break}case 53:s++,b=$(),g(52),t.addVertex(w,b,"cylinder");break;case 73:s++,i[s]===73?(s++,b=$(),g(72),c(72),t.addVertex(w,b,"hexagon")):(b=$(),g(72),t.addVertex(w,b,"diamond"));break;case 51:s++,b=$(),g(70),t.addVertex(w,b,"odd");break;case 58:s++,b=$(),i[s]===57?(s++,t.addVertex(w,b,"lean_right")):(g(56),t.addVertex(w,b,"trapezoid"));break;case 59:s++,b=$(),i[s]===56?(s++,t.addVertex(w,b,"lean_left")):(g(57),t.addVertex(w,b,"inv_trapezoid"));break;default:t.addVertex(w)}return w},k=()=>{let w=F();return i[s]===34&&(s++,t.setClass(w,u())),w},I=()=>{let w=[k()];for(a=void 0;;){let b=i[s]===7?_():void 0;if(i[s]!==75)return a=b,w;do s++;while(i[s]===75);if(i[s]!==36)return b!==void 0&&d("'AMP'"),w;s++,i[s]!==75&&d("'SPACE'");do s++;while(i[s]===75);let M=k();b!==void 0&&t.addVertex(w[w.length-1],void 0,void 0,void 0,void 0,void 0,void 0,b),w.push(M)}},E=()=>{let w;if(i[s]===31&&(w=n[s++]),i[s]===40){let b=t.destructLink(n[s++]);return w!==void 0&&(b.id=w),i[s]===67&&(s++,b.text=$(),g(67),i[s]===75&&s++),b}if(i[s]===41){let b=n[s++],M=T(),f=c(40,"'EDGE_TEXT'"),x=t.destructLink(f,b);return x.text=M,w!==void 0&&(x.id=w),x}return d("'LINK', 'START_LINK'")},m=()=>{let w=I();a!==void 0&&t.addVertex(w[w.length-1],void 0,void 0,void 0,void 0,void 0,void 0,a);let b=w;for(;;){let M=i[s];if(M!==40&&M!==41&&M!==31)return b;let f=E(),x=I();a!==void 0&&t.addVertex(x[x.length-1],void 0,void 0,void 0,void 0,void 0,void 0,a),t.addLink(w,x,f),b=x.concat(b),w=x}},y=()=>{Us[i[s]]===0&&d("'NODE_STRING', 'NUM', 'COLON', 'BRKT'");let w=n[s++];for(;Us[i[s]]===1;)w+=n[s++];return w},C=()=>{let w=[y()];for(;i[s]===38;)s++,w.push(y());return w},L=()=>{s++,c(75);let w;if(i[s]===13)w=[n[s++]];else for(w=[c(32,"'DEFAULT'")];i[s]===38;)s++,w.push(c(32));if(c(75),i[s]!==15){t.updateLink(w,C());return}s++,c(75);let b=h();if(i[s]===75){s++;let M=C();t.updateLinkInterpolate(w,b),t.updateLink(w,M)}else t.updateLinkInterpolate(w,b)},S=(w,b)=>{if(i[s]!==75){t.setLink(w,b);return}if(s++,i[s]===23){t.setLink(w,b,n[s++]);return}let M=c(11,"'LINK_TARGET'");i[s]===75?(s++,t.setLink(w,b,c(23))):t.setLink(w,b),t.setTooltip(w,M)},Z=()=>{let w=n[s++];switch(i[s]){case 8:{let b=n[s++],M=i[s]===9,f=M?n[s++]:void 0,x;i[s]===75&&(s++,x=c(11)),M?t.setClickEvent(w,b,f):t.setClickEvent(w,b),x!==void 0&&t.setTooltip(w,x);return}case 18:s++,S(w,c(11));return;case 11:S(w,n[s++]);return;default:{let b=h();if(i[s]===75){s++;let M=c(11);t.setClickEvent(w,b),t.setTooltip(w,M)}else t.setClickEvent(w,b)}}},H=()=>{s++;let w=i[s];if(w===74||w===37||w===76)return s++,{id:void 0,title:void 0,list:[],collect:!1};c(75,"'SEMI', 'NEWLINE', 'EOF'");let b=D(),M=b;return i[s]===71&&(s++,M=$(),g(70)),w=i[s],w!==74&&w!==37&&w!==76&&d("'SEMI', 'NEWLINE', 'EOF', 'SQS'"),s++,{id:b,title:M,list:[],collect:!1}},R=()=>{let w=i[s];switch(w){case 12:{s++,c(75);let b=u();return c(75),t.addVertex(b,void 0,void 0,C()),p(),ka}case 14:return L(),p(),ka;case 16:{s++,c(75);let b=u();return c(75),t.addClass(b,C()),p(),ka}case 17:{s++,c(75);let b=u();return c(75),t.setClass(b,u()),p(),ka}case 19:return Z(),p(),ka;case 26:case 27:case 28:case 29:case 30:return s++,{stmt:"dir",value:lu[w-26]};case 2:{s++;let b=c(3).trim();return t.setAccTitle(b),b}case 4:{s++;let b=c(5).trim();return t.setAccDescription(b),b}case 6:{let b=n[s++].trim();return t.setAccDescription(b),b}default:{yi[w]===0&&d(lo);let b=m();return p(),b}}},P=()=>{let w=[],b=[],M=!1;for(;;){let f=i[s];if(f===0)break;if(f===22){let x=w.pop();if(x===void 0)break;s++;let A=t.addSubGraph(x.id,b,x.title);b=x.list,M=x.collect,M&&b.push(A)}else if(f===37||f===74||f===75||f===76)M&&b.push(n[s]),s++;else if(f===21){let x=H();x.list=b,x.collect=M,w.push(x),b=[],M=!0}else{let x=R();M&&(!Array.isArray(x)||x.length>0)&&b.push(x)}}w.length>0&&d("'end'")};for(;i[s]===75||i[s]===74;)s++;if(c(20,"'SPACE', 'NEWLINE'"),i[s]===24)s++,t.setDirection("TB");else{let w=c(25,"'NODIR'"),b=i[s];if(b===75){do s++;while(i[s]===75);b=i[s],b!==74&&d("'NEWLINE', 'SPACE'")}else b!==37&&b!==74&&d("'SEMI', 'NEWLINE', 'SPACE'");s++,t.setDirection(w)}P(),i[s]!==0&&d(lo)}var lu=["TB","BT","RL","LR","TD"],lo="'SEMI', 'NEWLINE', 'SPACE', 'EOF', 'subgraph', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'STYLE', 'LINKSTYLE', 'CLASSDEF', 'CLASS', 'CLICK', 'NODE_STRING'";function nu(e){if(e.img)return"imageSquare";if(e.icon)return e.form==="circle"?"iconCircle":e.form==="square"?"iconSquare":e.form==="rounded"?"iconRounded":"icon";switch(e.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";default:return e.type}}function ou(e){switch(e){case"arrow_point":case"arrow_circle":case"arrow_cross":return["none",e];case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":{let t=e.replace("double_","");return[t,t]}}return["none","arrow_point"]}function cu(e,t){let r=[],i=[],n=e.subgraphs,l=k=>{let I=[];for(let E of k){let m=e.classes.get(E);m?.styles&&(I=[...I,...m.styles].map(y=>y.trim())),m?.textStyles&&(I=[...I,...m.textStyles].map(y=>y.trim()))}return I},s=new Map;for(let k of n)for(let I of k.nodes)e.subgraph(I)&&s.set(I,k.id);let a=new Map,d=new Map;for(let k of n){let I=s.get(k.id);if(I===void 0)continue;let E=d.get(I);E?E.push(k.id):d.set(I,[k.id])}let c=0;for(let k of n){if(s.has(k.id))continue;let I=[k.id];for(;I.length>0;){let E=I.pop();if(a.has(E))continue;a.set(E,c++);let m=d.get(E);if(m)for(let y=m.length-1;y>=0;y--)I.push(m[y])}}let p=k=>e.subgraph(k)?.metadata?.view==="collapsed",u=!1;for(let k of n)k.metadata?.view==="collapsed"&&(u=!0);let h=new Map,$=k=>{let I=[],E=new Set,m=k;for(;m!==void 0&&!h.has(m)&&!E.has(m);)E.add(m),I.push(m),m=s.get(m);let y=m!==void 0?h.get(m):void 0;for(let C=I.length-1;C>=0;C--)y===void 0&&p(I[C])&&(y=I[C]),h.set(I[C],y);return y},g=new Set,T=new Map;for(let k of u?n:[]){let I=$(k.id);if(I!==void 0){k.id!==I&&(g.add(k.id),T.set(k.id,I));for(let E of k.nodes)E!==I&&(g.add(E),T.set(E,I))}}let D=new Map,_=new Set;for(let k=n.length-1;k>=0;k--){let I=n[k];if(!g.has(I.id)){I.nodes.length>0&&_.add(I.id);for(let E of I.nodes)D.set(E,I.id)}}let F=new Map;for(let k=n.length-1;k>=0;k--){let I=n[k];if(g.has(I.id))continue;let E=I.metadata?.view==="collapsed",m={id:I.id,label:I.title,labelType:I.labelType,parentId:D.get(I.id),cssStyles:[],cssCompiledStyles:l(I.classes),cssClasses:I.classes.join(" "),shape:E?"collapsedGroup":"rect",dir:I.dir,isGroup:!E,colorIndex:a.get(I.id)};E||(m.metadata=I.metadata),r.push(m),F.set(I.id,m)}for(let k of e.nodes.values()){if(g.has(k.id))continue;let I=F.get(k.id);if(I){I.cssStyles=k.styles,I.cssCompiledStyles=l(k.classes),I.cssClasses=k.classes.join(" ");continue}let E=_.has(k.id),m={id:k.id,label:k.text,labelType:k.labelType,parentId:D.get(k.id),cssStyles:k.styles,cssCompiledStyles:l(["default","node",...k.classes]),cssClasses:"default "+k.classes.join(" "),dir:k.dir,link:k.link,linkTarget:k.linkTarget,tooltip:e.tooltips.get(k.id),icon:k.icon,pos:k.pos,img:k.img,assetWidth:k.assetWidth,assetHeight:k.assetHeight,constraint:k.constraint,isGroup:E,shape:E?"rect":nu(k)};r.push(m),F.set(k.id,m)}return e.edges.forEach((k,I)=>{let E=T.get(k.start)??k.start,m=T.get(k.end)??k.end;if(E===m&&(T.has(k.start)||T.has(k.end)))return;let[y,C]=ou(k.type),L=[...e.defaultEdgeStyle??[]];k.style&&L.push(...k.style);let S=k.stroke==="invisible"||k.type==="arrow_open";i.push({id:k.id||`L_${E}_${m}_${I}`,isUserDefinedId:k.isUserDefinedId,start:E,end:m,type:k.type??"normal",label:k.text,labelType:k.labelType,thickness:k.stroke,pattern:k.stroke,minlen:k.length,classes:k.stroke==="invisible"?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:S?"none":y,arrowTypeEnd:S?"none":C,cssCompiledStyles:l(k.classes),style:L,animate:k.animate,animation:k.animation,curve:k.interpolate||e.defaultInterpolate||t})}),{nodes:r,edges:i}}var du=40,hu=16,fu=48,no=20,Ps=26,Hs=' fill="var(--_s)" stroke="var(--_b)"',uu=' stroke="var(--_b)"';function Ys(e,t,r){let i=e[t];return typeof i=="number"&&i>0?Math.min(i,2e3):r}function va(e,t){return e!==void 0&&e>0&&e<=4e3?e:t}function pu(e,t,r,i){let n=l=>Vr(r,s=>gu(e,t,r,i,l,s));return dr(e.direction)?Ct(r,n):n(!1)}function gu(e,t,r,i,n,l){let s=l?12:no,a=i?t[i.type]:void 0,d=typeof a=="object"&&a!==null&&!Array.isArray(a)?a:t.flowchart??{},c=cu(e,typeof d.curve=="string"?d.curve:void 0);i?.prepare(c);let p=r.fontSize??16,u=Math.round(p*.875),h=r.measurer??tt(r.fontFamily),$=Math.min(Ys(d,"wrappingWidth",200),i&&l?100:1/0),g=r.padding??8,T=r.icons,D=new Map,_=[],F=[];c.nodes.forEach((V,Y)=>D.set(V.id,Y));for(let V of c.nodes){let Y=ct(V.cssStyles.length>0?V.cssCompiledStyles.concat(V.cssStyles):V.cssCompiledStyles),de=(Y.bold?1:0)|(Y.italic?2:0),te=V.labelType==="markdown",xe=Y.fontSize??p,me,ae;if(V.isGroup){let O=Fe(V.label,te,h,xe,i&&l?Math.max(80,Pt(r)/2):4e3,de);me={node:V,style:Y,label:O,shape:"group",w:0,h:0,dy:0,loops:0},ae=wt(0,0),ae.isGroup=!0,ae.dir=V.dir?Ft(V.dir):void 0,ae.padX=s,ae.padTop=O.height>0?O.height+16:no,ae.padBottom=s,ae.minW=O.width+2*s-12}else{let O=yn(V.shape),B=V.img||V.icon||Jn(O)?V.label:void 0,Q=Fe(B,te,h,xe,$,de),se,ie,re=0;if(V.img||V.icon){let ne=V.img?80:48,X=va(V.assetWidth,ne),j=va(V.assetHeight,ne);se=Math.max(X,Q.width+8),ie=j+(Q.height>0?Q.height+6:0),re=V.pos==="t"?-j/2:j/2,Q.height===0&&(re=0)}else{let ne=gi(O,Q.width,Q.height);se=ne.w,ie=ne.h,re=ne.dy}me={node:V,style:Y,label:Q,shape:O,w:se,h:ie,dy:re,loops:0},ae=wt(se,ie)}ae.seq=_.length,_.push(me),F.push(ae)}c.nodes.forEach((V,Y)=>{F[Y].parent=V.parentId!==void 0?D.get(V.parentId)??-1:-1});let k=n?"TB":Ft(e.direction),I=V=>{let Y;for(let de=F[V].parent,te=0;de>=0&&Y===void 0&&te<1e4;de=F[de].parent,te++)Y=F[de].dir;return Y??=k,Y==="LR"||Y==="RL"};_.forEach((V,Y)=>{V.node.isGroup?F[Y].span=1/0:!V.node.img&&!V.node.icon&&(F[Y].span=Qn(V.shape,V.w,V.h,I(Y)))});let E=[],m=[],y=[];for(let V of c.edges){let Y=D.get(V.start),de=D.get(V.end);if(Y===void 0||de===void 0)continue;let te=Fe(V.label,V.labelType==="markdown",h,u,$);Y===de&&(_[Y].loops++,I(Y)?F[Y].h+=2*(Ps+(te.height>0?te.height+8:0)):F[Y].w+=2*(Ps+(te.width>0?te.width+12:0))),y.push(V),m.push(te),E.push({src:Y,dst:de,minlen:V.minlen??1,labelW:te.width>0?te.width+12:0,labelH:te.height>0?te.height+4:0,route:[],labelX:0,labelY:0})}let C={nodeSep:Ys(d,"nodeSpacing",du)*(l?.5:1),edgeSep:hu,rankSep:Ys(d,"rankSpacing",fu)*(l?.75:1),portSep:20,tracks:typeof d.curve=="string"&&/^step/.test(d.curve),straight:d.curve==="linear",headRoom:Nt("arrow_point")},L=i?i.layout(F,E,k,C,l):or(F,E,k,C),S=Fe(e.title,!1,h,p,l?Pt(r):4e3,1),Z=S.height>0?S.height+12:0,H=Math.max(L.width,S.width),R=g+(H-L.width)/2,P=g+Z;di(F,E,R,P);let w=Math.ceil(H+2*g),b=Math.ceil(L.height+Z+2*g),M=[],f=new Map,x=!1;for(let V of F)V.isGroup&&(x=!0);if(x)for(let V of E)Yr(f,V.route);let A="",z="",v="";for(let V=0;V<_.length;V++){let Y=_[V],de=F[V],te=Y.node,xe=de.x,me=de.y,ae=Mt(te.cssClasses.replace(/^default\s?/,"")),O=Oe(te.id);if(de.isGroup&&i?.drawGroup&&de.parent<0){A+=i.drawGroup(de,Y.label,Y.style,ae,O,k,T);continue}if(de.isGroup){let ne=Gr(de,Y.label.width,f,s),X=me-de.h/2+8+Y.label.height/2,j=` class="pele-cluster-label" fill="var(--_m)"${Y.style.text}`,oe=ai(de,Y.label.width,ne,f);oe&&(z+=ii(Y.label,ne,X,j,O,F,V,T)),A+=`<g class="pele-cluster${ae}" data-id="${O}"><rect x="${o(xe-de.w/2)}" y="${o(me-de.h/2)}" width="${o(de.w)}" height="${o(de.h)}" rx="${Ke}" fill="var(--_a)" fill-opacity="0.5" stroke="var(--_b)"${Y.style.shape}/>`+(oe?"":Ne(Y.label,ne,X,j,T))+"</g>";continue}let B=Y.w,Q=Y.h,se;if(te.img){let ne=va(te.assetWidth,80),X=va(te.assetHeight,80),j=Y.label.height>0?te.pos==="t"?Q/2-X:-Q/2:-X/2,oe=jn(br(te.img),r);se=oe===void 0?"":`<image href="${Be(oe)}" x="${o(-ne/2)}" y="${o(j)}" width="${o(ne)}" height="${o(X)}" preserveAspectRatio="${te.constraint==="on"?"xMidYMid meet":"none"}"/>`}else if(te.icon){let ne=va(te.assetHeight,48),X=Y.label.height>0?te.pos==="t"?Q/2-ne:-Q/2:-ne/2,j=te.shape==="icon"?"":te.shape==="iconCircle"?`<circle cy="${o(X+ne/2)}" r="${o(ne/2)}"${Hs}${Y.style.shape}/>`:`<rect x="${o(-ne/2)}" y="${o(X)}" width="${o(ne)}" height="${o(ne)}" rx="${te.shape==="iconRounded"?8:0}"${Hs}${Y.style.shape}/>`,oe=ne*.6;se=j+`<svg class="pele-icon" data-icon="${Oe(te.icon)}" x="${o(-oe/2)}" y="${o(X+(ne-oe)/2)}" width="${o(oe)}" height="${o(oe)}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${T?.(te.icon)??""}</svg>`}else se=ba(Y.shape,B,Q,Hs+Y.style.shape,uu+Y.style.line);let ie=Ne(Y.label,0,Y.dy,` class="pele-label"${Y.style.text}`,T);if(/ internal-link(?: |$)/.test(ae+" ")&&te.label&&r.links!==!1){let ne=nt(te.label),X=ma(xr(ne),r)!==void 0,j=Be(ne);ie=`<a class="internal-link"${X?` href="${j}"${ya(r)}`:""} data-href="${j}">${ie}</a>`,M.push({id:te.id,href:ne,internal:!0})}let re=se+ie;te.tooltip&&(re=`<title>${Oe(te.tooltip)}</title>`+re),te.link&&(re=cr(re,te.link,te.id,M,r,te.linkTarget?` target="${Be(te.linkTarget)}"`:"")),v+=`<g class="pele-node pele-shape-${Y.shape}${ae}" data-id="${O}" transform="translate(${o(xe)},${o(me)})">${re}</g>`}let G=ci();for(let V=0;V<E.length;V++){let Y=E[V];Y.src===Y.dst||y[V].thickness==="invisible"||Y.route.length<6||(G.add(Y.src,Lt(Y.route,0,F[Y.src]),y[V].arrowTypeStart),G.add(Y.dst,Lt(Y.route,Y.route.length-3,F[Y.dst]),y[V].arrowTypeEnd))}let ee="",he="",ue=new Map;for(let V=0;V<E.length;V++){let Y=E[V],de=y[V],te=m[V],xe=de.style.length>0||de.cssCompiledStyles.length>0?ct(de.cssCompiledStyles.concat(de.style)):void 0;if(de.thickness!=="invisible"){let me=de.arrowTypeStart,ae=de.arrowTypeEnd,O;if(Y.src===Y.dst){let ie=_[Y.src],re=ue.get(Y.src)??0;ue.set(Y.src,re+1),O=Pn(F[Y.src],ie.w,ie.h,re,I(Y.src),Ps,Nt(ae),Y)}else{let ie=Y.route.slice(),re=G.of(Y.src,Lt(ie,0,F[Y.src])),ne=G.of(Y.dst,Lt(ie,ie.length-3,F[Y.dst]));Rs(ie,0,_[Y.src],F[Y.src]),Rs(ie,ie.length-3,_[Y.dst],F[Y.dst]),O=lr(ie,de.curve,Nt(me),Nt(ae),re,ne)}let B=xe?.stroke&&de.thickness!=="invisible"?Be(xe.stroke):"var(--_l)",Q="";de.thickness==="thick"?Q+=' stroke-width="2.5"':de.thickness==="dotted"&&(Q+=' stroke-dasharray="3 4"');let se=Mt(de.classes.replace(/edge-thickness-normal|edge-pattern-solid|flowchart-link/g,""));ee+=`<g class="pele-edge${se}" data-id="${Oe(de.id)}"${xe?.line??""}><path d="${O.d}"${Q}/>`+St(me,O.sx,O.sy,O.sdx,O.sdy,B)+St(ae,O.ex,O.ey,O.edx,O.edy,B)+"</g>"}if(te.width>0){let me=Y.labelX,ae=Y.labelY;he+=nr(de.id,te,me,ae,xe?.text??"",T)}}return{svg:Je(i?.type??"flowchart",w,b,p,r,e,Ne(S,w/2,g+S.height/2,' class="pele-title" font-weight="var(--_tw)"')+(A?`<g class="pele-clusters">${A}</g>`:"")+(ee?`<g class="pele-edges" fill="none" stroke="var(--_l)" stroke-linecap="round">${ee}</g>`:"")+(z?`<g class="pele-cluster-titles">${z}</g>`:"")+(he?`<g class="pele-edge-labels" font-size="${u}">${he}</g>`:"")+`<g class="pele-nodes">${v}</g>`),width:w,height:b,links:M}}var qs={type:"flowchart",parse(e,t,r,i,n){let l=t.flowchart??{},s=new Wf({inheritDir:l.inheritDir===!0,maxEdges:n.maxEdges});return r&&(s.title=r),su(e,s),s},render:pu};function co(e,t,r){if(e.width<=r)return e;let i=[],n=[];for(let s=0;s<e.lines.length;s++){if(e.widths[s]<=r){i.push(e.lines[s]),n.push(e.widths[s]);continue}let a=[],d=0,c=()=>{i.push(a),n.push(d),a=[],d=0};for(let p of e.lines[s]){if(p.icon!==void 0){a.length&&d+p.width>r&&c(),a.push(p),d+=p.width;continue}for(let u of Array.from(p.text)){let h=a[a.length-1],$=h&&h.icon===void 0&&h.style===p.style,g=t.width($?h.text+u:u,e.size,p.style)-($?h.width:0);a.length&&d+g>r&&(c(),h=void 0,g=t.width(u,e.size,p.style)),h&&h.icon===void 0&&h.style===p.style?(h.text+=u,h.width+=g):a.push({text:u,style:p.style,width:g}),d+=g}}(a.length||!e.lines[s].length)&&c()}let l=0;for(let s of n)l=Math.max(l,s);return{...e,lines:i,widths:n,width:l,height:i.length*e.lineHeight}}var mu="aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen transparent currentcolor inherit initial unset revert accentcolor accentcolortext activetext buttonborder buttonface buttontext canvas canvastext field fieldtext graytext highlight highlighttext linktext mark marktext selecteditem selecteditemtext visitedtext activeborder activecaption appworkspace background buttonhighlight buttonshadow captiontext inactiveborder inactivecaption inactivecaptiontext infobackground infotext menu menutext scrollbar threeddarkshadow threedface threedhighlight threedlightshadow threedshadow window windowframe windowtext",ho,yu=/^[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?(%|deg|grad|rad|turn)?$/i;function ko(e){if(e.toLowerCase()==="none")return 4;let t=yu.exec(e);return t?t[1]===void 0?1:t[1]==="%"?2:3:0}function $u(e,t){let r=ko(e);return r===1||r===2||t&&r===4}function wu(e){let t=e.startsWith("hsl"),r=e.indexOf("("),i=e.slice(0,r);if(i!=="rgb"&&i!=="rgba"&&i!=="hsl"&&i!=="hsla"||e.length>120||e.indexOf(")")!==e.length-1)return!1;let n=e.slice(r+1,-1).trim(),l,s,a=n.includes(",");if(a)l=n.split(",").map(c=>c.trim()),l.length===4&&(s=l.pop());else{let c=n.split("/");if(c.length>2)return!1;l=c[0].trim().split(/\s+/),c.length===2&&(s=c[1].trim())}if(l.length!==3||s!==void 0&&!$u(s,!a))return!1;let d=l.map(ko);if(a)return t?(d[0]===1||d[0]===3)&&d[1]===2&&d[2]===2:(d[0]===1||d[0]===2)&&d[1]===d[0]&&d[2]===d[0];for(let c=0;c<3;c++){let p=d[c];if(!(p===1||p===4||(t&&c===0?p===3:p===2)))return!1}return!0}function xu(e){return e.includes("(")?wu(e):(ho??=new Set(mu.split(" ")),ho.has(e.toLowerCase()))}var bu=/^:?wrap:/,ku=/^:?nowrap:/,vu=/^:?(?:no)?wrap:/,Mu=/^(?:rgba?|hsla?)\s*\(/,fo=/[\r\u2028\u2029]/,Au=/^\w*/;function Ma(e){throw new He(e,"semantic",{type:"sequence"})}function uo(e){let t=e.trim(),r=bu.test(t)?!0:ku.test(t)?!1:void 0;return{text:(r===void 0?t:t.replace(vu,"")).trim(),wrap:r}}function Tu(e){let t=Mu.exec(e);if(t){let i=e.lastIndexOf(")");if(i>=t[0].length)return fo.test(e.slice(t[0].length))?void 0:[e.slice(0,i+1),e.slice(i+1)]}if(fo.test(e))return;let r=Au.exec(e)[0];return[r,e.slice(r.length)]}function po(e){return typeof e=="string"?[...e].map((t,r)=>[String(r),t]):e!==null&&typeof e=="object"?Object.entries(e):[]}var Cu=class{type="sequence";actors=new Map;createdActors=new Map;destroyedActors=new Map;boxes=[];messages=[];notes=[];title;accTitle;accDescr;prevActor;currentBox;lastCreated;lastDestroyed;wrapEnabled;sequenceWrap;active=new Map;constructor(e={}){this.wrapEnabled=e.wrap,this.sequenceWrap=e.sequenceWrap??!1}autoWrap(){return this.wrapEnabled??this.sequenceWrap}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
53`)}setDiagramTitle(e){this.title=e}parseMessage(e){return uo(e)}parseBoxData(e){let t=Tu(e),r=t?.[0]?t[0].trim():"transparent",i=t?.[1]?t[1].trim():void 0;if(xu(r)||(r="transparent",i=e.trim()),i===void 0)return{text:void 0,color:r,wrap:void 0};let{text:n,wrap:l}=uo(i);return{text:n||void 0,color:r,wrap:l}}addBox(e){this.currentBox={name:e.text,wrap:e.wrap??this.autoWrap(),fill:e.color,actorKeys:[]},this.boxes.push(this.currentBox)}addActor(e,t,r,i,n){let l=this.currentBox,s;if(n!==void 0){let p;try{p=Wr(n.includes(`
54`)?n+`
55`:`{
56`+n+`
57}`)}catch(u){throw new He(`Config of participant "${e}" is not valid YAML. ${u.message}`,"syntax",{type:"sequence"})}p!==null&&typeof p=="object"&&!Array.isArray(p)&&(s=p)}let a=s&&Object.prototype.hasOwnProperty.call(s,"type")?s.type:void 0,d=s&&Object.prototype.hasOwnProperty.call(s,"alias")?s.alias:void 0;a!=null&&(i=String(a)),d&&(!r||r.text===t)&&(r={text:String(d),wrap:r?.wrap,type:i});let c=this.actors.get(e);if(!(c&&(this.currentBox&&c.box&&this.currentBox!==c.box&&Ma(`A same participant should only be defined in one Box: ${c.name} can't be in '${c.box.name}' and in '${this.currentBox.name}' at the same time.`),l=c.box?c.box:this.currentBox,c.box=l,t===c.name&&r==null))){if((r?.text==null||i==null)&&(r={text:t,type:i}),this.actors.set(e,{box:l,name:t,description:r.text,wrap:r.wrap??this.autoWrap(),prevActor:this.prevActor,links:new Map,properties:new Map,type:i??"participant"}),this.prevActor){let p=this.actors.get(this.prevActor);p&&(p.nextActor=e)}this.currentBox&&this.currentBox.actorKeys.push(e),this.prevActor=e}}addMessage(e,t,r,i){this.messages.push({id:String(this.messages.length),from:e,to:t,message:r.text,wrap:r.wrap??this.autoWrap(),answer:i})}addSignal(e,t,r,i,n=!1,l){if(i===18){let s=e?this.active.get(e)??0:0;s<1&&Ma(`Trying to inactivate an inactive participant (${e})`),this.active.set(e,s-1)}else i===17&&e&&this.active.set(e,(this.active.get(e)??0)+1);return this.messages.push({id:String(this.messages.length),from:e,to:t,message:r?.text??"",wrap:r?.wrap??this.autoWrap(),type:i,activate:n,centralConnection:l??0}),!0}addNote(e,t,r){let i=r.wrap??this.autoWrap(),n={actor:e,placement:t,message:r.text,wrap:i},l=typeof e=="string"?[e,e]:e;this.notes.push(n),this.messages.push({id:String(this.messages.length),from:l[0],to:l[1],message:r.text,wrap:i,type:2,placement:t})}addLinks(e,t){let r=this.actors.get(e);if(r)try{let i=JSON.parse(t.text);for(let[n,l]of po(i))r.links.set(n,l)}catch{return}}addALink(e,t){let r=this.actors.get(e);if(!r)return;let i=t.text.indexOf("@");r.links.set(t.text.slice(0,i-1).trim(),t.text.slice(i+1).trim())}addProperties(e,t){let r=this.actors.get(e);if(r)try{let i=JSON.parse(t.text);for(let[n,l]of po(i))r.properties.set(n,l)}catch{return}}addDetails(e,t){let r=this.actors.get(e);r&&(r.details=t.text)}apply(e){let t=[],r=[],i=e;for(;;){i!==void 0&&(Array.isArray(i)?(t.push(i),r.push(0)):typeof i!="string"&&this.applyOne(i));let n=t.length-1;if(n<0)return;let l=t[n];r[n]<l.length?i=l[r[n]++]:(t.pop(),r.pop(),i=void 0)}}applyOne(e){let t=e.actor;switch(e.type){case"sequenceIndex":this.messages.push({id:String(this.messages.length),from:void 0,to:void 0,message:{start:e.sequenceIndex,step:e.sequenceIndexStep,visible:e.sequenceVisible===!0},wrap:!1,type:e.signalType});break;case"addParticipant":this.addActor(t,t,e.description,e.draw,e.config);break;case"createParticipant":this.actors.has(t)&&Ma("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior"),this.lastCreated=t,this.addActor(t,t,e.description,e.draw,e.config),this.createdActors.set(t,this.messages.length);break;case"destroyParticipant":this.lastDestroyed=t,this.destroyedActors.set(t,this.messages.length);break;case"activeStart":case"activeEnd":case"centralConnection":case"centralConnectionReverse":this.addSignal(t,void 0,void 0,e.signalType);break;case"addNote":this.addNote(e.actor,e.placement,e.text);break;case"addLinks":this.addLinks(t,e.text);break;case"addALink":this.addALink(t,e.text);break;case"addProperties":this.addProperties(t,e.text);break;case"addDetails":this.addDetails(t,e.text);break;case"addMessage":this.lastCreated?(e.to!==this.lastCreated&&Ma(`The created participant ${this.lastCreated} does not have an associated creating message after its declaration. Please check the sequence diagram.`),this.lastCreated=void 0):this.lastDestroyed&&(e.to!==this.lastDestroyed&&e.from!==this.lastDestroyed&&Ma(`The destroyed participant ${this.lastDestroyed} does not have an associated destroying message after its declaration. Please check the sequence diagram.`),this.lastDestroyed=void 0),this.addSignal(e.from,e.to,e.msg,e.signalType,e.activate,e.centralConnection);break;case"boxStart":this.addBox(e.boxData);break;case"boxEnd":this.currentBox=void 0;break;case"loopStart":this.addSignal(void 0,void 0,e.loopText,e.signalType);break;case"rectStart":this.addSignal(void 0,void 0,e.color,e.signalType);break;case"optStart":this.addSignal(void 0,void 0,e.optText,e.signalType);break;case"altStart":case"else":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"parStart":case"and":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"criticalStart":this.addSignal(void 0,void 0,e.criticalText,e.signalType);break;case"option":this.addSignal(void 0,void 0,e.optionText,e.signalType);break;case"breakStart":this.addSignal(void 0,void 0,e.breakText,e.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break}}},go=["$end","INVALID","INVALID","NEWLINE","SD","create","box","restOfLine","end","autonumber","NUM","off","activate","deactivate","title","legacy_title","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","loop","rect","opt","alt","par","par_over","critical","break","option","and","else","participant","AS","participant_actor","destroy","note","over","links","link","properties","details",",","left_of","right_of","+","-","()","ACTOR","CONFIG_START","CONFIG_CONTENT","CONFIG_END","TXT","SOLID_OPEN_ARROW","DOTTED_OPEN_ARROW","SOLID_ARROW","BIDIRECTIONAL_SOLID_ARROW","DOTTED_ARROW","BIDIRECTIONAL_DOTTED_ARROW","SOLID_CROSS","DOTTED_CROSS","SOLID_POINT","DOTTED_POINT","SOLID_ARROW_TOP","SOLID_ARROW_BOTTOM","STICK_ARROW_TOP","STICK_ARROW_BOTTOM","SOLID_ARROW_TOP_DOTTED","SOLID_ARROW_BOTTOM_DOTTED","STICK_ARROW_TOP_DOTTED","STICK_ARROW_BOTTOM_DOTTED","SOLID_ARROW_TOP_REVERSE","SOLID_ARROW_BOTTOM_REVERSE","STICK_ARROW_TOP_REVERSE","STICK_ARROW_BOTTOM_REVERSE","SOLID_ARROW_TOP_REVERSE_DOTTED","SOLID_ARROW_BOTTOM_REVERSE_DOTTED","STICK_ARROW_TOP_REVERSE_DOTTED","STICK_ARROW_BOTTOM_REVERSE_DOTTED"],vo=new Uint8Array(128);for(let e=0;e<128;e++){let t=String.fromCharCode(e),r=e===32||e>=9&&e<=13,i=0;`/\\+()<->:
58,;`.includes(t)||(i|=1),`+<->:
59,;`.includes(t)||(i|=2),`<>:
60,;@`.includes(t)||(i|=8|(r?0:4)),`#
61;`.includes(t)||(i|=16),!`/\\+()<>:
62,;-`.includes(t)&&!r&&(i|=32),vo[e]=i}function Eu(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=-1,c=(f,x,A)=>{r.push(f),i.push(e.slice(x,A)),n.push(x),a=A},p=(f,x,A,z)=>{r.push(f),i.push(z),n.push(x),a=A},u=f=>{l.push(s),s=f},h=()=>{l.length>0&&(s=l.pop())},$=f=>(d<f&&(d=e.indexOf(`
63`,f),d===-1&&(d=t)),d),g=(f,x)=>{let A=e.charCodeAt(f);return A<128?(vo[A]&x)!==0:x===4||x===32?!Le(A):!0},T=(f,x)=>{for(let A=0;A<x.length;A++){let z=x.charCodeAt(A),v=e.charCodeAt(f+A);if(z>=97&&z<=122?(v|32)!==z:v!==z)return!1}return!0},D=f=>T(a,f)&&!Pe(e.charCodeAt(a+f.length)),_=f=>{for(;f<t&&Le(e.charCodeAt(f));)f++;return f},F=()=>{let f=a;for(;f<t;){let x=e.charCodeAt(f);if(x===10||!Le(x))break;f++}return f===a?!1:(a=f,!0)},k=f=>{for(;f<t&&g(f,16);)f++;return f},I=(f,x,A)=>{c(f,a,a+x),u(A)},E=(f,x,A=-1)=>D(f)?(c(x,a,a+f.length),A>=0&&u(A),!0):!1,m=(f,x)=>{if(!T(a,f))return!1;let A=a+f.length,z=e.charCodeAt(A);if(z!==32&&z!==9)return!1;for(;z===32||z===9;)z=e.charCodeAt(++A);return A>=t||!g(A,32)?!1:(c(x,a,a+f.length),!0)},y=f=>{let x=e.charCodeAt(f),A=e.charCodeAt(f+1);if(x===45){if(A===120||A===88||A===41||A===92||A===47||A===45)return!0;let z=e.charCodeAt(f+2);return A===124&&(z===92||z===47)}return x===47||x===92?(A===124||A===x)&&e.charCodeAt(f+2)===45:x===40&&A===41},C=()=>{let f=a+1;for(;f<t&&g(f,1);)f++;for(;f<t&&!y(f);){let x=f;for(;e.charCodeAt(x)===45;)x++;if(x>=t||!g(x,2))break;for(x++;x<t&&g(x,2);)x++;f=x}p(48,a,f,e.slice(a,f).trim())},L=()=>{let f=a;for(;ot(e.charCodeAt(f));)f++;let x=f>a;if(e.charCodeAt(f)===46&&ot(e.charCodeAt(f+1))){let z=ot(e.charCodeAt(f+2))?f+3:f+2,v=e.charCodeAt(z);if(v===32||v===10)return c(10,a,z),!0}let A=e.charCodeAt(f);return x&&(A===32||A===10)?(c(10,a,f),!0):!1},S=()=>{let f=e.charCodeAt(a+1),x=e.charCodeAt(a+2);if(f===62)c(x===62?55:53,a,a+(x===62?3:2));else if(f===120||f===88)c(59,a,a+2);else if(f===41)c(61,a,a+2);else if(f===124&&x===92)c(63,a,a+3);else if(f===124&&x===47)c(64,a,a+3);else if(f===92&&x===92)c(65,a,a+3);else if(f===47&&x===47)c(66,a,a+3);else if(f===45){let A=e.charCodeAt(a+3);x===62?c(A===62?57:54,a,a+(A===62?4:3)):x===120||x===88?c(60,a,a+3):x===41?c(62,a,a+3):x===124&&A===92?c(67,a,a+4):x===124&&A===47?c(68,a,a+4):x===92&&A===92?c(69,a,a+4):x===47&&A===47?c(70,a,a+4):c(46,a,a+1)}else c(46,a,a+1)},Z=f=>{let x=e.charCodeAt(a+1);if(x!==124&&x!==f||e.charCodeAt(a+2)!==45)return!1;let A=e.charCodeAt(a+3)===45,z=f===47,v;return x===124?A?v=z?75:76:v=z?71:72:A?v=z?77:78:v=z?73:74,c(v,a,a+(A?4:3)),!0},H=()=>{if(!T(a,"title"))return!1;let f=a+5,x=e.charCodeAt(f)===58;return x&&f++,!Le(e.charCodeAt(f))||f+1>=t||!g(f+1,16)?!1:(c(x?15:14,a,k(f+1)),!0)},R=()=>{let f=T(a,"accdescr");if(!f&&!T(a,"acctitle"))return!1;let x=_(a+8),A=e.charCodeAt(x);return A===58?(c(f?18:16,a,_(x+1)),u(f?6:5),!0):f&&A===123?(a=_(x+1),u(7),!0):!1},P=f=>{switch(f|32){case 97:return E("actor",34,1)||E("alt",24,3)||E("and",30,3)||E("activate",12,1)||R()||E("autonumber",9);case 98:return E("box",6,3)||E("break",28,3);case 99:return E("create",5)||E("critical",27,3);case 100:return E("destroy",35,1)||m("details",41)||E("deactivate",13,1);case 101:return E("else",31,3)||E("end",8);case 108:return E("loop",21,3)||E("left of",43)||m("links",38)||m("link",39);case 110:return E("note",36);case 111:return E("opt",23,3)||E("option",29,3)||E("over",37)||E("off",11);case 112:return E("participant",32,1)||E("par",25,3)||E("par_over",26,3)||m("properties",40);case 114:return E("rect",22,3)||E("right of",44);case 115:return E("sequencediagram",4);case 116:return H();default:return!1}},w=()=>{let f=e.charCodeAt(a);if(f===10){let x=a+1;for(;e.charCodeAt(x)===10;)x++;c(3,a,x);return}if(Le(f)){a=_(a+1);return}if(f===35||f===37&&e.charCodeAt(a+1)!==123){a=$(a);return}if(f!==125&&e.charCodeAt(a+1)===37&&e.charCodeAt(a+2)===37){a=$(a);return}if(!((ot(f)||f===46)&&L())&&!(f<128&&(f|32)>=97&&(f|32)<=122&&P(f)))if(f===44)c(42,a,a+1);else if(f===59)c(3,a,a+1);else if(g(a,1))C();else if(f===45)S();else if(f===60&&e.startsWith("<<->>",a))c(56,a,a+5);else if(f===60&&e.startsWith("<<-->>",a))c(58,a,a+6);else{if((f===47||f===92)&&Z(f))return;f===58?c(52,a,k(a+1)):f===43?c(45,a,a+1):f===40&&e.charCodeAt(a+1)===41?c(47,a,a+2):c(2,a,a+1)}},b=()=>{if(F())return!0;let f=e.charCodeAt(a);if(f===35)return a=$(a),!0;if(f===64&&e.charCodeAt(a+1)===123)return I(49,2,4),!0;let x=a;for(;x<t&&g(x,4);)x++;if(x>a){let z=_(x);if(e.charCodeAt(z)===64&&e.charCodeAt(z+1)===123)return c(48,a,x),!0;if(z>x&&T(z,"as")&&Le(e.charCodeAt(z+2)))return c(48,a,x),u(2),!0}let A=x;for(;A<t&&g(A,8);)A++;if(A>a){let z=e.charCodeAt(A),v=A;if(A<t&&z!==10&&z!==59)for(v--;v>a&&e.charCodeAt(v)!==35;)v--;if(v>a)return p(48,a,v,e.slice(a,v).trim()),h(),!0}if(e.charCodeAt(A)===60)return c(2,a,$(a)),h(),!0;if(f!==10){let z=$(a);return p(2,a,z,e.slice(a,z).trim()),h(),!0}return!1},M=()=>{switch(s){case 0:return w(),!0;case 1:return b();case 2:return F()?!0:e.charCodeAt(a)===35?(a=$(a),!0):(h(),h(),D("as")?I(33,2,3):c(3,a,a),!0);case 3:return F()?!0:e.charCodeAt(a)===35?(a=$(a),!0):(c(7,a,k(a)),h(),!0);case 4:if(e.charCodeAt(a)!==125){let f=e.indexOf("}",a);return f===-1&&(f=t),c(50,a,f),!0}else{let f=_(a+1),x=f>a+1&&T(f,"as")&&Le(e.charCodeAt(f+2));return c(51,a,a+1),h(),x?u(2):h(),!0}case 5:case 6:return c(s===5?17:19,a,$(a)),h(),!0;default:if(e.charCodeAt(a)===125)a++,h();else{let f=e.indexOf("}",a);f===-1&&(f=t),c(20,a,f)}return!0}};for(;a<t;)if(!M())return r.push(1),i.push(""),n.push(a),{types:r,texts:i,starts:n};return s===0||s===2?c(3,t,t):s===3?c(7,t,t):s===5?c(17,t,t):s===6?c(19,t,t):s===7&&c(20,t,t),r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n}}var et=new Int8Array(79).fill(-1);et[53]=5;et[54]=6;et[55]=0;et[57]=1;et[56]=33;et[58]=34;et[59]=3;et[60]=4;et[61]=24;et[62]=25;et[63]=41;et[64]=42;et[65]=43;et[66]=44;et[67]=51;et[68]=52;et[69]=53;et[70]=54;et[71]=45;et[72]=46;et[73]=47;et[74]=48;et[75]=55;et[76]=56;et[77]=57;et[78]=58;var qt=new Int8Array(79).fill(-1);qt[21]=2;qt[22]=3;qt[23]=4;qt[28]=5;qt[24]=6;qt[25]=7;qt[26]=7;qt[27]=8;qt[6]=1;var Su="'SOLID_OPEN_ARROW', 'DOTTED_OPEN_ARROW', 'SOLID_ARROW', 'DOTTED_ARROW', 'SOLID_CROSS', 'DOTTED_CROSS', 'SOLID_POINT', 'DOTTED_POINT'";function _u(e,t){let{types:r,texts:i,starts:n}=Eu(e),l=0,s=k=>{let I=r[l];throw I===1?Ve("sequence",e,n[l],"",!0):Ve("sequence",e,n[l],`Expecting ${k}, got '${go[I]}'`)},a=k=>(r[l]!==k&&s(`'${go[k]}'`),i[l++]),d=()=>{let k=r[l];return k!==48&&k!==39&&s("'ACTOR'"),{type:"addParticipant",actor:i[l++]}},c=()=>t.parseMessage(a(52).trim().substring(1)),p=()=>{let k=r[l++];if(k===35){let E=d();return a(3),E.type="destroyParticipant",E}let I=d();if(r[l]===49&&r[l-1]===48){l++;let E=a(50);a(51),I.config=E.trim()}if(I.draw=k===32?"participant":"actor",r[l]===33){l++;let E=a(7);a(3),I.description=t.parseMessage(E)}else r[l]===3?l++:s("'AS', 'NEWLINE'");return I},u=k=>{let I=!1;r[l]===47&&(I=!0,l++);let E=et[r[l]];E<0&&s(Su),l++;let m=r[l];(m===47||!I&&(m===45||m===46))&&l++;let y=d(),C=c(),L={type:"addMessage",from:k.actor,to:y.actor,signalType:E,msg:C},S=[k,y,L];if(I){let Z=m===47;L.activate=Z,L.centralConnection=Z?61:60,Z&&S.push({type:"centralConnection",signalType:59,actor:y.actor}),S.push({type:"centralConnectionReverse",signalType:60,actor:k.actor})}else m===45?(L.activate=!0,S.push({type:"activeStart",signalType:17,actor:y.actor})):m===46?S.push({type:"activeEnd",signalType:18,actor:k.actor}):m===47&&(L.activate=!0,L.centralConnection=59,S.push({type:"centralConnection",signalType:59,actor:y.actor}));return S},h=k=>{l++;let I=d();return[I,{type:k,actor:I.actor,text:c()}]},$=()=>{l++;let k=r[l];if(k===37){l++;let m=d(),y=m,C=[m.actor,m.actor];if(r[l]===42){l++;let L=d();y=[m,L],C=[m.actor,L.actor]}return[y,{type:"addNote",placement:2,actor:C,text:c()}]}k!==43&&k!==44&&s("'over', 'left_of', 'right_of'"),l++;let I=d();return[I,{type:"addNote",placement:k===43?0:1,actor:I.actor,text:c()}]},g=()=>{l++;let k={type:"sequenceIndex",sequenceVisible:!0,signalType:26};return r[l]===10?(k.sequenceIndex=Number(i[l++]),k.sequenceIndexStep=r[l]===10?Number(i[l++]):1):r[l]===11&&(l++,k.sequenceVisible=!1),r[l]!==3&&s("'NEWLINE', 'NUM', 'off'"),l++,k},T=(k,I,E,m)=>{let y=k.list,C=k.sections;if(C)for(let L=C.length-2;L>=0;L-=2){let S={type:I,signalType:m};S[E]=t.parseMessage(C[L+1]),y=C[L].concat([S,y])}return y},D=k=>{let I=k.text,E=k.list;switch(k.kind){case 1:E[0]={type:"boxStart",boxData:t.parseBoxData(I)},E.push({type:"boxEnd",boxText:I});break;case 2:E[0]={type:"loopStart",loopText:t.parseMessage(I),signalType:10},E.push({type:"loopEnd",loopText:I,signalType:11});break;case 3:E[0]={type:"rectStart",color:t.parseMessage(I),signalType:22},E.push({type:"rectEnd",color:t.parseMessage(I),signalType:23});break;case 4:E[0]={type:"optStart",optText:t.parseMessage(I),signalType:15},E.push({type:"optEnd",optText:t.parseMessage(I),signalType:16});break;case 5:E[0]={type:"breakStart",breakText:t.parseMessage(I),signalType:30},E.push({type:"breakEnd",optText:t.parseMessage(I),signalType:31});break;case 6:E=T(k,"else","altText",13),E[0]={type:"altStart",altText:t.parseMessage(I),signalType:12},E.push({type:"altEnd",signalType:14});break;case 7:E=T(k,"and","parText",20),E[0]={type:"parStart",parText:t.parseMessage(I),signalType:k.startType},E.push({type:"parEnd",signalType:21});break;default:E=T(k,"option","optionText",28),E[0]={type:"criticalStart",criticalText:t.parseMessage(I),signalType:27},E.push({type:"criticalEnd",signalType:29})}return E};for(;r[l]===3;)l++;a(4);let _=[],F={kind:0,text:"",startType:0,list:[],sections:void 0};for(;;){let k=r[l],I=F.list;if(F.kind===1){if(k===32||k===34||k===35)I.push(p());else if(k===3)I.push([]),l++;else if(k===8){l++;let E=D(F);F=_.pop(),F.list.push(E)}else s("'end', 'NEWLINE', 'participant', 'participant_actor', 'destroy'");continue}switch(k){case 3:case 2:I.push([]),l++;break;case 32:case 34:case 35:I.push(p());break;case 5:{l++;let E=r[l];E!==32&&E!==34&&E!==35&&s("'participant', 'participant_actor', 'destroy'");let m=p();m.type="createParticipant",I.push(m);break}case 48:I.push(u(d())),a(3);break;case 39:{let E=r[l+1];I.push(E===48||E===39?h("addALink"):u(d())),a(3);break}case 38:I.push(h("addLinks")),a(3);break;case 40:I.push(h("addProperties")),a(3);break;case 41:I.push(h("addDetails")),a(3);break;case 36:I.push($()),a(3);break;case 9:I.push(g());break;case 12:case 13:{l++;let E=d();a(3),I.push(k===12?{type:"activeStart",signalType:17,actor:E.actor}:{type:"activeEnd",signalType:18,actor:E.actor});break}case 14:case 15:{let E=i[l++].substring(k===14?6:7);t.setDiagramTitle(E),I.push(E);break}case 16:{l++;let E=a(17).trim();t.setAccTitle(E),I.push(E);break}case 18:{l++;let E=a(19).trim();t.setAccDescription(E),I.push(E);break}case 20:{let E=i[l++].trim();t.setAccDescription(E),I.push(E);break}case 21:case 22:case 23:case 28:case 24:case 25:case 26:case 27:case 6:{l++;let E=a(7);_.push(F),F={kind:qt[k],text:E,startType:k===26?32:19,list:[[]],sections:void 0};break}case 31:case 30:case 29:{F.kind!==(k===31?6:k===30?7:8)&&s("'end'"),l++;let E=a(7);(F.sections??=[]).push(I,E),F.list=[];break}case 8:{F.kind===0&&s("'NEWLINE', 'EOF'"),l++;let E=D(F);F=_.pop(),F.list.push(E);break}case 0:F.kind!==0&&s("'end'"),t.apply(I);return;default:s("'NEWLINE', 'ACTOR', 'participant', 'note', 'end'")}}}var Du=16,Iu=10,Mo=34,Ao=4,Cr=5,Tr=6,Kt=' fill="var(--_s)" stroke="var(--_b)"',Qr=' fill="none" stroke="var(--_b)"',Nu=new Set(["participant","actor","boundary","control","entity","database","collections","queue"]),Lu=new Set(["actor","boundary","control","entity","database"]);function Ou(e){return Nu.has(e)?e:"participant"}function Vs(e){return Lu.has(e)}function Ru(e,t,r,i,n=Du){if(Vs(e))return{w:Math.max(40,t.width+8),h:Mo+(t.height>0?Ao+t.height:0)};let l=e==="collections"?Cr:e==="queue"?2*Tr:0;return{w:Math.max(r,t.width+2*n)+l,h:Math.max(i,t.height+2*Iu)+(e==="collections"?Cr:0)}}function zu(e,t,r){let i=o(t),n=l=>o(r+l);switch(e){case"actor":return`<circle cx="${i}" cy="${n(7)}" r="6"${Kt}/><path d="M${i},${n(13)}V${n(24)}M${o(t-10)},${n(17)}H${o(t+10)}M${o(t-8)},${n(34)}L${i},${n(24)}L${o(t+8)},${n(34)}"${Qr}/>`;case"boundary":return`<path d="M${o(t-19)},${n(6)}V${n(28)}M${o(t-19)},${n(17)}H${o(t-8)}"${Qr}/><circle cx="${o(t+3)}" cy="${n(17)}" r="11"${Kt}/>`;case"control":return`<circle cx="${i}" cy="${n(21)}" r="11"${Kt}/><path d="M${o(t+5)},${n(5)}L${o(t-1)},${n(10)}L${o(t+5)},${n(15)}"${Qr}/>`;case"entity":return`<circle cx="${i}" cy="${n(15)}" r="11"${Kt}/><path d="M${o(t-11)},${n(30)}H${o(t+11)}"${Qr}/>`;default:{let l=o(t-14),s=o(t+14);return`<path d="M${l},${n(7)}V${n(27)}A14,5 0 0 0 ${s},${n(27)}V${n(7)}A14,5 0 0 0 ${l},${n(7)}Z"${Kt}/><path d="M${l},${n(7)}A14,5 0 0 0 ${s},${n(7)}"${Qr}/>`}}}function Fu(e,t,r,i,n,l){let{w:s,h:a}=i,d=' class="pele-label"';if(Vs(e))return zu(e,t,r)+Ne(n,t,r+Mo+Ao+n.height/2,d,l);let c=t-s/2;if(e==="collections"){let p=s-Cr,u=a-Cr,h=`<rect x="${o(c+Cr)}" y="${o(r)}" width="${o(p)}" height="${o(u)}" rx="${Ke}"${Kt}/>`,$=`<rect x="${o(c)}" y="${o(r+Cr)}" width="${o(p)}" height="${o(u)}" rx="${Ke}"${Kt}/>`;return h+$+Ne(n,c+p/2,r+Cr+u/2,d,l)}if(e==="queue"){let p=o(c+Tr),u=o(c+s-Tr),h=o(r+a),$=o(a/2);return`<path d="M${p},${o(r)}H${u}A${Tr},${$} 0 0 1 ${u},${h}H${p}A${Tr},${$} 0 0 1 ${p},${o(r)}Z"${Kt}/><path d="M${u},${o(r)}A${Tr},${$} 0 0 0 ${u},${h}"${Qr}/>`+Ne(n,t-Tr/2,r+a/2,d,l)}return`<rect x="${o(c)}" y="${o(r)}" width="${o(s)}" height="${o(a)}" rx="${Ke}"${Kt}/>`+Ne(n,t,r+a/2,d,l)}var Ks=[];function gt(e,t,r,i=1,n=!1){Ks[e]={dotted:t,head:r,atStart:i!==1,atEnd:i!==0,bottom:n}}gt(0,!1,1);gt(1,!0,1);gt(3,!1,2);gt(4,!0,2);gt(5,!1,0);gt(6,!0,0);gt(24,!1,3);gt(25,!0,3);gt(33,!1,1,2);gt(34,!0,1,2);for(let e of[!1,!0]){let t=e?10:0;gt(41+t,e,4),gt(42+t,e,4,1,!0),gt(43+t,e,5),gt(44+t,e,5,1,!0),gt(45+t,e,4,0),gt(46+t,e,4,0,!0),gt(47+t,e,5,0),gt(48+t,e,5,0,!0)}var Wu=new Map([[10,"loop"],[12,"alt"],[15,"opt"],[19,"par"],[32,"par"],[27,"critical"],[30,"break"],[22,"rect"]]),Pu=12,js=28,mo=22,Ht=10,yo=4,Hu=14,Kr=10,Yu=16,Gu=20,Bu=10,$i=20,$o=240,wi=16,Zr=4,wo=' stroke-dasharray="4 4"';function Xs(e){return e!==void 0&&Ks[e]!==void 0}function Uu(e,t){let r=new Array(e.length),i=new Array(e.length),n=1,l=1,s=!1;for(let a=0;a<e.length;a++){let d=e[a];if(r[a]=NaN,i[a]=!1,d.type===26){let c=d.message;n=c.start||n,l=c.step||l,s=c.visible}else Xs(d.type)&&(r[a]=n,i[a]=s||t,n=Math.round((n+l)*100)/100)}return{index:r,shown:i,visible:s}}var xo={lines:[],widths:[],width:0,height:0,size:0,lineHeight:0};function Ar(e,t,r){let i=e[t];return typeof i=="number"&&i>=0&&i<=2e3?i:r}function bo(e,t,r,i,n){let l=o(e-r*At);return n?`<path class="pele-marker" d="M${o(e)},${o(t)}L${l},${o(t+i*5)}"/>`:`<path class="pele-marker" d="M${o(e)},${o(t)}L${l},${o(t+i*4.5)}V${o(t)}Z" fill="var(--_l)" stroke="none"/>`}function xi(e,t,r,i,n){switch(e){case 1:return St("arrow_point",t,r,i,0,"var(--_l)");case 2:return St("arrow_cross",t,r,i,0,"var(--_l)");case 3:return`<path class="pele-marker" d="M${o(t-i*At)},${o(r-4.5)}L${o(t)},${o(r)}L${o(t-i*At)},${o(r+4.5)}" stroke-linejoin="round"/>`;case 4:return bo(t,r,i,n,!1);case 5:return bo(t,r,i,n,!0);default:return""}}function qu(e){return e===1?At-1:e===2?4:0}function ju(e,t,r){return Vr(r,i=>Xu(e,t,r,i))}function Xu(e,t,r,i){let n=t.sequence??{},l=r.fontSize??16,s=Math.round(l*.875),a=Math.round(l*.75),d=r.measurer??tt(r.fontFamily),c=r.icons,p=r.padding??8,u=n.mirrorActors!==!1,h=n.rightAngles===!0,$=Math.min(Ar(n,"actorMargin",40),i?8:1/0),g=Math.min(Ar(n,"width",64),i?48:1/0),T=Ar(n,"height",Math.round(l*1.5)+20),D=Math.min(Ar(n,"width",160),i?Math.max(32,((r.maxWidth??320)-2*p)/Math.max(1,e.actors.size)-$-24):1/0),_=Math.max(4,14+Ar(n,"messageMargin",35)-35),F=Math.min(Ar(n,"noteMargin",10),i?6:1/0),k=Math.min(Ar(n,"boxMargin",10),i?6:1/0),I=n.messageAlign==="left"?-1:n.messageAlign==="right"?1:0,E=i?6:Pu,m=i?8:Yu,y=i?12:Gu,C=i?6:Bu,L=e.messages,S=L.length,Z=Uu(L,n.showSequenceNumbers===!0),H=(q,ce,be,Ce=D,ve=0)=>{let ke=Fe(q,!1,d,ce,i||be?Ce:1/0,ve);return i?co(ke,d,Math.max(120,Ce)):ke},R;if(n.hideUnusedParticipants===!0){R=new Set;for(let q of L)R.add(q.from).add(q.to)}let P=new Int32Array(S+1);P[S]=-1;for(let q=S-1;q>=0;q--)P[q]=Xs(L[q].type)?q:P[q+1];let w=[],b=new Map;for(let[q,ce]of e.actors){if(R&&!R.has(q))continue;let be=Ou(ce.type),Ce=H(ce.description,l,ce.wrap),ve=e.createdActors.get(q),ke=e.destroyedActors.get(q),Re=ve===void 0?-1:P[Math.min(ve,S)];Re>=0&&L[Re].to!==q&&(Re=-1);let ze=ke===void 0?-1:P[Math.min(ke,S)];ze>=0&&L[ze].to!==q&&L[ze].from!==q&&(ze=-1),b.set(q,w.length),w.push({id:q,actor:ce,kind:be,label:Ce,size:Ru(be,Ce,g,T,i?8:void 0),x:0,createAt:Re,destroyAt:ze,top:0,lifeStart:0,lifeEnd:-1,activations:[]})}let M=w.length-1,f=new Map,x=(q,ce,be)=>{if(q<0||ce>M)return;let Ce=q*w.length+ce;(f.get(Ce)??0)<be&&f.set(Ce,be)},A=q=>Z.shown[q]?Math.max(wi,d.width(String(Z.index[q]),a,0)+8):0,z=new Array(S);for(let q=0;q<S;q++){let ce=L[q],be=ce.from===void 0?void 0:b.get(ce.from),Ce=ce.to===void 0?void 0:b.get(ce.to);if(!(be===void 0||Ce===void 0||typeof ce.message!="string")){if(ce.type===2){let ve=H(ce.message,s,ce.wrap),ke=ve.width+2*F;ce.placement===0?x(be-1,be,ke+2*Kr+Ht):ce.placement===1?x(be,be+1,ke+2*Kr+Ht):be===Ce?(x(be-1,be,ke/2+Kr),x(be,be+1,ke/2+Kr)):x(Math.min(be,Ce),Math.max(be,Ce),ke-2*m),z[q]={kind:2,a:be,b:Ce,label:ve,x:0,w:ke}}else if(Xs(ce.type)){let ve=H(ce.message,s,ce.wrap),ke=A(q);if(be===Ce)x(be,be+1,js+8+ve.width+16+Ht+ke),z[q]={kind:1,a:be,b:Ce,label:ve,x:0,w:0};else{let Re=w[Ce].createAt===q?w[Ce].size.w/2:0,ze=ce.centralConnection?4*Zr:0;x(Math.min(be,Ce),Math.max(be,Ce),(i?Math.min(ve.width,Math.max(16,D-16)):ve.width)+2*E+Ht+ke+Re+ze),z[q]={kind:0,a:be,b:Ce,label:ve,x:0,w:0}}}}}let v=[];for(let q=0;q<=M;q++){let ce=w[q].actor.box,be=v[v.length-1];ce&&be&&be.box===ce&&be.last===q-1?be.last=q:ce&&v.push({box:ce,first:q,last:q,title:H(ce.name,s,ce.wrap),grow:0})}let G=new Array(Math.max(M,0));for(let q=0;q<M;q++){let ce=w[q],be=w[q+1],Ce=ce.actor.box!==be.actor.box?(ce.actor.box?k:0)+(be.actor.box?k:0):0;G[q]=Math.max(ce.size.w/2+be.size.w/2+$+Ce,f.get(q*w.length+q+1)??0)}let ee=[];for(let[q,ce]of f){let be=Math.floor(q/w.length),Ce=q%w.length;Ce-be>1&&ee.push([be,Ce,ce])}ee.sort((q,ce)=>q[1]-q[0]-(ce[1]-ce[0])||q[0]-ce[0]);for(let[q,ce,be]of ee){let Ce=0;for(let ke=q;ke<ce;ke++)Ce+=G[ke];if(Ce>=be)continue;let ve=(be-Ce)/(ce-q);for(let ke=q;ke<ce;ke++)G[ke]+=ve}let he=()=>{for(let q=1;q<=M;q++)w[q].x=w[q-1].x+G[q-1]};he();for(let q of v){let ce=w[q.last].x+w[q.last].size.w/2-(w[q.first].x-w[q.first].size.w/2);q.grow=Math.max(0,(q.title.width-ce)/2),q.grow!==0&&(q.first>0&&(G[q.first-1]+=q.grow),q.last<M&&(G[q.last]+=q.grow))}he();let ue=1/0,V=-1/0,Y=(q,ce)=>{q<ue&&(ue=q),ce>V&&(V=ce)};for(let q of w)Y(q.x-q.size.w/2,q.x+q.size.w/2);for(let q of v)Y(w[q.first].x-w[q.first].size.w/2-k-q.grow,w[q.last].x+w[q.last].size.w/2+k+q.grow);let de=new Array(S),te=[],xe=()=>M<0?[0,120]:[w[0].x-y,w[M].x+y];for(let q=0;q<S;q++){let ce=L[q],be=ce.type,Ce=be===void 0?void 0:Wu.get(be),ve=z[q];if(Ce!==void 0){let ke={kind:Ce,x0:1/0,x1:-1/0,top:0,title:xo,tabW:0,fill:Ce==="rect"&&typeof ce.message=="string"?ce.message:"",dividers:[q],dividerY:[],dividerLabels:[]};de[q]=ke,te.push(ke)}else if(be===13||be===20||be===28)te[te.length-1]?.dividers.push(q);else if(be===11||be===14||be===16||be===21||be===29||be===31||be===23){let ke=te.pop();if(!ke)continue;if(de[q]=ke,ke.x0>ke.x1&&([ke.x0,ke.x1]=xe()),ke.kind!=="rect"){ke.tabW=d.width(ke.kind,a,1)+14;for(let ze=0;ze<ke.dividers.length;ze++){let We=L[ke.dividers[ze]].message,je=ze===0?ke.tabW+8:0,st=ke.x1-ke.x0-16-je,_e=We?H(`[${We}]`,s,!0,Math.max(st,i?Math.min($o,D):$o)):xo;_e.width>st&&(ke.x1+=_e.width-st),ze===0?ke.title=_e:ke.dividerLabels.push(_e)}}Y(ke.x0,ke.x1);let Re=te[te.length-1];Re&&(Re.x0=Math.min(Re.x0,ke.x0-C),Re.x1=Math.max(Re.x1,ke.x1+C))}else if(ve){let ke=w[ve.a],Re=w[ve.b],ze,We;if(ve.kind===2){if(ce.placement===0)ve.x=ke.x-Kr-ve.w;else if(ce.placement===1)ve.x=ke.x+Kr;else if(ve.a===ve.b)ve.x=ke.x-ve.w/2;else{let st=Math.min(ke.x,Re.x)-m,_e=Math.max(ke.x,Re.x)+m;(i||ce.wrap)&&(ve.label=H(ce.message,s,!0,Math.max(D,_e-st-2*F))),ve.w=Math.max(_e-st,ve.label.width+2*F),ve.x=(st+_e-ve.w)/2}ze=ve.x,We=ve.x+ve.w}else ve.kind===1?(ze=ke.x,We=ke.x+Ht+js+8+ve.label.width+A(q)):(ze=Math.min(ke.x,Re.x),We=Math.max(ke.x,Re.x),(i||ce.wrap)&&(ve.label=H(ce.message,s,!0,Math.max(D,We-ze-2*E-Ht))),Re.createAt===q&&(Re.x>ke.x?We+=Re.size.w/2:ze-=Re.size.w/2));Y(ze,We);let je=te[te.length-1];je&&(je.x0=Math.min(je.x0,ze-y),je.x1=Math.max(je.x1,We+y))}}let me=0;for(let q of v)me=Math.max(me,q.title.height);let ae=v.length>0?k+(me>0?me+4:0):0,O=0;for(let q of w)q.createAt<0&&(O=Math.max(O,q.size.h));let B=ae+O;for(let q of w)q.top=B-q.size.h,q.lifeStart=B;let Q=w.map(q=>q.x),se=(q,ce)=>{let be=0,Ce=Q.length;for(;be<Ce;){let ve=be+Ce>>1;Q[ve]<=q?be=ve+1:Ce=ve}return be<Q.length&&Q[be]<ce},ie=(q,ce,be,Ce)=>{if(q.width===0)return"";let ve=ce-q.width/2;return(se(ve,ve+q.width)?`<rect x="${o(ve-3)}" y="${o(be-q.height/2+2)}" width="${o(q.width+6)}" height="${o(q.height-4)}" rx="3" fill="var(--_bg)" stroke="none"/>`:"")+Ne(q,ce,be,Ce,c)},re=(q,ce=0)=>q.activations.length+ce>0?q.x-Ht/2:q.x,ne=(q,ce=0)=>{let be=q.activations.length+ce;return be>0?q.x+Ht/2+(be-1)*yo:q.x},X=[],j=[],oe="",$e="",ge="",Te="",pe="",W="",K=(q,ce)=>{let be=q.activations.pop(),Ce=Math.max(ce,be+Hu),ve=q.x-Ht/2+q.activations.length*yo;return Y(ve,ve+Ht),j.push(`<rect class="pele-activation" data-id="${Oe(q.id)}" x="${o(ve)}" y="${o(be)}" width="${Ht}" height="${o(Ce-be)}" rx="2"/>`),Ce},N=(q,ce)=>{let be=q.x,Ce=ce+16;return q.lifeEnd=Ce,W+=`<path class="pele-destroy" data-id="${Oe(q.id)}" d="M${o(be-6)},${o(Ce-6)}L${o(be+6)},${o(Ce+6)}M${o(be+6)},${o(Ce-6)}L${o(be-6)},${o(Ce+6)}"/>`,Ce+6},U=(q,ce,be)=>{let Ce=q.actor.properties.get("class");return`<g class="pele-node pele-actor pele-actor-${q.kind}${be?" pele-actor-footer":""}${typeof Ce=="string"?Mt(Ce):""}" data-id="${Oe(q.id)}">`+Fu(q.kind,q.x,ce,q.size,q.label,c)+"</g>"},J=(q,ce,be,Ce)=>`<g class="pele-sequence-number"><rect x="${o(ce-Ce/2)}" y="${o(be-wi/2)}" width="${o(Ce)}" height="${wi}" rx="${wi/2}" fill="var(--_l)" stroke="none"/><text x="${o(ce)}" y="${o(be+a*.35)}" text-anchor="middle" font-size="${a}" fill="var(--_bg)" stroke="none">${Be(String(Z.index[q]))}</text></g>`,le=B+6,fe=[];for(let q=0;q<S;q++){let ce=L[q],be=ce.type,Ce=z[q],ve=de[q];if(be===17){let ke=ce.from===void 0?void 0:b.get(ce.from);ke!==void 0&&w[ke].activations.push(le)}else if(be===18){let ke=ce.from===void 0?void 0:b.get(ce.from);ke!==void 0&&w[ke].activations.length>0&&(le=Math.max(le,K(w[ke],le)))}else if(ve&&ve.dividers[0]===q)fe.push(ve),ve.kind==="rect"?(ve.top=le+8,le=ve.top):(ve.top=le+12,le=ve.top+Math.max($i,ve.title.height+2));else if(ve){fe.pop();let ke=le+12,Re=o(ve.x0),ze=o(ve.x1-ve.x0);if(ve.kind==="rect"){let We=ve.fill?ct([`fill:${ve.fill}`]).shape:"";X.push(`<rect class="pele-rect" x="${Re}" y="${o(ve.top)}" width="${ze}" height="${o(ke-ve.top)}" rx="${Ke}"${We?"":' fill-opacity="0.5"'}${We}/>`)}else{let We=`<rect x="${Re}" y="${o(ve.top)}" width="${ze}" height="${o(ke-ve.top)}" rx="${Ke}" fill="none"/>`;for(let je=0;je<ve.dividerY.length;je++){let st=ve.dividerY[je],_e=ve.dividerLabels[je];We+=`<path d="M${Re},${o(st)}H${o(ve.x1)}"${wo}/>`+ie(_e,ve.x0+8+_e.width/2,st+2+_e.height/2,' class="pele-frame-label" fill="var(--_m)" stroke="none"')}We+=`<rect x="${Re}" y="${o(ve.top)}" width="${o(ve.tabW)}" height="${$i}" rx="${Ke}" fill="var(--_s)"/><text class="pele-frame-kind" x="${o(ve.x0+ve.tabW/2)}" y="${o(ve.top+$i/2+a*.35)}" text-anchor="middle" font-size="${a}" font-weight="var(--_hw)" fill="var(--_m)" stroke="none">${ve.kind}</text>`+ie(ve.title,ve.x0+ve.tabW+8+ve.title.width/2,ve.top+Math.max($i,ve.title.height)/2,' class="pele-frame-label" fill="var(--_m)" stroke="none"'),oe+=`<g class="pele-frame pele-frame-${ve.kind}">${We}</g>`}le=ke}else if(be===13||be===20||be===28){let ke=fe[fe.length-1];if(ke){let Re=ke.dividerLabels[ke.dividerY.length];ke.dividerY.push(le+12),le+=12+(Re.height>0?Re.height:0)}}else if(Ce&&Ce.kind===2){let ke=w[Ce.a],Re=Ce.label.height+2*Math.max(4,F-4),ze=le+10,We=Ce.x;ce.placement===1?We+=ne(ke)-ke.x:ce.placement===0&&(We+=re(ke)-ke.x),Y(We,We+Ce.w),Te+=`<g class="pele-note" data-id="i${Oe(ce.id)}"><rect x="${o(We)}" y="${o(ze)}" width="${o(Ce.w)}" height="${o(Re)}" rx="${Ke}"/>`+Ne(Ce.label,We+Ce.w/2,ze+Re/2,' class="pele-label" stroke="none" fill="var(--_fg)"',c)+"</g>",le=ze+Re}else if(Ce){let ke=Ks[be],Re=w[Ce.a],ze=w[Ce.b],We=Ce.label,je=A(q),st=0;for(let Ge=q+1;Ge<S;Ge++){let at=L[Ge].type;if(at===17)L[Ge].from===ce.to&&st++;else if(at!==18&&at!==59&&at!==60)break}let _e=ke.bottom?1:-1,Ye=ke.dotted?wo:"",Xe=ce.centralConnection,ht=Xe===59||Xe===61,$t=Xe===60||Xe===61,Bt=(Ge,at)=>`<circle class="pele-central" cx="${o(Ge)}" cy="${o(at)}" r="${Zr}" fill="var(--_l)" stroke="none"/>`,yr=ke.atStart&&!ke.atEnd,ar=qu(ke.head),pt="",rt;if(Ce.kind===1){let Ge=le+_+Math.max(0,(We.height-mo)/2),at=Ge+mo,Qe=$t?Re.x+Zr:ne(Re),Ze=ht?Re.x+Zr:ne(Re,st),ft=Math.max(Qe,Ze)+js+je/2;$t&&(pt+=Bt(Re.x,Ge)),ht&&(pt+=Bt(Re.x,at)),je>0&&(pt+=J(q,yr?Ze:Qe,yr?at:Ge,je),yr?Ze+=je/2:Qe+=je/2);let zt=(ke.atStart?xi(ke.head,Qe,Ge,-1,_e):"")+(ke.atEnd?xi(ke.head,Ze,at,-1,-_e):""),It=o(Qe+(ke.atStart?ar:0)),lt=o(Ze+(ke.atEnd?ar:0));pt=`<path d="${h?`M${It},${o(Ge)}H${o(ft)}V${o(at)}H${lt}`:`M${It},${o(Ge)}H${o(ft-6)}A6,6 0 0 1 ${o(ft)},${o(Ge+6)}V${o(at-6)}A6,6 0 0 1 ${o(ft-6)},${o(at)}H${lt}`}"${Ye}/>`+zt+pt,Y(Re.x,ft+8+We.width),We.width>0&&(ge+=`<g class="pele-edge-label" data-id="i${Oe(ce.id)}">${Ne(We,ft+8+We.width/2,(Ge+at)/2,"",c)}</g>`),rt=at}else{let Ge=ze.x>Re.x?1:-1,at=ze.createAt===q;rt=le+_+Math.max(We.height>0?We.height+2:6,at?ze.size.h/2-_+6:0);let Qe=Ge>0?ne(Re):re(Re),Ze=Ge>0?re(ze,st):ne(ze,st);if(at&&(ze.top=rt-ze.size.h/2,ze.lifeStart=ze.top+ze.size.h,Ze=ze.x-Ge*(Vs(ze.kind)?18:ze.size.w/2+1)),$t&&(pt+=Bt(Re.x,rt),Qe=Re.x+Ge*Zr),ht&&(pt+=Bt(ze.x,rt),Ze=ze.x-Ge*Zr),je>0)if(yr){let lt=ht?Ze-Ge*(je/2+2):Ze;pt+=J(q,lt,rt,je),Ze=lt-Ge*je/2}else{let lt=$t?Qe+Ge*(je/2+2):Qe;pt+=J(q,lt,rt,je),Qe=lt+Ge*je/2}let ft=(ke.atStart?xi(ke.head,Qe,rt,-Ge,_e*Ge):"")+(ke.atEnd?xi(ke.head,Ze,rt,Ge,_e*Ge):""),zt=Qe+(ke.atStart?Ge*ar:0),It=Ze-(ke.atEnd?Ge*ar:0);if(pt=`<path d="M${o(zt)},${o(rt)}H${o(It)}"${Ye}/>`+ft+pt,We.width>0){let lt=Math.min(Qe,Ze),xt=Math.max(Qe,Ze),bt=I<0?lt+E+We.width/2:I>0?xt-E-We.width/2:(lt+xt)/2;Y(bt-We.width/2,bt+We.width/2),ge+=`<g class="pele-edge-label" data-id="i${Oe(ce.id)}">${ie(We,bt,rt-4-We.height/2,"")}</g>`}at&&(le=rt+ze.size.h/2-6)}$e+=`<g class="pele-edge pele-message" data-id="i${Oe(ce.id)}">${pt}</g>`,le=Math.max(le,rt),Re.destroyAt===q&&(le=Math.max(le,N(Re,rt))),ze.destroyAt===q&&ze!==Re&&(le=Math.max(le,N(ze,rt)))}}le+=20;for(let q of w)for(;q.activations.length>0;)K(q,le);let we=le;if(u){let q=0;for(let ce of w)ce.lifeEnd>=0||(q=Math.max(q,ce.size.h),pe+=U(ce,le,!0));we=le+q}let Ee="";for(let q of w){pe+=U(q,q.top,!1);let ce=q.lifeEnd>=0?q.lifeEnd:le;ce>q.lifeStart&&(Ee+=`<path class="pele-lifeline" data-id="${Oe(q.id)}" d="M${o(q.x)},${o(q.lifeStart)}V${o(ce)}"/>`)}let Ae="";for(let q of v){let ce=w[q.first].x-w[q.first].size.w/2-k-q.grow,be=w[q.last].x+w[q.last].size.w/2+k+q.grow,Ce=q.box.fill==="transparent"?"":ct([`fill:${q.box.fill}`]).shape;Ae+=`<g class="pele-cluster pele-box"${q.box.name?` data-id="${Oe(q.box.name)}"`:""}><rect x="${o(ce)}" y="0" width="${o(be-ce)}" height="${o(we+k)}" rx="${Ke}" fill="var(--_a)" stroke="var(--_b)"${Ce?"":' fill-opacity="0.5"'}${Ce}/>`+Ne(q.title,(ce+be)/2,k/2+2+q.title.height/2,' class="pele-cluster-label" fill="var(--_m)"',c)+"</g>"}v.length>0&&(we+=k);let De=0,Ie="",ye=H(e.title,l,!1,i?Pt(r):D,1);if(ue>V&&Y(0,Math.max(ye.width,40)),ye.width>0){let q=(ue+V)/2;Y(q-ye.width/2,q+ye.width/2),De=-ye.height-12,Ie=Ne(ye,q,De+ye.height/2,' class="pele-title" font-weight="var(--_tw)"',c)}let Me=Math.ceil(V-ue+2*p),Se=Math.ceil(we-De+2*p);return{svg:Je("sequence",Me,Se,l,r,e,`<g transform="translate(${o(p-ue)},${o(p-De)})">`+Ie+(Ae?`<g class="pele-boxes" font-size="${s}">${Ae}</g>`:"")+(X.length>0?`<g class="pele-rects" fill="var(--_a)">${X.reverse().join("")}</g>`:"")+(Ee?`<g class="pele-lifelines" fill="none" stroke="var(--_b)">${Ee}</g>`:"")+(j.length>0?`<g class="pele-activations" fill="var(--_s)" stroke="var(--_b)">${j.reverse().join("")}</g>`:"")+(oe?`<g class="pele-frames" font-size="${s}" stroke="var(--_b)">${oe}</g>`:"")+($e?`<g class="pele-edges" fill="none" stroke="var(--_l)" stroke-linecap="round">${$e}</g>`:"")+(W?`<g class="pele-destroys" fill="none" stroke="var(--_l)" stroke-width="1.5" stroke-linecap="round">${W}</g>`:"")+(ge?`<g class="pele-edge-labels" font-size="${s}">${ge}</g>`:"")+(Te?`<g class="pele-notes" font-size="${s}" fill="var(--_a)" stroke="var(--_b)">${Te}</g>`:"")+(pe?`<g class="pele-nodes">${pe}</g>`:"")+"</g>"),width:Me,height:Se,links:[]}}var Zs={type:"sequence",parse(e,t,r){let i=t.sequence??{},n=new Cu({wrap:typeof t.wrap=="boolean"?t.wrap:void 0,sequenceWrap:i.wrap===!0});return r&&n.setDiagramTitle(r),_u(e,n),n},render:ju};function bi(e,t,r,i,n,l,s){let a=Fe(e,!1,t,r,4e3,1);if(a.height===0)return{width:n,height:l,content:s};let d=a.height+12,c=Math.max(n,Math.ceil(a.width+2*i));return{width:c,height:Math.ceil(l+d),content:Ne(a,c/2,i+a.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g transform="translate(${o((c-n)/2)},${o(d)})">${s}</g>`}}function Vu(e){let t="TB";for(let r of e)typeof r!="string"&&r.stmt==="dir"&&(t=r.value);return t}function Ku(e,t,r){let i=[],n=[],l=new Map,s=new Map,a=new Map,d=0,c=0,p=$=>{if(!$.id||$.id==="</join></fork>"||$.id==="</choice>")return;if($.cssClasses){let T;for(let D of $.cssClasses.split(" ")){let _=r.get(D);if(_){T??=$.cssCompiledStyles.slice();for(let F of _.styles)T.push(F)}}T&&($.cssCompiledStyles=T)}let g=l.get($.id);if(g){let T=$.parentId??g.parentId;Object.assign(g,$),T!==void 0&&(g.parentId=T)}else l.set($.id,$),i.push($)},u=($,g,T)=>{let D=g.id;if(D==="root")return;let _=t.get(D),F=_?.classes?.join(" ")??"",k=_?.styles??[],I=s.get(D);if(!I){let R="rect";g.start===!0?R="stateStart":g.start===!1&&(R="stateEnd"),g.type!=="default"&&(R=g.type),I={shape:R,description:D,cssClasses:`${F} statediagram-state`,cssStyles:k,type:void 0,dir:void 0,colorIndex:void 0},s.set(D,I)}if(g.description&&(Array.isArray(I.description)?(I.shape="rectWithTitle",I.description=I.description.concat(g.description)):I.description.length>0?(I.shape="rectWithTitle",I.description=I.description===D?[g.description].flat():[I.description,g.description].flat()):(I.shape="rect",I.description=Array.isArray(g.description)?g.description.slice():g.description)),I.description.length===1&&I.shape==="rectWithTitle"&&(I.shape=I.type==="group"?"roundedWithTitle":"rect"),!I.type&&g.doc){if(I.type="group",I.dir=Vu(g.doc),I.shape=g.type==="divider"?"divider":"roundedWithTitle",I.shape==="divider"&&$?.id!==void 0&&a.has($.id))I.colorIndex=a.get($.id);else{let R=c++;I.colorIndex=F.trim()!==""||k.length>0?void 0:R}a.set(D,I.colorIndex),I.cssClasses=`${I.cssClasses} statediagram-cluster ${T?"statediagram-cluster-alt":""}`}let E=I.description,m={id:D,shape:I.shape,label:Array.isArray(E)?E[0]:E,description:Array.isArray(E)?E.slice(1):[],cssClasses:I.cssClasses,cssCompiledStyles:[],cssStyles:I.cssStyles,type:I.type,isGroup:I.type==="group",dir:I.dir,colorIndex:I.colorIndex};m.shape==="divider"&&(m.label=""),$&&$.id!=="root"&&(m.parentId=$.id);let y=g.note;if(!y){p(m);return}let C=(R,P,w,b)=>({id:R,shape:P,label:y.text,description:[],cssClasses:w,cssCompiledStyles:[],cssStyles:[],type:b?"group":"node",isGroup:b,dir:void 0,position:y.position}),L=C(`${D}----note-${d++}`,"note","statediagram-note",!1);L.parentId=`${D}----parent`,L.noteFor=D,p(C(L.parentId,"noteGroup",I.cssClasses,!0)),p(L),p(m);let S=y.position==="left of",Z=S?L.id:D,H=S?D:L.id;n.push({id:`${Z}-${H}`,start:Z,end:H,label:"",classes:"transition note-edge",pattern:"dashed"})},h=[{item:void 0,doc:e,at:0,alt:!0}];for(;h.length>0;){let $=h[h.length-1];if($.at>=$.doc.length){h.pop();continue}let g=$.doc[$.at++];typeof g!="string"&&(g.stmt==="state"?(u($.item,g,$.alt),g.doc&&h.push({item:g,doc:g.doc,at:0,alt:!$.alt})):g.stmt==="relation"&&(u($.item,g.state1,$.alt),u($.item,g.state2,$.alt),n.push({id:`edge${d++}`,start:g.state1.id,end:g.state2.id,label:g.description??"",classes:"transition"})))}for(let $ of i)if($.isGroup&&$.description.length>0)throw new He(`Group nodes can only have label. Remove the additional description for node [${$.id}]`,"semantic",{type:"state"});return{nodes:i,edges:n}}var Zu=class{type="state";rootDoc=[];states=new Map;relations=[];classes=new Map;links=new Map;graph={nodes:[],edges:[]};title;accTitle;accDescr;dividerCount=0;get direction(){let e="TB";for(let t of this.rootDoc)typeof t!="string"&&t.stmt==="dir"&&(e=t.value);return e}setRootDoc(e){this.rootDoc=e,this.translate(),this.extract(e)}extract(e){this.states=new Map,this.relations=[],this.classes=new Map;let t=Array.isArray(e)?e:e.doc;for(let r of t)if(typeof r!="string")switch(r.stmt){case"state":this.addState(r.id.trim(),r.type,r.doc,r.description,r.note);break;case"relation":this.addRelation(r.state1,r.state2,r.description);break;case"classDef":this.addStyleClass(r.id.trim(),r.classes);break;case"style":{let i=r.styleClass.split(",").map(n=>n.replace(/;/g,"").trim());for(let n of this.named(r.id.trim()))n.styles=i.slice();break}case"applyClass":this.setCssClass(r.id.trim(),r.styleClass);break;case"click":this.addLink(typeof r.id=="string"?r.id:r.id.id,r.url,r.tooltip);break}this.graph=Ku(t,this.states,this.classes)}translate(){let e=[["root",{stmt:"root",id:"root",doc:this.rootDoc},!0]];for(;e.length>0;){let[t,r,i]=e.pop();if(typeof r=="string")continue;if(r.stmt==="relation"){e.push([t,r.state2,!1],[t,r.state1,!0]);continue}if(r.stmt==="state")r.id==="[*]"?(r.id=t+(i?"_start":"_end"),r.start=i):r.id=r.id.trim();else if(r.stmt!=="root")continue;if(!r.doc)continue;let n=[],l=[];for(let s of r.doc)typeof s!="string"&&s.stmt==="state"&&s.type==="divider"&&!s.doc?(n.push({...s,doc:l}),l=[]):l.push(s);n.length>0&&(l.length>0&&n.push({stmt:"state",id:this.getDividerId(),type:"divider",doc:l}),r.doc=n);for(let s=r.doc.length-1;s>=0;s--)e.push([r.id,r.doc[s],!0])}}addState(e,t="default",r,i,n,l){let s=e.trim(),a=this.states.get(s);if(a?(a.doc||(a.doc=r),a.type||(a.type=t)):(a={stmt:"state",id:s,descriptions:[],type:t,doc:r,note:n,classes:[],styles:[],textStyles:[]},this.states.set(s,a)),i)for(let d of Array.isArray(i)?i:[i])this.addDescription(s,d.trim());if(n&&(a.note=n),l)for(let d of l)this.setCssClass(s,d.trim())}getState(e){return this.states.get(e)}addLink(e,t,r){this.links.set(e,{url:t,tooltip:r})}addRelation(e,t,r=""){for(let i of[e,t])this.addState(i.id,i.type,i.doc,i.description,i.note,i.classes);this.relations.push({id1:e.id.trim(),id2:t.id.trim(),relationTitle:r})}addDescription(e,t){this.states.get(e)?.descriptions?.push(t.startsWith(":")?t.replace(":","").trim():t)}getDividerId(){return`divider-id-${++this.dividerCount}`}addStyleClass(e,t=""){let r=this.classes.get(e);if(r||(r={id:e,styles:[],textStyles:[]},this.classes.set(e,r)),!!t)for(let i of t.split(",")){let n=i.replace(";","").trim();i.includes("color")&&r.textStyles.push(n.replace("fill","bgFill").replace("color","fill")),r.styles.push(n)}}setCssClass(e,t){for(let r of this.named(e))r.classes?.push(t)}getDirection(){for(let e of this.rootDoc)if(typeof e!="string"&&e.stmt==="dir")return e.value;return"TB"}setDirection(e){for(let t of this.rootDoc)if(typeof t!="string"&&t.stmt==="dir"){t.value=e;return}this.rootDoc.unshift({stmt:"dir",value:e})}trimColon(e){return e.startsWith(":")?e.slice(1).trim():e.trim()}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
64`)}named(e){let t=[];for(let r of e.split(",")){let i=this.states.get(r);i||(this.addState(r),i=this.states.get(r.trim())),i&&t.push(i)}return t}},To=["$end","INVALID","NL","SD","DESCR","-->","HIDE_EMPTY","scale","WIDTH","COMPOSIT_STATE","STRUCT_START","STRUCT_STOP","STATE_DESCR","AS","ID","FORK","JOIN","CHOICE","CONCURRENT","note","NOTE_TEXT","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","CLICK","STRING","HREF","classDef","CLASSDEF_ID","DEFAULT_CLASSDEF_ID","CLASSDEF_STYLEOPTS","DEFAULT","style","STYLE_IDS","STYLEDEF_STYLEOPTS","class","CLASSENTITY_IDS","STYLECLASS","direction_tb","direction_bt","direction_rl","direction_lr","EDGE_STATE","STYLE_SEPARATOR","left_of","right_of","INVALID"],Qu=/direction/gi,Ju=/<<(?:fork|join|choice)>>|\[\[(?:fork|join|choice)\]\]/gi,ep=/[\n\r\u2028\u2029]/g,tp=/%%/g,rp=/\{/g;function Aa(e,t){let r=0,i=-2;return n=>{if(i===-2||n<r||i!==-1&&n>i){e.lastIndex=n;let l=e.exec(t);i=l?l.index:-1,r=n}return i}}function ap(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d,c=Aa(Qu,e),p=Aa(Ju,e),u=Aa(ep,e),h=Aa(tp,e),$=Aa(rp,e),g=-1,T=-1,D=[-1,-1,-1,-1],_=[0,0,0,0],F=-1,k=-1,I=[-1,-1,-1,-1,-1,-1],E=(f,x,A)=>{r.push(f),i.push(e.slice(x,A)),n.push(x),a=A},m=(f,x,A,z)=>{r.push(f),i.push(x),n.push(A),a=z},y=f=>{l.push(s),s=f},C=()=>{l.length>0&&(s=l.pop())},L=(f,x)=>{for(let A=0;A<f.length;A++){let z=f.charCodeAt(A),v=e.charCodeAt(x+A);if(v!==z&&!(z>=97&&z<=122&&v===z-32))return!1}return!0},S=f=>{let x=f;for(;x<t&&Le(e.charCodeAt(x));)x++;return x},Z=f=>{let x=f;for(;x<t&&Pe(e.charCodeAt(x));)x++;return x},H=f=>{let x=e.indexOf(`
65`,f);return x===-1?t:x},R=f=>{let x=u(f);return x===-1?t:x},P=f=>{if(f<g||f>T){let x=c(f),A=x===-1?t:R(f);g=f,T=A,D[0]=D[1]=D[2]=D[3]=-1;for(let z=x;z!==-1&&z<A;z=c(z+1)){let v=S(z+9);if(v===z+9)continue;let G=L("tb",v)?0:L("bt",v)?1:L("rl",v)?2:L("lr",v)?3:-1;G!==-1&&(D[G]=z,_[G]=v+2)}}for(let x=0;x<4;x++)if(D[x]>=f)return x;return-1},w=f=>{if(f<F||f>k){let x=p(f),A=x===-1?t:R(f);F=f,k=A,I.fill(-1);for(let z=x;z!==-1&&z<A;z=p(z+1)){let v=e.charCodeAt(z+2)|32;I[(e.charCodeAt(z)===60?0:3)+(v===102?0:v===106?1:2)]=z}}for(let x=0;x<6;x++)if(I[x]>=f)return x;return-1},b=(f,x)=>{let A=h(f);return A===-1||A+2>x?(E(14,f,x),!0):A===f?(a=x,!1):(E(14,f,A),!0)},M=f=>(r.push(f),i.push(""),n.push(a),{types:r,texts:i,starts:n,error:d});for(;;){if(a>=t){switch(s){case 0:E(2,t,t);break;case 6:E(22,t,t);break;case 7:E(24,t,t);break;case 8:E(25,t,t);break;case 10:E(32,t,t);break;case 12:E(39,t,t);break;case 14:E(36,t,t);break;case 3:E(12,t,t);break;case 18:E(20,t,t);break;case 4:case 19:E(14,t,t);break}return M(0)}let f=e.charCodeAt(a);switch(s){case 0:case 1:{let x=s===0,A=f|32;if(x){if(A===99&&L("click",a)&&!Pe(e.charCodeAt(a+5))){E(26,a,a+5);continue}if(A===104&&L("href",a)&&!Pe(e.charCodeAt(a+4))){E(28,a,a+4);continue}if(f===34){let G=e.indexOf('"',a+1);if(G!==-1){E(27,a,G+1);continue}}if(A===100&&L("default",a)&&!Pe(e.charCodeAt(a+7))){E(33,a,a+7);continue}let v=P(a);if(v!==-1){E(40+v,a,H(_[v]));continue}if(f===10){let G=a+1;for(;e.charCodeAt(G)===10;)G++;E(2,a,G);continue}if(Le(f)){a=S(a);continue}}else if(f!==10&&Le(f)){let v=a+1;for(;v<t&&e.charCodeAt(v)!==10&&Le(e.charCodeAt(v));)v++;a=v;continue}if(f===35||f===37&&e.charCodeAt(a+1)===37&&e.charCodeAt(a+2)!==123){a=H(a);continue}if(A===115){if(x&&L("scale",a)){let v=S(a+5);if(v>a+5){E(7,a,v),y(5);continue}}if(L("style",a)){let v=S(a+5);if(v>a+5){E(34,a,v),y(13);continue}}if(L("state",a)){let v=S(a+5);if(v>a+5){a=v,y(2);continue}if(x&&L("diagram",a+5)){let G=L("-v2",a+12)?a+15:a+12;if(v=S(G),v>G){E(3,a,v);continue}}}}else if(A===99){if(L("class",a)){let v=L("def",a+5),G=v?a+8:a+5,ee=S(G);if(ee>G){E(v?29:37,a,ee),y(v?9:11);continue}}}else if(A===97&&x&&(L("acctitle",a)||L("accdescr",a))){let v=(e.charCodeAt(a+3)|32)===116,G=S(a+8),ee=e.charCodeAt(G);if(ee===58){E(v?21:23,a,S(G+1)),y(v?6:7);continue}if(ee===123&&!v){a=S(G+1),y(8);continue}}if(x){if(f===123){E(10,a,a+1),y(1);continue}}else{let v=P(a);if(v!==-1){E(40+v,a,H(_[v]));continue}if(f===125){E(11,a,a+1),C();continue}if(f===10){a++;continue}}if(A===110&&L("note",a)){let v=S(a+4);if(v>a+4){E(19,a,v),y(15);continue}}if(x&&A===104&&L("hide empty description",a)&&!Pe(e.charCodeAt(a+22))){E(6,a,a+22);continue}if(f===91&&e.charCodeAt(a+1)===42&&e.charCodeAt(a+2)===93){E(44,a,a+3);continue}let z=a;for(;z<t;){let v=e.charCodeAt(z);if(v===58||v===45||v===123||Le(v))break;z++}if(z>a){b(a,z);continue}if(f===58){for(z=a+1;z<t;){let v=e.charCodeAt(z);if(v===10||v===59)break;if(v===58){let G=e.charCodeAt(z+1);if(z+1>=t||G===58||G===10||G===59)break;z++}z++}if(z>a+1){m(4,e.slice(a,z).trim(),a,z);continue}if(e.charCodeAt(a+1)===58&&e.charCodeAt(a+2)===58){E(45,a,a+3);continue}}else if(f===45&&e.charCodeAt(a+1)===45){if(e.charCodeAt(a+2)===62){E(5,a,a+3);continue}if(!x){E(18,a,a+2);continue}}if(!x)return M(1);E(48,a,a+1);continue}case 2:{if(f!==10&&Le(f)){let v=a+1;for(;v<t&&e.charCodeAt(v)!==10&&Le(e.charCodeAt(v));)v++;a=v;continue}if(f===35||f===37&&e.charCodeAt(a+1)===37&&e.charCodeAt(a+2)!==123){a=H(a);continue}let x=w(a);if(x!==-1){let v=I[x],G=x===2||x===5;m(G?17:x%3===0?15:16,e.slice(a,v).trim(),a,v+(G?10:8)),C();continue}if(f===34){a++,y(3);continue}let A=f===10?S(a):a;if(L("as",A)){let v=S(A+2);if(v>A+2){E(13,a,v),y(4);continue}}if(f===10){a++,C();continue}if(f===123){E(10,a,a+1),C(),y(1);continue}if(Pe(f)){let v=Z(a),G=S(v);if(G>v&&Pe(e.charCodeAt(G))){let ee=$(G+1);if(ee!==-1&&ee<R(G))return d=`Error: State name must be a single word. Found: "${e.slice(a,ee+1).trim()}"`,M(1)}}let z=a+1;for(;z<t;){let v=e.charCodeAt(z);if(v===123||Le(v))break;z++}E(9,a,z);continue}case 3:{if(f===34){a++,C();continue}let x=e.indexOf('"',a);E(12,a,x===-1?t:x);continue}case 4:{let x=a;for(;x<t;){let A=e.charCodeAt(x);if(A===10||A===123)break;x++}b(a,x)&&C();continue}case 5:{if(f>=48&&f<=57){let A=a+1;for(;A<t&&e.charCodeAt(A)>=48&&e.charCodeAt(A)<=57;)A++;E(8,a,A);continue}let x=S(a);if(x>a&&L("width",x)&&!Pe(e.charCodeAt(x+5))){a=x+5,C();continue}return M(1)}case 6:E(22,a,H(a)),C();continue;case 7:E(24,a,H(a)),C();continue;case 8:{if(f===125){a++,C();continue}let x=e.indexOf("}",a);E(25,a,x===-1?t:x);continue}case 9:{let x=L("default",a)&&S(a+7)>a+7,A=x?a+7:Z(a),z=S(A);if(A===a||z===A)return M(1);E(x?31:30,a,z),C(),y(10);continue}case 10:E(32,a,H(a)),C();continue;case 11:{let x=Z(a);if(x===a)return M(1);for(;e.charCodeAt(x)===44;){let A=S(x+1),z=Z(A);if(z===A)break;x=z}E(38,a,x),C(),y(12);continue}case 12:E(39,a,H(a)),C();continue;case 13:{let x=a;for(;x<t&&(Pe(e.charCodeAt(x))||e.charCodeAt(x)===44);)x++;let A=S(x);if(x===a||A===x)return M(1);E(35,a,A),C(),y(14);continue}case 14:E(36,a,H(a)),C();continue;case 15:{if(L("left of",a)&&!Pe(e.charCodeAt(a+7))){E(46,a,a+7),C(),y(16);continue}if(L("right of",a)&&!Pe(e.charCodeAt(a+8))){E(47,a,a+8),C(),y(16);continue}if(f===34){a++,C(),y(18);continue}return M(1)}case 16:{let x=S(a),A=x;for(;A<t;){let z=e.charCodeAt(A);if(z===58||z===45||Le(z))break;A++}if(A===x)return M(1);b(a,A)&&(C(),y(17));continue}case 17:{let x=S(a);if(e.charCodeAt(x)===58){let v=x+1;for(;v<t;){let G=e.charCodeAt(v);if(G===58||G===10||G===59)break;v++}if(v>x+1){m(20,e.slice(a+2,v).trim(),a,v),C();continue}}let A=e.indexOf(`
66`,a),z=-1;for(;A!==-1&&(z=S(A),!(L("end note",z)&&!Pe(e.charCodeAt(z+8))));)A=e.indexOf(`
67`,z);if(A===-1)return M(1);m(20,e.slice(a,z).trim(),a,z+8),C();continue}case 18:{let x=S(a);if(L("as",x)){E(13,a,S(x+2)),C(),y(19);continue}if(f===34){a++;continue}let A=e.indexOf('"',a);E(20,a,A===-1?t:A);continue}case 19:b(a,H(a))&&C();continue}}}var ip=["TB","BT","RL","LR"],ki="'NL', 'ID', 'HIDE_EMPTY', 'scale', 'COMPOSIT_STATE', 'STATE_DESCR', 'FORK', 'JOIN', 'CHOICE', 'CONCURRENT', 'note', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'CLICK', 'classDef', 'style', 'class', 'direction_tb', 'direction_bt', 'direction_rl', 'direction_lr', 'EDGE_STATE'";function sp(e,t){let{types:r,texts:i,starts:n,error:l}=ap(e),s=0,a=g=>{let T=r[s];throw T===1?l!==void 0?new He(l,"syntax",{type:"state",...xs(e,n[s])}):Ve("state",e,n[s],"",!0):Ve("state",e,n[s],`Expecting ${g}, got '${To[T]}'`)},d=g=>(r[s]!==g&&a(`'${To[g]}'`),i[s++]),c=()=>{let g=r[s];g!==14&&g!==44&&a("'ID', 'EDGE_STATE'");let T=i[s++].trim();return r[s]!==45?{stmt:"state",id:T,type:"default",description:""}:(s++,{stmt:"state",id:T,classes:[d(14).trim()],type:"default",description:""})};for(;r[s]===2;)s++;r[s]!==3&&a("'NL', 'SD'"),s++;let p=[],u=[],h=g=>{g!=="nl"&&p.push(g)},$=(g,T)=>{s++;let D=[];p.push({stmt:"state",id:g,type:"default",description:T,doc:D}),u.push(p),p=D};for(;;){let g=r[s];switch(g){case 2:s++;break;case 14:case 44:{let T=c();if(r[s]===4)T.description=t.trimColon(i[s++]),h(T);else if(r[s]===5){s++;let D=c();r[s]===4?h({stmt:"relation",state1:T,state2:D,description:t.trimColon(i[s++])}):h({stmt:"relation",state1:T,state2:D})}else h(T);break}case 6:h(i[s++]);break;case 7:s++,d(8),h(i[s-2]);break;case 9:r[s+1]===10?$(i[s++],""):h(i[s++]);break;case 12:{let T=i[s++];d(13);let D=d(14);if(r[s]===10)$(D,T);else if(D.includes(":")){let _=D.split(":");h({stmt:"state",id:_[0],type:"default",description:[T.trim(),_[1]]})}else h({stmt:"state",id:D,type:"default",description:T.trim()});break}case 15:h({stmt:"state",id:i[s++],type:"fork"});break;case 16:h({stmt:"state",id:i[s++],type:"join"});break;case 17:h({stmt:"state",id:i[s++],type:"choice"});break;case 18:s++,h({stmt:"state",id:t.getDividerId(),type:"divider"});break;case 19:{let T=i[s++];if(r[s]===46||r[s]===47){let D=i[s++].trim(),_=d(14).trim();h({stmt:"state",id:_,note:{position:D,text:d(20).trim()}})}else r[s]!==20&&a("'NOTE_TEXT', 'left_of', 'right_of'"),s++,d(13),d(14),h(T);break}case 40:case 41:case 42:case 43:{let T=ip[g-40];s++,t.setDirection(T),h({stmt:"dir",value:T});break}case 21:{s++;let T=d(22).trim();t.setAccTitle(T),h(T);break}case 23:{s++;let T=d(24).trim();t.setAccDescription(T),h(T);break}case 25:{let T=i[s++].trim();t.setAccDescription(T),h(T);break}case 26:{s++;let T=c(),D,_="";r[s]===28?(s++,D=d(27)):(r[s]!==27&&a("'STRING', 'HREF'"),D=i[s++],_=d(27)),d(2),h({stmt:"click",id:T,url:D,tooltip:_});break}case 29:{s++;let T=d(30).trim();h({stmt:"classDef",id:T,classes:d(32).trim()});break}case 34:{s++;let T=d(35).trim();h({stmt:"style",id:T,styleClass:d(36).trim()});break}case 37:{s++;let T=d(38).trim();h({stmt:"applyClass",id:T,styleClass:d(39).trim()});break}case 11:u.length===0&&a(`'$end', ${ki}`),s++,p=u.pop();break;case 0:return u.length>0&&a(`'STRUCT_STOP', ${ki}`),t.setRootDoc(p),p;default:a(u.length>0?`'STRUCT_STOP', ${ki}`:`'$end', ${ki}`)}}}var lp=40,np=16,op=44,Jr=16,Qs=10,cp=16,Co=10,Js=26,Eo=8,dp=320,el=10,So=8,_o=' fill="var(--_s)" stroke="var(--_b)"',vi=' fill="none" stroke="var(--_b)"',hp=/(?:^| )statediagram-(?:state|cluster-alt|cluster|note)(?= |$)/g,fp=new Map([["rectWithTitle",1],["stateStart",2],["stateEnd",3],["choice",4],["fork",5],["join",6],["note",7],["divider",10]]),up=["pele-node pele-state","pele-node pele-state","pele-node pele-state-start","pele-node pele-state-end","pele-node pele-state-choice","pele-node pele-state-fork","pele-node pele-state-join","pele-note","pele-cluster pele-state-composite"];function Do(e){return e==="TB"||e==="BT"}function tl(e,t,r){let i=e.state?.[t];return typeof i=="number"&&i>0?Math.min(i,2e3):r}function Io(e){let t=0,r=e.length;for(;t<r&&e.charCodeAt(t)===34;)t++;for(;r>t&&e.charCodeAt(r-1)===34;)r--;return e.slice(t,r)}function No(e,t,r){return e<t?t:e>r?r:e}function Mi(e,t,r,i,n){return`<rect x="${o(e)}" y="${o(t)}" width="${o(r)}" height="${o(i)}"${n}/>`}function Ai(e,t,r,i){let n=wt(0,0);return n.isGroup=!0,n.dir=e,n.padX=t,n.padTop=r,n.padBottom=i,n}function pp(e,t,r){return dr(e.direction)?Ct(r,i=>Lo(e,t,r,i)):Lo(e,t,r,!1)}function Lo(e,t,r,i){let n=e.graph,l=r.fontSize??16,s=Math.round(l*.875),a=r.measurer??tt(r.fontFamily),d=tl(t,"wrappingWidth",200),c=r.padding??8,p=r.icons,u=i?"TB":Ft(e.direction),h=Fe(void 0,!1,a,l,0),$=(X,j,oe,$e=0)=>Fe(X,!0,a,j,oe,$e),g=new Map,T=[],D=[],_=(X,j,oe)=>(T.push({node:X,kind:j,style:void 0,label:h,lines:[],w:0,h:0,titleH:0}),oe&&D.push(oe),T.length-1);for(let X of n.nodes){if(X.shape==="noteGroup")continue;let j=X.isGroup?X.shape==="divider"?9:8:fp.get(X.shape)??0;g.set(X.id,_(X,j,void 0))}let F=T.length,k=[];for(let X=0;X<F;X++){let j=T[X].node.parentId,oe=j===void 0?void 0:g.get(j);k.push(oe!==void 0&&oe!==X&&T[oe].node.isGroup?oe:-1)}{let X=[];for(let pe=0;pe<F;pe++)X.push([]);let j=[],oe=new Uint8Array(F);for(let pe=0;pe<F;pe++)k[pe]===-1?(oe[pe]=1,j.push(pe)):X[k[pe]].push(pe);let $e=0,ge=()=>{for(;$e<j.length;$e++)for(let pe of X[j[$e]])oe[pe]||(oe[pe]=1,j.push(pe))};ge();let Te=new Int32Array(F).fill(-1);for(let pe=0;pe<F;pe++){if(oe[pe])continue;let W=pe;for(;Te[W]!==pe;)Te[W]=pe,W=k[W];k[W]=-1,oe[W]=1,j.push(W),ge()}}let I=new Int32Array(F).fill(-1);for(let X=0;X<F;X++){let j=T[X].node.noteFor,oe=j===void 0?void 0:g.get(j);oe!==void 0&&(I[X]=oe,k[X]=k[oe])}let E=X=>Ft(T[X].node.dir),m=X=>Do(k[X]===-1?u:E(k[X])),y=new Int32Array(F),C=new Uint8Array(F),L=new Array(F).fill(1/0),S=0,Z=new Int32Array(2*F);for(let X of n.edges){let j=g.get(X.start),oe=g.get(X.end);if(!(j===void 0||oe===void 0)){if(X.pattern==="dashed"){C[T[j].kind===7?oe:j]=1;continue}y[j]=Math.max(y[j],++Z[2*j]),y[oe]=Math.max(y[oe],++Z[2*oe+1]),L[j]===1/0&&(L[j]=S++),L[oe]===1/0&&(L[oe]=S++)}}for(let X=0;X<F;X++){let j=T[X],oe=j.node,$e=ct(oe.cssStyles.length>0?oe.cssCompiledStyles.concat(oe.cssStyles):oe.cssCompiledStyles),ge=($e.bold?1:0)|($e.italic?2:0),Te=$e.fontSize??l;j.style=$e;let pe;switch(j.kind){case 8:j.label=$(oe.label,Te,4e3,ge),j.titleH=j.label.height>0?j.label.height+12:0,pe=Ai(E(X),Jr,j.titleH+Jr,Jr),pe.minW=j.label.width+2*Jr;break;case 9:pe=Ai(E(X),Qs,Qs,Qs);break;case 2:j.w=j.h=14;break;case 3:j.w=j.h=18;break;case 4:j.w=j.h=30;break;case 5:case 6:{let W=No(40*y[X]+16,72,320);j.w=m(X)?W:So,j.h=m(X)?So:W;break}case 10:break;case 7:j.label=$(oe.label,s,Math.max(d,dp)),j.w=j.label.width+24,j.h=j.label.height+16;break;default:{j.label=$(oe.label,Te,d,ge);let W=j.label.width,K=j.label.height+2*Co;if(j.kind===1){K+=14;for(let N of oe.description){let U=$(N===""?" ":N,s,d,ge);j.lines.push(U),U.width>W&&(W=U.width),K+=U.height}}j.w=Math.max(W+2*cp,56),j.h=K}}pe??=wt(j.w,j.h),(j.kind===0||j.kind===1)&&(pe.span=(m(X)?j.w:j.h)-24),D.push(pe)}let H=[],R=[],P=[],w=new Int32Array(F),b=new Float64Array(F),M=new Float64Array(F),f=new Map,x=(X,j)=>{if(!D[X].isGroup)return!1;for(let oe=k[j];oe!==-1;oe=k[oe])if(oe===X)return!0;return!1},A=(X,j)=>(f.set(H.length,X),L.push(j?-1:1/0),_(void 0,10,wt(0,0,X)));for(let X of n.edges){let j=g.get(X.start),oe=g.get(X.end);if(j===void 0||oe===void 0)continue;let $e=$(X.label,s,d),ge=$e.width>0?$e.width+12:0;j===oe?(w[j]++,b[j]=Math.max(b[j],ge),M[j]+=$e.height):x(j,oe)?j=A(j,!0):x(oe,j)&&(oe=A(oe,!1)),P.push(X),R.push($e),H.push({src:j,dst:oe,minlen:1,labelW:ge,labelH:$e.height>0?$e.height+4:0,route:[],labelX:0,labelY:0})}for(let X=0;X<F;X++){if(I[X]!==-1)continue;let j=D[X],oe=0;if(w[X]>0){let ge=Js+(w[X]-1)*8;oe=m(X)?ge+b[X]:ge*.75+4+M[X],j.isGroup||(m(X)?(j.w+=2*oe,j.h=Math.max(j.h,M[X])):(j.h+=2*oe,j.w=Math.max(j.w,b[X])),oe=0)}if(!C[X]&&oe===0){j.parent=k[X];continue}let $e=m(X)?Ai("LR",oe,0,0):Ai("TB",0,oe,oe);$e.parent=k[X],L.push(L[X]),D[X].parent=_(void 0,10,$e)}for(let X=0;X<F;X++)I[X]!==-1&&(D[X].parent=D[I[X]].parent);{let X=[];for(let pe=0;pe<D.length;pe++)X.push([]);let j=[];for(let pe=0;pe<D.length;pe++){let W=D[pe].parent;W>=0?X[W].push(pe):j.push(pe)}let oe=pe=>T[pe].kind===2?0:1,$e=(pe,W)=>oe(pe)-oe(W)||(L[pe]===L[W]?0:L[pe]<L[W]?-1:1)||pe-W,ge=0,Te=j.sort($e).reverse();for(;Te.length>0;){let pe=Te.pop();D[pe].seq=ge++;let W=X[pe].sort($e);for(let K=W.length-1;K>=0;K--)Te.push(W[K])}}let z=or(D,H,u,{nodeSep:tl(t,"nodeSpacing",lp),edgeSep:np,rankSep:tl(t,"rankSpacing",op),portSep:20,headRoom:Nt("arrow_point")}),v=Math.ceil(z.width+2*c),G=Math.ceil(z.height+2*c),ee=[],he=new Map;for(let X of H){let j=X.route;for(let oe=3;oe<j.length-3;oe+=3){let $e=Math.round(j[oe+1]),ge=he.get($e);ge?ge.push(j[oe]):he.set($e,[j[oe]])}}let ue=[];for(let X=0;X<D.length;X++)ue.push([]);let V=[];for(let X=0;X<D.length;X++){let j=D[X].parent;j>=0?ue[j].push(X):V.push(X)}let Y=V.slice();for(let X=0;X<V.length;X++)for(let j of ue[V[X]])V.push(j);let de="",te="",xe="",me="",ae=(X,j,oe,$e,ge)=>{let Te=X.filter(K=>T[K].kind===9);if(Te.length<2)return;let pe=(K,N)=>N?D[K].x-D[K].w/2:D[K].y-D[K].h/2,W=(K,N)=>N?D[K].x+D[K].w/2:D[K].y+D[K].h/2;for(let K of[!0,!1]){let N=Te.slice().sort((J,le)=>pe(J,K)-pe(le,K)||J-le),U=!0;for(let J=1;J<N.length;J++)W(N[J-1],K)>pe(N[J],K)+.5&&(U=!1);if(U){for(let J=1;J<N.length;J++){let le=o((W(N[J-1],K)+pe(N[J],K))/2+c);te+=`<path class="pele-divider" d="M${K?`${le},${o(oe)}V${o(ge)}`:`${o(j)},${le}H${o($e)}`}"/>`}return}}for(let K of Te){let N=D[K];te+=Mi(N.x-N.w/2+c,N.y-N.h/2+c,N.w,N.h,` class="pele-divider" rx="${el}"`)}};ae(Y,c/2,c/2,v-c/2,G-c/2);for(let X of V){let j=T[X],oe=j.node,$e=j.style;if(oe===void 0||$e===void 0||j.kind>=9)continue;let ge=D[X],Te=ge.x+c,pe=ge.y+c,W=j.w,K=j.h,N=` class="pele-label"${$e.text}`,U;switch(j.kind){case 8:{let fe=Te-ge.w/2,we=pe-ge.h/2;U=Mi(fe,we,ge.w,ge.h,` rx="${el}" fill="var(--_a)" fill-opacity="0.5" stroke="var(--_b)"${$e.shape}`),j.titleH>0&&(U+=`<path d="M${o(fe)},${o(we+j.titleH)}H${o(fe+ge.w)}"${vi}${$e.line}/>`+Ne(j.label,gp(ge,j.label.width,he)+c,we+j.titleH/2,` class="pele-cluster-label"${$e.text}`,p)),ae(ue[X],fe,we+j.titleH,fe+ge.w,we+ge.h);break}case 2:U=`<circle r="7" fill="var(--_l)"${$e.shape}/>`;break;case 3:U=`<circle r="8.5" fill="var(--_bg)" stroke="var(--_l)"${$e.line}/><circle r="5" fill="var(--_l)"${$e.shape}/>`;break;case 4:U=`<polygon points="0,${o(-K/2)} ${o(W/2)},0 0,${o(K/2)} ${o(-W/2)},0"${_o}${$e.shape}/>`;break;case 5:case 6:U=Mi(-W/2,-K/2,W,K,` rx="2" fill="var(--_l)"${$e.shape}`);break;case 7:{let fe=o(W/2),we=o(K/2),Ee=o(W/2-Eo),Ae=o(Eo-K/2);U=`<path d="M-${fe},-${we}H${Ee}L${fe},${Ae}V${we}H-${fe}Z" fill="var(--_bg)" stroke="var(--_b)"/><path d="M${Ee},-${we}V${Ae}H${fe}"${vi}/>`+Ne(j.label,0,0,` class="pele-label" font-size="${s}" fill="var(--_m)"`,p);break}default:{if(U=Mi(-W/2,-K/2,W,K,` rx="${o(Math.min(el,K/2))}"${_o}${$e.shape}`),j.kind===0){U+=Ne(j.label,0,0,N,p);break}let fe=Co-K/2+j.label.height;U+=`<path d="M${o(-W/2)},${o(fe+6)}H${o(W/2)}"${vi}${$e.line}/>`+Ne(j.label,0,fe-j.label.height/2,N,p),fe+=14;for(let we of j.lines)U+=Ne(we,0,fe+we.height/2,` class="pele-state-description" font-size="${s}"${$e.text}`,p),fe+=we.height}}let J=e.links.get(oe.id);if(J){let fe=nt(Io(J.tooltip));fe&&(U=`<title>${Be(fe)}</title>`+U),U=cr(U,br(Io(J.url)),oe.id,ee,r,' target="_blank"')}let le=`<g class="${up[j.kind]}${Mt(oe.cssClasses.replace(hp,""))}" data-id="${Oe(oe.id)}"`;j.kind===8?de+=`${le}>${U}</g>`:j.kind===7?me+=`${le} transform="translate(${o(Te)},${o(pe)})">${U}</g>`:xe+=`${le} transform="translate(${o(Te)},${o(pe)})">${U}</g>`}let O=(X,j,oe)=>{let $e=D[oe];if($e.isGroup)return;let ge=T[oe],Te=ge.kind===5||ge.kind===6,pe=j===0?3:j-3;for(let W of[1,0]){let K=W?$e.h:$e.w,N=W?ge.h:ge.w,U=W?ge.w:ge.h,J=(W?$e.y:$e.x)+c,le=(W?$e.x:$e.y)+c,fe=X[j+W]-J;if(!(Math.abs(Math.abs(fe)-K/2)>=.5)){X[j+W]-=Math.sign(fe)*(K-N)/2,Te&&U>N&&(X[j+1-W]=No(X[pe+1-W],le-U/2+6,le+U/2-6));return}}},B=ci();for(let X=0;X<H.length;X++){let j=H[X];j.src===j.dst||j.route.length<6||P[X].pattern==="dashed"||B.add(j.dst,Lt(j.route,j.route.length-3,D[j.dst]),"arrow_point")}let Q="",se="",ie=new Int32Array(F),re=new Float64Array(F);for(let X=0;X<H.length;X++){let j=H[X],oe=P[X],$e=R[X],ge=oe.pattern==="dashed",Te=ge?"none":"arrow_point",pe;if(j.src===j.dst){let W=D[j.src],K=T[j.src],N=ie[j.src]++,U=m(j.src),J=W.isGroup?W.w:K.w,le=W.isGroup?W.h:K.h,fe=(U?J:le)/2,we=Math.max(Math.min((U?le:J)/2-4,8+N*6),2),Ee=Js+N*8,Ae=Nt(Te)/(Math.hypot(Ee,we)||1),De=(ce,be)=>W.x+c+(U?fe+ce:-be),Ie=(ce,be)=>W.y+c+(U?be:fe+ce),ye=(ce,be)=>`${o(De(ce,be))},${o(Ie(ce,be))}`;pe={d:`M${ye(0,-we)}C${ye(Ee,-2*we)} ${ye(Ee,2*we)} ${ye(Ee*Ae,we+we*Ae)}`,sx:0,sy:0,sdx:0,sdy:0,ex:De(0,we),ey:Ie(0,we),edx:De(-Ee,-we)-De(0,0),edy:Ie(-Ee,-we)-Ie(0,0)};let Me=Math.hypot(pe.edx,pe.edy)||1;pe.edx/=Me,pe.edy/=Me;let Se=Js+(w[j.src]-1)*8,q=re[j.src]+$e.height/2;re[j.src]+=$e.height,j.labelX=U?W.x+fe+Se+4+j.labelW/2:W.x,j.labelY=U?W.y-M[j.src]/2+q:W.y+fe+Se*.75+4+q}else{let W=j.route.slice(),K=B.of(j.src,Lt(W,0,D[j.src])),N=B.of(j.dst,Lt(W,W.length-3,D[j.dst]));for(let J=0;J<W.length;J+=3)W[J]+=c,W[J+1]+=c;O(W,0,j.src),O(W,W.length-3,j.dst);let U=f.get(X);if(U!==void 0&&W.length>=6){let J=D[U],le=T[j.src].kind===10,fe=le?0:W.length-3,we=(J.dir==="TB"||J.dir==="LR")===le,Ee=Do(J.dir)?[W[fe],J.y+c+(we?T[U].titleH-J.h/2:J.h/2),0]:[J.x+c+(we?-J.w/2:J.w/2),W[fe+1],1];W=le?Ee.concat(W):W.concat(Ee)}pe=lr(W,void 0,0,Nt(Te),K,N)}if(Q+=`<g class="pele-edge ${ge?'pele-note-edge" stroke="var(--_b)" stroke-dasharray="3 4':"pele-transition"}" data-id="${Oe(oe.id)}"><path d="${pe.d}"/>`+St(Te,pe.ex,pe.ey,pe.edx,pe.edy,"var(--_l)")+"</g>",$e.width>0){let W=j.labelX+c,K=j.labelY+c;se+=nr(oe.id,$e,W,K,"",p)}}let ne=bi(e.title,a,l,c,v,G,(de?`<g class="pele-clusters">${de}</g>`:"")+(te?`<g class="pele-dividers" stroke-dasharray="4 4"${vi}>${te}</g>`:"")+(Q?`<g class="pele-edges" fill="none" stroke="var(--_l)" stroke-linecap="round">${Q}</g>`:"")+(se?`<g class="pele-edge-labels" font-size="${s}">${se}</g>`:"")+`<g class="pele-nodes">${xe}${me}</g>`);return{svg:Je("state",ne.width,ne.height,l,r,e,ne.content),width:ne.width,height:ne.height,links:ee}}function gp(e,t,r){let i=r.get(Math.round(e.y-e.h/2));if(i===void 0||t===0)return e.x;let n=e.x-e.w/2,l=t/2,s=e.x,a=-1;for(let d of[e.x,n+Jr+l,n+e.w-Jr-l]){let c=1/0;for(let p of i)p>n&&p<n+e.w&&(c=Math.min(c,Math.abs(p-d)-l));if(c>=6)return d;c>a+.5&&(a=c,s=d)}return s}var rl={type:"state",parse(e,t,r){let i=new Zu;return r&&(i.title=r),sp(e,i),i},render:pp};function al(e){let t=0;for(let r=e.indexOf("~");r!==-1;r=e.indexOf("~",r+1))t++;return t}function mp(e){let t=al(e);if(t<=1)return e;let r=t%2!==0&&e.startsWith("~"),i=e.split(""),n=[];for(let l=r?1:0;l<i.length;l++)i[l]==="~"&&n.push(l);for(let l=0,s=n.length-1;l<s;l++,s--)i[n[l]]="<",i[n[s]]=">";return i.join("")}function Er(e){if(!e.includes("~"))return e;let t=e.split(/(,)/),r=[];for(let i=0;i<t.length;i++){let n=t[i];n===","&&i>0&&i+1<t.length&&al(t[i-1])===1&&al(t[i+1])===1&&(n=t[i-1]+","+t[i+1],i++,r.pop()),r.push(mp(n))}return r.join("")}function Oo(e){return e==="#"||e==="+"||e==="~"||e==="-"}var Ro=class{id="";memberType;visibility="";classifier="";parameters="";returnType="";constructor(e,t){this.memberType=t,(t!=="method"||!this.parseMethod(e))&&this.parseAttribute(e),this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim()}parseMethod(e){let t=e.length;for(let r=0;r<t;){let i=r;for(;i<t&&!ha(e.charCodeAt(i));)i++;let n=i-1;for(;n>r&&e.charCodeAt(n)!==41;)n--;let l=n-1;for(;l>r&&e.charCodeAt(l)!==40;)l--;if(l>r){let s=e[r],a=Oo(s)&&l>r+1;a&&(this.visibility=s),this.id=e.slice(a?r+1:r,l),this.parameters=e.slice(l+1,n).trim();let d=n+1,c="";if(d<t){let u=e[d];(u==="$"||u==="*"||u.trim()==="")&&(c=u.trim(),d++)}let p=d;for(;p<t&&!ha(e.charCodeAt(p));)p++;if(this.returnType=e.slice(d,p).trim(),c===""){let u=this.returnType.slice(-1);(u==="$"||u==="*")&&(c=u,this.returnType=this.returnType.slice(0,-1))}return this.classifier=c,!0}r=i+1}return this.memberType="attribute",!1}parseAttribute(e){let t=e.slice(0,1),r=e.slice(-1);Oo(t)&&(this.visibility=t),(r==="$"||r==="*")&&(this.classifier=r),this.id=e.substring(this.visibility===""?0:1,this.classifier===""?e.length:e.length-1)}getDisplayDetails(){let e=this.visibility+Er(this.id);return this.memberType==="method"&&(e+=`(${Er(this.parameters.trim())})`,this.returnType&&(e+=" : "+Er(this.returnType))),{displayText:e.trim(),cssStyle:this.parseClassifier()}}parseClassifier(){return this.classifier==="*"?"font-style:italic;":this.classifier==="$"?"text-decoration:underline;":""}},yp={LINE:0,DOTTED_LINE:1},Ea={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},$p="classId-";function hr(e){let t=e.indexOf("~");if(t<=0)return{className:e,type:""};let r=e.indexOf("~",t+1);return{className:e.slice(0,t),type:e.slice(t+1,r===-1?e.length:r)}}function zo(e){let t=e.charCodeAt(0);return hr(t>=48&&t<=57?$p+e:e).className}var wp=class{type="class";lineType=yp;relationType=Ea;direction="TB";classes=new Map;relations=[];notes=new Map;namespaces=new Map;interfaces=[];styleClasses=new Map;title;accTitle;accDescr;namespaceStack=[];withCssClass=new Map;addClass(e){let{className:t,type:r}=hr(e);if(this.classes.has(t))return;let i={id:t,type:r,label:t,cssClasses:"default",methods:[],members:[],annotations:[],styles:[]};this.classes.set(t,i),this.tag(i,"default")}tag(e,t){let r=this.withCssClass.get(t);r?r.add(e):this.withCssClass.set(t,new Set([e]))}ensure(e){return this.addClass(e),this.classes.get(hr(e).className)}setClassLabel(e,t){this.ensure(e).label=t}addRelation(e){let{type1:t,type2:r}=e.relation;t===Ea.LOLLIPOP&&r==="none"?(this.addClass(e.id2),e.id1=this.addInterface(e.id1,e.id2)):r===Ea.LOLLIPOP&&t==="none"?(this.addClass(e.id1),e.id2=this.addInterface(e.id2,e.id1)):(this.addClass(e.id1),this.addClass(e.id2)),e.id1=hr(e.id1).className,e.id2=hr(e.id2).className,e.relationTitle1=e.relationTitle1.trim(),e.relationTitle2=e.relationTitle2.trim(),this.relations.push(e)}addInterface(e,t){let r=`interface${this.interfaces.length}`;return this.interfaces.push({id:r,label:e,classId:t}),r}addAnnotation(e,t){this.ensure(e).annotations.push(t)}addMember(e,t){let r=this.ensure(e);if(typeof t!="string")return;let i=t.trim();if(i.startsWith("<<")&&i.endsWith(">>"))r.annotations.push(i.substring(2,i.length-2));else if(i.indexOf(")")>0){let n=new Ro(i,"method");(n.memberType==="method"?r.methods:r.members).push(n)}else i&&r.members.push(new Ro(i,"attribute"))}addMembers(e,t){if(Array.isArray(t)){t.reverse();for(let r of t)this.addMember(e,r)}}addNote(e,t){let r=this.notes.size,i=`note${r}`;return this.notes.set(i,{id:i,class:t,text:e,index:r}),i}cleanupLabel(e){return(e.startsWith(":")?e.substring(1):e).trim()}setCssClass(e,t){for(let r of e.split(",")){let i=this.classes.get(zo(r));if(i!==void 0){i.cssClasses+=" "+t;for(let n of t.split(" "))this.tag(i,n)}}}defineClass(e,t){for(let r of e){let i=this.styleClasses.get(r);if(i===void 0&&(i={id:r,styles:[],textStyles:[]},this.styleClasses.set(r,i)),!t)continue;for(let s of t)s.includes("color")&&i.textStyles.push(s.replace("fill","bgFill")),i.styles.push(s);let n=this.withCssClass.get(r);if(n===void 0)continue;let l=t.flatMap(s=>s.split(","));for(let s of n)for(let a of l)s.styles.push(a)}}setTooltip(e,t){if(t!==void 0)for(let r of e.split(",")){let i=this.classes.get(hr(r).className);i&&(i.tooltip=t)}}setLink(e,t,r){let i=nt(t).trim();for(let n of e.split(",")){let l=this.classes.get(zo(n));l&&(l.link=i?xr(i):void 0,l.linkTarget=typeof r=="string"?r:"_blank")}this.setCssClass(e,"clickable")}setClickEvent(e,t,r){for(let i of e.split(",")){let n=this.classes.get(hr(i).className);n&&(n.haveCallback=!0)}this.setCssClass(e,"clickable")}setDirection(e){this.direction=e}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
68`)}addNamespace(e,t){let r=this.namespaceStack[this.namespaceStack.length-1],i=r?`${r}.${e}`:e;this.namespaceStack.push(i);let n=this.namespaces.get(i);if(n)return n.explicit=!0,t&&(n.label=t),i;let l=r||void 0,s=r?r.length+1:0;for(;;){let a=i.indexOf(".",s),d=a===-1,c=d?i:i.slice(0,a),p=this.namespaces.get(c);if(p===void 0){let h=i.slice(s,d?i.length:a);p={id:c,label:d&&t?t:h,classes:new Map,notes:new Map,children:new Map,parent:l,explicit:d},this.namespaces.set(c,p)}else d&&(p.explicit=!0);let u=l?this.namespaces.get(l):void 0;if(u&&(u.children.has(c)||u.children.set(c,p),p.parent??=l),d)return i;l=c,s=a+1}}popNamespace(){this.namespaceStack.pop()}addClassesToNamespace(e,t,r){let i=this.namespaces.get(e);if(i!==void 0){for(let n of t){let{className:l}=hr(n),s=this.classes.get(l);s!==void 0&&(s.parent=e,i.classes.set(l,s))}for(let n of r){let l=this.notes.get(n);l!==void 0&&(l.parent=e,i.notes.set(n,l))}}}setCssStyle(e,t){let r=this.classes.get(e);if(!(!t||!r))for(let i of t)for(let n of i.split(","))r.styles.push(n)}},Fo=["$end","INVALID","CLASS_DIAGRAM","NEWLINE","EOF","SQS","STR","SQE","DOT","GENERICTYPE","LABEL","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","STRUCT_START","STRUCT_STOP","NAMESPACE","STYLE_SEPARATOR","ANNOTATION_START","ANNOTATION_END","CLASS","MEMBER","NOTE_FOR","NOTE","CLASSDEF","ALPHA","COMMA","direction_tb","direction_bt","direction_rl","direction_lr","AGGREGATION","EXTENSION","COMPOSITION","DEPENDENCY","LOLLIPOP","LINE","DOTTED_LINE","CALLBACK","LINK","LINK_TARGET","CLICK","CALLBACK_NAME","CALLBACK_ARGS","HREF","STYLE","CSSCLASS","COLON","BRKT","PCT","MINUS","UNICODE_TEXT","BQUOTE_STR","EDGE_STATE","EOF_IN_STRUCT","OPEN_IN_STRUCT","PLUS","EQUALS","PUNCTUATION"],xp=[4,6,4,9,44,45,12,14,15,4,56,4,56],bp=[/.*direction\s+TB[^\n]*/y,/.*direction\s+BT[^\n]*/y,/.*direction\s+RL[^\n]*/y,/.*direction\s+LR[^\n]*/y],il=/[\n\r\u2028\u2029]/g;function kp(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=e.indexOf("direction"),c=-1,p=0,u=(m,y,C)=>(r.push(m),i.push(e.slice(y,C)),n.push(y),a=C,!0),h=m=>{l.push(s),s=m},$=()=>{l.length>0&&(s=l.pop())},g=m=>e.startsWith(m,a)&&!Pe(e.charCodeAt(a+m.length)),T=m=>{for(;m<t&&Le(e.charCodeAt(m));)m++;return m},D=m=>{let y=e.indexOf(m,a);return y===-1?t:y},_=m=>{let y=a,C=-1;for(let L=e.charCodeAt(y);y<t&&Le(L);L=e.charCodeAt(++y))L===10&&(C=y);if(C<0){a=y;return}m&&$(),u(3,a,C+1)},F=m=>{switch(m){case 99:if(g("cssClass"))return u(48,a,a+8);if(g("callback"))return u(40,a,a+8);if(g("click"))return u(43,a,a+5);break;case 108:if(g("link"))return u(41,a,a+4);break;case 110:if(g("note for"))return u(24,a,a+8);if(g("note"))return u(25,a,a+4);break;case 60:if(e.charCodeAt(a+1)===60)return u(20,a,a+2);break;case 62:if(e.charCodeAt(a+1)===62)return u(21,a,a+2);break;case 104:if(g("href"))return u(46,a,a+4);break}return!1},k=m=>{if(F(m))return!0;let y=e.charCodeAt(a+1);switch(m){case 34:return h(1),a++,!0;case 126:return h(3),a++,!0;case 96:return h(2),a++,!0;case 95:if(g("_self"))return u(42,a,a+5);if(g("_blank"))return u(42,a,a+6);if(g("_parent"))return u(42,a,a+7);if(g("_top"))return u(42,a,a+4);break;case 60:return y===124?u(34,a,a+2):u(36,a,a+1);case 124:return y===62&&u(34,a,a+2);case 62:return u(36,a,a+1);case 42:return u(35,a,a+1);case 111:if(!Pe(y))return u(33,a,a+1);break;case 40:return y===41&&u(37,a,a+2);case 45:return y===45?u(38,a,a+2):u(52,a,a+1);case 46:return y===46?u(39,a,a+2):u(8,a,a+1);case 58:{let C=a+1;for(;C<t;){let L=e.charCodeAt(C);if(L===58||L===10||L===59)break;C++}return C>a+1?u(10,a,C):y===58&&e.charCodeAt(a+2)===58&&u(19,a,a+3)}case 43:return u(58,a,a+1);case 37:return u(51,a,a+1);case 61:return u(59,a,a+1);case 91:return u(5,a,a+1);case 93:return u(7,a,a+1);case 33:case 35:case 36:case 38:case 39:case 44:case 63:case 92:case 47:return u(60,a,a+1)}if(Pe(m)){let C=a+1;for(;Pe(e.charCodeAt(C));)C++;return u(27,a,C)}return ti(m)&&u(53,a,a+1)},I=()=>{if(d===-1||a<p||(d<a&&(d=e.indexOf("direction",a)),d===-1)||(c<a&&(il.lastIndex=a,c=il.test(e)?il.lastIndex-1:t),d>=c))return!1;for(let m=0;m<4;m++){let y=bp[m];if(y.lastIndex=a,y.test(e))return u(29+m,a,y.lastIndex)}return p=c,!1},E=m=>{if(I())return!0;if(Le(m))return _(!1),!0;switch(m){case 37:if(e.charCodeAt(a+1)===37){let y=D(`
69`);for(;y<t&&(e.charCodeAt(y)===10||e.charCodeAt(y)===13);)y++;return a=y,!0}break;case 97:{let y=e.startsWith("accTitle",a);if(!y&&!e.startsWith("accDescr",a))break;let C=T(a+8),L=e.charCodeAt(C);if(L===58)return u(y?11:13,a,T(C+1)),h(y?6:7),!0;if(L===123&&!y)return a=T(C+1),h(8),!0;break}case 99:if(g("classDiagram-v2"))return u(2,a,a+15);if(g("classDiagram"))return u(2,a,a+12);if(e.startsWith("call",a)&&Le(e.charCodeAt(a+4)))return a=T(a+4),h(4),!0;if(g("classDef"))return u(26,a,a+8);if(g("class"))return h(9),u(22,a,a+5);break;case 91:if(e.startsWith("*]",a+1))return u(55,a,a+3);break;case 115:if(g("style"))return u(47,a,a+5);break;case 110:if(g("namespace"))return h(11),u(18,a,a+9);break;case 44:return u(28,a,a+1);case 35:return u(50,a,a+1)}return k(m)||m===58&&u(49,a,a+1)};for(;;){if(a>=t){r.push(xp[s]),i.push(""),n.push(t);break}let m=e.charCodeAt(a),y=!0;switch(s){case 0:y=E(m);break;case 9:Le(m)?_(!0):m===125?($(),$(),u(17,a,a+1)):m===123?(h(10),u(16,a,a+1)):y=k(m);break;case 10:if(m===34)h(1),a++;else if(m===125)$(),u(17,a,a+1);else if(m===91&&e.startsWith("*]",a+1))u(55,a,a+3);else if(m===123)u(57,a,a+1);else if(m===10)a++;else{let C=a+1;for(;C<t;){let L=e.charCodeAt(C);if(L===123||L===125||L===10)break;C++}u(23,a,C)}break;case 11:Le(m)?_(!0):m===123?(h(12),u(16,a,a+1)):m===125?$():m===110&&g("namespace")?(h(11),u(18,a,a+9)):y=k(m);break;case 12:Le(m)?_(!1):m===125?($(),u(17,a,a+1)):m===110&&g("namespace")?(h(11),u(18,a,a+9)):m===91&&e.startsWith("*]",a+1)?u(55,a,a+3):m===99&&g("class")?(h(9),u(22,a,a+5)):y=k(m);break;case 1:m===34?($(),a++):u(6,a,D('"'));break;case 3:if(m===34)h(1),a++;else{if(F(m))break;m===126?($(),a++):u(9,a,D("~"))}break;case 2:if(m===34)h(1),a++;else{if(F(m))break;m===126?(h(3),a++):m===96?($(),a++):u(54,a,D("`"))}break;case 4:if(m===40){let C=T(a+1);$(),e.charCodeAt(C)===41?a=C+1:(h(5),a++)}else u(44,a,D("("));break;case 5:m===41?($(),a++):u(45,a,D(")"));break;case 6:case 7:u(s===6?12:14,a,D(`
70`)),$();break;case 8:m===125?($(),a++):u(15,a,D("}"));break}if(!y)return r.push(1),i.push(""),n.push(a),{types:r,texts:i,starts:n}}return r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n}}var cl=61,_i=new Uint8Array(cl);for(let e of[53,27,52])_i[e]=1;var nl=new Uint8Array(cl);for(let e of[27,49,50,47,51,10])nl[e]=1;var _r=new Uint8Array(cl);_r[33]=1;_r[34]=2;_r[35]=3;_r[36]=4;_r[37]=5;var vp="'UNICODE_TEXT', 'NUM', 'ALPHA', 'MINUS', 'BQUOTE_STR'";function Mp(e,t){let{types:r,texts:i,starts:n}=kp(e),l=0,s=m=>{let y=r[l];throw y===1?Ve("class",e,n[l],"",!0):Ve("class",e,n[l],`Expecting ${m}, got '${Fo[y]}'`)},a=m=>(r[l]!==m&&s(`'${Fo[m]}'`),i[l++]),d=()=>(_i[r[l]]===0&&s("'UNICODE_TEXT', 'NUM', 'ALPHA', 'MINUS'"),i[l++]),c=m=>{let y="";for(;;){if(r[l]===54){y+=i[l++];break}_i[r[l]]===0&&s(vp),y+=i[l++];let C=r[l];if(C===8)y+=".",l++;else if(_i[C]===0&&C!==54)break}return m&&r[l]===9&&(y+="~"+i[l++]+"~"),y},p=()=>{l++;let m=a(6);return a(7),m},u=()=>{r[l]!==23&&s("'STRUCT_STOP', 'MEMBER'");let m=[];for(;r[l]===23;)m.push(i[l++]);return a(17),m.reverse()},h=()=>{l++;let m=c(!0);switch(t.addClass(m),r[l]===5&&t.setClassLabel(m,p()),r[l]){case 19:{l++;let y=d();t.setCssClass(m,y),r[l]===16&&(l++,t.addMembers(m,u()));break}case 16:l++,r[l]===17?l++:t.addMembers(m,u());break;case 20:{l++;let y=d();a(21),t.addAnnotation(m,y),r[l]===16&&(l++,r[l]===17?l++:t.addMembers(m,u()));break}}return m},$=()=>{if(r[l++]===25)return t.addNote(a(6));let m=c(!0);return t.addNote(a(6),m)},g=()=>{let m=[];for(;;){l++;let y=c(!1),C=r[l]===5?t.addNamespace(y,p()):t.addNamespace(y);a(16),r[l]===3&&l++,m.push({id:C,classes:[],notes:[]});let L=!0;for(;L;){let S=m[m.length-1],Z=r[l];if(Z===18)break;for(Z===22?S.classes.push(h()):Z===25||Z===24?S.notes.push($()):s("'NAMESPACE', 'CLASS', 'NOTE_FOR', 'NOTE'");;){if(r[l]===3){let R=r[l+1];if(R===18||R===22||R===25||R===24){l++;break}l++}a(17);let H=m.pop();if(t.addClassesToNamespace(H.id,H.classes,H.notes),t.popNamespace(),m.length===0){L=!1;break}}}if(m.length===0)return}},T=()=>{let m=_r[r[l]];return m===0?"none":(l++,m-1)},D=()=>{let m=c(!0),y=r[l];if(y===10){t.addMember(m,t.cleanupLabel(i[l++]));return}let C="none";if(y===6)C=i[l++],y=r[l];else if(_r[y]===0&&y!==38&&y!==39)return;let L=T();y=r[l],y!==38&&y!==39&&s("'AGGREGATION', 'EXTENSION', 'COMPOSITION', 'DEPENDENCY', 'LOLLIPOP', 'LINE', 'DOTTED_LINE'"),l++;let S=T(),Z=r[l]===6?i[l++]:"none",H=c(!0),R={id1:m,id2:H,relation:{type1:L,type2:S,lineType:y===38?0:1},relationTitle1:C,relationTitle2:Z};r[l]===10&&(R.title=t.cleanupLabel(i[l++])),t.addRelation(R)},_=()=>{let m=[];for(;;){nl[r[l]]===0&&s("'ALPHA', 'NUM', 'COLON', 'UNIT', 'SPACE', 'BRKT', 'STYLE', 'PCT', 'LABEL'");let y=i[l++];for(;nl[r[l]]===1;)y+=i[l++];if(m.push(y),r[l]!==28)return m;l++}},F=m=>{r[l]===6&&t.setTooltip(m,i[l++])},k=m=>{let y=a(6),C=r[l]===6?i[l++]:void 0;r[l]===42?t.setLink(m,y,i[l++]):t.setLink(m,y),C!==void 0&&t.setTooltip(m,C)},I=()=>{let m=r[l];switch(m){case 53:case 27:case 52:case 54:D();return;case 18:g();return;case 22:h();return;case 23:l++;return;case 20:{l++;let y=d();a(21),t.addAnnotation(c(!0),y);return}case 40:{l++;let y=c(!0);t.setClickEvent(y,a(6)),F(y);return}case 41:l++,k(c(!0));return;case 43:{l++;let y=c(!0);if(r[l]===46){l++,k(y);return}let C=a(44);r[l]===45?t.setClickEvent(y,C,i[l++]):t.setClickEvent(y,C),F(y);return}case 47:{l++;let y=a(27);t.setCssStyle(y,_());return}case 48:{l++;let y=a(6);t.setCssClass(y,a(27));return}case 25:case 24:$();return;case 26:{l++;let y=[a(27)];for(;r[l]===28;)l++,y.push(a(27));t.defineClass(y,_());return}case 29:case 30:case 31:case 32:l++,t.setDirection(m===29?"TB":m===30?"BT":m===31?"RL":"LR");return;case 11:l++,t.setAccTitle(a(12).trim());return;case 13:l++,t.setAccDescription(a(14).trim());return;case 15:t.setAccDescription(i[l++].trim());return}s("'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'NAMESPACE', 'ANNOTATION_START', 'CLASS', 'MEMBER', 'NOTE_FOR', 'NOTE', 'CLASSDEF', 'direction_tb', 'CALLBACK', 'LINK', 'CLICK', 'STYLE', 'CSSCLASS', 'ALPHA', 'MINUS', 'BQUOTE_STR'")},E=r[l]===2;for(E&&(l++,a(3));I(),!(r[l]!==3||(l++,r[l]===4||r[l]===0)););E&&a(4),a(0)}var Ap=["aggregation","extension","composition","dependency","lollipop"];function Wo(e){return typeof e=="number"&&Ap[e]||"none"}function Tp(e,t=!0){let r=[],i=[],n=new Map,l=new Map,s=new Map,a=new Map,d=h=>{if(t||h===void 0)return h;let $=[],g=h,T;for(;g;){if(a.has(g)){T=a.get(g);break}let D=e.namespaces.get(g);if(D===void 0)break;if(D.explicit){T=g;break}$.push(g),g=D.parent}for(let D of $)a.set(D,T);return T},c=h=>h===void 0?-1:n.get(h)??-1;for(let h of e.namespaces.values())!t&&!h.explicit||(n.set(h.id,r.length),r.push({id:h.id,label:t?h.label:h.id,isGroup:!0,shape:"rect",parentId:t?h.parent:void 0,parent:-1}));for(let h of r)h.parent=c(h.parentId);let p=0;for(let h of e.classes.values()){let $=d(h.parent);l.set(h.id,r.length),r.push({id:h.id,label:h.label,isGroup:!1,shape:"classBox",parentId:$,parent:c($),classNode:h,colorIndex:p++})}for(let h of e.notes.values()){let $=d(h.parent),g=h.class===void 0?void 0:l.get(h.class);g!==void 0&&i.push({id:`edgeNote${h.index}`,start:h.id,end:r[g].id,source:r.length,target:g,label:void 0,arrowTypeStart:"none",arrowTypeEnd:"none",startLabelRight:"",endLabelLeft:"",pattern:"dotted",classes:"relation"}),r.push({id:h.id,label:h.text,isGroup:!1,shape:"note",parentId:$,parent:c($)})}for(let h of e.interfaces){let $=l.get(h.classId);s.set(h.id,r.length),r.push({id:h.id,label:h.label,isGroup:!1,shape:"interface",parentId:void 0,parent:$===void 0?-1:r[$].parent})}let u=0;for(let h of e.relations){u++;let{type1:$,type2:g}=h.relation,T=$===Ea.LOLLIPOP&&g==="none"?s:l,D=T===l&&g===Ea.LOLLIPOP&&$==="none"?s:l;i.push({id:`id_${h.id1}_${h.id2}_${u}`,start:h.id1,end:h.id2,source:T.get(h.id1)??-1,target:D.get(h.id2)??-1,label:h.title,arrowTypeStart:Wo($),arrowTypeEnd:Wo(g),startLabelRight:h.relationTitle1==="none"?"":h.relationTitle1,endLabelLeft:h.relationTitle2==="none"?"":h.relationTitle2,pattern:h.relation.lineType===1?"dashed":"solid",classes:"relation"})}return{nodes:r,edges:i}}var ol=12,Ca=16,Ta=6,Di=5;function Po(e){switch(e){case"extension":return ol;case"composition":case"aggregation":return Ca;case"lollipop":return 2*Di;case"dependency":return Nt("arrow_point")}return 0}function Ho(e,t,r,i,n,l){let s=-n,a=i;switch(e){case"extension":{let d=t-i*ol,c=r-n*ol;return`<path class="pele-marker" d="M${o(t)},${o(r)}L${o(d+s*Ta)},${o(c+a*Ta)}L${o(d-s*Ta)},${o(c-a*Ta)}Z" stroke-linejoin="round"/>`}case"composition":case"aggregation":{let d=t-i*Ca/2,c=r-n*Ca/2,p=Ta-1;return`<path class="pele-marker" d="M${o(t)},${o(r)}L${o(d+s*p)},${o(c+a*p)}L${o(t-i*Ca)},${o(r-n*Ca)}L${o(d-s*p)},${o(c-a*p)}Z" stroke-linejoin="round"${e==="composition"?` fill="${l}"`:""}/>`}case"lollipop":return`<circle class="pele-marker" cx="${o(t-i*Di)}" cy="${o(r-n*Di)}" r="${Di}"/>`;case"dependency":return St("arrow_point",t,r,i,n,l)}return""}var Cp=40,Ep=16,Yo=56,Sr=20,Go=26,sl=12,Ti=8,Bo=6,Sp=10,_p=64,Ci=8,ll="var(--_l)",Dp=new Set(["_self","_blank","_parent","_top"]);function Uo(e,t,r){let i=e[t];return typeof i=="number"&&i>0?Math.min(i,2e3):r}var Ei=[],Si=[];function qo(e,t,r){let i=nt(e.getDisplayDetails().displayText).trim();return{text:i,width:t.width(i,r,e.classifier==="*"?2:0),classifier:e.classifier}}function Ip(e,t,r){let i=n=>Vr(r,l=>Np(e,t,r,n,l));return dr(e.direction)?Ct(r,i):i(!1)}function Np(e,t,r,i,n){let l=t.class??{},s=Tp(e,l.hierarchicalNamespaces!==!1),a=l.hideEmptyMembersBox===!0,d=r.fontSize??16,c=Math.round(d*.875),p=Math.round(d*.8),u=Math.round(p*1.4),h=r.measurer??tt(r.fontFamily),$=r.padding??8,g=i?"TB":Ft(e.direction),T=new Map,D=new Map,_=new Map,F=W=>{let K=T.get(W);if(K===void 0){let N=ct([W]);K=N.shape===""&&N.text===""?"":W.slice(0,W.indexOf(":")).trim().toLowerCase(),T.set(W,K)}K!==""&&_.set(K,W)},k=W=>{_.clear();let K=D.get(W.cssClasses);if(K===void 0){for(let N of W.cssClasses.split(" ")){let U=e.styleClasses.get(N);if(U)for(let J of U.styles)for(let le of J.split(","))F(le)}K=[..._],D.set(W.cssClasses,K)}else for(let[N,U]of K)_.set(N,U);for(let N of W.styles)F(N);return ct(_.size===0?Si:[..._.values()])},I=new Int32Array(s.nodes.length);for(let W of s.nodes)W.parent>=0&&I[W.parent]++;let E=new Uint8Array(s.nodes.length);for(let W of s.edges){if(W.source<0||W.target<0)continue;let K=s.nodes[W.source].parent,N=s.nodes[W.target].parent;if(K!==N){for(let U=K;U>=0&&E[U]===0;U=s.nodes[U].parent)E[U]=1;for(let U=N;U>=0&&E[U]===0;U=s.nodes[U].parent)E[U]=1}}let m=[],y=[];s.nodes.forEach((W,K)=>{let N,U;if(W.isGroup){let J=Fe(W.label,!1,h,d,4e3);N=C(W,J,0,0,d),I[K]>0?(U=wt(0,0),U.isGroup=!0,U.padX=Sr,U.padTop=J.height>0?J.height+16:Sr,U.padBottom=Sr,U.minW=J.width+2*Sr-12+(E[K]===1&&!n?Math.min(J.width+24,240):0)):(N.w=Math.max(J.width+2*Sr,80),N.h=J.height+2*Sr,U=wt(N.w,N.h))}else if(W.classNode)N=L(W,W.classNode),U=wt(N.w,N.h);else if(W.shape==="note"){let J=Fe(W.label,!0,h,c,260);N=C(W,J,Math.max(J.width+2*sl,40),J.height+2*Ti,c),U=wt(N.w,N.h)}else{let J=Fe(W.label,!1,h,c,200);N=C(W,J,Math.max(J.width,12)+4,Math.max(J.height,12),c),U=wt(N.w,N.h)}U.parent=W.parent,U.seq=K,m.push(N),y.push(U)});function C(W,K,N,U,J){return{node:W,style:ct(Si),label:K,w:N,h:U,loops:0,annotations:Si,attributes:Ei,methods:Ei,titleH:0,attributesH:0,fontSize:J}}function L(W,K){let N=k(K),U=N.fontSize??d,J=Math.round(U*.875),le=Math.round(J*1.5),fe=K.type?"<"+Er(K.type).replace(/</g,"<").replace(/>/g,">")+">":"",we=Fe(K.label+fe,!1,h,U,4e3,1|(N.italic?2:0)),Ee=K.annotations.length>0?K.annotations.map(ce=>`\xAB${nt(ce).trim()}\xBB`):Si,Ae=K.members.length>0?K.members.map(ce=>qo(ce,h,J)):Ei,De=K.methods.length>0?K.methods.map(ce=>qo(ce,h,J)):Ei,Ie=we.width;for(let ce of Ee)Ie=Math.max(Ie,h.width(ce,p,0));for(let ce of Ae)Ie=Math.max(Ie,ce.width);for(let ce of De)Ie=Math.max(Ie,ce.width);let ye=!(a&&Ae.length===0&&De.length===0),Me=ce=>ye?ce>0?2*Bo+ce*le:Sp:0,Se=2*Ti+Ee.length*u+Math.max(we.height,Math.round(U*1.5)),q=Me(Ae.length);return{node:W,style:N,label:we,w:Math.max(Ie+2*sl,_p),h:Se+q+Me(De.length),loops:0,annotations:Ee,attributes:Ae,methods:De,titleH:Se,attributesH:q,fontSize:U}}let S=[],Z=[],H=[],R=[],P=[],w=new Float64Array(m.length*4),b=(W,K,N)=>{w[W*4+K]++,N>w[W*4+K+1]&&(w[W*4+K+1]=N)};for(let W of s.edges){if(W.source<0||W.target<0)continue;let K=Fe(W.label,!0,h,c,200),N=W.startLabelRight?h.width(nt(W.startLabelRight),p,0):0,U=W.endLabelLeft?h.width(nt(W.endLabelLeft),p,0):0;W.source===W.target?(m[W.source].loops++,y[W.source].w+=2*(Go+(K.width>0?K.width+12:0))):(b(W.source,0,N),b(W.target,2,U)),R.push(N),P.push(U),Z.push(W),H.push(K),S.push({src:W.source,dst:W.target,minlen:1,labelW:K.width>0?K.width+12:0,labelH:K.height>0?K.height+4:0,route:[],labelX:0,labelY:0})}if(g==="TB"||g==="BT")for(let W=0;W<m.length;W++){if(!m[W].node.classNode)continue;let K=0;for(let N=0;N<4;N+=2){let U=w[W*4+N],J=w[W*4+N+1];U>1&&(K=Math.max(K,(U-1)*(J>0?J+24:14)+24))}K=Math.min(K,480),K>m[W].w&&(y[W].w+=K-m[W].w,m[W].w=K)}let M=!1;for(let W=0;W<Z.length&&!M;W++)M=R[W]>0||P[W]>0;let f=or(y,S,g,{nodeSep:Uo(l,"nodeSpacing",Cp),edgeSep:Ep,rankSep:Uo(l,"rankSpacing",M?Yo+16:Yo),portSep:20,apart:!0}),x=new Map,A=[],z=(W,K,N,U,J)=>{let le=W.route,fe=y[N],we=Lt(le,K,fe);if(we<0)return;let Ee=(fe.w-m[N].w)/2;we===1?le[K]-=Ee:we===3&&(le[K]+=Ee);let Ae=we&1,De=le[(K===0?3:K-3)+Ae],Ie=De-le[K+Ae],ye={route:le,at:K,toward:De,order:J,room:U,side:we,after:Ae?Ie>0:Ie>=0},Me=N*4+we,Se=x.get(Me);return Se?Se.push(ye):x.set(Me,[ye]),ye},v=[],G=[];for(let W=0;W<S.length;W++){let K=S[W],N=K.src!==K.dst&&K.route.length>=6;v.push(N?z(K,0,K.src,R[W],W):void 0),G.push(N?z(K,K.route.length-3,K.dst,P[W],W):void 0)}let ee=(W,K,N)=>{for(let U=y[W].parent,J=0;U>=0&&J<1e4;U=y[U].parent,J++){let le=y[U],fe=Math.abs(K-le.x),we=Math.abs(N-le.y);if(Math.abs(we-le.h/2)<.5&&fe<=le.w/2+.5||Math.abs(fe-le.w/2)<.5&&we<=le.h/2+.5)return!0}return!1},he=[];for(let[W,K]of x){if(K.length<2)continue;let N=W>>2,U=W&1,J=U?m[N].h:m[N].w;K.sort((Ee,Ae)=>Ee.toward-Ae.toward||Ee.order-Ae.order);let le=0;for(let Ee=0;Ee+1<K.length;Ee++){let Ae=K[Ee],De=K[Ee+1],Ie=U?20:24;Ae.room>0&&Ae.after&&(Ie+=U?u+6:Ae.room),De.room>0&&!De.after&&(Ie+=U?u+6:De.room),he[Ee]=Ie,le+=Ie}let fe=Math.min(1,(J-24)/le);if(fe<=0)continue;let we=(U?y[N].y:y[N].x)-le*fe/2;for(let Ee=0;Ee<K.length;Ee++){let{route:Ae,at:De}=K[Ee],Ie=De===0?3:-3,ye=De+Ie,Me=-1;for(let Se=ye;Se>=0&&Se<Ae.length&&Math.abs(Ae[Se+U]-Ae[ye+U])<.5;Se+=Ie)if(ee(N,Ae[Se],Ae[Se+1])){Me=Se;break}if(Me>=0&&Math.abs(Ae[ye+U]-we)<=24)for(let Se=ye;Se!==Me+Ie;Se+=Ie)Ae[Se+U]=we;Ae[De+U]=we,we+=he[Ee]*fe}}let ue=(W,K,N,U)=>{if(K===void 0||N<=0)return;let J=K.side&1,le=U?0:W.length-3,fe=le+1-J,we=Math.abs(W[(U?3:le-3)+1-J]-W[fe]),Ee=Math.min(J?N+10:u+6,we*.35);if(Ee<4)return;let Ae=[W[le],W[le+1],W[le+2]];Ae[1-J]+=(K.side===0||K.side===3?-1:1)*Ee,W.splice(U?3:le,0,Ae[0],Ae[1],Ae[2])};for(let W=0;W<S.length;W++)ue(S[W].route,v[W],R[W],!0),ue(S[W].route,G[W],P[W],!1);let V=0,Y=0,de=f.width,te=f.height,xe=(W,K,N,U,J,le)=>{if(!W)return;let fe=N,we=U;J&1?(fe+=(J===3?-1:1)*(5+K/2),we+=(le?1:-1)*(7+u/2)):(fe+=(le?1:-1)*(9+K/2),we+=(J===0?-1:1)*(3+u/2)),A.push({text:nt(W),x:fe,y:we}),V=Math.min(V,fe-K/2),de=Math.max(de,fe+K/2),Y=Math.min(Y,we-u/2),te=Math.max(te,we+u/2)},me=new Map,ae=new Int32Array(S.length);for(let W=0;W<S.length;W++){let K=S[W],N=Z[W],U=K.route;if(K.src===K.dst){let J=me.get(K.src)??0;me.set(K.src,J+1),ae[W]=J;let le=y[K.src],fe=m[K.src],we=le.x+fe.w/2,Ee=Math.min(fe.h/2-4,8+J*6);xe(N.startLabelRight,R[W],we,le.y-Ee,1,!1),xe(N.endLabelLeft,P[W],we,le.y+Ee,1,!0)}else if(U.length>=6){let J=U.length-3,le=v[W],fe=G[W];xe(N.startLabelRight,R[W],U[0],U[1],le?le.side:2,le?le.after:!0),xe(N.endLabelLeft,P[W],U[J],U[J+1],fe?fe.side:0,fe?fe.after:!0)}}let O=$-V,B=$-Y,Q=Math.ceil(de-V+2*$),se=Math.ceil(te-Y+2*$),ie=[],re=new Map;if(s.nodes.length>0&&s.nodes[0].isGroup)for(let W of S)Yr(re,W.route);let ne="",X="",j="";for(let W=0;W<m.length;W++){let K=m[W],N=y[W],U=K.node,J=N.x+O,le=N.y+B,fe=Oe(U.id),we=N.isGroup?N.w:K.w,Ee=N.isGroup?N.h:K.h;if(U.isGroup){let De=N.isGroup?Gr(N,K.label.width,re,Sr):N.x,Ie=le-Ee/2+8+K.label.height/2,ye=' class="pele-cluster-label" fill="var(--_m)"',Me=N.isGroup&&ai(N,K.label.width,De,re);Me&&(X+=ii(K.label,De+O,Ie,ye,fe,s.nodes,W)),ne+=`<g class="pele-cluster pele-namespace" data-id="${fe}"><rect x="${o(J-we/2)}" y="${o(le-Ee/2)}" width="${o(we)}" height="${o(Ee)}" rx="${Ke}" fill="var(--_a)" fill-opacity="0.5" stroke="var(--_b)"/>`+(Me?"":Ne(K.label,De+O,Ie,ye))+"</g>";continue}let Ae=` transform="translate(${o(J)},${o(le)})"`;if(U.classNode)j+=oe(K,U.classNode,fe,Ae);else if(U.shape==="note"){let De=we/2,Ie=-Ee/2;j+=`<g class="pele-node pele-note" data-id="${fe}"${Ae}><path d="M${o(-De)},${o(Ie)}H${o(De-Ci)}L${o(De)},${o(Ie+Ci)}V${o(-Ie)}H${o(-De)}Z" fill="var(--_a)" stroke="var(--_b)" stroke-linejoin="round"/><path d="M${o(De-Ci)},${o(Ie)}V${o(Ie+Ci)}H${o(De)}" fill="none" stroke="var(--_b)" stroke-linejoin="round"/>`+Ne(K.label,0,0,` class="pele-label" font-size="${c}"`,r.icons)+"</g>"}else j+=`<g class="pele-node pele-interface" data-id="${fe}"${Ae}>`+Ne(K.label,0,0,` class="pele-label" font-size="${c}"`,r.icons)+"</g>"}function oe(W,K,N,U){let{w:J,h:le,style:fe}=W,we=-J/2,Ee=-le/2,Ae=Math.round(W.fontSize*.875),De=Math.round(Ae*1.5),Ie=`<rect x="${o(we)}" y="${o(Ee)}" width="${o(J)}" height="${o(le)}" rx="${Ke}" fill="var(--_s)" stroke="var(--_b)"${fe.shape}/>`,ye=Ee+W.titleH,Me=ye+W.attributesH;if(le>W.titleH){let be=fe.stroke?` style="stroke:${Be(fe.stroke)}"`:"";Ie+=`<path class="pele-divider" d="M${o(we)},${o(ye)}H${o(-we)}M${o(we)},${o(Me)}H${o(-we)}" fill="none" stroke="var(--_b)"${be}/>`}let Se=Ee+Ti;for(let be of W.annotations)Ie+=`<text class="pele-annotation" x="0" y="${o(Se+u/2+p*.35)}" text-anchor="middle" font-size="${p}" fill="var(--_m)">${Be(be)}</text>`,Se+=u;let q=W.fontSize===d?"":` font-size="${o(W.fontSize)}"`;Ie+=Ne(W.label,0,(Se+ye-Ti)/2,` class="pele-label"${q} font-weight="var(--_hw)"${fe.text}`,r.icons);let ce=(be,Ce,ve)=>{let ke="",Re=ve+Bo+De/2+Ae*.35;for(let ze of be){let We=ze.classifier==="$"?` pele-static"${fe.text?fe.text.slice(0,-1)+'text-decoration:underline"':' style="text-decoration:underline"'}`:ze.classifier==="*"?` pele-abstract" font-style="italic"${fe.text}`:`"${fe.text}`;ke+=`<text class="pele-member pele-${Ce}${We} x="${o(we+sl)}" y="${o(Re)}">${Be(ze.text)}</text>`,Re+=De}return ke};return(W.attributes.length>0||W.methods.length>0)&&(Ie+=`<g class="pele-members" font-size="${Ae}">${ce(W.attributes,"attribute",ye)}${ce(W.methods,"method",Me)}</g>`),K.tooltip&&(Ie=`<title>${Oe(K.tooltip)}</title>`+Ie),K.link&&(Ie=cr(Ie,K.link,K.id,ie,r,K.linkTarget&&Dp.has(K.linkTarget)?` target="${K.linkTarget}"`:"")),`<g class="pele-node pele-class${Mt(K.cssClasses.replace(/^default\s?/,""))}" data-id="${N}"${U}>${Ie}</g>`}let $e="",ge="";for(let W=0;W<S.length;W++){let K=S[W],N=Z[W],U=H[W],J=N.arrowTypeStart,le=N.arrowTypeEnd,fe=Po(J),we=Po(le),Ee;if(K.src===K.dst){let De=y[K.src],Ie=m[K.src],ye=ae[W],Me=De.x+O+Ie.w/2,Se=De.y+B,q=Math.min(Ie.h/2-4,8+ye*6),ce=Go+ye*8;Ee={d:`M${o(Me+fe)},${o(Se-q)}C${o(Me+ce+fe)},${o(Se-q)} ${o(Me+ce+we)},${o(Se+q)} ${o(Me+we)},${o(Se+q)}`,sx:Me,sy:Se-q,sdx:-1,sdy:0,ex:Me,ey:Se+q,edx:-1,edy:0},K.labelX=De.x+Ie.w/2+ce+4+K.labelW/2,K.labelY=De.y}else{let De=K.route;for(let Ie=0;Ie<De.length;Ie+=3)De[Ie]+=O,De[Ie+1]+=B;Ee=lr(De,void 0,fe,we)}let Ae=N.pattern==="dashed"?' stroke-dasharray="6 4"':N.pattern==="dotted"?' stroke-dasharray="2 4"':"";if($e+=`<g class="pele-edge${N.pattern==="dotted"?" pele-note-edge":" pele-relation"}" data-id="${Oe(N.id)}"><path d="${Ee.d}"${Ae}/>`+Ho(J,Ee.sx,Ee.sy,Ee.sdx,Ee.sdy,ll)+Ho(le,Ee.ex,Ee.ey,Ee.edx,Ee.edy,ll)+"</g>",U.width>0){let De=K.labelX+O,Ie=K.labelY+B;ge+=nr(N.id,U,De,Ie,"",r.icons)}}let Te="";for(let W of A)Te+=`<text class="pele-cardinality" x="${o(W.x+O)}" y="${o(W.y+B+p*.35)}" text-anchor="middle">${Be(W.text)}</text>`;let pe=bi(e.title,h,d,$,Q,se,(ne?`<g class="pele-clusters">${ne}</g>`:"")+($e?`<g class="pele-edges" fill="none" stroke="${ll}" stroke-linecap="round">${$e}</g>`:"")+(X?`<g class="pele-cluster-titles">${X}</g>`:"")+(ge?`<g class="pele-edge-labels" font-size="${c}">${ge}</g>`:"")+(Te?`<g class="pele-cardinalities" font-size="${p}" fill="var(--_m)">${Te}</g>`:"")+`<g class="pele-nodes">${j}</g>`);return{svg:Je("class",pe.width,pe.height,d,r,e,pe.content),width:pe.width,height:pe.height,links:ie}}var dl={type:"class",parse(e,t,r){let i=new wp;return r&&(i.title=r),Mp(e,i),i},render:Ip};function Lp(e){return e==="markdown"||e==="string"||e==="text"?e:"markdown"}var Op=class{type="er";direction="TB";entities=new Map;relationships=[];classes=new Map;subgraphs=[];title;accTitle;accDescr;subgraphLookup=new Map;claimed=new Set;addEntity(e,t=""){let r=this.entities.get(e);return r===void 0?(r={id:`entity-${e}-${this.entities.size}`,label:e,alias:t,attributes:[],cssClasses:"default",cssStyles:[]},this.entities.set(e,r)):!r.alias&&t&&(r.alias=t),r}addAttributes(e,t){let r=this.addEntity(e);for(let i=t.length-1;i>=0;i--){let n=t[i];n.keys??=[],n.comment??="",r.attributes.push(n)}}addRelationship(e,t,r,i){let n=this.subgraphLookup.has(e)?e:this.addEntity(e).id,l=this.subgraphLookup.has(r)?r:this.addEntity(r).id;this.relationships.push({entityA:n,roleA:t,entityB:l,relSpec:i})}setDirection(e){this.direction=e}addCssStyles(e,t){if(t)for(let r of e){let i=this.entities.get(r);if(i)for(let l of t)i.cssStyles.push(l);let n=this.subgraphLookup.get(r);if(n)for(let l of t)n.cssStyles.push(l)}}addClass(e,t){for(let r of e){let i=this.classes.get(r);if(i===void 0&&(i={id:r,styles:[],textStyles:[]},this.classes.set(r,i)),!!t)for(let n of t)n.includes("color")&&i.textStyles.push(n.replace("fill","bgFill")),i.styles.push(n)}}setClass(e,t){for(let r of e){let i=this.entities.get(r);if(i)for(let l of t)i.cssClasses+=" "+l;let n=this.subgraphLookup.get(r);if(n)for(let l of t)n.classes.push(l)}}addSubGraph(e,t,r){let i=e.text.trim(),n=new Set,l=[],s;for(let d of t.flat()){if(typeof d!="string"){d?.stmt==="dir"&&(s=d.value);continue}let c=d.trim();c===""||n.has(c)||(n.add(c),this.claimed.has(d)||l.push(d))}for(let d of l)this.claimed.add(d);let a={id:i,nodes:l,title:(r.text||"").trim(),classes:[],cssStyles:[],dir:s,labelType:Lp(r.type)};return this.subgraphs.push(a),this.subgraphLookup.set(i,a),i}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
71`)}},jo=["$end","INVALID","ER_DIAGRAM","EOF","NEWLINE","COLON","STYLE_SEPARATOR","BLOCK_START","BLOCK_STOP","SQS","SQE","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","END","SUBGRAPH","direction_tb","direction_bt","direction_rl","direction_lr","CLASSDEF","UNICODE_TEXT","STYLE_TEXT","COMMA","CLASS","STYLE","SEMI","NUM","BRKT","ENTITY_NAME","DECIMAL_NUM","ENTITY_ONE","ATTRIBUTE_WORD","ATTRIBUTE_KEY","COMMENT","ZERO_OR_ONE","ZERO_OR_MORE","ONE_OR_MORE","ONLY_ONE","MD_PARENT","NON_IDENTIFYING","IDENTIFYING","WORD","CHAR"],Da=1,Li=2,wl=4,Ia=8,Yt=new Uint8Array(128);for(let e=0;e<128;e++){let t=e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||e===95,r=t&&(e<48||e>57);t&&(Yt[e]|=Da|Li|Ia),r&&(Yt[e]|=wl)}for(let e of"-*")Yt[e.charCodeAt(0)]|=Da|Li|Ia;Yt[46]|=Da|Ia;Yt[42]|=wl;for(let e of"[](),")Yt[e.charCodeAt(0)]|=Ia;var Rp=/accTitle\s*:\s*/iy,zp=/accDescr\s*:\s*/iy,Fp=/accDescr\s*\{\s*/iy,Wp=[/.*direction\s+TB[^\n]*/iy,/.*direction\s+BT[^\n]*/iy,/.*direction\s+RL[^\n]*/iy,/.*direction\s+LR[^\n]*/iy],hl=/direction/gi,fl=/[\n\r\u2028\u2029]/g;function Xo(e,t){return e<128?(Yt[e]&t)!==0:e>=192||e===181}function Pp(e){let t=e.length,r=[],i=[],n=[],l=0,s=0,a=-2,d=0,c=-1,p=-2,u=-1,h=-1,$=-1,g=(R,P,w)=>{r.push(R),i.push(e.slice(P,w)),n.push(P),s=w},T=(R,P)=>(R.lastIndex=P,R.test(e)?R.lastIndex:-1),D=R=>{for(let P=0;P<R.length;P++){let w=R.charCodeAt(P),b=e.charCodeAt(s+P);if(b!==w&&(w<97||w>122||(b|32)!==w))return!1}return!0},_=R=>D(R)&&!Pe(e.charCodeAt(s+R.length)),F=R=>{let P=e.charCodeAt(R);return P>=65&&P<=90?P+32:P},k=R=>(fl.lastIndex=R,fl.test(e)?fl.lastIndex-1:t),I=R=>{for(;ot(e.charCodeAt(R));)R++;return R},E=()=>{if(a===-1||a<s&&(hl.lastIndex=s,a=hl.test(e)?hl.lastIndex-9:-1,a===-1)||s<d||(c<s&&(c=k(s)),a>=c))return!1;for(let R=0;R<4;R++){let P=T(Wp[R],s);if(P>=0)return g(18+R,s,P),!0}return d=c,!1},m=()=>{let R=e.indexOf('"',s+1);if(R===-1){g(45,s,s+1);return}let P=R>s+1;for(let w=s+1;P&&w<R;w++){let b=e.charCodeAt(w);(b===37||b===92||b===13||b===10||b===11||b===8)&&(P=!1)}g(P?31:44,s,R+1)},y=R=>{let P=e.charCodeAt(s+1);if(P===43&&(R===49||R===48)){g(R===49?39:38,s,s+2);return}let w=I(s+1);if(e.charCodeAt(w)===46&&ot(e.charCodeAt(w+1))){g(32,s,I(w+2));return}if(R===49){if(Le(P)){let b=s+2;for(;Le(e.charCodeAt(b));)b++;let M=e.charCodeAt(b);if(Pe(M)||M===34||M===39){g(40,s,s+1);return}}else if(P===45||P===46){let b=e.charCodeAt(s+2);if(b===45||b===46){g(40,s,s+1);return}}if(!Pe(P)){g(33,s,s+1);return}}g(29,s,w)},C=R=>{let P=e.charCodeAt(s+1);switch(R){case 101:if(_("erdiagram"))g(2,s,s+9);else if(_("end")){let w=s+3;for(;Le(e.charCodeAt(w));)w++;g(16,s,w)}else return!1;return!0;case 115:if(_("style"))l=6,g(27,s,s+5);else if(_("subgraph"))g(17,s,s+8);else return!1;return!0;case 99:if(_("classdef"))l=6,g(22,s,s+8);else if(_("class"))g(26,s,s+5);else return!1;return!0;case 111:if(_("one or zero"))g(37,s,s+11);else if(_("one or more")||_("one or many"))g(39,s,s+11);else if(_("one"))g(40,s,s+3);else if(_("only one"))g(40,s,s+8);else if(P===124)g(37,s,s+2);else if(P===123)g(38,s,s+2);else if(_("optionally to"))g(42,s,s+13);else return!1;return!0;case 122:if(_("zero or one"))g(37,s,s+11);else if(_("zero or more")||_("zero or many"))g(38,s,s+12);else return!1;return!0;case 109:if(D("many(0)"))g(38,s,s+7);else if(D("many(1)"))g(39,s,s+7);else if(_("many"))g(38,s,s+4);else return!1;return!0;case 116:return _("to")?(g(43,s,s+2),!0):!1;case 117:return P!==46&&P!==45&&P!==124?!1:(g(41,s,s+1),!0);case 124:if(F(s+1)===111&&!Pe(e.charCodeAt(s+2)))g(37,s,s+2);else if(P===124)g(40,s,s+2);else if(P===123)g(39,s,s+2);else return!1;return!0;case 125:if(F(s+1)===111&&!Pe(e.charCodeAt(s+2)))g(38,s,s+2);else if(P===124)g(39,s,s+2);else return!1;return!0;case 46:return P!==46&&P!==45?!1:(g(42,s,s+2),!0);case 45:if(P===45)g(43,s,s+2);else if(P===46)g(42,s,s+2);else return!1;return!0}return!1},L=R=>{let P;if((R===97||R===65)&&D("acc")){if((P=T(Rp,s))>=0){l=3,g(11,s,P);return}if((P=T(zp,s))>=0){l=4,g(13,s,P);return}if((P=T(Fp,s))>=0){l=5,s=P;return}}if(!E()){switch(R){case 32:case 9:case 13:P=s+1;for(let w=e.charCodeAt(P);w===32||w===9||w===13;w=e.charCodeAt(P))P++;s=P;return;case 10:for(P=s+1;e.charCodeAt(P)===10;)P++;g(4,s,P);return;case 34:m();return;case 123:l=1,g(7,s,s+1);return;case 35:g(30,s,s+1);return;case 44:g(25,s,s+1);return;case 58:e.charCodeAt(s+1)===58&&e.charCodeAt(s+2)===58?g(6,s,s+3):g(5,s,s+1);return;case 91:g(9,s,s+1);return;case 93:g(10,s,s+1);return}if(ot(R)){y(R);return}if(!C(R>=65&&R<=90?R+32:R)){if(R>=128||(Yt[R]&Da)!==0){P=s+1;for(let w=e.charCodeAt(P);w>=128||(Yt[w]&Da)!==0;w=e.charCodeAt(P))P++;g(23,s,P);return}g(45,s,s+1)}}},S=()=>{if(p===-1||p<s&&(p=e.indexOf("~",s),p===-1))return!1;if($<s){let P=s;for(;P<t&&!Le(e.charCodeAt(P));)P++;$=P}if(p>=$||(u<s&&(u=k(s),h=e.lastIndexOf("~",u-1)),h<=p))return!1;let R=h+1;for(;R<t&&!Le(e.charCodeAt(R));)R++;return g(34,s,R),!0},Z=R=>{if(Le(R)){for(s++;Le(e.charCodeAt(s));)s++;return}let P=R|32;if((P===112||P===102||P===117)&&(e.charCodeAt(s+1)|32)===107&&!Pe(e.charCodeAt(s+2))){g(35,s,s+2);return}if(!S()){if(Xo(R,wl)){let w=s+1;for(;w<t&&Xo(e.charCodeAt(w),Ia);)w++;g(34,s,w);return}if(R===96){l=2,s++;return}if(R===34){let w=e.indexOf('"',s+1);if(w!==-1){g(36,s,w+1);return}}else if(R===125){l=0,g(8,s,s+1);return}g(45,s,s+1)}};for(;s<t;){let R=e.charCodeAt(s),P;switch(l){case 0:L(R);break;case 1:Z(R);break;case 2:R===96?(l=1,s++):(P=e.indexOf("`",s),g(34,s,P===-1?t:P));break;case 3:case 4:P=e.indexOf(`
72`,s),g(l===3?12:14,s,P===-1?t:P),l=0;break;case 5:R===125?(l=0,s++):(P=e.indexOf("}",s),g(15,s,P===-1?t:P));break;case 6:if(R===10){for(P=s+1;e.charCodeAt(P)===10;)P++;l=0,g(4,s,P)}else if(Le(R))for(s++;Le(e.charCodeAt(s));)s++;else if(R===58)g(5,s,s+1);else if(R===44)g(25,s,s+1);else if(R===35)g(30,s,s+1);else if(R===59)g(28,s,s+1);else if(R>=128||(Yt[R]&Li)!==0){P=s+1;for(let w=e.charCodeAt(P);w>=128||(Yt[w]&Li)!==0;w=e.charCodeAt(P))P++;g(24,s,P)}else return r.push(1),i.push(""),n.push(s),{types:r,texts:i,starts:n};break}}let H=l===0?3:l===3?12:l===4?14:l===5?15:-1;return H!==-1&&(r.push(H),i.push(""),n.push(t)),r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n}}var ul=new Map([[37,"ZERO_OR_ONE"],[38,"ZERO_OR_MORE"],[39,"ONE_OR_MORE"],[40,"ONLY_ONE"],[41,"MD_PARENT"]]),Hp=["TB","BT","RL","LR"],sc="'UNICODE_TEXT', 'NUM', 'ENTITY_NAME', 'DECIMAL_NUM', 'ENTITY_ONE'",Yp="'ZERO_OR_ONE', 'ZERO_OR_MORE', 'ONE_OR_MORE', 'ONLY_ONE', 'MD_PARENT'",Ii="'EOF', 'NEWLINE', 'title', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'SUBGRAPH', 'direction_tb', 'direction_bt', 'direction_rl', 'direction_lr', 'CLASSDEF', 'CLASS', 'STYLE', "+sc;function Gp(e,t){let{types:r,texts:i,starts:n}=Pp(e),l=0,s=y=>{let C=r[l];throw C===1?Ve("er",e,n[l],"",!0):Ve("er",e,n[l],`Expecting ${y}, got '${C===45?i[l]:jo[C]}'`)},a=y=>(r[l]!==y&&s(`'${jo[y]}'`),i[l++]),d=()=>{let y=r[l];y!==4&&y!==28&&y!==3&&s("'EOF', 'NEWLINE', 'SEMI'"),l++},c=y=>y===23||y===31||y===29||y===32||y===33,p=()=>{let y=r[l];c(y)||s(sc);let C=i[l++];return y===31?C.slice(1,-1):C},u=()=>{let y=[];for(;;){let C=r[l];if(C!==23&&C!==24&&s("'UNICODE_TEXT', 'STYLE_TEXT'"),y.push(i[l++]),r[l]!==25)return y;l++}},h=y=>y===24||y===29||y===5||y===30,$=()=>{let y=[];for(;;){h(r[l])||s("'STYLE_TEXT', 'COLON', 'NUM', 'BRKT'");let C=i[l++];for(;h(r[l]);)C+=i[l++];if(y.push(C),r[l]!==25)return y;l++}},g=()=>{let y=ul.get(r[l++]),C=r[l];C!==43&&C!==42&&s("'NON_IDENTIFYING', 'IDENTIFYING'");let L=C===43?"IDENTIFYING":"NON_IDENTIFYING";l++;let S=ul.get(r[l]);return S===void 0?s(Yp):(l++,{cardA:S,relType:L,cardB:y})},T=()=>{let y=r[l];y!==44&&y!==31&&y!==23&&s("'UNICODE_TEXT', 'ENTITY_NAME', 'WORD'");let C=i[l++];return y===23?C:C.slice(1,-1)},D=y=>r[l]===45&&i[l]===y,_=()=>{let y=[];do{let C=a(34);D("?")&&(C+=i[l++]),r[l]!==34&&s(C.endsWith("?")?"'ATTRIBUTE_WORD'":"'ATTRIBUTE_WORD', '?'");let L={type:C,name:i[l++]};if(r[l]===35){let S=[i[l++]];for(;D(",");)l++,S.push(a(35));L.keys=S}r[l]===36&&(L.comment=i[l++].slice(1,-1)),y.push(L)}while(r[l]!==8);return y.reverse()},F=()=>{if(r[l]!==7)return;if(l++,r[l]===8){l++;return}let y=_();return l++,y},k=()=>{let y=p(),C=r[l];if(C===9){l++;let Z=p();a(10);let H;r[l]===6&&(l++,H=u());let R=F();return t.addEntity(y,Z),R&&t.addAttributes(y,R),H&&t.setClass([y],H),[y]}let L;if(C===6&&(l++,L=u(),C=r[l]),ul.has(C)){let Z=g(),H=p(),R;r[l]===6&&(l++,R=u()),a(5);let P=T();return t.addEntity(y),t.addEntity(H),t.addRelationship(y,P,H,Z),L&&t.setClass([y],L),R&&t.setClass([H],R),[y,H]}let S=F();return t.addEntity(y),S&&t.addAttributes(y,S),L&&t.setClass([y],L),[y]};a(2);let I=[{id:"",title:"",list:[]}],E=I[0],m=!1;for(;;){let y=r[l];switch(y){case 4:l++;break;case 3:l++,m&&s(`'END', ${Ii}`);return;case 16:{m||s(Ii),l++;let C=t.addSubGraph({text:E.id},E.list,{text:E.title});I.pop(),E=I[I.length-1],m=I.length>1,m&&E.list.push(C);break}case 17:{l++;let C=p(),L=C;if(r[l]===9){for(l++,L=p();c(r[l]);)L+=" "+p();a(10)}d(),E={id:C,title:L,list:[]},I.push(E),m=!0;break}case 11:{l++;let C=a(12).trim();t.setAccTitle(C),m&&E.list.push(C);break}case 13:{l++;let C=a(14).trim();t.setAccDescription(C),m&&E.list.push(C);break}case 15:{let C=i[l++].trim();t.setAccDescription(C),m&&E.list.push(C);break}case 18:case 19:case 20:case 21:{l++;let C=Hp[y-18];m?E.list.push({stmt:"dir",value:C}):t.setDirection(C);break}case 22:{let C=i[l++],L=u(),S=$();d(),t.addClass(L,S),m&&E.list.push(C);break}case 26:{let C=i[l++],L=u();t.setClass(L,u()),m&&E.list.push(C);break}case 27:{let C=i[l++],L=u(),S=$();d(),t.addCssStyles(L,S),m&&E.list.push(C);break}default:{c(y)||s(m?`'END', ${Ii}`:Ii);let C=k();if(m)for(let L of C)E.list.push(L)}}}}var Bp=[];function Up(e){let t=[],r=[],i=e.subgraphs,n=d=>{let c=[];for(let p of d){let u=e.classes.get(p);if(u!==void 0){for(let h of u.styles)c.push(h.trim());for(let h of u.textStyles)c.push(h.trim())}}return c},l=new Map,s=new Set;for(let d=i.length-1;d>=0;d--){let c=i[d];s.add(c.id);for(let p of c.nodes)l.set(p,c.id)}for(let d=i.length-1;d>=0;d--){let c=i[d];t.push({id:c.id,label:c.title,alias:"",attributes:Bp,isGroup:!0,parentId:l.get(c.id),cssStyles:c.cssStyles,cssCompiledStyles:n(c.classes),cssClasses:c.classes.join(" "),dir:c.dir,labelType:c.labelType})}let a=new Map;for(let[d,c]of e.entities){if(s.has(d)){a.set(c.id,d);continue}t.push({id:c.id,label:c.label,alias:c.alias,attributes:c.attributes,isGroup:!1,parentId:l.get(d),cssStyles:c.cssStyles,cssCompiledStyles:n(c.cssClasses.split(" ")),cssClasses:c.cssClasses,dir:void 0,labelType:"markdown"})}return e.relationships.forEach((d,c)=>{r.push({id:`id_${d.entityA}_${d.entityB}_${c}`,start:a.get(d.entityA)??d.entityA,end:a.get(d.entityB)??d.entityB,label:d.roleA,arrowTypeStart:d.relSpec.cardB.toLowerCase(),arrowTypeEnd:d.relSpec.cardA.toLowerCase(),pattern:d.relSpec.relType==="IDENTIFYING"?"solid":"dashed"})}),{nodes:t,edges:r}}var Zt=18,Vo=5,Ko=6,pl=10,Zo=3.5;function ea(e,t,r,i,n){let l=(p,u)=>o(t-i*p-n*u)+","+o(r-n*p+i*u),s=p=>`M${l(p,-Vo)}L${l(p,Vo)}`,a=`M${l(0,-Ko)}L${l(pl,0)}L${l(0,Ko)}`,d=p=>`<circle class="pele-marker" cx="${o(t-i*p)}" cy="${o(r-n*p)}" r="${Zo}" fill="var(--_bg)"/>`,c=p=>`<path class="pele-marker" d="${p}"/>`;switch(e){case"only_one":return c(s(6)+s(10));case"zero_or_one":return c(s(6))+d(13.5);case"one_or_more":return c(a+s(pl+3.5));case"zero_or_more":return c(a)+d(pl+Zo+.5);case"md_parent":return`<path class="pele-marker" d="M${l(0,0)}L${l(6,4)}L${l(12,0)}L${l(6,-4)}Z" fill="var(--_bg)"/>`}return""}var qp=48,jp=20,Xp=64,Sa=20,_a=28,Vp=38,Qo=96,Jo=18,Kp=12,Zp=9,gl=12,ec=16,ml=9,Qp=260,yl=1e6,Jp=[],e0=18,t0=14,tc=' fill="var(--_s)" stroke="var(--_b)"';function rc(e,t,r){let i=e.er?.[t];return typeof i=="number"&&i>0?Math.min(i,2e3):r}function Ni(e,t,r,i,n){let l=e.lines;if(l.length===0)return"";if(l.length===1&&l[0].length===1&&l[0][0].icon===void 0&&l[0][0].style===0)return`<text${i} x="${o(t)}" y="${o(r)}">${Be(l[0][0].text)}</text>`;let s=Ss(e),a="",d="";for(let c of l){let p=!1;for(let $ of c)$.icon!==void 0&&(p=!0);let u=t,h=!1;for(let $ of c){if($.icon!==void 0){let g=e.size*1.1;d+=`<svg class="pele-icon" data-icon="${Oe($.icon)}" x="${o(u)}" y="${o(r-e.size*.35-g/2)}" width="${o(g)}" height="${o(g)}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n?.($.icon)??""}</svg>`}else if($.text!==""){let g=p||!h?` x="${o(u)}" y="${o(r)}"`:"";a+=`<tspan${g}${ri($.style&~s)}>${Be($.text)}</tspan>`,h=!0}u+=$.width}r+=e.lineHeight}return`<text${_s(i,s)} xml:space="preserve">${a}</text>${d}`}function $l(e){let t=Er(e);return t===e?e:t.replace(/</g,"<").replace(/>/g,">")}function r0(e,t,r){return dr(e.direction)?Ct(r,i=>ac(e,t,r,i)):ac(e,t,r,!1)}function ac(e,t,r,i){let n=Up(e),l=r.fontSize??16,s=Math.round(l*.875),a=r.measurer??tt(r.fontFamily),d=r.padding??8,c=r.icons,p=new Map,u=[],h=[];n.nodes.forEach((x,A)=>p.set(x.id,A));let $=[],g=[],T=[],D=new Map,_=[];for(let x of n.edges){let A=p.get(x.start),z=p.get(x.end);if(A===void 0||z===void 0)continue;let v=Fe(x.label,!0,a,s,200),G;if(A===z){G={label:v,band:0,at:0};let ee=D.get(A);ee?ee.push(G):D.set(A,[G])}_.push(G),T.push(x),g.push(v),$.push({src:A,dst:z,minlen:1,labelW:v.width>0?v.width+12:0,labelH:v.height>0?v.height+4:0,route:[],labelX:0,labelY:0})}let F=x=>{let A=x;for(let z=0;z<n.nodes.length;z++){let v=n.nodes[A].parentId,G=v===void 0?void 0:p.get(v);if(G===void 0)break;let ee=n.nodes[G].dir;if(ee)return ee==="LR"||ee==="RL";A=G}return e.direction==="LR"||e.direction==="RL"};for(let x=0;x<n.nodes.length;x++){let A=n.nodes[x],z=ct(A.cssStyles.length>0?A.cssCompiledStyles.concat(A.cssStyles):A.cssCompiledStyles),v=(z.bold?1:0)|(z.italic?2:0),G=z.fontSize??l,ee=z.fontSize??s,he=z.fontSize??Math.round(l*.75),ue=A.isGroup?Fe(A.label,!0,a,G,4e3,v):Fe(A.alias||A.label,!0,a,G,240,v),V=D.get(x)??Jp,Y=V.length>0&&!A.isGroup&&F(x),de={node:A,style:z,label:ue,w:0,h:0,headH:0,rows:[],cols:[],rowSize:ee,keySize:he,below:Y},te=0,xe=0;for(let O of V)O.band=Math.max(Vp,Y?O.label.width+12:O.label.height+6),xe+=O.band,te=Math.max(te,Y?O.label.height:O.label.width);let me=Math.max(Qo,Y?xe+8:0),ae;if(A.isGroup)ae=wt(0,0),ae.isGroup=!0,ae.dir=A.dir?Ft(A.dir):void 0,ae.padX=Sa,ae.padTop=de.label.height>0?de.label.height+16:Sa,ae.padBottom=Sa,ae.minW=Math.max(de.label.width+2*Sa-12,Qo);else{let O=Math.max(ue.height,Math.round(G*1.5));if(A.attributes.length===0)de.w=Math.max(ue.width+2*Jo,me),de.h=Math.max(O+2*Kp,Y?0:xe+8);else{let Q=Math.round(ee*1.5),se=[0,0,0,0];for(let j of A.attributes){let oe=[Fe($l(j.type),!0,a,ee,yl,v),Fe($l(j.name),!0,a,ee,yl,v),Fe(j.keys.join(", "),!1,a,he,yl,v),Fe($l(j.comment),!0,a,ee,Qp,v)],$e=Q;for(let ge=0;ge<4;ge++)oe[ge].width>se[ge]&&(se[ge]=oe[ge].width),oe[ge].height>$e&&($e=oe[ge].height);de.rows.push({cells:oe,h:$e+ml}),de.h+=$e+ml}let ie=0,re=0;for(let j of se)j!==0&&(re+=j+(ie>0?ec:0),ie++);de.w=Math.max(re+2*gl,ue.width+2*Jo,me);let ne=ie>0?(de.w-re-2*gl)/ie:0,X=gl;for(let j of se)de.cols.push(X),j>0&&(X+=j+ne+ec);de.headH=O+2*Zp,de.h+=de.headH}let B=V.length>0?2*(Zt+_a*.75+10+te):0;ae=Y?wt(de.w,de.h+B):wt(de.w+B,de.h)}ae.seq=u.length,u.push(de),h.push(ae)}n.nodes.forEach((x,A)=>{h[A].parent=x.parentId!==void 0?p.get(x.parentId)??-1:-1});let k=or(h,$,i?"TB":Ft(e.direction),{nodeSep:rc(t,"nodeSpacing",qp),edgeSep:jp,rankSep:rc(t,"rankSpacing",Xp),portSep:24});i0($,h,u);let I=k.width;for(let[x,A]of D){let z=h[x];if(!z.isGroup)continue;let v=0;for(let G of A)v=Math.max(v,G.label.width);I=Math.max(I,z.x+z.w/2+Zt+_a*.75+10+v)}let E=Fe(e.title,!1,a,l,4e3,1),m=E.height>0?E.height+12:0,y=Math.max(I,E.width),C=d+(y-I)/2,L=d+m;di(h,$,C,L);let S=Math.ceil(y+2*d),Z=Math.ceil(k.height+m+2*d),H=[],R=new Map,P=!1;for(let x of h)x.isGroup&&(P=!0);if(P)for(let x of $)Yr(R,x.route);let w="",b="";for(let x=0;x<u.length;x++){let A=u[x],z=h[x],v=A.node,G=Mt(v.cssClasses.replace(/^default\s?/,""));if(z.isGroup){A.w=z.w,A.h=z.h;let ae=z.x-z.w/2,O=z.y-z.h/2,B=Gr(z,A.label.width,R,Sa);w+=`<g class="pele-cluster${G}" data-id="${Oe(v.id)}"><rect x="${o(ae)}" y="${o(O)}" width="${o(z.w)}" height="${o(z.h)}" rx="${Ke}" fill="var(--_a)" fill-opacity="0.5" stroke="var(--_b)"${A.style.shape}/>`+Ne(A.label,B,O+8+A.label.height/2,` class="pele-cluster-label" fill="var(--_m)"${A.style.text}`,c)+"</g>";continue}let ee=A.w,he=A.h,ue=-ee/2,V=-he/2,Y=A.style.text,de=`x="${o(ue)}" y="${o(V)}" width="${o(ee)}" height="${o(he)}" rx="${Ke}"`,te=Ne(A.label,0,A.rows.length>0?V+A.headH/2:0,` class="pele-label"${Y}`,c),xe=nt(v.alias||v.label);if(/ internal-link(?: |$)/.test(G+" ")&&te!==""&&r.links!==!1){let ae=ma(xr(xe),r)!==void 0,O=Be(xe);te=`<a class="internal-link"${ae?` href="${O}"${ya(r)}`:""} data-href="${O}">${te}</a>`,H.push({id:v.label,href:xe,internal:!0})}let me;if(A.rows.length===0)me=`<rect ${de}${tc}${A.style.shape}/>`+te;else{let ae=Math.round(A.rowSize*1.5),O=A.style.stroke?Be(A.style.stroke):"var(--_b)",B="",Q="",se=V+A.headH;for(let re=0;re<A.rows.length;re++){let ne=A.rows[re];if(re%2===0){let Te=`x="${o(ue)}" width="${o(ee)}"`;re===A.rows.length-1?B+=`<rect ${Te} y="${o(se)}" height="${o(ne.h)}" rx="${Ke}"/><rect ${Te} y="${o(se)}" height="${o(ne.h/2)}"/>`:B+=`<rect ${Te} y="${o(se)}" height="${o(ne.h)}"/>`}let X=se+ml/2+ae/2+A.rowSize*.35,[j,oe,$e,ge]=ne.cells;Q+=Ni(j,ue+A.cols[0],X,` class="pele-er-type" fill="var(--_m)"${Y}`,c)+Ni(oe,ue+A.cols[1],X,` class="pele-er-name"${Y}`,c)+Ni($e,ue+A.cols[2],X,` class="pele-er-keys" font-size="${A.keySize}" fill="var(--_m)"${Y}`,c)+Ni(ge,ue+A.cols[3],X,` class="pele-er-comment" fill="var(--_m)"${Y}`,c),se+=ne.h}let ie=o(V+A.headH);me=`<rect ${de}${tc}${A.style.shape}/><g class="pele-er-stripes" fill="var(--_bg)"${A.style.shape.includes("fill:")?' opacity="0.6"':""}>${B}</g><path class="pele-er-divider" d="M${o(ue)},${ie}H${o(ue+ee)}" stroke="${O}"/><rect ${de} fill="none" stroke="var(--_b)"${A.style.line}/>`+te+`<g class="pele-er-attributes" font-size="${A.rowSize}">${Q}</g>`}b+=`<g class="pele-node pele-entity${G}" data-id="${Oe(v.label)}" transform="translate(${o(z.x)},${o(z.y)})">${me}</g>`}for(let[x,A]of D){let z=u[x],v=0;for(let he of A)v+=he.band;let G=Math.min(1,Math.max((z.below?z.w:z.h)-8,0)/v),ee=-v*G/2;for(let he of A)he.band*=G,he.at=ee+he.band/2,ee+=he.band}let M="",f="";for(let x=0;x<$.length;x++){let A=$[x],z=T[x],v=g[x],G,ee,he,ue=_[x];if(ue){let Y=h[A.src],de=u[A.src],te=Math.max(Math.min(ue.band/2-6,13),1),xe=Zt+_a*.75+6;if(de.below){let me=Y.x+ue.at,ae=Y.y+de.h/2,O=o(ae+Zt),B=o(ae+Zt+_a);G=`M${o(me-te)},${o(ae)}V${O}C${o(me-te)},${B} ${o(me+te)},${B} ${o(me+te)},${O}V${o(ae)}`,ee=ea(z.arrowTypeStart,me-te,ae,0,-1),he=ea(z.arrowTypeEnd,me+te,ae,0,-1),A.labelX=me,A.labelY=ae+xe+v.height/2}else{let me=Y.x+de.w/2,ae=Y.y+ue.at,O=o(me+Zt),B=o(me+Zt+_a);G=`M${o(me)},${o(ae-te)}H${O}C${B},${o(ae-te)} ${B},${o(ae+te)} ${O},${o(ae+te)}H${o(me)}`,ee=ea(z.arrowTypeStart,me,ae-te,-1,0),he=ea(z.arrowTypeEnd,me,ae+te,-1,0),A.labelX=me+xe+v.width/2,A.labelY=ae}}else{let Y=a0(A.route);if(Y.length<6)continue;ic(Y,0,u[A.src],h[A.src]),ic(Y,Y.length-3,u[A.dst],h[A.dst]);let de=Math.abs(Y[Y.length-3]-Y[0]),te=Math.abs(Y[Y.length-2]-Y[1]),xe=Y.length===6&&(de<.01||te<.01||Math.hypot(de,te)<=3*Zt)?0:Zt,me=lr(Y,void 0,xe,xe);G=xe>0?`M${o(me.sx)},${o(me.sy)}L${me.d.slice(1)}L${o(me.ex)},${o(me.ey)}`:me.d,ee=ea(z.arrowTypeStart,me.sx,me.sy,me.sdx,me.sdy),he=ea(z.arrowTypeEnd,me.ex,me.ey,me.edx,me.edy)}let V=z.pattern==="dashed";if(M+=`<g class="pele-edge pele-er-${V?"non-identifying":"identifying"}" data-id="${Oe(z.id)}"><path d="${G}"${V?' stroke-dasharray="4 3"':""}/>`+ee+he+"</g>",v.width>0){let Y=A.labelX,de=A.labelY;f+=nr(z.id,v,Y,de,"",c)}}return{svg:Je("er",S,Z,l,r,e,Ne(E,S/2,d+E.height/2,' class="pele-title" font-weight="var(--_tw)"')+(w?`<g class="pele-clusters">${w}</g>`:"")+(M?`<g class="pele-edges" fill="none" stroke="var(--_l)" stroke-linecap="round">${M}</g>`:"")+(f?`<g class="pele-edge-labels" font-size="${s}">${f}</g>`:"")+`<g class="pele-nodes">${b}</g>`),width:S,height:Z,links:H}}function a0(e){let t=e.slice(0,3);for(let r=3;r<e.length;r+=3){let i=t.length-3,n=l=>Math.abs(t[i+l]-e[r+l])<.01&&Math.abs(e[r+l]-e[r+3+l])<.01;r+3<e.length&&(n(0)||n(1))||t.push(e[r],e[r+1],e[r+2])}return t}function i0(e,t,r){let i=new Map,n=(l,s,a,d)=>{let c=t[l],p=s[a]-c.x,u=s[a+1]-c.y,h;if(Math.abs(Math.abs(u)-c.h/2)<.5)h=u<0?0:2;else if(Math.abs(Math.abs(p)-c.w/2)<.5)h=p<0?3:1;else return;let $=l*4+h,g={route:s,at:a,toward:s[d+(h&1?1:0)]},T=i.get($);T?T.push(g):i.set($,[g])};for(let l of e){let s=l.route.length-3;l.src===l.dst||s<3||(n(l.src,l.route,0,3),n(l.dst,l.route,s,s-3))}for(let[l,s]of i){if(s.length<2)continue;let a=l>>2,d=(l&1)===1,c=t[a].isGroup?t[a]:r[a],p=d?c.h:c.w,u=Math.max(Math.min(e0,(p-2*t0)/(s.length-1)),0),h=d?t[a].y:t[a].x;s.sort(($,g)=>$.toward-g.toward);for(let $=0;$<s.length;$++)s[$].route[s[$].at+(d?1:0)]=h+($-(s.length-1)/2)*u}}function ic(e,t,r,i){if(i.isGroup)return;let n=e[t]-i.x,l=e[t+1]-i.y;i.w!==r.w&&Math.abs(Math.abs(n)-i.w/2)<.5&&(e[t]-=Math.sign(n)*(i.w-r.w)/2),i.h!==r.h&&Math.abs(Math.abs(l)-i.h/2)<.5&&(e[t+1]-=Math.sign(l)*(i.h-r.h)/2)}var xl={type:"er",parse(e,t,r){let i=new Op;return r&&(i.title=r),Gp(e,i),i},render:r0};var lc=new WeakMap;function s0(e){let t=e.map((n,l)=>l),r=[];for(let n=0;n<128;n++){let l=String.fromCharCode(n);r.push(t.filter(s=>{let{pattern:a,first:d}=e[s];return typeof a=="string"?a[0]===l:d===void 0||d.includes(l)}))}let i={starting:r,every:t,longer:e.map(n=>n.longer?.map(l=>e.indexOf(l)))};return lc.set(e,i),i}function Oi(e,t,r){let i=[],n=[],l=[],s=new Uint8Array(t.length),{starting:a,every:d,longer:c}=lc.get(t)??s0(t),p=[],u=e.length,h=(g,T)=>{if(s[g])return-1;let D=t[g];if(D.match!==void 0)return D.match(e,T);if(D.scanner!==void 0)return(p[g]??=D.scanner())(e,T);let _=D.pattern;return typeof _=="string"?e.startsWith(_,T)?T+_.length:-1:(_.lastIndex=T,_.test(e)?_.lastIndex:(D.opener!==void 0&&(D.opener.lastIndex=T,D.opener.test(e)&&(s[g]=1)),-1))},$=0;e:for(;$<u;){let g=e.charCodeAt($);for(let T of g<128?a[g]:d){let D=h(T,$);if(D<=$)continue;let _=T,F=c[T];if(F!==void 0)for(let k of F){let I=h(k,$);if(I>D){_=k,D=I;break}}t[_].hidden||(i.push(_),n.push($),l.push(D)),$=D;continue e}throw Ve(r,e,$,"",!0)}return i.push(-1),n.push(u),l.push(u),{kinds:i,starts:n,ends:l,src:e}}var Ri={name:"ACC_DESCR",pattern:/[\t ]*accDescr(?:[\t ]*:([^\n\r]*?(?=%%)|[^\n\r]*)|\s*{([^}]*)})/y,first:" a"},zi={name:"ACC_TITLE",pattern:/[\t ]*accTitle[\t ]*:(?:[^\n\r]*?(?=%%)|[^\n\r]*)/y,first:" a"},Fi={name:"TITLE",pattern:/[\t ]*title(?:[\t ][^\n\r]*?(?=%%)|[\t ][^\n\r]*|)/y,first:" t"},Wi={name:"STRING",pattern:/"([^"\\]|\\.)*"|'([^'\\]|\\.)*'/y,first:`"'`},Pi={name:"NEWLINE",pattern:/\r?\n/y,first:`\r
73`},Hi={name:"WHITESPACE",pattern:/[\t ]+/y,hidden:!0,first:" "},Yi={name:"YAML",pattern:/---[\t ]*\r?\n(?:[\S\s]*?\r?\n)?---(?:\r?\n|(?!\S))/y,hidden:!0,opener:/---[\t ]*\r?\n/y,first:"-"},Gi={name:"DIRECTIVE",pattern:/[\t ]*%%{[\S\s]*?}%%(?:\r?\n|(?!\S))/y,hidden:!0,opener:/[\t ]*%%{/y,first:" %"},Bi={name:"SINGLE_LINE_COMMENT",pattern:/[\t ]*%%[^\n\r]*/y,first:" %",hidden:!0};function Na(e){return{name:e,pattern:new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"(?:(?=%%)|(?!\\S))","y"),first:e[0]}}var l0=/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,n0=/accTitle[\t ]*:([^\n\r]*)/,o0=/title([\t ][^\n\r]*|)/;function bl(e){return e.trim().replace(/[\t ]{2,}/gm," ")}function Ui(e){return bl(o0.exec(e)[1])}function qi(e){return bl(n0.exec(e)[1])}function ji(e){let t=l0.exec(e);return t[1]!==void 0?bl(t[1]):t[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,`
74`)}var c0=new Map([["b","\b"],["f","\f"],["n",`
75`],["r","\r"],["t"," "],["v","\v"],["0","\0"]]);function La(e){if(!e.includes("\\"))return e.slice(1,-1);let t="";for(let r=1;r<e.length-1;r++){let i=e[r];if(i==="\\"){let n=e[++r];t+=c0.get(n)??n}else t+=i}return t}var Xi=class{constructor(e,t,r){this.tokens=e,this.types=t,this.diagram=r,this.kinds=e.kinds}tokens;types;diagram;i=0;kinds;get kind(){return this.kinds[this.i]}text(e=this.i){return this.tokens.src.slice(this.tokens.starts[e],this.tokens.ends[e])}take(){return this.text(this.i++)}accept(e){return this.kinds[this.i]!==e?!1:(this.i++,!0)}expect(e){return this.kinds[this.i]!==e&&this.fail(`token of type '${this.types[e].name}'`),this.take()}fail(e){let t=this.kind===-1?"end of input":`\`${this.text()}\``;throw Ve(this.diagram,this.tokens.src,this.tokens.starts[this.i],`Expecting ${e} but found ${t}.`)}};function d0(e,t){let r=new Map;for(let{label:i,value:n}of e.sections){if(n<0)throw new He(`"${i}" has invalid value: ${n}. Negative values are not allowed in pie charts. All slice values must be >= 0.`,"semantic",{type:"pie"});r.has(i)||r.set(i,n)}return{type:"pie",title:e.title||t,accTitle:e.accTitle?e.accTitle.replace(/^\s+/g,""):void 0,accDescr:e.accDescr?e.accDescr.replace(/\n\s+/g,`
76`):void 0,showData:e.showData,sections:r}}function nc(e,t){let r=t;for(let i=e.charCodeAt(r);i>=48&&i<=57;i=e.charCodeAt(r))r++;return r}function h0(){let e=0,t=0,r=-1;return(i,n)=>{let l=i.charCodeAt(n)===45?n+1:n;if((l<e||l>=t)&&(e=l,t=nc(i,l),r=-1,t>l&&i.charCodeAt(t)===46)){let s=nc(i,t+1),a=s-t-1;a>0&&i.charCodeAt(s)!==46?r=s:a>1&&(r=s-1)}return t===l?-1:r>=0?r:i.charCodeAt(l)===48?i.charCodeAt(l+1)===46?-1:l+1:i.charCodeAt(t)!==46?t:t-1>l?t-1:-1}}var oc=[Na("showData"),Na("pie"),{name:":",pattern:":"},{name:"NUMBER_PIE",pattern:/(?:-?[0-9]+\.[0-9]+(?!\.))|(?:-?(0|[1-9][0-9]*)(?!\.))/y,scanner:h0,first:"-0123456789"},Ri,zi,Fi,Wi,Pi,Hi,Yi,Gi,Bi];function f0(e){let t=new Xi(Oi(e,oc,"pie"),oc,"pie"),r={$type:"Pie",showData:!1,sections:[]},i=()=>{if(t.kind!==-1)for(t.kind!==8&&t.fail("a line break or the end of input");t.kind===8;)t.i++};for(;t.kind===8;)t.i++;for(t.expect(1),r.showData=t.accept(0);t.kind!==-1;)switch(t.kind){case 8:t.i++;break;case 4:r.accDescr=ji(t.take()),i();break;case 5:r.accTitle=qi(t.take()),i();break;case 6:r.title=Ui(t.take()),i();break;case 7:{let n=La(t.take());t.expect(2);let l=Number(t.expect(3));r.sections.push({$type:"PieSection",label:n,value:l}),i();break}default:t.fail("a section, a title, or a line break")}return r}var u0=120,Oa=12,kl=26,vl=32,cc=28;function Ml(e,t){return e.pie?.[t]}function ta(e,t){return`${o(Math.sin(e)*t)},${o(-Math.cos(e)*t)}`}function p0(e,t,r,i){if(t-e>=Math.PI*2-1e-9){let l=(s,a)=>`M0,${o(-s)}A${o(s)},${o(s)} 0 1 ${a} 0,${o(s)}A${o(s)},${o(s)} 0 1 ${a} 0,${o(-s)}Z`;return l(r,1)+(i>0?l(i,0):"")}let n=t-e>Math.PI?1:0;return i<=0?`M0,0L${ta(e,r)}A${o(r)},${o(r)} 0 ${n} 1 ${ta(t,r)}Z`:`M${ta(e,r)}A${o(r)},${o(r)} 0 ${n} 1 ${ta(t,r)}L${ta(t,i)}A${o(i)},${o(i)} 0 ${n} 0 ${ta(e,i)}Z`}function g0(e,t,r){return mi(r,u0*2,140,(i,n)=>m0(e,t,r,i/2,n))}function m0(e,t,r,i,n){let l=r.fontSize??16,s=Math.round(l*.875),a=r.measurer??tt(r.fontFamily),d=r.padding??8,c=Ml(t,"textPosition"),p=typeof c=="number"&&c>=0&&c<=1?c:.75,u=Ml(t,"donutHole"),h=typeof u=="number"&&u>0&&u<=.9?u*i:0,$=String(Ml(t,"legendPosition")??"right"),g=n&&($==="left"||$==="right")?"bottom":$,T=[...e.sections],D=0;for(let[,te]of T)D+=te;let _=T.map(([te,xe])=>Fe(e.showData?`${te} [${xe}]`:te,!1,a,s,4e3)),F=0;for(let te of _)F=Math.max(F,te.width);F+=_.length>0?Oa+8:0;let k=_.length*kl,I=Fe(e.title,!1,a,l,Pt(r),1),E=I.height>0?I.height+16:0,m=T.map(([,te])=>{let xe=D>0?te/D:0;return xe*100>=1&&(xe*100).toFixed(0)!=="0"?xe:0}),y=m.map(te=>te===0||te>=.5?!1:2*i*p*Math.sin(te*Math.PI)<a.width((te*100).toFixed(0)+"%",s,0)+6),C=y.includes(!0)?cc:0,L=g==="left"||g==="right"||g==="center"?g:"",S=g==="top"||g==="bottom",Z=(i+C)*2,H=Z,R=Z;L==="left"||L==="right"?(H+=F>0?vl+F:0,R=Math.max(R,k)):S&&(H=Math.max(H,F),R+=k>0?20+k:0),H=Math.max(H,I.width);let P=d+(L==="left"?F+vl+Z/2:L==="right"?Z/2:H/2),w=d+E,b=w+(g==="top"?k+20+Z/2:S?Z/2:R/2),M="",f="",x="",A=0,z=i+cc/2,v=[],G=(te,xe,me)=>v.every(ae=>Math.abs(te-ae.x)>=(me+ae.width)/2+2||Math.abs(xe-ae.y)>=s+2);T.forEach(([te],xe)=>{let me=m[xe];if(me===0)return;let ae=A+me*Math.PI*2;M+=`<path class="pele-slice" data-id="${Oe(te)}" d="${p0(A,ae,i,h)}" fill="${it(xe)}"/>`;let O=(A+ae)/2,B=(me*100).toFixed(0)+"%";if(y[xe]){let Q=a.width(B,s,0),se=O;for(let ne=0;ne<360&&!G(Math.sin(se)*z,-Math.cos(se)*z,Q);ne++)se+=2/z;let ie=Math.sin(se)*z,re=-Math.cos(se)*z;v.push({x:ie,y:re,width:Q}),x+=`<text x="${o(ie)}" y="${o(re+s*.35)}">${B}</text>`}else{let Q=i*p;f+=`<text x="${o(Math.sin(O)*Q)}" y="${o(-Math.cos(O)*Q+s*.35)}">${B}</text>`}A=ae}),M===""&&(M=`<circle class="pele-slice" r="${i}" fill="none" stroke="var(--_b)"/>`);let ee="",he,ue;L==="right"?(he=P+Z/2+vl,ue=w+(R-k)/2):L==="left"?(he=d,ue=w+(R-k)/2):L==="center"?(he=P-F/2,ue=b-k/2):(he=d+(H-F)/2,ue=g==="top"?w:w+Z+20),_.forEach((te,xe)=>{let me=ue+xe*kl+kl/2;ee+=`<g class="pele-legend-item" data-id="${Oe(T[xe][0])}"><rect x="${o(he)}" y="${o(me-Oa/2)}" width="${Oa}" height="${Oa}" rx="2" fill="${it(xe)}"/>`+Ne(te,he+Oa+8+te.width/2,me,"")+"</g>"});let V=Math.ceil(H+2*d),Y=Math.ceil(R+E+2*d),de=Ne(I,V/2,d+I.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g class="pele-slices" transform="translate(${o(P)},${o(b)})" stroke="var(--_bg)" stroke-width="1" stroke-linejoin="round">${M}</g>`+(f?`<g class="pele-slice-labels" transform="translate(${o(P)},${o(b)})" font-size="${s}" text-anchor="middle" fill="var(--_bg)">${f}</g>`:"")+(x?`<g class="pele-slice-labels" transform="translate(${o(P)},${o(b)})" font-size="${s}" text-anchor="middle">${x}</g>`:"")+(ee?`<g class="pele-legend" font-size="${s}">${ee}</g>`:"");return{svg:Je("pie",V,Y,l,r,e,de),width:V,height:Y,links:[]}}var Al={type:"pie",parse:(e,t,r)=>d0(f0(e),r),render:g0};var ia=["January","February","March","April","May","June","July","August","September","October","November","December"],Ir=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function Fa(e){return!Number.isNaN(e.getTime())}function Dt(e,t){let r=String(e);return r.length>=t?r:"0".repeat(t-r.length)+r}function vc(e){let t=["th","st","nd","rd"],r=e%100;return e+(t[(r-20)%10]||t[r]||t[0])}function _l(e){let t=-Math.round(e.getTimezoneOffset()/15)*15;return t===0?0:t}function dc(e){let t=_l(e),r=Math.abs(t);return(t>=0?"+":"-")+Dt(Math.floor(r/60),2)+":"+Dt(r%60,2)}function Mc(e){return e.getDay()||7}function ur(e,t){let r=new Date(e);return r.setDate(r.getDate()+t),r}function y0(e){let t=new Date(e.getFullYear(),e.getMonth()+1,0);return t.setHours(23,59,59,999),t.getDate()}function hc(e,t){let r=new Date(e);return r.setDate(1),t(r),r.setDate(Math.min(e.getDate(),y0(r))),r}function Ac(e,t,r){switch(r){case"M":return hc(e,i=>i.setMonth(e.getMonth()+t));case"y":return hc(e,i=>i.setFullYear(e.getFullYear()+t));case"d":return ur(e,Math.round(t));case"w":return ur(e,Math.round(7*t));case"h":return new Date(e.getTime()+t*36e5);case"m":return new Date(e.getTime()+t*6e4);case"s":return new Date(e.getTime()+t*1e3);default:return new Date(e.getTime()+t)}}function Tc(e){return ur(e,4-Mc(e))}function fc(e){let t=Tc(e),r=new Date(t.getFullYear(),0,1),i=Mc(r),n=ur(r,4-i+(i>4?7:0)),l=(_l(n)-_l(t))*6e4,s=(t.getTime()-n.getTime()-l)/6048e5;return(s<0?Math.ceil(s)||0:Math.floor(s))+1}var $0=/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,w0=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,x0="YYYY-MM-DDTHH:mm:ssZ";function Cc(e,t){if(!Fa(e))return"Invalid Date";let r=t||x0;if(r==="YYYY-MM-DD")return Ec(e);let i=!1,n=r.replace($0,s=>{switch(s){case"Q":return String(Math.ceil((e.getMonth()+1)/3));case"Do":return"["+vc(e.getDate())+"]";case"GGGG":return String(Tc(e).getFullYear());case"W":return String(fc(e));case"WW":return Dt(fc(e),2);case"k":return String(e.getHours()||24);case"kk":return Dt(e.getHours()||24,2);case"X":return String(Math.floor(e.getTime()/1e3));case"x":return String(e.getTime());case"gggg":case"wo":case"w":case"ww":case"z":case"zzz":return i=!0,s;default:return s}});if(i)return;let l=e.getHours();return n.replace(w0,(s,a)=>{if(a)return a;switch(s){case"YY":return String(e.getFullYear()).slice(-2);case"YYYY":return Dt(e.getFullYear(),4);case"M":return String(e.getMonth()+1);case"MM":return Dt(e.getMonth()+1,2);case"MMM":return ia[e.getMonth()].slice(0,3);case"MMMM":return ia[e.getMonth()];case"D":return String(e.getDate());case"DD":return Dt(e.getDate(),2);case"d":return String(e.getDay());case"dd":return Ir[e.getDay()].slice(0,2);case"ddd":return Ir[e.getDay()].slice(0,3);case"dddd":return Ir[e.getDay()];case"H":return String(l);case"HH":return Dt(l,2);case"h":return String(l%12||12);case"hh":return Dt(l%12||12,2);case"a":return l<12?"am":"pm";case"A":return l<12?"AM":"PM";case"m":return String(e.getMinutes());case"mm":return Dt(e.getMinutes(),2);case"s":return String(e.getSeconds());case"ss":return Dt(e.getSeconds(),2);case"SSS":return Dt(e.getMilliseconds(),3);case"Z":return dc(e);default:return dc(e).replace(":","")}})}function Ec(e){let t=e.getFullYear(),r=e.getMonth()+1,i=e.getDate();return(t>=1e3&&t<=9999?t:Dt(t,4))+(r<10?"-0":"-")+r+(i<10?"-0":"-")+i}var b0=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,k0=/\[[^\]]+]/g,uc=/\d/,Ra=/\d\d/,v0=/\d{3}/,M0=/\d{4}/,Gt=/\d\d?/,A0=/[+-]?\d+/,pc=/[+-]\d\d:?(\d\d)?|Z/,za=/\d*[^-_:/,()\s\d]+/;function vt(e){return(t,r)=>(t[e]=+r,!0)}var gc=(e,t)=>{if(t==="Z")return e.offset=0,!0;let r=t.match(/([+-]|\d\d)/g),i=+r[1]*60+(+r[2]||0);return e.offset=i===0?0:r[0]==="+"?-i:i,!0};function mc(e){return(t,r)=>{let i=e.indexOf(r)+1;return i<1?!1:(t.month=i%12||i,!0)}}var T0=new Map([["A",{re:za,read:(e,t)=>(e.afternoon=t==="PM",!0)}],["a",{re:za,read:(e,t)=>(e.afternoon=t==="pm",!0)}],["Q",{re:uc,read:(e,t)=>(e.month=(+t-1)*3+1,!0)}],["S",{re:uc,read:(e,t)=>(e.milliseconds=+t*100,!0)}],["SS",{re:Ra,read:(e,t)=>(e.milliseconds=+t*10,!0)}],["SSS",{re:v0,read:(e,t)=>(e.milliseconds=+t,!0)}],["s",{re:Gt,read:vt("seconds")}],["ss",{re:Gt,read:vt("seconds")}],["m",{re:Gt,read:vt("minutes")}],["mm",{re:Gt,read:vt("minutes")}],["H",{re:Gt,read:vt("hours")}],["h",{re:Gt,read:vt("hours")}],["HH",{re:Gt,read:vt("hours")}],["hh",{re:Gt,read:vt("hours")}],["D",{re:Gt,read:vt("day")}],["DD",{re:Ra,read:vt("day")}],["Do",{re:za,read:(e,t)=>{let r=t.match(/\d+/);if(!r)return!1;e.day=+r[0],e.dayGiven=!0;for(let i=1;i<=31;i++)vc(i)===t&&(e.day=i);return!0}}],["w",{re:Gt,read:vt("week")}],["ww",{re:Ra,read:vt("week")}],["M",{re:Gt,read:vt("month")}],["MM",{re:Ra,read:vt("month")}],["MMM",{re:za,read:mc(ia.map(e=>e.slice(0,3)))}],["MMMM",{re:za,read:mc(ia)}],["Y",{re:A0,read:vt("year")}],["YY",{re:Ra,read:(e,t)=>(e.year=+t+(+t>68?1900:2e3),!0)}],["YYYY",{re:M0,read:vt("year")}],["Z",{re:pc,read:gc}],["ZZ",{re:pc,read:gc}]]),yc,Vi=null;function C0(e){if(e===yc)return Vi;if(yc=e,Vi=null,/[Ll]/.test(e.replace(k0,"")))return null;let t=e.match(b0);return t?(Vi=t.map(r=>T0.get(r)??r.replace(/^\[|\]$/g,"")),Vi):null}function E0(e,t,r){if(t==="x"||t==="X")return new Date((t==="X"?1e3:1)*Number(e));let i=C0(t);if(!i)return;let n={},l=e,s=0;for(let g of i){if(typeof g=="string"){s+=g.length;continue}let T=g.re.exec(l.slice(s));if(!T||!g.read(n,T[0]))return;l=l.replace(T[0],"")}n.afternoon!==void 0&&n.hours!==void 0&&(n.afternoon?n.hours<12&&(n.hours+=12):n.hours===12&&(n.hours=0));let a=n.dayGiven||n.day?n.day:!n.year&&!n.month?r.getDate():1,d=n.year||r.getFullYear(),c=0;n.year&&!n.month||(c=n.month>0?n.month-1:r.getMonth());let p=n.hours||0,u=n.minutes||0,h=n.seconds||0,$=n.milliseconds||0;if(n.offset!==void 0)return new Date(Date.UTC(d,c,a,p,u,h,$+n.offset*6e4));if(!n.week)return new Date(d,c,a,p,u,h,$)}function S0(e,t,r){let i=E0(e,t,r);return i&&Fa(i)&&Cc(i,t)===e?i:void 0}var _0=/^[YMDHhmsSZXx\-/.:, T]*$/,D0=/^\s*(active|done|crit|milestone|vert)\s*$/,I0=/^after\s+([\d\w- ]+)/,N0=/^until\s+([\d\w- ]+)/,L0=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/,O0=/[\s,]+/,R0=/^\d+$/,z0=new Set(Ir.map(e=>e.toLowerCase())),F0=4e8,W0=400,P0=200,H0=400;function Sc(e){let t=e===void 0?NaN:+e;return Number.isFinite(t)?t:Date.now()}function Y0(e){let t=L0.exec(e.trim());return t?[Number.parseFloat(t[1]),t[2]]:[NaN,"ms"]}function $c(e,t){let r=new Set(e);for(let i of t.toLowerCase().split(O0))i!==""&&r.add(i);return[...r]}var G0=class{type="gantt";title;accTitle;accDescr;dateFormat="";axisFormat="";tickInterval;todayMarker="";includes=[];excludes=[];inclusiveEndDates=!1;topAxis=!1;displayMode="";weekday;weekend="saturday";sections=[];links=new Map;tasks=[];byId=new Map;currentSection="";taskCount=0;lastOrder=0;lastTaskId;options;now=0;work=0;includeSet=new Set;excludeSet=new Set;excludedDays=[];datedTokens=!1;constructor(e={}){this.options=e}setDateFormat(e){this.dateFormat=e}enableInclusiveEndDates(){this.inclusiveEndDates=!0}TopAxis(){this.topAxis=!0}setAxisFormat(e){this.axisFormat=e}setTickInterval(e){this.tickInterval=e}setTodayMarker(e){this.todayMarker=e}setIncludes(e){this.includes=$c(this.includes,e)}setExcludes(e){this.excludes=$c(this.excludes,e)}setWeekday(e){this.weekday=e}setWeekend(e){this.weekend=e}setDiagramTitle(e){this.title=e}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
77`)}addSection(e){this.currentSection=e,this.sections.push(e)}addTask(e,t){let r=(t.startsWith(":")?t.slice(1):t).split(","),i={id:"",task:e,section:this.currentSection,startTime:void 0,endTime:void 0,renderEndTime:null,manualEndTime:!1,processed:!1,active:!1,done:!1,crit:!1,milestone:!1,vert:!1,order:-1,classes:[],prevTaskId:this.lastTaskId,raw:{data:t,start:void 0,end:""}},n;for(;r.length>0&&(n=D0.exec(r[0]))!==null;)i[n[1]]=!0,r.shift();if(r.length===0)throw new He(`Task "${e.trim()}" needs a duration or an end date.`,"semantic",{type:"gantt"});if(r.length>3)throw new He(`Task "${e.trim()}" has too many fields. A task takes an id, a start, and an end or duration.`,"semantic",{type:"gantt"});for(let l=0;l<r.length;l++)r[l]=r[l].trim();r.length===3?i.id=r[0]:(this.taskCount++,i.id="task"+this.taskCount),r.length>1&&(i.raw.start=r[r.length-2]),i.raw.end=r[r.length-1],i.vert||(i.order=this.lastOrder++),this.tasks.push(i),this.lastTaskId=i.id,this.byId.set(i.id,i)}setLink(e,t){let r=br(t);for(let i of e.split(","))this.byId.has(i)&&this.links.set(i,r);this.setClass(e,"clickable")}setClickEvent(e,t,r){this.setClass(e,"clickable")}setClass(e,t){for(let r of e.split(","))this.byId.get(r)?.classes.push(t)}getTasks(e){this.now=Sc(e),this.work=0,this.includeSet=new Set(this.includes),this.excludeSet=new Set(this.excludes);let t=this.weekend==="friday"?5:this.weekend==="saturday"?6:NaN,r=this.excludeSet.has("weekends");this.excludedDays=Ir.map((n,l)=>{let s=l||7;return r&&(s===t||s===t+1)||this.excludeSet.has(n.toLowerCase())}),this.datedTokens=this.includes.length>0||!_0.test(this.dateFormat.trim());for(let n of this.excludes)n!=="weekends"&&!z0.has(n)&&(this.datedTokens=!0);for(let n of this.tasks)n.startTime=n.endTime=void 0,n.renderEndTime=null,n.processed=n.manualEndTime=!1;let i=this.compileTasks();for(let n=0;!i&&n<10;n++)i=this.compileTasks();return this.tasks}isInvalidDate(e){let t=this.excludedDays[e.getDay()];if(!this.datedTokens)return t;let r=this.dateFormat.trim(),i=Ec(e),n=i;this.spend(P0),r!=="YYYY-MM-DD"&&(this.spend(H0+r.length*8),n=Cc(e,r));let l=s=>s.has(i)||n!==void 0&&s.has(n);return l(this.includeSet)?!1:t||l(this.excludeSet)}spend(e){if(this.work+=e,this.work>F0)throw new He("The gantt chart takes too much work to schedule.","limit",{type:"gantt"})}parse(e,t){return this.spend((t.length+1)*(e.length+1)),S0(e,t,new Date(this.now))}today(){let e=new Date(this.now);return e.setHours(0,0,0,0),e}warn(e){this.options.warn&&this.options.warn(e())}compileTasks(){let e=!0;for(let t of this.tasks)this.compileTask(t),e=e&&t.processed;return e}compileTask(e){let t=e.raw.start;if(t===void 0){let r=e.prevTaskId===void 0?void 0:this.byId.get(e.prevTaskId);e.startTime=r?r.endTime:this.today()}else{let r=this.getStartDate(t);r&&(e.startTime=r)}e.startTime&&(e.endTime=this.getEndDate(e.startTime,e.raw.end),e.endTime&&(e.processed=!0,e.manualEndTime=this.parse(e.raw.end,"YYYY-MM-DD")!==void 0,this.checkTaskDates(e)))}references(e,t){let r=[],i;for(let n of t.split(" ")){if(n==="")continue;let l=this.byId.get(n);l?r.push(l):(i??=[]).push(n)}if(i){let n=i;this.warn(()=>`Gantt: "${e}" refers to task ids that do not exist: ${n.join(", ")}.`)}return r}getStartDate(e){let t=e.trim(),r=this.dateFormat.trim();if((r==="x"||r==="X")&&R0.test(t))return this.checked(new Date(Number(t)),t);let i=I0.exec(t);if(i!==null){let s=this.references("after",i[1]),a;for(let d of s)(!a||d.endTime>a.endTime)&&(a=d);return a?a.endTime:this.today()}let n=this.parse(t,r);if(n)return n;let l=new Date(t);if(!Fa(l)||l.getFullYear()<-1e4||l.getFullYear()>1e4)throw new He("Invalid date:"+t,"semantic",{type:"gantt"});return l}checked(e,t){if(!Fa(e))throw new He("Invalid date:"+t,"semantic",{type:"gantt"});return e}getEndDate(e,t){let r=t.trim(),i=N0.exec(r);if(i!==null){let c=this.references("until",i[1]),p;for(let u of c)(!p||u.startTime<p.startTime)&&(p=u);return p?p.startTime:this.today()}let n=this.dateFormat.trim(),l=this.parse(r,n);if(l)return this.inclusiveEndDates?ur(l,1):l;let[s,a]=Y0(r);if(Number.isNaN(s))return this.warn(()=>`Gantt: "${r}" is neither a date in the "${n}" format nor a duration such as "3d", so the task gets no duration.`),new Date(e);let d=Ac(e,s,a);return Fa(d)?d:new Date(e)}checkTaskDates(e){if(this.excludes.length===0||e.manualEndTime)return;let t=ur(e.startTime,1),r=new Date(e.endTime),i=+ur(r,1e4),n=!1,l=null;for(;+t<=+r;){if(this.spend(W0),n||(l=+r),n=this.isInvalidDate(t),n&&(r.setDate(r.getDate()+1),+r>i))throw new He("Failed to find a valid date that was not excluded by `excludes` after 10,000 iterations.","semantic",{type:"gantt"});t.setDate(t.getDate()+1)}e.endTime=r,e.renderEndTime=l===null?null:new Date(l)}},B0=["$end","INVALID","open_directive","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","NL","href","callbackname","callbackargs","click","gantt","dateFormat","inclusiveEndDates","topAxis","axisFormat","tickInterval","includes","excludes","todayMarker","weekday_monday","weekday_tuesday","weekday_wednesday","weekday_thursday","weekday_friday","weekday_saturday","weekday_sunday","weekend_friday","weekend_saturday","date","title","accDescription","section","taskTxt","taskData",":","EOF"],U0=/accTitle\s*:\s*/iy,q0=/accDescr\s*:\s*/iy,j0=/accDescr\s*\{\s*/iy,X0=/href\s+"/iy,V0=/call\s+/iy,K0=/click\s+/iy,Z0=/\(\s*\)/y,Tl=/weekday\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/iy,Q0=["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],Cl=/weekend\s+(?:(friday)|saturday)\b/iy,J0=/\d\d\d\d-\d\d-\d\d\b/y,e1=new Map([[97,[[/axisFormat\s[^#\n;]+/iy,17],[/accDescription\s[^#\n;]+/iy,33]]],[103,[[/gantt\b/iy,13]]],[100,[[/dateFormat\s[^#\n;]+/iy,14]]],[105,[[/inclusiveEndDates\b/iy,15],[/includes\s[^#\n;]+/iy,19]]],[116,[[/topAxis\b/iy,16],[/tickInterval\s[^#\n;]+/iy,18],[/todayMarker\s[^\n;]+/iy,21],[/title\s[^\n]+/iy,32]]],[101,[[/excludes\s[^#\n;]+/iy,20]]],[115,[[/section\s[^\n]+/iy,34]]]]);function t1(e){let t=e.length,r=[],i=[],n=[],l=0,s=0,a=(u,h,$)=>{r.push(u),i.push(e.slice(h,$)),n.push(h),s=$},d=u=>(u.lastIndex=s,u.test(e)?u.lastIndex:-1),c=(u,h)=>{let $=e.indexOf(u,h);return $===-1?t:$},p=u=>{let h;switch(u|32){case 97:if((h=d(U0))>=0)return l=1,a(3,s,h),!0;if((h=d(q0))>=0)return l=2,a(5,s,h),!0;if((h=d(j0))>=0)return l=3,s=h,!0;break;case 104:if((h=d(X0))>=0)return l=4,s=h,!0;break;case 99:if((h=d(V0))>=0)return l=5,s=h,!0;if((h=d(K0))>=0)return l=7,s=h,!0;break;case 119:{Tl.lastIndex=s;let g=Tl.exec(e);if(g)return a(22+Q0.indexOf(g[1].toLowerCase()),s,Tl.lastIndex),!0;if(Cl.lastIndex=s,g=Cl.exec(e),g)return a(g[1]!==void 0?29:30,s,Cl.lastIndex),!0;break}}let $=e1.get(u|32);if($){for(let[g,T]of $)if((h=d(g))>=0)return a(T,s,h),!0}return!1};for(;;){if(s>=t){let h=38;switch(l){case 1:h=4;break;case 2:h=6;break;case 3:h=7;break;case 4:h=9;break;case 5:h=10;break;case 6:h=11;break;case 7:h=12;break}a(h,t,t);break}let u=e.charCodeAt(s);switch(l){case 0:{let h=e.charCodeAt(s+1);if(u===37)if(h!==37){let $=c(`
78`,s+1);for(;e.charCodeAt($)===10;)$++;s=$}else{if(e.charCodeAt(s+2)===123)return a(2,s,s+3),a(1,s,s),{types:r,texts:i,starts:n};s=c(`
79`,s+2)}else if(u!==125&&h===37)s=c(`
80`,s+2);else if(u===10){let $=s+1;for(;e.charCodeAt($)===10;)$++;a(8,s,$)}else if(Le(u))for(s++;s<t&&Le(e.charCodeAt(s));)s++;else{if(p(u))break;if(u>=48&&u<=57&&d(J0)>=0)a(31,s,s+10);else if(u!==58){let $=s+1;for(;$<t;){let g=e.charCodeAt($);if(g===58||g===10)break;$++}a(35,s,$)}else{let $=s+1;for(;$<t;){let g=e.charCodeAt($);if(g===35||g===10||g===59)break;$++}a($>s+1?36:37,s,$)}}break}case 1:case 2:{let h=l===1?4:6;l=0,a(h,s,c(`
81`,s));break}case 3:u===125?(l=0,s++):a(7,s,c("}",s));break;case 4:u===34?(l=0,s++):a(9,s,c('"',s));break;case 5:if(u===40){let h=d(Z0);h>=0?(l=0,s=h):(l=6,s++)}else a(10,s,c("(",s));break;case 6:u===41?(l=0,s++):a(11,s,c(")",s));break;case 7:if(Le(u))l=0,s++;else{let h=s+1;for(;h<t&&!Le(e.charCodeAt(h));)h++;a(12,s,h)}break}}return r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n}}var r1=["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],wc="'EOF', 'SPACE', 'NL', 'weekday_monday', 'weekday_tuesday', 'weekday_wednesday', 'weekday_thursday', 'weekday_friday', 'weekday_saturday', 'weekday_sunday', 'weekend_friday', 'weekend_saturday', 'dateFormat', 'inclusiveEndDates', 'topAxis', 'axisFormat', 'tickInterval', 'excludes', 'includes', 'todayMarker', 'title', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'section', 'taskTxt', 'click'",es=new Uint8Array(39);for(let e=22;e<=30;e++)es[e]=1;for(let e of[38,8,14,15,16,17,18,20,19,21,32,3,5,7,34,35,12])es[e]=1;function a1(e,t){let{types:r,texts:i,starts:n}=t1(e),l=0,s=d=>{let c=r[l];throw Ve("gantt",e,n[l],`Expecting ${d}, got '${c===0?"1":B0[c]}'`)},a=(d="")=>{es[r[l]]!==1&&s(wc+d)};for(r[l]!==13&&s("'gantt'"),l++;;){let d=r[l],c=i[l];switch(es[d]!==1&&s(wc),l++,d){case 38:if(r[l]===0)return;a();break;case 8:break;case 14:a(),t.setDateFormat(c.slice(11));break;case 15:a(),t.enableInclusiveEndDates();break;case 16:a(),t.TopAxis();break;case 17:a(),t.setAxisFormat(c.slice(11));break;case 18:a(),t.setTickInterval(c.slice(13));break;case 20:a(),t.setExcludes(c.slice(9));break;case 19:a(),t.setIncludes(c.slice(9));break;case 21:a(),t.setTodayMarker(c.slice(12));break;case 29:a(),t.setWeekend("friday");break;case 30:a(),t.setWeekend("saturday");break;case 32:a(),t.setDiagramTitle(c.slice(6));break;case 3:{r[l]!==4&&s("'acc_title_value'");let p=i[l++];a(),t.setAccTitle(p.trim());break}case 5:{r[l]!==6&&s("'acc_descr_value'");let p=i[l++];a(),t.setAccDescription(p.trim());break}case 7:a(),t.setAccDescription(c.trim());break;case 34:a(),t.addSection(c.slice(8));break;case 35:{r[l]!==36&&s("'taskData'");let p=i[l++];a(),t.addTask(c,p);break}case 12:{let p,u=null,h;r[l]===10?(p=i[l++],r[l]===11&&(u=i[l++]),r[l]===9?(h=i[l++],a()):a(u===null?", 'callbackargs', 'href'":", 'href'")):r[l]===9?(h=i[l++],r[l]===10?(p=i[l++],r[l]===11?(u=i[l++],a()):a(", 'callbackargs'")):a(", 'callbackname'")):s("'callbackname', 'href'"),p!==void 0&&t.setClickEvent(c,p,u),h!==void 0&&t.setLink(c,h);break}default:a(),t.setWeekday(r1[d-22])}}}var Qt=1e3,Jt=60*Qt,Dr=60*Jt,Nr=24*Dr,Pa=7*Nr,Dl=30*Nr,ts=365*Nr;function Ki(e){e.setHours(0,0,0,0)}function as(e){return{floor(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),Ki(t)},offset:(t,r)=>t.setDate(t.getDate()+r*7),cycle:1/0,ms:Pa}}var Wa={millisecond:{floor:()=>{},offset:(e,t)=>e.setTime(+e+t),cycle:1/0,ms:1},second:{floor:e=>e.setTime(+e-e.getMilliseconds()),offset:(e,t)=>e.setTime(+e+t*Qt),field:e=>e.getUTCSeconds(),cycle:60,ms:Qt},minute:{floor:e=>e.setTime(+e-e.getMilliseconds()-e.getSeconds()*Qt),offset:(e,t)=>e.setTime(+e+t*Jt),field:e=>e.getMinutes(),cycle:60,ms:Jt},hour:{floor:e=>e.setTime(+e-e.getMilliseconds()-e.getSeconds()*Qt-e.getMinutes()*Jt),offset:(e,t)=>e.setTime(+e+t*Dr),field:e=>e.getHours(),cycle:24,ms:Dr},day:{floor:Ki,offset:(e,t)=>e.setDate(e.getDate()+t),field:e=>e.getDate()-1,cycle:31,ms:Nr},month:{floor(e){e.setDate(1),Ki(e)},offset:(e,t)=>e.setMonth(e.getMonth()+t),field:e=>e.getMonth(),cycle:12,ms:Dl},year:{floor(e){e.setMonth(0,1),Ki(e)},offset:(e,t)=>e.setFullYear(e.getFullYear()+t),cycle:1/0,ms:ts}};function rs(e,t,r){return Math.floor((+t-+e-(t.getTimezoneOffset()-e.getTimezoneOffset())*Jt)/r)}function i1(e,t){return(e%t+t)%t}function Zi(e,t,r){let i=e==="week"?as(r):Wa[e];if(t<=1)return i;if(e==="millisecond")return{...i,floor:s=>s.setTime(Math.floor(+s/t)*t),offset:(s,a)=>s.setTime(+s+a*t)};if(e==="year")return{...i,floor(s){s.setFullYear(Math.floor(s.getFullYear()/t)*t),i.floor(s)},offset:(s,a)=>s.setFullYear(s.getFullYear()+a*t)};if(e==="week"){let s=new Date(0);return i.floor(s),{...i,floor(a){i.floor(a),i.offset(a,-i1(rs(s,a,Pa),t))},offset:(a,d)=>i.offset(a,d*t)}}let n=i.field,l=s=>n(s)%t===0;return{...i,floor(s){for(i.floor(s);Number.isFinite(+s)&&!l(s);i.floor(s))s.setTime(+s-1)},offset(s,a){for(let d=0;d<a&&Number.isFinite(+s);d++)do i.offset(s,1);while(Number.isFinite(+s)&&!l(s))}}}function _c(e,t,r,i){let n=new Date(t-1);e.floor(n),e.offset(n,1),e.floor(n);let l=[],s=-1/0;for(;+n<=r&&+n>s;){if(l.length>=i)return;s=+n,l.push(s),e.offset(n,1),e.floor(n)}return l}function xc(e,t,r){let i=(t-e)/Math.max(0,r),n=Math.floor(Math.log10(i)),l=i/Math.pow(10,n),s=l>=Math.sqrt(50)?10:l>=Math.sqrt(10)?5:l>=Math.SQRT2?2:1;return Math.pow(10,n)*s}var ra=[["second",1,Qt],["second",5,5*Qt],["second",15,15*Qt],["second",30,30*Qt],["minute",1,Jt],["minute",5,5*Jt],["minute",15,15*Jt],["minute",30,30*Jt],["hour",1,Dr],["hour",3,3*Dr],["hour",6,6*Dr],["hour",12,12*Dr],["day",1,Nr],["day",2,2*Nr],["week",1,Pa],["month",1,Dl],["month",3,3*Dl],["year",1,ts]];function s1(e,t,r){let i=(t-e)/r,n=0;for(;n<ra.length&&ra[n][2]<=i;)n++;let l;if(n===ra.length)l=Zi("year",Math.max(1,xc(e/ts,t/ts,r)),0);else if(n===0)l=Zi("millisecond",Math.max(xc(e,t,r),1),0);else{let[s,a]=ra[i/ra[n-1][2]<ra[n][2]/i?n-1:n];l=Zi(s,a,0)}return _c(l,e,t,4*r+8)??[]}var l1=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/,n1=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"];function o1(e,t,r,i,n){let l=l1.exec(e);if(!l)return;let s=parseInt(l[1],10),a=l[2],d=Zi(a,s,Math.max(0,n1.indexOf(t)));if(!((i-r)/(Math.min(s,d.cycle)*d.ms)>n))return _c(d,r,i,n)}function mt(e,t,r){let i=e<0?"-":"",n=String(i?-e:e);return i+(n.length<r?t.repeat(r-n.length)+n:n)}function fr(e,t){let r=new Date(+e);return t.floor(r),r}function bc(e,t){let r=as(t),i=fr(e,Wa.year);return rs(fr(new Date(+i-1),r),fr(e,r),Pa)}function El(e){let t=as(4),r=e.getDay(),i=fr(r>=4||r===0?e:new Date(+e-1),t);return r>=4||r===0||(t.offset(i,1),t.floor(i)),i}var c1=new Map([["-",""],["_"," "],["0","0"]]);function Qi(e,t){let r="",i=0,n=e.length;for(let l=0;l<n;l++){if(e.charCodeAt(l)!==37)continue;r+=e.slice(i,l);let s=e.charAt(++l),a=c1.get(s);a!==void 0?s=e.charAt(++l):a=s==="e"?" ":"0",r+=d1(s,t,a),i=l+1}return r+e.slice(i)}function d1(e,t,r){switch(e){case"a":return Ir[t.getDay()].slice(0,3);case"A":return Ir[t.getDay()];case"b":return ia[t.getMonth()].slice(0,3);case"B":return ia[t.getMonth()];case"c":return Qi("%x, %X",t);case"d":case"e":return mt(t.getDate(),r,2);case"f":return mt(t.getMilliseconds(),r,3)+"000";case"g":return mt(El(t).getFullYear()%100,r,2);case"G":return mt(El(t).getFullYear()%1e4,r,4);case"H":return mt(t.getHours(),r,2);case"I":return mt(t.getHours()%12||12,r,2);case"j":return mt(1+rs(fr(t,Wa.year),fr(t,Wa.day),Nr),r,3);case"L":return mt(t.getMilliseconds(),r,3);case"m":return mt(t.getMonth()+1,r,2);case"M":return mt(t.getMinutes(),r,2);case"p":return t.getHours()>=12?"PM":"AM";case"q":return String(1+Math.floor(t.getMonth()/3));case"Q":return String(+t);case"s":return String(Math.floor(+t/1e3));case"S":return mt(t.getSeconds(),r,2);case"u":return String(t.getDay()||7);case"U":return mt(bc(t,0),r,2);case"V":{let i=El(t),n=fr(i,Wa.year),l=fr(n,as(4));return mt(rs(l,i,Pa)+(n.getDay()===4?1:0),r,2)}case"w":return String(t.getDay());case"W":return mt(bc(t,1),r,2);case"x":return Qi("%-m/%-d/%Y",t);case"X":return Qi("%-I:%M:%S %p",t);case"y":return mt(t.getFullYear()%100,r,2);case"Y":return mt(t.getFullYear()%1e4,r,4);case"Z":{let i=t.getTimezoneOffset(),n=Math.abs(i);return(i>0?"-":"+")+mt(Math.floor(n/60),"0",2)+mt(n%60,"0",2)}case"%":return"%";default:return e}}var h1=800,f1=240,aa=8,u1=/<br\s*\/?>/gi;function jt(e,t,r,i){let n=e.gantt?.[t];return typeof n=="number"&&Number.isFinite(n)?Math.min(i,Math.max(r,n)):void 0}function Sl(e,t){let r=e.gantt?.[t];return typeof r=="string"?r:void 0}function p1(e,t){return e.gantt?.[t]===!0}function kc(e,t,r){let i=Fe(e.replace(u1," "),!1,t,r,4e3);return i.lines.length<=1?i:{...i,lines:[i.lines[0]],widths:[i.widths[0]],width:i.widths[0],height:i.lineHeight}}function Ji(e){return Number.isFinite(+e.startTime)&&Number.isFinite(+e.endTime)}function g1(e,t,r){let i=e.filter(Ji).sort((s,a)=>+s.startTime-+a.startTime||s.order-a.order),n=[];for(let s of i){let a=+s.startTime,d=0;for(;d<n.length&&a<n[d];)d++;n[d]=+s.endTime,r.set(s,t+d)}let l=n.length;for(let s of e)r.has(s)||r.set(s,t+l++);return Math.max(l,1)}function m1(e,t,r){let i=r.fontSize??16,n=r.measurer??tt(r.fontFamily),l=r.padding??8,s=Sc(r.now),a=jt(t,"fontSize",4,72)??Math.round(i*.8125),d=jt(t,"sectionFontSize",4,72)??a,c=Math.round(i*.75),p=jt(t,"barHeight",4,400)??Math.round(a*1.85),u=jt(t,"barGap",0,400)??Math.round(p/4),h=p+u,$=Math.round(jt(t,"numberSectionStyles",1,1e3)??4),g=e.displayMode==="compact",T=e.topAxis||p1(t,"topAxis"),D=e.getTasks(s),_=D.filter(ye=>!ye.vert),F=D.filter(ye=>ye.vert&&Ji(ye)),k=new Map;for(let ye of _)k.has(ye.section)||k.set(ye.section,k.size);let I=new Map,E=[];if(g){let ye=new Map;for(let Me of _){let Se=ye.get(Me.section);Se?Se.push(Me):ye.set(Me.section,[Me])}for(let[Me,Se]of ye){let q=g1(Se,E.length,I);for(let ce=0;ce<q;ce++)E.push(Me)}}else for(let ye of _)I.set(ye,E.length),E.push(ye.section);let m=E.length,y=1/0,C=-1/0;for(let ye of D)Ji(ye)&&(y=Math.min(y,+ye.startTime),C=Math.max(C,+ye.endTime));let L=y<=C,S=Fe(e.title,!1,n,i,4e3,1),Z=S.height>0?S.height+16:0;if(!L){let ye=Math.ceil(Math.max(S.width,1)+2*l),Me=Math.ceil(Math.max(S.height,1)+2*l),Se=Ne(S,ye/2,l+S.height/2,' class="pele-title" font-weight="var(--_tw)"');return{svg:Je("gantt",ye,Me,i,r,e,Se),width:ye,height:Me,links:[]}}let H=new Map,R=0;for(let ye of k.keys()){let Me=Fe(ye,!1,n,d,180);H.set(ye,Me),R=Math.max(R,Me.width)}let P=e.axisFormat||(e.dateFormat==="D"?"%d":Sl(t,"axisFormat")??"%Y-%m-%d"),w=ye=>Qi(P,new Date(ye)),b=Math.max(n.width(w(y),c,0),n.width(w(C),c,0)),M=l+(jt(t,"leftPadding",0,2e3)??Math.max(R>0?R+24:0,b/2)),f=jt(t,"rightPadding",0,2e3)??Math.max(16,b/2),x=Xr(r,jt(t,"useWidth",100,2e4)??h1,280),A=Math.max(f1,x-M-f-l),z=M+A,v=C>y?A/(C-y):0,G=ye=>v===0?M+A/2:M+(ye-y)*v,ee=Math.round(c*1.75),he=jt(t,"topPadding",0,2e3),ue=jt(t,"gridLineStartPadding",0,2e3),V=l+Z+(T?ee:0),Y=Math.max(V,he??0),de=he!==void 0&&ue!==void 0?Math.max(0,Math.min(he-ue,Y-V)):0,te=Math.max(m,1)*h,xe=Y+te,me=[],ae=z+f;for(let ye of _){let Me=kc(ye.task,n,a),Se=I.get(ye);if(!Ji(ye)){let ve=M+aa+Me.width/2;ae=Math.max(ae,ve+Me.width/2),me.push({task:ye,label:Me,row:Se,x0:NaN,x1:NaN,labelX:ve,inside:!1});continue}let q=G(+ye.startTime),ce=Math.max(G(+(ye.renderEndTime??ye.endTime)),q+(ye.milestone?0:2));if(ye.milestone){let ve=q+(G(+ye.endTime)-q)/2;q=ve-p/2,ce=ve+p/2}let be=!ye.milestone&&Me.width+2*aa<=ce-q,Ce=(q+ce)/2;if(!be){let ve=ce+aa+Me.width<=z+f,ke=q-aa-Me.width>=M;Ce=ve||!ke?ce+aa+Me.width/2:q-aa-Me.width/2,ae=Math.max(ae,Ce+Me.width/2)}me.push({task:ye,label:Me,row:Se,x0:q,x1:ce,labelX:Ce,inside:be})}let O=e.tickInterval||Sl(t,"tickInterval")||"",B=e.weekday??Sl(t,"weekday")??"sunday",Q=Math.max(2,Math.min(10,Math.floor(A/(b+24)))),se=o1(O,B,y,C,Math.ceil(A/3))??s1(y,C,Q),ie="",re="",ne="",X=-1/0,j="",oe=xe+ee/2+2,$e=Y-de-ee/2-2;for(let ye of se){let Me=G(ye);ie+=`M${o(Me)},${o(Y-de)}V${o(xe)}`;let Se=w(ye),q=n.width(Se,c,0);if(Me-q/2<X+8||Se===j)continue;X=Me+q/2,j=Se,ae=Math.max(ae,X);let ce=`text-anchor="middle">${Be(Se)}</text>`;re+=`<text x="${o(Me)}" y="${o(oe+c*.35)}" ${ce}`,T&&(ne+=`<text x="${o(Me)}" y="${o($e+c*.35)}" ${ce}`)}let ge="",Te="",pe=[],W=xe+ee+4,K=Math.round(a*1.5);for(let ye of[...F].sort((Me,Se)=>+Me.startTime-+Se.startTime)){let Me=G(+ye.startTime),Se=kc(ye.task,n,a),q=Math.max(l+Se.width/2,Me),ce=0;for(;ce<pe.length&&q-Se.width/2<pe[ce]+8;)ce++;pe[ce]=q+Se.width/2,ae=Math.max(ae,pe[ce]),ge+=`<path class="pele-vert" data-id="${Oe(ye.id)}" d="M${o(Me)},${o(Y-de)}V${o(xe)}"/>`,Te+=Ne(Se,q,W+ce*K+K/2,` class="pele-vert-label" data-id="${Oe(ye.id)}"`)}let N=Math.ceil(Math.max(ae,l+S.width)+l),U=Math.ceil(xe+ee+(pe.length>0?4+pe.length*K:0)+l),J="",le="";for(let ye=0;ye<m;){let Me=E[ye],Se=ye+1;for(;Se<m&&E[Se]===Me;)Se++;let q=k.get(Me)%$,ce=Y+ye*h,be=(Se-ye)*h;(k.size>1||Me!=="")&&(J+=`<rect class="pele-section pele-section-${q}" x="0" y="${o(ce)}" width="${N}" height="${o(be)}" fill="${q%2===0?"var(--_s)":"none"}"/>`);let Ce=H.get(Me);le+=Ne(Ce,l+8+Ce.width/2,ce+be/2,` class="pele-section-label" data-id="${Oe(Me)}"`,r.icons),ye=Se}let fe="";if((e.excludes.length>0||e.includes.length>0)&&+Ac(new Date(y),6,"y")>C){let ye,Me,Se=()=>{if(!ye||!Me)return;let q=new Date(ye);q.setHours(0,0,0,0);let ce=new Date(Me);ce.setHours(23,59,59,999);let be=Math.max(M,G(+q)),Ce=Math.min(z,G(+ce));Ce>be&&(fe+=`<rect x="${o(be)}" y="${o(Y)}" width="${o(Ce-be)}" height="${o(te)}"/>`),ye=Me=void 0};for(let q=new Date(y);+q<=C;q=ur(q,1))e.isInvalidDate(q)?(ye??=q,Me=q):Se();Se()}let we=[],Ee="";for(let ye of me){let Me=ye.task,Se=Y+ye.row*h+h/2,q=Me.active?"active":Me.done?"done":"",ce="pele-task";q&&(ce+=" pele-"+q),Me.crit&&(ce+=" pele-crit"),Me.milestone&&(ce+=" pele-milestone"),Me.classes.includes("clickable")&&(ce+=" pele-clickable");let be="",Ce="";if(Number.isNaN(ye.x0))ce+=" pele-unscheduled",Ce=' fill="var(--_m)"';else{let Re=Me.crit?Cn:"var(--_c)",ze=q==="done"?'fill="var(--_a)"':q==="active"?`fill="${Re}" fill-opacity="0.25"`:`fill="${Re}"`,We=`stroke="${q==="done"&&!Me.crit?"var(--_b)":Re}"`;if(Me.milestone){let je=(ye.x0+ye.x1)/2,st=p/2;be=`<path d="M${o(je)},${o(Se-st)}L${o(je+st)},${o(Se)}L${o(je)},${o(Se+st)}L${o(je-st)},${o(Se)}Z" ${ze} ${We} stroke-linejoin="round"/>`}else be=`<rect x="${o(ye.x0)}" y="${o(Se-p/2)}" width="${o(ye.x1-ye.x0)}" height="${o(p)}" rx="${Ke}" ${ze} ${We}/>`;ye.inside?Ce=q===""?' fill="var(--_bg)"':"":q==="done"&&(Ce=' fill="var(--_m)"')}let ve=be+Ne(ye.label,ye.labelX,Se,` class="pele-label"${Ce}`),ke=e.links.get(Me.id);ke!==void 0&&(ve=cr(ve,ke,Me.id,we,r)),Ee+=`<g class="${ce}" data-id="${Oe(Me.id)}">${ve}</g>`}let Ae="";if(e.todayMarker!=="off"&&s>=y&&s<=C&&C>y){let ye=G(s),Me=Y-de,Se=e.todayMarker?ct(e.todayMarker.split(",")).line:"";Ae=`<g class="pele-today"><path d="M${o(ye)},${o(Me)}V${o(xe)}" fill="none" stroke="var(--_c)" stroke-width="2"${Se}/>`+(Se?"":`<path d="M${o(ye-4)},${o(Me-5)}H${o(ye+4)}L${o(ye)},${o(Me+1)}Z" fill="var(--_c)"/>`)+"</g>"}let De=`M${o(M)},${o(xe)}H${o(z)}`+(T?`M${o(M)},${o(Y-de)}H${o(z)}`:""),Ie=Ne(S,N/2,l+S.height/2,' class="pele-title" font-weight="var(--_tw)"')+(J?`<g class="pele-sections">${J}</g>`:"")+(fe?`<g class="pele-excluded" fill="var(--_a)">${fe}</g>`:"")+`<g class="pele-grid" fill="none"><path d="${ie}" stroke="var(--_b)" stroke-dasharray="1 3"/><path d="${De}" stroke="var(--_b)"/></g>`+(ge?`<g class="pele-verts" fill="none" stroke="var(--_l)" stroke-width="1.5" stroke-dasharray="4 3">${ge}</g>`:"")+Ae+`<g class="pele-tasks" font-size="${o(a)}">${Ee}</g><g class="pele-section-labels" font-size="${o(d)}">${le}</g><g class="pele-axis" font-size="${c}" fill="var(--_m)">${re}${ne}</g>`+(Te?`<g class="pele-vert-labels" font-size="${o(a)}">${Te}</g>`:"");return{svg:Je("gantt",N,U,i,r,e,Ie),width:N,height:U,links:we}}var Il={type:"gantt",parse(e,t,r){let i=new G0;r&&(i.title=r);let n=t.gantt?.displayMode;return typeof n=="string"&&(i.displayMode=n),a1(e,i),i},render:m1};function yt(e,t,r){for(let i=0;i<r.length;i++){let n=e.charCodeAt(t+i),l=r.charCodeAt(i);if(n!==l&&!(l>=97&&l<=122&&n===l-32))return!1}return!0}var y1=class{type="xychart";title;accTitle;accDescr;orientation;xAxis={type:"band",title:"",categories:[]};yAxis={type:"linear",title:"",min:1/0,max:-1/0};hasSetXAxis=!1;hasSetYAxis=!1;plots=[];setOrientation(e){this.orientation=e==="horizontal"?"horizontal":"vertical"}setXAxisTitle(e){this.xAxis.title=e.text.trim()}setXAxisRangeData(e,t){this.xAxis={type:"linear",title:this.xAxis.title,min:e,max:t},this.hasSetXAxis=!0}setXAxisBand(e){this.xAxis={type:"band",title:this.xAxis.title,categories:e.map(t=>t.text.trim())},this.hasSetXAxis=!0}setYAxisTitle(e){this.yAxis.title=e.text.trim()}setYAxisRangeData(e,t){this.yAxis={type:"linear",title:this.yAxis.title,min:e,max:t},this.hasSetYAxis=!0}plotData(e){if(e.length===0)return[];this.hasSetXAxis||this.setXAxisRangeData(1,e.length);let t=this.xAxis;if(t.type==="band"&&e.length>t.categories.length&&(e=e.slice(0,t.categories.length)),!this.hasSetYAxis){let{min:i,max:n}=this.yAxis;for(let l of e)l<i&&(i=l),l>n&&(n=l);this.yAxis={type:"linear",title:this.yAxis.title,min:i,max:n}}if(t.type==="band")return t.categories.map((i,n)=>[i,e[n]]);if(e.length===1)return[[`${t.min}`,e[0]]];let r=(t.max-t.min)/(e.length-1);return e.map((i,n)=>[`${t.min+n*r}`,i])}addPlot(e,t,r){let i={type:e,title:t.text.trim(),data:this.plotData(r.map(n=>n.value))};e==="line"&&r.some(n=>n.label.trim()!=="")&&(i.pointLabels=r.map(n=>n.label.trim())),this.plots.push(i)}setLineData(e,t){this.addPlot("line",e,t)}setBarData(e,t){this.addPlot("bar",e,t)}setDiagramTitle(e){this.title=e}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
82`)}},Dc=["$end","INVALID","NEWLINE","title","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","XYCHART","CHART_ORIENTATION","X_AXIS","Y_AXIS","ARROW_DELIMITER","LINE","BAR","NUMBER_WITH_DECIMAL","SQUARE_BRACES_START","SQUARE_BRACES_END","STR","ALPHA","COLON","PLUS","COMMA","EQUALS","MULT","BRKT","UNDERSCORE","DOT","AMP","MINUS","NUM","SEMI","EOF"],Ic=[33,33,33,33,33,19,5,7,8],Nc="`)"+" ".repeat(36)+'{ this.pushstate(md_string); }\n<md_string>(?:(?!`").)+'+" ".repeat(18)+"{ return md_str; }\n<md_string>(?:`",Ll=new Uint8Array(128);for(let[e,t]of[[":",21],["+",22],[",",23],["=",24],["*",25],["#",26],["_",27],[".",28],["&",29],["-",30],[";",32]])Ll[e.charCodeAt(0)]=t;function $1(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=(T,D,_)=>{r.push(T),i.push(e.slice(D,_)),n.push(D),a=_},c=T=>{l.push(s),s=T},p=()=>{l.length>0&&(s=l.pop())},u=T=>{let D=e.indexOf(`
83`,T);return D===-1?t:D},h=T=>{for(;T<t&&Le(e.charCodeAt(T));)T++;return T},$=T=>{for(;ot(e.charCodeAt(T));)T++;return T},g=T=>yt(e,a,T)&&!Pe(e.charCodeAt(a+T.length));for(;a<t;){let T=e.charCodeAt(a);if(s===5){if(T===34)a++,p();else{let _=e.indexOf('"',a);d(19,a,_===-1?t:_)}continue}if(s===6||s===7){d(Ic[s],a,u(a)),p();continue}if(s===8){if(T===125)a++,p();else{let _=e.indexOf("}",a);d(8,a,_===-1?t:_)}continue}let D=e.charCodeAt(a+1);if(T===37&&D===37){a=u(a+2);continue}if(T!==125&&D===37&&e.charCodeAt(a+2)===37){a=u(a+3);continue}if(T===10||T===13){if((s===1||s===3)&&(T===10||D===10)){d(2,a,T===10?a+1:a+2),p();continue}let _=a+1;for(let F=e.charCodeAt(_);F===10||F===13;F=e.charCodeAt(++_));d(2,a,_);continue}switch(T|32){case 116:if(g("title")){d(3,a,a+5);continue}break;case 97:if(yt(e,a,"acc")){let _=yt(e,a+3,"descr");if(_||yt(e,a+3,"title")){let F=h(a+8),k=e.charCodeAt(F);if(k===58){d(_?6:4,a,h(F+1)),c(_?7:6);continue}if(k===123&&_){a=h(F+1),c(8);continue}}}break;case 120:if(g("xychart-beta")){d(9,a,a+12);continue}if(g("xychart")){d(9,a,a+7);continue}if(g("x-axis")){d(11,a,a+6),c(1);continue}break;case 121:if(g("y-axis")){d(12,a,a+6),c(1);continue}break;case 118:if(yt(e,a,"vertical")){d(10,a,a+8);continue}break;case 104:if(yt(e,a,"horizontal")){d(10,a,a+10);continue}break;case 108:if(g("line")){d(14,a,a+4),c(3);continue}break;case 98:if(g("bar")){d(15,a,a+3),c(3);continue}break}if(T===91){s===1?c(2):s===3&&c(4),d(17,a,a+1);continue}if(T===93){(s===4||s===2)&&p(),d(18,a,a+1);continue}if(s===1&&T===45&&D===45&&e.charCodeAt(a+2)===62){d(13,a,a+3);continue}if(s===1||s===4){let _=T===43||T===45?a+1:a,F=e.charCodeAt(_),k=-1;if(ot(F)?(k=$(_+1),e.charCodeAt(k)===46&&ot(e.charCodeAt(k+1))&&(k=$(k+2))):F===46&&ot(e.charCodeAt(_+1))&&(k=$(_+2)),k!==-1){d(16,a,k);continue}}if(T===96&&yt(e,a,Nc)){a+=Nc.length,p();continue}if(T===34){a++,c(5);continue}if(Pr(T)){let _=a+1;for(;Pr(e.charCodeAt(_));)_++;d(20,a,_);continue}if(ot(T)){d(31,a,$(a+1));continue}if(Le(T)){a=h(a+1);continue}if(T<128&&Ll[T]!==0){d(Ll[T],a,a+1);continue}break}return a<t?(r.push(1),i.push(""),n.push(a),{types:r,texts:i,starts:n}):(r.push(Ic[s]),i.push(""),n.push(t),r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n})}function Gc(...e){let t=new Uint8Array(34);for(let r of e)t[r]=1;return t}var Lc=Gc(29,31,20,22,24,25,28,26,30,27),Oc=Gc(2,32,33);function w1(e,t){let{types:r,texts:i,starts:n}=$1(e),l=0,s=h=>{let $=r[l];throw $===1?Ve("xychart",e,n[l],"",!0):Ve("xychart",e,n[l],`Expecting ${h}, got '${Dc[$]}'`)},a=h=>(r[l]!==h&&s(`'${Dc[h]}'`),i[l++]),d=h=>h===19||Lc[h]===1,c=()=>{d(r[l])||s("'STR', 'ALPHA', 'NUM'");let h=i[l++];if(r[l-1]!==19)for(;Lc[r[l]]===1;)h+=i[l++];return{text:h,type:"text"}},p=()=>{let h=Number(a(16));return a(13),[h,Number(a(16))]},u=()=>{let h=[];for(a(17);;){let $=Number(a(16));if(h.push({value:$,label:r[l]===19?i[l++]:""}),r[l]!==23)break;l++}return a(18),h};for(;;)if(Oc[r[l]]===1)l++;else{if(r[l]!==9)break;r[++l]===10&&t.setOrientation(i[l++])}for(;r[l]!==0;){let h=r[l++];switch(h){case 3:t.setDiagramTitle(c().text.trim());break;case 11:case 12:{let $=d(r[l])?c():void 0;if(h===11&&r[l]===17){let g=[];do l++,g.push(c());while(r[l]===23);a(18),t.setXAxisBand(g)}else if(r[l]===16||$===void 0){let[g,T]=p();h===11?t.setXAxisRangeData(g,T):t.setYAxisRangeData(g,T)}h===11?t.setXAxisTitle($??{type:"text",text:""}):t.setYAxisTitle($??{type:"text",text:""});break}case 14:case 15:{let $=r[l]===17?{text:"",type:"text"}:c(),g=u();h===14?t.setLineData($,g):t.setBarData($,g);break}case 4:t.setAccTitle(a(5).trim());break;case 6:t.setAccDescription(a(7).trim());break;case 8:t.setAccDescription(i[l-1].trim());break;default:l--,s("'title', 'X_AXIS', 'Y_AXIS', 'LINE', 'BAR', 'acc_title', 'acc_descr', 'acc_descr_multiline_value'")}for(;Oc[r[l]]===1;)l++}}function Rc(e,t){let r=e/Math.max(t,1),i=Math.floor(Math.log10(r)),n=r/10**i,l=n>=7.07?10:n>=3.16?5:n>=1.41?2:1;return i<0?-(10**-i)/l:l*10**i}function ss(e,t){return e>0?t/e:t*-e}function Ha(e,t){return e>0?t*e:t/-e}function zc(e,t,r){let i=Math.round(ss(r,e));Ha(r,i)<e&&i++;let n=Math.round(ss(r,t));Ha(r,n)>t&&n--;let l=[];for(let s=i;s<=n&&l.length<100;s++)l.push(Ha(r,s));return l}var Fc=4,sa=12,Wc=26,Pc=24,Hc=1e300;function Nl(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:{}}function Ot(e,t,r=!0){let i=e[t];return typeof i=="boolean"?i:r}function Yc(e,t){return typeof e=="number"&&e>0?Math.round(Math.min(Math.max(e,100),4e3)):t}function pr(e){return typeof e=="number"&&isFinite(e)?Math.min(Math.max(e,-Hc),Hc):void 0}function x1(e){let t=0;for(let r of e)t=Math.max(t,r.label.width);return t}function is(e,t,r,i){let n=e.lines.length===1?e.lines[0]:void 0;return n&&n.length===1&&n[0].icon===void 0&&n[0].style===0?`<text x="${o(t)}" y="${o(r+e.size*.35)}" text-anchor="${i}">${Be(n[0].text)}</text>`:Ne(e,t+(i==="start"?e.width/2:i==="end"?-e.width/2:0),r,"")}function b1(e,t,r){if(e.plots.length===0)throw new He("No Plot to render, please provide a plot with some data","semantic",{type:"xychart"});let i=Nl(t.xyChart),n=r.fontSize??16,l=Math.round(n*.875),s=Math.round(n*.75),a=r.measurer??tt(r.fontFamily),d=r.padding??8,c=Yc(i.width,700),p=Xr(r,c,240),u=Math.round(Yc(i.height,500)*Math.max(.6,p/c)),h=(e.orientation??i.chartOrientation)==="horizontal",$=Ot(i,"showDataLabel",!1),g=e.xAxis,T=e.plots,D=(_e,Ye,Xe)=>Fe(_e,!1,a,Ye,Xe),_=D("0",l,4e3).height,F=D("0",s,4e3).height,k=Fe(Ot(i,"showTitle")?e.title:void 0,!1,a,n,p-2*d,1),I=k.height>0?k.height+12:0,E=[],m=0;Ot(i,"showLegend")&&T.forEach((_e,Ye)=>{if(_e.title==="")return;let Xe=D(_e.title,l,p*.3);E.push({index:Ye,label:Xe}),m=Math.max(m,Xe.width+sa+8)});let y=E.length>0?m+Pc:0,C=T.filter(_e=>_e.type==="bar").length,L=e.yAxis.min,S=e.yAxis.max,Z=e.hasSetYAxis&&isFinite(L)&&isFinite(S)&&L!==S;if(Z)L=pr(L),S=pr(S);else{L=1/0,S=-1/0;for(let _e of T)for(let[,Ye]of _e.data){let Xe=pr(Ye);Xe!==void 0&&(Xe<L&&(L=Xe),Xe>S&&(S=Xe))}L>S&&(L=S=0),C>0&&(L=Math.min(L,0),S=Math.max(S,0)),L===S&&(L===0?S=1:(L-=Math.abs(L)/2,S+=Math.abs(S)/2))}let H=(_e,Ye)=>{let Xe=Rc(Math.abs(S-L),Math.max(2,Math.min(10,Math.floor(_e/Ye))));return Z||(L=Ha(Xe,Math.floor(ss(Xe,L)+1e-9)),S=Ha(Xe,Math.ceil(ss(Xe,S)-1e-9))),zc(Math.min(L,S),Math.max(L,S),Xe).map(ht=>({at:(ht-L)/(S-L),label:D(String(ht),l,4e3)}))},R=1;if(g.type==="band")R=Math.max(g.categories.length,1);else for(let _e of T)R=Math.max(R,_e.data.length);let P=1/R,w=g.type==="band"||C>0?P/2:0,b=pr(g.type==="linear"?g.min:void 0),M=pr(g.type==="linear"?g.max:void 0),f=b!==void 0&&M!==void 0&&b!==M,x=(_e,Ye)=>g.type==="band"?(_e+.5)*P:w+(Ye>1?_e/(Ye-1):f?0:.5)*(1-2*w),A=Nl(i.xAxis),z=Nl(i.yAxis),v=h?A:z,G=h?z:A,ee=D(Ot(v,"showTitle")?h?g.title:e.yAxis.title:void 0,l,u*.8),he=D(Ot(G,"showTitle")?h?e.yAxis.title:g.title:void 0,l,p*.8),ue=Ot(v,"showTick")?Fc:0,V=Ot(G,"showTick")?Fc:0,Y=Ot(v,"showLabel"),de=Ot(G,"showLabel"),te=h?p*.3:Math.max(48,(p-2*d-64-y)*P-8),xe=g.type==="band"&&Ot(A,"showLabel")?g.categories.map(_e=>D(_e,l,te)):[],me=0,ae=0;for(let _e of xe)me=Math.max(me,_e.width),ae=Math.max(ae,_e.height);let O=_e=>{let Ye=[];if(g.type==="band"){let Xe=xe.length===0?8:h?ae:me+12,ht=Math.max(1,Math.ceil(Xe/(_e*P)));for(let $t=0;$t<g.categories.length;$t+=ht)Ye.push({at:($t+.5)*P,label:xe[$t]??D(void 0,l,0)})}else if(f){let Xe=Rc(Math.abs(M-b),Math.max(2,Math.min(10,Math.floor(_e/(h?32:80)))));for(let ht of zc(Math.min(b,M),Math.max(b,M),Xe))Ye.push({at:w+(ht-b)/(M-b)*(1-2*w),label:D(String(ht),l,4e3)})}else b!==void 0&&Ye.push({at:.5,label:D(String(b),l,4e3)});return Ye},B=0,Q=0;for(let _e of T){for(let Ye of _e.pointLabels??[])B=Math.max(B,a.width(Ye,s,0));if($&&h&&_e.type==="bar")for(let[,Ye]of _e.data)Q=Math.max(Q,a.width(String(pr(Ye)??""),s,0))}let se=de?h||g.type!=="band"?_:ae:0,ie=V+(se>0?se+4:0)+(he.height>0?he.height+4:0),re=h?0:B>0||$?F+4:Y?_/2:0,ne=d+I+re,X=Math.max(1,u-d-ie-ne),j=ne+X,oe=h?O(X):H(X,56),$e=Y?x1(oe):0,ge=d+(ee.height>0?ee.height+6:0)+($e>0?$e+6:0)+ue,Te=Math.max(B>0?B+12:0,Q>0?Q+8:0),pe=h?Math.min(p*.25,Te):0,W=Math.max(1,p-d-ge-y-pe),K=h?H(W,80):O(W);if(de&&y+pe===0){let _e=0;for(let Ye of K)_e=Math.max(_e,Ye.at*W+Ye.label.width/2-W);W=Math.max(1,W-_e)}let N=ge+W,U=(_e,Ye)=>h?ge+Ye*W:ge+_e*W,J=(_e,Ye)=>h?ne+_e*X:j-Ye*X,le=_e=>(_e-L)/(S-L),fe=_e=>Math.min(Math.max(_e,0),1),we=_e=>h?`M${o(U(0,_e))},${o(ne)}V${o(j)}`:`M${o(ge)},${o(J(0,_e))}H${o(N)}`,Ee="";for(let _e of h?K:oe)Ee+=we(_e.at);let Ae="",De="";Ot(v,"showAxisLine")&&(Ae+=`M${o(ge)},${o(ne)}V${o(j)}`),Ot(G,"showAxisLine")&&(Ae+=`M${o(ge)},${o(j)}H${o(N)}`);for(let _e of oe){let Ye=h?ne+_e.at*X:j-_e.at*X;ue&&(Ae+=`M${o(ge)},${o(Ye)}h${-ue}`),Y&&(De+=is(_e.label,ge-ue-6,Ye,"end"))}for(let _e of K){let Ye=ge+_e.at*W;V&&(Ae+=`M${o(Ye)},${o(j)}v${V}`),de&&(De+=is(_e.label,Ye,j+V+4+_e.label.height/2,"middle"))}let Ie=(h?X:W)*P,ye=Ie*.7/Math.max(C,1),Me=C>1?Math.min(2,ye*.2):0,Se=fe(le(0));C>0&&Se>0&&Se<1&&(Ae+=we(Se));let q="",ce="",be="",Ce="",ve=0;T.forEach((_e,Ye)=>{let Xe=it(Ye),ht=_e.title?` data-id="${Oe(_e.title)}"`:"",$t=g.type==="band"?Math.min(_e.data.length,R):_e.data.length;if(_e.type==="bar"){let Ge=(ve++-(C-1)/2)*ye-(ye-Me)/2,at="";for(let Qe=0;Qe<$t;Qe++){let Ze=pr(_e.data[Qe][1]);if(Ze===void 0)continue;let ft=x(Qe,$t),zt=fe(le(Ze)),It=Math.min(Se,zt),lt=Math.max(Se,zt),xt=h?U(ft,It):U(ft,0)+Ge,bt=h?J(ft,0)+Ge:J(ft,lt),Xt=h?(lt-It)*W:ye-Me,Ut=h?ye-Me:(lt-It)*X;if(at+=`<rect x="${o(xt)}" y="${o(bt)}" width="${o(Xt)}" height="${o(Ut)}"/>`,!$)continue;let ir=String(Ze),qa=a.width(ir,s,0),sr=zt>=Se?1:-1,en=xt+Xt/2,tn=bt+Ut/2,rn="middle";if(h){if(Ut<s)continue;en=(sr>0?xt+Xt:xt)+sr*6,rn=sr>0?"start":"end"}else{if(qa+2>Ie/C)continue;tn=(sr>0?bt:bt+Ut)-sr*(F/2+2)}be+=`<text x="${o(en)}" y="${o(tn+s*.35)}" text-anchor="${rn}">${ir}</text>`}q+=`<g class="pele-series pele-bars"${ht} fill="${Xe}">${at}</g>`;return}let Bt="",yr="",ar=!1,pt=0,rt=NaN;for(let Ge=0;Ge<$t;Ge++){let at=pr(_e.data[Ge][1]);if(at===void 0){rt=NaN;continue}let Qe=x(Ge,$t),Ze=le(at),ft=Ze>=0&&Ze<=1;if(rt!==rt)ft&&(Bt+=`M${o(U(Qe,Ze))},${o(J(Qe,Ze))}`),ar=ft;else{let xt=Ze-rt,bt=0,Xt=1;if(xt!==0){let Ut=-rt/xt,ir=(1-rt)/xt;bt=Math.max(bt,Math.min(Ut,ir)),Xt=Math.min(Xt,Math.max(Ut,ir))}else ft||(bt=2);if(bt<=Xt){let Ut=pt+(Qe-pt)*bt,ir=rt+xt*bt,qa=pt+(Qe-pt)*Xt,sr=rt+xt*Xt;(!ar||bt>0)&&(Bt+=`M${o(U(Ut,ir))},${o(J(Ut,ir))}`),Bt+=`L${o(U(qa,sr))},${o(J(qa,sr))}`}ar=ft}if(pt=Qe,rt=Ze,!ft)continue;let zt=U(Qe,Ze),It=J(Qe,Ze);Ie>=12&&(yr+=`<circle cx="${o(zt)}" cy="${o(It)}" r="3"/>`);let lt=D(_e.pointLabels?.[Ge],s,4e3);if(lt.height>0){let xt=lt.width/2;Ce+=h?is(lt,zt+10,It,"start"):is(lt,Math.max(Math.min(zt,N-xt),ge+xt),It-6-lt.height/2,"middle")}}ce+=`<g class="pele-series pele-line"${ht} fill="${Xe}">`+(Bt?`<path d="${Bt}" fill="none" stroke="${Xe}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>`:"")+yr+"</g>"});let ke="";ee.height>0&&(ke+=`<g transform="translate(${o(d+ee.height/2)},${o(ne+X/2)}) rotate(-90)">${Ne(ee,0,0,"")}</g>`),ke+=Ne(he,ge+W/2,u-d-he.height/2,"");let Re="",ze=0;for(let _e of E)ze+=Math.max(Wc,_e.label.height+6);let We=ne+Math.max(0,(X-ze)/2),je=N+pe+Pc;for(let{index:_e,label:Ye}of E){let Xe=Math.max(Wc,Ye.height+6);if(We+Xe>u)break;let ht=We+Xe/2,$t=it(_e);Re+=`<g class="pele-legend-item" data-id="${Oe(T[_e].title)}">`+(T[_e].type==="bar"?`<rect x="${o(je)}" y="${o(ht-sa/2)}" width="${sa}" height="${sa}" rx="2" fill="${$t}"/>`:`<path d="M${o(je)},${o(ht)}h${sa}" stroke="${$t}" stroke-width="2" stroke-linecap="round"/>`)+Ne(Ye,je+sa+8+Ye.width/2,ht,"")+"</g>",We+=Xe}let st=Ne(k,p/2,d+k.height/2,' class="pele-title" font-weight="var(--_tw)"')+(Ee?`<path class="pele-grid" d="${Ee}" stroke="var(--_a)"/>`:"")+`<g class="pele-plot">${q}${ce}</g>`+(Ae?`<path class="pele-axis" d="${Ae}" fill="none" stroke="var(--_b)"/>`:"")+(De?`<g class="pele-axis-labels" font-size="${l}" fill="var(--_m)">${De}</g>`:"")+(ke?`<g class="pele-axis-titles" font-size="${l}">${ke}</g>`:"")+(be?`<g class="pele-data-labels" font-size="${s}">${be}</g>`:"")+(Ce?`<g class="pele-point-labels" font-size="${s}">${Ce}</g>`:"")+(Re?`<g class="pele-legend" font-size="${l}">${Re}</g>`:"");return{svg:Je("xychart",p,u,n,r,e,st),width:p,height:u,links:[]}}var Ol={type:"xychart",section:"xyChart",parse(e,t,r){let i=new y1;return i.title=r,w1(e,i),i},render:b1};function la(e,t){let r=e.indexOf(`
84`,t);return r===-1?e.length:r}function gr(e,t,r){for(let i=0;i<r.length;i++)if((e.charCodeAt(t+i)|32)!==r.charCodeAt(i))return!1;return!0}function Bc(e,t){let r=e.length,i=t;for(;i<r;){let n=e.charCodeAt(i);if(n===37&&e.charCodeAt(i+1)!==123)i=la(e,i);else if(n!==125&&e.charCodeAt(i+1)===37&&e.charCodeAt(i+2)===37)i=la(e,i+3);else{if(n===10)return i;if(Le(n))do i++;while(i<r&&Le(e.charCodeAt(i)));else if(n===35)i=la(e,i);else return i}}return i}function Rl(e,t){let r=t;for(;Le(e.charCodeAt(r));)r++;return r}function Uc(e,t,r,i){let n=gr(e,t,"accdescr");if(!n&&!gr(e,t,"acctitle"))return t;let l=e.length,s=Rl(e,t+8),a=e.charCodeAt(s),d=(c,p,u)=>{r.types.push(c),r.texts.push(e.slice(p,u)),r.starts.push(p)};if(a===58){s=Rl(e,s+1);let c=la(e,s);return d(n?i+2:i,t,s),d(n?i+3:i+1,s,c),c}if(!n||a!==123)return t;for(s=Rl(e,s+1);e.charCodeAt(s)!==125;){let c=e.indexOf("}",s);if(c===-1&&(c=l),d(i+4,s,c),s===l)return l;s=c}return s+1}var k1=/<(?!br\s*\/?>)/gi,v1=/:fa-/g,M1=/<br\s*\/?>|fl°°?\w+¶ß|&#?\w+;|[\ud800-\udbff][\udc00-\udfff]|[\s\S]/gi;function er(e,t,r,i,n=0){let l=e;return l!==void 0&&(l.includes("<")&&(l=l.replace(k1,"<")),l.includes(":fa-")&&(l=l.replace(v1,":fa-"))),Fe(l,!1,t,r,i,n)}function Ya(e,t,r,i,n=0){let l=er(e,t,r,i,n);if(e===void 0||l.width<=i)return l;let s="",a=0;for(let d of e.match(M1)??[]){if(d.trim()===""||d.length>2&&d[0]==="<")a=0;else{let c=t.width(d.length>2?"x":d,r,n);a>0&&a+c>i&&(s+=`
85`,a=0),a+=c}s+=d}return er(s,t,r,i,n)}var A1=class{type="timeline";title;accTitle;accDescr;direction="LR";sections=[];periods=[];currentSection="";getCommonDb(){return this}setDiagramTitle(e){this.title=e}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
86`)}setDirection(e){this.direction=e}addSection(e){this.currentSection=e,this.sections.push(e)}addTask(e,t,r){this.periods.push({text:e,events:r?[r]:[],section:this.currentSection,sectionIndex:this.sections.length-1})}addEvent(e){let t=this.periods[this.periods.length-1];if(!t)throw new He("An event needs a time period before it.","semantic",{type:"timeline"});t.events.push(e)}},T1=["$end","EOF","INVALID","NEWLINE","timeline","timeline_lr","timeline_td","title","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","section","period","event"];function C1(e){let t=e.length,r=[],i=[],n=[],l={types:r,texts:i,starts:n},s=0,a=(d,c)=>{r.push(d),i.push(e.slice(s,c)),n.push(s),s=c};for(;s=Bc(e,s),!(s>=t);){let d=e.charCodeAt(s),c=s+1;if(d===10){for(;e.charCodeAt(c)===10;)c++;a(3,c);continue}if(gr(e,s,"timeline")){for(c=s+8;e.charCodeAt(c)===32||e.charCodeAt(c)===9;)c++;let p=gr(e,c,"lr");if(c>s+8&&(p||gr(e,c,"td"))&&!Pe(e.charCodeAt(c+2))){a(p?5:6,c+2);continue}if(!Pe(e.charCodeAt(s+8))){a(4,s+8);continue}}if(gr(e,s,"title")&&Le(e.charCodeAt(s+5))&&s+6<t&&e.charCodeAt(s+6)!==10){a(7,la(e,s+6));continue}if(c=Uc(e,s,l,8),c!==s){s=c;continue}if(gr(e,s,"section")&&Le(e.charCodeAt(s+7))){for(c=s+8;c<t&&e.charCodeAt(c)!==58&&e.charCodeAt(c)!==10;)c++;if(c>s+8){a(13,c);continue}}if(d!==58){c=s+1;for(let p=e.charCodeAt(c);c<t&&p!==35&&p!==58&&p!==10;p=e.charCodeAt(++c));a(14,c);continue}if(Le(e.charCodeAt(s+1))){for(c=s+2;c<t;c++){let p=e.charCodeAt(c);if(p===10||p===58&&Le(e.charCodeAt(c+1)))break}if(c>s+2){a(15,c);continue}}a(2,s+1)}return(n.length===0||n[n.length-1]<t)&&a(1,t),a(0,t),l}var E1="'EOF', 'SPACE', 'NEWLINE', 'title', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'section', 'period', 'event'";function S1(e,t){let{types:r,texts:i,starts:n}=C1(e),l=(a,d)=>{let c=r[a]===0?"1":T1[r[a]];throw Ve("timeline",e,n[a],`Expecting ${d}, got '${c}'`)},s=r[0];s!==4&&s!==5&&s!==6&&l(0,"'timeline', 'timeline_lr', 'timeline_td'"),s!==4&&t.setDirection(s===5?"LR":"TD");for(let a=1;;a++){let d=i[a];switch(r[a]){case 3:break;case 7:t.getCommonDb().setDiagramTitle(d.substring(6));break;case 8:t.getCommonDb().setAccTitle(i[++a].trim());break;case 10:t.getCommonDb().setAccDescription(i[++a].trim());break;case 12:t.getCommonDb().setAccDescription(d.trim());break;case 13:t.addSection(d.substring(8));break;case 14:t.addTask(d,0,"");break;case 15:t.addEvent(d.substring(2));break;case 1:return;default:l(a,E1)}}}var ls=12,qc=8,_1=152,D1=216,I1=264,Lr=20,na=20,ns=14,Ga=8,zl=8,os=12,jc=' fill="var(--_bg)"',Xc=' fill="none" stroke="var(--_b)"';function Fl(e,t,r,i,n){return`<rect x="${o(e)}" y="${o(t)}" width="${o(r)}" height="${o(i)}" rx="${Ke}"${n}/>`}function N1(e,t,r){return e.direction==="TD"?Vc(e,t,r,!0):Ct(r,i=>Vc(e,t,r,i))}function Vc(e,t,r,i){let n=r.fontSize??16,l=Math.round(n*.875),s=r.measurer??tt(r.fontFamily),a=r.padding??8,d=t.timeline?.disableMulticolor!==!0,c=e.periods,p=e.sections.length>0,u=e.sections.map((B,Q)=>({section:Q,periods:[]})),h={section:-1,periods:[]};c.forEach((B,Q)=>(u[B.sectionIndex]??h).periods.push(Q)),h.periods.length>0&&u.unshift(h);let $=i&&r.maxWidth!==void 0&&r.maxWidth>0?r.maxWidth-2*a:1/0,g=na+ns*2+4*ls,T=Math.min(_1,Math.max(80,Math.round(($-g)*.38))),D=Math.min(I1,Math.max(110,$-g-T)),_=T,F=()=>i?D:_,k=c.map(B=>er(B.text,s,n,_)),I=c.map(B=>B.events.map(Q=>er(Q,s,l,F()))),E=0;for(let B of k)E=Math.max(E,B.width);if(!i)for(let B of I)for(let Q of B)E=Math.max(E,Q.width);let m=E>_;if(i)for(let B of I)for(let Q of B)m||=Q.width>D;m&&(_=Math.min(Math.max(Math.ceil(E),T),$===1/0?D1:T),k=c.map(B=>Ya(B.text,s,n,_)),I=c.map(B=>B.events.map(Q=>Ya(Q,s,l,F()))));let y=Math.round(n*1.5),C=_+2*ls,L=F()+2*ls,S=B=>Math.max(B.height,y)+2*qc,Z=B=>Math.max(B.height,Math.round(l*1.5))+2*qc,H=(B,Q)=>B.section>=0?it(B.section):p?"var(--_m)":it(d?Q:0),R=!1;for(let B of I)B.length>0&&(R=!0);let P=0;for(let B of u)P+=Math.max(B.periods.length,1);let w=C+Lr,b=c.length>0,M=i?C+(R?na+ns*2+L:b?na+os:0):P>0?P*w-Lr+(b?os+At:0):0,f=Ya(e.title,s,n,Math.max(M,320),1),x=f.height>0?f.height+16:0,A=Math.max(M,f.width),z=a+(A-M)/2,v=a+x,G=(B,Q)=>Ya(e.sections[B.section],s,n,Q-2*ls,1),ee=(B,Q,se,ie,re,ne)=>Fl(se,ie,re,ne,` fill="${it(B.section)}"`)+Ne(Q,se+re/2,ie+ne/2,' font-weight="var(--_hw)"'+jc),he=(B,Q,se,ie,re)=>Fl(se,ie,C,re,` fill="${Q}"`)+Ne(k[B],se+C/2,ie+re/2,jc),ue=(B,Q,se,ie,re)=>'<g class="pele-node pele-event">'+Fl(se,ie,L,re,` fill="${Q}" fill-opacity="0.16"`)+Ne(B,se+L/2,ie+re/2,` font-size="${l}"`)+"</g>",V=(B,Q,se)=>`<circle class="pele-dot" cx="${o(B)}" cy="${o(Q)}" r="4" fill="${se}" stroke="var(--_bg)" stroke-width="2"/>`,Y=B=>B.section>=0?`<g class="pele-cluster pele-section" data-id="${Oe(e.sections[B.section].trim())}">`:"",de=B=>`<g class="pele-node pele-period" data-id="${Oe(c[B].text.trim())}">`,te="",xe;if(i){let B=z+C+na,Q=B+ns,se=Q+ns,ie=v;for(let re of u){if(te+=Y(re),re.section>=0){let ne=G(re,M),X=S(ne);te+=ee(re,ne,z,ie,M,X),ie+=X+zl+4}for(let ne of re.periods){let X=H(re,ne),j=S(k[ne]),oe=ie+j/2,$e=`M${o(z+C)},${o(oe)}H${o(B)}`,ge="",Te=ie,pe=oe;for(let W of I[ne]){let K=Z(W);pe=Te+K/2,$e+=`M${o(Q)},${o(pe)}H${o(se)}`,ge+=ue(W,X,se,Te,K),Te+=K+Ga}ge&&($e+=`M${o(B)},${o(oe)}H${o(Q)}V${o(pe)}`),te+=de(ne)+he(ne,X,z,ie,j)+`<path class="pele-edge" d="${$e}"${Xc}/>`+V(B,oe,X)+ge+"</g>",ie=Math.max(ie+j,Te-Ga)+Lr}re.periods.length===0&&(ie+=Lr-zl-4),re.section>=0&&(te+="</g>")}if(u.length>0&&(ie-=Lr),b){let re=ie+os+At;te=`<path class="pele-axis" d="M${o(B)},${o(v)}V${o(re-At+1)}" fill="none" stroke="var(--_l)"/>`+St("arrow_point",B,re,0,1,"var(--_l)")+te,ie=re}xe=ie+a}else{let B=0,Q=u.map(oe=>{if(oe.section<0)return;let $e=G(oe,Math.max(oe.periods.length,1)*w-Lr);return B=Math.max(B,S($e)),$e}),se=0;for(let oe of k)se=Math.max(se,S(oe));let ie=v+(p?B+zl:0),re=ie+se+(se>0?na:0),ne=re+na,X=b?re+os:v+B,j=0;if(u.forEach((oe,$e)=>{let ge=Math.max(oe.periods.length,1),Te=z+j*w;te+=Y(oe);let pe=Q[$e];pe&&(te+=ee(oe,pe,Te,v,ge*w-Lr,B)),oe.periods.forEach((W,K)=>{let N=H(oe,W),U=Te+K*w,J=U+C/2,le=`M${o(J)},${o(ie+se)}V${o(I[W].length>0?ne:re)}`,fe="",we=ne;for(let Ee of I[W]){let Ae=Z(Ee);we>ne&&(le+=`M${o(J)},${o(we-Ga)}V${o(we)}`),fe+=ue(Ee,N,U,we,Ae),we+=Ae+Ga}X=Math.max(X,we-Ga),te+=de(W)+he(W,N,U,ie,se)+`<path class="pele-edge" d="${le}"${Xc}/>`+V(J,re,N)+fe+"</g>"}),oe.section>=0&&(te+="</g>"),j+=ge}),b){let oe=z+M;te=`<path class="pele-axis" d="M${o(z)},${o(re)}H${o(oe-At+1)}" fill="none" stroke="var(--_l)"/>`+St("arrow_point",oe,re,1,0,"var(--_l)")+te}xe=X+a}let me=Math.ceil(A+2*a),ae=Math.ceil(Math.max(xe,a*2)),O=Ne(f,me/2,a+f.height/2,' class="pele-title" font-weight="var(--_tw)"')+te;return{svg:Je("timeline",me,ae,n,r,e,O),width:me,height:ae,links:[]}}var Wl={type:"timeline",parse(e,t,r){let i=new A1;return i.title=r,S1(e,i),i},render:N1};var L1=["1","INVALID","SPACELINE","NL","EOF","","SPACELIST","ICON","CLASS","NODE_DSTART","NODE_ID","NODE_DESCR","NODE_DEND","SHAPE_DATA"];function Kc(e,t){return e===5?t?"KANBAN":"MINDMAP":L1[e]}var mr={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6};function Qc(e,t){switch(e){case"[":return mr.RECT;case"(":return t===")"?mr.ROUNDED_RECT:mr.CLOUD;case"((":return mr.CIRCLE;case")":return mr.CLOUD;case"))":return mr.BANG;case"{{":return mr.HEXAGON;default:return mr.DEFAULT}}var O1=/\s+/y,Pl=/.+/y,R1=/[^([\n){}]+/y,z1=/[^([\n){}@]+/y,F1=/[^)\](}]+/y,W1=/[^`"]+/y,P1=/[^}^"]+/y,H1=/\n\s*/g;function Zc(e,t,r){for(let i=0;i<r.length;i++)if((e.charCodeAt(t+i)|32)!==r.charCodeAt(i))return!1;return!0}function Y1(e,t){let r=e.length,i=[],n=[],l=[],s=t?"kanban":"mindmap",a=t?z1:R1,d=0,c=0,p=-1,u=(T,D,_)=>{i.push(T),n.push(D),l.push(c),c=_},h=(T,D,_)=>{u(T,e.slice(c,D),D),d=_},$=(T,D)=>(T.lastIndex=D,T.test(e)?T.lastIndex:-1),g=T=>{let D=e.indexOf(T,c);return D===-1?r:D};for(;c<r;){let T=e.charCodeAt(c),D=e.charCodeAt(c+1),_;if(d===0){let F=T<=32||T>=160?Math.max($(O1,c),c):c;if(t&&T===64&&D===123)u(13,"",c+2),d=6;else if(e.charCodeAt(F)===37&&e.charCodeAt(F+1)===37)h(2,$(Pl,F),0);else if(F>c)p<c&&(p=g(`
87`)),p>=F?h(6,F,0):(_=e.lastIndexOf(`
88`,F-1))>c?h(2,_+1,0):h(3,c+1,0);else if(Zc(e,c,s)&&!Pe(e.charCodeAt(c+s.length)))h(5,c+s.length,0);else if(T===58&&D===58&&e.charCodeAt(c+2)===58)c+=3,d=1;else if(T===58&&D===58&&Zc(e,c+2,"icon")&&e.charCodeAt(c+6)===40)c+=7,d=2;else if(T===45&&D===41||T===40&&(D===45||D===40)||(T===41||T===123)&&D===T)h(9,c+2,3);else if(T===41||T===40||T===91)h(9,c+1,3);else if((_=$(a,c))!==-1)h(10,_,0);else break}else if(d===3)T===34?(d=D===96?5:4,c+=D===96?2:1):T===41||T===40?h(12,D===T||T===40&&D===45?c+2:c+1,0):T===93?h(12,c+1,0):T===125&&D===125||T===45&&D===41?h(12,c+2,0):h(11,$(T===125?Pl:F1,c),3);else if(d===4)T===34?(c++,d=3):h(11,g('"'),4);else if(d===5)if(T===96&&D===34)c+=2,d=3;else if((_=$(W1,c))!==-1)h(11,_,5);else break;else if(d===1)if((_=$(Pl,c))!==-1)h(8,_,0);else if(T===10)c++,d=0;else break;else if(d===2)T===41?(c++,d=0):h(7,g(")"),2);else if(d===6)if(T===34)h(13,c+1,7);else if(T===125)c++,d=0;else if((_=$(P1,c))!==-1)h(13,_,6);else break;else T===34?h(13,c+1,6):(_=g('"'),u(13,e.slice(c,_).replace(H1,"<br/>"),_))}return c<r?u(1,"",c):(d===0&&u(4,"",r),u(0,"",r)),{types:i,texts:n,starts:l}}var Or="'SPACELINE', 'NL', 'EOF'",Jc=new Uint8Array(14);for(let e of[2,6,7,8,9,10])Jc[e]=1;function oa(e){return e===2||e===3||e===4}function ed(e,t,r){let i=r?"kanban":"mindmap",{types:n,texts:l,starts:s}=Y1(e,r),a=r?", 'SHAPE_DATA'":"",d=0,c=h=>{let $=n[d];throw $===1?Ve(i,e,s[d],"",!0):Ve(i,e,s[d],`Expecting ${h}, got '${Kc($,r)}'`)},p=`'${Kc(5,r)}'`;if(n[d]===2){for(d++;n[d]===2||n[d]===3;)d++;n[d]!==5&&c(`'SPACELINE', 'NL', ${p}`)}else n[d]!==5&&c(`'SPACELINE', ${p}`);d++;let u="'SPACELINE', 'NL', 'SPACELIST', 'ICON', 'CLASS', 'NODE_DSTART', 'NODE_ID'";for(n[d]===3&&(d++,u="'SPACELINE', 'SPACELIST', 'ICON', 'CLASS', 'NODE_DSTART', 'NODE_ID'");;){let h=n[d],$=0,g=h===6;if(g&&($=l[d++].length,h=n[d]),h===10||h===9){let T,D,_=0;if(h===10&&(T=l[d++]),n[d]===9){let F=l[d++];n[d]!==11&&c("'NODE_DESCR'"),D=l[d++],n[d]!==12&&c("'NODE_DEND'");let k=l[d++];!oa(n[d])&&n[d]!==13&&c(Or+a),_=t.getType(F,k)}else!oa(n[d])&&n[d]!==13&&c(Or+", 'NODE_DSTART'"+a),D=T;if(n[d]===13){let F=l[d++];for(;n[d]===13;)F+=l[d++];oa(n[d])||c(Or+a),t.addNode($,T??D,D,_,F)}else t.addNode($,T??D,D,_)}else if(h===7||h===8){let T=l[d++];oa(n[d])||c(Or),t.decorateNode(h===7?{icon:T}:{class:T})}else g?oa(h)||c(Or+", 'ICON', 'CLASS', 'NODE_DSTART', 'NODE_ID'"):h===2?oa(n[++d])||c(Or):c(u);for(d++;n[d]===3||n[d]===4;)d++;if(n[d]===0)return;Jc[n[d]]===0&&c(Or+", 'SPACELIST', 'ICON', 'CLASS', 'NODE_DSTART', 'NODE_ID'")}}function td(e,t,r,i,n){return`<svg class="pele-icon" data-icon="${Oe(e)}" x="${o(t)}" y="${o(r)}" width="${o(i)}" height="${o(i)}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n?.(e)??""}</svg>`}var G1=11,B1=class{type="mindmap";title;nodes=[];getType=Qc;baseLevel=0;open=[];addNode(e,t,r,i){let n=this.nodes.length===0;n&&(this.baseLevel=e),e-=this.baseLevel;let l=this.open,s=l.length;for(;s>0&&l[s-1].level>=e;)s--;let a=l[s-1];if(!a&&!n)throw new He(`There can be only one root. No parent could be found for ("${r}")`,"semantic",{type:"mindmap"});let d={id:this.nodes.length,nodeId:t,level:e,descr:r,type:i,children:[],isRoot:n};a&&(d.section=a.isRoot?a.children.length%G1:a.section,a.children.push(d)),l.length=s,l.push(d),this.nodes.push(d)}decorateNode(e){let t=this.nodes[this.nodes.length-1];!e||!t||(e.icon&&(t.icon=e.icon),e.class&&(t.class=e.class))}};function U1(e,t){ed(e,t,!1)}var q1=["","rounded","rect","circle","cloud","bang","hex"],rd="stadium",j1=36,X1=8,V1=18,K1=52,ad=28,id=6,Z1=12,Q1=.22,Hl=6,Yl=28,sd=12,ld=8,nd=10;function J1(e,t,r,i){if(e.lines.length<2)return Ne(e,t+e.width/2,r,' class="pele-label"',i);let n="";for(let l=0;l<e.lines.length;l++){let s=e.widths[l],a={lines:[e.lines[l]],widths:[s],width:s,height:e.lineHeight,size:e.size,lineHeight:e.lineHeight};n+=Ne(a,t+s/2,r+(l-(e.lines.length-1)/2)*e.lineHeight,' class="pele-label"',i)}return n}function eg(e,t,r){return Ct(r,i=>tg(e,t,r,i))}function tg(e,t,r,i){let n=r.fontSize??16,l=r.measurer??tt(r.fontFamily),s=r.padding??8,a=r.icons,d=t.mindmap?.maxNodeWidth,c=typeof d=="number"&&d>0?Math.min(d,2e3):200,p=n*1.25,u=e.nodes,h=u.length,$=new Int32Array(h),g=new Int32Array(h);for(let ae=0;ae<h;ae++)for(let O of u[ae].children)$[O.id]=ae,g[O.id]=g[ae]+1;let T=i&&r.maxWidth!==void 0&&r.maxWidth>0?r.maxWidth-2*s:1/0,D=new Array(h),_=new Array(h),F=new Float64Array(h),k=new Float64Array(h),I=new Float64Array(h),E=new Float64Array(h),m=new Uint8Array(h);for(let ae=0;ae<h;ae++){let O=u[ae];m[ae]=O.icon!==void 0&&Za(O.icon)!==""?1:0;let B=Math.min(c,Math.max(72,T-g[ae]*Yl-2*id-(m[ae]?p+Hl:0))),Q=D[ae]=Fe(O.descr,!0,l,n,B),se=Q.width+(m[ae]?p+(Q.width>0?Hl:0):0),ie=Math.max(Q.height,Math.round(n*1.5)),re=q1[O.type]||(ae===0?rd:"");if(i&&ae===0&&re!=="rect"&&re!=="rounded"&&(re=rd),_[ae]=re,re===""){let ne=O.children.length>0;F[ae]=se+2*(ne?Z1:id),k[ae]=ie+(ne?6:0),E[ae]=k[ae]/2}else{let ne=gi(re,se,ie);F[ae]=ne.w,k[ae]=ne.h,I[ae]=ne.dy,E[ae]=ne.h/2}}let y=new Float64Array(h),C=new Float64Array(h),L=new Float64Array(h),S=new Float64Array(h),Z=0,H=(ae,O,B,Q)=>{let se=0,ie=0;for(let X=O;X<B;X++){let j=ae[X].id;C[j]=se,ie=ae[X].children.length>0||X+1<B&&ae[X+1].children.length>0?Math.max(Q,V1):Q,se+=y[j]+ie}Z=se-ie;let re=ae[O].id,ne=ae[B-1].id;return(C[re]+L[re]+E[re]+C[ne]+L[ne]+E[ne])/2};for(let ae=h-1;ae>0;ae--){let O=u[ae].children;if(O.length===0){y[ae]=k[ae];continue}let B=H(O,0,O.length,X1)-E[ae],Q=Math.min(0,B);y[ae]=Math.max(Z,B+k[ae])-Q,L[ae]=B-Q,S[ae]=-Q}let R=new Float64Array(h),P=new Float64Array(h),w=new Float64Array(h),b=new Int8Array(h),M=new Float64Array(h);if(i){let ae=0;for(let O=0;O<h;O++)O>0&&$[O]===0&&(ae+=nd),R[O]=g[O]*Yl+F[O]/2,P[O]=ae,ae+=k[O]+nd}else if(h>0){let ae=u[0].children,O=ae.length,B=0;for(let re of ae)B+=y[re.id];let Q=O,se=1/0,ie=0;for(let re=1;re<O;re++){ie+=y[ae[re-1].id];let ne=Math.abs(2*ie-B+(2*re-O)*ad);ne<se&&(se=ne,Q=re)}for(let re=0,ne=Q,X=1;re<O;re=ne,ne=O,X=-1){let j=H(ae,re,ne,ad);for(let oe=re;oe<ne;oe++){let $e=ae[oe].id;w[$e]=C[$e]-j,b[$e]=X}}P[0]=-k[0]/2;for(let re=0;re<h;re++){re>0&&(P[re]=w[re]+L[re]);for(let ne of u[re].children){let X=ne.id;re>0&&(b[X]=b[re],w[X]=w[re]+S[re]+C[X]),R[X]=R[re]+b[X]*(F[re]/2+(re>0?j1:K1)+F[X]/2)}}}let f=0,x=0,A=0,z=0,v="",G="",ee="",he="",ue=ae=>{ee!==""&&(v+=`<g class="pele-branch pele-section-${ae??0}"><g class="pele-edges" fill="none" stroke="${he}" stroke-width="1.5">${G}</g>${ee}</g>`,G=ee="")};for(let ae=1;ae<=h;ae++){let O=ae%h,B=u[O],Q=_[O],se=D[O],ie=R[O],re=P[O];if(f=Math.min(f,ie-F[O]/2),x=Math.max(x,ie+F[O]/2),A=Math.min(A,re),z=Math.max(z,re+k[O]),(O===0||$[O]===0)&&ue(u[ae-1].section),O>0&&i){$[O]===0&&(he=it(B.section??0));let ge=$[O],Te=ge===0?Math.min(Math.max(sd,k[0]/2),Yl-ld):sd,pe=R[ge]-F[ge]/2+Math.min(Te,F[ge]/2),W=M[ge]||P[ge]+k[ge],K=ie-F[O]/2+(Q?jr(Q,F[O],k[O],3):0),N=re+E[O],U=Math.max(0,Math.min(ld,K-pe,N-W));M[ge]=N-U,G+=`<path class="pele-edge" d="M${o(pe)},${o(W)}V${o(N-U)}Q${o(pe)},${o(N)} ${o(pe+U)},${o(N)}H${o(K)}"/>`}else if(O>0){$[O]===0&&(he=it(B.section??0));let ge=$[O],Te=b[O],pe=Te>0?1:3,W=R[ge]+Te*(F[ge]/2-(_[ge]?jr(_[ge],F[ge],k[ge],pe):0)),K=P[ge]+E[ge],N=ie-Te*F[O]/2+(Q?Te*jr(Q,F[O],k[O],4-pe):0),U=re+E[O],J=o((W+N)/2);G+=`<path class="pele-edge" d="M${o(W)},${o(K)}C${J},${o(K)} ${J},${o(U)} ${o(N)},${o(U)}"/>`}let ne=!Q&&B.children.length>0,X=` fill="${he}" fill-opacity="${Q1}" stroke="${he}"`,j="";Q?j=O>0?ba(Q,F[O],k[O],X,` stroke="${he}"`):ba(Q,F[O],k[O],' fill="var(--_s)" stroke="var(--_b)"',' stroke="var(--_b)"'):ne&&(j=`<rect x="${o(-F[O]/2)}" y="${o(-k[O]/2)}" width="${o(F[O])}" height="${o(k[O])}" rx="${o(k[O]/2)}"${X}/>`);let oe=0;B.icon&&m[O]&&(oe=(p+(se.width>0?Hl:0))/2,j+=td(B.icon,-oe-se.width/2,I[O]-p/2,p,a));let $e=`<g class="pele-node pele-shape-${Q||(ne?"branch":"text")}${O>0?"":" pele-root"}${Mt(B.class??"")}" data-id="${Oe(B.nodeId)}" transform="translate(${o(ie)},${o(re+k[O]/2)})">`+j+(i&&!Q?J1(se,oe-se.width/2,I[O],a):Ne(se,oe,I[O],' class="pele-label"',a))+"</g>";O>0?ee+=$e:v+=$e}let V=Fe(e.title,!1,l,n,Pt(r),1),Y=V.height>0?V.height+16:0,de=Math.max(x-f,V.width),te=Math.ceil(de+2*s),xe=Math.ceil(z-A+Y+2*s),me=Ne(V,te/2,s+V.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g transform="translate(${o(s-f+(de-x+f)/2)},${o(s+Y-A)})">${v}</g>`;return{svg:Je("mindmap",te,xe,n,r,{},me),width:te,height:xe,links:[]}}var Gl={type:"mindmap",parse(e,t,r){let i=new B1;return i.title=r,U1(e,i),i},render:eg};var rg=/^\d+$/,od=/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/,ag=/^\d+px$/;function cs(e,t,r){return new He(`value for ${e} ${t} is invalid, please use a valid ${r}`,"semantic",{type:"quadrantChart"})}function ig(e){let t=e.trim(),r=t.indexOf(":");if(r===-1)return[t,"undefined"];let i=t.slice(r+1).trimStart(),n=i.indexOf(":");return[t.slice(0,r).trimEnd(),n===-1?i:i.slice(0,n).trimEnd()]}function cd(e){let t={};for(let r of e){let[i,n]=ig(r);if(i==="radius"){if(!rg.test(n))throw cs(i,n,"number");t.radius=parseInt(n)}else if(i==="color"){if(!od.test(n))throw cs(i,n,"hex code");t.color=n}else if(i==="stroke-color"){if(!od.test(n))throw cs(i,n,"hex code");t.strokeColor=n}else if(i==="stroke-width"){if(!ag.test(n))throw cs(i,n,"number of pixels (eg. 10px)");t.strokeWidth=n}else throw new He(`style named ${i} is not supported.`,"semantic",{type:"quadrantChart"})}return t}function tr(e){return{text:e.text.trim(),type:e.type}}var sg=class{type="quadrantChart";title;accTitle;accDescr;quadrants=[void 0,void 0,void 0,void 0];xAxisLeft;xAxisRight;yAxisBottom;yAxisTop;points=[];classes=new Map;setQuadrant1Text(e){this.quadrants[0]=tr(e)}setQuadrant2Text(e){this.quadrants[1]=tr(e)}setQuadrant3Text(e){this.quadrants[2]=tr(e)}setQuadrant4Text(e){this.quadrants[3]=tr(e)}setXAxisLeftText(e){this.xAxisLeft=tr(e)}setXAxisRightText(e){this.xAxisRight=tr(e)}setYAxisBottomText(e){this.yAxisBottom=tr(e)}setYAxisTopText(e){this.yAxisTop=tr(e)}addPoint(e,t,r,i,n){this.points.push({x:Number(r),y:Number(i),text:tr(e),className:t,...cd(n)})}addClass(e,t){this.classes.set(e,cd(t))}setDiagramTitle(e){this.title=e}setAccTitle(e){this.accTitle=e.replace(/^\s+/g,"")}setAccDescription(e){this.accDescr=e.replace(/\n\s+/g,`
89`)}},dd=["$end","INVALID","NEWLINE","title","title_value","acc_title","acc_title_value","acc_descr","acc_descr_value","acc_descr_multiline_value","X-AXIS","Y-AXIS","AXIS-TEXT-DELIMITER","QUADRANT_1","QUADRANT_2","QUADRANT_3","QUADRANT_4","CLASSDEF","MD_STR","STR","class_name","point_start","point_x","point_y","QUADRANT","ALPHA","UNICODE_TEXT","COLON","PLUS","COMMA","EQUALS","MULT","BRKT","UNDERSCORE","DOT","AMP","MINUS","NUM","SPACE","SEMI","PUNCTUATION","EOF"],Bl=[41,4,6,8,9,19],ql=new Uint8Array(128);for(let[e,t]of[[":",27],["+",28],[",",29],["=",30],["*",31],["#",32],["_",33],[".",34],["&",35],["-",36],[" \v\f",38],[";",39],["!$%'`?\\/",40]])for(let r=0;r<e.length;r++)ql[e.charCodeAt(r)]=t;function lg(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=0,c=0,p=0,u=0,h=0,$=0,g=0,T=0,D=(y,C,L)=>{r.push(y),i.push(e.slice(C,L)),n.push(C),a=L},_=y=>{l.push(s),s=y},F=()=>{l.length>0&&(s=l.pop())},k=y=>{let C=e.indexOf(`
90`,y);return C===-1?t:C},I=y=>{for(;e.charCodeAt(y)===32;)y++;return y},E=y=>{for(;y<t&&Le(e.charCodeAt(y));)y++;return y},m=y=>{let C=e.charCodeAt(y);if(C===49)return y+1;if(C!==48)return-1;let L=y+1;if(L<t&&!ha(e.charCodeAt(L))&&ot(e.charCodeAt(L+1)))for(L+=2;ot(e.charCodeAt(L));)L++;return L};e:for(;a<t;){let y=e.charCodeAt(a),C=e.charCodeAt(a+1);switch(s){case 0:break;case 1:case 2:case 3:D(Bl[s],a,k(a)),F();continue;case 4:if(y===125)a++,F();else{let w=e.indexOf("}",a);D(9,a,w===-1?t:w)}continue;case 5:if(y===34)a++,F();else{let w=e.indexOf('"',a);D(19,a,w===-1?t:w)}continue;case 6:if(y===96&&C===34){a+=2,F();continue}if(y!==96&&y!==34){let w=a+1;for(let b=e.charCodeAt(w);w<t&&b!==96&&b!==34;b=e.charCodeAt(++w));D(18,a,w);continue}break e;case 7:if(Pe(y)){let w=a+1;for(;Pe(e.charCodeAt(w));)w++;D(20,a,w),F();continue}break e;case 8:{let w=m(a);if(w!==-1){D(22,a,w),_(9);continue}let b=E(a);if(e.charCodeAt(b)===93){a=I(b+1),F();continue}break e}case 9:{let w=E(a);if(e.charCodeAt(w)===44){a=E(w+1),s=10;continue}break e}case 10:{let w=m(a);if(w!==-1){D(23,a,w),F();continue}break e}}if(y===37&&C===37){a=k(a+2);continue}if(y!==125&&C===37&&e.charCodeAt(a+2)===37){a=k(a+3);continue}if(y===10||y===13){let w=a+1;for(let b=e.charCodeAt(w);b===10||b===13;b=e.charCodeAt(++w));D(2,a,w);continue}let L=y|32;if(L===116&&yt(e,a,"title")&&!Pe(e.charCodeAt(a+5))){D(3,a,a+5),_(1);continue}if(L===97&&yt(e,a,"acc")){let w=yt(e,a+3,"descr");if(w||yt(e,a+3,"title")){let b=E(a+8),M=e.charCodeAt(b);if(M===58){D(w?7:5,a,E(b+1)),_(w?3:2);continue}if(M===123&&w){a=E(b+1),_(4);continue}}}let S=a;y===32&&((a<d||a>=c)&&(d=a,c=I(a)),S=c);let Z=e.charCodeAt(S),H=Z|32,R=0,P=0;if(H===120&&yt(e,S,"x-axis"))R=10,P=S+6;else if(H===121&&yt(e,S,"y-axis"))R=11,P=S+6;else if(Z===45){if(S<p||S>=u)for(p=S,u=S;e.charCodeAt(u)===45;)u++;u-S>=2&&e.charCodeAt(u)===62&&(R=12,P=u+1)}else if(H===113&&yt(e,S,"quadrant")){let w=e.charCodeAt(S+9);e.charCodeAt(S+8)===45&&w>=49&&w<=52?(R=13+w-49,P=S+10):yt(e,S+8,"chart")&&(R=24,P=S+13)}if(R!==0){D(R,a,I(P));continue}if(L===99&&yt(e,a,"classdef")&&!Pe(e.charCodeAt(a+8))){D(17,a,a+8);continue}if(y===34){C===96?(a+=2,_(6)):(a++,_(5));continue}if(y===58&&C===58&&e.charCodeAt(a+2)===58){a+=3,_(7);continue}if(y===58||Le(y)){let w=a;if(y!==58&&((a<h||a>=$)&&(h=a,$=E(a)),w=$),e.charCodeAt(w)===58&&((w+1<g||w+1>=T)&&(g=w+1,T=E(w+1)),e.charCodeAt(T)===91)){D(21,a,E(T+1)),_(8);continue}}if(Pr(y)){let w=a+1;for(;Pr(e.charCodeAt(w));)w++;D(25,a,w);continue}if(y>=128){let w=a+1;for(;e.charCodeAt(w)>=128;)w++;D(26,a,w);continue}if(ot(y)){let w=a+1;for(;ot(e.charCodeAt(w));)w++;D(37,a,w);continue}if(ql[y]!==0){D(ql[y],a,a+1);continue}break}return a<t?(r.push(1),i.push(""),n.push(a),{types:r,texts:i,starts:n}):(s<Bl.length&&(r.push(Bl[s]),i.push(""),n.push(t)),r.push(0),i.push(""),n.push(t),{types:r,texts:i,starts:n})}function ds(...e){let t=new Uint8Array(42);for(let r of e)t[r]=1;return t}var hd=ds(40,35,37,25,29,28,30,31,34,32,33,26),fd=ds(25,37,36,29,27,35,32,31,26),Ul=ds(25,37,27,38,32,36),ud=ds(2,39,41),ng=["setQuadrant1Text","setQuadrant2Text","setQuadrant3Text","setQuadrant4Text"],og="'STR', 'MD_STR', 'ALPHA', 'NUM', 'UNICODE_TEXT', 'PUNCTUATION'";function cg(e,t){let{types:r,texts:i,starts:n}=lg(e),l=0,s=u=>{let h=r[l];throw h===1?Ve("quadrantChart",e,n[l],"",!0):Ve("quadrantChart",e,n[l],`Expecting ${u}, got '${dd[h]}'`)},a=u=>(r[l]!==u&&s(`'${dd[u]}'`),i[l++]),d=u=>u===19||u===18||hd[u]===1,c=()=>{let u=r[l];d(u)||s(og);let h=i[l++];for(;hd[r[l]]===1||r[l]===38||r[l]===36;)h+=i[l++];return{text:h,type:u===18?"markdown":"text"}},p=()=>{let u=[];for(;;){Ul[r[l]]===0&&s("'ALPHA', 'NUM', 'COLON', 'SPACE', 'BRKT', 'MINUS'");let h=i[l++];for(;Ul[r[l]]===1;)h+=i[l++];if(u.push(h.trim()),r[l]!==29)return u;l++}};for(;ud[r[l]]===1||r[l]===38;)l++;for(a(24);r[l]!==0;){for(;r[l]===38;)l++;let u=r[l];switch(u){case 17:{l++,a(38),fd[r[l]]===0&&s("'ALPHA', 'NUM', 'UNICODE_TEXT'");let h=i[l++];for(;fd[r[l]]===1;)h+=i[l++];a(38),t.addClass(h,p());break}case 10:case 11:{l++;let h=c(),$;r[l]===12&&(l++,d(r[l])?$=c():h.text+=" \u27F6 "),u===10?(t.setXAxisLeftText(h),$&&t.setXAxisRightText($)):(t.setYAxisBottomText(h),$&&t.setYAxisTopText($));break}case 13:case 14:case 15:case 16:l++,t[ng[u-13]](c());break;case 3:l++,t.setDiagramTitle(a(4).trim());break;case 5:l++,t.setAccTitle(a(6).trim());break;case 7:l++,t.setAccDescription(a(8).trim());break;case 9:t.setAccDescription(i[l++].trim());break;default:if(d(u)){let h=c(),$=r[l]===20?i[l++]:"";a(21);let g=a(22),T=a(23);t.addPoint(h,$,g,T,Ul[r[l]]===1?p():[])}}ud[r[l]]===0&&s("'NEWLINE', 'SEMI', 'EOF'"),l++}}var pd=4,dg=300;function jl(e,t){return e.quadrantChart?.[t]}function rr(e,t,r,i){let n=jl(e,t);return typeof n=="number"&&n>=0?Math.min(n,i):r}function gd(e){return e.startsWith("#")?e:"#"+e}function hg(e,t,r){let i=r.fontSize??16,n=Math.round(i*.875),l=Math.round(i*.75),s=r.measurer??tt(r.fontFamily),a=Math.round(Math.max(100,rr(t,"chartWidth",500,4e3))),d=Math.round(Xr(r,a,280)),c=Math.round(Math.max(100,rr(t,"chartHeight",500,4e3))*d/a),p=rr(t,"quadrantPadding",r.padding??8,200),u=rr(t,"xAxisLabelPadding",5,200),h=rr(t,"yAxisLabelPadding",5,200),$=e.points.length>0,g=(B,Q,se)=>Fe(B?.text,B?.type==="markdown",s,Q,Math.max(se,40)),T=Fe(e.title,!1,s,i,Math.max(d-2*p,40),1),D=rr(t,"titlePadding",10,200),_=T.height>0?T.height+D:0,F=!!(e.xAxisLeft?.text||e.xAxisRight?.text),k=!!(e.yAxisBottom?.text||e.yAxisTop?.text),I=$||jl(t,"xAxisPosition")==="bottom",E=jl(t,"yAxisPosition")==="right",m=d-2*p,y=g(e.xAxisLeft,n,e.xAxisRight?m/2-16:m),C=g(e.xAxisRight,n,m/2-16),L=Math.max(y.height,C.height),S=F?L+u:0,Z=c-2*p-_-S,H=g(e.yAxisBottom,n,e.yAxisTop?Z/2-16:Z),R=g(e.yAxisTop,n,Z/2-16),P=Math.max(H.height,R.height),w=k?P+h:0,b=p+(E?0:w),M=p+_+(I?0:S),f=Math.max(0,m-w),x=Math.max(0,Z),A=Math.max(0,(f-pd)/2),z=Math.max(0,(x-pd)/2),v=[b+A,M,b+f-A,M+x,b,M+z,b+f,M+x-z],G=(B,Q,se,ie,re)=>{for(let ne=B;ne<v.length;ne+=4)if(Q<v[ne+2]&&ie>v[ne]&&se<v[ne+3]&&re>v[ne+1])return!1;return!0},ee=rr(t,"quadrantTextTopPadding",5,200),he="";for(let B=0;B<4;B++){let Q=B===0||B===3?b+f-A:b,se=B<2?M:M+x-z,ie=g(e.quadrants[B],i,A-16),re=Q+A/2,ne=$?se+ee+ie.height/2:se+z/2;v.push(re-ie.width/2,ne-ie.height/2,re+ie.width/2,ne+ie.height/2),he+=`<g class="pele-quadrant" data-id="${B+1}"><rect x="${o(Q)}" y="${o(se)}" width="${o(A)}" height="${o(z)}" rx="${Ke}"/>`+Ne(ie,re,ne,' class="pele-label" fill="var(--_fg)" stroke="none"')+"</g>"}let ue="";if(F){let B=I?M+x+u+L/2:M-u-L/2;ue+=Ne(y,C.height>0?b+f/4:b+y.width/2,B,"")+Ne(C,b+f*3/4,B,"")}if(k){let B=E?b+f+h+P/2:b-h-P/2,Q=(se,ie)=>se.height>0?`<g transform="translate(${o(B)},${o(ie)}) rotate(-90)">${Ne(se,0,0,"")}</g>`:"";ue+=Q(H,R.height>0?M+x*3/4:M+x-H.width/2)+Q(R,M+x/4)}let V=rr(t,"pointRadius",5,200),Y=rr(t,"pointTextPadding",5,200),de=it(0),te=[],xe=[];for(let B of e.points){if(!(B.x>=0&&B.x<=1&&B.y>=0&&B.y<=1))continue;let Q=e.classes.get(B.className),se=Math.min(B.radius??Q?.radius??V,2e3),ie=B.color??Q?.color,re=B.strokeColor??Q?.strokeColor,ne=B.strokeWidth??Q?.strokeWidth,X=[];ie&&X.push("fill:"+gd(ie)),ne&&(re&&X.push("stroke:"+gd(re)),X.push("stroke-width:"+ne));let j=b+B.x*f,oe=M+(1-B.y)*x;te.push({cx:j,cy:oe,reach:se+(ne?Math.min(parseInt(ne),400)/2:0),text:g(B.text,l,200)}),xe.push(`<circle class="pele-point${Mt(B.className)}" data-id="${Oe(B.text.text)}" cx="${o(j)}" cy="${o(oe)}" r="${o(se)}"${ne&&!re?` stroke="${de}"`:""}${ct(X).shape}/>`)}let me=te.length<=dg;if(me)for(let{cx:B,cy:Q,reach:se}of te)v.push(B-se,Q-se,B+se,Q+se);let ae="";for(let{cx:B,cy:Q,reach:se,text:ie}of te){let re=ie.width/2,ne=ie.size*.6+(ie.height-ie.lineHeight)/2,X=se+Y,j=[B,Q+X+ne,B,Q-X-ne,B+X+re,Q,B-X-re,Q],oe=B,$e=j[1],ge=!1;for(let Te=0;Te<16;Te+=2){let pe=Te%8,W=pe<4&&ie.width<f?Math.min(Math.max(j[pe],b+re),b+f-re):j[pe],K=j[pe+1];if(W-re<b||W+re>b+f||K-ne<M||K+ne>M+x)continue;let N=!me||G(Te<8?0:8,W-re,K-ne,W+re,K+ne);if((!ge||N)&&(oe=W,$e=K,ge=!0),N)break}me&&v.push(oe-re,$e-ne,oe+re,$e+ne),ae+=Ne(ie,oe,$e,' class="pele-label"')}let O=Ne(T,d/2,D/2+T.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g class="pele-quadrants" fill="var(--_s)" stroke="var(--_b)">${he}</g>`+(ue?`<g class="pele-axis-labels" font-size="${n}" fill="var(--_m)">${ue}</g>`:"")+(te.length>0?`<g class="pele-points" fill="${de}">${xe.reverse().join("")}</g><g class="pele-point-labels" font-size="${l}">${ae}</g>`:"");return{svg:Je("quadrantChart",d,c,i,r,e,O),width:d,height:c,links:[]}}var Xl={type:"quadrantChart",parse(e,t,r){let i=new sg;return i.title=r,cg(e,i),i},render:hg};var ut={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4};function Et(e){throw new He(e,"semantic",{type:"gitGraph"})}function md(e){return e==="REVERSE"?ut.REVERSE:e==="HIGHLIGHT"?ut.HIGHLIGHT:ut.NORMAL}function fg(e,t){e.dir&&t.setDirection(e.dir);for(let r of e.statements)ug(r,t)}function ug(e,t){switch(e.$type){case"Commit":t.commit({id:e.id,msg:e.message??"",type:e.type!==void 0?md(e.type):ut.NORMAL,tags:e.tags??void 0});break;case"Branch":t.branch({name:e.name,order:e.order??0});break;case"Merge":t.merge({branch:e.branch,id:e.id??"",type:e.type!==void 0?md(e.type):void 0,tags:e.tags??void 0});break;case"Checkout":t.checkout(e.branch);break;case"CherryPicking":t.cherryPick({id:e.id,targetId:"",tags:e.tags?.length===0?void 0:e.tags,parent:e.parent});break}}function pg(e,t,r){let i=t.gitGraph,n=typeof i?.mainBranchName=="string"?i.mainBranchName:"main",l=typeof i?.mainBranchOrder=="number"?i.mainBranchOrder:0,s=new Map,a=new Map([[n,null]]),d=new Map([[n,l]]),c=[],p=null,u=n,h="LR",$=0,g=()=>{for(let F=$+1;;F+=2654435761){let k=`${$}-${(Math.imul(F,2654435761)>>>0).toString(16).padStart(8,"0").slice(0,7)}`;if(!s.has(k))return k}},T=F=>{p=F,s.set(F.id,F),a.set(u,F.id)},D=F=>{a.has(F)||Et(`Trying to checkout branch which is not yet created. (Help try using "branch ${F}")`),u=F;let k=a.get(F);p=k?s.get(k)??null:null};fg(e,{setDirection(F){h=F},commit({msg:F,id:k,type:I,tags:E}){let m={id:k||g(),message:F,seq:$++,type:I??ut.NORMAL,tags:E?[...E]:[],parents:p===null?[]:[p.id],branch:u};s.has(m.id)&&c.push(`Commit ID ${m.id} already exists`),T(m)},branch({name:F,order:k}){a.has(F)&&Et(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${F}")`),a.set(F,p!==null?p.id:null),d.set(F,k),D(F)},merge({branch:F,id:k,type:I,tags:E}){let m=a.get(u),y=a.get(F),C=m?s.get(m):void 0,L=y?s.get(y):void 0;C&&L&&C.branch===F&&Et(`Cannot merge branch '${F}' into itself.`),u===F&&Et('Incorrect usage of "merge". Cannot merge a branch to itself'),C===void 0&&Et(`Incorrect usage of "merge". Current branch (${u})has no commits`),a.has(F)||Et(`Incorrect usage of "merge". Branch to be merged (${F}) does not exist`),L===void 0&&Et(`Incorrect usage of "merge". Branch to be merged (${F}) has no commits`),C===L&&Et('Incorrect usage of "merge". Both branches have same head'),k&&s.has(k)&&Et(`Incorrect usage of "merge". Commit with id:${k} already exists, use different custom id`),T({id:k||g(),message:`merged branch ${F} into ${u}`,seq:$++,parents:p===null?[]:[p.id,y||""],branch:u,type:ut.MERGE,customType:I,customId:!!k,tags:E?[...E]:[]})},cherryPick({id:F,targetId:k,tags:I,parent:E}){let m=F?s.get(F):void 0;if(m===void 0&&Et('Incorrect usage of "cherryPick". Source commit id should exist and provided'),E&&!m.parents.includes(E)&&Et("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit."),m.type===ut.MERGE&&!E&&Et("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified."),k&&s.has(k))return;m.branch===u&&Et('Incorrect usage of "cherryPick". Source commit is already on current branch');let y=a.get(u);(!y||!s.has(y))&&Et(`Incorrect usage of "cherry-pick". Current branch (${u})has no commits`),T({id:g(),message:`cherry-picked ${m.message} into ${u}`,seq:$++,parents:p===null?[]:[p.id,m.id],branch:u,type:ut.CHERRY_PICK,tags:I?I.filter(Boolean):[`cherry-pick:${m.id}${m.type===ut.MERGE?`|parent:${E}`:""}`]})},checkout:D});let _=[...d].map(([F,k],I)=>({name:F,order:k??parseFloat(`0.${I}`)})).sort((F,k)=>F.order-k.order).map(F=>F.name);return{type:"gitGraph",title:e.title||r,accTitle:e.accTitle?e.accTitle.replace(/^\s+/g,""):void 0,accDescr:e.accDescr?e.accDescr.replace(/\n\s+/g,`
91`):void 0,direction:h,commits:s,branches:a,lanes:_,currentBranch:u,head:p,warnings:c}}var kd={name:"REFERENCE",pattern:/\w([-\./\w]*[-\w])?/y},vd=[kd];function Rt(e){return{name:e,pattern:e,longer:vd}}var yd=[Rt("cherry-pick"),{name:"gitGraph:",pattern:"gitGraph:"},Rt("HIGHLIGHT"),{...Na("gitGraph"),longer:vd},Rt("checkout"),Rt("REVERSE"),{name:"parent:",pattern:"parent:"},Rt("commit"),Rt("NORMAL"),Rt("branch"),{name:"order:",pattern:"order:"},Rt("switch"),{name:"type:",pattern:"type:"},Rt("merge"),{name:"msg:",pattern:"msg:"},{name:"tag:",pattern:"tag:"},{name:"id:",pattern:"id:"},Rt("LR"),Rt("TB"),Rt("BT"),{name:":",pattern:":"},{...Ri,opener:/[\t ]*accDescr\s*{/y},zi,Fi,{name:"INT",pattern:/0|[1-9][0-9]*(?!\.)/y},Wi,Pi,Hi,Yi,Gi,Bi,kd];function gg(e){let t=new Xi(Oi(e,yd,"gitGraph"),yd,"gitGraph"),r={$type:"GitGraph",statements:[]},i=()=>{if(t.kind!==-1)for(t.kind!==26&&t.fail("a line break or the end of input");t.kind===26;)t.i++},n=()=>t.kind===31?t.take():t.kind===25?La(t.take()):t.fail("a branch name"),l=()=>La(t.expect(25)),s=()=>(t.kind!==8&&t.kind!==5&&t.kind!==2&&t.fail("NORMAL, REVERSE, or HIGHLIGHT"),t.take());for(;t.kind===26;)t.i++;if(!t.accept(1)){t.expect(3);let a=t.kinds[t.i+1];(t.kind===17||t.kind===18||t.kind===19)&&a===20?(r.$type="Direction",r.dir=t.take(),t.i++):t.accept(20)}for(;t.kind!==-1;)switch(t.kind){case 26:t.i++;break;case 21:r.accDescr=ji(t.take()),i();break;case 22:r.accTitle=qi(t.take()),i();break;case 23:r.title=Ui(t.take()),i();break;case 7:{t.i++;let a={$type:"Commit",tags:[]};for(;;)if(t.accept(16))a.id=l();else if(t.accept(15))a.tags.push(l());else if(t.accept(12))a.type=s();else if(t.accept(14)||t.kinds[t.i]===25)a.message=l();else break;i(),r.statements.push(a);break}case 9:{t.i++;let a={$type:"Branch",name:n()};t.accept(10)&&(a.order=parseInt(t.expect(24))),i(),r.statements.push(a);break}case 13:{t.i++;let a={$type:"Merge",branch:n(),tags:[]};for(;;)if(t.accept(16))a.id=l();else if(t.accept(15))a.tags.push(l());else if(t.accept(12))a.type=s();else break;i(),r.statements.push(a);break}case 4:case 11:{t.i++;let a={$type:"Checkout",branch:n()};i(),r.statements.push(a);break}case 0:{t.i++;let a={$type:"CherryPicking",tags:[]};for(;;)if(t.accept(16))a.id=l();else if(t.accept(15))a.tags.push(l());else if(t.accept(6))a.parent=l();else break;i(),r.statements.push(a);break}default:t.fail("a statement, a title, or a line break")}return r}var dt=7,mg=44,yg=44,hs=36,fs=8,Rr=20,Ba=20,Ua=7,$d=6,Vl=Math.SQRT1_2,wd=["normal","reverse","highlight","merge","cherry-pick"];function us(e,t,r){let i=e.gitGraph?.[t];return typeof i=="boolean"?i:r}function xd(e){return Ua+4+e.width+6}function $g(e,t,r,i){let n=`cx="${o(t)}" cy="${o(r)}"`;if(e===ut.HIGHLIGHT)return`<rect x="${o(t-dt-1)}" y="${o(r-dt-1)}" width="${2*dt+2}" height="${2*dt+2}" rx="2" fill="${i}"/>`;if(e===ut.MERGE)return`<circle ${n} r="${dt-1}" fill="var(--_bg)" stroke="${i}" stroke-width="2"/><circle ${n} r="2.5" fill="${i}"/>`;let l=`<circle ${n} r="${dt}" fill="${i}"/>`;return e===ut.REVERSE?l+`<path d="M${o(t-3)},${o(r-3)}l6,6M${o(t-3)},${o(r+3)}l6,-6" fill="none" stroke="var(--_bg)" stroke-width="1.5" stroke-linecap="round"/>`:e===ut.CHERRY_PICK?l+`<path d="M${o(t-2.6)},${o(r+1)}L${o(t+.8)},${o(r-4.2)}L${o(t+2.6)},${o(r+1)}" fill="none" stroke="var(--_bg)" stroke-linejoin="round"/><circle cx="${o(t-2.6)}" cy="${o(r+2.2)}" r="1.8" fill="var(--_bg)"/><circle cx="${o(t+2.6)}" cy="${o(r+2.2)}" r="1.8" fill="var(--_bg)"/>`:l}function wg(e,t,r){return e.direction!=="LR"?bd(e,t,r,e.direction):Ct(r,i=>bd(e,t,r,i?"TB":"LR"))}function bd(e,t,r,i){let n=r.fontSize??16,l=Math.round(n*.75),s=r.measurer??tt(r.fontFamily),a=r.padding??8,d=us(t,"showBranches",!0),c=us(t,"showCommitLabel",!0),p=us(t,"rotateCommitLabel",!0),u=us(t,"parallelCommits",!1),h=i!=="LR",$=i==="BT",g=new Map;e.lanes.forEach((O,B)=>g.set(O,B));let T=e.lanes.length,D=Math.round(n*.875),_=e.lanes.map(O=>er(d?O:"",s,D,4e3)),F=[],k=new Map;for(let O of[...e.commits.values()].sort((B,Q)=>B.seq-Q.seq)){let B=c&&O.type!==ut.CHERRY_PICK&&(O.type!==ut.MERGE||O.customId===!0),Q=[];for(let ie of O.tags){let re=er(ie,s,l,4e3);re.lines.length>0&&Q.push(re)}let se={commit:O,index:F.length,lane:g.get(O.branch)??0,m:0,label:B?er(O.id,s,l,4e3):void 0,tags:Q};F.push(se),k.set(O.id,se)}let I=new Float64Array(F.length),E=new Float64Array(F.length),m=new Float64Array(T).fill(dt),y=new Float64Array(T).fill(dt);F.forEach((O,B)=>{let{label:Q,tags:se}=O,ie=0,re=0;for(let ge of se){let Te=xd(ge);h?(ie=Math.max(ie,ge.height),re+=Te+4):(ie=Math.max(ie,Te),re+=ge.height+3)}let ne=0,X=0;Q!==void 0&&Q.lines.length>0&&(p?X=3+Vl*(Q.width+Q.height):(ne=h?Q.height:Q.width,X=6+(h?Q.width:Q.height))),I[B]=Math.max(dt,ie/2,ne/2),E[B]=ie/2;let j=dt+(se.length>0?$d+re:0),oe=dt+X,$e=O.lane;m[$e]=Math.max(m[$e],h?oe:j),y[$e]=Math.max(y[$e],h?j:oe)});let C=new Float64Array(F.length);h||F.forEach((O,B)=>{if(E[B]!==0)for(let Q of O.commit.parents){let se=k.get(Q);se!==void 0&&se.lane<O.lane&&(C[B]=E[B]+4)}});let L=(O,B)=>Math.max(mg,I[O]+I[B]+fs,C[B]>0?I[O]+hs+C[B]:0);F.forEach((O,B)=>{if(!u){O.m=B===0?0:F[B-1].m+L(B-1,B);return}let Q=0;for(let se of O.commit.parents){let ie=k.get(se);ie===void 0||ie.index>=B||(Q=Math.max(Q,ie.m+L(ie.index,B)))}O.m=Q});let S=0;for(let O of F)S=Math.max(S,O.m);let Z=new Float64Array(T);for(let O=0;O<T;O++){let B=_[O],Q=B.lines.length===0?0:h?B.width/2+8:B.height/2+2;m[O]=Math.max(m[O],Q),y[O]=Math.max(y[O],Q),O>0&&(Z[O]=Z[O-1]+Math.max(yg,y[O-1]+m[O]+fs))}let H=(O,B)=>h?B:O,R=(O,B)=>h?$?-O:O:B,P=(O,B)=>`${o(H(O,B))},${o(R(O,B))}`,w=1/0,b=1/0,M=-1/0,f=-1/0,x=(O,B,Q,se)=>{O<w&&(w=O),B<b&&(b=B),Q>M&&(M=Q),se>f&&(f=se)},A="";if(d)for(let O=0;O<T;O++){let B=_[O],Q=it(O),se=Z[O],ie=B.width+16,re=B.height+4,ne=B.lines.length===0?-Rr:-Rr-(h?re:ie),X=H(ne+(h?re:ie)/2,se),j=R(ne+(h?re:ie)/2,se);x(H(-Rr,se),R(-Rr,se),H(-Rr,se),R(-Rr,se)),x(H(S+Ba,se),R(S+Ba,se),H(S+Ba,se),R(S+Ba,se)),A+=`<g class="pele-branch" data-id="${Oe(e.lanes[O])}"><path class="pele-lane" d="M${P(-Rr,se)}L${P(S+Ba,se)}" stroke="${Q}" stroke-dasharray="2 4"/>`,B.lines.length>0&&(x(X-ie/2,j-re/2,X+ie/2,j+re/2),A+=`<rect x="${o(X-ie/2)}" y="${o(j-re/2)}" width="${o(ie)}" height="${o(re)}" rx="${Ke}" fill="${Q}"/>`+Ne(B,X,j,' class="pele-label" fill="var(--_bg)"')),A+="</g>"}let z=Array.from({length:T},()=>[]);for(let O of F)z[O.lane].push(O.m);if(u)for(let O of z)O.sort((B,Q)=>B-Q);let v=(O,B,Q)=>{let se=z[O],ie=0,re=se.length;for(;ie<re;){let ne=ie+re>>1;se[ne]<=B?ie=ne+1:re=ne}return ie<se.length&&se[ie]<Q},G="",ee="";for(let O of F){let{commit:B}=O,Q=Z[O.lane],se=O.m;for(let ie=0;ie<B.parents.length;ie++){let re=k.get(B.parents[ie]);if(re===void 0||re===O)continue;let ne=Z[re.lane],X=re.m;if(re.lane===O.lane){ee+=`<path class="pele-edge" d="M${P(X,ne)}L${P(se,Q)}" stroke="${it(O.lane)}"/>`;continue}let j=ie>0&&B.type===ut.MERGE,oe=ie>0&&!j,$e=`M${P(X,ne)}`;if(se<=X){let ge=(X+se)/2;$e+=`C${P(ge,ne)} ${P(ge,Q)} ${P(se,Q)}`}else if(!j&&!v(O.lane,X,se)){let ge=Math.min(hs,se-X);$e+=`C${P(X+ge/2,ne)} ${P(X+ge/2,Q)} ${P(X+ge,Q)}L${P(se,Q)}`}else{let ge=re.lane<O.lane&&se-C[O.index]>X?se-C[O.index]:se,Te=Math.min(hs,ge-X),pe=ne;(!j||v(re.lane,X,se))&&(pe=ne>Q?Q+y[O.lane]+fs/2:Q-m[O.lane]-fs/2,Te=Math.min(hs,(ge-X)/2),$e+=`C${P(X+Te/2,ne)} ${P(X+Te/2,pe)} ${P(X+Te,pe)}`),$e+=`L${P(ge-Te,pe)}C${P(ge-Te/2,pe)} ${P(ge-Te/2,Q)} ${P(ge,Q)}`,ge<se&&($e+=`L${P(se,Q)}`)}G+=`<path class="pele-edge${j?" pele-edge-merge":oe?" pele-edge-cherry-pick":""}" d="${$e}" stroke="${it(j?re.lane:O.lane)}"${oe?' stroke-dasharray="4 3"':""}/>`}}let he="";for(let O of F){let{commit:B,label:Q,tags:se}=O,ie=H(O.m,Z[O.lane]),re=R(O.m,Z[O.lane]),ne=B.customType??B.type;x(ie-dt-1,re-dt-1,ie+dt+1,re+dt+1);let X=B.type<ut.MERGE&&B.message!==""?`<title>${Oe(B.message)}</title>`:"";if(X+=$g(ne,ie,re,it(O.lane)),Q!==void 0&&Q.lines.length>0){let $e=Q.width,ge=Q.height,Te=(pe,W)=>`<rect x="${o(pe-$e/2-2)}" y="${o(W-ge/2+2)}" width="${o($e+4)}" height="${o(ge-4)}" rx="3" fill="var(--_bg)"/>`;if(p){let pe=Vl*ge/2,W=h?ie-dt-3-pe:ie+3,K=h?re:re+dt+3+pe,N=Vl*$e+pe;x(W-N,$?K-N:K-pe,W+pe,$?K+pe:K+N),X+=`<g class="pele-commit-label" transform="rotate(${$?45:-45} ${o(W)} ${o(K)})">`+Te(W-$e/2,K)+Ne(Q,W-$e/2,K,"")+"</g>"}else{let pe=h?ie-dt-6-$e/2:ie,W=h?re:re+dt+6+ge/2;x(pe-$e/2,W-ge/2,pe+$e/2,W+ge/2),X+=`<g class="pele-commit-label">${Te(pe,W)}${Ne(Q,pe,W,"")}</g>`}}let j=dt+$d;for(let $e=h?0:se.length-1;$e>=0&&$e<se.length;$e+=h?1:-1){let ge=se[$e],Te=xd(ge),pe=ge.height,W=h?ie+j:ie-Te/2,K=h?re:re-j-pe/2;j+=h?Te+4:pe+3,x(W,K-pe/2,W+Te,K+pe/2),X+=`<g class="pele-tag"><path d="M${o(W)},${o(K)}L${o(W+Ua)},${o(K-pe/2)}H${o(W+Te)}V${o(K+pe/2)}H${o(W+Ua)}Z" fill="var(--_s)" stroke="var(--_b)" stroke-linejoin="round"/><circle cx="${o(W+Ua)}" cy="${o(K)}" r="1.5" fill="var(--_b)"/>`+Ne(ge,W+Ua+4+ge.width/2,K,' fill="var(--_fg)"')+"</g>"}let oe=B.type===ut.MERGE&&ne!==ut.MERGE?" pele-commit-merge":"";he+=`<g class="pele-commit pele-commit-${wd[ne]??wd[0]}${oe}" data-id="${Oe(B.id)}">${X}</g>`}w>M&&x(0,0,0,0);let ue=Fe(e.title,!1,s,n,4e3,1),V=ue.height>0?ue.height+16:0,Y=Math.max(M-w,ue.width),de=Math.ceil(Y+2*a),te=Math.ceil(f-b+V+2*a),xe=a-w+(Y-(M-w))/2,me=a+V-b,ae=Ne(ue,de/2,a+ue.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g transform="translate(${o(xe)},${o(me)})">`+(A?`<g class="pele-branches" fill="none" font-size="${D}">${A}</g>`:"")+(G||ee?`<g class="pele-edges" fill="none" stroke-width="2" stroke-linecap="round">${G}${ee}</g>`:"")+(he?`<g class="pele-commits" font-size="${l}" fill="var(--_m)">${he}</g>`:"")+"</g>";return{svg:Je("gitGraph",de,te,n,r,e,ae),width:de,height:te,links:[]}}var Kl={type:"gitGraph",parse:(e,t,r)=>pg(gg(e),t,r),render:wg};var xg=class{type="sankey";nodes=[];links=[];title;accTitle;accDescr;lookup=new Map;findOrCreateNode(e){let t=this.lookup.get(e);return t===void 0&&(t={id:e,index:this.nodes.length},this.lookup.set(e,t),this.nodes.push(t)),t}addLink(e,t,r){this.links.push({source:e,target:t,value:r})}},Zl=["$end","STUCK","SANKEY","NEWLINE","COMMA","DQUOTE","NON_ESCAPED_TEXT","ESCAPED_TEXT","EOF"];function Md(e){return e>=32&&e<=126&&e!==34&&e!==44}function bg(e){let t=e.length,r=[],i=[],n=[],l=[],s=0,a=0,d=(p,u,h)=>{r.push(p),i.push(e.slice(u,h)),n.push(u),a=h},c=p=>e.slice(a,a+p.length).toLowerCase()===p&&!Pe(e.charCodeAt(a+p.length));for(;a<t;){let p=e.charCodeAt(a),u=a,h=a;if(s===2){if(p===34&&e.charCodeAt(a+1)!==34){l.length>0&&(s=l.pop()),d(5,a,a+1);continue}for(;h<t;){let $=e.charCodeAt(h);if(Md($)||$===44||$===13||$===10)h++;else if($===34&&e.charCodeAt(h+1)===34)h+=2;else break}d(7,a,h)}else{if(s===0&&(p|32)===115){let $=c("sankey-beta")?11:c("sankey")?6:0;if($>0){l.push(s),s=1,d(2,a,a+$);continue}}if(p===10||p===13&&e.charCodeAt(a+1)===10){d(3,a,p===10?a+1:a+2);continue}if(p===44){d(4,a,a+1);continue}if(p===34){l.push(s),s=2,d(5,a,a+1);continue}for(;h<t&&Md(e.charCodeAt(h));)h++;d(6,a,h)}if(h===u)return d(1,a,a),{types:r,texts:i,starts:n}}return d(s===2?7:8,t,t),d(0,t,t),{types:r,texts:i,starts:n}}var kg=/[\n\r]+/g;function Ad(e){return e===10||e===13?!1:e<128?e===32||e===9||e===11||e===12:e===160||e===5760||e>=8192&&e<=8202||e===8232||e===8233||e===8239||e===8287||e===12288||e===65279}function vg(e){let t=0,r=e.length;for(;t<r&&Ad(e.charCodeAt(t));)t++;for(;r>t&&Ad(e.charCodeAt(r-1));)r--;return e.slice(t,r).replace(kg,`
92`).trim()}function Mg(e,t){let{types:r,texts:i,starts:n}=bg(e),l=0,s=p=>{let u=r[l],h=u===1?Zl[r[l-1]]:Zl[u];throw Ve("sankey",e,n[l],`Expecting ${p}, got '${h}'`)},a=(p,u="")=>{r[l]!==p&&s(`'${Zl[p]}'${u}`),l++},d=()=>{if(r[l]===6)return i[l++];r[l]!==5&&s("'DQUOTE', 'NON_ESCAPED_TEXT'"),l++,r[l]!==7&&s("'ESCAPED_TEXT'");let p=i[l++];return a(5),p},c=()=>d().trim().replaceAll('""','"');for(a(2),a(3);;){let p=c();a(4,", 'NEWLINE', 'EOF'");let u=c();a(4,", 'NEWLINE', 'EOF'");let h=d(),$=t.findOrCreateNode(p),g=t.findOrCreateNode(u);if(t.addLink($,g,parseFloat(h.trim())),r[l]!==3)break;l++}r[l]===8&&l++,r[l]!==0&&s("'NEWLINE', 'EOF'")}var Ag=6;function Ql(e,t){if(e.length>8){e.sort(t);return}for(let r=1;r<e.length;r++){let i=e[r],n=r-1;for(;n>=0&&t(e[n],i)>0;)e[n+1]=e[n],n--;e[n+1]=i}}function Tg(e,t){let r=e.nodes.length,i=e.links.map(M=>({source:M.source.index,target:M.target.index,value:Number.isFinite(M.value)&&M.value>0?M.value:0,thickness:0,sourceY:0,targetY:0})),n=[],l=[];for(let M=0;M<r;M++)n.push([]),l.push([]);i.forEach((M,f)=>{n[M.source].push(f),l[M.target].push(f)});let s=new Int32Array(r),a=new Int32Array(r),d=[];for(let M=0;M<r;M++)a[M]=l[M].length,a[M]===0&&d.push(M);for(let M=0;M<d.length;M++){let f=d[M];for(let x of n[f]){let A=i[x].target;s[A]<s[f]+1&&(s[A]=s[f]+1),--a[A]===0&&d.push(A)}}if(d.length<r){let M=0;for(;a[M]===0;)M++;let f=new Uint8Array(r);for(;f[M]===0;){f[M]=1;for(let x of l[M])if(a[i[x].source]>0){M=i[x].source;break}}throw new He(`Sankey diagrams cannot have circular links, and "${e.nodes[M].id}" is part of one.`,"semantic",{type:"sankey"})}let c=1;for(let M=0;M<r;M++)s[M]+1>c&&(c=s[M]+1);let p=new Int32Array(r);for(let M=r-1;M>=0;M--){let f=d[M];for(let x of n[f])p[f]<p[i[x].target]+1&&(p[f]=p[i[x].target]+1)}let u=0;for(let M of i)M.value>u&&(u=M.value);let h=u>0?1/u:0,$=[],g=new Float64Array(r),T=[];for(let M=0;M<c;M++)T.push([]);let D=c>1?(t.width-t.nodeWidth)/(c-1):0;for(let M=0;M<r;M++){let f;if(t.alignment==="left")f=s[M];else if(t.alignment==="right")f=c-1-p[M];else if(t.alignment==="center"){if(f=s[M],l[M].length===0&&n[M].length>0){f=c;for(let G of n[M])s[i[G].target]-1<f&&(f=s[i[G].target]-1)}}else f=n[M].length>0?s[M]:c-1;let x=0,A=0,z=0,v=0;for(let G of l[M])x+=i[G].value*h,z+=i[G].value;for(let G of n[M])A+=i[G].value*h,v+=i[G].value;g[M]=Math.max(x,A),$.push({layer:f,value:Math.max(z,v),x:f*D,y:0,height:0}),T[f].push(M)}let _=1;for(let M of T)M.length>_&&(_=M.length);let F=_>1?Math.min(t.nodePadding,t.height/(_-1)):t.nodePadding,k=1/0;for(let M of T){let f=0;for(let x of M)f+=g[x];f>0&&(k=Math.min(k,(t.height-(M.length-1)*F)/f))}(!Number.isFinite(k)||k<0)&&(k=0);let I=Math.max(0,t.labelHeight-F),E=M=>{for(let f of T){let x=(f.length-1)*F;for(let A of f)x+=Math.max(g[A]*M,I);if(x>t.height+1e-6)return!1}return!0};if(I>0&&!E(k))if(E(0)){let M=0;for(let f=0;f<40;f++){let x=(M+k)/2;E(x)?M=x:k=x}k=M}else I=0;let m=new Float64Array(r);for(let M of i)M.thickness=M.value*h*k;for(let M of T){let f=0;for(let A of M)$[A].height=g[A]*k,m[A]=Math.max(0,I-$[A].height)/2,$[A].y=f+m[A],f+=$[A].height+2*m[A]+F;let x=(t.height-f+F)/(M.length+1);M.forEach((A,z)=>$[A].y+=x*(z+1))}let y=M=>$[M].y+$[M].height/2,C=new Float64Array(i.length),L=new Float64Array(i.length),S=(M,f)=>y(i[M].target)-y(i[f].target)||M-f,Z=(M,f)=>y(i[M].source)-y(i[f].source)||M-f,H=(M,f)=>y(M)-y(f)||M-f,R=M=>{let f=0;Ql(n[M],S);for(let x of n[M])C[x]=f+i[x].thickness/2,f+=i[x].thickness},P=M=>{let f=0;Ql(l[M],Z);for(let x of l[M])L[x]=f+i[x].thickness/2,f+=i[x].thickness},w=()=>{for(let M=0;M<r;M++)R(M),P(M)},b=(M,f,x)=>{for(let z of M){let v=x?l[z]:n[z];if(v.length===0)continue;x?P(z):R(z);let G=0,ee=0,he=0;for(let V of v){let Y=x?$[i[V].source].y+C[V]-L[V]:$[i[V].target].y+L[V]-C[V];G+=Y*i[V].thickness,ee+=i[V].thickness,he+=y(x?i[V].source:i[V].target)-$[z].height/2}let ue=ee>0?G/ee:he/v.length;$[z].y+=(ue-$[z].y)*f}Ql(M,H);let A=0;for(let z of M)$[z].y-m[z]<A&&($[z].y=A+m[z]),A=$[z].y+$[z].height+m[z]+F;A=t.height;for(let z=M.length-1;z>=0;z--){let v=M[z];$[v].y+$[v].height+m[v]>A&&($[v].y=A-$[v].height-m[v]),A=$[v].y-m[v]-F}};w();for(let M=0;M<Ag;M++){let f=Math.pow(.99,M);for(let x=c-2;x>=0;x--)b(T[x],f,!1);w();for(let x=1;x<c;x++)b(T[x],f,!0);w()}for(let M=0;M<i.length;M++)i[M].sourceY=$[i[M].source].y+C[M],i[M].targetY=$[i[M].target].y+L[M];return{nodes:$,links:i}}var Td=6,Cg=15;function _d(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ps(e,t,r,i,n){let l=e[t];return typeof l=="number"&&l>=i?Math.min(l,n):r}function Cd(e,t){let r=e[t];return typeof r=="string"||typeof r=="number"&&Number.isFinite(r)?String(r):""}function Ed(e){return Math.abs(e)<1e15?Math.round(e*100)/100:e}function Sd(e){return typeof e=="string"?ct([`fill:${e}`]).shape:""}function Eg(e,t,r){let i=_d(t.sankey)?t.sankey:{};return mi(r,ps(i,"width",600,1,1e4),160,n=>Sg(e,i,r,n))}function Sg(e,t,r,i){let n=r.fontSize??16,l=Math.round(n*.875),s=r.measurer??tt(r.fontFamily),a=r.padding??8,d=ps(t,"height",400,1,1e4),c=Math.min(ps(t,"nodeWidth",10,1,200),i),p=t.showValues!==!1,u=Cd(t,"prefix"),h=Cd(t,"suffix"),$=t.labelStyle==="outlined",g=t.nodeAlignment==="left"||t.nodeAlignment==="right"||t.nodeAlignment==="center"?t.nodeAlignment:"justify",T=typeof t.linkColor=="string"?t.linkColor:"gradient",{nodes:D,links:_}=Tg(e,{width:i,height:d,nodeWidth:c,nodePadding:ps(t,"nodePadding",12,0,200)+(p?Cg:0),labelHeight:l*1.15,alignment:g}),F=new Map;if(_d(t.nodeColors))for(let[z,v]of Object.entries(t.nodeColors)){let G=Sd(v);G&&F.set(z,G)}let k=z=>F.get(e.nodes[z].id)??"",I=0,E=0;D.forEach(z=>{z.value>E&&(E=z.value,I=z.layer)});let m=0,y=i,C=0,L=d,S="",Z="";D.forEach((z,v)=>{let G=e.nodes[v].id,ee=Math.max(z.height,1);Z+=`<rect class="pele-sankey-node" data-id="${Oe(G)}" x="${o(z.x)}" y="${o(z.y)}" width="${o(c)}" height="${o(ee)}" rx="${o(Math.min(2,ee/2))}" fill="${it(v)}"${k(v)}/>`;let he=p?`${u}${Ed(z.value)}${h}`:"",ue=$?z.layer>=I:z.x<i/2,V=s.width(he?`${G} ${he}`:G,l,0),Y=ue?z.x+c+Td:z.x-Td,de=z.y+z.height/2;m=Math.min(m,ue?Y:Y-V),y=Math.max(y,ue?Y+V:Y),C=Math.min(C,de-l*.75),L=Math.max(L,de+l*.75);let te=` x="${o(Y)}" y="${o(de+l*.35)}" text-anchor="${ue?"start":"end"}"`,xe=Be(G)+(he?` <tspan class="pele-sankey-value" fill="var(--_m)">${Be(he)}</tspan>`:"");S+=`<g class="pele-label" data-id="${Oe(G)}">`+($?`<text${te} fill="none" stroke="var(--_bg)" stroke-width="3" stroke-linejoin="round">${Be(G)}${he?" "+Be(he):""}</text>`:"")+`<text${te}>${xe}</text></g>`});let H=T==="gradient"||T==="source"||T==="target"?"":Sd(T),R="";for(let z of _){let v=T==="target"?z.target:z.source,G=Math.max(z.thickness,1)/2,ee=D[z.source].x+c,he=D[z.target].x,ue=o((ee+he)/2),V=Oe(e.nodes[z.source].id),Y=Oe(e.nodes[z.target].id);R+=`<path class="pele-sankey-link" data-id="${V}->${Y}" d="M${o(ee)},${o(z.sourceY-G)}C${ue},${o(z.sourceY-G)} ${ue},${o(z.targetY-G)} ${o(he)},${o(z.targetY-G)}L${o(he)},${o(z.targetY+G)}C${ue},${o(z.targetY+G)} ${ue},${o(z.sourceY+G)} ${o(ee)},${o(z.sourceY+G)}Z" fill="${it(v)}"${H||k(v)}><title>${V} \u2192 ${Y}: ${Oe(u)}${Ed(z.value)}${Oe(h)}</title></path>`}let P=Fe(e.title,!1,s,n,Pt(r),1),w=P.height>0?P.height+12:0,b=Math.max(y-m,P.width),M=a-m+(b-(y-m))/2,f=a+w-C,x=Math.ceil(b+2*a),A=Math.ceil(L-C+w+2*a);return{svg:Je("sankey",x,A,n,r,e,Ne(P,x/2,a+P.height/2,' class="pele-title" font-weight="var(--_tw)"')+`<g transform="translate(${o(M)},${o(f)})"><g class="pele-sankey-links" fill-opacity="0.4">${R}</g><g class="pele-sankey-nodes">${Z}</g><g class="pele-labels" font-size="${l}">${S}</g></g>`),width:x,height:A,links:[]}}var Jl={type:"sankey",parse(e,t,r){let i=new xg;return r&&(i.title=r),Mg(vg(e),i),i},render:Eg};vs(qs,Zs,rl,dl,xl,Al,Il,Ol,Wl,Gl,Xl,Kl,Jl);return Rd(_g);})();
93return pele
94}
95