dsh-md-plus 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # 更新日志
2
2
 
3
- ## 0.4.3 —— 未发布
3
+ ## 0.4.5 —— 2026-11-03
4
+
5
+ - 修复保存设置时无条件重绘所有 Mermaid 图、重置所有折叠状态的问题:只对真正变化的设置项执行重绘或重新测量,用户手动展开的长代码块和长表格不会被折叠回去。
6
+ - 优化长会话性能:流式输出期间跳过历史代码块的重复装饰;缓存设置读取,折叠扫描每轮只取一次阈值;同一轮扫描复用 Mermaid 图类型判断。
7
+ - 降低长会话内存:高亮去重键从 DOM 属性改为 WeakMap,避免完整源码复制进页面属性;定期清理已脱离文档的插件按钮。
8
+ - 工程化:`npm run check` 先构建再测试;补声明 `@shikijs/langs` 直接依赖;`publishConfig` 固定 npmjs registry;预览和展示脚本从 `package.json` 读取版本。
9
+ - 新增维护者发版脚本:自动修改 CHANGELOG 发布日期、提交、打 tag、推送代码和 tag,支持 `npm run release:dry` 预览。
10
+ - 修复 Mermaid「下载 PNG」不可用:Mermaid 改用 SVG 文本标签,避免 `foreignObject` 污染 canvas;导出失败时按钮会给出提示;新增 `npm run smoke` 真实浏览器验证。
11
+ - 修复折叠表格的 resize 监听泄漏和侧栏宽度变化时按钮偏位:表格卸载时自动清理监听,按钮位置改用 `ResizeObserver` 跟随。
12
+ - 修复合法 Mermaid 图的节点标签包含「Syntax error in text」时被误判为渲染失败。
13
+ - 修复表格复制按钮的反馈文案显示到另一颗按钮、剪贴板 API 被拒时没有 textarea 兜底;设置面板和图片预览打开时锁定背景滚动并约束键盘焦点;离开 Markdown 页面时移除设置齿轮。
14
+ - 修复 localStorage 读成功但写入失败时 Mermaid 配色只在存储里变化、当前会话不生效的问题。
15
+ - README 预览图改用 GitHub Pages 绝对地址,npm 包页面也能正常显示。
16
+ - 测试补到 85 条,补强设置保存不重置折叠、只改字号不重绘 Mermaid、流式输出不插按钮、源码不复制进属性、剪贴板降级、弹层滚动和主题存储等回归用例。
17
+
18
+ ## 0.4.4 —— 2026-11-01
19
+
20
+ - 修复表格折叠按钮在低阈值和展开/收起后漂移、消失的问题:补齐表格折叠高度规则、重置滚动位置,并给按钮阴影留出空间。
21
+
22
+ ## 0.4.3 —— 2026-10-30
4
23
 
5
24
  - 修复补高亮语言映射:`hbs` / `jade` / `tscn` / `tres` 分别使用 handlebars / pug / gdresource 语法着色。
6
25
  - 修复 Mermaid 12.1 在占位标签兜底路径下的图种识别:补充 `radar-beta`、`treemap-beta`、`venn-beta`、`ishikawa-beta`、`wardley-beta`、`cynefin-beta`、`treeView-beta`、`flowchart-elk` 等,并去掉无效裸关键字的误判。
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  给 DeepSeek Harness Web / Desktop 的 Markdown 阅读增强插件:重做代码块卡片、给 DSH 不认识的语言补语法高亮、自己渲染 mermaid 图形、重做表格样式并支持复制、图片点击放大,以及一个调整显示参数的设置面板。
4
4
 
5
- [![dsh-md-plus 显示效果预览](<docs/preview.png>)](https://josephhy.github.io/dsh-md-plus/docs/showcase/)
5
+ [![dsh-md-plus 显示效果预览](https://josephhy.github.io/dsh-md-plus/docs/preview.png)](https://josephhy.github.io/dsh-md-plus/docs/showcase/)
6
6
 
7
7
  ## 功能
8
8
 
@@ -27,9 +27,12 @@ dsh plugin --profile desktop remove dsh-md-plus
27
27
  ```powershell
28
28
  npm install # 顺带跑 prepare → build
29
29
  npm run build # 产出 lib/ 下四个文件
30
- npm run check # 语法检查 + 78 条测试(先 build 再跑,check 不含 build)
30
+ npm run check # 构建 + 语法检查 + 85 条测试(check 会先 build)
31
+ npm run release:dry # 维护者发版:先看 CHANGELOG 日期 + 提交 + tag + push 计划
32
+ npm run release # 维护者发版:改 CHANGELOG 日期 + 提交 + 打 tag + 推送(tag 会触发 GitHub Actions 自动发 npm)
31
33
  npm run preview # 生成 preview.html(含真渲出来的 mermaid 图)
32
34
  npm run shot # 用 headless Chrome 把 preview.html 截成 docs/preview.png
35
+ npm run smoke # 用本机 Chrome 验证 Mermaid 渲染和 PNG 导出(Chrome 路径可用 CHROME_PATH 覆盖)
33
36
  ```
34
37
 
35
38
  `npm run preview` / `scripts/showcase.mjs` 需要读取 DSH 安装目录里的主题和前端资源;如果本机 DSH 是 `app.asar` 包,请先解包到目录,并把 `DSH_APP_DIR` 指向该目录。
package/lib/client.js CHANGED
@@ -65,6 +65,7 @@ window.__ModuleLoader__.load({
65
65
  fit: "\u9002\u5E94\u6574\u56FE",
66
66
  downloadSvg: "\u4E0B\u8F7D SVG",
67
67
  downloadPng: "\u4E0B\u8F7D PNG",
68
+ exportFailed: "\u5BFC\u51FA\u5931\u8D25\uFF0C\u8BF7\u6539\u7528 SVG",
68
69
  close: "\u5173\u95ED",
69
70
  tableCsv: "CSV",
70
71
  tableMd: "Markdown",
@@ -118,6 +119,7 @@ window.__ModuleLoader__.load({
118
119
  fit: "Fit",
119
120
  downloadSvg: "Download SVG",
120
121
  downloadPng: "Download PNG",
122
+ exportFailed: "Export failed; try SVG instead",
121
123
  close: "Close",
122
124
  tableCsv: "CSV",
123
125
  tableMd: "Markdown",
@@ -154,7 +156,6 @@ window.__ModuleLoader__.load({
154
156
  }
155
157
  var MODAL_CLASS = "md-plus-mmd-modal";
156
158
  var DONE_ATTR = "data-md-plus";
157
- var KEY_ATTR = "data-md-plus-key";
158
159
  var WRAP_ATTR = "data-md-plus-wrap";
159
160
  var MMD_ATTR = "data-md-plus-mmd";
160
161
  var FOLD_ATTR = "data-md-plus-fold";
@@ -180,7 +181,10 @@ window.__ModuleLoader__.load({
180
181
  var DEBOUNCE_MS = 160;
181
182
  var memorySettings = null;
182
183
  var memoryTheme = null;
184
+ var settingsCache = null;
185
+ var themeCache = null;
183
186
  function readSettings() {
187
+ if (settingsCache !== null) return { ...settingsCache };
184
188
  var settings = { ...DEFAULT_SETTINGS };
185
189
  try {
186
190
  var raw = window.localStorage.getItem(SETTINGS_KEY);
@@ -198,12 +202,14 @@ window.__ModuleLoader__.load({
198
202
  }
199
203
  memorySettings = { ...settings };
200
204
  } catch {
201
- if (memorySettings !== null) return { ...DEFAULT_SETTINGS, ...memorySettings };
205
+ if (memorySettings !== null) settings = { ...DEFAULT_SETTINGS, ...memorySettings };
202
206
  }
203
- return settings;
207
+ settingsCache = { ...settings };
208
+ return { ...settingsCache };
204
209
  }
205
210
  function saveSettings(next) {
206
211
  memorySettings = { ...next };
212
+ settingsCache = { ...next };
207
213
  try {
208
214
  window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(next));
209
215
  } catch {
@@ -451,7 +457,7 @@ window.__ModuleLoader__.load({
451
457
  // 用 clip 而不是 hidden:hidden 会建立隐形滚动容器,鼠标在折叠内容上滚轮会被它吞掉。
452
458
  "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{max-height:var(--md-plus-fold-max-height);overflow:clip}',
453
459
  "." + FOLD_BTN_CLASS + "{display:block;white-space:nowrap;margin:8px auto 0;padding:4px 12px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 22%));border-radius:999px;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-primary);font:12px/18px var(--dsw-font-family-sans,system-ui,sans-serif);cursor:pointer;box-shadow:0 2px 8px rgb(0 0 0 / 12%);z-index:2}",
454
- "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"] .' + FOLD_BTN_CLASS + "{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);margin:0}",
460
+ "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"] .' + FOLD_BTN_CLASS + "{position:absolute;left:50%;bottom:12px;transform:translateX(-50%);margin:0}",
455
461
  // ── 图片点击放大 ────────────────────────────────────────────────
456
462
  '[class*="_markdown_"] img{cursor:zoom-in}',
457
463
  "." + IMG_MODAL_CLASS + "{position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:calc(var(--dsh-windows-titlebar-height,0px) + 16px) 24px 24px;background:rgb(0 0 0 / 72%)}",
@@ -529,11 +535,18 @@ window.__ModuleLoader__.load({
529
535
  TABLE + ".md-table-wide > table{width:100%;max-width:none;min-width:max-content}",
530
536
  // 折叠态保留横向滚动,但纵向必须 clip;横向滚动容器只有在
531
537
  // overscroll-behavior:auto 时才会把纵向滚轮交还给页面。
532
- TABLE + "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{overflow-x:auto;overflow-y:clip}'
538
+ // 这里同时写明 min/max-height:基础表格规则的 max-height 特异性更高,不补会压过设置值;
539
+ // 最小高度保证极低阈值下「展开」按钮仍完整可见。
540
+ TABLE + "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{min-height:48px;max-height:var(--md-plus-fold-max-height);overflow-x:auto;overflow-y:clip}'
533
541
  ].join("\n");
534
542
  var scripts = /* @__PURE__ */ new Map();
535
543
  var pending = /* @__PURE__ */ new Set();
536
544
  var foldSyncs = /* @__PURE__ */ new WeakMap();
545
+ var foldTargets = /* @__PURE__ */ new Set();
546
+ var foldResizeObserver = null;
547
+ var foldResizeHandler = null;
548
+ var diagramKindCache = /* @__PURE__ */ new WeakMap();
549
+ var cacheKeys = /* @__PURE__ */ new WeakMap();
537
550
  var timer = null;
538
551
  var rescanQueued = false;
539
552
  var injected = /* @__PURE__ */ new Set();
@@ -666,7 +679,7 @@ window.__ModuleLoader__.load({
666
679
  var single = MMD_SINGLE.exec(value);
667
680
  return single === null ? null : single[1];
668
681
  }
669
- function diagramKind(block) {
682
+ function computeDiagramKind(block) {
670
683
  var lang = readLang(block);
671
684
  if (MMD_LANGS.has(lang)) return "diagram";
672
685
  if (lang !== "") return null;
@@ -674,12 +687,22 @@ window.__ModuleLoader__.load({
674
687
  if (pre === null) return null;
675
688
  return sniffDiagramType(pre.textContent ?? "") === null ? null : "diagram";
676
689
  }
690
+ function diagramKind(block) {
691
+ if (diagramKindCache.has(block)) return diagramKindCache.get(block);
692
+ var kind = computeDiagramKind(block);
693
+ diagramKindCache.set(block, kind);
694
+ return kind;
695
+ }
677
696
  function isOurs(node) {
678
697
  var element = node?.nodeType === 1 ? node : node?.parentElement;
679
698
  return element?.closest?.(
680
- "." + HOST_CLASS + ", ." + BTN_CLASS + ", ." + MMD_CLASS + ", ." + FOLD_BTN_CLASS + ", ." + TABLE_TOOLS_CLASS + ", ." + IMG_MODAL_CLASS + ", ." + SETTINGS_BTN_CLASS + ", ." + SETTINGS_MODAL_CLASS
699
+ "." + HOST_CLASS + ", ." + BTN_CLASS + ", ." + MMD_CLASS + ", ." + FOLD_BTN_CLASS + ", ." + TABLE_TOOLS_CLASS + ", ." + IMG_MODAL_CLASS + ", ." + MODAL_CLASS + ", ." + SETTINGS_BTN_CLASS + ", ." + SETTINGS_MODAL_CLASS
681
700
  ) != null;
682
701
  }
702
+ function closestStreaming(node) {
703
+ var element = node?.nodeType === 1 ? node : node?.parentElement;
704
+ return element?.closest?.("[data-streaming]") ?? null;
705
+ }
683
706
  function schedule(block) {
684
707
  if (disposed) return;
685
708
  if (block !== void 0) pending.add(block);
@@ -690,6 +713,11 @@ window.__ModuleLoader__.load({
690
713
  function flush() {
691
714
  timer = null;
692
715
  if (disposed) return;
716
+ for (const node of injected) {
717
+ if (!node.isConnected) injected.delete(node);
718
+ }
719
+ cleanupFoldTargets();
720
+ diagramKindCache = /* @__PURE__ */ new WeakMap();
693
721
  if (rescanQueued) {
694
722
  rescanQueued = false;
695
723
  for (const block of document.querySelectorAll(BLOCK)) pending.add(block);
@@ -697,6 +725,7 @@ window.__ModuleLoader__.load({
697
725
  var batch = Array.from(pending);
698
726
  pending.clear();
699
727
  for (const block of batch) {
728
+ if (closestStreaming(block) !== null) continue;
700
729
  decorate(block);
701
730
  void enhance(block);
702
731
  }
@@ -709,6 +738,7 @@ window.__ModuleLoader__.load({
709
738
  redrawDiagrams();
710
739
  return;
711
740
  }
741
+ if (closestStreaming(record.target) !== null) continue;
712
742
  if (isOurs(record.target)) continue;
713
743
  var added = record.addedNodes;
714
744
  var oursOnly = added.length > 0;
@@ -725,7 +755,7 @@ window.__ModuleLoader__.load({
725
755
  function redrawDiagrams() {
726
756
  for (const block of document.querySelectorAll("[" + MMD_ATTR + "]")) {
727
757
  if (block.getAttribute(MMD_ATTR) === "failed") continue;
728
- block.removeAttribute(KEY_ATTR);
758
+ cacheKeys.delete(block);
729
759
  pending.add(block);
730
760
  }
731
761
  schedule();
@@ -777,7 +807,7 @@ window.__ModuleLoader__.load({
777
807
  titleKey: "retry",
778
808
  ariaKey: "retryAria",
779
809
  run: (block) => {
780
- block.removeAttribute(KEY_ATTR);
810
+ cacheKeys.delete(block);
781
811
  block.removeAttribute(MMD_ATTR);
782
812
  block.querySelector("." + MMD_CLASS + "-error")?.remove();
783
813
  void enhance(block);
@@ -830,13 +860,13 @@ window.__ModuleLoader__.load({
830
860
  if (host === null) return false;
831
861
  if (content.querySelector("pre.shiki:not(.md-plus-pre)") === null) return false;
832
862
  host.remove();
833
- block.removeAttribute(KEY_ATTR);
863
+ cacheKeys.delete(block);
834
864
  block.removeAttribute(DONE_ATTR);
835
865
  return true;
836
866
  }
837
867
  async function enhance(block) {
838
868
  if (!block.isConnected) return;
839
- if (block.closest("[data-streaming]") !== null) return;
869
+ if (closestStreaming(block) !== null) return;
840
870
  var content = block.querySelector(CONTENT);
841
871
  if (content === null) return;
842
872
  if (releaseTakenOver(block, content)) return;
@@ -856,7 +886,7 @@ window.__ModuleLoader__.load({
856
886
  var code = pre.textContent ?? "";
857
887
  if (code.trim() === "") return;
858
888
  var key = lang + "\0" + code;
859
- if (block.getAttribute(KEY_ATTR) === key) return;
889
+ if (cacheKeys.get(block) === key) return;
860
890
  var html;
861
891
  try {
862
892
  html = await api.highlight(code, lang);
@@ -881,21 +911,27 @@ window.__ModuleLoader__.load({
881
911
  content.querySelector("." + HOST_CLASS)?.remove();
882
912
  resetFold(content);
883
913
  pre.after(host);
884
- block.setAttribute(KEY_ATTR, key);
914
+ cacheKeys.set(block, key);
885
915
  block.setAttribute(DONE_ATTR, "done");
886
916
  scheduleFold(content, foldLimit("code"));
887
917
  }
888
918
  function getMermaidTheme() {
919
+ if (themeCache !== null) return themeCache;
889
920
  try {
890
921
  var saved = window.localStorage.getItem(THEME_KEY);
891
922
  if (saved !== null && THEME_ORDER.indexOf(saved) !== -1) {
892
923
  memoryTheme = saved;
924
+ themeCache = saved;
893
925
  return saved;
894
926
  }
895
927
  memoryTheme = null;
896
928
  } catch {
897
- if (memoryTheme !== null) return memoryTheme;
929
+ if (memoryTheme !== null) {
930
+ themeCache = memoryTheme;
931
+ return memoryTheme;
932
+ }
898
933
  }
934
+ themeCache = "blue";
899
935
  return "blue";
900
936
  }
901
937
  function themeLabel(name) {
@@ -913,6 +949,7 @@ window.__ModuleLoader__.load({
913
949
  var index = THEME_ORDER.indexOf(current);
914
950
  var next = THEME_ORDER[(index + 1) % THEME_ORDER.length];
915
951
  memoryTheme = next;
952
+ themeCache = next;
916
953
  try {
917
954
  window.localStorage.setItem(THEME_KEY, next);
918
955
  } catch {
@@ -924,7 +961,7 @@ window.__ModuleLoader__.load({
924
961
  var code = (pre.textContent ?? "").trim();
925
962
  if (code === "") return;
926
963
  var key = "mmd\0" + code;
927
- if (block.getAttribute(KEY_ATTR) === key) return;
964
+ if (cacheKeys.get(block) === key) return;
928
965
  var api = await loadScript(MMD_URL, MMD_GLOBAL);
929
966
  if (disposed || api === null) return;
930
967
  if (!pre.isConnected) return;
@@ -957,7 +994,7 @@ window.__ModuleLoader__.load({
957
994
  if (viewport !== null) bindViewport(block, viewport);
958
995
  pre.before(host);
959
996
  content.querySelector("." + MMD_CLASS + "-error")?.remove();
960
- block.setAttribute(KEY_ATTR, key);
997
+ cacheKeys.set(block, key);
961
998
  var view = block.getAttribute(MMD_ATTR);
962
999
  if (view !== "code" && view !== "diagram") block.setAttribute(MMD_ATTR, readSettings().diagramView);
963
1000
  zooms.delete(block);
@@ -1070,14 +1107,65 @@ window.__ModuleLoader__.load({
1070
1107
  var sync = foldSyncs.get(target);
1071
1108
  if (sync !== void 0) {
1072
1109
  target.removeEventListener("scroll", sync);
1073
- window.removeEventListener("resize", sync);
1074
1110
  foldSyncs.delete(target);
1075
1111
  }
1112
+ foldTargets.delete(target);
1113
+ if (foldTargets.size === 0) {
1114
+ if (foldResizeObserver !== null) {
1115
+ foldResizeObserver.disconnect();
1116
+ foldResizeObserver = null;
1117
+ }
1118
+ if (foldResizeHandler !== null) {
1119
+ window.removeEventListener("resize", foldResizeHandler);
1120
+ foldResizeHandler = null;
1121
+ }
1122
+ } else if (foldResizeObserver !== null) {
1123
+ foldResizeObserver.unobserve(target);
1124
+ }
1076
1125
  target.removeAttribute(FOLD_ATTR);
1077
1126
  target.classList.remove(FOLD_CLASS);
1078
1127
  target.style.removeProperty("--md-plus-fold-max-height");
1079
1128
  target.querySelector("." + FOLD_BTN_CLASS)?.remove();
1080
1129
  }
1130
+ function watchFoldTarget(target, sync) {
1131
+ foldSyncs.set(target, sync);
1132
+ foldTargets.add(target);
1133
+ if (typeof window.ResizeObserver === "function") {
1134
+ if (foldResizeObserver === null) {
1135
+ foldResizeObserver = new window.ResizeObserver((entries) => {
1136
+ for (const entry of entries) {
1137
+ var entryTarget = entry.target;
1138
+ var entrySync = foldSyncs.get(entryTarget);
1139
+ if (entrySync === void 0) continue;
1140
+ if (!entryTarget.isConnected) {
1141
+ resetFold(entryTarget);
1142
+ continue;
1143
+ }
1144
+ entrySync();
1145
+ }
1146
+ });
1147
+ }
1148
+ foldResizeObserver.observe(target);
1149
+ return;
1150
+ }
1151
+ if (foldResizeHandler === null) {
1152
+ foldResizeHandler = () => {
1153
+ for (const entryTarget of foldTargets) {
1154
+ if (!entryTarget.isConnected) {
1155
+ resetFold(entryTarget);
1156
+ continue;
1157
+ }
1158
+ foldSyncs.get(entryTarget)?.();
1159
+ }
1160
+ };
1161
+ window.addEventListener("resize", foldResizeHandler);
1162
+ }
1163
+ }
1164
+ function cleanupFoldTargets() {
1165
+ for (const target of foldTargets) {
1166
+ if (!target.isConnected) resetFold(target);
1167
+ }
1168
+ }
1081
1169
  function scheduleFold(target, limit) {
1082
1170
  if (target === null) return;
1083
1171
  if (!(limit > 0)) {
@@ -1092,7 +1180,7 @@ window.__ModuleLoader__.load({
1092
1180
  if (target.getAttribute(FOLD_ATTR) !== null) return;
1093
1181
  var schedule2 = window.requestAnimationFrame ?? ((cb) => window.setTimeout(cb, 0));
1094
1182
  schedule2(() => {
1095
- if (!target.isConnected || target.getAttribute(FOLD_ATTR) !== null) return;
1183
+ if (disposed || !target.isConnected || target.getAttribute(FOLD_ATTR) !== null) return;
1096
1184
  if (target.scrollHeight <= limit) {
1097
1185
  target.setAttribute(FOLD_ATTR, "none");
1098
1186
  return;
@@ -1100,6 +1188,7 @@ window.__ModuleLoader__.load({
1100
1188
  target.setAttribute(FOLD_ATTR, "on");
1101
1189
  target.classList.add(FOLD_CLASS);
1102
1190
  target.style.setProperty("--md-plus-fold-max-height", limit + "px");
1191
+ if (target.hasAttribute(TABLE_DONE_ATTR)) target.scrollTop = 0;
1103
1192
  var button = document.createElement("button");
1104
1193
  button.type = "button";
1105
1194
  button.className = FOLD_BTN_CLASS;
@@ -1109,13 +1198,13 @@ window.__ModuleLoader__.load({
1109
1198
  button.style.left = target.scrollLeft + target.clientWidth / 2 + "px";
1110
1199
  } : null;
1111
1200
  if (sync !== null) {
1112
- foldSyncs.set(target, sync);
1113
1201
  target.addEventListener("scroll", sync, { passive: true });
1114
- window.addEventListener("resize", sync);
1202
+ watchFoldTarget(target, sync);
1115
1203
  }
1116
1204
  button.addEventListener("click", () => {
1117
1205
  var folded = target.getAttribute(FOLD_ATTR) === "on";
1118
1206
  target.setAttribute(FOLD_ATTR, folded ? "off" : "on");
1207
+ if (target.hasAttribute(TABLE_DONE_ATTR)) target.scrollTop = 0;
1119
1208
  button.textContent = folded ? t("foldClose") : t("foldOpen");
1120
1209
  button.setAttribute("aria-expanded", folded ? "true" : "false");
1121
1210
  sync?.();
@@ -1125,15 +1214,17 @@ window.__ModuleLoader__.load({
1125
1214
  });
1126
1215
  }
1127
1216
  function scanFolds() {
1217
+ var codeLimit = foldLimit("code");
1218
+ var tableLimit = foldLimit("table");
1128
1219
  for (const block of document.querySelectorAll(BLOCK)) {
1129
- if (block.closest("[data-streaming]") !== null) continue;
1220
+ if (closestStreaming(block) !== null) continue;
1130
1221
  if (diagramKind(block) !== null) continue;
1131
- scheduleFold(block.querySelector(CONTENT), foldLimit("code"));
1222
+ scheduleFold(block.querySelector(CONTENT), codeLimit);
1132
1223
  }
1133
1224
  for (const table of document.querySelectorAll(TABLE)) {
1134
- if (table.closest("[data-streaming]") !== null) continue;
1225
+ if (closestStreaming(table) !== null) continue;
1135
1226
  decorateTable(table);
1136
- scheduleFold(table, foldLimit("table"));
1227
+ scheduleFold(table, tableLimit);
1137
1228
  }
1138
1229
  }
1139
1230
  function cellText(cell) {
@@ -1157,8 +1248,11 @@ window.__ModuleLoader__.load({
1157
1248
  }
1158
1249
  async function copyText(text) {
1159
1250
  if (window.navigator.clipboard !== void 0 && typeof window.navigator.clipboard.writeText === "function") {
1160
- await window.navigator.clipboard.writeText(text);
1161
- return true;
1251
+ try {
1252
+ await window.navigator.clipboard.writeText(text);
1253
+ return true;
1254
+ } catch {
1255
+ }
1162
1256
  }
1163
1257
  var area = document.createElement("textarea");
1164
1258
  area.value = text;
@@ -1197,7 +1291,7 @@ window.__ModuleLoader__.load({
1197
1291
  ["csv", t("tableCsv"), "copyCsvTitle", tableToCsv],
1198
1292
  ["md", t("tableMd"), "copyMdTitle", tableToMarkdown]
1199
1293
  ]) {
1200
- var button = document.createElement("button");
1294
+ const button = document.createElement("button");
1201
1295
  button.type = "button";
1202
1296
  button.textContent = label;
1203
1297
  button.title = t(titleKey);
@@ -1216,6 +1310,48 @@ window.__ModuleLoader__.load({
1216
1310
  tools.appendChild(group);
1217
1311
  dataTable.insertBefore(tools, dataTable.firstChild);
1218
1312
  }
1313
+ var scrollLocks = 0;
1314
+ var previousRootOverflow = "";
1315
+ function lockPageScroll() {
1316
+ if (scrollLocks === 0) {
1317
+ previousRootOverflow = document.documentElement.style.overflow;
1318
+ document.documentElement.style.overflow = "hidden";
1319
+ }
1320
+ scrollLocks += 1;
1321
+ }
1322
+ function unlockPageScroll() {
1323
+ if (scrollLocks === 0) return;
1324
+ scrollLocks -= 1;
1325
+ if (scrollLocks === 0) {
1326
+ document.documentElement.style.overflow = previousRootOverflow;
1327
+ previousRootOverflow = "";
1328
+ }
1329
+ }
1330
+ function trapFocus(container) {
1331
+ function onKey(event) {
1332
+ if (event.key !== "Tab") return;
1333
+ var candidates = Array.from(
1334
+ container.querySelectorAll(
1335
+ 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
1336
+ )
1337
+ ).filter((node) => node.offsetParent !== null || node === document.activeElement);
1338
+ if (candidates.length === 0) {
1339
+ event.preventDefault();
1340
+ return;
1341
+ }
1342
+ var first = candidates[0];
1343
+ var last = candidates[candidates.length - 1];
1344
+ if (event.shiftKey && document.activeElement === first) {
1345
+ event.preventDefault();
1346
+ last.focus();
1347
+ } else if (!event.shiftKey && document.activeElement === last) {
1348
+ event.preventDefault();
1349
+ first.focus();
1350
+ }
1351
+ }
1352
+ container.addEventListener("keydown", onKey, true);
1353
+ return () => container.removeEventListener("keydown", onKey, true);
1354
+ }
1219
1355
  function openImage(source, alt) {
1220
1356
  if (document.querySelector("." + IMG_MODAL_CLASS) !== null) return;
1221
1357
  var overlay = document.createElement("div");
@@ -1232,12 +1368,15 @@ window.__ModuleLoader__.load({
1232
1368
  closeButton.textContent = "\xD7";
1233
1369
  closeButton.setAttribute("aria-label", t("imageClose"));
1234
1370
  var previousFocus = document.activeElement;
1371
+ var releaseFocus = null;
1235
1372
  var closed = false;
1236
1373
  function closeViewer() {
1237
1374
  if (closed) return;
1238
1375
  closed = true;
1376
+ releaseFocus?.();
1239
1377
  document.removeEventListener("keydown", onKey, true);
1240
1378
  overlay.remove();
1379
+ unlockPageScroll();
1241
1380
  if (previousFocus !== null && typeof previousFocus.focus === "function") previousFocus.focus();
1242
1381
  }
1243
1382
  function onKey(event) {
@@ -1253,7 +1392,9 @@ window.__ModuleLoader__.load({
1253
1392
  document.addEventListener("keydown", onKey, true);
1254
1393
  overlay.appendChild(image);
1255
1394
  overlay.appendChild(closeButton);
1395
+ lockPageScroll();
1256
1396
  document.body.appendChild(overlay);
1397
+ releaseFocus = trapFocus(overlay);
1257
1398
  closeButton.focus();
1258
1399
  }
1259
1400
  function onDocumentClick(event) {
@@ -1296,10 +1437,26 @@ window.__ModuleLoader__.load({
1296
1437
  return input;
1297
1438
  }
1298
1439
  function rescanFolds() {
1299
- for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) resetFold(node);
1440
+ diagramKindCache = /* @__PURE__ */ new WeakMap();
1441
+ var codeLimit = foldLimit("code");
1442
+ var tableLimit = foldLimit("table");
1443
+ var diagramLimit = foldLimit("diagram");
1444
+ for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) {
1445
+ if (node.classList.contains(MMD_CLASS + "-viewport")) continue;
1446
+ var limit = node.hasAttribute(TABLE_DONE_ATTR) ? tableLimit : codeLimit;
1447
+ if (node.getAttribute(FOLD_ATTR) === "off" && limit > 0) {
1448
+ node.style.setProperty("--md-plus-fold-max-height", limit + "px");
1449
+ continue;
1450
+ }
1451
+ resetFold(node);
1452
+ }
1300
1453
  for (const viewport of document.querySelectorAll("." + MMD_CLASS + "-viewport")) {
1454
+ if (viewport.getAttribute(FOLD_ATTR) === "off" && diagramLimit > 0) {
1455
+ viewport.style.setProperty("--md-plus-fold-max-height", diagramLimit + "px");
1456
+ continue;
1457
+ }
1301
1458
  resetFold(viewport);
1302
- scheduleFold(viewport, foldLimit("diagram"));
1459
+ scheduleFold(viewport, diagramLimit);
1303
1460
  }
1304
1461
  scanFolds();
1305
1462
  }
@@ -1372,12 +1529,15 @@ window.__ModuleLoader__.load({
1372
1529
  panel.appendChild(actions);
1373
1530
  overlay.appendChild(panel);
1374
1531
  var previousFocus = document.activeElement;
1532
+ var releaseFocus = null;
1375
1533
  var closed = false;
1376
1534
  function closeSettings() {
1377
1535
  if (closed) return;
1378
1536
  closed = true;
1537
+ releaseFocus?.();
1379
1538
  document.removeEventListener("keydown", onKey, true);
1380
1539
  overlay.remove();
1540
+ unlockPageScroll();
1381
1541
  if (previousFocus !== null && typeof previousFocus.focus === "function") previousFocus.focus();
1382
1542
  }
1383
1543
  function onKey(event) {
@@ -1404,22 +1564,29 @@ window.__ModuleLoader__.load({
1404
1564
  foldDiagram.value = String(DEFAULT_SETTINGS.foldDiagram);
1405
1565
  });
1406
1566
  saveButton.addEventListener("click", () => {
1407
- saveSettings({
1567
+ var previous = readSettings();
1568
+ var previousTheme = getMermaidTheme();
1569
+ var nextTheme = THEME_ORDER.indexOf(themeSelect.value) === -1 ? "blue" : themeSelect.value;
1570
+ var next = {
1408
1571
  codeFontSize: readFontSize(fontInput),
1409
1572
  diagramView: viewSelect.value === "code" ? "code" : "diagram",
1410
1573
  foldCode: readNumber(foldCode, DEFAULT_SETTINGS.foldCode),
1411
1574
  foldTable: readNumber(foldTable, DEFAULT_SETTINGS.foldTable),
1412
1575
  foldDiagram: readNumber(foldDiagram, DEFAULT_SETTINGS.foldDiagram)
1413
- });
1414
- memoryTheme = themeSelect.value;
1576
+ };
1577
+ saveSettings(next);
1578
+ memoryTheme = nextTheme;
1579
+ themeCache = nextTheme;
1415
1580
  try {
1416
- window.localStorage.setItem(THEME_KEY, themeSelect.value);
1581
+ window.localStorage.setItem(THEME_KEY, nextTheme);
1417
1582
  } catch {
1418
1583
  }
1419
1584
  applyCodeFontSize();
1420
1585
  refreshThemeButtons();
1421
- redrawDiagrams();
1422
- rescanFolds();
1586
+ if (previousTheme !== nextTheme) redrawDiagrams();
1587
+ if (previous.codeFontSize !== next.codeFontSize || previous.foldCode !== next.foldCode || previous.foldTable !== next.foldTable || previous.foldDiagram !== next.foldDiagram) {
1588
+ rescanFolds();
1589
+ }
1423
1590
  closeSettings();
1424
1591
  });
1425
1592
  closeButton.addEventListener("click", closeSettings);
@@ -1427,12 +1594,18 @@ window.__ModuleLoader__.load({
1427
1594
  if (event.target === overlay) closeSettings();
1428
1595
  });
1429
1596
  document.addEventListener("keydown", onKey, true);
1597
+ lockPageScroll();
1430
1598
  document.body.appendChild(overlay);
1599
+ releaseFocus = trapFocus(overlay);
1431
1600
  saveButton.focus();
1432
1601
  }
1433
1602
  function ensureSettingsButton() {
1434
- if (document.querySelector("." + SETTINGS_BTN_CLASS) !== null) return;
1435
- if (document.querySelector('[class*="_markdown_"], .md-code-block') === null) return;
1603
+ var existing = document.querySelector("." + SETTINGS_BTN_CLASS);
1604
+ if (document.querySelector('[class*="_markdown_"], .md-code-block') === null) {
1605
+ existing?.remove();
1606
+ return;
1607
+ }
1608
+ if (existing !== null) return;
1436
1609
  var button = document.createElement("button");
1437
1610
  button.type = "button";
1438
1611
  button.className = SETTINGS_BTN_CLASS;
@@ -1486,16 +1659,23 @@ window.__ModuleLoader__.load({
1486
1659
  link.remove();
1487
1660
  window.setTimeout(() => URL.revokeObjectURL(url), 1e3);
1488
1661
  }
1489
- function downloadSvg(svg) {
1662
+ function exportFailed(button, error) {
1663
+ console.warn("[dsh-md-plus] \u56FE\u8868\u5BFC\u51FA\u5931\u8D25", error);
1664
+ if (button !== void 0) flashButton(button, t("exportFailed"));
1665
+ }
1666
+ function downloadSvg(svg, button) {
1490
1667
  try {
1491
1668
  downloadBlob(new Blob([serializeSvg(svg)], { type: "image/svg+xml;charset=utf-8" }), "mermaid-diagram.svg");
1492
1669
  } catch (error) {
1493
- console.warn("[dsh-md-plus] SVG \u5BFC\u51FA\u5931\u8D25", error);
1670
+ exportFailed(button, error);
1494
1671
  }
1495
1672
  }
1496
- function downloadPng(svg) {
1673
+ function downloadPng(svg, button) {
1497
1674
  var size = svgSize(svg);
1498
- if (size.width <= 0 || size.height <= 0) return;
1675
+ if (size.width <= 0 || size.height <= 0) {
1676
+ exportFailed(button, new Error("\u56FE\u8868\u5C3A\u5BF8\u65E0\u6548"));
1677
+ return;
1678
+ }
1499
1679
  var image = new window.Image();
1500
1680
  var objectUrl = "";
1501
1681
  image.onload = function() {
@@ -1509,16 +1689,17 @@ window.__ModuleLoader__.load({
1509
1689
  context.drawImage(image, 0, 0, canvas.width, canvas.height);
1510
1690
  canvas.toBlob((blob) => {
1511
1691
  if (blob !== null) downloadBlob(blob, "mermaid-diagram.png");
1692
+ else exportFailed(button, new Error("canvas \u672A\u751F\u6210\u56FE\u7247"));
1512
1693
  }, "image/png");
1513
1694
  } catch (error) {
1514
- console.warn("[dsh-md-plus] PNG \u5BFC\u51FA\u5931\u8D25", error);
1695
+ exportFailed(button, error);
1515
1696
  } finally {
1516
1697
  if (objectUrl !== "") URL.revokeObjectURL(objectUrl);
1517
1698
  }
1518
1699
  };
1519
1700
  image.onerror = function() {
1520
1701
  if (objectUrl !== "") URL.revokeObjectURL(objectUrl);
1521
- console.warn("[dsh-md-plus] PNG \u5BFC\u51FA\u5931\u8D25\uFF1ASVG \u65E0\u6CD5\u8F7D\u5165");
1702
+ exportFailed(button, new Error("SVG \u65E0\u6CD5\u8F7D\u5165"));
1522
1703
  };
1523
1704
  objectUrl = URL.createObjectURL(new Blob([serializeSvg(svg)], { type: "image/svg+xml;charset=utf-8" }));
1524
1705
  image.src = objectUrl;
@@ -1591,15 +1772,16 @@ window.__ModuleLoader__.load({
1591
1772
  panel.appendChild(body);
1592
1773
  overlay.appendChild(panel);
1593
1774
  var previousFocus = document.activeElement;
1594
- var previousOverflow = document.documentElement.style.overflow;
1775
+ var releaseFocus = null;
1595
1776
  var closed = false;
1596
1777
  var reset = () => fitToView(overlay);
1597
1778
  function closeViewer() {
1598
1779
  if (closed) return;
1599
1780
  closed = true;
1781
+ releaseFocus?.();
1600
1782
  document.removeEventListener("keydown", onKey, true);
1601
1783
  overlay.remove();
1602
- document.documentElement.style.overflow = previousOverflow;
1784
+ unlockPageScroll();
1603
1785
  zooms.delete(overlay);
1604
1786
  if (previousFocus !== null && typeof previousFocus.focus === "function") {
1605
1787
  previousFocus.focus();
@@ -1615,16 +1797,17 @@ window.__ModuleLoader__.load({
1615
1797
  if (event.target === overlay) closeViewer();
1616
1798
  });
1617
1799
  fitButton.addEventListener("click", reset);
1618
- svgButton.addEventListener("click", () => downloadSvg(svg));
1619
- pngButton.addEventListener("click", () => downloadPng(svg));
1800
+ svgButton.addEventListener("click", () => downloadSvg(svg, svgButton));
1801
+ pngButton.addEventListener("click", () => downloadPng(svg, pngButton));
1620
1802
  zoomOut.addEventListener("click", () => zoomBy(overlay, 1 / ZOOM_STEP));
1621
1803
  zoomIn.addEventListener("click", () => zoomBy(overlay, ZOOM_STEP));
1622
1804
  closeButton.addEventListener("click", closeViewer);
1623
1805
  document.addEventListener("keydown", onKey, true);
1624
1806
  zooms.set(overlay, { scale: 1, x: 0, y: 0, min: ZOOM_MIN_MODAL });
1625
1807
  bindViewport(overlay, viewport, reset, true);
1626
- document.documentElement.style.overflow = "hidden";
1808
+ lockPageScroll();
1627
1809
  document.body.appendChild(overlay);
1810
+ releaseFocus = trapFocus(overlay);
1628
1811
  closeButton.focus();
1629
1812
  var schedule2 = window.requestAnimationFrame ?? ((cb) => window.setTimeout(cb, 0));
1630
1813
  schedule2(reset);
@@ -1636,7 +1819,7 @@ window.__ModuleLoader__.load({
1636
1819
  var reason = (error?.message ?? String(error)).split("\n")[0] ?? "";
1637
1820
  note.textContent = t("renderFailed") + reason;
1638
1821
  content.appendChild(note);
1639
- block.setAttribute(KEY_ATTR, key);
1822
+ cacheKeys.set(block, key);
1640
1823
  block.setAttribute(MMD_ATTR, "failed");
1641
1824
  decorate(block);
1642
1825
  console.warn("[dsh-md-plus] mermaid \u6E32\u67D3\u5931\u8D25", error);
@@ -1645,6 +1828,8 @@ window.__ModuleLoader__.load({
1645
1828
  if (typeof document === "undefined") return;
1646
1829
  ctx.effect(() => {
1647
1830
  disposed = false;
1831
+ settingsCache = null;
1832
+ themeCache = null;
1648
1833
  injectStyle();
1649
1834
  applyCodeFontSize();
1650
1835
  ensureSettingsButton();
@@ -1667,6 +1852,7 @@ window.__ModuleLoader__.load({
1667
1852
  }
1668
1853
  pending.clear();
1669
1854
  rescanQueued = false;
1855
+ for (const target of [...foldTargets]) resetFold(target);
1670
1856
  observer.disconnect();
1671
1857
  document.removeEventListener("click", onDocumentClick, true);
1672
1858
  for (const node of injected) node.remove();
@@ -1676,7 +1862,7 @@ window.__ModuleLoader__.load({
1676
1862
  for (const node of document.querySelectorAll("." + FOLD_BTN_CLASS)) node.remove();
1677
1863
  for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) resetFold(node);
1678
1864
  for (const node of document.querySelectorAll("." + TABLE_TOOLS_CLASS)) node.remove();
1679
- for (const attr of [DONE_ATTR, KEY_ATTR, WRAP_ATTR, MMD_ATTR, TABLE_DONE_ATTR, "data-md-plus-lang", ZOOM_ATTR]) {
1865
+ for (const attr of [DONE_ATTR, WRAP_ATTR, MMD_ATTR, TABLE_DONE_ATTR, "data-md-plus-lang", ZOOM_ATTR]) {
1680
1866
  for (const node of document.querySelectorAll("[" + attr + "]")) node.removeAttribute(attr);
1681
1867
  }
1682
1868
  for (const node of document.querySelectorAll("[data-md-plus-original-label]")) {
@@ -1688,7 +1874,9 @@ window.__ModuleLoader__.load({
1688
1874
  )) {
1689
1875
  node.remove();
1690
1876
  }
1691
- document.documentElement.style.overflow = "";
1877
+ scrollLocks = 0;
1878
+ document.documentElement.style.overflow = previousRootOverflow;
1879
+ previousRootOverflow = "";
1692
1880
  document.documentElement.style.removeProperty("--md-plus-code-font-size");
1693
1881
  document.documentElement.style.removeProperty("--md-plus-code-line-height");
1694
1882
  document.querySelector("style[" + STYLE_ATTR + "]")?.remove();
@@ -1696,6 +1884,10 @@ window.__ModuleLoader__.load({
1696
1884
  script.remove();
1697
1885
  }
1698
1886
  scripts.clear();
1887
+ settingsCache = null;
1888
+ themeCache = null;
1889
+ diagramKindCache = /* @__PURE__ */ new WeakMap();
1890
+ cacheKeys = /* @__PURE__ */ new WeakMap();
1699
1891
  delete window[HL_GLOBAL];
1700
1892
  delete window[MMD_GLOBAL];
1701
1893
  };
@@ -4290,4 +4290,4 @@ ${i?"":`
4290
4290
  `}else s+=`${t.themeCSS}
4291
4291
  `;return s+Hme(i)},"createCssStyles"),H0i=_((t,r)=>cxe(qEr(`${t}{${r}}`),YEr([_(function(s,o,u,h){if(s.type==="rule"&&Array.isArray(s.props)){if(s.parent&&s.parent.type===kre)return;s.props=s.props.map(d=>d===t&&Array.isArray(s.children)&&s.children.every(y=>y.type!=="decl"?!1:new Set(["font-family","font-size","fill"]).has(y.props))||(d.startsWith(`${t} `)||d.startsWith(`${t}>`))&&!d.startsWith(`${t} ||`)?d:`${t} ${d}`)}else s.type.startsWith("@")&&([...[REr,IEr,txe,OEr,"@container","@starting-style"],kre].includes(s.type)||(We.warn(`Removing unsupported at-rule ${s.type} from CSS`),s.type=cU))},"addNamespace"),WEr])),"compileCSS"),q0i=_((t,r,i,s)=>{let o=V0i(t,i),u=Eir(r,o,{...t.themeVariables,theme:t.theme,look:t.look},s);return H0i(s,u)},"createUserStyles"),W0i=_((t="",r,i)=>{let s=t;return!i&&!r&&(s=s.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),s=Z3(s),s=s.replace(/<br>/g,"<br/>"),s},"cleanUpSvgCode"),Y0i=_((t="",r)=>{let i=r?.viewBox?.baseVal?.height?r.viewBox.baseVal.height+"px":B0i,s=FGr(`<body style="${$0i}">${t}</body>`);return`<iframe style="width:${P0i};height:${i};${F0i}" src="data:text/html;charset=UTF-8;base64,${s}" sandbox="${z0i}">
4292
4292
  ${j0i}
4293
- </iframe>`},"putIntoIFrame"),Kjr=_((t,r,i,s,o)=>{let u=t.append("div");u.attr("id",i),s&&u.attr("style",s);let h=u.append("svg").attr("id",r).attr("width","100%").attr("xmlns",O0i);return o&&h.attr("xmlns:xlink",o),h.append("g"),t},"appendDivSvgG");function Qct(t,r){return t.append("iframe").attr("id",r).attr("style","width: 100%; height: 100%;").attr("sandbox","")}_(Qct,"sandboxedIframe");var K0i=_((t,r,i,s)=>{t.getElementById(r)?.remove(),t.getElementById(i)?.remove(),t.getElementById(s)?.remove()},"removeExistingElements"),X0i=_(async function(t,r,i){Hke();let s=Zct(r),o=s.code;r=o.cleaned;let u=Di();We.debug(u),r.length>(u?.maxTextSize??R0i)&&(r=L0i,o={raw:r,cleaned:r});let h=`#${t}`,d="i"+t,g="#"+d,y="d"+t,v="#"+y,x=_(()=>{let Q=un(C?g:v).node();Q&&"remove"in Q&&Q.remove()},"removeTempElements"),k=un(document.body),C=u.securityLevel===I0i,E=u.securityLevel===M0i,A=u.fontFamily;if(i!==void 0){if(i&&(i.innerHTML=""),C){let Z=Qct(un(i),d);k=un(Z.nodes()[0].contentDocument.body),k.node().style.margin="0"}else k=un(i);Kjr(k,t,y,`font-family: ${A}`,N0i)}else{if(K0i(document,t,y,d),C){let Z=Qct(un(document.body),d);k=un(Z.nodes()[0].contentDocument.body),k.node().style.margin="0"}else k=un("body");Kjr(k,t,y)}let R,L;try{R=await Uke.fromText(o,{title:s.title})}catch(Z){if(u.suppressErrorRendering)throw x(),Z;R=await Uke.fromText("error"),L=Z,R.db.setErrorMessage?.(iYe(Z))}let O=k.select(v).node(),N=R.type,F=O.firstChild,D=F.firstChild,P=R.renderer.getClasses?.(r,R),z=q0i(u,N,P,h),V=document.createElement("style");V.innerHTML=z,F.insertBefore(V,D);try{await R.renderer.draw(r,t,"12.1.0",R)}catch(Z){throw u.suppressErrorRendering?x():Jdi.draw(r,t,"12.1.0"),Z}let Y=k.select(`${v} svg`),K=R.db.getAccTitle?.(),J=R.db.getAccDescription?.();jGr(N,Y,K,J);let q=_(()=>{k.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",D0i);let Z=k.select(v).node().innerHTML;if(We.debug("config.arrowMarkerAbsolute",u.arrowMarkerAbsolute),Z=W0i(Z,C,_w(u.arrowMarkerAbsolute)),C){let Q=k.select(v+" svg").node();Z=Y0i(Z,Q)}else E||(Z=qm.sanitize(Z,{ADD_TAGS:G0i,ADD_ATTR:U0i,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));return C0i(),Z},"serializeSvg")();if(L)throw L;return x(),{diagramType:N,svg:q,bindFunctions:R.db.bindFunctions}},"renderDiagram"),Q0i=_(async function(t,r,i){try{return await X0i(t,r,i)}finally{Vme(void 0)}},"render");function zGr(t={}){let r=Vh({},t);r?.fontFamily&&!r.themeVariables?.fontFamily&&(r.themeVariables||(r.themeVariables={}),r.themeVariables.fontFamily=r.fontFamily),mir(r);let i=B6.theme;r?.theme&&Object.hasOwn(S5,r.theme)?r.themeVariables=S5[r.theme].getThemeVariables(r.themeVariables):r&&(r.theme!=null&&r.theme!=="null"&&(r.theme=i),r.themeVariables=S5[i].getThemeVariables(r.themeVariables));let s=typeof r=="object"?gir(r):zVe();lZ(s.logLevel),Hke()}_(zGr,"initialize");var J0i=_((t,r={})=>{let{code:i}=Jct(t);return Uke.fromText(i,r)},"getDiagramFromText");function jGr(t,r,i,s){NGr(r,t),DGr(r,i,s,r.attr("id"))}_(jGr,"addA11yInfo");var CP=Object.freeze({render:Q0i,parse:$Gr,getDiagramFromText:J0i,initialize:zGr,getConfig:Di,setConfig:jVe,getSiteConfig:zVe,updateSiteConfig:yir,reset:_(()=>{LZ()},"reset"),globalReset:_(()=>{LZ(B6)},"globalReset"),defaultConfig:B6});lZ(Di().logLevel);LZ(Di());var Z0i=_((t,r,i)=>{We.warn(t),Gve(t)?(i&&i(t.str,t.hash),r.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&r.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),GGr=_(async function(t={querySelector:".mermaid"}){try{await e1i(t)}catch(r){if(Gve(r)&&We.error(r.str),WA.parseError&&WA.parseError(r),!t.suppressErrors)throw We.error("Use the suppressErrors option to suppress these errors"),r}},"run"),e1i=_(async function({postRenderCallback:t,querySelector:r,nodes:i}={querySelector:".mermaid"}){let s=CP.getConfig();We.debug(`${t?"":"No "}Callback function found`);let o;if(i)o=i;else if(r)o=document.querySelectorAll(r);else throw new Error("Nodes and querySelector are both undefined");We.debug(`Found ${o.length} diagrams`),s?.startOnLoad!==void 0&&(We.debug("Start On Load: "+s?.startOnLoad),CP.updateSiteConfig({startOnLoad:s?.startOnLoad}));let u=new ss.InitIDGenerator(s.deterministicIds,s.deterministicIDSeed),h,d=[];for(let g of Array.from(o)){if(We.info("Rendering diagram: "+g.id),g.getAttribute("data-processed"))continue;g.setAttribute("data-processed","true");let y=`mermaid-${u.next()}`;h=g.innerHTML,h=Kve(ss.entityDecode(h)).trim().replace(/<br\s*\/?>/gi,"<br/>");let v=ss.detectInit(h);v&&We.debug("Detected early reinit: ",v);try{let{svg:x,bindFunctions:k}=await qGr(y,h,g);g.innerHTML=x,t&&await t(y),k&&k(g)}catch(x){Z0i(x,d,WA.parseError)}}if(d.length>0)throw d[0]},"runThrowsErrors"),UGr=_(function(t){CP.initialize(t)},"initialize"),t1i=_(async function(t,r,i){We.warn("mermaid.init is deprecated. Please use run instead."),t&&UGr(t);let s={postRenderCallback:i,querySelector:".mermaid"};typeof r=="string"?s.querySelector=r:r&&(r instanceof HTMLElement?s.nodes=[r]:s.nodes=r),await GGr(s)},"init"),r1i=_(async(t,{lazyLoad:r=!0}={})=>{Hke(),Ume(...t),r===!1&&await T0i()},"registerExternalDiagrams"),VGr=_(function(){if(WA.startOnLoad){let{startOnLoad:t}=CP.getConfig();t&&WA.run().catch(r=>We.error("Mermaid failed to initialize",r))}},"contentLoaded");typeof document<"u"&&window.addEventListener("load",VGr,!1);var n1i=_(function(t){WA.parseError=t},"setParseErrorHandler"),Vke=[],Xct=!1,HGr=_(async()=>{if(!Xct){for(Xct=!0;Vke.length>0;){let t=Vke.shift();if(t)try{await t()}catch(r){We.error("Error executing queue",r)}}Xct=!1}},"executeQueue"),i1i=_(async(t,r)=>new Promise((i,s)=>{let o=_(()=>new Promise((u,h)=>{CP.parse(t,r).then(d=>{u(d),i(d)},d=>{We.error("Error parsing",d),WA.parseError?.(d),h(d),s(d)})}),"performCall");Vke.push(o),HGr().catch(s)}),"parse"),qGr=_((t,r,i)=>new Promise((s,o)=>{let u=_(()=>new Promise((h,d)=>{CP.render(t,r,i).then(g=>{h(g),s(g)},g=>{We.error("Error parsing",g),WA.parseError?.(g),d(g),o(g)})}),"performCall");Vke.push(u),HGr().catch(o)}),"render"),a1i=_(()=>Object.keys(iR).map(t=>({id:t})),"getRegisteredDiagramsMetadata"),WA={startOnLoad:!0,mermaidAPI:CP,parse:i1i,render:qGr,init:t1i,run:GGr,registerExternalDiagrams:r1i,registerLayoutLoaders:Ket,initialize:UGr,parseError:void 0,contentLoaded:VGr,setParseErrorHandler:n1i,detectType:cj,registerIconPacks:jj,getRegisteredDiagramsMetadata:a1i},qke=WA;var WGr={fontSize:"16px",flowchart:{curve:"basis",nodeSpacing:40,rankSpacing:41,padding:18,useMaxWidth:!0}},s1i={background:"transparent",primaryColor:"#e5f2ff",primaryTextColor:"#339cff",primaryBorderColor:"#e5f2ff",secondaryColor:"#e5f2ff",tertiaryColor:"#e5f2ff",lineColor:"#339cff",edgeLabelBackground:"#ffffff",clusterBkg:"#f2f8ff",clusterBorder:"#cde7ff",titleColor:"#339cff",nodeTextColor:"#339cff"},o1i={background:"transparent",primaryColor:"#16283d",primaryTextColor:"#79bdff",primaryBorderColor:"#16283d",secondaryColor:"#16283d",tertiaryColor:"#16283d",lineColor:"#5aa9f0",edgeLabelBackground:"#0f1115",clusterBkg:"#132133",clusterBorder:"#2b4a6b",titleColor:"#79bdff",nodeTextColor:"#79bdff"},l1i={background:"transparent",primaryColor:"#f2f2f2",primaryTextColor:"#222222",primaryBorderColor:"#c9c9c9",secondaryColor:"#f2f2f2",tertiaryColor:"#f2f2f2",lineColor:"#666666",edgeLabelBackground:"#ffffff",clusterBkg:"#fafafa",clusterBorder:"#dddddd",titleColor:"#222222",nodeTextColor:"#222222"},c1i={background:"transparent",primaryColor:"#2a2a2a",primaryTextColor:"#eeeeee",primaryBorderColor:"#555555",secondaryColor:"#2a2a2a",tertiaryColor:"#2a2a2a",lineColor:"#aaaaaa",edgeLabelBackground:"#111111",clusterBkg:"#1f1f1f",clusterBorder:"#3a3a3a",titleColor:"#eeeeee",nodeTextColor:"#eeeeee"},u1i={background:"transparent",primaryColor:"#e8f5e9",primaryTextColor:"#1b5e20",primaryBorderColor:"#a5d6a7",secondaryColor:"#e8f5e9",tertiaryColor:"#e8f5e9",lineColor:"#43a047",edgeLabelBackground:"#ffffff",clusterBkg:"#f1f8e9",clusterBorder:"#c8e6c9",titleColor:"#1b5e20",nodeTextColor:"#1b5e20"},h1i={background:"transparent",primaryColor:"#1b3320",primaryTextColor:"#a5d6a7",primaryBorderColor:"#2e7d32",secondaryColor:"#1b3320",tertiaryColor:"#1b3320",lineColor:"#66bb6a",edgeLabelBackground:"#0f1115",clusterBkg:"#142418",clusterBorder:"#2e4a34",titleColor:"#a5d6a7",nodeTextColor:"#a5d6a7"},f1i={background:"transparent",primaryColor:"#ffffff",primaryTextColor:"#000000",primaryBorderColor:"#000000",secondaryColor:"#ffffff",tertiaryColor:"#ffffff",lineColor:"#000000",edgeLabelBackground:"#ffffff",clusterBkg:"#ffffff",clusterBorder:"#000000",titleColor:"#000000",nodeTextColor:"#000000"},d1i={background:"transparent",primaryColor:"#0b0b0b",primaryTextColor:"#ffffff",primaryBorderColor:"#ffffff",secondaryColor:"#0b0b0b",tertiaryColor:"#0b0b0b",lineColor:"#ffffff",edgeLabelBackground:"#0b0b0b",clusterBkg:"#0b0b0b",clusterBorder:"#ffffff",titleColor:"#ffffff",nodeTextColor:"#ffffff"},eut={blue:{light:s1i,dark:o1i},neutral:{light:l1i,dark:c1i},forest:{light:u1i,dark:h1i},contrast:{light:f1i,dark:d1i}},G9a=Object.keys(eut);function YGr(t,r,i="blue"){let s=eut[i]??eut.blue,o=t?s.dark:s.light;return{startOnLoad:!1,securityLevel:"strict",theme:"base",fontFamily:r,themeVariables:{...o,...WGr},flowchart:WGr.flowchart,themeCSS:[".nodeLabel,.edgeLabel,.label{font-weight:600}",".flowchart-link{stroke-width:1.6px}",`.marker,.arrowheadPath{fill:${o.lineColor};stroke:${o.lineColor}}`].join("")}}var tut=11;var KGr=null,XGr=Promise.resolve();function p1i(t){let r=XGr.then(t,t);return XGr=r.then(()=>{},()=>{}),r}function g1i(t,r){let i=(t?"dark":"light")+":"+r;if(KGr===i)return;KGr=i;let s=getComputedStyle(document.body).fontFamily||"system-ui, sans-serif";qke.initialize(YGr(t,s,r))}function m1i(t){for(let r of t.querySelectorAll(".node rect"))r.setAttribute("rx",String(tut)),r.setAttribute("ry",String(tut))}function y1i(t){return t.includes('aria-roledescription="error"')||t.includes("Syntax error in text")}function v1i(t){let r=typeof CSS<"u"&&CSS.escape!==void 0?CSS.escape(t):t;for(let i of document.querySelectorAll(`#d${r}, #d${r} svg`))i.remove()}window.__DSH_MD_PLUS_MMD__={render(t,r,i,s){return p1i(async()=>{g1i(i===!0,s??"blue");let o=null;qke.parseError=u=>{o??=u};try{let{svg:u}=await qke.render(t,r);if(o!==null)throw o;if(y1i(u))throw new Error("mermaid \u8FD4\u56DE\u7684\u662F\u9519\u8BEF\u5361\u7247\uFF08\u8BED\u6CD5\u65E0\u6CD5\u89E3\u6790\uFF09");let h=document.createElement("div");return h.innerHTML=u,m1i(h),await new Promise(d=>setTimeout(d,0)),h.innerHTML}finally{v1i(t)}})}};})();
4293
+ </iframe>`},"putIntoIFrame"),Kjr=_((t,r,i,s,o)=>{let u=t.append("div");u.attr("id",i),s&&u.attr("style",s);let h=u.append("svg").attr("id",r).attr("width","100%").attr("xmlns",O0i);return o&&h.attr("xmlns:xlink",o),h.append("g"),t},"appendDivSvgG");function Qct(t,r){return t.append("iframe").attr("id",r).attr("style","width: 100%; height: 100%;").attr("sandbox","")}_(Qct,"sandboxedIframe");var K0i=_((t,r,i,s)=>{t.getElementById(r)?.remove(),t.getElementById(i)?.remove(),t.getElementById(s)?.remove()},"removeExistingElements"),X0i=_(async function(t,r,i){Hke();let s=Zct(r),o=s.code;r=o.cleaned;let u=Di();We.debug(u),r.length>(u?.maxTextSize??R0i)&&(r=L0i,o={raw:r,cleaned:r});let h=`#${t}`,d="i"+t,g="#"+d,y="d"+t,v="#"+y,x=_(()=>{let Q=un(C?g:v).node();Q&&"remove"in Q&&Q.remove()},"removeTempElements"),k=un(document.body),C=u.securityLevel===I0i,E=u.securityLevel===M0i,A=u.fontFamily;if(i!==void 0){if(i&&(i.innerHTML=""),C){let Z=Qct(un(i),d);k=un(Z.nodes()[0].contentDocument.body),k.node().style.margin="0"}else k=un(i);Kjr(k,t,y,`font-family: ${A}`,N0i)}else{if(K0i(document,t,y,d),C){let Z=Qct(un(document.body),d);k=un(Z.nodes()[0].contentDocument.body),k.node().style.margin="0"}else k=un("body");Kjr(k,t,y)}let R,L;try{R=await Uke.fromText(o,{title:s.title})}catch(Z){if(u.suppressErrorRendering)throw x(),Z;R=await Uke.fromText("error"),L=Z,R.db.setErrorMessage?.(iYe(Z))}let O=k.select(v).node(),N=R.type,F=O.firstChild,D=F.firstChild,P=R.renderer.getClasses?.(r,R),z=q0i(u,N,P,h),V=document.createElement("style");V.innerHTML=z,F.insertBefore(V,D);try{await R.renderer.draw(r,t,"12.1.0",R)}catch(Z){throw u.suppressErrorRendering?x():Jdi.draw(r,t,"12.1.0"),Z}let Y=k.select(`${v} svg`),K=R.db.getAccTitle?.(),J=R.db.getAccDescription?.();jGr(N,Y,K,J);let q=_(()=>{k.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",D0i);let Z=k.select(v).node().innerHTML;if(We.debug("config.arrowMarkerAbsolute",u.arrowMarkerAbsolute),Z=W0i(Z,C,_w(u.arrowMarkerAbsolute)),C){let Q=k.select(v+" svg").node();Z=Y0i(Z,Q)}else E||(Z=qm.sanitize(Z,{ADD_TAGS:G0i,ADD_ATTR:U0i,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));return C0i(),Z},"serializeSvg")();if(L)throw L;return x(),{diagramType:N,svg:q,bindFunctions:R.db.bindFunctions}},"renderDiagram"),Q0i=_(async function(t,r,i){try{return await X0i(t,r,i)}finally{Vme(void 0)}},"render");function zGr(t={}){let r=Vh({},t);r?.fontFamily&&!r.themeVariables?.fontFamily&&(r.themeVariables||(r.themeVariables={}),r.themeVariables.fontFamily=r.fontFamily),mir(r);let i=B6.theme;r?.theme&&Object.hasOwn(S5,r.theme)?r.themeVariables=S5[r.theme].getThemeVariables(r.themeVariables):r&&(r.theme!=null&&r.theme!=="null"&&(r.theme=i),r.themeVariables=S5[i].getThemeVariables(r.themeVariables));let s=typeof r=="object"?gir(r):zVe();lZ(s.logLevel),Hke()}_(zGr,"initialize");var J0i=_((t,r={})=>{let{code:i}=Jct(t);return Uke.fromText(i,r)},"getDiagramFromText");function jGr(t,r,i,s){NGr(r,t),DGr(r,i,s,r.attr("id"))}_(jGr,"addA11yInfo");var CP=Object.freeze({render:Q0i,parse:$Gr,getDiagramFromText:J0i,initialize:zGr,getConfig:Di,setConfig:jVe,getSiteConfig:zVe,updateSiteConfig:yir,reset:_(()=>{LZ()},"reset"),globalReset:_(()=>{LZ(B6)},"globalReset"),defaultConfig:B6});lZ(Di().logLevel);LZ(Di());var Z0i=_((t,r,i)=>{We.warn(t),Gve(t)?(i&&i(t.str,t.hash),r.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&r.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),GGr=_(async function(t={querySelector:".mermaid"}){try{await e1i(t)}catch(r){if(Gve(r)&&We.error(r.str),WA.parseError&&WA.parseError(r),!t.suppressErrors)throw We.error("Use the suppressErrors option to suppress these errors"),r}},"run"),e1i=_(async function({postRenderCallback:t,querySelector:r,nodes:i}={querySelector:".mermaid"}){let s=CP.getConfig();We.debug(`${t?"":"No "}Callback function found`);let o;if(i)o=i;else if(r)o=document.querySelectorAll(r);else throw new Error("Nodes and querySelector are both undefined");We.debug(`Found ${o.length} diagrams`),s?.startOnLoad!==void 0&&(We.debug("Start On Load: "+s?.startOnLoad),CP.updateSiteConfig({startOnLoad:s?.startOnLoad}));let u=new ss.InitIDGenerator(s.deterministicIds,s.deterministicIDSeed),h,d=[];for(let g of Array.from(o)){if(We.info("Rendering diagram: "+g.id),g.getAttribute("data-processed"))continue;g.setAttribute("data-processed","true");let y=`mermaid-${u.next()}`;h=g.innerHTML,h=Kve(ss.entityDecode(h)).trim().replace(/<br\s*\/?>/gi,"<br/>");let v=ss.detectInit(h);v&&We.debug("Detected early reinit: ",v);try{let{svg:x,bindFunctions:k}=await qGr(y,h,g);g.innerHTML=x,t&&await t(y),k&&k(g)}catch(x){Z0i(x,d,WA.parseError)}}if(d.length>0)throw d[0]},"runThrowsErrors"),UGr=_(function(t){CP.initialize(t)},"initialize"),t1i=_(async function(t,r,i){We.warn("mermaid.init is deprecated. Please use run instead."),t&&UGr(t);let s={postRenderCallback:i,querySelector:".mermaid"};typeof r=="string"?s.querySelector=r:r&&(r instanceof HTMLElement?s.nodes=[r]:s.nodes=r),await GGr(s)},"init"),r1i=_(async(t,{lazyLoad:r=!0}={})=>{Hke(),Ume(...t),r===!1&&await T0i()},"registerExternalDiagrams"),VGr=_(function(){if(WA.startOnLoad){let{startOnLoad:t}=CP.getConfig();t&&WA.run().catch(r=>We.error("Mermaid failed to initialize",r))}},"contentLoaded");typeof document<"u"&&window.addEventListener("load",VGr,!1);var n1i=_(function(t){WA.parseError=t},"setParseErrorHandler"),Vke=[],Xct=!1,HGr=_(async()=>{if(!Xct){for(Xct=!0;Vke.length>0;){let t=Vke.shift();if(t)try{await t()}catch(r){We.error("Error executing queue",r)}}Xct=!1}},"executeQueue"),i1i=_(async(t,r)=>new Promise((i,s)=>{let o=_(()=>new Promise((u,h)=>{CP.parse(t,r).then(d=>{u(d),i(d)},d=>{We.error("Error parsing",d),WA.parseError?.(d),h(d),s(d)})}),"performCall");Vke.push(o),HGr().catch(s)}),"parse"),qGr=_((t,r,i)=>new Promise((s,o)=>{let u=_(()=>new Promise((h,d)=>{CP.render(t,r,i).then(g=>{h(g),s(g)},g=>{We.error("Error parsing",g),WA.parseError?.(g),d(g),o(g)})}),"performCall");Vke.push(u),HGr().catch(o)}),"render"),a1i=_(()=>Object.keys(iR).map(t=>({id:t})),"getRegisteredDiagramsMetadata"),WA={startOnLoad:!0,mermaidAPI:CP,parse:i1i,render:qGr,init:t1i,run:GGr,registerExternalDiagrams:r1i,registerLayoutLoaders:Ket,initialize:UGr,parseError:void 0,contentLoaded:VGr,setParseErrorHandler:n1i,detectType:cj,registerIconPacks:jj,getRegisteredDiagramsMetadata:a1i},qke=WA;var WGr={fontSize:"16px",flowchart:{curve:"basis",nodeSpacing:40,rankSpacing:41,padding:18,useMaxWidth:!0}},s1i={background:"transparent",primaryColor:"#e5f2ff",primaryTextColor:"#339cff",primaryBorderColor:"#e5f2ff",secondaryColor:"#e5f2ff",tertiaryColor:"#e5f2ff",lineColor:"#339cff",edgeLabelBackground:"#ffffff",clusterBkg:"#f2f8ff",clusterBorder:"#cde7ff",titleColor:"#339cff",nodeTextColor:"#339cff"},o1i={background:"transparent",primaryColor:"#16283d",primaryTextColor:"#79bdff",primaryBorderColor:"#16283d",secondaryColor:"#16283d",tertiaryColor:"#16283d",lineColor:"#5aa9f0",edgeLabelBackground:"#0f1115",clusterBkg:"#132133",clusterBorder:"#2b4a6b",titleColor:"#79bdff",nodeTextColor:"#79bdff"},l1i={background:"transparent",primaryColor:"#f2f2f2",primaryTextColor:"#222222",primaryBorderColor:"#c9c9c9",secondaryColor:"#f2f2f2",tertiaryColor:"#f2f2f2",lineColor:"#666666",edgeLabelBackground:"#ffffff",clusterBkg:"#fafafa",clusterBorder:"#dddddd",titleColor:"#222222",nodeTextColor:"#222222"},c1i={background:"transparent",primaryColor:"#2a2a2a",primaryTextColor:"#eeeeee",primaryBorderColor:"#555555",secondaryColor:"#2a2a2a",tertiaryColor:"#2a2a2a",lineColor:"#aaaaaa",edgeLabelBackground:"#111111",clusterBkg:"#1f1f1f",clusterBorder:"#3a3a3a",titleColor:"#eeeeee",nodeTextColor:"#eeeeee"},u1i={background:"transparent",primaryColor:"#e8f5e9",primaryTextColor:"#1b5e20",primaryBorderColor:"#a5d6a7",secondaryColor:"#e8f5e9",tertiaryColor:"#e8f5e9",lineColor:"#43a047",edgeLabelBackground:"#ffffff",clusterBkg:"#f1f8e9",clusterBorder:"#c8e6c9",titleColor:"#1b5e20",nodeTextColor:"#1b5e20"},h1i={background:"transparent",primaryColor:"#1b3320",primaryTextColor:"#a5d6a7",primaryBorderColor:"#2e7d32",secondaryColor:"#1b3320",tertiaryColor:"#1b3320",lineColor:"#66bb6a",edgeLabelBackground:"#0f1115",clusterBkg:"#142418",clusterBorder:"#2e4a34",titleColor:"#a5d6a7",nodeTextColor:"#a5d6a7"},f1i={background:"transparent",primaryColor:"#ffffff",primaryTextColor:"#000000",primaryBorderColor:"#000000",secondaryColor:"#ffffff",tertiaryColor:"#ffffff",lineColor:"#000000",edgeLabelBackground:"#ffffff",clusterBkg:"#ffffff",clusterBorder:"#000000",titleColor:"#000000",nodeTextColor:"#000000"},d1i={background:"transparent",primaryColor:"#0b0b0b",primaryTextColor:"#ffffff",primaryBorderColor:"#ffffff",secondaryColor:"#0b0b0b",tertiaryColor:"#0b0b0b",lineColor:"#ffffff",edgeLabelBackground:"#0b0b0b",clusterBkg:"#0b0b0b",clusterBorder:"#ffffff",titleColor:"#ffffff",nodeTextColor:"#ffffff"},eut={blue:{light:s1i,dark:o1i},neutral:{light:l1i,dark:c1i},forest:{light:u1i,dark:h1i},contrast:{light:f1i,dark:d1i}},G9a=Object.keys(eut);function YGr(t,r,i="blue"){let s=eut[i]??eut.blue,o=t?s.dark:s.light;return{startOnLoad:!1,securityLevel:"strict",htmlLabels:!1,theme:"base",fontFamily:r,themeVariables:{...o,...WGr},flowchart:WGr.flowchart,themeCSS:[".nodeLabel,.edgeLabel,.label{font-weight:600}",".flowchart-link{stroke-width:1.6px}",`.marker,.arrowheadPath{fill:${o.lineColor};stroke:${o.lineColor}}`].join("")}}var tut=11;var KGr=null,XGr=Promise.resolve();function p1i(t){let r=XGr.then(t,t);return XGr=r.then(()=>{},()=>{}),r}function g1i(t,r){let i=(t?"dark":"light")+":"+r;if(KGr===i)return;KGr=i;let s=getComputedStyle(document.body).fontFamily||"system-ui, sans-serif";qke.initialize(YGr(t,s,r))}function m1i(t){for(let r of t.querySelectorAll(".node rect"))r.setAttribute("rx",String(tut)),r.setAttribute("ry",String(tut))}function y1i(t){return t.includes('aria-roledescription="error"')||t.includes('class="error-text"')}function v1i(t){let r=typeof CSS<"u"&&CSS.escape!==void 0?CSS.escape(t):t;for(let i of document.querySelectorAll(`#d${r}, #d${r} svg`))i.remove()}window.__DSH_MD_PLUS_MMD__={render(t,r,i,s){return p1i(async()=>{g1i(i===!0,s??"blue");let o=null;qke.parseError=u=>{o??=u};try{let{svg:u}=await qke.render(t,r);if(o!==null)throw o;if(y1i(u))throw new Error("mermaid \u8FD4\u56DE\u7684\u662F\u9519\u8BEF\u5361\u7247\uFF08\u8BED\u6CD5\u65E0\u6CD5\u89E3\u6790\uFF09");let h=document.createElement("div");return h.innerHTML=u,m1i(h),await new Promise(d=>setTimeout(d,0)),h.innerHTML}finally{v1i(t)}})}};})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-md-plus",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Markdown display enhancements for DeepSeek Harness Web: code block restyle, syntax highlighting for languages DSH does not ship, and built-in mermaid diagrams.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -21,8 +21,12 @@
21
21
  "prepare": "node scripts/build.mjs",
22
22
  "preview": "node scripts/build.mjs && node scripts/preview.mjs && node scripts/shot.mjs",
23
23
  "shot": "node scripts/shot.mjs",
24
+ "smoke": "npm run build && node scripts/smoke.mjs",
24
25
  "test": "node --test test/host.test.mjs test/client.test.mjs",
25
- "check": "node --check src/index.js && node --check src/client.js && node --check src/highlight-runtime.js && node --check src/mermaid-runtime.js && node --check src/mermaid-theme.js && node --check scripts/build.mjs && npm test"
26
+ "check": "npm run build && node --check src/index.js && node --check src/client.js && node --check src/highlight-runtime.js && node --check src/mermaid-runtime.js && node --check src/mermaid-theme.js && node --check scripts/build.mjs && node --check scripts/smoke.mjs && npm test",
27
+ "release": "node scripts/release.mjs",
28
+ "release:dry": "node scripts/release.mjs --dry-run",
29
+ "release:yes": "node scripts/release.mjs --yes"
26
30
  },
27
31
  "dsh": {
28
32
  "bundle": {
@@ -34,6 +38,7 @@
34
38
  }
35
39
  },
36
40
  "devDependencies": {
41
+ "@shikijs/langs": "4.4.3",
37
42
  "esbuild": "0.28.2",
38
43
  "happy-dom": "^20.14.5",
39
44
  "mermaid": "^12.1.0",
@@ -62,6 +67,7 @@
62
67
  "url": "https://github.com/JosephHy/dsh-md-plus/issues"
63
68
  },
64
69
  "publishConfig": {
65
- "access": "public"
70
+ "access": "public",
71
+ "registry": "https://registry.npmjs.org/"
66
72
  }
67
73
  }