> ## Documentation Index
> Fetch the complete documentation index at: https://prefab.prefect.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Mermaid

> Render diagrams from Mermaid text definitions.

export const ComponentPreview = ({json, height, resizable, bare, hideJson, playground, children}) => {
  const hostRef = React.useRef(null);
  const handleRef = React.useRef(null);
  const cardRef = React.useRef(null);
  const containerRef = React.useRef(null);
  const [previewWidth, setPreviewWidth] = React.useState(null);
  const [isDragging, setIsDragging] = React.useState(false);
  const [playgroundHref, setPlaygroundHref] = React.useState(null);
  React.useEffect(function () {
    if (!playground) return;
    var isLocal = location.hostname === "localhost" || location.hostname === "127.0.0.1";
    var path = isLocal ? "/playground" : "/docs/playground";
    var url = new URL(path, window.location.href);
    url.hash = "code=" + playground;
    setPlaygroundHref(url.href);
  }, [playground]);
  var jsonStr = typeof json === "string" ? json : JSON.stringify(json, null, 2);
  React.useEffect(function () {
    if (cardRef.current) {
      var card = cardRef.current.closest(".group");
      if (card) card.classList.remove("group");
    }
    var host = hostRef.current;
    if (!host || !json) return;
    function mount() {
      if (!window.__prefab || !host) return;
      var dark = document.documentElement.classList.contains("dark");
      handleRef.current = window.__prefab.mountPreview(host, jsonStr, {
        dark: dark
      });
      if (bare && host.shadowRoot) {
        var m = host.shadowRoot.querySelector("[data-prefab-mount]");
        if (m) m.style.background = "transparent";
      }
    }
    if (window.__prefab) {
      mount();
    } else {
      if (!window.__prefabLoading) {
        if (!window.__prefabReady) {
          var s = document.createElement("script");
          s.src = "/renderer.js";
          document.head.appendChild(s);
        }
        window.__prefabLoading = new Promise(function (resolve) {
          function check() {
            if (window.__prefabReady) {
              window.__prefabReady.then(resolve);
            } else {
              setTimeout(check, 10);
            }
          }
          check();
        });
      }
      window.__prefabLoading.then(mount);
    }
    var observer = new MutationObserver(function () {
      var dark = document.documentElement.classList.contains("dark");
      if (handleRef.current) handleRef.current.setDark(dark);
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return function () {
      observer.disconnect();
      if (handleRef.current) {
        handleRef.current.unmount();
        handleRef.current = null;
      }
    };
  }, [json]);
  function startResize(e) {
    e.preventDefault();
    var startX = e.clientX;
    var startW = hostRef.current ? hostRef.current.offsetWidth : 0;
    var maxW = containerRef.current ? containerRef.current.offsetWidth - 10 : startW;
    setIsDragging(true);
    function onMove(ev) {
      var w = Math.max(260, Math.min(startW + (ev.clientX - startX), maxW));
      setPreviewWidth(w);
    }
    function onUp() {
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseup", onUp);
      setIsDragging(false);
    }
    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseup", onUp);
  }
  if (bare) {
    return <div ref={hostRef} />;
  }
  if (resizable) {
    return <Card>
        <div ref={cardRef} />
        <div ref={containerRef} style={{
      display: "flex",
      position: "relative",
      overflow: "hidden"
    }}>
          <div ref={hostRef} style={{
      flex: previewWidth ? "none" : 1,
      width: previewWidth ? previewWidth + "px" : undefined,
      minWidth: 0
    }} />
          <div onMouseDown={startResize} style={{
      width: "14px",
      flexShrink: 0,
      cursor: "col-resize",
      background: isDragging ? "var(--border, #e5e7eb)" : "color-mix(in srgb, var(--border, #e5e7eb) 40%, transparent)",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      transition: "background 0.15s",
      userSelect: "none"
    }}>
            <svg width="6" height="24" style={{
      opacity: 0.5
    }}>
              <circle cx="2" cy="4" r="1.2" fill="currentColor" />
              <circle cx="2" cy="9" r="1.2" fill="currentColor" />
              <circle cx="2" cy="14" r="1.2" fill="currentColor" />
              <circle cx="2" cy="19" r="1.2" fill="currentColor" />
              <circle cx="5" cy="4" r="1.2" fill="currentColor" />
              <circle cx="5" cy="9" r="1.2" fill="currentColor" />
              <circle cx="5" cy="14" r="1.2" fill="currentColor" />
              <circle cx="5" cy="19" r="1.2" fill="currentColor" />
            </svg>
          </div>
          <div style={{
      flex: previewWidth ? 1 : "0 0 24px",
      minWidth: "24px",
      background: "repeating-linear-gradient(-45deg, transparent, transparent 3px, var(--border, #e5e7eb) 3px, var(--border, #e5e7eb) 4px)",
      opacity: 0.4
    }} />
          {previewWidth && <div style={{
      position: "absolute",
      bottom: "8px",
      right: "8px",
      background: "var(--background, white)",
      border: "1px solid var(--border, #e5e7eb)",
      borderRadius: "4px",
      padding: "1px 6px",
      fontSize: "11px",
      fontFamily: "monospace",
      color: "var(--muted-foreground, #6b7280)",
      pointerEvents: "none"
    }}>
              {previewWidth}px
            </div>}
        </div>
        {playgroundHref && <div style={{
      display: "flex",
      justifyContent: "flex-end",
      padding: "4px 0 8px"
    }}>
            <a href={playgroundHref} target="_blank" rel="noopener noreferrer" style={{
      fontSize: "11px",
      opacity: 0.4,
      textDecoration: "none",
      textDecorationLine: "none",
      borderBottom: "none",
      boxShadow: "none",
      display: "inline-flex",
      alignItems: "center",
      gap: "3px",
      transition: "opacity 0.15s",
      fontWeight: 400
    }} onMouseOver={function (e) {
      e.currentTarget.style.opacity = "0.6";
    }} onMouseOut={function (e) {
      e.currentTarget.style.opacity = "0.4";
    }}>
              Edit in Playground
              <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></svg>
            </a>
          </div>}
        <div style={{
      marginBottom: "-2rem"
    }}>{children}</div>
      </Card>;
  }
  return <Card>
      <div ref={cardRef} />
      <div ref={hostRef} />
      {playgroundHref && <div style={{
    display: "flex",
    justifyContent: "flex-end",
    padding: "4px 0 8px"
  }}>
          <a href={playgroundHref} target="_blank" rel="noopener noreferrer" style={{
    fontSize: "11px",
    opacity: 0.4,
    textDecoration: "none",
    textDecorationLine: "none",
    borderBottom: "none",
    boxShadow: "none",
    display: "inline-flex",
    alignItems: "center",
    gap: "3px",
    transition: "opacity 0.15s",
    fontWeight: 400
  }} onMouseOver={function (e) {
    e.currentTarget.style.opacity = "0.6";
  }} onMouseOut={function (e) {
    e.currentTarget.style.opacity = "0.4";
  }}>
            Edit in Playground
            <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></svg>
          </a>
        </div>}
      <div style={{
    marginBottom: "-2rem"
  }}>{children}</div>
    </Card>;
};

Mermaid renders diagrams from text definitions — flowcharts, sequence diagrams, state machines, ER diagrams, and more. The mermaid library loads lazily on first use, so apps that don't use diagrams pay zero cost.

Mermaid is particularly useful for generative UI, where LLMs can produce diagram definitions directly without needing image generation or specialized tooling.

## Flowchart

Flowcharts map decision logic as nodes joined by directional arrows: `[...]` for steps, `{...}` for decision branches, and `-->|label|` to name the path taken. The `style` lines tint individual nodes — the simplest way to draw the eye to terminal states like errors or successful outcomes.

<ComponentPreview json={{"view":{"type":"Mermaid","chart":"\ngraph TD\n    A[New Request] --> B{Authenticated?}\n    B -->|Yes| C{Authorized?}\n    B -->|No| D[401 Unauthorized]\n    C -->|Yes| E[Process Request]\n    C -->|No| F[403 Forbidden]\n    E --> G{Success?}\n    G -->|Yes| H[200 OK]\n    G -->|No| I[500 Error]\n\n    style A fill:#818cf8,color:#fff\n    style H fill:#34d399,color:#fff\n    style D fill:#f472b6,color:#fff\n    style F fill:#f472b6,color:#fff\n    style I fill:#fb923c,color:#fff\n"}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgTWVybWFpZAoKTWVybWFpZCgiIiIKZ3JhcGggVEQKICAgIEFbTmV3IFJlcXVlc3RdIC0tPiBCe0F1dGhlbnRpY2F0ZWQ_fQogICAgQiAtLT58WWVzfCBDe0F1dGhvcml6ZWQ_fQogICAgQiAtLT58Tm98IERbNDAxIFVuYXV0aG9yaXplZF0KICAgIEMgLS0-fFllc3wgRVtQcm9jZXNzIFJlcXVlc3RdCiAgICBDIC0tPnxOb3wgRls0MDMgRm9yYmlkZGVuXQogICAgRSAtLT4gR3tTdWNjZXNzP30KICAgIEcgLS0-fFllc3wgSFsyMDAgT0tdCiAgICBHIC0tPnxOb3wgSVs1MDAgRXJyb3JdCgogICAgc3R5bGUgQSBmaWxsOiM4MThjZjgsY29sb3I6I2ZmZgogICAgc3R5bGUgSCBmaWxsOiMzNGQzOTksY29sb3I6I2ZmZgogICAgc3R5bGUgRCBmaWxsOiNmNDcyYjYsY29sb3I6I2ZmZgogICAgc3R5bGUgRiBmaWxsOiNmNDcyYjYsY29sb3I6I2ZmZgogICAgc3R5bGUgSSBmaWxsOiNmYjkyM2MsY29sb3I6I2ZmZgoiIiIpCg">
  <CodeGroup>
    ```python icon="python" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    from prefab_ui.components import Mermaid

    Mermaid("""
    graph TD
        A[New Request] --> B{Authenticated?}
        B -->|Yes| C{Authorized?}
        B -->|No| D[401 Unauthorized]
        C -->|Yes| E[Process Request]
        C -->|No| F[403 Forbidden]
        E --> G{Success?}
        G -->|Yes| H[200 OK]
        G -->|No| I[500 Error]

        style A fill:#818cf8,color:#fff
        style H fill:#34d399,color:#fff
        style D fill:#f472b6,color:#fff
        style F fill:#f472b6,color:#fff
        style I fill:#fb923c,color:#fff
    """)
    ```

    ```json Protocol icon="brackets-curly" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    {
      "view": {
        "type": "Mermaid",
        "chart": "\ngraph TD\n    A[New Request] --> B{Authenticated?}\n    B -->|Yes| C{Authorized?}\n    B -->|No| D[401 Unauthorized]\n    C -->|Yes| E[Process Request]\n    C -->|No| F[403 Forbidden]\n    E --> G{Success?}\n    G -->|Yes| H[200 OK]\n    G -->|No| I[500 Error]\n\n    style A fill:#818cf8,color:#fff\n    style H fill:#34d399,color:#fff\n    style D fill:#f472b6,color:#fff\n    style F fill:#f472b6,color:#fff\n    style I fill:#fb923c,color:#fff\n"
      }
    }
    ```
  </CodeGroup>
</ComponentPreview>

## Sequence Diagram

Sequence diagrams trace messages between participants over time, reading top to bottom. `->>` is a call and `-->>` a response; declare each `actor` or `participant` once and every message references it by name. Reach for this when the *order* of interactions across services is what you need to convey.

<ComponentPreview json={{"view":{"type":"Mermaid","chart":"\nsequenceDiagram\n    actor User\n    participant App\n    participant Auth\n    participant API\n    participant DB\n\n    User->>App: Click \"Sign In\"\n    App->>Auth: Redirect to OAuth\n    Auth-->>User: Show login form\n    User->>Auth: Enter credentials\n    Auth->>Auth: Validate\n    Auth-->>App: Authorization code\n    App->>Auth: Exchange for token\n    Auth-->>App: Access token\n    App->>API: GET /user (token)\n    API->>DB: Query user\n    DB-->>API: User data\n    API-->>App: User profile\n    App-->>User: Welcome!\n"}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgTWVybWFpZAoKTWVybWFpZCgiIiIKc2VxdWVuY2VEaWFncmFtCiAgICBhY3RvciBVc2VyCiAgICBwYXJ0aWNpcGFudCBBcHAKICAgIHBhcnRpY2lwYW50IEF1dGgKICAgIHBhcnRpY2lwYW50IEFQSQogICAgcGFydGljaXBhbnQgREIKCiAgICBVc2VyLT4-QXBwOiBDbGljayAiU2lnbiBJbiIKICAgIEFwcC0-PkF1dGg6IFJlZGlyZWN0IHRvIE9BdXRoCiAgICBBdXRoLS0-PlVzZXI6IFNob3cgbG9naW4gZm9ybQogICAgVXNlci0-PkF1dGg6IEVudGVyIGNyZWRlbnRpYWxzCiAgICBBdXRoLT4-QXV0aDogVmFsaWRhdGUKICAgIEF1dGgtLT4-QXBwOiBBdXRob3JpemF0aW9uIGNvZGUKICAgIEFwcC0-PkF1dGg6IEV4Y2hhbmdlIGZvciB0b2tlbgogICAgQXV0aC0tPj5BcHA6IEFjY2VzcyB0b2tlbgogICAgQXBwLT4-QVBJOiBHRVQgL3VzZXIgKHRva2VuKQogICAgQVBJLT4-REI6IFF1ZXJ5IHVzZXIKICAgIERCLS0-PkFQSTogVXNlciBkYXRhCiAgICBBUEktLT4-QXBwOiBVc2VyIHByb2ZpbGUKICAgIEFwcC0tPj5Vc2VyOiBXZWxjb21lIQoiIiIpCg">
  <CodeGroup>
    ```python icon="python" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    from prefab_ui.components import Mermaid

    Mermaid("""
    sequenceDiagram
        actor User
        participant App
        participant Auth
        participant API
        participant DB

        User->>App: Click "Sign In"
        App->>Auth: Redirect to OAuth
        Auth-->>User: Show login form
        User->>Auth: Enter credentials
        Auth->>Auth: Validate
        Auth-->>App: Authorization code
        App->>Auth: Exchange for token
        Auth-->>App: Access token
        App->>API: GET /user (token)
        API->>DB: Query user
        DB-->>API: User data
        API-->>App: User profile
        App-->>User: Welcome!
    """)
    ```

    ```json Protocol icon="brackets-curly" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    {
      "view": {
        "type": "Mermaid",
        "chart": "\nsequenceDiagram\n    actor User\n    participant App\n    participant Auth\n    participant API\n    participant DB\n\n    User->>App: Click \"Sign In\"\n    App->>Auth: Redirect to OAuth\n    Auth-->>User: Show login form\n    User->>Auth: Enter credentials\n    Auth->>Auth: Validate\n    Auth-->>App: Authorization code\n    App->>Auth: Exchange for token\n    Auth-->>App: Access token\n    App->>API: GET /user (token)\n    API->>DB: Query user\n    DB-->>API: User data\n    API-->>App: User profile\n    App-->>User: Welcome!\n"
      }
    }
    ```
  </CodeGroup>
</ComponentPreview>

## State Diagram

State diagrams show the states an entity moves through and the transitions between them. `[*]` marks the start and end, each transition label names the event that triggers the move, and a nested `state X { }` block expands a state into its own sub-machine. This is the natural fit for documenting a lifecycle — a job, an order, a request.

<ComponentPreview json={{"view":{"type":"Mermaid","chart":"\nstateDiagram-v2\n    [*] --> Pending\n    Pending --> Running: start()\n    Running --> Completed: finish()\n    Running --> Failed: error()\n    Running --> Cancelled: cancel()\n    Failed --> Pending: retry()\n    Cancelled --> [*]\n    Completed --> [*]\n\n    state Running {\n        [*] --> Initializing\n        Initializing --> Processing\n        Processing --> Finalizing\n        Finalizing --> [*]\n    }\n"}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgTWVybWFpZAoKTWVybWFpZCgiIiIKc3RhdGVEaWFncmFtLXYyCiAgICBbKl0gLS0-IFBlbmRpbmcKICAgIFBlbmRpbmcgLS0-IFJ1bm5pbmc6IHN0YXJ0KCkKICAgIFJ1bm5pbmcgLS0-IENvbXBsZXRlZDogZmluaXNoKCkKICAgIFJ1bm5pbmcgLS0-IEZhaWxlZDogZXJyb3IoKQogICAgUnVubmluZyAtLT4gQ2FuY2VsbGVkOiBjYW5jZWwoKQogICAgRmFpbGVkIC0tPiBQZW5kaW5nOiByZXRyeSgpCiAgICBDYW5jZWxsZWQgLS0-IFsqXQogICAgQ29tcGxldGVkIC0tPiBbKl0KCiAgICBzdGF0ZSBSdW5uaW5nIHsKICAgICAgICBbKl0gLS0-IEluaXRpYWxpemluZwogICAgICAgIEluaXRpYWxpemluZyAtLT4gUHJvY2Vzc2luZwogICAgICAgIFByb2Nlc3NpbmcgLS0-IEZpbmFsaXppbmcKICAgICAgICBGaW5hbGl6aW5nIC0tPiBbKl0KICAgIH0KIiIiKQo">
  <CodeGroup>
    ```python icon="python" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    from prefab_ui.components import Mermaid

    Mermaid("""
    stateDiagram-v2
        [*] --> Pending
        Pending --> Running: start()
        Running --> Completed: finish()
        Running --> Failed: error()
        Running --> Cancelled: cancel()
        Failed --> Pending: retry()
        Cancelled --> [*]
        Completed --> [*]

        state Running {
            [*] --> Initializing
            Initializing --> Processing
            Processing --> Finalizing
            Finalizing --> [*]
        }
    """)
    ```

    ```json Protocol icon="brackets-curly" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    {
      "view": {
        "type": "Mermaid",
        "chart": "\nstateDiagram-v2\n    [*] --> Pending\n    Pending --> Running: start()\n    Running --> Completed: finish()\n    Running --> Failed: error()\n    Running --> Cancelled: cancel()\n    Failed --> Pending: retry()\n    Cancelled --> [*]\n    Completed --> [*]\n\n    state Running {\n        [*] --> Initializing\n        Initializing --> Processing\n        Processing --> Finalizing\n        Finalizing --> [*]\n    }\n"
      }
    }
    ```
  </CodeGroup>
</ComponentPreview>

## Entity Relationship

ER diagrams describe data models — entities, their attributes, and the cardinality of the relationships between them. The crow's-foot notation (`||--o{`) reads as "one to zero-or-many," and each entity block lists its typed fields. Use it to communicate a schema without leaving the diagram for a database tool.

<ComponentPreview json={{"view":{"type":"Mermaid","chart":"\nerDiagram\n    TEAM ||--o{ MEMBER : has\n    MEMBER ||--o{ TASK : assigned\n    TEAM ||--o{ PROJECT : owns\n    PROJECT ||--o{ TASK : contains\n    TASK ||--o{ COMMENT : has\n    MEMBER ||--o{ COMMENT : writes\n\n    TEAM {\n        string name\n        string department\n    }\n    MEMBER {\n        string name\n        string role\n        string email\n    }\n    PROJECT {\n        string name\n        date deadline\n        string status\n    }\n"}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgTWVybWFpZAoKTWVybWFpZCgiIiIKZXJEaWFncmFtCiAgICBURUFNIHx8LS1veyBNRU1CRVIgOiBoYXMKICAgIE1FTUJFUiB8fC0tb3sgVEFTSyA6IGFzc2lnbmVkCiAgICBURUFNIHx8LS1veyBQUk9KRUNUIDogb3ducwogICAgUFJPSkVDVCB8fC0tb3sgVEFTSyA6IGNvbnRhaW5zCiAgICBUQVNLIHx8LS1veyBDT01NRU5UIDogaGFzCiAgICBNRU1CRVIgfHwtLW97IENPTU1FTlQgOiB3cml0ZXMKCiAgICBURUFNIHsKICAgICAgICBzdHJpbmcgbmFtZQogICAgICAgIHN0cmluZyBkZXBhcnRtZW50CiAgICB9CiAgICBNRU1CRVIgewogICAgICAgIHN0cmluZyBuYW1lCiAgICAgICAgc3RyaW5nIHJvbGUKICAgICAgICBzdHJpbmcgZW1haWwKICAgIH0KICAgIFBST0pFQ1QgewogICAgICAgIHN0cmluZyBuYW1lCiAgICAgICAgZGF0ZSBkZWFkbGluZQogICAgICAgIHN0cmluZyBzdGF0dXMKICAgIH0KIiIiKQo">
  <CodeGroup>
    ```python icon="python" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    from prefab_ui.components import Mermaid

    Mermaid("""
    erDiagram
        TEAM ||--o{ MEMBER : has
        MEMBER ||--o{ TASK : assigned
        TEAM ||--o{ PROJECT : owns
        PROJECT ||--o{ TASK : contains
        TASK ||--o{ COMMENT : has
        MEMBER ||--o{ COMMENT : writes

        TEAM {
            string name
            string department
        }
        MEMBER {
            string name
            string role
            string email
        }
        PROJECT {
            string name
            date deadline
            string status
        }
    """)
    ```

    ```json Protocol icon="brackets-curly" theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
    {
      "view": {
        "type": "Mermaid",
        "chart": "\nerDiagram\n    TEAM ||--o{ MEMBER : has\n    MEMBER ||--o{ TASK : assigned\n    TEAM ||--o{ PROJECT : owns\n    PROJECT ||--o{ TASK : contains\n    TASK ||--o{ COMMENT : has\n    MEMBER ||--o{ COMMENT : writes\n\n    TEAM {\n        string name\n        string department\n    }\n    MEMBER {\n        string name\n        string role\n        string email\n    }\n    PROJECT {\n        string name\n        date deadline\n        string status\n    }\n"
      }
    }
    ```
  </CodeGroup>
</ComponentPreview>

## API Reference

<Card icon="code" title="Mermaid Parameters">
  <ParamField body="chart" type="str" required>
    Mermaid diagram definition string. Supports all [Mermaid diagram types](https://mermaid.js.org/intro/syntax-reference.html). Can be passed as a positional argument.
  </ParamField>

  <ParamField body="css_class" type="str | None" default="None">
    Additional Tailwind CSS classes.
  </ParamField>
</Card>

## Protocol Reference

```json Mermaid theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "type": "Mermaid",
  "id?": "string",
  "onMount?": "any",
  "chart": "string (required)",
  "cssClass?": "string"
}
```

For the complete protocol schema, see [Mermaid](/docs/protocol/mermaid).
