/*!
 * BlockWriteAI Mermaid Plugin
 * Adds the licensed Mermaid drawing designer block.
 */
(function (global) {
  "use strict";

  var BlockWriteAI = global.BlockWriteAI;
  if (!BlockWriteAI || BlockWriteAI.__mermaidPluginInstalled) return;
  BlockWriteAI.__mermaidPluginInstalled = true;

  var H = BlockWriteAI.helpers || {};
  var el = H.el;
  var esc = H.escapeHTML || function (value) {
    return String(value == null ? "" : value).replace(/[&<>"]/g, function (ch) {
      return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[ch];
    });
  };
  var sanitize = H.sanitizeHTML || function (value) { return String(value || ""); };
  var inline = H.renderOutputInline || sanitize;
  var svgIcon = H.svgIcon || function (name, label) {
    name = String(name || "circle").trim();
    return '<svg class="rbe-svg-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" data-rbe-icon="' + esc(name) + '"><circle cx="12" cy="12" r="8"/></svg><span class="rbe-sr-only">' + esc(label || name) + "</span>";
  };

  function injectStyles() {
    if (document.querySelector("style[data-blockwriteai-advanced-blocks]")) return;
    var style = document.createElement("style");
    style.dataset.blockwriteaiAdvancedBlocks = "true";
    style.textContent =
      ".rbe-plugin-card{border:1px solid var(--rbe-border,#d7dee8);border-radius:8px;background:#fff;padding:12px;display:grid;gap:12px;}" +
      ".rbe-plugin-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;}" +
      ".rbe-plugin-toolbar label{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:750;color:#667085;}" +
      ".rbe-plugin-toolbar input,.rbe-plugin-toolbar select,.rbe-plugin-card textarea{border:1px solid var(--rbe-border,#d7dee8);border-radius:7px;background:#fff;color:#172033;font:14px/1.4 Arial,sans-serif;padding:8px 9px;}" +
      ".rbe-plugin-toolbar input[type='color']{width:40px;min-width:40px;height:34px;padding:3px;}" +
      ".rbe-plugin-card textarea{width:100%;min-height:150px;resize:vertical;font-family:Consolas,'Liberation Mono',monospace;}" +
      ".rbe-plugin-preview{border:1px dashed #cbd5e1;border-radius:8px;background:#f8fbff;min-height:120px;padding:12px;overflow:auto;}" +
      ".rbe-chart-block{position:relative;}" +
      ".rbe-chart-preview-wrap{position:relative;}" +
      ".rbe-chart-type-bar{position:absolute;left:50%;top:50%;z-index:4;display:flex;gap:6px;align-items:center;border:1px solid #cbd5e1;border-radius:999px;background:rgba(255,255,255,.96);padding:7px;box-shadow:0 16px 40px rgba(15,23,42,.16);opacity:0;pointer-events:none;transform:translate(-50%,-50%) scale(.96);transition:opacity .16s ease,transform .16s ease;}" +
      ".rbe-chart-preview-wrap:hover .rbe-chart-type-bar,.rbe-chart-type-bar:focus-within{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1);}" +
      ".rbe-chart-type-btn{width:34px;height:34px;border:1px solid #d7dee8;border-radius:999px;background:#fff;color:#344054;display:inline-grid;place-items:center;cursor:pointer;}" +
      ".rbe-chart-type-btn:hover,.rbe-chart-type-btn.is-active{border-color:#2563eb;background:#eaf1ff;color:#1d4ed8;}" +
      ".rbe-chart-slice-colors{display:flex;flex-wrap:wrap;gap:8px;align-items:center;}" +
      ".rbe-chart-slice-colors[hidden],.rbe-chart-series-color[hidden]{display:none!important;}" +
      ".rbe-chart-slice-label{font-size:12px;font-weight:800;color:#667085;}" +
      ".rbe-chart-slice-list{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}" +
      ".rbe-chart-slice-chip{display:inline-flex;align-items:center;gap:4px;border:1px solid #d7dee8;border-radius:999px;background:#fff;padding:3px 6px;font-size:11px;font-weight:750;color:#475467;}" +
      ".rbe-chart-slice-chip input{width:28px!important;min-width:28px!important;height:24px!important;padding:2px!important;border-radius:999px;}" +
      ".rbe-chart-preview svg,.rbe-output-chart svg{width:100%;height:auto;max-height:300px;}" +
      ".rbe-output-chart,.rbe-output-mermaid,.rbe-output-latex,.rbe-output-audio,.rbe-output-drawing,.rbe-output-columns{margin:0 0 15px;}" +
      ".rbe-output-chart{border:1px solid #d7dee8;border-radius:8px;padding:12px;background:#fff;}" +
      ".rbe-output-chart-title{display:block;margin-bottom:8px;font-weight:760;}" +
      ".rbe-chart-caption{width:min(560px,100%);min-height:42px;margin:0 auto;border:1px solid var(--rbe-border,#d7dee8);border-radius:8px;background:#fff;padding:10px 12px;text-align:center;outline:none;}" +
      ".rbe-chart-caption:focus{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12);}" +
      ".rbe-chart-caption:empty:before{content:attr(data-placeholder);color:#98a2b3;}" +
      ".rbe-output-chart-caption{display:block;margin:10px auto 0;color:#475467;font-size:13px;font-weight:650;}" +
      ".rbe-latex-preview,.rbe-output-latex{font-family:Georgia,'Times New Roman',serif;font-size:20px;line-height:1.6;text-align:center;font-style:italic;}" +
      ".rbe-output-latex{display:block;width:100%;}" +
      ".rbe-latex-frac{display:inline-grid;grid-template-rows:auto auto;vertical-align:middle;text-align:center;line-height:1.1;}.rbe-latex-frac span:first-child{border-bottom:1px solid currentColor;padding:0 2px;}" +
      ".rbe-output-align-left{text-align:left;}" +
      ".rbe-output-align-center{text-align:center;}" +
      ".rbe-output-align-right{text-align:right;}" +
      ".rbe-output-align-center>.rbe-output-mermaid-diagram,.rbe-output-align-center>.rbe-output-mermaid,.rbe-output-align-center>svg{margin-left:auto;margin-right:auto;}" +
      ".rbe-output-align-right>.rbe-output-mermaid-diagram,.rbe-output-align-right>.rbe-output-mermaid,.rbe-output-align-right>svg{margin-left:auto;margin-right:0;}" +
      ".rbe-mermaid-block{gap:10px;}" +
      ".rbe-mermaid-card{position:relative;min-height:220px;display:grid;gap:10px;align-items:stretch;border:1px solid #d7dee8;border-radius:10px;background:#fbfdff;padding:14px;}" +
      ".rbe-mermaid-card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;}" +
      ".rbe-mermaid-card-title{font-weight:820;color:#172033;font-size:14px;}" +
      ".rbe-mermaid-card-preview{min-height:160px;display:grid;place-items:center;border:1px dashed #cbd5e1;border-radius:9px;background:#fff;padding:12px;overflow:auto;}" +
      ".rbe-mermaid-card-preview .rbe-output-mermaid-diagram{max-width:100%;width:100%;}" +
      ".rbe-mermaid-card-empty{color:#667085;font-weight:750;font-size:13px;}" +
      ".rbe-mermaid-edit-btn{position:absolute;right:12px;top:12px;width:34px;height:34px;border:1px solid #cbd5e1;border-radius:999px;background:#fff;color:#172033;display:grid;place-items:center;cursor:pointer;box-shadow:0 12px 28px rgba(15,23,42,.12);}" +
      ".rbe-mermaid-edit-btn:empty:before{content:'';width:17px;height:17px;background:currentColor;display:block;-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h4l11-11-4-4L4 16z'/%3E%3Cpath d='m13 7 4 4'/%3E%3Cpath d='M14 5l1-1a2 2 0 0 1 3 0l2 2a2 2 0 0 1 0 3l-1 1'/%3E%3C/svg%3E\") center/contain no-repeat;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h4l11-11-4-4L4 16z'/%3E%3Cpath d='m13 7 4 4'/%3E%3Cpath d='M14 5l1-1a2 2 0 0 1 3 0l2 2a2 2 0 0 1 0 3l-1 1'/%3E%3C/svg%3E\") center/contain no-repeat;}" +
      ".rbe-mermaid-edit-btn:hover,.rbe-mermaid-edit-btn:focus-visible{border-color:#2563eb;color:#1d4ed8;background:#eaf1ff;}" +
      ".rbe-mermaid-modal-open{overflow:hidden!important;}" +
      ".rbe-mermaid-modal{position:fixed;inset:0;z-index:10000;background:rgba(15,23,42,.46);display:grid;place-items:stretch;padding:22px;}" +
      ".rbe-mermaid-dialog{display:grid;grid-template-rows:auto 1fr auto;min-height:0;border-radius:14px;background:#fff;box-shadow:0 28px 80px rgba(15,23,42,.32);overflow:hidden;}" +
      ".rbe-mermaid-modal-head,.rbe-mermaid-modal-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:1px solid #e2e8f0;}" +
      ".rbe-mermaid-modal-foot{border-top:1px solid #e2e8f0;border-bottom:0;justify-content:flex-end;}" +
      ".rbe-mermaid-modal-title{margin:0;font-size:17px;font-weight:820;color:#172033;}" +
      ".rbe-mermaid-close{width:34px;height:34px;border:1px solid #cbd5e1;border-radius:999px;background:#fff;display:grid;place-items:center;cursor:pointer;}" +
      ".rbe-mermaid-modal-save,.rbe-mermaid-modal-cancel{border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#172033;font-weight:800;padding:9px 14px;cursor:pointer;}" +
      ".rbe-mermaid-modal-save{border-color:#2563eb;background:#2563eb;color:#fff;}" +
      ".rbe-mermaid-modal-body{min-height:0;overflow:hidden;padding:0;background:#f8fafc;}" +
      ".rbe-mermaid-modal .rbe-mermaid-block{height:100%;border:0;border-radius:0;background:transparent;padding:0;display:grid;grid-template-rows:auto 1fr;gap:0;}" +
      ".rbe-mermaid-toolbar{display:flex;flex-wrap:wrap;gap:7px;align-items:center;padding:8px;border:1px solid #d7dee8;border-radius:12px;background:#eef4fb;}" +
      ".rbe-mermaid-modal .rbe-mermaid-toolbar{position:relative;z-index:5;border-width:0 0 1px;border-radius:0;background:#edf2f8;padding:9px 14px;}" +
      ".rbe-mermaid-tool,.rbe-mermaid-icon-btn{width:34px;height:34px;border:1px solid transparent;border-radius:8px;background:transparent;color:#344054;display:inline-grid;place-items:center;cursor:pointer;}" +
      ".rbe-mermaid-icon-btn{border-color:#d7dee8;background:#fff;}" +
      ".rbe-mermaid-tool:hover,.rbe-mermaid-tool.is-active,.rbe-mermaid-icon-btn:hover,.rbe-mermaid-icon-btn.is-active{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8;}" +
      ".rbe-mermaid-tool:disabled,.rbe-mermaid-icon-btn:disabled{opacity:.45;cursor:not-allowed;}" +
      ".rbe-mermaid-menu{position:relative;}" +
      ".rbe-mermaid-menu-btn{width:34px;height:34px;border:1px solid transparent;border-radius:8px;background:transparent;color:#344054;display:inline-grid;place-items:center;cursor:pointer;}" +
      ".rbe-mermaid-menu-btn:hover,.rbe-mermaid-menu:focus-within>.rbe-mermaid-menu-btn{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8;}" +
      ".rbe-mermaid-popover{position:absolute;left:0;top:calc(100% + 6px);z-index:12;display:none;min-width:166px;border:1px solid #d7dee8;border-radius:8px;background:#fff;box-shadow:0 16px 34px rgba(15,23,42,.18);padding:6px;}" +
      ".rbe-mermaid-menu:focus-within>.rbe-mermaid-popover,.rbe-mermaid-menu:hover>.rbe-mermaid-popover{display:block;}" +
      ".rbe-mermaid-menu-row{position:relative;display:flex;align-items:center;gap:10px;min-height:34px;padding:7px 8px;border-radius:6px;font-size:14px;color:#344054;white-space:nowrap;}" +
      ".rbe-mermaid-menu-row:hover{background:#eef2f7;}" +
      ".rbe-mermaid-menu-row:after{content:'>';margin-left:auto;color:#667085;}" +
      ".rbe-mermaid-submenu{position:absolute;left:100%;top:-7px;display:none;min-width:270px;border:1px solid #d7dee8;border-radius:8px;background:#fff;box-shadow:0 16px 34px rgba(15,23,42,.18);padding:8px;}" +
      ".rbe-mermaid-menu-row:hover>.rbe-mermaid-submenu{display:block;}" +
      ".rbe-mermaid-popover:not(:has(.rbe-mermaid-menu-row:hover)) .rbe-mermaid-menu-row:first-child>.rbe-mermaid-submenu{display:block;}" +
      ".rbe-mermaid-menu-row-icon{width:18px;display:inline-grid;place-items:center;color:#344054;}" +
      ".rbe-mermaid-choice-grid{display:grid;grid-template-columns:repeat(10,22px);gap:7px;align-items:center;}" +
      ".rbe-mermaid-choice-grid:has(+ .rbe-mermaid-choice-grid){border-bottom:1px solid #e5e7eb;padding-bottom:8px;margin-bottom:8px;}" +
      ".rbe-mermaid-choice{width:22px;height:22px;border:0;background:transparent;color:#111827;display:grid;place-items:center;cursor:pointer;font:14px/1 Arial,sans-serif;border-radius:4px;}" +
      ".rbe-mermaid-choice:hover,.rbe-mermaid-choice.is-active{background:#dbeafe;color:#1d4ed8;}" +
      ".rbe-mermaid-line-menu .rbe-mermaid-popover{min-width:210px;}" +
      ".rbe-mermaid-line-menu .rbe-mermaid-menu-row:after{content:'';}" +
      ".rbe-mermaid-line-choice{width:100%;border:0;border-radius:6px;background:transparent;color:#344054;display:flex;align-items:center;gap:10px;padding:8px;text-align:left;cursor:pointer;font:14px/1.2 Arial,sans-serif;}" +
      ".rbe-mermaid-line-choice:hover{background:#eef2f7;color:#1d4ed8;}" +
      ".rbe-mermaid-menu-select,.rbe-mermaid-action-select,.rbe-mermaid-stylebar select,.rbe-mermaid-workspace input{border:1px solid #d7dee8;border-radius:8px;background:#fff;color:#172033;font:13px/1.2 Arial,sans-serif;padding:7px 9px;max-width:156px;}" +
      ".rbe-mermaid-workspace input{width:72px;}" +
      ".rbe-mermaid-stylebar,.rbe-mermaid-workspace{display:flex;flex-wrap:wrap;gap:7px;align-items:center;border:1px solid #d7dee8;border-radius:10px;background:#fbfdff;padding:6px;}" +
      ".rbe-mermaid-stylebar[hidden]{display:none!important;}" +
      ".rbe-mermaid-stylebar label,.rbe-mermaid-workspace label{display:inline-flex;gap:6px;align-items:center;font-size:12px;font-weight:800;color:#667085;}" +
      ".rbe-mermaid-stylebar label{height:32px;border:1px solid #d7dee8;border-radius:8px;background:#fff;padding:3px 6px;color:#344054;}" +
      ".rbe-mermaid-stylebar label:hover{border-color:#93c5fd;background:#eef6ff;color:#1d4ed8;}" +
      ".rbe-mermaid-stylebar .rbe-mermaid-icon-control,.rbe-mermaid-stylebar .rbe-mermaid-style-btn{position:relative;width:34px;height:32px;box-sizing:border-box;border:1px solid transparent;border-radius:8px;background:#fff;color:#344054;display:inline-grid;place-items:center;padding:0;cursor:pointer;}" +
      ".rbe-mermaid-stylebar .rbe-mermaid-icon-control:hover,.rbe-mermaid-stylebar .rbe-mermaid-style-btn:hover,.rbe-mermaid-stylebar .rbe-mermaid-style-btn.is-active{border-color:#93c5fd;background:#dbeafe;color:#1d4ed8;}" +
      ".rbe-mermaid-stylebar .rbe-mermaid-icon-control input,.rbe-mermaid-stylebar .rbe-mermaid-icon-control select{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;opacity:0!important;cursor:pointer;}" +
      ".rbe-mermaid-control-swatch{position:absolute;left:7px;right:7px;bottom:3px;height:3px;border-radius:999px;background:#2563eb;pointer-events:none;}" +
      ".rbe-mermaid-fill-swatch{background:var(--rbe-mermaid-fill,#eef5ff);}" +
      ".rbe-mermaid-stroke-swatch{background:var(--rbe-mermaid-stroke,#111827);}" +
      ".rbe-mermaid-text-swatch{background:var(--rbe-mermaid-text,#172033);}" +
      ".rbe-mermaid-highlight-swatch{background:var(--rbe-mermaid-highlight,transparent);}" +
      ".rbe-mermaid-stylebar.is-line-selection .rbe-mermaid-fill-control,.rbe-mermaid-stylebar.is-line-selection .rbe-mermaid-text-control{display:none;}" +
      ".rbe-mermaid-stylebar:not(.is-text-capable) .rbe-mermaid-text-control{display:none;}" +
      ".rbe-mermaid-stylebar .rbe-mermaid-hidden-control{display:none!important;}" +
      ".rbe-mermaid-hint{font-size:12px;font-weight:700;color:#667085;}" +
      ".rbe-mermaid-stylebar input[type='color']{width:28px;height:24px;padding:1px;border:1px solid #d7dee8;border-radius:6px;background:#fff;}" +
      ".rbe-mermaid-stylebar input[type='range']{width:90px;}" +
      ".rbe-mermaid-stylebar select{height:24px;max-width:86px;padding:2px 5px;font-size:12px;}" +
      ".rbe-mermaid-stylebar .rbe-mermaid-icon-control.is-active{border-color:#93c5fd;background:#dbeafe;color:#1d4ed8;}" +
      ".rbe-mermaid-toolbar-sep{width:1px;height:24px;background:#cbd5e1;margin:0 2px;}" +
      ".rbe-mermaid-stage-shell{display:grid;grid-template-columns:28px minmax(0,1fr);grid-template-rows:26px minmax(0,1fr);min-height:0;height:100%;background:#fff;}" +
      ".rbe-mermaid-ruler-corner{grid-column:1;grid-row:1;border-right:1px solid #cbd5e1;border-bottom:1px solid #cbd5e1;background:#f8fafc;}" +
      ".rbe-mermaid-top-ruler{grid-column:2;grid-row:1;position:relative;border-bottom:1px solid #cbd5e1;background:#f8fafc;background-image:repeating-linear-gradient(90deg,#cbd5e1 0,#cbd5e1 1px,transparent 1px,transparent 10px),repeating-linear-gradient(90deg,#94a3b8 0,#94a3b8 1px,transparent 1px,transparent 100px);}" +
      ".rbe-mermaid-side-ruler{grid-column:1;grid-row:2;position:relative;border-right:1px solid #cbd5e1;background:#f8fafc;background-image:repeating-linear-gradient(0deg,#cbd5e1 0,#cbd5e1 1px,transparent 1px,transparent 10px),repeating-linear-gradient(0deg,#94a3b8 0,#94a3b8 1px,transparent 1px,transparent 100px);}" +
      ".rbe-mermaid-top-ruler span,.rbe-mermaid-side-ruler span{position:absolute;color:#475467;font:11px/1 Arial,sans-serif;user-select:none;}" +
      ".rbe-mermaid-top-ruler span{top:5px;transform:translateX(-50%);}" +
      ".rbe-mermaid-side-ruler span{left:8px;transform:translateY(-50%) rotate(-90deg);transform-origin:center;}" +
      ".rbe-mermaid-stage{position:relative;border:1px solid #d7dee8;border-radius:8px;background-color:#fff;background-image:linear-gradient(45deg,#f8fafc 25%,transparent 25%),linear-gradient(-45deg,#f8fafc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#f8fafc 75%),linear-gradient(-45deg,transparent 75%,#f8fafc 75%);background-position:0 0,0 12px,12px -12px,-12px 0;background-size:24px 24px;overflow:auto;resize:vertical;min-height:320px;max-height:560px;}" +
      ".rbe-mermaid-modal .rbe-mermaid-stage{grid-column:2;grid-row:2;height:100%;min-height:0;max-height:none;border:0;border-radius:0;resize:none;}" +
      ".rbe-mermaid-canvas{display:block;width:auto;height:auto;min-width:100%;touch-action:none;cursor:crosshair;background:rgba(255,255,255,.72);}" +
      ".rbe-mermaid-canvas [data-el-id]{cursor:move;}" +
      ".rbe-mermaid-canvas .is-selected{outline:none;filter:drop-shadow(0 0 0 #2563eb);}" +
      ".rbe-mermaid-selected-stroke{stroke:#2563eb!important;stroke-width:2!important;fill:none!important;pointer-events:none;}" +
      ".rbe-mermaid-handle{fill:#fff;stroke:#2563eb;stroke-width:2;cursor:nwse-resize;transition:fill .12s ease;}" +
      ".rbe-mermaid-handle:hover{fill:var(--rbe-handle-color,#2563eb);}" +
      ".rbe-mermaid-handle[data-handle='ne'],.rbe-mermaid-handle[data-handle='sw']{cursor:nesw-resize;}" +
      ".rbe-mermaid-handle[data-handle='n'],.rbe-mermaid-handle[data-handle='s']{cursor:ns-resize;}" +
      ".rbe-mermaid-handle[data-handle='e'],.rbe-mermaid-handle[data-handle='w']{cursor:ew-resize;}" +
      ".rbe-mermaid-rotate{cursor:grab;}" +
      ".rbe-mermaid-rotate circle{fill:#2563eb;stroke:#fff;stroke-width:2;}" +
      ".rbe-mermaid-rotate text{fill:#fff;stroke:none;font:800 12px/1 Arial,sans-serif;pointer-events:none;}" +
      ".rbe-mermaid-rotate-icon{pointer-events:none;}" +
      ".rbe-mermaid-marquee{fill:rgba(37,99,235,.09);stroke:#2563eb;stroke-width:1.5;stroke-dasharray:6 4;pointer-events:none;}" +
      ".rbe-mermaid-arrow-origin{fill:#fff;stroke:#2563eb;stroke-width:2;pointer-events:none;}" +
      ".rbe-mermaid-hidden-text{visibility:hidden!important;}" +
      ".rbe-mermaid-text-editor{position:absolute;z-index:20;box-sizing:border-box;border:0;border-radius:0;background:transparent;outline:none;overflow:hidden;resize:none;color:#172033;box-shadow:none;text-align:center;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;caret-color:#0f172a;font-weight:400;}" +
      ".rbe-mermaid-text-editor::placeholder{color:#667085;opacity:.62;}" +
      ".rbe-mermaid-options{display:flex;flex-wrap:wrap;gap:8px;align-items:center;border:1px solid #d7dee8;border-radius:8px;background:#fff;padding:8px;}" +
      ".rbe-mermaid-options[hidden]{display:none;}" +
      ".rbe-mermaid-options input,.rbe-mermaid-options select{border:1px solid #d7dee8;border-radius:7px;padding:7px 8px;}" +
      ".rbe-mermaid-source{margin-top:0;}" +
      ".rbe-mermaid-source summary{cursor:pointer;font-weight:750;color:#475467;}" +
      ".rbe-output-mermaid-diagram{display:block;width:fit-content;max-width:100%;max-height:560px;margin:0 auto;overflow:auto;border:1px solid #d7dee8;border-radius:8px;background:#fff;}" +
      ".rbe-output-mermaid-diagram svg{display:block;width:100%;max-width:100%;height:auto;min-width:0;border:0;border-radius:0;background:#fff;}" +
      ".rbe-output-mermaid-error{display:inline-block;border:1px solid #fecaca;border-radius:8px;background:#fff1f2;color:#991b1b;padding:10px 12px;font:13px/1.45 Consolas,'Liberation Mono',monospace;white-space:pre-wrap;}" +
      ".rbe-audio-dropzone{min-height:170px;}" +
      ".rbe-audio-error{border:1px solid #fecaca;border-radius:8px;background:#fff1f2;color:#991b1b;padding:8px 10px;font-size:13px;font-weight:700;}" +
      ".rbe-audio-card{display:grid;gap:10px;justify-items:center;text-align:center;}" +
      ".rbe-audio-card audio,.rbe-output-audio audio{width:min(560px,100%);}" +
      ".rbe-output-audio{display:grid;justify-items:center;text-align:center;}" +
      ".rbe-output-audio figcaption{font-weight:760;margin-bottom:8px;}" +
      ".rbe-drawing-text-input{min-width:220px;flex:1 1 260px;}" +
      ".rbe-drawing-text-apply{min-width:38px;}" +
      ".rbe-drawing-shell{display:grid;gap:10px;}" +
      ".rbe-drawing-canvas{width:100%;height:260px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;touch-action:none;}" +
      ".rbe-output-drawing img{max-width:100%;border:1px solid #d7dee8;border-radius:8px;background:#fff;}" +
      ".rbe-columns-block{overflow-x:auto;}" +
      ".rbe-columns-grid,.rbe-output-columns{display:grid;gap:12px;}" +
      ".rbe-column-field{display:grid;gap:8px;}" +
      ".rbe-column-header{min-height:38px;border:1px solid #d7dee8;border-radius:8px;padding:9px 10px;font-weight:760;background:#eef5ff!important;outline:none;}" +
      ".rbe-column-header:focus,.rbe-column-editor:focus{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12);}" +
      ".rbe-column-header:empty:before{content:attr(data-placeholder);color:#98a2b3;font-weight:650;}" +
      ".rbe-column-editor{min-height:120px;border:1px solid #d7dee8;border-radius:8px;padding:10px;background:#fbfdff;outline:none;}" +
      ".rbe-column-editor:empty:before{content:attr(data-placeholder);color:#98a2b3;}" +
      ".rbe-output-columns{grid-template-columns:repeat(var(--rbe-columns,2),minmax(180px,1fr));overflow-x:auto;}" +
      ".rbe-output-column{border:1px solid #e2e8f0;border-radius:8px;padding:12px;background:#fff;}" +
      ".rbe-output-column-header{margin:-12px -12px 10px;padding:10px 12px;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0;background:#eef5ff;font-weight:760;text-align:left;}" +
      ".rbe-output-column-body{min-width:0;}" +
      ".rbe-image-stage.is-media-menu-open{min-width:176px;}" +
      ".rbe-image-transform-panel{position:absolute;left:50%;top:10px;z-index:4;transform:translateX(-50%);display:grid;grid-template-columns:repeat(3,30px);gap:5px;align-items:center;justify-content:center;max-width:calc(100% - 16px);opacity:0;pointer-events:none;transition:opacity .18s ease,transform .18s ease;}" +
      ".rbe-image-stage.is-media-menu-open>.rbe-image-transform-panel{opacity:1;pointer-events:auto;transform:translateX(-50%) translateY(0);}" +
      ".rbe-image-transform-panel .rbe-media-action{position:static;left:auto;top:auto;width:30px;height:30px;opacity:1;pointer-events:auto;transform:none;box-shadow:0 8px 18px rgba(15,23,42,.14);}" +
      ".rbe-image-transform.is-active{background:#2563eb;color:#fff;}" +
      "@media (max-width:900px){.rbe-plugin-toolbar input,.rbe-plugin-toolbar select,.rbe-plugin-card textarea{min-width:0;max-width:100%;}.rbe-chart-preview svg,.rbe-output-chart svg{max-height:260px;}.rbe-mermaid-modal{padding:10px;}.rbe-mermaid-dialog{border-radius:10px;}.rbe-mermaid-modal .rbe-mermaid-toolbar{overflow-x:auto;align-content:flex-start;}.rbe-mermaid-popover{max-width:calc(100vw - 28px);max-height:62dvh;overflow:auto;}.rbe-mermaid-submenu{max-width:calc(100vw - 44px);max-height:58dvh;overflow:auto;}.rbe-output-mermaid-diagram{max-height:60dvh;}.rbe-columns-grid{grid-template-columns:1fr!important;}.rbe-output-columns{grid-template-columns:1fr!important;}}" +
      "@media (max-width:640px){.rbe-plugin-card{padding:10px;gap:10px;}.rbe-plugin-toolbar{display:grid;grid-template-columns:1fr;align-items:stretch;}.rbe-plugin-toolbar label{width:100%;justify-content:space-between;}.rbe-plugin-toolbar input,.rbe-plugin-toolbar select{width:100%;}.rbe-chart-type-bar{top:auto;bottom:10px;transform:translate(-50%,0) scale(.96);}.rbe-chart-preview-wrap:hover .rbe-chart-type-bar,.rbe-chart-type-bar:focus-within{transform:translate(-50%,0) scale(1);}.rbe-chart-slice-chip{width:100%;justify-content:space-between;}.rbe-latex-preview,.rbe-output-latex{font-size:18px;}.rbe-mermaid-modal{padding:0;}.rbe-mermaid-dialog{border-radius:0;}.rbe-mermaid-modal-head,.rbe-mermaid-modal-foot{padding:10px 12px;}.rbe-mermaid-modal-foot{flex-wrap:wrap;}.rbe-mermaid-modal-save,.rbe-mermaid-modal-cancel{flex:1 1 140px;}.rbe-mermaid-modal .rbe-mermaid-toolbar{gap:5px;padding:7px 8px;}.rbe-mermaid-tool,.rbe-mermaid-icon-btn,.rbe-mermaid-menu-btn{width:32px;height:32px;}.rbe-mermaid-stage-shell{grid-template-columns:22px minmax(0,1fr);grid-template-rows:22px minmax(0,1fr);}.rbe-mermaid-choice-grid{grid-template-columns:repeat(6,22px);}.rbe-mermaid-submenu{left:0;top:calc(100% + 6px);}.rbe-mermaid-stage{min-height:280px;}.rbe-mermaid-card-preview{min-height:140px;padding:8px;}.rbe-audio-card audio,.rbe-output-audio audio{width:100%;}.rbe-drawing-canvas{height:220px;}.rbe-image-transform-panel{grid-template-columns:repeat(3,28px);gap:4px;}.rbe-image-transform-panel .rbe-media-action{width:28px;height:28px;}.rbe-image-stage.is-media-menu-open{min-width:min(176px,100%);}}" +
      "@media (max-width:900px){.rbe-mermaid-card,.rbe-mermaid-card-preview{min-width:0;max-width:100%;}.rbe-mermaid-card-preview .rbe-output-mermaid-diagram{width:100%;max-width:100%;}.rbe-mermaid-modal{overflow:hidden;}.rbe-mermaid-dialog{width:100%;max-width:100%;height:calc(100dvh - 20px);max-height:calc(100dvh - 20px);}.rbe-mermaid-stage-shell{width:100%;min-width:0;overflow:hidden;}.rbe-mermaid-modal .rbe-mermaid-stage{width:100%;min-width:0;overflow:auto;}.rbe-mermaid-modal .rbe-mermaid-block{min-width:0;}.rbe-mermaid-card-preview .rbe-output-mermaid-diagram svg{max-width:100%;}}" +
      "@media (max-width:640px){.rbe-mermaid-card{padding:10px;min-height:180px;}.rbe-mermaid-card-preview{width:100%;max-width:100%;overflow:auto;}.rbe-mermaid-card-preview .rbe-output-mermaid-diagram{max-height:340px;overflow:hidden;}.rbe-mermaid-card-preview .rbe-output-mermaid-diagram svg{width:100%!important;min-width:0!important;max-width:100%;height:auto!important;}.rbe-mermaid-dialog{height:100dvh;max-height:100dvh;}.rbe-mermaid-modal-body{min-height:0;overflow:hidden;}.rbe-mermaid-modal .rbe-mermaid-toolbar{max-width:100%;overflow-x:auto;overflow-y:hidden;white-space:nowrap;}.rbe-mermaid-stage-shell{width:100%;min-width:0;overflow:hidden;}.rbe-mermaid-modal .rbe-mermaid-stage{width:100%;min-width:0;overflow:auto;}.rbe-mermaid-top-ruler{min-width:0;}.rbe-mermaid-canvas{min-width:100%;}.rbe-mermaid-toolbar-sep{display:none;}}" +
      ".rbe-mermaid-modal .rbe-mermaid-dialog{min-width:0;}" +
      ".rbe-mermaid-modal .rbe-mermaid-modal-body{display:grid;min-height:0;}" +
      ".rbe-mermaid-modal .rbe-mermaid-block{min-width:0;min-height:0;overflow:hidden;}" +
      ".rbe-mermaid-modal .rbe-mermaid-stage-shell{min-width:0;min-height:0;}" +
      ".rbe-mermaid-modal .rbe-mermaid-stage{overscroll-behavior:contain;-webkit-overflow-scrolling:touch;}" +
      "@media (max-width:900px){.rbe-mermaid-modal{height:100dvh;max-height:100dvh;padding:8px;overflow:hidden;}.rbe-mermaid-dialog{width:100%;height:100%;max-height:100%;}.rbe-mermaid-modal-body{overflow:hidden;}.rbe-mermaid-modal .rbe-mermaid-block{grid-template-rows:auto minmax(0,1fr);}.rbe-mermaid-modal .rbe-mermaid-toolbar{flex-wrap:nowrap;align-items:center;max-width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-width:thin;}.rbe-mermaid-modal .rbe-mermaid-toolbar::-webkit-scrollbar{height:6px;}.rbe-mermaid-modal .rbe-mermaid-toolbar::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:999px;}.rbe-mermaid-modal .rbe-mermaid-stylebar{flex:0 0 auto;flex-wrap:nowrap;min-width:max-content;}.rbe-mermaid-modal .rbe-mermaid-popover{position:fixed;left:12px!important;right:12px;top:98px;width:auto;min-width:0;max-width:none;max-height:calc(100dvh - 180px);overflow:auto;}.rbe-mermaid-modal .rbe-mermaid-stage-shell{height:100%;}.rbe-mermaid-modal .rbe-mermaid-stage{height:100%;min-height:0;max-height:none;}.rbe-mermaid-modal .rbe-mermaid-canvas{max-width:none;max-height:none;}}" +
      "@media (max-width:640px){.rbe-mermaid-modal{padding:0;}.rbe-mermaid-dialog{width:100vw;height:100dvh;max-height:100dvh;border-radius:0;}.rbe-mermaid-modal-head{min-height:46px;padding:7px 10px;}.rbe-mermaid-modal-foot{display:flex;justify-content:center;align-items:center;width:100%;max-width:100%;min-height:56px;padding:8px 10px;background:#fff;overflow:hidden;}.rbe-mermaid-modal-save,.rbe-mermaid-modal-cancel{flex:0 0 auto;width:auto;min-width:112px;min-height:40px;white-space:nowrap;font-size:13px;}.rbe-mermaid-modal .rbe-mermaid-toolbar{gap:5px;padding:7px 8px;}.rbe-mermaid-modal .rbe-mermaid-stage-shell{grid-template-columns:20px minmax(0,1fr);grid-template-rows:22px minmax(0,1fr);}.rbe-mermaid-modal .rbe-mermaid-top-ruler span,.rbe-mermaid-modal .rbe-mermaid-side-ruler span{font-size:10px;}.rbe-mermaid-modal .rbe-mermaid-side-ruler span{left:5px;}.rbe-mermaid-modal .rbe-mermaid-popover{left:8px!important;right:8px;top:86px;max-height:calc(100dvh - 154px);}.rbe-mermaid-modal .rbe-mermaid-submenu{max-width:calc(100vw - 28px);}}" +
      "@media (max-width:520px){.rbe-mermaid-modal .rbe-mermaid-popover{padding:6px;}.rbe-mermaid-modal .rbe-mermaid-menu-row{position:static;flex-wrap:wrap;white-space:normal;}.rbe-mermaid-modal .rbe-mermaid-menu-row:after{content:'';}.rbe-mermaid-modal .rbe-mermaid-menu-row>.rbe-mermaid-submenu{position:static;flex:1 1 100%;min-width:0;max-width:100%;margin-top:6px;border-radius:7px;box-shadow:none;}.rbe-mermaid-modal .rbe-mermaid-choice-grid{grid-template-columns:repeat(auto-fill,minmax(22px,1fr));}.rbe-mermaid-modal .rbe-mermaid-line-choice{font-size:13px;padding:7px;}}" +
      "@media (max-width:420px){.rbe-mermaid-modal-title{font-size:15px;}.rbe-mermaid-modal-head{padding:7px 9px;}.rbe-mermaid-choice-grid{grid-template-columns:repeat(auto-fill,minmax(22px,1fr));}.rbe-mermaid-popover{max-width:calc(100vw - 16px);}.rbe-mermaid-submenu{max-width:calc(100vw - 24px);}.rbe-mermaid-modal .rbe-mermaid-tool,.rbe-mermaid-modal .rbe-mermaid-icon-btn,.rbe-mermaid-modal .rbe-mermaid-menu-btn{width:31px;height:31px;}.rbe-mermaid-modal .rbe-mermaid-stage-shell{grid-template-columns:18px minmax(0,1fr);grid-template-rows:20px minmax(0,1fr);}.rbe-mermaid-modal-foot{gap:8px;}.rbe-mermaid-modal-save,.rbe-mermaid-modal-cancel{min-width:104px;padding:8px 10px;}.rbe-mermaid-modal-save{font-size:0;}.rbe-mermaid-modal-save:after{content:'Save';font-size:13px;}}";
    document.head.appendChild(style);
  }

  function numberList(value) {
    return String(value || "")
      .split(/[\s,]+/)
      .map(function (item) { return Number(item); })
      .filter(function (item) { return Number.isFinite(item); });
  }

  function labelList(value) {
    return String(value || "")
      .split(",")
      .map(function (item) { return item.trim(); })
      .filter(Boolean);
  }

  var DEFAULT_CHART_COLORS = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed", "#0891b2", "#db2777", "#65a30d"];

  function normalizeChartColor(value, fallback) {
    value = String(value || "").trim();
    return /^#[0-9a-f]{3}([0-9a-f]{3})?$/i.test(value) ? value : fallback;
  }

  function chartColorList(value, count) {
    var colors = String(value || "")
      .split(",")
      .map(function (item, index) { return normalizeChartColor(item, DEFAULT_CHART_COLORS[index % DEFAULT_CHART_COLORS.length]); })
      .filter(Boolean);
    while (colors.length < count) colors.push(DEFAULT_CHART_COLORS[colors.length % DEFAULT_CHART_COLORS.length]);
    return colors.slice(0, count);
  }

  function chartValueLabel(value) {
    if (!Number.isFinite(value)) return "0";
    return String(Math.round(value * 100) / 100);
  }

  function chartTickValues(max) {
    var steps = 4;
    var ticks = [];
    for (var index = 0; index <= steps; index += 1) {
      ticks.push((max / steps) * index);
    }
    return ticks;
  }

  function chartSvg(data) {
    var type = data.type === "line" || data.type === "pie" ? data.type : "bar";
    var labels = labelList(data.labels || "Q1,Q2,Q3,Q4");
    var values = numberList(data.values || "12,19,7,14");
    if (!values.length) values = [12, 19, 7, 14];
    var count = Math.max(labels.length, values.length);
    for (var fillIndex = 0; fillIndex < count; fillIndex += 1) {
      if (!labels[fillIndex]) labels[fillIndex] = "Item " + (fillIndex + 1);
      if (!Number.isFinite(values[fillIndex])) values[fillIndex] = 0;
    }
    var color = data.color || "#2563eb";
    var max = Math.max.apply(null, values.map(function (value) { return Math.max(0, value); }).concat([1]));
    var width = 640;
    var height = 300;
    if (type === "pie") {
      var total = values.reduce(function (sum, item) { return sum + Math.max(0, item); }, 0) || 1;
      var start = -Math.PI / 2;
      var colors = chartColorList(data.colors, values.length);
      var slices = values.map(function (value, index) {
        var angle = (Math.max(0, value) / total) * Math.PI * 2;
        var end = start + angle;
        var mid = start + angle / 2;
        var x1 = 320 + Math.cos(start) * 105;
        var y1 = 145 + Math.sin(start) * 105;
        var x2 = 320 + Math.cos(end) * 105;
        var y2 = 145 + Math.sin(end) * 105;
        var labelX = 320 + Math.cos(mid) * 64;
        var labelY = 145 + Math.sin(mid) * 64;
        var large = angle > Math.PI ? 1 : 0;
        var path = "M320 145 L" + x1 + " " + y1 + " A105 105 0 " + large + " 1 " + x2 + " " + y2 + " Z";
        start = end;
        return '<g><path d="' + path + '" fill="' + esc(colors[index % colors.length]) + '"><title>' + esc((labels[index] || "") + ": " + value) + '</title></path>' + (value > 0 ? '<text x="' + labelX + '" y="' + labelY + '" text-anchor="middle" dominant-baseline="central" fill="#fff" stroke="#0f172a" stroke-opacity=".35" stroke-width="3" paint-order="stroke fill" font-size="15" font-weight="800">' + esc(chartValueLabel(value)) + "</text>" : "") + "</g>";
      }).join("");
      return '<svg viewBox="0 0 640 300" role="img" aria-label="' + esc(data.title || "Pie chart") + '">' + slices + "</svg>";
    }
    var padLeft = 58;
    var padRight = 28;
    var padTop = 30;
    var padBottom = 48;
    var plotWidth = width - padLeft - padRight;
    var plotHeight = height - padTop - padBottom;
    var axisBottom = height - padBottom;
    var step = plotWidth / values.length;
    var yFor = function (value) {
      return axisBottom - (Math.max(0, value) / max) * plotHeight;
    };
    var points = values.map(function (value, index) {
      var x = padLeft + step * index + step / 2;
      var y = yFor(value);
      return [x, y];
    });
    var axis =
      '<path d="M' + padLeft + " " + axisBottom + "H" + (width - padRight) + "M" + padLeft + " " + padTop + "V" + axisBottom + '" stroke="#cbd5e1" fill="none"/>' +
      chartTickValues(max).map(function (tick) {
        var y = yFor(tick);
        return '<g><path d="M' + padLeft + " " + y + "H" + (width - padRight) + '" stroke="#e8eef6" fill="none"/><text x="' + (padLeft - 10) + '" y="' + (y + 4) + '" text-anchor="end" font-size="12" fill="#64748b">' + esc(chartValueLabel(tick)) + "</text></g>";
      }).join("") +
      labels.map(function (label, index) {
        var x = padLeft + step * index + step / 2;
        return '<text x="' + x + '" y="' + (height - 18) + '" text-anchor="middle" font-size="12" fill="#64748b">' + esc(label) + "</text>";
      }).join("");
    if (type === "line") {
      return '<svg viewBox="0 0 640 300" role="img" aria-label="' + esc(data.title || "Line chart") + '">' + axis + '<polyline points="' + points.map(function (point) { return point.join(","); }).join(" ") + '" fill="none" stroke="' + esc(normalizeChartColor(color, "#2563eb")) + '" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>' + points.map(function (point, index) { return '<g><circle cx="' + point[0] + '" cy="' + point[1] + '" r="5" fill="' + esc(normalizeChartColor(color, "#2563eb")) + '"><title>' + esc((labels[index] || "") + ": " + values[index]) + '</title></circle><text x="' + point[0] + '" y="' + (point[1] - 10) + '" text-anchor="middle" font-size="12" fill="#344054" font-weight="700">' + esc(chartValueLabel(values[index])) + "</text></g>"; }).join("") + "</svg>";
    }
    return '<svg viewBox="0 0 640 300" role="img" aria-label="' + esc(data.title || "Bar chart") + '">' + axis + values.map(function (value, index) {
      var barHeight = (Math.max(0, value) / max) * plotHeight;
      var x = padLeft + step * index + step * 0.18;
      var y = axisBottom - barHeight;
      var barWidth = step * 0.64;
      var centerY = y + barHeight / 2 + 5;
      return '<g><rect x="' + x + '" y="' + y + '" width="' + barWidth + '" height="' + barHeight + '" rx="5" fill="' + esc(normalizeChartColor(color, "#2563eb")) + '"><title>' + esc((labels[index] || "") + ": " + value) + '</title></rect><text x="' + (x + barWidth / 2) + '" y="' + centerY + '" text-anchor="middle" font-size="13" fill="#fff" stroke="#0f172a" stroke-opacity=".25" stroke-width="2" paint-order="stroke fill" font-weight="800">' + esc(chartValueLabel(value)) + "</text></g>";
    }).join("") + "</svg>";
  }

  function loadScriptOnce(src, key, callback) {
    var existing = document.querySelector("script[data-blockwriteai-lib='" + key + "']");
    if (existing) {
      if (existing.dataset.loaded === "true") callback();
      else existing.addEventListener("load", callback, { once: true });
      return;
    }
    var script = document.createElement("script");
    script.src = src;
    script.dataset.blockwriteaiLib = key;
    script.onload = function () {
      script.dataset.loaded = "true";
      callback();
    };
    script.onerror = callback;
    document.head.appendChild(script);
  }

  function localVendorAsset(path) {
    var scriptSrc = "";
    if (typeof document !== "undefined") {
      scriptSrc = document.currentScript && document.currentScript.src || "";
      if (!scriptSrc) {
        var scripts = document.getElementsByTagName ? document.getElementsByTagName("script") : [];
        for (var i = scripts.length - 1; i >= 0; i -= 1) {
          var src = scripts[i].src || "";
          if (/blockwriteai-mermaid(?:\.min)?\.js(?:\?|#|$)/.test(src)) {
            scriptSrc = src;
            break;
          }
        }
      }
    }
    var prefix = scriptSrc.indexOf("/blockwriteai_editor/static/blockwriteai/plugins/") !== -1 ? "../../../../" : "../../";
    try {
      return scriptSrc ? new URL(prefix + path, scriptSrc).href : path;
    } catch (error) {
      return prefix + path;
    }
  }

  function loadStyleOnce(href, key) {
    if (document.querySelector("link[data-blockwriteai-lib='" + key + "']")) return;
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.href = href;
    link.dataset.blockwriteaiLib = key;
    document.head.appendChild(link);
  }

  function renderMermaidPreview(target, code) {
    target.innerHTML = '<pre>' + esc(code || "") + "</pre>";
    if (!code || !code.trim()) return;
    loadScriptOnce(localVendorAsset("vendor/mermaid/mermaid.min.js"), "mermaid", function () {
      if (!global.mermaid) return;
      try {
        global.mermaid.initialize({ startOnLoad: false, securityLevel: "strict" });
        var render = function () {
          global.mermaid.render("rbe-mermaid-" + Math.random().toString(36).slice(2), code).then(function (result) {
            target.innerHTML = result.svg;
          }).catch(function () {
            target.innerHTML = '<pre class="rbe-output-mermaid-error">' + esc(code || "") + "</pre>";
          });
        };
        if (global.mermaid.parse) {
          Promise.resolve(global.mermaid.parse(code)).then(render).catch(function () {
            target.innerHTML = '<pre class="rbe-output-mermaid-error">' + esc(code || "") + "</pre>";
          });
        } else {
          render();
        }
      } catch (error) {}
    });
  }

  function latexFallbackHTML(code) {
    var html = esc(code || "");
    html = html
      .replace(/\\int/g, "&int;")
      .replace(/\\sum/g, "&sum;")
      .replace(/\\sqrt\{([^}]*)\}/g, "&radic;<span style=\"text-decoration:overline\">$1</span>")
      .replace(/\\frac\{([^}]*)\}\{([^}]*)\}/g, '<span class="rbe-latex-frac"><span>$1</span><span>$2</span></span>')
      .replace(/\^\{([^}]*)\}/g, "<sup>$1</sup>")
      .replace(/\^([A-Za-z0-9+\-=]+)/g, "<sup>$1</sup>")
      .replace(/_\{([^}]*)\}/g, "<sub>$1</sub>")
      .replace(/_([A-Za-z0-9+\-=]+)/g, "<sub>$1</sub>")
      .replace(/\\,/g, " ")
      .replace(/\\ /g, " ");
    return html;
  }

  function renderLatexPreview(target, code, displayMode) {
    target.innerHTML = latexFallbackHTML(code || "");
    if (!code || !code.trim()) return;
    loadStyleOnce(localVendorAsset("vendor/katex/css/katex.min.css"), "katex-css");
    loadScriptOnce(localVendorAsset("vendor/katex/js/katex.min.js"), "katex", function () {
      if (!global.katex) return;
      try {
        global.katex.render(code, target, { throwOnError: false, displayMode: !!displayMode });
      } catch (error) {}
    });
  }

  var DIAGRAM_LINE_TYPES = /^(line|arrow|leftArrow|rightArrow|upArrow|downArrow|biArrow|elbow|curved|curve|polyline|scribble)$/;
  var DIAGRAM_SHAPE_TYPES = /^(rect|roundedRect|circle|oval|triangle|diamond|pentagon|hexagon|parallelogram|trapezoid|octagon|heart|cloud|cylinder|cube|callout|roundCallout|thought|plus|minus|multiply|divide|equal|brackets|text|wordart|image)$/;

  function defaultMermaidWorkspace() {
    return { width: 1100, height: 620, zoom: 1 };
  }

  var MERMAID_WORKSPACE_MAX = 6000;
  var MERMAID_WORKSPACE_GROW_PADDING = 260;
  var MERMAID_WORKSPACE_GROW_STEP = 240;

  function defaultMermaidDiagram() {
    return [
      { id: "shape-start", type: "roundedRect", x: 120, y: 140, w: 170, h: 76, text: "Start", fill: "#eef5ff", stroke: "#111827", fontSize: 16, strokeWidth: 1 },
      { id: "shape-blockwriteai", type: "roundedRect", x: 560, y: 140, w: 190, h: 76, text: "BlockWriteAI", fill: "#ecfdf3", stroke: "#111827", fontSize: 16, strokeWidth: 1 },
      { id: "line-main", type: "arrow", x1: 290, y1: 178, x2: 560, y2: 178, stroke: "#475467", strokeWidth: 1 }
    ];
  }

  function simpleMermaidToDiagram(code) {
    code = String(code || "");
    if (/^\s*sequenceDiagram\b/i.test(code)) return sequenceMermaidToDiagram(code);
    if (!/^\s*(flowchart|graph)\b/im.test(code)) return null;
    var nodes = {};
    var order = [];
    var edges = [];
    var direction = /^\s*(?:flowchart|graph)\s+LR\b/im.test(code) ? "LR" : "TD";

    function cleanLabel(value) {
      return String(value || "")
        .replace(/^["']|["']$/g, "")
        .replace(/<br\s*\/?>/gi, "\n")
        .replace(/\s+/g, " ")
        .trim();
    }

    function ensureNode(id, label, kind) {
      id = String(id || "").trim();
      if (!id) return;
      if (!nodes[id]) {
        nodes[id] = { id: id, label: cleanLabel(label) || id, kind: kind || "process" };
        order.push(id);
      } else {
        if (label && (!nodes[id].label || nodes[id].label === id)) nodes[id].label = cleanLabel(label);
        if (kind && nodes[id].kind === "process") nodes[id].kind = kind;
      }
    }

    function parseNode(raw) {
      raw = String(raw || "").trim();
      var idMatch = raw.match(/^([A-Za-z][A-Za-z0-9_-]*)/);
      if (!idMatch) return null;
      var id = idMatch[1];
      var rest = raw.slice(id.length).trim();
      var label = id;
      var kind = "process";
      var match;
      if ((match = rest.match(/^\(\[([\s\S]*?)\]\)/))) {
        label = match[1]; kind = "start";
      } else if ((match = rest.match(/^\(\(([\s\S]*?)\)\)/))) {
        label = match[1]; kind = "end";
      } else if ((match = rest.match(/^\{([\s\S]*?)\}/))) {
        label = match[1]; kind = "decision";
      } else if ((match = rest.match(/^\[\[([\s\S]*?)\]\]/))) {
        label = match[1]; kind = "service";
      } else if ((match = rest.match(/^\[\(([\s\S]*?)\)\]/))) {
        label = match[1]; kind = "database";
      } else if ((match = rest.match(/^\[\/([\s\S]*?)\/\]/))) {
        label = match[1]; kind = "input";
      } else if ((match = rest.match(/^\[([\s\S]*?)\]/))) {
        label = match[1]; kind = "process";
      }
      return { id: id, label: cleanLabel(label), kind: kind };
    }

    function parseEdge(line) {
      var normalized = String(line || "").replace(/\s+/g, " ").trim();
      var match = normalized.match(/^([A-Za-z][A-Za-z0-9_-]*)\s*(?:--[^>]*-->|-->|---|-\.-|==>)\s*(?:\|[^|]*\|\s*)?([A-Za-z][A-Za-z0-9_-]*)/);
      if (!match) match = normalized.match(/^([A-Za-z][A-Za-z0-9_-]*)\s*-->\|[^|]*\|\s*([A-Za-z][A-Za-z0-9_-]*)/);
      if (!match) return null;
      return { from: match[1], to: match[2] };
    }

    code.split(/\r?\n/).forEach(function (line) {
      line = line.replace(/%%.*$/, "").trim();
      if (!line || /^(flowchart|graph|subgraph|end|classDef|class|style|linkStyle)\b/i.test(line)) return;
      var edge = parseEdge(line);
      if (edge) {
        edges.push(edge);
        ensureNode(edge.from);
        ensureNode(edge.to);
        line.split(/(?:--[^>]*-->|-->|---|-\.-|==>)/).forEach(function (part) {
          var node = parseNode(part.replace(/^\|[^|]*\|/, ""));
          if (node) ensureNode(node.id, node.label, node.kind);
        });
        return;
      }
      var node = parseNode(line);
      if (node) ensureNode(node.id, node.label, node.kind);
    });

    if (!order.length) return null;

    var width = 190;
    var height = 76;
    var xGap = 250;
    var yGap = 132;
    var cols = direction === "LR" ? Math.min(order.length, 4) : Math.min(order.length, 3);
    var elements = [];
    var placed = {};
    order.forEach(function (id, index) {
      var node = nodes[id];
      var col = direction === "LR" ? index : index % cols;
      var row = direction === "LR" ? index % 3 : Math.floor(index / cols);
      if (direction === "LR") {
        col = Math.floor(index / 3);
        row = index % 3;
      }
      var type = node.kind === "decision" ? "diamond" : node.kind === "database" ? "cylinder" : node.kind === "end" ? "oval" : "roundedRect";
      var fill = node.kind === "decision" ? "#fff7ed" : node.kind === "database" ? "#f0f9ff" : node.kind === "service" ? "#eef2ff" : node.kind === "end" ? "#ecfdf3" : "#eef5ff";
      var x = 100 + col * xGap;
      var y = 90 + row * yGap;
      var w = node.kind === "decision" ? 180 : width;
      var h = node.kind === "decision" ? 96 : height;
      placed[id] = { x: x, y: y, w: w, h: h };
      elements.push({ id: "shape-" + id, type: type, x: x, y: y, w: w, h: h, text: node.label, fill: fill, stroke: "#111827", fontSize: 15, strokeWidth: 1 });
    });
    edges.forEach(function (edge, index) {
      var from = placed[edge.from];
      var to = placed[edge.to];
      if (!from || !to) return;
      var horizontal = Math.abs((to.x + to.w / 2) - (from.x + from.w / 2)) >= Math.abs((to.y + to.h / 2) - (from.y + from.h / 2));
      elements.push({
        id: "line-" + edge.from + "-" + edge.to + "-" + index,
        type: "arrow",
        x1: horizontal && to.x >= from.x ? from.x + from.w : from.x + from.w / 2,
        y1: horizontal && to.x >= from.x ? from.y + from.h / 2 : from.y + from.h,
        x2: horizontal && to.x >= from.x ? to.x : to.x + to.w / 2,
        y2: horizontal && to.x >= from.x ? to.y + to.h / 2 : to.y,
        stroke: "#475467",
        strokeWidth: 1
      });
    });
    return elements.length ? elements : null;
  }

  function sequenceMermaidToDiagram(code) {
    var participants = [];
    var messages = [];
    function addParticipant(id, label) {
      id = String(id || "").trim();
      if (!id) return;
      if (!participants.some(function (item) { return item.id === id; })) {
        participants.push({ id: id, label: label || id });
      }
    }
    String(code || "").split(/\r?\n/).forEach(function (line) {
      line = line.trim();
      var declaration = line.match(/^(?:actor|participant)\s+([A-Za-z][A-Za-z0-9_-]*)(?:\s+as\s+(.+))?/i);
      if (declaration) {
        addParticipant(declaration[1], declaration[2] || declaration[1]);
        return;
      }
      var message = line.match(/^([A-Za-z][A-Za-z0-9_-]*)\s*-{1,2}>>\s*([A-Za-z][A-Za-z0-9_-]*)\s*:?\s*(.*)$/);
      if (message) {
        addParticipant(message[1]);
        addParticipant(message[2]);
        messages.push({ from: message[1], to: message[2], text: message[3] || "" });
      }
    });
    if (!participants.length) return null;
    var elements = [];
    var xById = {};
    participants.forEach(function (participant, index) {
      var x = 100 + index * 220;
      xById[participant.id] = x + 85;
      elements.push({ id: "shape-" + participant.id, type: "roundedRect", x: x, y: 70, w: 170, h: 64, text: participant.label, fill: "#eef5ff", stroke: "#111827", fontSize: 15, strokeWidth: 1 });
      elements.push({ id: "life-" + participant.id, type: "line", x1: x + 85, y1: 145, x2: x + 85, y2: 145 + Math.max(260, messages.length * 58), stroke: "#cbd5e1", strokeWidth: 1, dash: "dashed" });
    });
    messages.slice(0, 14).forEach(function (message, index) {
      var y = 180 + index * 58;
      if (xById[message.from] == null || xById[message.to] == null) return;
      elements.push({ id: "msg-" + index, type: "arrow", x1: xById[message.from], y1: y, x2: xById[message.to], y2: y, stroke: "#475467", strokeWidth: 1 });
      if (message.text) {
        elements.push({ id: "msg-text-" + index, type: "text", x: Math.min(xById[message.from], xById[message.to]) + 16, y: y - 28, w: Math.abs(xById[message.to] - xById[message.from]) - 32 || 170, h: 26, text: message.text, fill: "transparent", stroke: "#111827", fontSize: 12, strokeWidth: 1 });
      }
    });
    return elements;
  }

  function isLineType(type) {
    return DIAGRAM_LINE_TYPES.test(type || "");
  }

  function isTextDiagramType(type) {
    return type === "text" || type === "wordart";
  }

  function clampNumber(value, min, max, fallback) {
    value = Number(value);
    if (!Number.isFinite(value)) value = fallback;
    return Math.min(max, Math.max(min, value));
  }

  function normalizeDiagramWorkspace(data) {
    var workspace = data && data.diagram && data.diagram.workspace ? data.diagram.workspace : data && data.workspace ? data.workspace : {};
    return {
      width: clampNumber(workspace.width, 640, MERMAID_WORKSPACE_MAX, 1100),
      height: clampNumber(workspace.height, 360, MERMAID_WORKSPACE_MAX, 620),
      zoom: clampNumber(workspace.zoom, 0.35, 2.5, 1)
    };
  }

  function normalizeDiagramDash(value) {
    return value === "dotted" || value === "dashed" || value === "longDash" || value === "dashDot" ? value : "solid";
  }

  function dashArray(value) {
    value = normalizeDiagramDash(value);
    if (value === "dotted") return "2 8";
    if (value === "dashed") return "10 8";
    if (value === "longDash") return "18 10";
    if (value === "dashDot") return "14 7 2 7";
    return "";
  }

  function normalizeDiagramLineHeight(value) {
    value = Number(value);
    if (!Number.isFinite(value)) value = 1.25;
    return clampNumber(value, 1, 2.5, 1.25);
  }

  function normalizeDiagramListType(value) {
    return value === "bullet" || value === "number" ? value : "none";
  }

  function normalizeDiagramListStyle(type, value) {
    if (type === "bullet") {
      return value === "circle" || value === "square" || value === "none" ? value : "disc";
    }
    if (type === "number") {
      return value === "lower-alpha" || value === "upper-alpha" || value === "lower-roman" || value === "upper-roman" || value === "none" ? value : "decimal";
    }
    return "none";
  }

  function normalizeDiagramElement(item, index) {
    item = item || {};
    var type = DIAGRAM_SHAPE_TYPES.test(item.type) || DIAGRAM_LINE_TYPES.test(item.type) ? item.type : "roundedRect";
    var isLine = isLineType(type);
    var text = item.text || "";
    if (!text && type === "wordart") text = "WordArt";
    if (!text && /^(plus|minus|multiply|divide|equal|brackets)$/.test(type)) {
      text = { plus: "+", minus: "-", multiply: "x", divide: "/", equal: "=", brackets: "[ ]" }[type] || "";
    }
    var fillValue = String(item.fill || "").trim();
    var fillFallback = type === "wordart" ? "#f59e0b" : type === "text" ? "transparent" : "#eef5ff";
    return {
      id: item.id || "diagram-" + index + "-" + Math.random().toString(36).slice(2),
      type: type,
      x: clampNumber(item.x, -500, 4000, 80),
      y: clampNumber(item.y, -500, 4000, 80),
      w: clampNumber(item.w, 20, 2000, isTextDiagramType(type) ? 180 : 150),
      h: clampNumber(item.h, 20, 2000, isTextDiagramType(type) ? 70 : 80),
      x1: clampNumber(item.x1 == null ? item.x : item.x1, -500, 4000, 80),
      y1: clampNumber(item.y1 == null ? item.y : item.y1, -500, 4000, 80),
      x2: clampNumber(item.x2 == null ? Number(item.x || 80) + 160 : item.x2, -500, 4000, 240),
      y2: clampNumber(item.y2 == null ? item.y : item.y2, -500, 4000, 80),
      text: text,
      fill: isLine ? "transparent" : fillValue === "transparent" ? "transparent" : normalizeChartColor(fillValue, fillFallback),
      stroke: normalizeChartColor(item.stroke, isLine ? "#475467" : "#111827"),
      strokeWidth: clampNumber(item.strokeWidth, 1, 16, 1),
      dash: normalizeDiagramDash(item.dash),
      opacity: clampNumber(item.opacity, 0.1, 1, 1),
      fontFamily: item.fontFamily || "Arial",
      fontSize: clampNumber(item.fontSize, 8, 96, type === "wordart" ? 36 : 16),
      bold: !!item.bold || type === "wordart",
      italic: !!item.italic,
      underline: !!item.underline,
      textColor: normalizeChartColor(item.textColor, "#172033"),
      highlightColor: String(item.highlightColor || "").trim() === "transparent" ? "transparent" : normalizeChartColor(item.highlightColor, "transparent"),
      textAlign: item.textAlign === "left" || item.textAlign === "right" || item.textAlign === "justify" ? item.textAlign : "center",
      lineHeight: normalizeDiagramLineHeight(item.lineHeight),
      spacingBefore: clampNumber(item.spacingBefore, 0, 48, 0),
      spacingAfter: clampNumber(item.spacingAfter, 0, 48, 0),
      indent: clampNumber(item.indent, 0, 8, 0),
      listType: normalizeDiagramListType(item.listType),
      listStyle: normalizeDiagramListStyle(normalizeDiagramListType(item.listType), item.listStyle),
      rotation: clampNumber(item.rotation, -360, 360, 0),
      group: item.group || "",
      flipX: !!item.flipX,
      flipY: !!item.flipY,
      image: item.image || "",
      name: item.name || ""
    };
  }

  function diagramElements(data) {
    var source = data && data.diagram && Array.isArray(data.diagram.elements) ? data.diagram.elements : Array.isArray(data && data.diagram) ? data.diagram : null;
    if (!source && data && data.code) source = simpleMermaidToDiagram(data.code);
    return (source ? source : defaultMermaidDiagram()).map(normalizeDiagramElement);
  }

  function selectedIdList(selectedIds) {
    return String(selectedIds || "").split(",").map(function (id) { return id.trim(); }).filter(Boolean);
  }

  function polygonPoints(cx, cy, rx, ry, count, startAngle) {
    var points = [];
    for (var i = 0; i < count; i += 1) {
      var angle = (startAngle || -Math.PI / 2) + (i / count) * Math.PI * 2;
      points.push((cx + Math.cos(angle) * rx) + "," + (cy + Math.sin(angle) * ry));
    }
    return points.join(" ");
  }

  function shapeMarkup(elm) {
    var x = elm.x;
    var y = elm.y;
    var w = elm.w;
    var h = elm.h;
    var cx = x + w / 2;
    var cy = y + h / 2;
    var fill = esc(elm.fill);
    var stroke = esc(elm.stroke);
    var sw = esc(elm.strokeWidth);
    var dash = dashArray(elm.dash);
    var common = ' fill="' + fill + '" stroke="' + stroke + '" stroke-width="' + sw + '"' + (dash ? ' stroke-dasharray="' + dash + '"' : "") + ' opacity="' + esc(elm.opacity) + '"';
    if (elm.type === "circle") return '<circle cx="' + cx + '" cy="' + cy + '" r="' + Math.min(w, h) / 2 + '"' + common + "></circle>";
    if (elm.type === "oval") return '<ellipse cx="' + cx + '" cy="' + cy + '" rx="' + w / 2 + '" ry="' + h / 2 + '"' + common + "></ellipse>";
    if (elm.type === "triangle") return '<polygon points="' + cx + "," + y + " " + (x + w) + "," + (y + h) + " " + x + "," + (y + h) + '"' + common + "></polygon>";
    if (elm.type === "diamond") return '<polygon points="' + cx + "," + y + " " + (x + w) + "," + cy + " " + cx + "," + (y + h) + " " + x + "," + cy + '"' + common + "></polygon>";
    if (elm.type === "pentagon") return '<polygon points="' + polygonPoints(cx, cy, w / 2, h / 2, 5) + '"' + common + "></polygon>";
    if (elm.type === "hexagon") return '<polygon points="' + polygonPoints(cx, cy, w / 2, h / 2, 6, 0) + '"' + common + "></polygon>";
    if (elm.type === "octagon") return '<polygon points="' + polygonPoints(cx, cy, w / 2, h / 2, 8, Math.PI / 8) + '"' + common + "></polygon>";
    if (elm.type === "parallelogram") return '<polygon points="' + (x + w * .18) + "," + y + " " + (x + w) + "," + y + " " + (x + w * .82) + "," + (y + h) + " " + x + "," + (y + h) + '"' + common + "></polygon>";
    if (elm.type === "trapezoid") return '<polygon points="' + (x + w * .18) + "," + y + " " + (x + w * .82) + "," + y + " " + (x + w) + "," + (y + h) + " " + x + "," + (y + h) + '"' + common + "></polygon>";
    if (elm.type === "heart") return '<path d="M' + cx + " " + (y + h * .86) + " C" + (x - w * .1) + " " + (y + h * .35) + " " + (x + w * .12) + " " + y + " " + cx + " " + (y + h * .28) + " C" + (x + w * .88) + " " + y + " " + (x + w * 1.1) + " " + (y + h * .35) + " " + cx + " " + (y + h * .86) + ' Z"' + common + "></path>";
    if (elm.type === "cloud") return '<path d="M' + (x + w * .22) + " " + (y + h * .72) + " C" + (x + w * .02) + " " + (y + h * .68) + " " + (x + w * .04) + " " + (y + h * .37) + " " + (x + w * .28) + " " + (y + h * .4) + " C" + (x + w * .34) + " " + (y + h * .12) + " " + (x + w * .68) + " " + (y + h * .1) + " " + (x + w * .74) + " " + (y + h * .38) + " C" + (x + w * 1.02) + " " + (y + h * .36) + " " + (x + w * 1.02) + " " + (y + h * .72) + " " + (x + w * .78) + " " + (y + h * .72) + ' Z"' + common + "></path>";
    if (elm.type === "cylinder") return '<path d="M' + x + " " + (y + h * .18) + " C" + x + " " + y + " " + (x + w) + " " + y + " " + (x + w) + " " + (y + h * .18) + " V" + (y + h * .82) + " C" + (x + w) + " " + (y + h) + " " + x + " " + (y + h) + " " + x + " " + (y + h * .82) + ' Z"' + common + "></path>" + '<ellipse cx="' + cx + '" cy="' + (y + h * .18) + '" rx="' + w / 2 + '" ry="' + h * .18 + '"' + common + "></ellipse>";
    if (elm.type === "cube") return '<path d="M' + x + " " + (y + h * .2) + " L" + (x + w * .2) + " " + y + " H" + (x + w) + " V" + (y + h * .8) + " L" + (x + w * .8) + " " + (y + h) + " H" + x + ' Z"' + common + "></path>" + '<path d="M' + (x + w * .2) + " " + y + " V" + (y + h * .8) + " H" + (x + w) + '" stroke="' + stroke + '" stroke-width="' + sw + '" fill="none" opacity="' + esc(elm.opacity) + '"></path>';
    if (elm.type === "callout") return '<polygon points="' + x + "," + y + " " + (x + w) + "," + y + " " + (x + w) + "," + (y + h * .75) + " " + (x + w * .62) + "," + (y + h * .75) + " " + (x + w * .5) + "," + (y + h) + " " + (x + w * .38) + "," + (y + h * .75) + " " + x + "," + (y + h * .75) + '"' + common + "></polygon>";
    if (elm.type === "roundCallout") return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + (h * .78) + '" rx="18"' + common + "></rect>" + '<path d="M' + (x + w * .44) + " " + (y + h * .78) + " L" + (x + w * .5) + " " + (y + h) + " L" + (x + w * .58) + " " + (y + h * .78) + ' Z"' + common + "></path>";
    if (elm.type === "thought") return '<ellipse cx="' + cx + '" cy="' + (y + h * .42) + '" rx="' + w / 2 + '" ry="' + h * .36 + '"' + common + "></ellipse>" + '<circle cx="' + (x + w * .62) + '" cy="' + (y + h * .82) + '" r="' + Math.min(w, h) * .08 + '"' + common + "></circle>" + '<circle cx="' + (x + w * .72) + '" cy="' + (y + h * .96) + '" r="' + Math.min(w, h) * .05 + '"' + common + "></circle>";
    if (elm.type === "text") return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" rx="4" fill="transparent" stroke="transparent"></rect>';
    if (elm.type === "wordart") return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" fill="transparent" stroke="transparent"></rect>';
    if (elm.type === "image") return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" rx="8" fill="#f8fafc" stroke="#d7dee8"></rect>' + (elm.image ? '<image href="' + esc(elm.image) + '" xlink:href="' + esc(elm.image) + '" x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" preserveAspectRatio="xMidYMid slice"></image>' : diagramText(elm));
    return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" rx="' + (elm.type === "roundedRect" ? 14 : 6) + '"' + common + "></rect>";
  }

  function diagramTextContent(elm) {
    var lines = String(elm.text || "").split(/\r?\n/);
    var highlight = elm.highlightColor && elm.highlightColor !== "transparent" ? 'background-color:' + esc(elm.highlightColor) + ";" : "";
    var lineStyle = highlight ? ' style="' + highlight + 'box-decoration-break:clone;-webkit-box-decoration-break:clone;"' : "";
    var items = lines.map(function (line) {
      return '<span' + lineStyle + ">" + (line ? esc(line) : "&nbsp;") + "</span>";
    });
    var listStyle = esc(normalizeDiagramListStyle(elm.listType, elm.listStyle));
    if (elm.listType === "bullet") {
      return '<ul style="margin:0;list-style-type:' + listStyle + ';padding-left:' + (18 + elm.indent * 18) + 'px;">' + items.map(function (item) { return "<li>" + item + "</li>"; }).join("") + "</ul>";
    }
    if (elm.listType === "number") {
      return '<ol style="margin:0;list-style-type:' + listStyle + ';padding-left:' + (22 + elm.indent * 18) + 'px;">' + items.map(function (item) { return "<li>" + item + "</li>"; }).join("") + "</ol>";
    }
    return items.map(function (item, index) {
      var margin = "margin:0;";
      if (index === 0 && elm.spacingBefore) margin += "padding-top:" + esc(elm.spacingBefore) + "px;";
      if (index === lines.length - 1 && elm.spacingAfter) margin += "padding-bottom:" + esc(elm.spacingAfter) + "px;";
      return '<div style="' + margin + '">' + item + "</div>";
    }).join("");
  }

  function diagramText(elm) {
    if (!elm.text) return "";
    if (elm.type === "wordart") {
      var anchor = elm.textAlign === "left" ? "start" : elm.textAlign === "right" ? "end" : "middle";
      var x = elm.textAlign === "left" ? elm.x + 12 : elm.textAlign === "right" ? elm.x + elm.w - 12 : elm.x + elm.w / 2;
      var y = elm.y + elm.h / 2;
      var decoration = elm.underline ? ' text-decoration="underline"' : "";
      var stroke = ' stroke="' + esc(elm.stroke) + '" stroke-width="' + Math.max(1, elm.strokeWidth) + '" paint-order="stroke fill"';
      return '<text x="' + x + '" y="' + y + '" text-anchor="' + anchor + '" dominant-baseline="middle" font-family="' + esc(elm.fontFamily) + ', Arial, sans-serif" font-size="' + esc(elm.fontSize) + '" font-weight="' + (elm.bold ? "800" : "400") + '" font-style="' + (elm.italic ? "italic" : "normal") + '"' + decoration + stroke + ' fill="' + esc(elm.textColor) + '">' + esc(elm.text || "") + "</text>";
    }
    var textBox = { x: elm.x, y: elm.y, w: elm.w, h: elm.h };
    if (elm.type === "callout") textBox.h = elm.h * .72;
    if (elm.type === "roundCallout") textBox.h = elm.h * .7;
    if (elm.type === "thought") textBox.h = elm.h * .72;
    var align = elm.textAlign || "center";
    var justify = align === "left" ? "flex-start" : align === "right" ? "flex-end" : "center";
    var decorationStyle = elm.underline ? "text-decoration:underline;" : "";
    var contentStyle = "box-sizing:border-box;width:100%;height:100%;display:flex;align-items:center;justify-content:" + justify + ";overflow:hidden;padding:4px 8px 4px " + (8 + elm.indent * 10) + "px;color:" + esc(elm.textColor) + ";font-family:" + esc(elm.fontFamily) + ",Arial,sans-serif;font-size:" + esc(elm.fontSize) + "px;font-weight:" + (elm.bold ? "800" : "400") + ";font-style:" + (elm.italic ? "italic" : "normal") + ";" + decorationStyle + "text-align:" + esc(align) + ";line-height:" + esc(elm.lineHeight) + ";white-space:normal;overflow-wrap:anywhere;word-break:break-word;";
    var innerStyle = "max-width:100%;";
    if (align === "justify") innerStyle += "text-align:justify;";
    return '<foreignObject class="rbe-mermaid-text-layer" x="' + esc(textBox.x) + '" y="' + esc(textBox.y) + '" width="' + esc(textBox.w) + '" height="' + esc(textBox.h) + '"><div xmlns="http://www.w3.org/1999/xhtml" style="' + contentStyle + '"><div style="' + innerStyle + '">' + diagramTextContent(elm) + "</div></div></foreignObject>";
  }

  function linePath(elm) {
    if (elm.type === "elbow") return "M" + elm.x1 + " " + elm.y1 + " L" + elm.x2 + " " + elm.y1 + " L" + elm.x2 + " " + elm.y2;
    if (elm.type === "curved" || elm.type === "curve") {
      var midX = (elm.x1 + elm.x2) / 2;
      return "M" + elm.x1 + " " + elm.y1 + " C" + midX + " " + elm.y1 + " " + midX + " " + elm.y2 + " " + elm.x2 + " " + elm.y2;
    }
    if (elm.type === "polyline") return "M" + elm.x1 + " " + elm.y1 + " L" + ((elm.x1 + elm.x2) / 2) + " " + (elm.y1 - 45) + " L" + elm.x2 + " " + elm.y2;
    if (elm.type === "scribble") {
      var d = "M" + elm.x1 + " " + elm.y1;
      for (var i = 1; i <= 8; i += 1) {
        var t = i / 8;
        d += " L" + (elm.x1 + (elm.x2 - elm.x1) * t) + " " + (elm.y1 + (elm.y2 - elm.y1) * t + (i % 2 ? 8 : -8));
      }
      return d;
    }
    return "M" + elm.x1 + " " + elm.y1 + " L" + elm.x2 + " " + elm.y2;
  }

  function elementBounds(elm) {
    if (isLineType(elm.type)) {
      return { x: Math.min(elm.x1, elm.x2), y: Math.min(elm.y1, elm.y2), w: Math.abs(elm.x2 - elm.x1), h: Math.abs(elm.y2 - elm.y1) };
    }
    return { x: elm.x, y: elm.y, w: elm.w, h: elm.h };
  }

  function rectsIntersect(a, b) {
    return a.x <= b.x + b.w && a.x + a.w >= b.x && a.y <= b.y + b.h && a.y + a.h >= b.y;
  }

  function selectionMarkup(elm, isSingle) {
    var b = elementBounds(elm);
    var markup = '<rect class="rbe-mermaid-selected-stroke" x="' + b.x + '" y="' + b.y + '" width="' + b.w + '" height="' + b.h + '" rx="6"></rect>';
    var handleStyle = ' style="--rbe-handle-color:#2563eb"';
    if (!isSingle || isLineType(elm.type)) {
      if (isSingle && isLineType(elm.type)) {
        markup += '<circle class="rbe-mermaid-handle" data-handle="start" cx="' + elm.x1 + '" cy="' + elm.y1 + '" r="5"' + handleStyle + '></circle><circle class="rbe-mermaid-handle" data-handle="end" cx="' + elm.x2 + '" cy="' + elm.y2 + '" r="5"' + handleStyle + '></circle>';
      }
      return markup;
    }
    [["nw", b.x, b.y], ["ne", b.x + b.w, b.y], ["se", b.x + b.w, b.y + b.h], ["sw", b.x, b.y + b.h]].forEach(function (handle) {
      markup += '<circle class="rbe-mermaid-handle" data-handle="' + handle[0] + '" cx="' + handle[1] + '" cy="' + handle[2] + '" r="5"' + handleStyle + '></circle>';
    });
    [
      ["n", b.x + b.w / 2, b.y, 24, 6],
      ["e", b.x + b.w, b.y + b.h / 2, 6, 24],
      ["s", b.x + b.w / 2, b.y + b.h, 24, 6],
      ["w", b.x, b.y + b.h / 2, 6, 24]
    ].forEach(function (handle) {
      markup += '<rect class="rbe-mermaid-handle" data-handle="' + handle[0] + '" x="' + (handle[1] - handle[3] / 2) + '" y="' + (handle[2] - handle[4] / 2) + '" width="' + handle[3] + '" height="' + handle[4] + '" rx="3"' + handleStyle + '></rect>';
    });
    var rotateX = b.x + b.w / 2;
    var rotateY = b.y - 28;
    markup += '<g class="rbe-mermaid-rotate" data-handle="rotate"><circle cx="' + rotateX + '" cy="' + rotateY + '" r="9"></circle><path d="M' + (rotateX + 2) + " " + (rotateY - 3) + " A4 4 0 1 0 " + (rotateX + 4) + " " + (rotateY + 2) + '" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round"></path><path d="M' + (rotateX + 3) + " " + (rotateY - 6) + " L" + (rotateX + 7) + " " + (rotateY - 3) + " L" + (rotateX + 3) + " " + rotateY + ' Z" fill="#fff"></path></g>';
    return markup;
  }

  function diagramSvg(elements, selectedIds, workspace, marquee) {
    elements = (elements || []).map(normalizeDiagramElement);
    workspace = workspace || defaultMermaidWorkspace();
    var selected = selectedIdList(selectedIds);
    var body = elements.map(function (elm) {
      var isSelected = selected.indexOf(elm.id) !== -1;
      var selectMarkup = isSelected ? selectionMarkup(elm, selected.length === 1) : "";
      var transform = "";
      if (!isLineType(elm.type) && (elm.rotation || elm.flipX || elm.flipY)) {
        var tx = elm.x + elm.w / 2;
        var ty = elm.y + elm.h / 2;
        transform = ' transform="' + (elm.rotation ? "rotate(" + esc(elm.rotation) + " " + tx + " " + ty + ") " : "") + ((elm.flipX || elm.flipY) ? "translate(" + tx + " " + ty + ") scale(" + (elm.flipX ? -1 : 1) + " " + (elm.flipY ? -1 : 1) + ") translate(" + (-tx) + " " + (-ty) + ")" : "") + '"';
      }
      if (isLineType(elm.type)) {
        var markerStart = elm.type === "leftArrow" || elm.type === "biArrow" ? ' marker-start="url(#rbe-arrow-head-start)"' : "";
        var markerEnd = /^(arrow|rightArrow|upArrow|downArrow|biArrow|elbow|curved)$/.test(elm.type) ? ' marker-end="url(#rbe-arrow-head)"' : "";
        var dash = dashArray(elm.dash);
        var originDot = isSelected && (markerStart || markerEnd) ? '<circle class="rbe-mermaid-arrow-origin" cx="' + esc(elm.x1) + '" cy="' + esc(elm.y1) + '" r="4"></circle>' : "";
        return '<g data-el-id="' + esc(elm.id) + '">' + selectMarkup + originDot + '<path d="' + linePath(elm) + '" fill="none" stroke="' + esc(elm.stroke) + '" stroke-width="' + esc(elm.strokeWidth) + '" stroke-linecap="round" stroke-linejoin="round"' + (dash ? ' stroke-dasharray="' + dash + '"' : "") + ' opacity="' + esc(elm.opacity) + '"' + markerStart + markerEnd + "></path></g>";
      }
      return '<g data-el-id="' + esc(elm.id) + '"' + transform + ">" + selectMarkup + shapeMarkup(elm) + (elm.type !== "image" ? diagramText(elm) : "") + "</g>";
    }).join("");
    if (marquee) body += '<rect class="rbe-mermaid-marquee" x="' + marquee.x + '" y="' + marquee.y + '" width="' + marquee.w + '" height="' + marquee.h + '"></rect>';
    return '<svg class="rbe-mermaid-canvas" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' + workspace.width * workspace.zoom + '" height="' + workspace.height * workspace.zoom + '" viewBox="0 0 ' + workspace.width + " " + workspace.height + '" role="img" aria-label="Diagram" tabindex="0"><defs><marker id="rbe-arrow-head" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L0,6 L9,3 z" fill="#475467"></path></marker><marker id="rbe-arrow-head-start" markerWidth="10" markerHeight="10" refX="1" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M9,0 L9,6 L0,3 z" fill="#475467"></path></marker></defs>' + body + "</svg>";
  }

  function renderDiagramCanvas(wrap) {
    var hidden = wrap.querySelector(".rbe-mermaid-diagram-json");
    var elements = [];
    try {
      elements = JSON.parse(hidden.value || "[]");
    } catch (error) {
      elements = defaultMermaidDiagram();
    }
    var workspace = readWorkspaceFromBlock(wrap);
    var marquee = null;
    try {
      marquee = wrap.dataset.marquee ? JSON.parse(wrap.dataset.marquee) : null;
    } catch (error) {}
    wrap.querySelector(".rbe-mermaid-stage").innerHTML = diagramSvg(elements, wrap.dataset.selectedIds || "", workspace, marquee);
  }

  function readWorkspaceFromBlock(wrap) {
    return {
      width: clampNumber((wrap.querySelector(".rbe-mermaid-workspace-w") || {}).value, 640, MERMAID_WORKSPACE_MAX, 1100),
      height: clampNumber((wrap.querySelector(".rbe-mermaid-workspace-h") || {}).value, 360, MERMAID_WORKSPACE_MAX, 620),
      zoom: clampNumber((wrap.querySelector(".rbe-mermaid-zoom") || {}).value, 0.35, 2.5, 1)
    };
  }

  function bindMermaidDesigner(editor, wrap) {
    var drag = null;
    var lastShapePointer = { id: "", time: 0 };

    function elements() {
      try {
        return JSON.parse(wrap.querySelector(".rbe-mermaid-diagram-json").value || "[]");
      } catch (error) {
        return defaultMermaidDiagram();
      }
    }

    function resizeWorkspaceToFit(items, point) {
      var workspace = readWorkspaceFromBlock(wrap);
      var base = defaultMermaidWorkspace();
      var maxX = point ? point.x : 0;
      var maxY = point ? point.y : 0;
      (items || []).forEach(function (elm) {
        var bounds = elementBounds(elm);
        maxX = Math.max(maxX, bounds.x + bounds.w);
        maxY = Math.max(maxY, bounds.y + bounds.h);
      });
      var width = Math.min(MERMAID_WORKSPACE_MAX, Math.max(base.width, Math.ceil((maxX + MERMAID_WORKSPACE_GROW_PADDING) / MERMAID_WORKSPACE_GROW_STEP) * MERMAID_WORKSPACE_GROW_STEP));
      var height = Math.min(MERMAID_WORKSPACE_MAX, Math.max(base.height, Math.ceil((maxY + MERMAID_WORKSPACE_GROW_PADDING) / MERMAID_WORKSPACE_GROW_STEP) * MERMAID_WORKSPACE_GROW_STEP));
      if (width !== workspace.width) wrap.querySelector(".rbe-mermaid-workspace-w").value = width;
      if (height !== workspace.height) wrap.querySelector(".rbe-mermaid-workspace-h").value = height;
    }

    function setElements(next, skipRender, growPoint) {
      var normalized = next.map(normalizeDiagramElement);
      resizeWorkspaceToFit(normalized, growPoint || null);
      wrap.querySelector(".rbe-mermaid-diagram-json").value = JSON.stringify(normalized);
      if (!skipRender) {
        renderDiagramCanvas(wrap);
        updateOptions();
      }
    }

    function historyStack(name) {
      try {
        return JSON.parse(wrap.dataset[name] || "[]");
      } catch (error) {
        return [];
      }
    }

    function writeHistory(name, stack) {
      wrap.dataset[name] = JSON.stringify(stack.slice(-60));
    }

    function snapshot() {
      return JSON.stringify({ elements: elements(), workspace: readWorkspaceFromBlock(wrap) });
    }

    function restoreSnapshot(value) {
      var state = JSON.parse(value);
      setElements(state.elements || []);
      if (state.workspace) {
        wrap.querySelector(".rbe-mermaid-workspace-w").value = state.workspace.width || 1100;
        wrap.querySelector(".rbe-mermaid-workspace-h").value = state.workspace.height || 620;
        wrap.querySelector(".rbe-mermaid-zoom").value = state.workspace.zoom || 1;
      }
      renderDiagramCanvas(wrap);
      updateOptions();
    }

    function pushUndo() {
      var undo = historyStack("undoStack");
      undo.push(snapshot());
      writeHistory("undoStack", undo);
      writeHistory("redoStack", []);
      refreshHistoryButtons();
    }

    function refreshHistoryButtons() {
      var undo = wrap.querySelector("[data-diagram-action='undo']");
      var redo = wrap.querySelector("[data-diagram-action='redo']");
      if (undo) undo.disabled = !historyStack("undoStack").length;
      if (redo) redo.disabled = !historyStack("redoStack").length;
    }

    function undo() {
      var undoStack = historyStack("undoStack");
      if (!undoStack.length) return;
      var redoStack = historyStack("redoStack");
      redoStack.push(snapshot());
      restoreSnapshot(undoStack.pop());
      writeHistory("undoStack", undoStack);
      writeHistory("redoStack", redoStack);
      refreshHistoryButtons();
      editor.changed(true);
    }

    function redo() {
      var redoStack = historyStack("redoStack");
      if (!redoStack.length) return;
      var undoStack = historyStack("undoStack");
      undoStack.push(snapshot());
      restoreSnapshot(redoStack.pop());
      writeHistory("undoStack", undoStack);
      writeHistory("redoStack", redoStack);
      refreshHistoryButtons();
      editor.changed(true);
    }

    function selectedIds() {
      return selectedIdList(wrap.dataset.selectedIds || "");
    }

    function setSelected(ids) {
      wrap.dataset.selectedIds = (ids || []).filter(Boolean).join(",");
      renderDiagramCanvas(wrap);
      updateOptions();
    }

    function selectedElements() {
      var ids = selectedIds();
      return elements().filter(function (elm) { return ids.indexOf(elm.id) !== -1; });
    }

    function setTool(tool, sourceSelect) {
      wrap.dataset.tool = tool;
      Array.prototype.slice.call(wrap.querySelectorAll(".rbe-mermaid-tool[data-tool]")).forEach(function (button) {
        button.classList.toggle("is-active", button.dataset.tool === tool);
      });
      Array.prototype.slice.call(wrap.querySelectorAll(".rbe-mermaid-menu-select")).forEach(function (select) {
        if (select !== sourceSelect) select.value = "";
      });
    }

    function point(event) {
      var svg = wrap.querySelector(".rbe-mermaid-canvas");
      var rect = svg.getBoundingClientRect();
      var workspace = readWorkspaceFromBlock(wrap);
      var raw = { x: ((event.clientX - rect.left) / rect.width) * workspace.width, y: ((event.clientY - rect.top) / rect.height) * workspace.height };
      return event.altKey ? raw : { x: Math.round(raw.x / 10) * 10, y: Math.round(raw.y / 10) * 10 };
    }

    function autoScrollStage(event) {
      var stage = wrap.querySelector(".rbe-mermaid-stage");
      if (!stage) return;
      var rect = stage.getBoundingClientRect();
      var edge = 56;
      var step = 30;
      var dx = 0;
      var dy = 0;
      if (event.clientX > rect.right - edge) dx = step;
      else if (event.clientX < rect.left + edge) dx = -step;
      if (event.clientY > rect.bottom - edge) dy = step;
      else if (event.clientY < rect.top + edge) dy = -step;
      if (dx || dy) {
        stage.scrollLeft += dx;
        stage.scrollTop += dy;
      }
    }

    function constrainLinePoint(start, current) {
      var dx = current.x - start.x;
      var dy = current.y - start.y;
      if (!dx && !dy) return current;
      var length = Math.sqrt(dx * dx + dy * dy);
      var snappedAngle = Math.round(Math.atan2(dy, dx) / (Math.PI / 4)) * (Math.PI / 4);
      return {
        x: Math.round((start.x + Math.cos(snappedAngle) * length) / 10) * 10,
        y: Math.round((start.y + Math.sin(snappedAngle) * length) / 10) * 10
      };
    }

    function selectedBounds() {
      var list = selectedElements();
      if (!list.length) return null;
      var bounds = list.map(elementBounds);
      var minX = Math.min.apply(null, bounds.map(function (b) { return b.x; }));
      var minY = Math.min.apply(null, bounds.map(function (b) { return b.y; }));
      var maxX = Math.max.apply(null, bounds.map(function (b) { return b.x + b.w; }));
      var maxY = Math.max.apply(null, bounds.map(function (b) { return b.y + b.h; }));
      return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };
    }

    function updateOptions() {
      var selected = selectedElements();
      var panel = wrap.querySelector(".rbe-mermaid-stylebar");
      if (!panel || !wrap.querySelector(".rbe-mermaid-option-text")) return;
      panel.hidden = !selected.length;
      if (!selected.length) return;
      var first = selected[0];
      var isLineSelection = selected.every(function (elm) { return isLineType(elm.type); });
      var isTextCapable = selected.some(function (elm) { return !isLineType(elm.type) && elm.type !== "image"; });
      panel.classList.toggle("is-line-selection", isLineSelection);
      panel.classList.toggle("is-text-capable", isTextCapable);
      wrap.querySelector(".rbe-mermaid-option-text").value = selected.length === 1 ? first.text || "" : selected.length + " objects selected";
      wrap.querySelector(".rbe-mermaid-option-text").disabled = selected.length !== 1;
      wrap.querySelector(".rbe-mermaid-option-font").value = first.fontFamily || "Arial";
      wrap.querySelector(".rbe-mermaid-option-size").value = first.fontSize || 16;
      var fillColor = first.fill === "transparent" ? "#ffffff" : normalizeChartColor(first.fill, "#eef5ff");
      var strokeColor = normalizeChartColor(first.stroke, "#111827");
      var textColor = normalizeChartColor(first.textColor, "#172033");
      var highlightColor = first.highlightColor === "transparent" ? "#fff3b0" : normalizeChartColor(first.highlightColor, "#fff3b0");
      wrap.querySelector(".rbe-mermaid-option-fill").value = fillColor;
      wrap.querySelector(".rbe-mermaid-option-stroke").value = strokeColor;
      wrap.querySelector(".rbe-mermaid-option-text-color").value = textColor;
      wrap.querySelector(".rbe-mermaid-option-highlight").value = highlightColor;
      wrap.querySelector(".rbe-mermaid-option-align").value = first.textAlign || "center";
      wrap.querySelector(".rbe-mermaid-option-line-height").value = String(normalizeDiagramLineHeight(first.lineHeight));
      wrap.querySelector(".rbe-mermaid-option-bullet").value = first.listType === "bullet" ? normalizeDiagramListStyle("bullet", first.listStyle) : "none";
      wrap.querySelector(".rbe-mermaid-option-number").value = first.listType === "number" ? normalizeDiagramListStyle("number", first.listStyle) : "none";
      panel.style.setProperty("--rbe-mermaid-fill", fillColor);
      panel.style.setProperty("--rbe-mermaid-stroke", strokeColor);
      panel.style.setProperty("--rbe-mermaid-text", textColor);
      panel.style.setProperty("--rbe-mermaid-highlight", first.highlightColor === "transparent" ? "transparent" : highlightColor);
      wrap.querySelector(".rbe-mermaid-option-weight").value = first.strokeWidth || 1;
      wrap.querySelector(".rbe-mermaid-option-dash").value = normalizeDiagramDash(first.dash);
      wrap.querySelector(".rbe-mermaid-option-opacity").value = first.opacity || 1;
      Array.prototype.slice.call(wrap.querySelectorAll("[data-format-toggle]")).forEach(function (button) {
        var prop = button.dataset.formatToggle;
        button.classList.toggle("is-active", !!first[prop]);
      });
      var activeControls = [
        [".rbe-mermaid-bullet-control", first.listType === "bullet"],
        [".rbe-mermaid-number-control", first.listType === "number"],
        [".rbe-mermaid-spacing-before", !!first.spacingBefore],
        [".rbe-mermaid-spacing-after", !!first.spacingAfter]
      ];
      activeControls.forEach(function (item) {
        var node = wrap.querySelector(item[0]);
        if (node) node.classList.toggle("is-active", !!item[1]);
      });
    }

    function updateSelected(mutator, skipUndo) {
      var ids = selectedIds();
      if (!ids.length) return;
      if (!skipUndo) pushUndo();
      setElements(elements().map(function (elm) {
        if (ids.indexOf(elm.id) !== -1) mutator(elm);
        return elm;
      }));
      editor.changed(true);
    }

    function applyStylebarChange(event) {
      if (!event.target.closest(".rbe-mermaid-stylebar")) return false;
      var bulletChanged = event.target.classList.contains("rbe-mermaid-option-bullet");
      var numberChanged = event.target.classList.contains("rbe-mermaid-option-number");
      updateSelected(function (elm) {
        if (event.target.classList.contains("rbe-mermaid-option-text")) elm.text = event.target.value;
        elm.fontFamily = wrap.querySelector(".rbe-mermaid-option-font").value || "Arial";
        elm.fontSize = Number(wrap.querySelector(".rbe-mermaid-option-size").value || 16);
        if (!isLineType(elm.type)) elm.fill = wrap.querySelector(".rbe-mermaid-option-fill").value;
        elm.stroke = wrap.querySelector(".rbe-mermaid-option-stroke").value;
        elm.textColor = wrap.querySelector(".rbe-mermaid-option-text-color").value;
        elm.highlightColor = event.target.classList.contains("rbe-mermaid-option-highlight") ? wrap.querySelector(".rbe-mermaid-option-highlight").value : elm.highlightColor;
        elm.textAlign = wrap.querySelector(".rbe-mermaid-option-align").value || "center";
        elm.lineHeight = normalizeDiagramLineHeight(wrap.querySelector(".rbe-mermaid-option-line-height").value);
        if (bulletChanged) {
          var bulletValue = wrap.querySelector(".rbe-mermaid-option-bullet").value || "none";
          elm.listType = bulletValue === "none" ? "none" : "bullet";
          elm.listStyle = bulletValue === "none" ? "none" : bulletValue;
          wrap.querySelector(".rbe-mermaid-option-number").value = "none";
        }
        if (numberChanged) {
          var numberValue = wrap.querySelector(".rbe-mermaid-option-number").value || "none";
          elm.listType = numberValue === "none" ? "none" : "number";
          elm.listStyle = numberValue === "none" ? "none" : numberValue;
          wrap.querySelector(".rbe-mermaid-option-bullet").value = "none";
        }
        elm.strokeWidth = Number(wrap.querySelector(".rbe-mermaid-option-weight").value || 1);
        elm.dash = wrap.querySelector(".rbe-mermaid-option-dash").value;
        elm.opacity = Number(wrap.querySelector(".rbe-mermaid-option-opacity").value || 1);
      }, true);
      return true;
    }

    function createElement(type, p, fileData) {
      var line = isLineType(type);
      var text = "";
      if (type === "wordart") text = "WordArt";
      else if (/^(plus|minus|multiply|divide|equal|brackets)$/.test(type)) text = { plus: "+", minus: "-", multiply: "x", divide: "/", equal: "=", brackets: "[ ]" }[type] || "";
      return normalizeDiagramElement({
        id: "diagram-" + Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 6),
        type: type,
        x: p.x,
        y: p.y,
        w: type === "image" ? 220 : type === "wordart" ? 240 : type === "text" ? 190 : 10,
        h: type === "image" ? 150 : type === "wordart" ? 78 : type === "text" ? 70 : 10,
        x1: p.x,
        y1: p.y,
        x2: p.x,
        y2: p.y,
        text: text,
        image: fileData && fileData.url ? fileData.url : "",
        name: fileData && fileData.name ? fileData.name : "",
        fill: line || type === "text" ? "transparent" : type === "wordart" ? "#f59e0b" : "#eef5ff",
        stroke: line ? "#475467" : "#111827",
        strokeWidth: 1,
        fontSize: type === "wordart" ? 36 : 16
      });
    }

    function editableDiagramElement(item) {
      return item && !isLineType(item.type) && item.type !== "image";
    }

    function restoreTextEditorTargets() {
      Array.prototype.slice.call(wrap.querySelectorAll(".rbe-mermaid-hidden-text")).forEach(function (node) {
        node.classList.remove("rbe-mermaid-hidden-text");
      });
    }

    function hideTextForEditor(id) {
      restoreTextEditorTargets();
      var group = Array.prototype.slice.call(wrap.querySelectorAll(".rbe-mermaid-canvas [data-el-id]")).filter(function (node) {
        return node.getAttribute("data-el-id") === id;
      })[0];
      if (!group) return;
      Array.prototype.slice.call(group.querySelectorAll("text,.rbe-mermaid-text-layer")).forEach(function (node) {
        node.classList.add("rbe-mermaid-hidden-text");
      });
    }

    function placeTextEditorCaretAtEnd(node) {
      if (!node) return;
      node.focus();
      try {
        node.setSelectionRange(node.value.length, node.value.length, "none");
      } catch (error) {}
    }

    function scheduleTextEditorCaretAtEnd(node) {
      if (!node) return;
      node.dataset.forceCaretEnd = "true";
      placeTextEditorCaretAtEnd(node);
      if (window.requestAnimationFrame) {
        window.requestAnimationFrame(function () { placeTextEditorCaretAtEnd(node); });
      }
      [0, 40, 120].forEach(function (delay) {
        setTimeout(function () { placeTextEditorCaretAtEnd(node); }, delay);
      });
    }

    function closeTextEditor(save) {
      var active = wrap.querySelector(".rbe-mermaid-text-editor");
      if (!active) return;
      var id = active.dataset.editId || "";
      var nextText = active.value || active.textContent || "";
      restoreTextEditorTargets();
      active.remove();
      if (!save || !id) return;
      pushUndo();
      setElements(elements().map(function (elm) {
        if (elm.id === id) elm.text = nextText.trim();
        return elm;
      }));
      setSelected([id]);
      editor.changed(true);
    }

    function openTextEditor(id, seedText) {
      var item = elements().filter(function (elm) { return elm.id === id; })[0];
      if (!editableDiagramElement(item)) return;
      closeTextEditor(true);
      var stage = wrap.querySelector(".rbe-mermaid-stage");
      var workspace = readWorkspaceFromBlock(wrap);
      var svg = wrap.querySelector(".rbe-mermaid-canvas");
      var svgRect = svg ? svg.getBoundingClientRect() : null;
      var scaleX = svgRect && svgRect.width ? svgRect.width / workspace.width : workspace.zoom;
      var scaleY = svgRect && svgRect.height ? svgRect.height / workspace.height : workspace.zoom;
      var scale = Math.min(scaleX, scaleY);
      var node = document.createElement("textarea");
      var initial = seedText != null ? seedText : item.text || "";
      node.className = "rbe-mermaid-text-editor";
      node.dataset.editId = id;
      node.spellcheck = false;
      node.wrap = "soft";
      node.setAttribute("role", "textbox");
      node.setAttribute("aria-label", "Shape text");
      if (item.type === "text") node.setAttribute("placeholder", "Text");
      var textBox = { x: item.x, y: item.y, w: item.w, h: item.h };
      if (item.type === "callout") textBox.h = item.h * .72;
      if (item.type === "roundCallout") textBox.h = item.h * .7;
      if (item.type === "thought") textBox.h = item.h * .72;
      var pixelX = textBox.x * scaleX;
      var pixelY = textBox.y * scaleY;
      var pixelW = Math.max(42, textBox.w * scaleX);
      var pixelH = Math.max(32, textBox.h * scaleY);
      node.style.left = pixelX + "px";
      node.style.top = pixelY + "px";
      node.style.width = pixelW + "px";
      node.style.height = pixelH + "px";
      node.style.fontFamily = item.fontFamily || "Arial";
      var fontSize = Math.max(18, (item.fontSize || 16) * scale);
      var lineHeight = Math.round(fontSize * 1.25);
      node.style.fontSize = fontSize + "px";
      lineHeight = Math.round(fontSize * normalizeDiagramLineHeight(item.lineHeight));
      node.style.lineHeight = lineHeight + "px";
      node.style.padding = Math.max(4, Math.floor((pixelH - lineHeight) / 2)) + "px 8px 4px";
      node.style.fontWeight = item.bold ? "800" : "700";
      node.style.fontStyle = item.italic ? "italic" : "normal";
      node.style.color = item.textColor || "#172033";
      node.style.textAlign = item.textAlign || "center";
      node.style.backgroundColor = item.highlightColor && item.highlightColor !== "transparent" ? item.highlightColor : "transparent";
      node.value = initial;
      hideTextForEditor(id);
      stage.appendChild(node);
      scheduleTextEditorCaretAtEnd(node);
      setTimeout(function () {
        node.dataset.allowPointerCaret = "true";
      }, 250);
      node.addEventListener("pointerdown", function () {
        if (node.dataset.allowPointerCaret === "true") node.dataset.forceCaretEnd = "";
      });
      node.addEventListener("keydown", function (event) {
        event.stopPropagation();
        if (event.ctrlKey || event.metaKey || event.altKey) {
          node.dataset.forceCaretEnd = "";
          return;
        }
        if (node.dataset.forceCaretEnd === "true" && (event.key.length === 1 || event.key === "Backspace" || event.key === "Delete")) {
          placeTextEditorCaretAtEnd(node);
          node.dataset.forceCaretEnd = "";
          if (event.key.length === 1 && /^[A-Za-z0-9]$/.test(event.key) && node.value && !/\s$/.test(node.value)) {
            event.preventDefault();
            node.setRangeText(" " + event.key, node.value.length, node.value.length, "end");
            return;
          }
        }
        if (event.key === "Enter" && !event.shiftKey) {
          event.preventDefault();
          closeTextEditor(true);
        }
        if (event.key === "Escape") {
          event.preventDefault();
          closeTextEditor(false);
        }
      });
      node.addEventListener("blur", function () {
        closeTextEditor(true);
      }, { once: true });
    }

    function applyAction(action) {
      var list = elements();
      var ids = selectedIds();
      if (action === "image") {
        wrap.querySelector(".rbe-mermaid-image-input").click();
        return;
      }
      if (!ids.length && !/^(paste|downloadSvg|downloadPng|downloadJpeg|downloadPdf|fit|zoomIn|zoomOut)$/.test(action)) return;
      if (action === "undo") return undo();
      if (action === "redo") return redo();
      if (action === "copy" || action === "cut") {
        wrap.dataset.clipboard = JSON.stringify(selectedElements());
        if (action === "cut") {
          pushUndo();
          setElements(list.filter(function (elm) { return ids.indexOf(elm.id) === -1; }));
          setSelected([]);
          editor.changed(true);
        }
        return;
      }
      if (action === "paste") {
        var clip = [];
        try { clip = JSON.parse(wrap.dataset.clipboard || "[]"); } catch (error) {}
        if (!clip.length) return;
        pushUndo();
        var pasted = clip.map(function (elm) {
          elm = normalizeDiagramElement(elm);
          elm.id = "diagram-" + Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 6);
          if (isLineType(elm.type)) {
            elm.x1 += 30; elm.x2 += 30; elm.y1 += 30; elm.y2 += 30;
          } else {
            elm.x += 30; elm.y += 30;
          }
          return elm;
        });
        setElements(list.concat(pasted));
        setSelected(pasted.map(function (elm) { return elm.id; }));
        editor.changed(true);
        return;
      }
      if (action === "duplicate") {
        wrap.dataset.clipboard = JSON.stringify(selectedElements());
        return applyAction("paste");
      }
      if (action === "delete") {
        pushUndo();
        setElements(list.filter(function (elm) { return ids.indexOf(elm.id) === -1; }));
        setSelected([]);
        editor.changed(true);
        return;
      }
      if (/^download/.test(action)) return downloadDiagram(wrap, action);
      if (action === "zoomIn" || action === "zoomOut" || action === "fit") {
        var zoom = wrap.querySelector(".rbe-mermaid-zoom");
        zoom.value = action === "fit" ? 1 : clampNumber(Number(zoom.value || 1) + (action === "zoomIn" ? .1 : -.1), .35, 2.5, 1);
        renderDiagramCanvas(wrap);
        editor.changed(true);
        return;
      }
      pushUndo();
      if (action === "bringFront") list = list.filter(function (elm) { return ids.indexOf(elm.id) === -1; }).concat(list.filter(function (elm) { return ids.indexOf(elm.id) !== -1; }));
      else if (action === "sendBack") list = list.filter(function (elm) { return ids.indexOf(elm.id) !== -1; }).concat(list.filter(function (elm) { return ids.indexOf(elm.id) === -1; }));
      else if (action === "bringForward" || action === "sendBackward") {
        var step = action === "bringForward" ? 1 : -1;
        ids.forEach(function (id) {
          var index = list.findIndex(function (elm) { return elm.id === id; });
          var nextIndex = index + step;
          if (index < 0 || nextIndex < 0 || nextIndex >= list.length) return;
          var item = list[index];
          list.splice(index, 1);
          list.splice(nextIndex, 0, item);
        });
      }
      else {
        var bounds = selectedBounds();
        if (action === "group") {
          var groupId = "group-" + Date.now().toString(36);
          list.forEach(function (elm) { if (ids.indexOf(elm.id) !== -1) elm.group = groupId; });
        }
        if (action === "ungroup") {
          list.forEach(function (elm) { if (ids.indexOf(elm.id) !== -1) elm.group = ""; });
        }
        if (action === "distributeH" && ids.length > 2) {
          var hItems = list.filter(function (elm) { return ids.indexOf(elm.id) !== -1 && !isLineType(elm.type); }).sort(function (a, b) { return a.x - b.x; });
          var firstX = hItems[0].x;
          var lastX = hItems[hItems.length - 1].x;
          var gapX = (lastX - firstX) / (hItems.length - 1);
          hItems.forEach(function (elm, index) { elm.x = firstX + gapX * index; });
        }
        if (action === "distributeV" && ids.length > 2) {
          var vItems = list.filter(function (elm) { return ids.indexOf(elm.id) !== -1 && !isLineType(elm.type); }).sort(function (a, b) { return a.y - b.y; });
          var firstY = vItems[0].y;
          var lastY = vItems[vItems.length - 1].y;
          var gapY = (lastY - firstY) / (vItems.length - 1);
          vItems.forEach(function (elm, index) { elm.y = firstY + gapY * index; });
        }
        list.forEach(function (elm) {
          if (ids.indexOf(elm.id) === -1) return;
          if (action === "rotateClockwise") elm.rotation = (elm.rotation || 0) + 15;
          if (action === "rotateCounter") elm.rotation = (elm.rotation || 0) - 15;
          if (action === "flipH" && !isLineType(elm.type)) elm.flipX = !elm.flipX;
          if (action === "flipV" && !isLineType(elm.type)) elm.flipY = !elm.flipY;
          if (!bounds || isLineType(elm.type)) return;
          if (action === "alignLeft") elm.x = bounds.x;
          if (action === "alignCenter") elm.x = bounds.x + bounds.w / 2 - elm.w / 2;
          if (action === "alignRight") elm.x = bounds.x + bounds.w - elm.w;
          if (action === "alignTop") elm.y = bounds.y;
          if (action === "alignMiddle") elm.y = bounds.y + bounds.h / 2 - elm.h / 2;
          if (action === "alignBottom") elm.y = bounds.y + bounds.h - elm.h;
        });
      }
      setElements(list);
      editor.changed(true);
    }

    function downloadDiagram(block, action) {
      var svg = diagramSvg(elements(), "", readWorkspaceFromBlock(block), null);
      var mime = "image/svg+xml";
      var ext = "svg";
      if (action === "downloadSvg") {
        triggerDownload("blockwriteai-diagram.svg", "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg));
        return;
      }
      if (action === "downloadPdf") {
        var popup = window.open("", "_blank");
        if (popup) {
          popup.document.write("<!doctype html><title>BlockWriteAI Diagram</title><style>body{margin:24px;font-family:Arial,sans-serif}svg{max-width:100%;height:auto}</style>" + svg + "<script>setTimeout(function(){window.print();},250);<\/script>");
          popup.document.close();
        }
        return;
      }
      var img = new Image();
      var url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
      img.onload = function () {
        var workspace = readWorkspaceFromBlock(block);
        var canvas = document.createElement("canvas");
        canvas.width = workspace.width;
        canvas.height = workspace.height;
        var ctx = canvas.getContext("2d");
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0);
        mime = action === "downloadJpeg" ? "image/jpeg" : "image/png";
        ext = action === "downloadJpeg" ? "jpg" : "png";
        triggerDownload("blockwriteai-diagram." + ext, canvas.toDataURL(mime, .92));
      };
      img.src = url;
    }

    function triggerDownload(name, href) {
      var link = document.createElement("a");
      link.href = href;
      link.download = name;
      document.body.appendChild(link);
      link.click();
      link.remove();
    }

    wrap.addEventListener("click", function (event) {
      var choiceButton = event.target.closest(".rbe-mermaid-choice[data-tool],.rbe-mermaid-line-choice[data-tool]");
      if (choiceButton) {
        event.preventDefault();
        setTool(choiceButton.dataset.tool || "select");
        return;
      }
      var toolButton = event.target.closest(".rbe-mermaid-tool[data-tool]");
      if (toolButton) {
        event.preventDefault();
        setTool(toolButton.dataset.tool || "select");
        return;
      }
      var textActionButton = event.target.closest("[data-text-action]");
      if (textActionButton) {
        event.preventDefault();
        var textAction = textActionButton.dataset.textAction || "";
        updateSelected(function (elm) {
          if (isLineType(elm.type) || elm.type === "image") return;
          if (textAction === "indent") elm.indent = clampNumber(Number(elm.indent || 0) + 1, 0, 8, 0);
          if (textAction === "outdent") elm.indent = clampNumber(Number(elm.indent || 0) - 1, 0, 8, 0);
          if (textAction === "spacing-before") elm.spacingBefore = elm.spacingBefore ? 0 : 10;
          if (textAction === "spacing-after") elm.spacingAfter = elm.spacingAfter ? 0 : 10;
          if (textAction === "reset-highlight") {
            elm.highlightColor = "transparent";
          }
        });
        updateOptions();
        return;
      }
      var alignButton = event.target.closest(".rbe-mermaid-align");
      if (alignButton) {
        event.preventDefault();
        wrap.querySelector(".rbe-mermaid-alignment").value = alignButton.dataset.align || "center";
        Array.prototype.slice.call(wrap.querySelectorAll(".rbe-mermaid-align")).forEach(function (button) {
          button.classList.toggle("is-active", button === alignButton);
        });
        editor.changed(true);
        return;
      }
      var styleButton = event.target.closest("[data-style-action]");
      if (styleButton) {
        event.preventDefault();
        var sizeInput = wrap.querySelector(".rbe-mermaid-option-size");
        var nextSize = Number(sizeInput.value || 16) + (styleButton.dataset.styleAction === "font-size-up" ? 2 : -2);
        sizeInput.value = clampNumber(nextSize, 8, 96, 16);
        applyStylebarChange({ target: sizeInput });
        updateOptions();
        return;
      }
      var actionButton = event.target.closest("[data-diagram-action]");
      if (actionButton) {
        event.preventDefault();
        applyAction(actionButton.dataset.diagramAction);
      }
    });

    wrap.addEventListener("change", function (event) {
      if (applyStylebarChange(event)) return;
      var picker = event.target.closest(".rbe-mermaid-menu-select");
      if (picker && picker.value) {
        setTool(picker.value, picker);
        return;
      }
      var action = event.target.closest(".rbe-mermaid-action-select");
      if (action && action.value) {
        applyAction(action.value);
        action.value = "";
        return;
      }
      if (event.target.closest(".rbe-mermaid-workspace")) {
        pushUndo();
        renderDiagramCanvas(wrap);
        editor.changed(true);
      }
    });

    wrap.addEventListener("input", function (event) {
      applyStylebarChange(event);
    });

    wrap.addEventListener("click", function (event) {
      var formatButton = event.target.closest("[data-format-toggle]");
      if (!formatButton) return;
      event.preventDefault();
      var prop = formatButton.dataset.formatToggle;
      updateSelected(function (elm) { elm[prop] = !elm[prop]; });
    });

    wrap.addEventListener("dblclick", function (event) {
      var target = event.target.closest("[data-el-id]");
      if (!target) return;
      var item = elements().filter(function (elm) { return elm.id === target.dataset.elId; })[0];
      if (!editableDiagramElement(item)) return;
      event.preventDefault();
      setSelected([item.id]);
      openTextEditor(item.id);
    });

    wrap.addEventListener("pointerdown", function (event) {
      var svg = event.target.closest(".rbe-mermaid-canvas");
      if (!svg) return;
      if (wrap.querySelector(".rbe-mermaid-text-editor") && !event.target.closest(".rbe-mermaid-text-editor")) {
        closeTextEditor(true);
        svg = wrap.querySelector(".rbe-mermaid-canvas");
        if (!svg) return;
      }
      wrap.focus();
      event.preventDefault();
      var p = point(event);
      var handle = event.target.closest("[data-handle]");
      var target = event.target.closest("[data-el-id]");
      var tool = wrap.dataset.tool || "select";
      if (target && tool === "select" && !handle) {
        var targetId = target.dataset.elId;
        var now = Date.now();
        var isFastRepeat = lastShapePointer.id === targetId && now - lastShapePointer.time < 430;
        lastShapePointer = { id: targetId, time: now };
        if (Number(event.detail || 0) >= 2 || isFastRepeat) {
          var doubleClicked = elements().filter(function (elm) { return elm.id === targetId; })[0];
          if (editableDiagramElement(doubleClicked)) {
            drag = null;
            setSelected([doubleClicked.id]);
            openTextEditor(doubleClicked.id);
            return;
          }
        }
      } else if (!target) {
        lastShapePointer = { id: "", time: 0 };
      }
      if (handle && selectedIds().length === 1) {
        pushUndo();
        drag = { mode: handle.dataset.handle === "rotate" ? "rotate" : "resize", handle: handle.dataset.handle, start: p, ids: selectedIds(), snapshot: elements() };
        svg.setPointerCapture(event.pointerId);
        return;
      }
      if (target && tool === "select") {
        var id = target.dataset.elId;
        var clicked = elements().filter(function (elm) { return elm.id === id; })[0];
        var groupIds = clicked && clicked.group ? elements().filter(function (elm) { return elm.group === clicked.group; }).map(function (elm) { return elm.id; }) : [id];
        var current = selectedIds();
        if (event.shiftKey || event.ctrlKey) {
          groupIds.forEach(function (groupId) {
            if (current.indexOf(groupId) === -1) current.push(groupId);
            else current = current.filter(function (item) { return item !== groupId; });
          });
          setSelected(current);
        } else if (current.indexOf(id) === -1) {
          setSelected(groupIds);
        }
        pushUndo();
        drag = { mode: "move", ids: selectedIds(), start: p, snapshot: elements() };
        svg.setPointerCapture(event.pointerId);
        return;
      }
      if (tool === "select") {
        setSelected([]);
        drag = { mode: "marquee", start: p };
        svg.setPointerCapture(event.pointerId);
        return;
      }
      var type = tool;
      if (!DIAGRAM_SHAPE_TYPES.test(type) && !DIAGRAM_LINE_TYPES.test(type)) return;
      pushUndo();
      var created = createElement(type, p);
      setElements(elements().concat([created]));
      setSelected([created.id]);
      drag = { mode: "draw", id: created.id, start: p };
      svg.setPointerCapture(event.pointerId);
    });

    wrap.addEventListener("pointermove", function (event) {
      if (!drag) return;
      autoScrollStage(event);
      var p = point(event);
      resizeWorkspaceToFit(elements(), p);
      if (drag.mode === "marquee") {
        var marquee = { x: Math.min(drag.start.x, p.x), y: Math.min(drag.start.y, p.y), w: Math.abs(p.x - drag.start.x), h: Math.abs(p.y - drag.start.y) };
        wrap.dataset.marquee = JSON.stringify(marquee);
        renderDiagramCanvas(wrap);
        return;
      }
      var next = elements().map(function (elm) {
        if (drag.mode === "move" && drag.ids.indexOf(elm.id) !== -1) {
          var original = drag.snapshot.filter(function (item) { return item.id === elm.id; })[0] || elm;
          var dx = p.x - drag.start.x;
          var dy = p.y - drag.start.y;
          if (isLineType(elm.type)) {
            elm.x1 = original.x1 + dx;
            elm.y1 = original.y1 + dy;
            elm.x2 = original.x2 + dx;
            elm.y2 = original.y2 + dy;
          } else {
            elm.x = original.x + dx;
            elm.y = original.y + dy;
          }
        } else if (drag.mode === "draw" && elm.id === drag.id) {
          if (isLineType(elm.type)) {
            var linePoint = event.shiftKey ? constrainLinePoint(drag.start, p) : p;
            elm.x2 = linePoint.x;
            elm.y2 = linePoint.y;
          } else {
            elm.x = Math.min(drag.start.x, p.x);
            elm.y = Math.min(drag.start.y, p.y);
            elm.w = Math.max(40, Math.abs(p.x - drag.start.x));
            elm.h = Math.max(32, Math.abs(p.y - drag.start.y));
          }
        } else if ((drag.mode === "resize" || drag.mode === "rotate") && drag.ids.indexOf(elm.id) !== -1) {
          var base = drag.snapshot.filter(function (item) { return item.id === elm.id; })[0] || elm;
          if (isLineType(elm.type)) {
            if (drag.handle === "start") { elm.x1 = p.x; elm.y1 = p.y; }
            if (drag.handle === "end") { elm.x2 = p.x; elm.y2 = p.y; }
          } else if (drag.mode === "rotate") {
            var cx = base.x + base.w / 2;
            var cy = base.y + base.h / 2;
            elm.rotation = Math.round(Math.atan2(p.y - cy, p.x - cx) * 180 / Math.PI + 90);
          } else {
            var x2 = base.x + base.w;
            var y2 = base.y + base.h;
            if (/w/.test(drag.handle)) elm.x = p.x;
            if (/n/.test(drag.handle)) elm.y = p.y;
            if (/e/.test(drag.handle)) x2 = p.x;
            if (/s/.test(drag.handle)) y2 = p.y;
            elm.w = Math.max(24, x2 - elm.x);
            elm.h = Math.max(24, y2 - elm.y);
          }
        }
        return elm;
      });
      setElements(next, false, p);
    });

    wrap.addEventListener("pointerup", function () {
      if (!drag) return;
      var completedDrawId = drag.mode === "draw" ? drag.id : "";
      if (drag.mode === "marquee") {
        var marquee = JSON.parse(wrap.dataset.marquee || "{}");
        var ids = elements().filter(function (elm) { return rectsIntersect(elementBounds(elm), marquee); }).map(function (elm) { return elm.id; });
        wrap.dataset.marquee = "";
        setSelected(ids);
      }
      if (drag.mode === "draw") setTool("select");
      drag = null;
      refreshHistoryButtons();
      editor.changed(true);
      if (completedDrawId) {
        var item = elements().filter(function (elm) { return elm.id === completedDrawId; })[0];
        if (editableDiagramElement(item)) setTimeout(function () { openTextEditor(completedDrawId); }, 0);
      }
    });

    wrap.addEventListener("keydown", function (event) {
      if (event.target.closest("input,textarea,select,[contenteditable='true']")) return;
      if (!event.ctrlKey && !event.metaKey && !event.altKey && event.key && event.key.length === 1) {
        var selected = selectedElements();
        if (selected.length === 1 && editableDiagramElement(selected[0])) {
          event.preventDefault();
          var existingText = String(selected[0].text || "").trim();
          var typedText = existingText ? existingText + (event.key === " " ? "" : " ") + event.key : event.key;
          openTextEditor(selected[0].id, typedText);
          return;
        }
      }
      if (event.key === "Delete" || event.key === "Backspace") {
        event.preventDefault();
        applyAction("delete");
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "z") {
        event.preventDefault();
        if (event.shiftKey) redo();
        else undo();
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "y") {
        event.preventDefault();
        redo();
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "c") {
        event.preventDefault();
        applyAction("copy");
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "x") {
        event.preventDefault();
        applyAction("cut");
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "v") {
        event.preventDefault();
        applyAction("paste");
      }
      if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "d") {
        event.preventDefault();
        applyAction("duplicate");
      }
    });

    var imageInput = wrap.querySelector(".rbe-mermaid-image-input");
    function readMermaidImageAsDataURL(file) {
      return new Promise(function (resolve, reject) {
        var reader = new FileReader();
        reader.onload = function () { resolve({ url: reader.result, name: file.name }); };
        reader.onerror = function () { reject(reader.error || new Error("Image read failed")); };
        reader.readAsDataURL(file);
      });
    }

    function uploadMermaidImage(file) {
      if (editor && typeof editor.uploadFile === "function") {
        return editor.uploadFile(file, "image").catch(function () {
          return readMermaidImageAsDataURL(file);
        });
      }
      return readMermaidImageAsDataURL(file);
    }

    imageInput.addEventListener("change", function (event) {
      var file = event.target.files && event.target.files[0];
      if (!file || !/^image\//.test(file.type || "")) return;
      uploadMermaidImage(file).then(function (uploaded) {
        if (!uploaded || !uploaded.url) return;
        pushUndo();
        var workspace = readWorkspaceFromBlock(wrap);
        var created = createElement("image", { x: workspace.width / 2 - 140, y: 80 }, { url: uploaded.url, name: uploaded.name || file.name });
        created.w = 280;
        created.h = 190;
        setElements(elements().concat([created]));
        setSelected([created.id]);
        setTool("select");
        editor.changed(true);
      }).catch(function () {
        alert("Image upload failed.");
      });
      event.target.value = "";
    });

    setTool("select");
    refreshHistoryButtons();
    updateOptions();
  }

  function mermaidChoice(tool, icon, label) {
    var iconNames = {
      "Rectangle": "square",
      "Rounded rectangle": "square",
      "Circle": "circle",
      "Oval": "circle",
      "Triangle": "play",
      "Diamond": "diamond",
      "Pentagon": "draw-polygon",
      "Hexagon": "draw-polygon",
      "Parallelogram": "draw-polygon",
      "Trapezoid": "draw-polygon",
      "Octagon": "draw-polygon",
      "Heart": "heart",
      "Cloud": "cloud",
      "Cylinder": "database",
      "Cube": "cube",
      "Right arrow": "arrow-right-long",
      "Left arrow": "arrow-left-long",
      "Up arrow": "arrow-up-long",
      "Down arrow": "arrow-down-long",
      "Bidirectional arrow": "arrows-left-right",
      "Callout": "comment",
      "Rounded callout": "comment-dots",
      "Thought bubble": "comments",
      "Plus": "plus",
      "Minus": "minus",
      "Multiply": "xmark",
      "Divide": "divide",
      "Equal": "equals",
      "Brackets": "code"
    };
    icon = /^[a-z0-9-]+$/i.test(String(icon || "")) ? icon : iconNames[label] || "square";
    return '<button type="button" class="rbe-mermaid-choice" data-tool="' + esc(tool) + '" title="' + esc(label) + '">' + svgIcon(icon, label) + "</button>";
  }

  function mermaidChoiceGrid(items) {
    return '<div class="rbe-mermaid-choice-grid">' + items.map(function (item) {
      return mermaidChoice(item[0], item[1], item[2]);
    }).join("") + "</div>";
  }

  function mermaidShapeMenuRow(label, icon, grid) {
    return '<div class="rbe-mermaid-menu-row"><span class="rbe-mermaid-menu-row-icon">' + svgIcon(icon, label) + '</span><span>' + esc(label) + '</span><div class="rbe-mermaid-submenu">' + grid + "</div></div>";
  }

  function mermaidShapeMenu() {
    var basics = mermaidChoiceGrid([
      ["rect", "square", "Rectangle"], ["roundedRect", "square", "Rounded rectangle"], ["circle", "circle", "Circle"], ["oval", "circle", "Oval"], ["triangle", "play", "Triangle"],
      ["diamond", "diamond", "Diamond"], ["pentagon", "draw-polygon", "Pentagon"], ["hexagon", "draw-polygon", "Hexagon"], ["parallelogram", "draw-polygon", "Parallelogram"], ["trapezoid", "draw-polygon", "Trapezoid"],
      ["octagon", "draw-polygon", "Octagon"], ["heart", "heart", "Heart"], ["cloud", "cloud", "Cloud"], ["cylinder", "database", "Cylinder"], ["cube", "cube", "Cube"]
    ]);
    var arrows = mermaidChoiceGrid([
      ["arrow", "arrow-right-long", "Right arrow"], ["leftArrow", "arrow-left-long", "Left arrow"], ["upArrow", "arrow-up-long", "Up arrow"], ["downArrow", "arrow-down-long", "Down arrow"], ["biArrow", "arrows-left-right", "Bidirectional arrow"]
    ]);
    var callouts = mermaidChoiceGrid([
      ["callout", "comment", "Callout"], ["roundCallout", "comment-dots", "Rounded callout"], ["thought", "comments", "Thought bubble"]
    ]);
    var equations = mermaidChoiceGrid([
      ["plus", "plus", "Plus"], ["minus", "minus", "Minus"], ["multiply", "xmark", "Multiply"], ["divide", "divide", "Divide"], ["equal", "equals", "Equal"], ["brackets", "code", "Brackets"]
    ]);
    return '<div class="rbe-mermaid-menu"><button type="button" class="rbe-mermaid-menu-btn" title="Shapes">' + svgIcon("shapes", "Shapes") + '</button><div class="rbe-mermaid-popover">' + mermaidShapeMenuRow("Shapes", "square", basics) + mermaidShapeMenuRow("Arrows", "arrow-right", arrows) + mermaidShapeMenuRow("Callouts", "comment", callouts) + mermaidShapeMenuRow("Equation", "plus", equations) + "</div></div>";
  }

  function mermaidLineChoice(tool, icon, label) {
    return '<button type="button" class="rbe-mermaid-line-choice" data-tool="' + esc(tool) + '"><span class="rbe-mermaid-menu-row-icon">' + svgIcon(icon, label) + '</span><span>' + esc(label) + "</span></button>";
  }

  function mermaidLineMenu() {
    return '<div class="rbe-mermaid-menu rbe-mermaid-line-menu"><button type="button" class="rbe-mermaid-menu-btn" title="Line options">' + svgIcon("caret-down", "Line options") + '</button><div class="rbe-mermaid-popover">' +
      mermaidLineChoice("line", "minus", "Line") +
      mermaidLineChoice("arrow", "arrow-right-long", "Arrow") +
      mermaidLineChoice("elbow", "share-nodes", "Elbow Connector") +
      mermaidLineChoice("curved", "code-branch", "Curved Connector") +
      mermaidLineChoice("curve", "bezier-curve", "Curve") +
      mermaidLineChoice("polyline", "draw-polygon", "Polyline") +
      mermaidLineChoice("scribble", "signature", "Scribble") +
      "</div></div>";
  }

  function mermaidShapeStylebar() {
    return '<div class="rbe-mermaid-stylebar" hidden aria-label="Shape style controls">' +
      '<input class="rbe-mermaid-option-text rbe-mermaid-hidden-control" type="text" aria-hidden="true" tabindex="-1">' +
      '<input class="rbe-mermaid-option-opacity rbe-mermaid-hidden-control" type="hidden" value="1">' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-fill-control" title="Fill color">' + svgIcon("fill-drip", "Fill color") + '<span class="rbe-mermaid-control-swatch rbe-mermaid-fill-swatch"></span><input class="rbe-mermaid-option-fill" type="color" value="#eef5ff" aria-label="Fill color"></label>' +
      '<label class="rbe-mermaid-icon-control" title="Border color">' + svgIcon("pen-nib", "Border color") + '<span class="rbe-mermaid-control-swatch rbe-mermaid-stroke-swatch"></span><input class="rbe-mermaid-option-stroke" type="color" value="#111827" aria-label="Border color"></label>' +
      '<label class="rbe-mermaid-icon-control" title="Border weight">' + svgIcon("grip-lines", "Border weight") + '<select class="rbe-mermaid-option-weight" aria-label="Border weight"><option value="1">1px</option><option value="2">2px</option><option value="3">3px</option><option value="4">4px</option><option value="8">8px</option><option value="12">12px</option><option value="16">16px</option><option value="24">24px</option></select></label>' +
      '<label class="rbe-mermaid-icon-control" title="Border dash">' + svgIcon("grip-lines-vertical", "Border dash") + '<select class="rbe-mermaid-option-dash" aria-label="Border dash"><option value="solid">Solid</option><option value="dotted">Dotted</option><option value="dashed">Dashed</option><option value="longDash">Long dash</option><option value="dashDot">Dash dot</option></select></label>' +
      '<span class="rbe-mermaid-toolbar-sep rbe-mermaid-text-control"></span>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Font family">' + svgIcon("font", "Font family") + '<select class="rbe-mermaid-option-font" aria-label="Font family"><option value="Arial">Arial</option><option value="Verdana">Verdana</option><option value="Tahoma">Tahoma</option><option value="Georgia">Georgia</option><option value="Times New Roman">Times New Roman</option><option value="Courier New">Courier New</option></select></label>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-style-action="font-size-down" title="Decrease font size">' + svgIcon("minus", "Decrease font size") + '</button>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Font size">' + svgIcon("text-height", "Font size") + '<select class="rbe-mermaid-option-size" aria-label="Font size"><option value="10">10</option><option value="12">12</option><option value="14">14</option><option value="16">16</option><option value="18">18</option><option value="20">20</option><option value="24">24</option><option value="28">28</option><option value="32">32</option><option value="40">40</option><option value="48">48</option><option value="64">64</option><option value="72">72</option></select></label>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-style-action="font-size-up" title="Increase font size">' + svgIcon("plus", "Increase font size") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-format-toggle="bold" title="Bold">' + svgIcon("bold", "Bold") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-format-toggle="italic" title="Italic">' + svgIcon("italic", "Italic") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-format-toggle="underline" title="Underline">' + svgIcon("underline", "Underline") + '</button>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Text color">' + svgIcon("font", "Text color") + '<span class="rbe-mermaid-control-swatch rbe-mermaid-text-swatch"></span><input class="rbe-mermaid-option-text-color" type="color" value="#172033" aria-label="Text color"></label>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Highlight color">' + svgIcon("highlighter", "Highlight color") + '<span class="rbe-mermaid-control-swatch rbe-mermaid-highlight-swatch"></span><input class="rbe-mermaid-option-highlight" type="color" value="#fff3b0" aria-label="Highlight color"></label>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-text-action="reset-highlight" title="Reset highlight">' + svgIcon("rotate-left", "Reset highlight") + '</button>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Text alignment">' + svgIcon("align-center", "Text alignment") + '<select class="rbe-mermaid-option-align" aria-label="Text alignment"><option value="left">Left</option><option value="center">Center</option><option value="right">Right</option><option value="justify">Justify</option></select></label>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control" title="Line spacing">' + svgIcon("arrows-up-down", "Line spacing") + '<select class="rbe-mermaid-option-line-height" aria-label="Line spacing"><option value="1">Single</option><option value="1.15">1.15</option><option value="1.5">1.5</option><option value="2">Double</option></select></label>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control rbe-mermaid-bullet-control" title="Bulleted list">' + svgIcon("list-ul", "Bulleted list") + '<select class="rbe-mermaid-option-bullet" aria-label="Bulleted list"><option value="none">None</option><option value="disc">Disc</option><option value="circle">Circle</option><option value="square">Square</option></select></label>' +
      '<label class="rbe-mermaid-icon-control rbe-mermaid-text-control rbe-mermaid-number-control" title="Numbered list">' + svgIcon("list-ol", "Numbered list") + '<select class="rbe-mermaid-option-number" aria-label="Numbered list"><option value="none">None</option><option value="decimal">1, 2, 3</option><option value="lower-alpha">a, b, c</option><option value="upper-alpha">A, B, C</option><option value="lower-roman">i, ii, iii</option><option value="upper-roman">I, II, III</option></select></label>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-text-action="outdent" title="Decrease indent">' + svgIcon("outdent", "Decrease indent") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control" data-text-action="indent" title="Increase indent">' + svgIcon("indent", "Increase indent") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control rbe-mermaid-spacing-before" data-text-action="spacing-before" title="Add space before paragraph">' + svgIcon("arrow-up", "Add space before paragraph") + '</button>' +
      '<button type="button" class="rbe-mermaid-style-btn rbe-mermaid-text-control rbe-mermaid-spacing-after" data-text-action="spacing-after" title="Add space after paragraph">' + svgIcon("arrow-down", "Add space after paragraph") + '</button>' +
      "</div>";
  }

  function mermaidDesignerToolbar() {
    return '<div class="rbe-mermaid-toolbar" role="toolbar" aria-label="Drawing tools">' +
      '<button type="button" class="rbe-mermaid-icon-btn" data-diagram-action="undo" title="Undo">' + svgIcon("rotate-left", "Undo") + '</button>' +
      '<button type="button" class="rbe-mermaid-icon-btn" data-diagram-action="redo" title="Redo">' + svgIcon("rotate-right", "Redo") + '</button>' +
      '<span class="rbe-mermaid-toolbar-sep"></span>' +
      '<button type="button" class="rbe-mermaid-tool" data-tool="select" title="Select">' + svgIcon("arrow-pointer", "Select") + '</button>' +
      mermaidShapeMenu() +
      '<button type="button" class="rbe-mermaid-tool" data-tool="arrow" title="Arrow">' + svgIcon("arrow-right-long", "Arrow") + '</button>' +
      mermaidLineMenu() +
      '<button type="button" class="rbe-mermaid-tool" data-tool="text" title="Text box">' + svgIcon("font", "Text box") + '</button>' +
      '<button type="button" class="rbe-mermaid-icon-btn" data-diagram-action="image" title="Insert image">' + svgIcon("image", "Insert image") + '</button>' +
      mermaidShapeStylebar() +
      "</div>";
  }

  function refreshMermaidCardPreview(card) {
    var target = card.querySelector(".rbe-mermaid-card-preview");
    if (!target) return;
    var elements = [];
    try {
      elements = JSON.parse((card.querySelector(".rbe-mermaid-diagram-json") || {}).value || "[]").map(normalizeDiagramElement);
    } catch (error) {}
    if (!elements.length) {
      target.innerHTML = '<span class="rbe-mermaid-card-empty">Open the designer to draw a diagram.</span>';
      return;
    }
    target.innerHTML = '<div class="rbe-output-mermaid-diagram">' + diagramSvg(elements, "", readWorkspaceFromBlock(card), null) + "</div>";
  }

  function mermaidRulerMarkup() {
    var top = "";
    var side = "";
    for (var i = 1; i <= 10; i += 1) top += '<span style="left:' + (i * 100) + 'px">' + i + "</span>";
    for (var j = 1; j <= 7; j += 1) side += '<span style="top:' + (j * 100) + 'px">' + j + "</span>";
    return '<div class="rbe-mermaid-stage-shell"><div class="rbe-mermaid-ruler-corner"></div><div class="rbe-mermaid-top-ruler">' + top + '</div><div class="rbe-mermaid-side-ruler">' + side + '</div><div class="rbe-mermaid-stage"></div></div>';
  }

  function openMermaidDesignerModal(editor, card) {
    var existing = document.querySelector(".rbe-mermaid-modal");
    if (existing) {
      existing.remove();
      document.body.classList.remove("rbe-mermaid-modal-open");
    }
    var modal = document.createElement("div");
    modal.className = "rbe-mermaid-modal";
    modal.innerHTML =
      '<div class="rbe-mermaid-dialog" role="dialog" aria-modal="true" aria-label="Drawing">' +
      '<div class="rbe-mermaid-modal-head"><h2 class="rbe-mermaid-modal-title">Drawing</h2><button type="button" class="rbe-mermaid-close" data-modal-action="close" title="Close">' + svgIcon("xmark", "Close") + '</button></div>' +
      '<div class="rbe-mermaid-modal-body"><div class="rbe-mermaid-block" tabindex="0">' +
      '<input type="hidden" class="rbe-mermaid-alignment"><input type="hidden" class="rbe-mermaid-diagram-json"><input class="rbe-mermaid-image-input" type="file" accept="image/*" hidden><textarea class="rbe-mermaid-code" hidden></textarea>' +
      mermaidDesignerToolbar() +
      '<input class="rbe-mermaid-workspace-w" type="hidden"><input class="rbe-mermaid-workspace-h" type="hidden"><input class="rbe-mermaid-zoom" type="hidden">' + mermaidRulerMarkup() +
      '</div></div>' +
      '<div class="rbe-mermaid-modal-foot"><button type="button" class="rbe-mermaid-modal-cancel" data-modal-action="close">Cancel</button><button type="button" class="rbe-mermaid-modal-save" data-modal-action="save">Save drawing</button></div>' +
      "</div>";
    function closeModal() {
      document.body.classList.remove("rbe-mermaid-modal-open");
      modal.remove();
    }
    document.body.classList.add("rbe-mermaid-modal-open");
    document.body.appendChild(modal);
    var designer = modal.querySelector(".rbe-mermaid-block");
    [".rbe-mermaid-alignment", ".rbe-mermaid-diagram-json", ".rbe-mermaid-code", ".rbe-mermaid-workspace-w", ".rbe-mermaid-workspace-h", ".rbe-mermaid-zoom"].forEach(function (selector) {
      var source = card.querySelector(selector);
      var target = designer.querySelector(selector);
      if (source && target) target.value = source.value || "";
    });
    renderDiagramCanvas(designer);
    bindMermaidDesigner(editor, designer);
    designer.focus();
    modal.addEventListener("click", function (event) {
      var actionButton = event.target.closest("[data-modal-action]");
      var action = actionButton ? actionButton.dataset.modalAction : "";
      if (!action) return;
      event.preventDefault();
      if (action === "save") {
        var textEditor = designer.querySelector(".rbe-mermaid-text-editor");
        if (textEditor && textEditor.dataset.editId) {
          var editId = textEditor.dataset.editId;
          var editedText = textEditor.value || textEditor.textContent || "";
          var current = [];
          try { current = JSON.parse((designer.querySelector(".rbe-mermaid-diagram-json") || {}).value || "[]"); } catch (error) {}
          designer.querySelector(".rbe-mermaid-diagram-json").value = JSON.stringify(current.map(function (elm) {
            elm = normalizeDiagramElement(elm);
            if (elm.id === editId) elm.text = editedText.trim();
            return elm;
          }));
          textEditor.remove();
        }
        [".rbe-mermaid-alignment", ".rbe-mermaid-diagram-json", ".rbe-mermaid-code", ".rbe-mermaid-workspace-w", ".rbe-mermaid-workspace-h", ".rbe-mermaid-zoom"].forEach(function (selector) {
          var source = designer.querySelector(selector);
          var target = card.querySelector(selector);
          if (source && target) target.value = source.value || "";
        });
        refreshMermaidCardPreview(card);
        editor.changed(true);
      }
      closeModal();
    });
  }

  function hydrateAdvancedOutput(root) {
    root = root || document;
    Array.prototype.slice.call(root.querySelectorAll(".rbe-output-latex")).forEach(function (node) {
      var code = node.dataset.latex || node.textContent || "";
      var display = node.dataset.display !== "false";
      if (node.dataset.renderedLatex === "true" && node.dataset.lastLatex === code && node.dataset.lastDisplay === String(display)) return;
      node.dataset.renderedLatex = "true";
      node.dataset.lastLatex = code;
      node.dataset.lastDisplay = String(display);
      renderLatexPreview(node, code, display);
    });
    Array.prototype.slice.call(root.querySelectorAll(".rbe-output-mermaid")).forEach(function (node) {
      var code = node.dataset.mermaid || node.textContent || "";
      if (node.dataset.renderedMermaid === "true" && node.dataset.lastMermaid === code) return;
      node.dataset.renderedMermaid = "true";
      node.dataset.lastMermaid = code;
      renderMermaidPreview(node, code);
    });
  }

  function bootOutputHydration() {
    var run = function () { hydrateAdvancedOutput(document); };
    if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", run, { once: true });
    else setTimeout(run, 0);
    if (!document.body) return;
    var timer = 0;
    new MutationObserver(function () {
      clearTimeout(timer);
      timer = setTimeout(run, 60);
    }).observe(document.body, { childList: true, subtree: true });
  }

  function bindChange(editor, block, update) {
    block.addEventListener("input", function () {
      update();
      editor.changed();
    });
    block.addEventListener("change", function () {
      update();
      editor.changed();
    });
  }

  function field(className, value) {
    return "." + className + " => " + value;
  }

  function chartCaptionAlignment(value) {
    value = String(value || "").toLowerCase();
    return value === "left" || value === "right" ? value : "center";
  }

  function plainTextFromHTML(value) {
    var template = document.createElement("template");
    template.innerHTML = sanitize(value || "");
    return template.content.textContent || "";
  }

  BlockWriteAI.registerTool("mermaid", {
    label: "Mermaid",
    hint: "Visual diagrams and flowcharts",
    icon: "diagram-project",
    premiumFeature: "mermaid",
    defaultData: { code: "", alignment: "center", openOnInsert: true, diagram: { elements: [], workspace: defaultMermaidWorkspace() } },
    render: function (body, data) {
      injectStyles();
      var editor = this;
      var wrap = el("div", "rbe-plugin-card rbe-mermaid-block rbe-mermaid-card");
      wrap.tabIndex = 0;
      var alignment = data.alignment === "left" || data.alignment === "right" ? data.alignment : "center";
      var workspace = normalizeDiagramWorkspace(data);
      wrap.innerHTML =
        '<input type="hidden" class="rbe-mermaid-alignment" value="' + esc(alignment) + '">' +
        '<input type="hidden" class="rbe-mermaid-diagram-json">' +
        '<textarea class="rbe-mermaid-code" hidden></textarea>' +
        '<input class="rbe-mermaid-workspace-w" type="hidden" value="' + esc(workspace.width) + '">' +
        '<input class="rbe-mermaid-workspace-h" type="hidden" value="' + esc(workspace.height) + '">' +
        '<input class="rbe-mermaid-zoom" type="hidden" value="' + esc(workspace.zoom) + '">' +
        '<div class="rbe-mermaid-card-head"><span class="rbe-mermaid-card-title">Mermaid drawing</span><button type="button" class="rbe-mermaid-edit-btn" title="Edit drawing"' + (editor.readOnly ? " hidden" : "") + '>' + svgIcon("pen-to-square", "Edit drawing") + '</button></div>' +
        '<div class="rbe-mermaid-card-preview"></div>';
      body.appendChild(wrap);
      var input = wrap.querySelector(".rbe-mermaid-code");
      input.value = data.code || "";
      wrap.querySelector(".rbe-mermaid-diagram-json").value = JSON.stringify(diagramElements(data));
      refreshMermaidCardPreview(wrap);
      wrap.addEventListener("click", function (event) {
        if (!event.target.closest(".rbe-mermaid-edit-btn")) return;
        event.preventDefault();
        if (!editor.readOnly) openMermaidDesignerModal(editor, wrap);
      });
      if (!editor.readOnly && data.openOnInsert === true) {
        setTimeout(function () { openMermaidDesignerModal(editor, wrap); }, 80);
      }
    },
    serialize: function (block) {
      var diagram = [];
      try {
        diagram = JSON.parse((block.querySelector(".rbe-mermaid-diagram-json") || {}).value || "[]");
      } catch (error) {}
      return {
        code: (block.querySelector(".rbe-mermaid-code") || {}).value || "",
        alignment: (block.querySelector(".rbe-mermaid-alignment") || {}).value || "center",
        openOnInsert: false,
        diagram: { elements: diagram.map(normalizeDiagramElement), workspace: readWorkspaceFromBlock(block) }
      };
    },
    toHTML: function (data) {
      var alignment = data.alignment === "left" || data.alignment === "right" ? data.alignment : "center";
      var elements = diagramElements(data);
      return '<figure class="rbe-output-mermaid-wrap rbe-output-align-' + esc(alignment) + '"><div class="rbe-output-mermaid-diagram">' + diagramSvg(elements, "", normalizeDiagramWorkspace(data), null) + "</div></figure>";
    },
    toMarkdown: function (data) {
      return "```mermaid\n" + (data.code || "") + "\n```";
    }
  });

  injectStyles();
  bootOutputHydration();
})(typeof window !== "undefined" ? window : this);

