"use client";
/**
* Single MermaidDiagram for the unified markdown engine (dark theme only —
* the old RichMarkdownRenderer's light-theme branch was dead code behind a
* hardcoded `isDarkMode = true` and is deleted, not carried over).
*
* `mermaid` stays a dynamic import so neither chat nor content bundles pay
* for it unless a diagram is actually rendered.
*/
import React, { useEffect, useState } from 'react';
import type { MermaidConfig } from 'mermaid';
import { AlertCircleIcon } from '../../icons-v2-generated';
/**
* SECURITY SSOT for the mermaid renderer — the ONLY place these knobs are
* written. `./__tests__/mermaid-security.test.ts` imports THIS constant and
* spreads it into its own `mermaid.initialize`, so the fixture and the
* component can no longer drift: flipping `securityLevel` to `'loose'` here
* fails the suite (verified by doing exactly that).
*
* This renderer sits on the CHAT path, so the diagram source is MODEL output
* — untrusted by construction — and the rendered SVG goes through
* `dangerouslySetInnerHTML`. The pre-unification renderer used `'loose'`,
* which permits raw HTML inside labels and enables mermaid's `click`
* interaction directive: a node label like `A["
"]`
* would have produced LIVE HTML.
*
* - `securityLevel: 'strict'` encodes HTML tags in text and disables click
* handlers.
* - `htmlLabels: false` renders labels as SVG `` instead of a
* foreignObject HTML subtree, so there is no HTML surface at all. Verified:
* no authored diagram in this repo or in the consuming hub's markdown uses
* HTML labels (not even `
`), so 'antiscript' (which still allows tags)
* is not needed. (`htmlLabels` is set at the ROOT — `flowchart.htmlLabels`
* is deprecated in mermaid 11 and the root value takes precedence.)
* - `secure` is the allowlist of config keys a `%%{init}%%` directive in the
* diagram SOURCE may NOT override. mermaid's default list covers
* `securityLevel` but NOT `htmlLabels`, so model-authored source could
* otherwise re-enable HTML labels while `securityLevel` stayed locked.
* Adding `htmlLabels` (plus `secure` itself and the resource limits) closes
* that hole.
*
* jsdom NOTE: with `htmlLabels` unlocked, a `%%{init: {"htmlLabels": true}}%%`
* directive was observed to make `mermaid.render` never settle under jsdom
* (>60s, against a passing two-render control). This was NOT reproduced in a
* real browser and may well be an artifact of jsdom having no layout — do not
* read it as a confirmed browser DoS. Either way the render below is wrapped
* in a timeout so a non-settling render surfaces the error state instead of
* sitting on "Rendering diagram…" forever.
*/
export const MERMAID_SECURITY_OPTIONS = {
htmlLabels: false,
securityLevel: 'strict',
secure: [
'securityLevel',
'htmlLabels',
'secure',
'startOnLoad',
'maxTextSize',
'maxEdges',
// `themeCSS` is RAW CSS that mermaid emits into a `