SLOPSHOPPER

cellsmith

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

newspinnerrowscommandtoastprompt
★ 1v0.2.0MITupdated 2026-10-244our4ace/cellsmith/plugin
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · cellsmith
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ fix the failing auth test and add an audit log call │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ⏺ Read(src/auth.ts) ⎿ Read 6 lines Edited src/auth.ts ● ⏺ Bash(bun test) ⎿ 3 pass, 1 fail Done. I made refresh reject expired claims and added an audit call. ✻ Worked for 42s › /cellsmith Commands ━━━━━━━━ [ ⧉ md ] [ ⧉ art ] ┌─────────────────────────┬───────────────────────────────────────────────────────────┐ │ Command │ Does │ ╞═════════════════════════╪═══════════════════════════════════════════════════════════╡ │ /cellsmith theme <name> │ Switch theme on the spot │ ├─────────────────────────┼───────────────────────────────────────────────────────────┤ │ /cellsmith copy │ Copy the last reply, or copy code for its last code block │ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Turn line
✻ Worked for 42s
Your message
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │ fix the failing auth test and add an audit log call │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
Claude's reply
Done. I made refresh reject expired claims and added an audit call.
Tool row
Edited src/auth.ts ●
Command output
Commands ━━━━━━━━ [ ⧉ md ] [ ⧉ art ] ┌─────────────────────────┬───────────────────────────────────────────────────────────┐ │ Command │ Does │ ╞═════════════════════════╪═══════════════════════════════════════════════════════════╡ │ /cellsmith theme <name> │ Switch theme on the spot │ ├─────────────────────────┼───────────────────────────────────────────────────────────┤ │ /cellsmith copy │ Copy the last reply, or copy code for its last code block │ ├─────────────────────────┼───────────────────────────────────────────────────────────┤ │ /cellsmith demo │ Full showcase, every element and diagram │ ├─────────────────────────┼───────────────────────────────────────────────────────────┤ │ /cellsmith demo-rtl │ Hebrew right-to-left showcase │ └─────────────────────────┴───────────────────────────────────────────────────────────┘ 16 themes [ ⧉ copy ] • Dark: catppuccin-mocha, 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 • Plain: mono, no color, only bold and dim Forked from https://github.com/NahumLitvin/prismantis, diagrams laid out by https://pele.run ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │ Tip │ │ Any color slot beats the theme. Set headingColor or numberColor to a hex value in /config. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ Task lists [ ⧉ copy ] [✓] Tables, diagrams and charts drawn in the terminal [✓] Copy tables as Markdown, art or HTML (macOS/Linux) [ ] Pick a taskStyle in /config: checks, ticks, box or progress [ ⧉ source ] [ ⧉ art ] ┌────────┐ ┌────────┐ ┌───────┐ ┌─────────┐ │ Reply ├───►│ Parse ├───►│ Draw ├───►│ Screen │ └────────┘ └────────┘ └───────┘ └─────────┘ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │ Caution │ │ Claude Code refuses trees over 20000 nodes. A code block past about 500 highlighted lines falls │ │ back to plain text. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
README

cellsmith

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.

A reply drawn by cellsmith in the catppuccin-mocha theme: a flowchart, a sequence diagram, a pie chart, a gantt chart, a state diagram and a bar chart side by side

TL;DR

  • Claude Code prints mermaid as source and tool calls as walls of text. cellsmith draws them: flowcharts, sequence, state, class and ER diagrams, pie, bar and line charts, gantt charts, timelines, mindmaps, quadrant charts, git graphs and sankey diagrams, plus typeset LaTeX math in kitty and Ghostty, colored tables and code, and quiet tool rows.
  • 15 palettes plus mono, and copy buttons on everything.
  • Two commands to install, /plugin to turn it off. Claude Code's own renderer comes back the moment you do.
  • No network calls. It runs a program only when you click ⧉ html (the clipboard helper) or turn on LaTeX (RaTeX's renderer).

The same reply drawn by Claude Code on the left and by cellsmith on the right: a table, a shell command and a flowchart

Install

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.

Features

FeatureWhat you get
Themes/cellsmith theme <name> switches on the spot. 16 themes and 20 color slots you can override
Tablescolored headers, rules, column alignment, colored numbers, sized to the terminal
Codea language header and copy button, Prism highlighting in two dozen languages, shell lines colored like a prompt
Diagrams and chartsflowcharts, 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
Layoutback-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 rowsRan 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 commandscommand output (/cost, /context, plugin commands) gets the same tables and code styling
Diagram hintsa short model-only note on each prompt so Claude reaches for diagrams and charts when they help
Textbold, italic, strikethrough, inline code, links, versions, durations, percentages and paths in their own colors
Headings, lists, quotes4 heading styles, nested lists, task lists, quotes with an accent bar
Your promptswhat you type draws in a bubble, an accent bar or a chevron, so you find your turns when you scroll back
Right to leftHebrew 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

Themes

The same reply in catppuccin-mocha, tokyo-night, gruvbox-light and mono

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.

Tables

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.

Code

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.

  • Prism highlights JavaScript, TypeScript, JSX/TSX, Python, Go, Rust, Java, Kotlin, Swift, C, C++, C#, Ruby, JSON, YAML, TOML, SQL, HTML, CSS, Dockerfile, HCL and diff.
  • Shell blocks (bash, sh, zsh, fish, powershell, unlabeled) color the command word, --flags, quoted strings and # comments, and restart after |, && and ;.

Diagrams and charts

Code blocks tagged mermaid draw as colored terminal graphics:

  • flowcharts, sequence, state, class and ER diagrams, with each box and participant in its own theme color, the same at both ends of a sequence diagram
  • pie charts, bar and line charts (xychart-beta), gantt charts, timelines, mindmaps, quadrant charts, git graphs and sankey diagrams
  • a single-series bar chart colors its tallest bar and mutes the rest

How 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.

LaTeX math

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.

Layout

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.

Copy buttons

  • Tables: ⧉ 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.
  • Code, lists and quotes: [ ⧉ copy ] on each. Code copies without its fences, lists as markdown, quotes without their > markers.
  • Diagrams: ⧉ source copies the mermaid code, ⧉ art the drawn art.
  • Whole replies: replies with more than one block, or any Hebrew or Arabic, end with ⧉ 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.
  • No mouse: /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.

Tool rows

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.

quiet: the row says what was listed and read, and nothing is drawn under it

Turn footer

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.

Slash commands

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.

Diagram hints

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.

Text

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.

Headings, lists, quotes

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.

Your prompts

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.

Right to left

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.

Looks

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
Defaults: a prompt bubble, a dimmed tool row on the right, check boxes, a boxed table and a banner headingAn accent bar prompt, a tool row tucked under the prompt, ticks, a table with rules and bold headings
chevron · tree-bold · box · grid · underlinebubble · classic · progress · minimal · uppercase
A chevron prompt, a bold tree tool row, box ticks, a grid table and underlined headingsA prompt bubble, a classic tool row with a status dot, a progress bar over the task list, a minimal table and an uppercase heading

Configure

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.

OptionValuesDefault
enabledtrue, falsetrue
themesee Themescatppuccin-mocha
tableStylebox, rules, grid, minimalbox
taskStylechecks ([ ] [✓], done struck through), ticks (○ ✓), box (□ ✓), progress (ticks with a done-count bar)checks
promptStylebubble, bar, chevron, offbubble
headingStylebanner, bold, underline, uppercasebanner
highlightNumberstrue, falsetrue
highlightPathstrue, falsetrue
toolRowstrue, falsetrue
toolStylechat, tree-dim, tree-bold, classicchat
toolOutputfull, quietfull
copyButtonstrue, falsetrue
diagramHintstrue, falsetrue
rtlauto, a terminal (warp, kitty, apple-terminal, iterm, ghostty, wezterm, vscode, alacritty, windows-terminal, gnome, konsole), offauto
mermaidtrue, falsetrue
mermaidAsciitrue, falsefalse
latextrue, falsefalse
<token>Colorany color, see belowtheme

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:

TokenColors
accentreply bullet, H3+ headings, quote bar, running tool dots
headingH1 and H2
strongbold text
emphasisitalic text, variables, attribute names
inlineCodeinline code
codeTextcode block text
codeCommandshell commands, functions, class names, keys
codeFlag--flags, keywords, failures
codeStringstrings
codeCommentcomments, the code block's language label
linklinks, URLs, properties, tags
pathfile paths, regexes
numbernumbers, versions, durations, done dots
quotequote text
rulerules, chart gridlines
tableHeadertable header cells
tableRuletable rules
bulletlist bullets and numbers
diagramdiagram lines
diagramTextdiagram labels and LaTeX formulas

Troubleshooting

  • A setting or update didn't take: run /reload. A session keeps what it loaded.
  • A diagram shows as code: it is still streaming, its source is over 80 lines or 8,000 characters, it's wider than the window, it doesn't parse, or mermaid is off. Widen the terminal or split the diagram.
  • No ⧉ 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.
  • Clicking a copy button selects the word "copy": your terminal copies on select. Use /cellsmith copy.
  • Diagram fills look grey: Claude Code fell back to 256 colors because your terminal doesn't set COLORTERM. WSL doesn't pass it through from Windows Terminal. Set COLORTERM=truecolor in your shell profile and start a new session.

Limits

  • The parser covers what Claude writes (headings, lists, tables, fences, quotes, emphasis, links). It's not full CommonMark: nested quotes and HTML draw as plain text.
  • Widths count CJK and emoji as two columns. Terminals disagree on a few emoji, so those can still be off by one.
  • Languages outside the 24 above draw in codeText.
  • cellsmith bundles 13 of Pele's diagram types: flowchart, sequence, state, class, ER, pie, gantt, xychart, timeline, mindmap, quadrant, git graph and sankey. The other types (C4, architecture, block, kanban, journey and more) would roughly double the module, which loaded about 0.8 s slower in the test runtime, so they fall back to the old engine or stay as code. Add one to PELE_DIAGRAMS in ../scripts/build-vendor.mjs to bundle it.
  • Braille curves and quarter-block fills need a font with those characters; most terminal fonts have them.
  • Tested on Linux (WSL, with Windows Terminal and in tmux). macOS, native Windows, the desktop app, VS Code and mobile use the same mod API but are not checked by hand yet.

To change the code, read AGENTS.md instead.

  • What it is: a Claude Code mod (function hooks in TypeScript) that redraws assistant replies, slash-command output, tool rows, the turn footer and user prompts. It changes how things look. The one thing it sends the model is the optional diagram hint below.
  • Install: claude plugin marketplace add 4our4ace/cellsmith, then claude plugin install cellsmith@cellsmith. Needs Claude Code 2.1.287+. Changes apply after /reload.
  • Configure: /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.
  • Side effects: no network. Programs it runs: the ⧉ 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.
  • Turning it off: "enabled": false, or disable the plugin in /plugin.
  • For other mods: $.cellsmith.markdown({ surface, text, columns }), typed in types/index.d.ts. See Other mods.

Develop

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

Source 16 files
hooks/register.tsx 395 lines
1import { 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}
395
hooks/latex.ts 99 lines
1import 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])))
99
hooks/markdown.ts 255 lines
1export 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}
255
hooks/clipboard.ts 31 lines
1export 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})
31
hooks/mermaid.tsx 229 lines
1import 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)}|`)
229
hooks/render.tsx 1155 lines
1import 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}
1155
hooks/help.ts 209 lines
1export 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`
209
hooks/presets.ts 118 lines
1import 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}
118
hooks/theme.ts 79 lines
1import 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}
79
hooks/rtl.ts 232 lines
1import 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)
232
hooks/vendor/mermaid-text.js 13 lines
1function 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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}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&&currentRole!==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==="}"&&currentNamespace){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&&currentNamespace.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&&currentNamespace.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&&currentEntity.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};
13
hooks/vendor/pele.js 95 lines
1export 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={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"};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=/^.+(:|&colon;)/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?"&lt;"+Er(K.type).replace(/</g,"&lt;").replace(/>/g,"&gt;")+"&gt;":"",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,"&lt;").replace(/>/g,"&gt;")}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,"&lt;")),l.includes(":fa-")&&(l=l.replace(v1,"&colon;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}-&gt;${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