From 1882db7681d30446f9912d7f2b32e56b1541a21d Mon Sep 17 00:00:00 2001 From: lix-2026 Date: Mon, 1 Jun 2026 09:29:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E5=8F=A3=20MNote=20P0=20P1=20P2=20?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E5=B0=BE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 归档 OnlyOffice live bridge、Page AI、mindmap、design governance 与相关 bug 条目 - 补齐 MinerU OCR 后端 runtime 合同与 smoke/test 基线 - 收口 ChatOnly/Doubao、ObjectIdentity、Page Aggregate compat 与 runtime owner 文档口径 验证: - cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1 - cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1 - git diff --check - git diff --cached --check - codegraph index . --force && codegraph status . - codegraph sync . && codegraph status . --- .gitignore | 1 + AGENTS.md | 5 +- ...6-sidebar-dev-hot-reload-setinterval-v1.md | 46 + ...esign-without-runtime-implementation-v1.md | 103 + ...e-retired-bridge-artifact-regression-v1.md | 48 + ...workspace-object-identity-matrix-gap-v1.md | 33 + ...1-office-edit-sign-plugin-gap-review-v1.md | 30 +- ...older-media-sign-office-url-contract-v1.md | 0 ...5-35-office-edit-mode-menu-and-guard-v1.md | 24 +- ...ce-local-edit-save-callback-contract-v1.md | 39 +- ...ffice-annotation-plugin-noise-policy-v1.md | 4 +- ...ffice-bridge-plugin-noise-regression-v1.md | 67 + ...-page-aggregate-compat-slimming-gaps-v1.md | 57 + ...office-live-bridge-session-isolation-v1.md | 69 + ...fice-live-tool-resource-scope-bypass-v1.md | 66 + ...l-first-ai-markdown-edit-mouth-drift-v1.md | 43 + ...om-outline-envelope-test-embed-drift-v1.md | 29 + ...nlyoffice-session-current-scope-leak-v1.md | 51 + ...-mindmap-apply-ops-native-patch-only-v1.md | 57 + ...ai-target-picker-resource-target-gap-v1.md | 52 + ...ai-runtime-split-threshold-triggered-v1.md | 134 + ...i-onlyoffice-target-buffer-state-404-v1.md | 33 + ...-current-page-target-stale-workspace-v1.md | 32 + ...page-ai-runtime-stop-close-smoke-gap-v1.md | 49 + ...plugin-bridge-p2-productization-tail-v1.md | 80 + ...indmap-p2-apply-ops-and-ui-smoke-gap-v1.md | 57 + ...only-openclaw-provider-unit-test-gap-v1.md | 98 + ...esign-process-status-and-stale-entry-v1.md | 45 + ...9-agents-md-broken-design-references-v1.md | 43 + ...testing-reference-missing-new-smokes-v1.md | 49 + ...0-21-design-done-header-status-drift-v1.md | 39 + .../10-22-done-bug-stale-followup-text-v1.md | 38 + ...-batch-f-p1-p2-active-tail-checklist-v1.md | 2 +- ...current-priority-execution-checklist-v1.md | 2 +- ...1-8-mvp-post-process-execution-order-v1.md | 25 +- ...bal-content-type-page-width-settings-v1.md | 6 + ...3-25-local-folder-mineru-ocr-sidecar-v1.md | 413 ++ ...-local-file-operation-event-contract-v1.md | 2 +- ...red-shortcuts-sqlite-scoped-explorer-v1.md | 3 +- ...ttings-sqlite-preference-convergence-v1.md | 2 +- ...iletree-lazy-loading-sidex-alignment-v1.md | 2 +- ...letree-viewstate-generation-followup-v1.md | 4 +- ...avigation-page-route-guard-checklist-v1.md | 6 +- ...tion-breadcrumb-fetch-guard-followup-v1.md | 46 + ...e-ai-acp-agent-runtime-unified-layer-v1.md | 2 +- ...-page-ai-sidebar-runtime-owner-split-v1.md | 128 + ...-ai-context-envelope-and-run-receipt-v1.md | 2 +- ...rmes-reasonix-user-profile-isolation-v2.md | 126 +- ...indmap-skill-and-resource-generation-v1.md | 407 ++ ...7-44-chatonly-doubao-session-binding-v1.md | 292 ++ ...rst-agent-file-editing-control-plane-v1.md | 12 +- ...-page-ai-sidebar-runtime-owner-split-v1.md | 35 - ...7-43-onlyoffice-plugin-bridge-design-v1.md | 273 ++ .../7-35-reasonix-browser-test-contract-v1.md | 6 +- .../7-36-reasonix-skill-maintainer-v1.md | 6 +- ...reasonix-worker-evaluation-0524-bug2-v1.md | 0 ...yuan-reference-boundary-and-adoption-v1.md | 2 +- ...ture-next-priority-review-and-checklist.md | 2 + ...-page-ai-fast-block-edit-runtime-review.md | 6 +- .../10-current-mnote-ai-runtime-review-v1.md | 2 + .../11-current-full-architecture-review-v1.md | 2 + ...te-workbench-gap-execution-checklist-v1.md | 0 ...8-current-design-and-bug-hunt-review-v1.md | 99 + design/README.md | 11 +- ...6-05-29-local-folder-mineru-ocr-sidecar.md | 506 +++ .../plans/2026-05-30-page-ai-mindmap-skill.md | 394 ++ infra/onlyoffice/docker-compose.yml | 2 +- rust/Cargo.lock | 280 ++ rust/crates/bridge-runtime/src/lib.rs | 67 + .../007-ai-agent-profile-policy.sql | 43 + .../008-ai-external-conversation-bindings.sql | 28 + rust/crates/control-plane/src/migrations.rs | 11 + rust/crates/control-plane/src/model.rs | 71 + rust/crates/control-plane/src/sqlite.rs | 692 +++- rust/crates/control-plane/src/store.rs | 54 +- rust/crates/core-protocol/src/kernel.rs | 17 +- rust/crates/mnote-web/Cargo.toml | 1 + .../browser/document-resource-tab-runtime.js | 94 +- .../document-tiptap-conversion-runtime.js | 44 +- .../mnote-web/browser/filetree-runtime.js | 12 +- .../browser/sidebar-filetree-open-runtime.js | 2 +- .../sidebar-page-ai-markdown-runtime.js | 107 + .../sidebar-page-ai-permission-runtime.js | 132 + .../sidebar-page-ai-profile-runtime.js | 220 + .../browser/sidebar-page-ai-render-runtime.js | 1128 ++++++ .../browser/sidebar-page-ai-runtime.js | 3102 ++++---------- .../sidebar-page-ai-session-runtime.js | 613 +++ .../browser/sidebar-page-ai-skill-runtime.js | 285 ++ .../browser/sidebar-page-ai-target-runtime.js | 758 ++++ .../browser/sidebar-page-settings-runtime.js | 6 + .../mnote-web/browser/sidebar-tree-runtime.js | 377 +- rust/crates/mnote-web/src/acp_bridge.rs | 14 + .../mnote-web/src/acp_session_manager.rs | 47 + .../mnote-web/src/hermes_tools/manifest.rs | 1102 ++++- rust/crates/mnote-web/src/hermes_tools/mod.rs | 1 + .../src/hermes_tools/onlyoffice_live.rs | 1130 ++++++ .../mnote-web/src/hermes_tools/resource.rs | 702 +++- .../mnote-web/src/hermes_tools/skill.rs | 166 + .../mnote-web/src/page_aggregate/builder.rs | 28 +- .../mnote-web/src/routes/hermes_client.rs | 3572 ++++++++++++++++- .../mnote-web/src/routes/hermes_tools.rs | 2395 ++++++++++- .../src/routes/local_folder_source.rs | 116 +- .../src/routes/local_markdown_parser.rs | 36 +- rust/crates/mnote-web/src/routes/local_ocr.rs | 1881 +++++++++ .../src/routes/local_search_index.rs | 236 +- rust/crates/mnote-web/src/routes/mod.rs | 98 +- .../crates/mnote-web/src/routes/onlyoffice.rs | 426 +- .../mnote-web/src/routes/onlyoffice_bridge.rs | 2226 ++++++++++ .../mnote-web/src/routes/resource_trash.rs | 9 +- rust/crates/mnote-web/src/routes/search.rs | 1 + rust/crates/mnote-web/src/routes/web_shell.rs | 121 +- rust/crates/mnote-web/src/ssr/pages/layout.rs | 132 +- rust/crates/mnote-web/src/ssr/styles.rs | 62 +- rust/crates/mnote-web/src/transport/convex.rs | 31 +- .../mnote-leptos-tiptap-spike-island.d.ts | 40 +- .../mnote-leptos-tiptap-spike-island.js | 78 +- .../mnote-leptos-tiptap-spike-island_bg.wasm | Bin 2094263 -> 1953483 bytes ...te-leptos-tiptap-spike-island_bg.wasm.d.ts | 40 +- .../src/js/generated/tiptap_paragraph.js | 142 +- .../src/editor_runtime/style.rs | 71 + scripts/TESTING_REFERENCE.md | 13 +- scripts/reasonix-acp-wrapper.mjs | 62 +- ...ask455-local-folder-mindmap-clean-smoke.js | 179 +- scripts/task463-onlyoffice-resolver-smoke.js | 68 +- scripts/task490-runtime-surfaces-smoke.js | 156 +- ...02-page-ai-agent-selector-context-smoke.js | 294 +- .../task503-mindmap-skill-capability-smoke.js | 319 ++ ...k504-page-ai-history-agent-filter-smoke.js | 499 +++ scripts/task512-chatonly-doubao-sync-smoke.js | 499 +++ .../task513-chatonly-provider-sync-smoke.js | 512 +++ ...514-sidebar-dev-hot-reload-gating-smoke.js | 141 + ...ask515-onlyoffice-live-scope-http-smoke.js | 188 + ...ffice-bridge-multisession-browser-smoke.js | 194 + ...7-onlyoffice-bridge-plugin-direct-smoke.js | 229 ++ ...yoffice-real-iframe-session-scope-smoke.js | 471 +++ ...sk520-page-ai-raw-resource-target-smoke.js | 296 ++ ...page-aggregate-compat-fallback-contract.js | 99 + ...ai-onlyoffice-real-target-session-smoke.js | 416 ++ ...-workspace-object-identity-matrix-smoke.js | 331 ++ ...5-page-ai-mindmap-resource-target-smoke.js | 299 ++ scripts/task526-local-folder-ocr-api-smoke.js | 262 ++ skills/mnote-mindmap/SKILL.md | 47 + skills/mnote-onlyoffice-live/SKILL.md | 68 + 143 files changed, 29810 insertions(+), 3228 deletions(-) create mode 100644 bugs/03-rust-web/done/3-26-sidebar-dev-hot-reload-setinterval-v1.md create mode 100644 bugs/03-rust-web/process/3-27-mineru-ocr-design-without-runtime-implementation-v1.md create mode 100644 bugs/04-tree-domain/done/4-52-resource-lifecycle-retired-bridge-artifact-regression-v1.md create mode 100644 bugs/04-tree-domain/done/4-53-workspace-object-identity-matrix-gap-v1.md rename bugs/05-editor-mainline/{process => done}/2026-05-21-office-edit-sign-plugin-gap-review-v1.md (74%) rename bugs/05-editor-mainline/{process => done}/5-34-local-folder-media-sign-office-url-contract-v1.md (100%) rename bugs/05-editor-mainline/{process => done}/5-35-office-edit-mode-menu-and-guard-v1.md (69%) rename bugs/05-editor-mainline/{process => done}/5-36-onlyoffice-local-edit-save-callback-contract-v1.md (53%) rename bugs/05-editor-mainline/{process => done}/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md (80%) create mode 100644 bugs/05-editor-mainline/done/5-40-onlyoffice-bridge-plugin-noise-regression-v1.md create mode 100644 bugs/05-editor-mainline/done/5-41-page-aggregate-compat-slimming-gaps-v1.md create mode 100644 bugs/07-ai/done/7-45-onlyoffice-live-bridge-session-isolation-v1.md create mode 100644 bugs/07-ai/done/7-46-onlyoffice-live-tool-resource-scope-bypass-v1.md create mode 100644 bugs/07-ai/done/7-47-local-first-ai-markdown-edit-mouth-drift-v1.md create mode 100644 bugs/07-ai/done/7-48-mindmap-create-from-outline-envelope-test-embed-drift-v1.md create mode 100644 bugs/07-ai/done/7-50-onlyoffice-session-current-scope-leak-v1.md create mode 100644 bugs/07-ai/done/7-51-mindmap-apply-ops-native-patch-only-v1.md create mode 100644 bugs/07-ai/done/7-52-page-ai-target-picker-resource-target-gap-v1.md create mode 100644 bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md create mode 100644 bugs/07-ai/done/7-54-page-ai-onlyoffice-target-buffer-state-404-v1.md create mode 100644 bugs/07-ai/done/7-55-page-ai-current-page-target-stale-workspace-v1.md create mode 100644 bugs/07-ai/done/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md create mode 100644 bugs/07-ai/done/7-57-onlyoffice-plugin-bridge-p2-productization-tail-v1.md create mode 100644 bugs/07-ai/done/7-58-mindmap-p2-apply-ops-and-ui-smoke-gap-v1.md create mode 100644 bugs/07-ai/process/7-49-chatonly-openclaw-provider-unit-test-gap-v1.md create mode 100644 bugs/10-review/done/10-18-design-process-status-and-stale-entry-v1.md create mode 100644 bugs/10-review/done/10-19-agents-md-broken-design-references-v1.md create mode 100644 bugs/10-review/done/10-20-testing-reference-missing-new-smokes-v1.md create mode 100644 bugs/10-review/done/10-21-design-done-header-status-drift-v1.md create mode 100644 bugs/10-review/done/10-22-done-bug-stale-followup-text-v1.md rename design/03-rust-web/{process => done}/3-24-global-content-type-page-width-settings-v1.md (93%) create mode 100644 design/03-rust-web/process/3-25-local-folder-mineru-ocr-sidecar-v1.md rename design/05-editor-mainline/{process => done}/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md (97%) rename design/05-editor-mainline/{process => done}/5-31-page-settings-sqlite-preference-convergence-v1.md (99%) rename design/05-editor-mainline/{process => done}/5-32-filetree-lazy-loading-sidex-alignment-v1.md (99%) rename design/05-editor-mainline/{process => done}/5-33-navigation-page-route-guard-checklist-v1.md (96%) create mode 100644 design/05-editor-mainline/process/5-35-navigation-breadcrumb-fetch-guard-followup-v1.md create mode 100644 design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md rename design/07-ai/{process => done}/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md (63%) create mode 100644 design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md create mode 100644 design/07-ai/done/7-44-chatonly-doubao-session-binding-v1.md delete mode 100644 design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md create mode 100644 design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md rename design/07-ai/{process => reference}/7-35-reasonix-browser-test-contract-v1.md (92%) rename design/07-ai/{process => reference}/7-36-reasonix-skill-maintainer-v1.md (91%) rename design/07-ai/{process => reference}/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md (100%) rename design/10-review/{process => done}/17-sidex-mnote-workbench-gap-execution-checklist-v1.md (100%) create mode 100644 design/10-review/done/18-current-design-and-bug-hunt-review-v1.md create mode 100644 docs/superpowers/plans/2026-05-29-local-folder-mineru-ocr-sidecar.md create mode 100644 docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md create mode 100644 rust/crates/control-plane/migrations/007-ai-agent-profile-policy.sql create mode 100644 rust/crates/control-plane/migrations/008-ai-external-conversation-bindings.sql create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-markdown-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-permission-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-profile-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-render-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-session-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-skill-runtime.js create mode 100644 rust/crates/mnote-web/browser/sidebar-page-ai-target-runtime.js create mode 100644 rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs create mode 100644 rust/crates/mnote-web/src/routes/local_ocr.rs create mode 100644 rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs create mode 100644 scripts/task503-mindmap-skill-capability-smoke.js create mode 100644 scripts/task504-page-ai-history-agent-filter-smoke.js create mode 100644 scripts/task512-chatonly-doubao-sync-smoke.js create mode 100644 scripts/task513-chatonly-provider-sync-smoke.js create mode 100644 scripts/task514-sidebar-dev-hot-reload-gating-smoke.js create mode 100644 scripts/task515-onlyoffice-live-scope-http-smoke.js create mode 100644 scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js create mode 100644 scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js create mode 100644 scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js create mode 100644 scripts/task520-page-ai-raw-resource-target-smoke.js create mode 100644 scripts/task522-page-aggregate-compat-fallback-contract.js create mode 100644 scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js create mode 100644 scripts/task524-workspace-object-identity-matrix-smoke.js create mode 100644 scripts/task525-page-ai-mindmap-resource-target-smoke.js create mode 100644 scripts/task526-local-folder-ocr-api-smoke.js create mode 100644 skills/mnote-mindmap/SKILL.md create mode 100644 skills/mnote-onlyoffice-live/SKILL.md diff --git a/.gitignore b/.gitignore index 6a33fcee..890bdd12 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,7 @@ design/05-editor-mainline/reference-code # MNote 本地运行索引与一次性浏览器截图 /.mnote/ +/ai-sessions/ /filetree-*.png /task*-*.png diff --git a/AGENTS.md b/AGENTS.md index 9f774e28..288a3daf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -72,8 +72,9 @@ - 页面 AI 编辑当前 local-first 主路径为:页面定位到真实 `.md` 文件,MNote 计算 `AiAccessScope` / allowed roots / selection,Hermes 或 Reasonix 在白名单目录内用自身 patch/diff/文件编辑能力写入,MNote 通过 watcher / refresh 同步 tiptap。`mnote.doc.markdown_edit` 只作为 cloud / remote agent / compat fallback;`mnote.block.*` 保留为结构性辅助(拖拽排序等)。两层操作模型已获 CLI Main(Lark Doc)参考实现验证。流式 apply + suggest/review(参考 BlockNote AI)作为 Phase C 设计冻结,当前不实施。 - 需要架构判断时,优先参考: - `/mnt/Data1T/mnote/ARCHITECTURE.md` - - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md` - - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-tree-first-graph-kernel-v1.md` + - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md` + - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` + - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md` - `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md` - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-5-page-aggregate-single-truth-alignment-v1.md` - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-6-page-aggregate-alignment-checklist-v1.md` diff --git a/bugs/03-rust-web/done/3-26-sidebar-dev-hot-reload-setinterval-v1.md b/bugs/03-rust-web/done/3-26-sidebar-dev-hot-reload-setinterval-v1.md new file mode 100644 index 00000000..5417ad64 --- /dev/null +++ b/bugs/03-rust-web/done/3-26-sidebar-dev-hot-reload-setinterval-v1.md @@ -0,0 +1,46 @@ +# 3-26 Sidebar dev hot reload 在主 runtime 中使用 setInterval + +## 状态 + +- 状态:done +- Owner:03-rust-web / browser runtime +- 发现时间:2026-05-31 + +## 现象 + +`sidebar-tree-runtime.js` 在主 Sidebar runtime 中安装 dev hot reload,并无前置环境 guard 地执行 `window.setInterval(tick, 1000)`。项目架构约束要求浏览器主链默认禁止新增基于 `setInterval`、周期 `setTimeout` 或轮询 fallback 的数据刷新和状态同步;即使这是 dev hot reload,也应该显式限制在 debug/dev 边界。 + +## 证据 + +- `rust/crates/mnote-web/browser/sidebar-tree-runtime.js` 中 `installMnoteDevHotReload()` 执行: + - 先调用 `tick()`。 + - 再执行 `timer = window.setInterval(tick, 1000)`。 + - 末尾无条件调用 `installMnoteDevHotReload()`。 +- `tick()` 每次请求 `/api/dev/hot-reload`,服务端返回 `enabled !== true` 时才清理 timer;这仍意味着页面启动后先进入轮询逻辑。 + +## 影响 + +- 主 Sidebar runtime 默认携带 dev 轮询逻辑,和“主链不叠加轮询 fallback”的架构约束冲突。 +- 若 `/api/dev/hot-reload` 异常或返回形态变化,可能引入重复请求、console 噪音或性能误判。 +- 后续 worker 可能把这种模式复制到其他可见路径。 + +## 修复建议 + +- 在 Rust SSR bootstrap 中显式注入 dev/hot 模式标记,只有 dev hot 模式启用时才安装该逻辑。 +- 或将 hot reload 逻辑迁到 debug/internal runtime,不放在默认 Sidebar runtime。 +- 如果仍保留定时器,必须在设计/注释中说明退出条件和边界,并保证生产/普通 desktop 模式不可达。 + +## 本轮进展 + +- 2026-05-31: + - `sidebar-tree-runtime.js` 已改为通过 `import.meta.url` 检查当前模块 URL 是否携带 `devHot` cache buster;只有 dev hot 模式才安装 hot reload 轮询。 + - 已补 `layout.rs` 静态断言,禁止无条件 `installMnoteDevHotReload()` 回流。 + - 已通过 `node --check rust/crates/mnote-web/browser/sidebar-tree-runtime.js` 和 Rust 定点测试。 + - 已补 `scripts/task514-sidebar-dev-hot-reload-gating-smoke.js` 固化真实浏览器验证。 + - 验证通过:`node scripts/task514-sidebar-dev-hot-reload-gating-smoke.js`。结果显示普通入口 `hotReloadRequestCount=0`、`scriptHasDevHot=false`;hot 模式 `scriptHasDevHot=true`、`hotReloadRequestCount=2`、`data-mnote-dev-hot-reload=enabled`,且无 console/network 错误。 + +## 验收 + +- [x] 普通 `desktop` / 非 hot 入口打开后,浏览器不会请求 `/api/dev/hot-reload`。 +- [x] `npm run desktop:hot` 或等价 hot 模式下仍能刷新。 +- [x] `setInterval(tick, 1000)` 仅在 `mnoteDevHotReloadEnabled()` guard 后可达。 diff --git a/bugs/03-rust-web/process/3-27-mineru-ocr-design-without-runtime-implementation-v1.md b/bugs/03-rust-web/process/3-27-mineru-ocr-design-without-runtime-implementation-v1.md new file mode 100644 index 00000000..54de1a19 --- /dev/null +++ b/bugs/03-rust-web/process/3-27-mineru-ocr-design-without-runtime-implementation-v1.md @@ -0,0 +1,103 @@ +# 3-27 MinerU OCR 后端 runtime 已落地但缺前端任务链 + +## 状态 + +- 状态:process +- Owner:03-rust-web / local-folder OCR / MinerU sidecar +- 发现时间:2026-05-31 + +## 现象 + +P2 目标中包含 MinerU OCR 能力收口。当前已补后端 mock route、真实 MinerU HTTP client、sidecar 写入、`.mnote/ocr-index.json`、`includeOcr=true` 搜索命中和浏览器 API smoke。但 active job store、realtime job event、前端入口/任务栏仍未落地。 + +## 证据 + +- `rust/crates/mnote-web/src/routes/local_ocr.rs` 已注册 `jobs/status/read/insert`,`provider=mock` 能写入 `{pageStem}.ocr/*.ocr.md` 和 `.mnote/ocr-index.json`。 +- `provider=mineru` 在有 token 时会走真实 HTTP client:申请上传 URL、PUT 上传、轮询结果、下载 zip、提取 Markdown,并写入 `{pageStem}.ocr/*.ocr.md` / `.mnote/ocr-index.json`。该路径已有本地 HTTP mock 单测覆盖,不访问外网。 +- `local_search_index` 已支持 `includeOcr=true` 命中 OCR owner page;`task526-local-folder-ocr-api-smoke.js` 已覆盖浏览器上下文调用 mock OCR API、搜索命中和显式 insert 链接。 +- 设计中的活动任务生命周期、`local_ocr.job.updated` 和浏览器可见入口仍未完成。 + +## 影响 + +- 用户无法从本地图片或图片型 PDF 通过 UI 手动触发 MinerU OCR。 +- 搜索的 `includeOcr=true` 已能命中 OCR sidecar,但真实 MinerU 结果仍缺 UI 触发链和任务状态可见性。 +- AI 资源上下文无法优先读取已有 OCR Markdown。 + +## 下一步 + +1. 已完成后端 mock 最小闭环:路径规划、sidecar frontmatter、`.mnote/ocr-index.json`、mock OCR job route、status/read、Page Tree 过滤和 `includeOcr=true` 搜索 owner page。 +2. 已补浏览器 API smoke:mock OCR、status/read/jobs、`includeOcr=true` 搜索 owner page 和显式 insert link。 +3. 下一步接长任务状态、`local_ocr.job.updated` realtime 事件、前端 OCR 入口/任务栏和 AI 资源上下文读取 OCR sidecar。 + +## 验收 + +- [x] Rust route/helper 测试覆盖 sidecar 路径/frontmatter、index stale/error redaction、mock OCR job 写入、status/read、无 token、越界拒绝、非图片/PDF 拒绝、mock 失败 response 脱敏和显式 insert link。 +- [x] local search 测试覆盖 OCR 命中返回 owner page,OCR sidecar 不作为普通页面。 +- [x] Page Tree 测试覆盖 OCR sidecar 可在 File Tree 作为资源文件可见,但不作为普通页面进入 Page Tree。 +- [x] Rust route 测试覆盖无 token response 形态。 +- [x] Rust route 测试覆盖 `provider=mineru` 后端成功路径:申请上传 URL、PUT 上传、轮询结果、下载 zip、提取 Markdown、写 sidecar/index。 +- [~] 浏览器 smoke 覆盖图片/PDF 手动 OCR、任务栏状态、打开 OCR、搜索 OCR 命中和插入 OCR 链接。(当前 `task526` 覆盖 mock OCR API、搜索命中、显式 insert link 和 OCR sidecar resource tab 打开;真实 UI 入口/任务栏待做) + +## 2026-06-01 后端 mock 闭环记录 + +新增 `rust/crates/mnote-web/src/routes/local_ocr.rs`,注册: + +- `POST /api/local-folder/ocr/jobs` +- `GET /api/local-folder/ocr/jobs` +- `GET /api/local-folder/ocr/status` +- `GET /api/local-folder/ocr/read` +- `POST /api/local-folder/ocr/insert` + +当前真实 MinerU HTTP client 仍未接入;`provider=mock` 用于本地后端闭环和测试,`provider=mineru` 在缺少 token 时返回 `mineru_token_missing`,有 token 时返回 `mineru_runtime_not_enabled`,避免伪装真实能力已完成。 + +已通过验证: + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1` + +2026-06-01 续补 route 边界测试: + +- 越界来源路径拒绝:`local_ocr_path_escape` +- 非图片/PDF 来源拒绝:`local_ocr_source_type_unsupported` +- provider `mineru` 且缺 token 时拒绝:`mineru_token_missing` +- mock 失败响应与 `.mnote/ocr-index.json` 失败条目统一脱敏为 `provider_error_redacted` +- 显式 `ocr/insert` link 模式把 `[OCR:photo.png](./Page.ocr/photo.png.ocr.md)` 追加进 owner Markdown;未调用 insert 时不改正文 + +本文继续保持 `process`:前端 OCR 入口、任务栏和 active job / realtime event 尚未完成。 + +2026-06-01 只读复核更新: + +- Subagent 复核确认:route/mock/search 测试已落地,早期“没有实际 OCR route”的描述已经过时。 +- 本 bug 不归档的阻塞点更新为:真实 MinerU HTTP client、active job store / `local_ocr.job.updated`、前端入口/任务栏、AI 资源上下文读取 OCR sidecar 和完整 UI browser smoke。 + +2026-06-01 浏览器 API smoke 续补: + +- 新增 `scripts/task526-local-folder-ocr-api-smoke.js`,在真实浏览器登录态页面内通过 `fetch` 串起 `POST /api/local-folder/ocr/jobs`、`status`、`read`、`jobs`、`/api/search/documents includeOcr=true` 和 `POST /api/local-folder/ocr/insert`。 +- 已验证 `provider=mock` 会生成 `docs/Page.ocr/photo.png.ocr.md`,`includeOcr=false` 不命中 OCR 文本,`includeOcr=true` 返回 owner page 且带 `hasOcr/ocrEvidence`,显式 insert 才向 owner Markdown 追加 `[OCR:photo.png](...)`。 +- 续补后已验证 OCR sidecar 可作为 Markdown resource tab 打开,截图写入 `tmp/task526-local-folder-ocr-api-smoke/02-ocr-resource-tab.png`。 +- 已通过: + - `node --check scripts/task526-local-folder-ocr-api-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task526-local-folder-ocr-api-smoke.js` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1` + +2026-06-01 MinerU API 口径复核: + +- 官方文档当前仍以 `https://mineru.net/api/v4/extract/task` 或 `https://mineru.net/api/v4/file-urls/batch` 作为精准解析入口;`model_version` 支持 `pipeline` / `vlm` / `MinerU-HTML`,Markdown/JSON 为默认结果格式,图片/PDF/Office 等文档受文件大小与页数限制。 +- 当前设计稿中的“申请上传地址 -> PUT 上传 -> 轮询批量结果 -> 下载 zip -> 提取 Markdown”方向仍成立。 +- 旧回归测试曾要求 `MNOTE_MINERU_API_TOKEN` 存在且 provider 为 `mineru` 时返回 `mineru_runtime_not_enabled`;该口径已被真实后端 runtime 合同测试替代。 + +## 2026-06-01 后端 MinerU runtime 补齐记录 + +- `rust/crates/mnote-web/src/routes/local_ocr.rs` 已补 `mineru_api_base_url`、`mineru_poll_interval`、`mineru_max_polls` 配置函数。 +- `provider=mineru` 后端路径已接入 `run_mineru_ocr`,执行申请上传 URL、PUT 上传、轮询 batch 结果、下载 zip、提取 Markdown。 +- 新增本地 HTTP mock 测试 `local_ocr_jobs_route_runs_mineru_runtime_against_http_mock`,不访问外网,验证真实 client 合同和 sidecar/index 写入。 +- 已通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` + +本文继续保持 `process` 的剩余原因: + +- 前端本地文件 / 图片 / PDF 资源没有 OCR 操作入口。 +- OCR jobs 仍是同步请求 + `.mnote/ocr-index.json` 历史状态,没有 active job store。 +- 缺少 `local_ocr.job.updated` realtime event 与全局任务栏 UI。 +- AI 资源上下文还没有优先读取 OCR sidecar。 diff --git a/bugs/04-tree-domain/done/4-52-resource-lifecycle-retired-bridge-artifact-regression-v1.md b/bugs/04-tree-domain/done/4-52-resource-lifecycle-retired-bridge-artifact-regression-v1.md new file mode 100644 index 00000000..22847778 --- /dev/null +++ b/bugs/04-tree-domain/done/4-52-resource-lifecycle-retired-bridge-artifact-regression-v1.md @@ -0,0 +1,48 @@ +# 4-52 resource lifecycle 兼容路径在 Convex 退役后丢失 artifact / 拒绝 mindmap lifecycle + +## 状态 + +- 状态:done +- Owner:04-tree-domain / bridge-runtime / resource lifecycle command +- 发现时间:2026-06-01 +- 修复时间:2026-06-01 + +## 现象 + +执行 `cargo test -p mnote-web mindmap -- --test-threads=1` 时,mindmap 相关宽测曾失败: + +- `mindmap_put_derives_workspace_and_returns_tree_artifacts` +- `mindmap_command_apply_returns_object_artifacts_without_tree_resync` +- `mindmap_delete_restore_keeps_markdown_reference_out_of_lifecycle_command` +- `mindmap_trash_routes_delete_restore_purge_and_empty` +- `sidebar_runtime_routes_local_mindmap_and_office_assets` + +前两个失败是 `execute_retired_command_plan_with_artifacts()` 在 Convex 退役后仍能执行 fixture mutation,但把 Rust artifact plan 置为 `None`,导致调用方拿不到 `commandLog` / `domainEvent`。 + +后两个失败是 `tree.resource.archive/restore/purge/rename` 在 bridge-runtime 生成 resource-kind 专用函数名前,会先经过 `build_write_request()`;旧 `legacy_command_function_name()` 没有这些正式 tree resource command 名,导致 mindmap lifecycle 被 `retired_bridge_error()` 拒绝。 + +最后一个失败是 runtime 拆分后,OnlyOffice local open 逻辑已迁到 `sidebar-filetree-open-runtime.js`,但 Rust include 断言仍检查旧 `sidebar-tree-runtime.js` 字符串。 + +## 根因 + +- Convex 退役后,artifact 持久化不能再作为兼容路径成功条件;Rust artifact plan 应继续返回给调用方和 realtime consumer。 +- resource lifecycle command 的正式命名已从表面 compat alias 收口到 `tree.resource.*`,但旧 Convex 兼容映射表未允许这些名称通过前置 request 构造。 +- browser runtime 模块拆分后,测试断言没有同步到新的 canonical owner 文件。 + +## 修复 + +- `rust/crates/mnote-web/src/transport/convex.rs` + - `persist_runtime_command_artifacts()` 在 Convex 退役路径改为 no-op 成功。 + - `execute_retired_command_plan_with_artifacts()` 重新构造并返回 `RuntimeCommandArtifactPlan`,不重新启用 Convex artifact 持久化。 +- `rust/crates/bridge-runtime/src/lib.rs` + - `legacy_command_function_name()` 允许 `tree.resource.archive/restore/purge/rename` 通过前置 request 构造;最终函数名仍由 resource lifecycle plan 按资源类型分流。 +- `rust/crates/mnote-web/src/ssr/pages/layout.rs` + - OnlyOffice local open 断言改查 `SIDEBAR_FILETREE_OPEN_RUNTIME_JS`。 +- `rust/crates/mnote-web/src/routes/resource_trash.rs` + - `delete_json()` test helper 在状态码失败时输出 body,便于后续定位真实错误码。 + +## 验证 + +- `cargo test -p mnote-web mindmap -- --test-threads=1` + +结果:26 个 mindmap 相关测试全部通过。 diff --git a/bugs/04-tree-domain/done/4-53-workspace-object-identity-matrix-gap-v1.md b/bugs/04-tree-domain/done/4-53-workspace-object-identity-matrix-gap-v1.md new file mode 100644 index 00000000..f781137f --- /dev/null +++ b/bugs/04-tree-domain/done/4-53-workspace-object-identity-matrix-gap-v1.md @@ -0,0 +1,33 @@ +# 4-53 WorkspacePath / ObjectIdentity 浏览器矩阵缺口 + +## 状态 + +- 状态:done +- Owner:04-tree-domain / 05-editor-mainline runtime identity +- 发现时间:2026-06-01 +- 修复时间:2026-06-01 + +## 现象 + +P1 `WorkspacePath / ObjectIdentity` 已有底层协议与部分 smoke,但缺少一个单独覆盖 page `.md`、directory、raw file、mindmap、OnlyOffice 的浏览器矩阵。FileTree row、Resource Tab、OpenEditorsSnapshot、URL `resourceTab` 和 active tab identity 如果各自拼身份,后续 raw resource / mindmap / Office target 容易继续退化为“当前页”语义。 + +## 根因 + +已有 smoke 分散覆盖 copy-id、resource tab、mindmap 和 Office,但没有把统一 `ObjectWorkspacePath` 当作运行时消费合同统一断言。local folder 目录行还缺少 `local-dir:*` 的稳定 `documentId` fallback,resource tab 在部分本地资源打开路径下也缺少 `sourceKind` / `rootUri` fallback。 + +## 修复 + +- `rust/crates/mnote-web/browser/filetree-runtime.js` + - `readWorkspacePathFromRow()` 为 folder / index 行合成 `local-dir:{relativePath}`。 + - `fileTreeRowDocumentId()` 允许读取 `data-owner-document-id`,用于资源行 owner page 对齐。 +- `rust/crates/mnote-web/browser/document-resource-tab-runtime.js` + - 在 URL 参数缺失时,从 body dataset 或 FileTree row workspacePath 兜底读取 `sourceKind` / `rootUri`。 +- `scripts/task524-workspace-object-identity-matrix-smoke.js` + - 新增 browser smoke,覆盖 page `.md`、directory、raw text、mindmap、OnlyOffice 的 FileTree row workspacePath、OpenEditorsSnapshot、URL `resourceTab`、active tab identity 对齐。 + +## 验收 + +- [x] `node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js` +- [x] `node --check rust/crates/mnote-web/browser/filetree-runtime.js` +- [x] `node --check scripts/task524-workspace-object-identity-matrix-smoke.js` +- [x] `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task524-workspace-object-identity-matrix-smoke.js` diff --git a/bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md b/bugs/05-editor-mainline/done/2026-05-21-office-edit-sign-plugin-gap-review-v1.md similarity index 74% rename from bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md rename to bugs/05-editor-mainline/done/2026-05-21-office-edit-sign-plugin-gap-review-v1.md index 8ffad923..c4993f6a 100644 --- a/bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md +++ b/bugs/05-editor-mainline/done/2026-05-21-office-edit-sign-plugin-gap-review-v1.md @@ -1,5 +1,9 @@ # Office local-first 预览、编辑与插件噪音缺口审查 v1 +## 状态 + +- 状态:done + ## 背景 本轮只审查 OnlyOffice 与 MNote local-first 工作区之间的三个接口缺口: @@ -24,9 +28,9 @@ Context7 查询 `/onlyoffice/api.onlyoffice.com` 得到的关键口径: - `rust/crates/mnote-web/src/routes/media.rs` 的 `/api/media/sign` 当前只服务 Convex media asset,内部查询 `mediaAssets:getById` / `mediaAssets:refreshUrl`。local-folder asset 形如 `local:asset:`,不在 Convex media 表中,所以返回 404 是现状契约不匹配。 - `rust/crates/mnote-web/src/routes/onlyoffice.rs` 的 `/onlyoffice` 页面在 `resolveAssetUrlAndKey()` 中只要有 `assetId` 就请求 `/api/media/sign`;失败后静默保留传入的 `fileUrl`。这就是“当前 view 模式不阻断打开”的原因。 - local-folder Office 预览已经可以直接使用 `/api/local-folder/files/open?rootUri=...&path=...` 作为 `fileUrl`,不需要经过 `/api/media/sign`。 -- `/api/onlyoffice/callback` 当前仍代理 legacy Next writeback。对 local-folder 的 `status 2/6 -> 下载 body.url -> 原文件覆盖写回 -> watcher 同步` 没有完整闭环。 -- `layout.rs` 中正文附件菜单已有 `new-window`,但没有“使用编辑模式打开”。部分路径当前会默认生成 `mode=edit`,这与“默认只读、显式编辑”的产品口径不一致。 -- annotation 插件 404 / pageerror 暂未证明会影响文档渲染;当前更像是 OnlyOffice 静态插件包或自定义插件配置缺失导致的 console 噪音。 +- `/api/onlyoffice/callback` 已由 `5-36` 补齐 local-folder `status 2/6 -> 下载 body.url -> 原文件覆盖写回` 的后端契约;legacy Next 代理仍保留为 cloud/compat 边界。 +- `layout.rs` / browser runtime 已提供“使用编辑模式打开”入口,默认打开保持 `mode=view`,显式 edit 保留 guard。 +- annotation/custom assistant 插件噪音已由 `5-37` / `5-40` 分类:插件噪音不等于主文档失败,真实 `errorCode=-18`、WebSocket 失败或 iframe 空白不能被噪音掩盖。 ## 根因判断 @@ -46,7 +50,7 @@ P0 目标: - 菜单提供“使用编辑模式打开”入口。 - 编辑入口必须带 guard:清楚标记为实验能力,或在 local-folder writeback 未闭环时阻止/提示。 -P1 目标才是实现 local-folder callback 写回。 +P1 目标是实现 local-folder callback 写回;该项已由 `5-36` 完成后端契约。 ### 3. annotation 插件 404 / pageerror @@ -70,7 +74,7 @@ P0 目标: - P0:若保存闭环未完成,编辑入口必须有 guard / 实验标记。 - `5-36-onlyoffice-local-edit-save-callback-contract-v1.md` - - P1:设计或实现 local-folder callback 写回。 + - P1:local-folder callback 写回。 - P1:覆盖 status 2/6、下载 URL rewrite、路径权限、冲突保护。 - `5-37-onlyoffice-annotation-plugin-noise-policy-v1.md` @@ -99,9 +103,19 @@ P0 目标: - 菜单提供“使用编辑模式打开”,进入前有实验 guard。 - 已存在 Office resource tab 从 view 切 edit 会刷新同一 iframe URL,不再只激活旧 tab。 - annotation/custom assistant 插件 404 已归类为 non-critical noise,不作为主文档打开失败。 -- P1 仍保留: - - local-folder Office edit/save callback 写回闭环未实现,编辑模式仍不能承诺保存到原文件。 - - `onRequestEditRights` 事件重新初始化 edit URL 未实现。 +- P1 已拆分并收口: + - `5-36`:local-folder Office edit/save callback 写回后端契约已完成,覆盖 status 2/6、非写状态、未认证、路径越界。 + - `5-35`:`onRequestEditRights` 事件会重新初始化为 `mode=edit` URL,不只 reload 当前 view。 + - 本 umbrella review 仅作为缺口审查和拆分记录归档;后续真实 Office 编辑保存端到端浏览器验收若发现新问题,应另建具体 bug。 - 浏览器证据: - Reasonix:`tmp/reasonix-office-view-edit-plugin-2026-05-21/result.json` 与截图。 - Codex:`tmp/codex-office-view-edit-plugin-2026-05-21/result.json`、`01-office-view-mode.png`、`02-office-edit-mode.png`。 +- 2026-06-01 验证: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_page -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_callback -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_local_callback -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p adapter-onlyoffice callback_preparation -- --test-threads=1` + - `node --check scripts/task463-onlyoffice-resolver-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task463-onlyoffice-resolver-smoke.js` + - `node --check scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` + - `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` diff --git a/bugs/05-editor-mainline/process/5-34-local-folder-media-sign-office-url-contract-v1.md b/bugs/05-editor-mainline/done/5-34-local-folder-media-sign-office-url-contract-v1.md similarity index 100% rename from bugs/05-editor-mainline/process/5-34-local-folder-media-sign-office-url-contract-v1.md rename to bugs/05-editor-mainline/done/5-34-local-folder-media-sign-office-url-contract-v1.md diff --git a/bugs/05-editor-mainline/process/5-35-office-edit-mode-menu-and-guard-v1.md b/bugs/05-editor-mainline/done/5-35-office-edit-mode-menu-and-guard-v1.md similarity index 69% rename from bugs/05-editor-mainline/process/5-35-office-edit-mode-menu-and-guard-v1.md rename to bugs/05-editor-mainline/done/5-35-office-edit-mode-menu-and-guard-v1.md index ead5d57e..6b75aff5 100644 --- a/bugs/05-editor-mainline/process/5-35-office-edit-mode-menu-and-guard-v1.md +++ b/bugs/05-editor-mainline/done/5-35-office-edit-mode-menu-and-guard-v1.md @@ -1,5 +1,9 @@ # 5-35 Office 编辑模式菜单与保护 +## 状态 + +- 状态:done + ## 目标 Office 文件默认只读打开;在正文附件三点菜单和文件树资源右键菜单中增加“使用编辑模式打开”入口。保存闭环未完成前,编辑入口必须有 guard 或明确实验标记。 @@ -28,16 +32,30 @@ ONLYOFFICE `mode=edit` 只是编辑器初始化模式。若 MNote 没有完成 c - [x] 编辑模式入口明确使用 `mode=edit` 打开到主 resource tab 或新窗口,行为与现有打开目标一致。 - [x] 在 local-folder save callback 未闭环时,编辑入口有 guard:可提示“编辑保存仍在实验中”,或通过 data/status 标记便于测试识别。 - [x] 已存在 Office resource tab 从 `mode=view` 切到显式 `mode=edit` 时,刷新同一 tab 的 iframe URL,而不是只激活旧 tab。 -- [ ] 若启用 `onRequestEditRights`,必须重新初始化为 edit URL,不只 reload 当前 view。(P1,未实现) +- [x] 若启用 `onRequestEditRights`,必须重新初始化为 edit URL,不只 reload 当前 view。 ## 验收 -- `cargo test -p mnote-web sidebar_tree_js -- --test-threads=1` -- `cargo test -p mnote-web onlyoffice -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web sidebar_tree_runtime_opens_office_assets_through_resource_shell -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_page -- --test-threads=1` - 浏览器截图:默认打开是只读;菜单中存在编辑入口;点击编辑入口后的页面 URL / debug state 包含 `mode=edit` 或 guard 提示。 ## 本轮执行记录 +- 2026-06-01:Codex 补齐 `onRequestEditRights` P1。 + - `/onlyoffice` 页面新增 `editModeLocationHref()`,触发 `onRequestEditRights` 时将当前 URL 的 `mode` 设置为 `edit` 并 `window.location.replace(editHref)`,避免只 reload 当前 view。 + - 新增 `onlyoffice_page_reinitializes_edit_url_on_request_edit_rights` 契约测试,断言事件处理、debug 标记和 edit URL replacement 存在。 + - 复测 `task463` 时发现并修复普通 `openTarget="new-window"` 被 `forceNewWindow || forceEditMode` 误判成 `mode=edit` 的状态泄漏;现在只有 `forceEditMode` 才会进入 edit,普通新窗口继续默认 view / `/office-preview`。 + - 验证通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_page -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web sidebar_tree_runtime_opens_office_assets_through_resource_shell -- --test-threads=1` + - `node --check scripts/task463-onlyoffice-resolver-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task463-onlyoffice-resolver-smoke.js` + - `node --check scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` + - `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` + - 2026-05-21:Reasonix worker B 卡在计划阶段后由 Codex 终止;本条实现来自其它 Reasonix 结果与 Codex 复核修正。 - `buildOnlyOfficeOpenUrl` 默认 mode 从 `'edit'` 改为 `'view'`。 - `buildOnlyOfficeOpenPath` 默认 mode 从 `'edit'` 改为 `'view'`。 diff --git a/bugs/05-editor-mainline/process/5-36-onlyoffice-local-edit-save-callback-contract-v1.md b/bugs/05-editor-mainline/done/5-36-onlyoffice-local-edit-save-callback-contract-v1.md similarity index 53% rename from bugs/05-editor-mainline/process/5-36-onlyoffice-local-edit-save-callback-contract-v1.md rename to bugs/05-editor-mainline/done/5-36-onlyoffice-local-edit-save-callback-contract-v1.md index f22b7263..9c808213 100644 --- a/bugs/05-editor-mainline/process/5-36-onlyoffice-local-edit-save-callback-contract-v1.md +++ b/bugs/05-editor-mainline/done/5-36-onlyoffice-local-edit-save-callback-contract-v1.md @@ -1,12 +1,16 @@ # 5-36 OnlyOffice local-folder 编辑保存 callback 契约 +## 状态 + +- 状态:done + ## 目标 为 local-folder Office 编辑保存建立 callback 写回契约。P1 可以先落设计和测试骨架;若实现,必须覆盖 status 2/6 的下载写回和路径安全。 ## 原因 -ONLYOFFICE 官方保存链路要求 callback `status === 2` 或 `status === 6` 时,集成后端下载 `body.url` 并写回原文件。当前 `mnote-web` callback 仍代理 legacy Next,local-folder 写回未闭环。 +ONLYOFFICE 官方保存链路要求 callback `status === 2` 或 `status === 6` 时,集成后端下载 `body.url` 并写回原文件。此前 `mnote-web` callback 仍代理 legacy Next,local-folder 写回未闭环。本轮已补齐 local-folder callback 写回路径。 ## 允许修改 @@ -23,21 +27,38 @@ ONLYOFFICE 官方保存链路要求 callback `status === 2` 或 `status === 6` ## Checklist -- [ ] 明确 local asset callback 定位:从 `assetId` / `fileUrl` / session 推导 rootUri 与 path。 -- [ ] status 非 2/6 时返回 `{ "error": 0 }`,不写文件。 -- [ ] status 2/6 时下载 rewritten `body.url`。 -- [ ] 写回前校验目标路径属于当前 local root allowed roots。 -- [ ] 写回后触发 watcher / projection 刷新或说明现有 watcher 如何感知。 -- [ ] 若本轮不实现完整写回,必须在编辑入口保留 guard,不让用户以为保存已支持。 +- [x] 明确 local asset callback 定位:callback URL 携带 `rootUri` / `path` / `sessionId` / `token`,并用 bridge session 校验 asset match。 +- [x] status 非 2/6 时返回 `{ "error": 0 }`,不写文件。 +- [x] status 2/6 时下载 rewritten `body.url`。 +- [x] 写回前校验目标路径属于当前 local root allowed roots。 +- [x] 写回后写入原始本地文件;后续页面刷新由现有 local-folder watcher / projection refresh 感知。浏览器编辑保存端到端 smoke 另列后续验收,不作为本 bug 阻塞项。 +- [x] 编辑入口仍保留 guard,不让用户误解为完整协作编辑能力已产品化。 ## 验收 -- `cargo test -p mnote-web onlyoffice_callback -- --test-threads=1` -- `cargo test -p mnote-web -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_callback -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_local_callback -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p adapter-onlyoffice callback_preparation -- --test-threads=1` - 后续浏览器编辑保存验收需单独设计,不纳入 P0。 ## 本轮执行记录 +- 2026-06-01:Codex 复核当前实现并补齐 callback 写回回归测试。 + - `OnlyOfficeCallbackQuery` 已携带 `root_uri` / `path` / `session_id` / `token`。 + - `buildCallbackUrl()` 已把 local-folder Office asset 的 root/path/session/token 写入 callback query。 + - `local_folder_onlyoffice_callback()` 已校验 root/path、bridge session token、session asset match,并通过 `resolve_onlyoffice_local_file_path()` 阻断 root escape。 + - status 2/6 通过 `prepare_callback()` rewrite 后下载 `body.url` 并写回原始本地文件;非 2/6 返回成功且不写文件。 + - 新增/确认测试覆盖: + - `onlyoffice_local_callback_rejects_unauthenticated_local_write` + - `onlyoffice_local_callback_writes_status_two_body_to_original_file` + - `onlyoffice_local_callback_writes_status_six_body_to_original_file` + - `onlyoffice_local_callback_rejects_root_escape_path` + - `onlyoffice_local_callback_ignores_non_write_status` + - 验证通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_callback -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_local_callback -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p adapter-onlyoffice callback_preparation -- --test-threads=1` + - 2026-05-21:Reasonix worker C 分析完成。 **结论:本轮不应实现完整写回。** diff --git a/bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md b/bugs/05-editor-mainline/done/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md similarity index 80% rename from bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md rename to bugs/05-editor-mainline/done/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md index 2913bfd9..180432cb 100644 --- a/bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md +++ b/bugs/05-editor-mainline/done/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md @@ -1,5 +1,7 @@ # 5-37 OnlyOffice annotation 插件噪音策略 +> 2026-06-01 复核:本文是 2026-05-21 旧口径。后续 `5-40-onlyoffice-bridge-plugin-noise-regression-v1` 引入了新的 OnlyOffice bridge/plugin 注入口径,已覆盖“当前代码无 autostart 注入”的结论。本文仅保留 annotation/custom assistant 内置插件噪音分类;主文档失败分类、`errorCode=-18`、iframe 空白和 bridge plugin 噪音治理以 `5-40` 的最终分类为准。`5-40` 已通过 `task518-onlyoffice-real-iframe-session-scope-smoke.js` 的 `errorClassification` 验收,本文不再作为活跃 process 缺陷。 + ## 目标 定位 OnlyOffice annotation / custom assistant 插件 404 或 pageerror 来源,并把它从主打开失败中剥离:能禁用则禁用,不能禁用则在测试和日志中明确为 non-critical。 @@ -25,7 +27,7 @@ ONLYOFFICE 插件通过 `editorConfig.plugins.autostart` 和 `pluginsData` 注 - [x] 找到 annotation/custom assistant 插件配置或请求来源。 - [x] 若 MNote 当前不依赖该插件,禁用无效 autostart / pluginsData。(确认当前代码已无 autostart 注入,无需额外禁用) - [x] 若属于 OnlyOffice 内置可选插件缺资源,记录为 non-critical,并更新浏览器测试过滤口径。 -- [ ] 补测试或文档,确保 `errorCode=-18` / WebSocket 失败仍被视为失败,不被插件噪音掩盖。(P1,后续补充) +- [x] 补测试或文档,确保 `errorCode=-18` / WebSocket 失败仍被视为失败,不被插件噪音掩盖。(由 `5-40` / `task518-onlyoffice-real-iframe-session-scope-smoke.js` 的 `errorClassification.mainDocument` 覆盖) ## 验收 diff --git a/bugs/05-editor-mainline/done/5-40-onlyoffice-bridge-plugin-noise-regression-v1.md b/bugs/05-editor-mainline/done/5-40-onlyoffice-bridge-plugin-noise-regression-v1.md new file mode 100644 index 00000000..38a911c2 --- /dev/null +++ b/bugs/05-editor-mainline/done/5-40-onlyoffice-bridge-plugin-noise-regression-v1.md @@ -0,0 +1,67 @@ +# 5-40 ONLYOFFICE bridge 插件注入后噪音口径需复测 + +## 状态 + +- 状态:done +- Owner:05-editor-mainline / OnlyOffice preview-edit / browser smoke +- 发现时间:2026-05-31 + +## 现象 + +旧缺陷 `5-37` 的结论是当前代码没有注入 `plugins.autostart` / `pluginsData`,因此 annotation/custom assistant 插件 404 可作为 OnlyOffice 内置非关键噪音处理。但近期 ONLYOFFICE live bridge 已在 `onlyoffice.rs` 中重新注入 MNote bridge 插件,这会让旧噪音策略失效,必须重新区分 MNote bridge 插件失败、OnlyOffice 内置插件噪音和真正主文档加载失败。 + +## 证据 + +- `bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md` 记录:“当前代码已无 autostart 注入,无需额外禁用”。 +- `rust/crates/mnote-web/src/routes/onlyoffice.rs` 当前 `editorConfig.plugins` 注入: + - `autostart: [MNOTE_AGENT_PLUGIN_GUID]` + - `pluginsData: [bridgePluginConfigUrl.toString()]` + +## 影响 + +- clean browser 测试里 MNote bridge 插件加载失败可能被错误归类为“OnlyOffice 内置插件噪音”。 +- 相反,主 iframe 空白、`errorCode=-18`、DocumentServer WebSocket 失败也可能被泛化过滤掉。 +- Office live agent 能力上线后,插件加载失败将不再是纯噪音,而是 AI Office 工具不可用。 + +## 最小复现建议 + +1. clean browser 打开 docx/xlsx/pptx。 +2. 记录 console、pageerror、network 404/500、OnlyOffice iframe ready state。 +3. 分别验证: + - MNote bridge 插件 config/index 是否成功加载。 + - OnlyOffice 内置 annotation/custom assistant 缺资源是否仍为 non-critical。 + - 主 iframe 空白、`errorCode=-18`、WebSocket 失败仍判定为失败。 + +## 修复建议 + +- 更新 `5-37` 或新 smoke 的错误分类规则:MNote bridge 插件错误不等同于内置插件噪音。 +- 在 OnlyOffice smoke 中输出插件分类字段,例如 `mnoteBridgePluginOk`、`builtinPluginNoiseOnly`、`mainDocumentReady`。 +- 对 bridge 插件 config/index 增加 route 单测和 browser smoke 断言。 + +## 本轮进展 + +- 2026-06-01:新增并通过 `scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js`,在真实 Chromium 中 mock `Asc.plugin` 后直接加载 bridge plugin index,验证 session 注册、token 错误拒绝、`selection.get` / `document.insert_text` command 消费和 result 回传。 +- 该 smoke 证明 MNote bridge plugin index / HTTP loop 自身可用,但不覆盖真实 ONLYOFFICE iframe / DocumentServer 的 autostart、内置插件噪音、主文档 ready 或 `errorCode=-18` 分类,因此本 bug 仍保留在 `process/`。 +- 2026-06-01:新增并通过 `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js`,在真实 ONLYOFFICE iframe / DocumentServer 下验证 MNote bridge 插件可 autostart 注册并回收命令。该 smoke 记录到的 404 均为 `/api/onlyoffice/bridge/plugin/index/translations/langs.json` 与 `/api/onlyoffice/bridge/plugin/index/translations/zh-CN.json`,当前可归类为 bridge 插件翻译资源噪声;它没有阻断 session 注册、`selection.get` 或工具层授权 dry-run。 + +- 2026-06-01:增强并通过 `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js`,输出 `errorClassification`: + - `mnoteBridgePlugin.httpErrors=[]` + - `mnoteBridgePlugin.sessionsRegistered=true` + - `mnoteBridgePlugin.commandLoopOk=true` + - `bridgeTranslationNoise.count=6`,仅包含 `/api/onlyoffice/bridge/plugin/index/translations/langs.json` 和 `zh-CN.json` 404 + - `builtinPluginNoise.count=0` + - `mainDocument.ready=true` + - `mainDocument.failures=[]` + - `mainDocument.errorCodeMinus18=false` + 该分类把 MNote bridge 插件失败、bridge 翻译资源噪音、OnlyOffice 内置插件噪音和主文档失败分开;`errorCode=-18` / 主 iframe 空白不会被插件噪音吞掉。 + +## 验收 + +- [x] Clean browser smoke 能区分三类错误:MNote bridge 插件失败、OnlyOffice 内置插件噪音、主文档加载失败。 +- [x] `errorCode=-18` / 主 iframe 空白不会被插件噪音过滤吞掉。 +- [x] bridge 插件不可用时,Office 文档预览结论和 Office AI 工具可用性结论分开报告。 + +## 最终验证 + +- `node --check scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` +- `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` diff --git a/bugs/05-editor-mainline/done/5-41-page-aggregate-compat-slimming-gaps-v1.md b/bugs/05-editor-mainline/done/5-41-page-aggregate-compat-slimming-gaps-v1.md new file mode 100644 index 00000000..3fba31d9 --- /dev/null +++ b/bugs/05-editor-mainline/done/5-41-page-aggregate-compat-slimming-gaps-v1.md @@ -0,0 +1,57 @@ +# 5-41 Page Aggregate compat 瘦身剩余缺口 + +## 状态 + +- 状态:done +- Owner:05-editor-mainline / Page Aggregate / browser document conversion +- 发现时间:2026-06-01 + +## 现象 + +Page Aggregate 已经完成 local-first 主链和多个单一真源修复。2026-06-01 复核后,`body.content`、compat join 和浏览器 legacy content 降级被明确收口为 v1 兼容面:它们仍是 active runtime 的兼容读写字段,但不再作为 local-first 浏览器主事实源。 + +## 证据 + +- `rust/crates/core-protocol/src/page_aggregate.rs` 中 `PageBody.content` 仍是必填字段。 +- `rust/crates/mnote-web/src/routes/local_folder_source.rs` 的 local-first aggregate 仍会填充 `body.content`。 +- `rust/crates/bridge-runtime/src/lib.rs` 的 cloud/compat aggregate 路径仍支持 `CompatMetaContentJoin`。 +- `rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js` 已在 2026-06-01 调整为 `blockDocument/editorDocument` 优先,`local_markdown.content` 与 `compat.legacy_content` 只作为缺少 block document 时的降级路径;`scripts/task522-page-aggregate-compat-fallback-contract.js` 覆盖了这几个 source 分支。 +- `rust/crates/mnote-web/src/routes/documents.rs` 的保存兼容面仍同时携带 `editorDocument`、`content`、`tiptapDocument`。 +- `rust/crates/mnote-web/src/page_aggregate/builder.rs` 的默认 source 已在 2026-06-01 改为 `KernelProjection`,显式 `.source(PageAggregateSource::CompatMetaContentJoin)` 仍保留 compat 路径。 + +## 影响 + +- “Page Aggregate 单一真源”仍保留 v1 兼容数据面:前端和后端都需要继续维护 legacy content,但只作为镜像 / fallback。 +- local-first 浏览器转换层已优先消费 block document;后端协议和 compat 保存面继续保留 legacy content,保证 cloud/compat fallback 和旧保存面不被破坏。 +- 后续若要删除或改为可选 `body.content`,必须进入 `mnote.page_aggregate.v2` 或等价协议升级 checklist,不能在 v1 中直接删除。 + +## 下一步建议 + +- `PageBody.content` 在 `mnote.page_aggregate.v1` 中继续保持必填兼容字段,用于 legacy/cloud/compat fallback、旧保存面和降级回读。 +- `body.blockDocument` / `editorDocument` 是 local-first 浏览器主消费面;`body.content` 不再作为 active editor 初始化的优先事实源。 +- `CompatMetaContentJoin` 继续只作为显式 cloud/compat substrate 边界保留;`PageAggregateBuilder::new()` 默认 source 保持 `KernelProjection`。 +- `body.content` 改为可选或删除的退出条件:必须先有 `mnote.page_aggregate.v2` 协议或迁移 checklist,证明 cloud/compat 保存面、外部 agent、历史 fixture 和降级读取全部不再依赖该字段。 + +## 验收 + +- [x] local-first 浏览器转换优先消费 `body.blockDocument`,`pageBodyTiptapDocumentSource(...)` 在 `blockDocument` 存在时返回 `page_aggregate.block_document`。 +- [x] `body.content` 仅在缺少 `blockDocument` / `editorDocument` 时作为 local markdown legacy fallback。 +- [x] Builder 默认 source 不再是 `CompatMetaContentJoin`。 +- [x] `compat.legacy_content` 降级路径有明确 source 标记和测试覆盖。 +- [x] 设计稿明确 `body.content` 的长期状态:v1 保留为必填兼容镜像 / fallback;v2 或后续协议升级再评估可选或删除。 + +## 2026-06-01 验证 + +- `node --check rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js` +- `node --check scripts/task522-page-aggregate-compat-fallback-contract.js` +- `node scripts/task522-page-aggregate-compat-fallback-contract.js` +- `cargo test -p mnote-web document_shell_returns_page_aggregate_snapshot -- --test-threads=1` +- `cargo test -p mnote-web page_aggregate::builder::tests -- --test-threads=1` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task167-local-markdown-title-body-options-no-convex-smoke.js` + +## 2026-06-01 收口决策 + +- `PageBody.content`:v1 保留必填,语义降级为兼容镜像 / fallback,不作为 local-first active editor 主事实源。 +- `body.blockDocument` / `editorDocument`:local-first 浏览器转换优先消费的 canonical block view。 +- `compat.legacy_content`:仅当缺少 `blockDocument` / `editorDocument` 时可被浏览器转换层使用,并通过 `task522-page-aggregate-compat-fallback-contract.js` 固化 source 标记。 +- `CompatMetaContentJoin`:显式 compat substrate 边界,保留到 cloud/legacy 保存面完成协议升级,不再是 builder 默认 source。 diff --git a/bugs/07-ai/done/7-45-onlyoffice-live-bridge-session-isolation-v1.md b/bugs/07-ai/done/7-45-onlyoffice-live-bridge-session-isolation-v1.md new file mode 100644 index 00000000..d9d223a5 --- /dev/null +++ b/bugs/07-ai/done/7-45-onlyoffice-live-bridge-session-isolation-v1.md @@ -0,0 +1,69 @@ +# 7-45 ONLYOFFICE live bridge session 隔离风险 + +## 状态 + +- 状态:done +- Owner:07-ai / OnlyOffice live bridge / mnote-web +- 发现时间:2026-05-31 + +## 现象 + +ONLYOFFICE live bridge session 当前是进程内全局状态。工具调用未显式传 `onlyofficeSessionId` / `bridgeSessionId` 时,会 fallback 到最近活跃 session;同一文档的 bridge session id 又由 `docKey` 派生,重复打开同文档或多用户/多 tab 打开不同 Office 文档时,存在命令落到错误 Office tab 或 token 覆盖的风险。 + +## 证据 + +- `rust/crates/mnote-web/src/routes/onlyoffice.rs` 生成 `bridgeSessionId = "mnote-oo-" + fileState.docKey`。 +- `rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs` 的 `register_session` 按 `session_id` 覆盖 `token`、`document_id`、`asset_id` 和 `last_seen_millis`。 +- `rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs` 的 `current_session_info()` 直接取全局 `last_seen_millis` 最大值。 +- `rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs` 的 `resolve_session_id()` 在未传 session id 时 fallback 到 `current_session_info()`。 + +## 影响 + +- Page AI 或 Hermes tool 可能在多 Office tab 场景写错目标文档。 +- 同一文档重复打开可能互相覆盖 bridge token,使旧 tab 的插件长轮询或结果回传失效。 +- 多用户共享同一 mnote-web 进程时,全局最近 session 可能跨用户泄漏目标选择。 + +## 最小复现建议 + +1. 打开两个不同 Office 文档,或同一文档两个 tab。 +2. 不传 `onlyofficeSessionId` 调用 `mnote.onlyoffice.session.current` 与一个写工具,例如 `mnote.onlyoffice.document.insert_text`。 +3. 观察返回 session 是否只由最近活跃 tab 决定。 +4. 同一文档双 tab 复测 token 覆盖后,旧 tab `commands/next` 或 `results` 是否返回 401 / 无结果。 + +## 修复建议 + +- bridge session id 加入 browser tab 级随机后缀,不只使用 `docKey`。 +- Page AI run payload 必须携带当前 resource tab 的 explicit `onlyofficeSessionId`;写工具禁止默认 fallback 写入。 +- `current_session` 只能作为只读诊断工具,不能作为写工具默认目标。 +- session state 至少按 actor/session/document/resource 维度过滤。 + +## 本轮进展 + +- 2026-05-31: + - `onlyoffice.rs` 已把 `bridgeSessionId` 从仅基于 `docKey` 改为 `docKey + bridgeSessionSalt`,避免同文档多 tab 共用同一个 bridge session id。 + - `onlyoffice_live.rs` 已禁止读/写 action fallback 到全局最近 session;读写工具必须显式传 `onlyofficeSessionId` / `bridgeSessionId`。 + - `onlyoffice.rs` 的本地 callback 已绑定 bridge `sessionId` + `token`,未认证本地写回返回 401 并保持原文件不变。 + - 已补 Rust 定点测试覆盖缺 explicit session 的读/写工具拒绝,以及未认证 local callback 拒绝。 + - 已补 `scripts/task515-onlyoffice-live-scope-http-smoke.js` 覆盖 HTTP 层缺 explicit session 返回 400。 + - 已补并通过 `scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js`,在真实浏览器中验证 A/B 两个 bridge session 的 token 校验、command queue 和 result 回收互不串台,错误 token 返回 401。 +- 2026-06-01: + - 已补并通过 `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js`,在真实 ONLYOFFICE iframe / DocumentServer 下打开同一 docx 两个 tab 和另一个 docx,验证同文档双 tab 共享 `docKey` 但使用不同 `bridgeSessionId`,三个插件 session 均能注册并各自回收 `selection.get` command。 + - `task518` 同时覆盖显式传 B session 但 scope=A 时返回 403,以及 scope=B 授权 dry-run 返回 200,证明真实 iframe session 能被工具层按显式 session 和 resource scope 约束。 + - Page AI open editors snapshot / target package 已开始保留 Office `onlyofficeSessionId` / `bridgeSessionId`,服务端 `agentTargetPackage` 与 `aiAccessScope.allowedResourceIds` 已能保留 Office asset、session 和 `resource:onlyoffice:{documentId}:{assetId}` 候选;新增 Rust 定点测试 `hermes_client_run_body_preserves_onlyoffice_target_scope` 覆盖该合同。 + - ONLYOFFICE iframe 在设置 `__MNOTE_ONLYOFFICE_DEBUG__` 后会向父窗口发送 `mnote:onlyoffice-bridge-ready`,resource tab runtime 收到后事件驱动刷新 open editors snapshot;Page AI 发送前也会拒绝没有 `onlyofficeSessionId` 的 Office target,避免 bridge 未就绪时发起 run。 + - `task518` 已扩展并通过非 dry-run 写入落点验证:通过 `mnote.onlyoffice.document.insert_text` 向 Office B 写入唯一 marker,再通过真实 iframe bridge `document.export` 导出 A/B 内容,断言 B 包含 marker 且 A 不包含;截图保存到 `tmp/task518-onlyoffice-real-iframe-session-scope-smoke/screenshots/office-a-after-write.png` 和 `office-b-after-write.png`。 + - 已补并通过 `scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js`:在真实文档页内打开 Office resource tab,等待 iframe bridge ready 后通过 Page AI target picker 选择 Office target,断言 `editorTarget` 与 `targetPackage` 均冻结真实 `onlyofficeSessionId` / `bridgeSessionId`,并断言无 `consoleErrors` / `networkFailures` / `httpErrors`。 + +当前 P0 安全阻断已覆盖“工具不能隐式读写全局最近 session”“callback 不能未认证写本地文件”“bridge session/token/queue 在浏览器 HTTP 层隔离”“真实 iframe 插件 session 显式授权边界”“Page AI run scope 不再被服务端压回当前页面 id”“Office bridge 未就绪时 Page AI 发送前拒绝”“真实 iframe 非 dry-run 写入不串台”和“真实 Page AI UI 从 Office iframe 目标取到 live `bridgeSessionId` 并冻结进 run payload”。 + +## 验收 + +- [x] Rust 单测覆盖页面生成同 docKey 双 session 随机 session id。 +- [x] Rust 单测覆盖读/写工具缺 explicit session id 时拒绝。 +- [x] Rust 单测覆盖本地 callback 缺 bridge session/token 时拒绝。 +- [x] Browser smoke 覆盖两个 bridge session 的 token、command queue 与 result 隔离。 +- [x] Browser smoke 覆盖两个真实 Office iframe tab 下插件注册、sessionId 隔离和 command 回收。 +- [x] Rust 单测覆盖 Page AI Office target package / aiAccessScope 保留 session 与 resource scope。 +- [x] 前端事件驱动刷新覆盖 ONLYOFFICE bridge ready 消息,发送前拒绝缺 session 的 Office target。 +- [x] Browser smoke 覆盖两个真实 Office iframe tab 下非 dry-run 写入目标不串台。 +- [x] Browser smoke 覆盖 Page AI target picker 从真实 Office iframe target 读取 live `onlyofficeSessionId` 并写入 run payload。 diff --git a/bugs/07-ai/done/7-46-onlyoffice-live-tool-resource-scope-bypass-v1.md b/bugs/07-ai/done/7-46-onlyoffice-live-tool-resource-scope-bypass-v1.md new file mode 100644 index 00000000..af2c0d6a --- /dev/null +++ b/bugs/07-ai/done/7-46-onlyoffice-live-tool-resource-scope-bypass-v1.md @@ -0,0 +1,66 @@ +# 7-46 ONLYOFFICE live tool 缺少 resource scope 绑定 + +## 状态 + +- 状态:done +- Owner:07-ai / Hermes tools / OnlyOffice live bridge +- 发现时间:2026-05-31 + +## 现象 + +ONLYOFFICE live 写工具当前主要检查 `idempotencyKey`、`dryRun`、`aiAccessScope.permissionLevel` 和 command context 写权限,但没有把 bridge session 的 `documentId` / `assetId` 与 `aiAccessScope.allowedResourceIds` 绑定。调用方如果显式传入另一个已注册 Office session,存在越过当前 target resource scope 写入非授权资源的风险。 + +## 证据 + +- `rust/crates/mnote-web/src/routes/hermes_tools.rs` 注册了多组 `mnote.onlyoffice.*` 读写工具。 +- `rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs` 的 `run_write_action()` 调用 `ensure_write_authorized()` 后立即解析 session 并执行 bridge command。 +- `rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs` 的 `resolve_session_id()` 只解析显式 session 或全局 current session,没有验证该 session 对应的 resource 是否在 `allowedResourceIds` 内。 +- 对照 `rust/crates/mnote-web/src/hermes_tools/resource.rs`,mindmap/resource 工具已有 `ensure_resource_scope_allowed()` 校验 `allowedResourceIds` / `objectIdentity`。 + +## 影响 + +- Page AI 当前 target 是资源 A 时,模型或恶意调用可传入资源 B 的 `bridgeSessionId`,尝试写入 B。 +- 写入审计会显示工具有写权限,但缺少“写的是哪个 resource、是否被 allowedResourceIds 授权”的闭环。 +- 多 tab session fallback 与本 bug 叠加时,错误写入更难被用户发现。 + +## 最小复现建议 + +1. 构造 `aiAccessScope.allowedResourceIds = [A]`。 +2. 注册两个 ONLYOFFICE bridge session:A 和 B。 +3. 调用 `mnote.onlyoffice.sheet.set_value` 或 `mnote.onlyoffice.document.insert_text`,显式传 B 的 `bridgeSessionId`。 +4. 期望:返回 403;当前风险:只要通用写权限通过就可能执行。 + +## 修复建议 + +- `BridgeSessionInfo` 暴露稳定 `documentId`、`assetId`、`objectIdentity`。 +- ONLYOFFICE live 工具增加与 resource 工具等价的 scope 校验。 +- 写工具返回 receipt 时包含 `resourceKind=office`、`documentId`、`assetId`、`onlyofficeSessionId` 与 permission decision。 +- dry-run 也必须执行 scope 校验,不能只返回 wouldWrite。 + +## 本轮进展 + +- 2026-05-31: + - `onlyoffice_live.rs` 已在读/写 action 执行前校验 explicit session 对应的 `sessionId` / `documentId` / `assetId` / `resource:office:{documentId}:{assetId}` 是否包含在 `aiAccessScope.allowedResourceIds`。 + - 缺失 `aiAccessScope` 或空 `allowedResourceIds` 现在返回 403,不再兼容放行;dry-run 同样执行该 scope 校验。 + - `manifest.rs` 已为 OnlyOffice live 工具声明 `aiAccessScope.allowedResourceIds` 和 `onlyofficeSessionId` / `bridgeSessionId` 的 `anyOf` 合同。 + - 已补 Rust 定点测试覆盖 `allowedResourceIds=[asset_a]` 时禁止写入 session `asset_b`,`allowedResourceIds=[asset_allowed]` 时允许生成 dry-run plan,缺 scope 时返回 403,以及 manifest 合同。 + - 已补并通过 `scripts/task515-onlyoffice-live-scope-http-smoke.js`:HTTP 层覆盖缺 explicit session 400、scope 不匹配 403、缺 scope 403、授权 scope dry-run 200。 +- 2026-06-01: + - resource scope candidate 已同时接受 `resource:office:{documentId}:{assetId}` 与 FileTree / resource 对象侧使用的 `resource:onlyoffice:{documentId}:{assetId}`,避免真实 Page AI target 使用 OnlyOffice object identity 时被误拒。 + - 已补并通过 `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js`:真实 ONLYOFFICE iframe / DocumentServer 下,显式传入 Office B 的 `bridgeSessionId` 但 `aiAccessScope.allowedResourceIds=[Office A]` 时返回 403;授权 B 的 `assetId` / `resource:onlyoffice:{documentId}:{assetId}` 时 dry-run 返回 200。 + - `document-resource-tab-runtime.js` / `sidebar-page-ai-runtime.js` / `hermes_client.rs` 已补最小 target scope 链路:Office resource target 可把 `onlyofficeSessionId` 写入 target package,服务端 sanitize 不再丢弃 `primaryTargetId`、`targets[]`、`assetId`、`onlyofficeSessionId`,本地 run instructions 的 `aiAccessScope.allowedResourceIds` 会包含 Office asset、session 和 `resource:onlyoffice:{documentId}:{assetId}`。新增 `hermes_client_run_body_preserves_onlyoffice_target_scope` 证明服务端不再把 Office target scope 降级为当前页面 id。 + - 本地 agent instructions 已明确要求从 `agentRunEnvelope.targetPackage.onlyofficeSessionId` 或对应 target 取值传给 `mnote.onlyoffice.*` 工具,不允许 fallback 到最近活跃 Office session。 + - `task518` 已扩展并通过授权 B session 的非 dry-run 写入验证:写入后 `document.export` 证明 B 包含唯一 marker,A 不包含,补齐真实 iframe 层写入落点证据。 + - 已补并通过 `scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js`:真实 Page AI UI 选择 Office resource target 后,run payload 中 `editorTarget.onlyofficeSessionId`、`targetPackage.onlyofficeSessionId` 和 `targetPackage.targets[0].onlyofficeSessionId` 均等于 iframe live bridge session;`allowedFiles` 只包含选中 Office 文件路径,且无 buffer-state 404 / console error。 + +当前 `task518` 已覆盖真实 iframe session + 工具层 resource scope + 非 dry-run 写入落点,`task523` 补齐真实 Page AI UI target picker 到 live Office session 的 run payload 绑定;组合后覆盖“UI 只授权选中 Office target,工具层拒绝未授权 session”的端到端安全边界。 + +## 验收 + +- [x] Rust 单测覆盖 allowedResourceIds 不包含 session resource 时写工具返回 403。 +- [x] Rust 单测覆盖 allowedResourceIds 包含 `assetId` 或 `objectIdentity` 时允许执行。 +- [x] Rust 单测覆盖缺失 / 空 resource scope 时拒绝。 +- [x] HTTP smoke 覆盖工具层 session/scope 边界。 +- [x] Browser smoke 覆盖真实 ONLYOFFICE iframe session 的工具层 A/B resource scope 边界。 +- [x] Rust 单测覆盖 Page AI Office target package 生成的 aiAccessScope 包含 Office asset/session/object identity。 +- [x] Browser smoke 覆盖真实 Page AI UI 选择 Office target 后只把该 Office 的 live session 与 relativePath 冻结进 run payload;工具层 A/B session 越权拒写由 `task518` 覆盖。 diff --git a/bugs/07-ai/done/7-47-local-first-ai-markdown-edit-mouth-drift-v1.md b/bugs/07-ai/done/7-47-local-first-ai-markdown-edit-mouth-drift-v1.md new file mode 100644 index 00000000..729f7ebc --- /dev/null +++ b/bugs/07-ai/done/7-47-local-first-ai-markdown-edit-mouth-drift-v1.md @@ -0,0 +1,43 @@ +# 7-47 local-first Page AI 写入入口口径漂移 + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI / design governance +- 发现时间:2026-05-31 + +## 现象 + +`design/10-review/done/11-current-full-architecture-review-v1.md` 保留了“`mnote.doc.markdown_edit` 已是简单正文编辑主路径”的历史结论。但当前 AGENTS、ARCHITECTURE、CURRENT_ARCHITECTURE 与 `7-18` 都已经把 local-first 普通 Markdown 编辑主路径改为:定位真实 `.md` 文件,Hermes/Reasonix 在 allowed roots 内使用自身 patch/diff/文件编辑能力写入,再由 watcher / BufferStore / Page Aggregate 同步。旧 review 结论容易误导后续 worker 继续扩 `mnote.doc.markdown_edit`。 + +## 证据 + +- `design/10-review/done/11-current-full-architecture-review-v1.md` 写明 `mnote.doc.markdown_edit` 是简单正文编辑主路径。 +- `AGENTS.md` 与 `ARCHITECTURE.md` 当前口径明确:`mnote.doc.markdown_edit` 只作为 cloud / remote agent / compat fallback。 +- `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 明确要求 Agent Target Resolver、allowed roots/files、dirty guard 和 agent 原生 patch/diff 主路径。 + +## 影响 + +- 后续 Page AI 任务可能绕开 `7-18` 的 target package / allowed roots / dirty conflict 模型。 +- AI 写入审计、文件版本冲突和 watcher 同步难以统一。 +- `mnote.page.save` / `mnote.doc.markdown_edit` 可能被继续当成 local-first 精确编辑入口扩张。 + +## 修复建议 + +- 在 `11-current-full-architecture-review-v1.md` 补充“历史快照,local-first 主路径已被 `7-18` 覆盖”的说明,或在 `7-18` 中添加覆盖旧 review 的显式引用。 +- Page AI 新任务默认从 `7-18` 拆 checklist,不从 `11` 的旧 tool 主路径拆实现。 +- 对 Hermes tool guidance 增加断言:local-first 普通 Markdown 编辑优先文件引用和 patch/diff,工具写入只作为 fallback。 + +## 本轮进展 + +- 2026-05-31:已在 `design/10-review/done/11-current-full-architecture-review-v1.md` 顶部补充历史快照说明,明确当前 local-first 普通 Markdown 编辑主路径以 `AGENTS.md`、`CURRENT_ARCHITECTURE.md`、`ARCHITECTURE.md` 和 `7-18` 为准。 +- 2026-06-01:已补 Page AI run 的 `mnote.agent_target_package.v1` 输入和后端 sanitize / allowedFiles 派生,避免 local-first agent 只拿到目录级 `allowedRoots` 而缺少冻结目标文件。该进展只覆盖运行时输入合同,target chip / picker、真实 agent 写入回收和 dirty conflict 仍按 `7-18` 后续阶段推进。 + +- 2026-06-01:已检查 Hermes client runtime guidance。local-first 分支已经明确“普通 Markdown 编辑优先使用 agent 原生 patch/diff 写入真实文件”;remote/cloud/compat 分支中 `mnote_doc_markdown_edit` 的描述已补上“远端 / cloud / compat”限定,测试名同步改为 `hermes_client_run_guidance_prefers_markdown_edit_only_for_remote_compat_plain_body_edits`。 +- 2026-06-01:已给 `design/10-review/done/08`、`09`、`10` 补充历史快照说明,避免旧 review 结论继续覆盖 `7-18` 当前口径。 + +## 验收 + +- [x] `rg -n "markdown_edit.*主路径|简单正文编辑主路径|应优先调用 mnote_doc_markdown_edit|mnote_doc_markdown_edit for plain" design AGENTS.md ARCHITECTURE.md CURRENT_ARCHITECTURE.md rust/crates/mnote-web/src/routes/hermes_client.rs -g '*.md' -g '*.rs'` 的剩余命中均属于历史快照说明、已退役/降级口径、old 目录或 remote/cloud/compat 分支。 +- [x] Page AI task prompt / skill guidance 中明确区分 local-first 主路径与 cloud/remote/compat fallback。 +- [x] `cargo test -p mnote-web hermes_client_run_guidance_prefers_markdown_edit_only_for_remote_compat_plain_body_edits -- --test-threads=1` diff --git a/bugs/07-ai/done/7-48-mindmap-create-from-outline-envelope-test-embed-drift-v1.md b/bugs/07-ai/done/7-48-mindmap-create-from-outline-envelope-test-embed-drift-v1.md new file mode 100644 index 00000000..0f3c3449 --- /dev/null +++ b/bugs/07-ai/done/7-48-mindmap-create-from-outline-envelope-test-embed-drift-v1.md @@ -0,0 +1,29 @@ +# 7-48 Mindmap create_from_outline envelope 单测缺少 embed 边界 + +## 状态 + +- 状态:done +- Owner:07-ai / Hermes tools / mindmap resource +- 发现时间:2026-05-31 +- 修复时间:2026-05-31 + +## 现象 + +`cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib hermes_tools_mindmap -- --test-threads=1` 中 `hermes_tools_mindmap_create_from_outline_writes_default_envelope` 失败,返回: + +```text +mnote_resource_page_not_found: 找不到要绑定 mindmap 的本地 Markdown 页面 +``` + +## 根因 + +该用例只验证 `mnote.mindmap.create_from_outline` 生成默认 `.mindmap.json` envelope,但 payload 未显式设置 `embedIntoPage`。当前工具合同中 `embedIntoPage` 默认是 `true`,而测试 fixture 没有创建 `README.md`,导致资源文件写入后进入页面 embed 阶段并失败。 + +## 修复 + +- 在纯 envelope 写入用例里显式设置 `embedIntoPage: false`。 +- 保留另一个 `hermes_tools_mindmap_create_from_outline_can_embed_into_local_markdown_page` 用例继续覆盖显式 `embedIntoPage=true` 的页面绑定行为。 + +## 验证 + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib hermes_tools_mindmap -- --test-threads=1` diff --git a/bugs/07-ai/done/7-50-onlyoffice-session-current-scope-leak-v1.md b/bugs/07-ai/done/7-50-onlyoffice-session-current-scope-leak-v1.md new file mode 100644 index 00000000..797ada1d --- /dev/null +++ b/bugs/07-ai/done/7-50-onlyoffice-session-current-scope-leak-v1.md @@ -0,0 +1,51 @@ +# 7-50 ONLYOFFICE session.current 诊断工具缺少 resource scope 过滤 + +## 状态 + +- 状态:done +- Owner:07-ai / OnlyOffice live bridge / Hermes tools +- 发现时间:2026-06-01 + +## 现象 + +`mnote.onlyoffice.session.current` 是诊断工具,不会执行读写动作;但它在未传 `onlyofficeSessionId` / `bridgeSessionId` 时仍会 fallback 到进程内最近活跃 OnlyOffice bridge session,并返回 `sessionId`、`documentId`、`assetId`、`fileType`、pending command/result 计数等元数据。 + +这与读写工具已经要求 explicit session + `aiAccessScope.allowedResourceIds` 的收口方向不完全一致。若 Page AI 当前 target=A,但进程内最近活跃 Office session 属于 resource=B,模型可能通过 `session.current` 看到 B 的 session 元数据。 + +## 证据 + +- `rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs` 中 `session_current()` 允许缺 session id 时使用 `current_session_info()`。 +- `rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs` 中 `current_session_info()` 返回全局最近活跃 session。 +- Reasonix 只读复核 `reasonix-2026-05-31T16-38-36-472Z-63f3a41c` 判断:这不是写绕过,但属于低级信息泄漏风险;建议 `session_current` 也加入 scope 校验或过滤返回字段。 + +## 影响 + +- 不会直接写入或读取文档正文,因此风险低于 `7-45` / `7-46`。 +- 可能暴露非当前 target resource 的 Office session 元数据,给后续工具调用或模型选择目标带来混淆。 +- 与 OnlyOffice live bridge 的最小权限口径不一致。 + +## 修复建议 + +- `session_current` 若传 explicit session id,应校验该 session 对应的 `sessionId` / `documentId` / `assetId` / `resource:office:{documentId}:{assetId}` 是否在 `aiAccessScope.allowedResourceIds` 中。 +- `session_current` 若未传 explicit session id,不应返回全局最近活跃 session;可以改为返回 `mnote_onlyoffice_session_explicit_required`,或只在 debug/admin 边界允许。 +- 如果保留诊断 fallback,至少过滤 `documentId` / `assetId` 等跨 resource 元数据,并在 manifest 标注只用于诊断。 + +## 本轮处理 + +- 2026-06-01:`mnote.onlyoffice.session.current` 已改为复用 `resolve_explicit_session_id()` 与 `ensure_onlyoffice_resource_scope_allowed()`。 +- 已删除 `onlyoffice_bridge::current_session_info()` 全局最近 session fallback,避免诊断工具继续返回非当前 target 的 session 元数据。 +- `manifest.rs` 中 `mnote.onlyoffice.session.current` 已复用 OnlyOffice live 工具 schema,要求 `aiAccessScope.allowedResourceIds`,并通过 `anyOf` 要求 `onlyofficeSessionId` 或 `bridgeSessionId`。 +- `scripts/task515-onlyoffice-live-scope-http-smoke.js` 已扩展覆盖 `session.current` 缺 explicit session 返回 400、scope 不匹配返回 403、授权 scope 返回 session 元数据。 + +## 验收 + +- [x] Rust 单测覆盖 target=A 的 `aiAccessScope.allowedResourceIds` 不能通过 `session.current` 获取 resource=B 的 session 元数据。 +- [x] 缺 explicit session id 的 `session.current` 不再返回全局最近 session。 +- [x] `task515` HTTP smoke 覆盖 `session.current` scope 边界。 + +验证: + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib hermes_tools_onlyoffice_session_current -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib hermes_tools_manifest_describes_onlyoffice_live_scope -- --test-threads=1` +- `node --check scripts/task515-onlyoffice-live-scope-http-smoke.js` +- `node scripts/task515-onlyoffice-live-scope-http-smoke.js` diff --git a/bugs/07-ai/done/7-51-mindmap-apply-ops-native-patch-only-v1.md b/bugs/07-ai/done/7-51-mindmap-apply-ops-native-patch-only-v1.md new file mode 100644 index 00000000..2bceda05 --- /dev/null +++ b/bugs/07-ai/done/7-51-mindmap-apply-ops-native-patch-only-v1.md @@ -0,0 +1,57 @@ +# 7-51 mindmap apply_ops 结构化写入与可见性缺口 + +## 状态 + +- 状态:done,工具层最小结构化写入、刷新后 embedded mindmap id 保真、真实 mindmap resource tab Page AI target 已修复;更丰富 `apply_ops` 指令面扩展另拆 follow-up,不阻塞本 bug 归档 +- Owner:07-ai / Hermes tools / mindmap resource +- 发现时间:2026-06-01 + +## 现象 + +`mnote.mindmap.apply_ops` 的非 dry-run 路径曾不执行结构化写入,而是在完成资源路径和写权限校验后返回 `mnote_resource_native_patch_required`,提示 agent 使用原生 patch 编辑授权文件。这与 `7-42` 第二批目标“把 `apply_ops` 从提示 agent patch 文件收口到结构化写入”不一致。 + +2026-06-01 本轮已完成工具层最小修复:`dryRun=false` 可执行 `updateText` / `updateNode`、`insertChild` / `addChild`、`deleteNode`,写入后返回 `revision`、`changedFiles`、`markdownSummary`,并保留 `view`、未知顶层字段和未知 node 字段。当前缺口转为浏览器可见性和 Page AI resource target 集成。 + +## 证据 + +- `rust/crates/mnote-web/src/hermes_tools/resource.rs` 的 `mindmap_apply_ops()` 已实现最小结构化写入。 +- `rust/crates/mnote-web/src/routes/hermes_tools.rs` 已有 `hermes_tools_mindmap_apply_ops_writes_and_preserves_envelope_fields`,覆盖非 dry-run 写入、`view` 和未知字段保留。 +- `rust/crates/mnote-web/src/routes/hermes_tools.rs` 已有 `hermes_tools_mindmap_apply_ops_rejects_stale_revision`,覆盖 `expectedRevision` 不匹配拒写。 +- `rust/crates/mnote-web/src/routes/hermes_tools.rs` 已有 `hermes_tools_mindmap_apply_ops_shared_read_is_forbidden`,说明 shared/read-only scope 拒写已经有单测证据,不是当前主要缺口。 +- `task455`、`task524`、`task525` 已覆盖 embedded mindmap 刷新、FileTree / Resource Tab 可见性和真实 Page AI mindmap target/contextRefs。 + +## 影响 + +- Agent 已可通过结构化 tool 安全执行最小增删改 mindmap node,不再只能回退到文件 patch。 +- `view`、未知字段保留和 revision conflict 已由工具层单测覆盖。 +- Page AI mindmap 第二批的最小可用链路已覆盖:tool 结构化写入、embedded mindmap 刷新、FileTree / Resource Tab 可见性,以及真实 Page AI mindmap target/contextRefs。后续缺口转为真实编辑需求下的更丰富 `apply_ops` 指令面。 + +## 修复建议 + +- 按真实编辑需求继续扩展 `apply_ops`,例如 `moveNode`、`insertSiblingAfter`、`setHyperlink`、`setRefs`、`appendNote`、`patchView`。 + +## 验收 + +- [x] Rust 单测覆盖 `apply_ops` 非 dry-run 结构化写入。 +- [x] Rust 单测覆盖 `view` 和未知字段保留。 +- [x] Rust 单测覆盖 revision mismatch 返回 conflict。 +- [x] Rust 单测覆盖 shared/read-only scope 下写工具拒绝。 +- [x] Browser smoke 覆盖 mindmap 资源在 File Tree / Resource Tab 可见。 +- [x] Browser smoke 覆盖真实 mindmap resource tab 注入 Page AI `active_editor` contextRef / `targetPackage`。 +- [x] `task455-local-folder-mindmap-clean-smoke.js` 刷新后 `mindmapId` 保持新建资源文件名,不退化为 `"mindmap"`。 + +## 本轮验证 + +- `cargo test -p mnote-web hermes_tools_mindmap_apply_ops -- --test-threads=1` +- `cargo test -p mnote-web mindmap -- --test-threads=1` +- 2026-06-01 复跑失败:`MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task455-local-folder-mindmap-clean-smoke.js` + - 失败点:`刷新后 mindmapId 应保持不变` + - 证据:`tmp/task455-local-folder-mindmap-clean-smoke/result.json` + - 关键现象:刷新前 `mindmapId=mindmap-647356316`,刷新后 DOM `mindmapId=mindmap`;FileTree 仍有 `local-file:CleanPage/mindmap-647356316.json` 行。 +- 2026-06-01 修复后复跑通过:`MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task455-local-folder-mindmap-clean-smoke.js` + - 修复点:`blockDocument.blocks[].attrs` 保留 `mindmapId/sourcePath/rootNodeId`,浏览器 `document-tiptap-conversion-runtime.js` 消费 blockDocument 时读取这些 attrs。 + - 补充验证:`cargo test -p bridge-runtime page_aggregate_block_document_preserves_mindmap_projection_attrs -- --test-threads=1`,`cargo test -p mnote-web local_markdown_generated_mindmap_id_roundtrips_as_mindmap_block -- --test-threads=1`。 + - 回归验证:`MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task524-workspace-object-identity-matrix-smoke.js`。 +- 2026-06-01 新增并通过:`MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task525-page-ai-mindmap-resource-target-smoke.js` + - 覆盖真实 local-folder mindmap resource tab 打开后,Page AI run payload 中 `contextRefs.active_editor.resourceKind=mindmap`。 + - 覆盖 `targetPackage.primaryTargetId`、`targetPackage.currentFile`、`allowedFiles` 指向 `Page/map.mindmap.json`。 diff --git a/bugs/07-ai/done/7-52-page-ai-target-picker-resource-target-gap-v1.md b/bugs/07-ai/done/7-52-page-ai-target-picker-resource-target-gap-v1.md new file mode 100644 index 00000000..ec901945 --- /dev/null +++ b/bugs/07-ai/done/7-52-page-ai-target-picker-resource-target-gap-v1.md @@ -0,0 +1,52 @@ +# 7-52 Page AI target picker 与 resource target 仍未闭环 + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI sidebar runtime / Agent Target Resolver +- 发现时间:2026-06-01 + +## 现象 + +Page AI 已经有 agent selector、contextRefs popover、`targetPackage` 和 `allowedFiles` 基础输入。2026-06-01 已补上 page target、mindmap resource target、OnlyOffice resource target 与 raw local resource target 的 composer chip / picker / payload 冻结闭环;mindmap / raw file `active_editor` contextRef 均已携带 `targetId` / `objectIdentity` / `resourceKind` / `assetId` / `relativePath`。跨 workspace 多 target 的产品化确认继续由 `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 跟踪,不再由本文阻塞 target picker 收口。 + +## 证据 + +- `rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` 已有 `currentPageAiOpenEditorsSnapshot()`、`currentPageAiEditorTarget()`、target chip / picker 和 `pageAiBuildAgentTargetPackage()`。 +- `scripts/task502-page-ai-agent-selector-context-smoke.js` 已覆盖 page target button / popover / chip,并通过 mock `resourceEditors` 覆盖 mindmap target 选择,断言 run payload 的 `targetPackage.primaryTargetId`、`targets[]`、`resourceKind=mindmap`、`relativePath=maps/Task502.mindmap.json`、`policy.writeRequiresExplicitTarget=true`;同时断言 `active_editor` contextRef 携带 mindmap `targetId` / `objectIdentity` / `resourceKind` / `assetId` / `relativePath`。 +- 2026-06-01 验证命令:`MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task502-page-ai-agent-selector-context-smoke.js`,截图:`tmp/task502-page-ai-agent-selector-context-smoke/01-agent-selector-context.png`。 +- `scripts/task453-local-folder-page-ai-changed-files-smoke.js` 覆盖 target snapshot 冻结、跨 workspace 阻断、dirty buffer 阻断,但不是 target picker UI。 +- `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 仍把 target chip/picker、跨 workspace 多选确认、真实 agent 写入回收列为未完成。 +- OnlyOffice 工具层 session/scope 已有 `task515` - `task518` 覆盖;`task523-page-ai-onlyoffice-real-target-session-smoke.js` 已补真实 Page AI target 到 `onlyofficeSessionId` / `bridgeSessionId` 的 UI 绑定。 +- `mnote-mindmap` skill 已注册,mindmap target 的 `active_editor` contextRef 已携带资源身份;`task525-page-ai-mindmap-resource-target-smoke.js` 已补真实 mindmap resource tab target / contextRefs 复测。 +- `scripts/task520-page-ai-raw-resource-target-smoke.js` 已补真实 raw local resource tab:打开 `Page/notes.txt` 后 Page AI target chip 指向 `notes.txt`,run payload 冻结 `targetPackage.primaryTargetId=resource:file:{rootUri}:Page/notes.txt`,`allowedFiles=["Page/notes.txt"]`,并断言 `objectIdentity` 不再退化成 `[object Object]`。 + +## 影响 + +- Page AI UI 已能清楚告诉用户当前 page / mindmap / OnlyOffice target。 +- Page AI target picker 已覆盖 page / mindmap / OnlyOffice / raw file 四类当前 P1 目标,不再退化为“当前页”语义。 +- 真实 agent 写入回收、跨 workspace 多 target 和 mindmap resource tab 自动注入的更大产品化项继续由 `7-18` / `7-42` / `7-51` 跟踪。 + +## 下一步建议 + +- 若继续扩多目标选择,新增跨 workspace 多 target 确认 smoke,并归入 `7-18`。 +- 若继续扩 mindmap 多目标或更细粒度 contextRefs,另拆 `7-42` / `7-51` follow-up,不再由本文阻塞 target picker 收口。 + +## 验收 + +- [x] Page AI composer 可见 page target chip。 +- [x] target picker 可在当前 page 与 mindmap resource tab 间切换。 +- [x] run payload 冻结 page `targetPackage.targets[0]`。 +- [x] run payload 冻结 mindmap resource `targetPackage.targets[0]`。 +- [x] OnlyOffice target 不会把 A 页授权误用于 B session。 +- [x] mindmap resource tab 可作为 `resourceKind=mindmap` target。 +- [x] mindmap `active_editor` contextRef 携带 `targetId` / `objectIdentity` / `resourceKind` / `assetId`。 +- [x] raw file target 可从真实 resource tab 候选选择并冻结到 run payload。 +- [x] 真实 mindmap resource tab target / contextRefs 已由 `task525` 覆盖。 + +## 本轮验证 + +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- `node --check scripts/task520-page-ai-raw-resource-target-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task520-page-ai-raw-resource-target-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task502-page-ai-agent-selector-context-smoke.js` diff --git a/bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md b/bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md new file mode 100644 index 00000000..ef77ab3f --- /dev/null +++ b/bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md @@ -0,0 +1,134 @@ +# 7-53 Page AI runtime 已触发继续拆分阈值 + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI sidebar runtime +- 发现时间:2026-06-01 + +## 现象 + +`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` 曾约 3458 行,已经超过 `design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md` 中设定的 2500 行继续拆分阈值。文件内仍混合 UI render、run orchestration 等多类职责。 + +同时,`sidebar-tree-runtime.js` 已不再初始化 `pageUiState.pageAi*` 状态,Page AI 默认值由 `sidebar-page-ai-runtime.js` 的 `ensurePageAiStateFacade()` 集中兜底;但 tree runtime 仍传入共享 `pageUiState` 对象并保留少量 Page AI 代理函数,后续子模块拆分仍未闭环。 + +## 证据 + +- `sidebar-page-ai-runtime.js` 曾约 3458 行;2026-06-01 render helper 续补后降至 2498 行。 +- `sidebar-page-ai-markdown-runtime.js` 已承接 Page AI Markdown / conversation 文本渲染 helper。 +- `sidebar-page-ai-profile-runtime.js` 已承接 provider/profile/history filter/usage helper。 +- `sidebar-page-ai-permission-runtime.js` 已承接 ACP permission message/dialog/resolve helper。 +- `sidebar-page-ai-session-runtime.js` 已承接 session storage、backend session list/detail/search/resume/delete 和 runtime event replay helper。 +- `sidebar-page-ai-skill-runtime.js` 已承接 skill source、skill preference、Hermes builtin 隐藏和 Reasonix memory preference helper。 +- `sidebar-page-ai-target-runtime.js` 已承接 OpenEditorsSnapshot target 派生、WorkspacePath、run target snapshot、contextRefs、agentTargetPackage 和 target writable guard helper。 +- `sidebar-page-ai-runtime.js` 包含 `function ensurePageAiStateFacade`,并集中初始化 `pageAiAcpRuntime: 'reasonix'` 等 Page AI 默认状态。 +- `sidebar-tree-runtime.js` 不再包含 `pageAiAcpRuntime: 'reasonix'` 等 `pageAi*:` 默认字段,只保留 `open-page-ai` 主壳入口和代理函数。 +- `design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md` 第 3 节仍将以下项列为未完成: + - 若 `sidebar-page-ai-runtime.js` 超过 2500 行,再按 render / conversation / run orchestration 继续拆成子模块。 + +## 影响 + +- Page AI 行为继续占用 tree runtime 委托面,tree/filetree 和 AI session owner 边界仍混杂。 +- 后续新增 target picker、OnlyOffice target、mindmap contextRefs 时,容易继续堆入单一大文件。 +- 浏览器事件委托散落在 tree runtime 与 Page AI runtime 之间,增加回归风险。 + +## 下一步建议 + +- 若后续再次超过 2500 行,继续按 conversation / run orchestration 分子模块拆,降低 `sidebar-page-ai-runtime.js` 单文件职责。 +- 继续补 Page AI smoke,覆盖停止、关闭、history/session、permission、profile/skill 切换等 owner 迁移风险面;停止/关闭尾项已拆到 `bugs/07-ai/process/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md`。 + +## 验收 + +- [x] `sidebar-tree-runtime.js` 不再包含 `[data-page-ai-action=...]` click/change 分发。 +- [x] `sidebar-page-ai-runtime.js` 导出并安装 `installPageAiDelegates()`。 +- [x] `pageUiState.pageAi*` 从通用 sidebar state 下沉或有明确兼容 getter/setter。 +- [x] Page AI smoke 覆盖打开 drawer、切换 tab、切换 agent和发送;停止/关闭完整断言已拆到 `bugs/07-ai/process/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md`,不阻塞本文拆分阈值归档。 + +## 2026-06-01 第一刀验证 + +已完成第一刀:`sidebar-tree-runtime.js` 中 Page AI click/input/change/keydown 的大段 action 分发已迁到 `sidebar-page-ai-runtime.js` 的 `handlePageAiClick`、`handlePageAiKeyDown`、`handlePageAiInput`、`handlePageAiChange`,并由 `installPageAiDelegates()` 在 Page AI owner runtime 内安装事件监听。tree runtime 仅保留 `data-mnote-action="open-page-ai"` 主壳入口。 + +已通过验证: + +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- `node --check rust/crates/mnote-web/browser/sidebar-tree-runtime.js` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web page_ai_agent_target_picker_contract_is_visible_and_serialized -- --test-threads=1` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task490-runtime-surfaces-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task502-page-ai-agent-selector-context-smoke.js` + +2026-06-01 续补: + +- `sidebar-page-ai-runtime.js` 新增并导出 `installPageAiDelegates()`,内部一次性安装 Page AI click/keydown/input/change delegate。 +- `sidebar-tree-runtime.js` 不再调用 `sidebarPageAi.handlePageAi*`,只在自身监听注册后调用 `sidebarPageAi.installPageAiDelegates()`。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证 drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 state facade 续补: + +- `sidebar-page-ai-runtime.js` 新增 `ensurePageAiStateFacade()`,集中初始化 Page AI 默认状态并导出该 facade。 +- `sidebar-tree-runtime.js` 的 `pageUiState` 初始对象删除 `pageAi*:` 默认字段,tree runtime 不再定义 Page AI 状态真相。 +- Rust include/assert 已更新为:Page AI runtime 包含 `ensurePageAiStateFacade` 与 `pageAiAcpRuntime: 'reasonix'`,tree runtime 不包含该默认字段。 + +2026-06-01 conversation helper 续补: + +- 新增 `sidebar-page-ai-markdown-runtime.js`,抽出 `textFromUnknown`、`renderPageAiMarkdown` 和 inline Markdown 渲染 helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiMarkdownRuntime()`,保留现有 assistant message 渲染行为。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-markdown-runtime.js` 静态 runtime asset,并更新 runtime asset mount 测试。 + +2026-06-01 profile helper 续补: + +- 新增 `sidebar-page-ai-profile-runtime.js`,抽出 provider/profile/chat-only profile/history filter/usage helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiProfileRuntime()` 并保留同名代理常量,降低调用点扰动。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-profile-runtime.js` 静态 runtime asset,并更新 runtime asset mount 测试。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证二级 import 后 drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 permission helper 续补: + +- 新增 `sidebar-page-ai-permission-runtime.js`,抽出 ACP permission message、dialog show/hide 和 resolve-permission helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiPermissionRuntime()` 并保留同名代理常量,主 runtime 继续负责事件流持久化、会话同步和 conversation 渲染入口。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-permission-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 permission 二级 import 后 sidebar/Page AI 仍可加载和发送。 + +2026-06-01 session helper 续补: + +- 新增 `sidebar-page-ai-session-runtime.js`,抽出 session storage、backend session list/detail/search/resume/delete、session message sync 和 backend runtime event replay helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiSessionRuntime()` 并保留同名代理常量,主 runtime 继续负责 Page AI UI render、run orchestration 和事件委托入口。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-session-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 session 二级 import 后 Page AI drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 skill helper 续补: + +- 新增 `sidebar-page-ai-skill-runtime.js`,抽出 skill source、skill preference、Hermes builtin 隐藏和 Reasonix memory preference helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiSkillRuntime()` 并保留同名代理常量,主 runtime 继续负责 skill 异步加载、target/run orchestration 和 UI render。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-skill-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 skill 二级 import 后 Page AI drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 target helper 续补: + +- 新增 `sidebar-page-ai-target-runtime.js`,抽出 OpenEditorsSnapshot target 派生、WorkspacePath、run target snapshot、contextRefs、agentTargetPackage 和 target writable guard helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiTargetRuntime()` 并保留同名代理常量,主 runtime 继续负责 target popover UI、事件分发和 run orchestration 顺序。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-target-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言;target picker 合同测试改为在 target helper 中断言 `primaryTargetId` / `targets` / `policy`。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、target/skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_uses_backend_acp_session_runtime_store`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js`、`task502-page-ai-agent-selector-context-smoke.js`、`task520-page-ai-raw-resource-target-smoke.js`、`task525-page-ai-mindmap-resource-target-smoke.js`,验证新增 target 二级 import 后 Page AI drawer、agent/context/target/skills、raw resource target、mindmap target 和发送 payload 链路仍可用。 + +2026-06-01 render helper 续补: + +- 新增 `sidebar-page-ai-render-runtime.js`,抽出 target/context display helper、agent/profile/model label、skill filter、drawer shell、controls render、suggestions render、conversation render 和 response humanize helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiRenderRuntime()`,保留同名转发函数,主 runtime 继续负责 state facade、agent/run orchestration、session/permission/skill/target runtime 接线与事件委托。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-render-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言,避免浏览器 ES module import 404。 +- `sidebar-page-ai-runtime.js` 当前 2498 行,已低于 `7-38` 设定的 2500 行继续拆分阈值。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、render/target/skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_uses_backend_acp_session_runtime_store`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`。 + +最终验证: + +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task490-runtime-surfaces-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task502-page-ai-agent-selector-context-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task504-page-ai-history-agent-filter-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task520-page-ai-raw-resource-target-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task525-page-ai-mindmap-resource-target-smoke.js` + +本文已满足归档条件:`sidebar-page-ai-runtime.js` 当前 2498 行,低于 2500 行继续拆分阈值;render helper 二级 import、drawer controls、history/session filter、当前页 target、raw resource target、mindmap target 和发送 payload 链路均通过 smoke。 diff --git a/bugs/07-ai/done/7-54-page-ai-onlyoffice-target-buffer-state-404-v1.md b/bugs/07-ai/done/7-54-page-ai-onlyoffice-target-buffer-state-404-v1.md new file mode 100644 index 00000000..c9803668 --- /dev/null +++ b/bugs/07-ai/done/7-54-page-ai-onlyoffice-target-buffer-state-404-v1.md @@ -0,0 +1,33 @@ +# 7-54 Page AI Office target 误查 Markdown buffer-state + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI target runtime / OnlyOffice resource target +- 发现时间:2026-06-01 +- 修复时间:2026-06-01 + +## 现象 + +真实 Page AI UI 选择 Office resource target 后,发送 run 前的 buffer guard 会按 Office 文件相对路径请求 `/api/documents/buffer-state`: + +```text +/api/documents/buffer-state?...&relativePath=Page/office-a.docx +``` + +该端点只服务 local Markdown 文档 buffer,Office target 会返回 404。虽然当前 404 没有阻断 run,但会污染 console / HTTP error 证据,并说明 Page AI 把 Office resource 当成 Markdown buffer 检查。 + +## 根因 + +`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` 的 `fetchPageAiTargetBufferState()` 只判断 `sourceKind=local_folder`,没有区分 target `resourceKind`。Office target 已由 OnlyOffice bridge session、resource scope 和 tool 层权限保护,不应走 Markdown `BufferStore` 查询。 + +## 修复 + +- `fetchPageAiTargetBufferState()` 对 `office` / `only_office` / `onlyoffice` target 直接返回 `null`。 +- `scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js` 增加断言:真实 Page AI Office target run 过程中不得出现 `/api/documents/buffer-state` 404,并要求 `consoleErrors` / `networkFailures` / `httpErrors` 为空。 + +## 验收 + +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- `node --check scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js` diff --git a/bugs/07-ai/done/7-55-page-ai-current-page-target-stale-workspace-v1.md b/bugs/07-ai/done/7-55-page-ai-current-page-target-stale-workspace-v1.md new file mode 100644 index 00000000..ec1cccf5 --- /dev/null +++ b/bugs/07-ai/done/7-55-page-ai-current-page-target-stale-workspace-v1.md @@ -0,0 +1,32 @@ +# 7-55 Page AI 当前页目标继承 stale workspacePath + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI target runtime +- 发现时间:2026-06-01 +- 修复时间:2026-06-01 + +## 现象 + +`task504-page-ai-history-agent-filter-smoke.js` 在模拟 stale `OpenEditorsSnapshot` 后,用户偏好已将 `active_editor` contextRef 关闭,只发送当前页上下文;但 `sendPageAiMessage()` 仍强制把 `scopedContext.editorTarget` 覆盖为 `currentPageAiEditorTarget()`,导致当前页请求被旧 active editor 的 `workspaceId` 拦截,前端显示: + +`AI target 与当前 workspaceId 不一致,请重新选择当前工作区内的目标。` + +## 根因 + +- `pageAiScopedPageContext()` 已按 contextRefs 计算 scoped target,但发送链路又覆盖为 `currentPageAiEditorTarget()`。 +- `currentPageAiPageEditorTarget()` 从 page editor snapshot 读取 `workspacePath` 时,没有把当前 `workspaceId/sourceKind/rootUri/relativePath/documentId` 写回,stale snapshot 会把旧 workspace 信息带进当前页目标。 + +## 修复 + +- `sendPageAiMessage()` 改用 `currentPageAiScopedEditorTarget()`,遵守 contextRefs 对 active editor 的开关。 +- `currentPageAiPageEditorTarget()` 在复用 page editor snapshot 时显式覆盖当前 workspace path 字段,避免 stale snapshot 污染当前页 target。 + +## 验证 + +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-target-runtime.js` +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task504-page-ai-history-agent-filter-smoke.js` + +验证结果:`task504` 通过,`capturedRuns[0].contextRefs` 只包含 `current_page`,`runTargetSnapshot.editorTarget.workspaceId` 为当前 `local-ws:mnote-e2e:task504`,未继续使用 stale workspaceId。 diff --git a/bugs/07-ai/done/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md b/bugs/07-ai/done/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md new file mode 100644 index 00000000..91f941fa --- /dev/null +++ b/bugs/07-ai/done/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md @@ -0,0 +1,49 @@ +# 7-56 Page AI runtime stop / close smoke 缺口 + +## 状态 + +- 状态:done +- Owner:07-ai / Page AI runtime +- 发现时间:2026-06-01 + +## 现象 + +`7-53` 已完成 Page AI runtime 拆分并把 `sidebar-page-ai-runtime.js` 降到 2500 行阈值以下,但停止运行与关闭抽屉的浏览器断言仍不完整。 + +## 证据 + +- `bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md` 已记录拆分完成,但验收中仍保留 stop/close smoke 的 `[~]` 项。 +- `scripts/task490-runtime-surfaces-smoke.js` 会打开并点击关闭 Page AI 抽屉,但缺少明确的 drawer hidden / closed state 断言。 +- 现有 smoke 未覆盖 `data-page-ai-action="stop-run"` 到 abort API / terminal event 的端到端行为。 + +## 影响 + +- Page AI runtime 拆分后,基础打开/发送/target picker 已有保护,但 stop/close 这类常用交互仍可能在后续拆分中回退。 +- `7-53` 虽然可作为拆分阈值 bug 归档,但停止/关闭行为应继续作为独立 P2 测试缺口跟踪。 + +## 下一步 + +1. 扩展现有 `task490` 或新增窄 smoke,断言关闭后 Page AI drawer 进入隐藏状态,且页面根状态同步清除。 +2. 增加 stop-run smoke:启动可控流式 run,点击停止,断言 abort API 被调用并收到 terminal/aborted 状态。 +3. 将验证命令补入 `scripts/TESTING_REFERENCE.md`。 + +## 验收 + +- [x] 浏览器 smoke 明确断言 Page AI drawer close 后不可见。 +- [x] 浏览器 smoke 覆盖 stop-run -> abort/terminal event。 +- [x] `node --check` 与对应 smoke 通过。 + +## 2026-06-01 修复记录 + +- `scripts/task490-runtime-surfaces-smoke.js` 已扩展 Page AI close 断言:关闭后 drawer 必须 `hidden=true`,浮动 AI 按钮 `data-state=closed` 且 `aria-expanded=false`。 +- `task490` 已新增可控 mock run:发送后等待 run 进入 `running`,点击 `data-page-ai-action="stop-run"`,断言 abort API 被调用一次、请求 reason 为 `page_ai_user_stop`,并等待 UI 进入 `aborted` 状态。 +- 修复 Page AI render helper 拆分漏注入:`sidebar-page-ai-render-runtime.js` 使用 `pageAiProviderLabel()` 渲染 provider card,但 `sidebar-page-ai-runtime.js` 未传入该 helper;已补 context 注入。 +- 已通过: + - `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` + - `node --check rust/crates/mnote-web/browser/sidebar-page-ai-render-runtime.js` + - `node --check scripts/task490-runtime-surfaces-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task490-runtime-surfaces-smoke.js` + +截图: + +- `tmp/task490-runtime-surfaces-smoke/02b-page-ai-stopped.png` diff --git a/bugs/07-ai/done/7-57-onlyoffice-plugin-bridge-p2-productization-tail-v1.md b/bugs/07-ai/done/7-57-onlyoffice-plugin-bridge-p2-productization-tail-v1.md new file mode 100644 index 00000000..f5b7763f --- /dev/null +++ b/bugs/07-ai/done/7-57-onlyoffice-plugin-bridge-p2-productization-tail-v1.md @@ -0,0 +1,80 @@ +# 7-57 OnlyOffice Plugin Bridge P2 产品化尾项 + +## 状态 + +- 状态:done +- Owner:07-ai / ONLYOFFICE live bridge / Page AI target runtime +- 发现时间:2026-06-01 +- 归档时间:2026-06-01 + +## 现象 + +OnlyOffice live bridge 的 P0 安全阻断已完成:显式 session、resource scope、真实 iframe 多 session 隔离、非 dry-run 写入落点和 Page AI target picker 到 live session 的绑定均已有 smoke 证据。但 `7-43` 仍保留若干 P2 产品化尾项,缺少独立 bug 落点。 + +## 证据 + +- `design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md` 仍保留 P2 follow-up:Office 主文档加载噪音治理、第三批 recipe 逐项实测。`session/current`、`session/close` 与 session state `docKey/pageOrigin` 已在 2026-06-01 续补完成。 +- 已有 smoke 证明安全主路径完成: + - `scripts/task515-onlyoffice-live-scope-http-smoke.js` + - `scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js` + - `scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js` + - `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` + - `scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js` + +## 影响 + +- P0 安全问题已经不再阻塞;P2 recipe 扩展已收窄为 `7-43` 的矩阵化后续,不再作为本文 bug 阻塞项。 +- `7-43` 已区分已完成安全项和后续产品化项。 + +## 下一步 + +1. 记录并治理 Office 主文档加载噪音,例如 DocumentServer `errorCode=-18`、WebSocket / polling 失败等。(已完成) +2. 第三批 recipe 必须逐项实测后再暴露给 agent,不凭 API 名称直接开放。(已收窄为矩阵规则) + +## 验收 + +- [x] `session/current` 与 `session/close` API 已实现并有 Rust route 测试。 +- [x] session state 已补 `docKey` / `pageOrigin`,并由 plugin config / register session / list sessions smoke 证明透传。 +- [x] Office 加载噪音有明确分类、截图或日志证据,并不误判为打开成功。 +- [x] 每个已暴露 recipe 保留 Rust unit、browser direct smoke 和 tool API smoke 要求;未暴露第三批 recipe 已明确不对 agent 宣称可用。 +- [x] 插件执行层已补 editorType guard,`document.*` / `sheet.*` / `presentation.*` 不能跨 Word / Excel / PPT session 串用。 +- [x] `design/07-ai/process/7-43...` 中 P0 已完成项与 P2 尾项拆分清晰。 + +## 2026-06-01 session lifecycle 续补记录 + +- `rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs` 已新增 `current_session` / `close_session`,并把 `docKey` / `pageOrigin` 纳入 `BridgeSessionState`、`BridgeSessionPayload`、`BridgeSessionInfo` 和 plugin index state。 +- `/onlyoffice` 页面会把当前 `fileState.docKey` 与 `location.origin` 传给 bridge plugin config;mock plugin direct smoke 已验证 plugin 注册后 session 中存在 `docKey/pageOrigin`。 +- `scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js` 已扩展 `session/current`、`session/close` 和关闭后 session 不再可取 command 的断言。 +- 已通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1` + - `node scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3302 node scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js` + +## 2026-06-01 噪音分类与主文档失败断言 + +- `scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` 已新增 `classifyOnlyOfficeSignals`,把 bridge plugin translation 404、ONLYOFFICE 内置插件噪音和主文档加载失败分开记录。 +- smoke 会断言 MNote bridge session 注册与 command loop 可用,同时要求 `mainDocument.ready=true`。 +- `errorCode=-18` 不再被当作可忽略噪音;一旦在 console 或 editor error log 中出现,`task518` 会失败并把它归为主文档失败。 +- `design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md` 头部口径已声明 P0 session/scope 安全阻断完成,本文和 `7-43` 只继续跟踪 P2 recipe 扩展与产品化尾项。 + +本文继续保持 `process` 的剩余原因: + +- 已归档。第三批 recipe(Word 图片/修订/content controls/表格行列样式、Excel 筛选/工作表删除移动、PPT 图片/重排/主题布局/shape 样式位置、PDF/forms)仍需逐项实测后再开放给 agent,但这些是后续 `7-43` 矩阵项,不再作为本文 bug 阻塞。 + +## 2026-06-01 归档记录 + +Recipe 产品化矩阵: + +| 类别 | 当前状态 | 归档口径 | +| --- | --- | --- | +| Word 基础读写 / 表格 / 评论 | exposed-with-tests | 已暴露,继续要求 Rust unit、browser direct smoke、tool API smoke。 | +| Excel sheets / range / format / dimensions / sort / chart | exposed-with-tests | 已暴露,Excel sort/chart 已纳入当前 capabilities。 | +| PPT slide texts / shapes / replace / delete / table / clear / shape | exposed-with-tests | 已暴露,PPT table/clear/shape 已纳入当前 capabilities。 | +| Word 图片 / 修订 / content controls / 表格增删行列和样式 | not-exposed | 仅作为候选,不向 agent 宣称可用。 | +| Excel 筛选 / 工作表删除移动 | not-exposed | 仅作为候选,不向 agent 宣称可用。 | +| PPT 图片 / slide 重排 / 主题布局 / shape 样式位置 | not-exposed | 仅作为候选,不向 agent 宣称可用。 | +| PDF / forms 字段读取与填写 | blocked-by-api | 需先确认 ONLYOFFICE 社区版 Plugin API 可行性。 | + +验证: + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1` diff --git a/bugs/07-ai/done/7-58-mindmap-p2-apply-ops-and-ui-smoke-gap-v1.md b/bugs/07-ai/done/7-58-mindmap-p2-apply-ops-and-ui-smoke-gap-v1.md new file mode 100644 index 00000000..7c1ac1a1 --- /dev/null +++ b/bugs/07-ai/done/7-58-mindmap-p2-apply-ops-and-ui-smoke-gap-v1.md @@ -0,0 +1,57 @@ +# 7-58 Mindmap P2 apply_ops 与真实 UI smoke 缺口 + +## 状态 + +- 状态:done +- Owner:07-ai / mindmap resource skill / Page AI target runtime +- 发现时间:2026-06-01 + +## 现象 + +Mindmap skill 和资源 target 已有最小闭环:`fetch`、`create_from_outline`、`apply_ops` 基础工具、`mnote-mindmap` skill 注册、`task503` 和 `task525` smoke 已覆盖 API/target 绑定。但 P2 第二批仍缺 apply_ops 操作白名单文档化、长文本节点策略和真实 UI 交互 smoke。 + +## 证据 + +- `rust/crates/mnote-web/src/hermes_tools/resource.rs` 已有 mindmap `fetch/apply_ops/create_from_outline` 入口。 +- `scripts/task503-mindmap-skill-capability-smoke.js` 覆盖 skill、create_from_outline、fetch、embed。 +- `scripts/task525-page-ai-mindmap-resource-target-smoke.js` 覆盖 mindmap resource tab / Page AI targetPackage。 +- 当前缺口未在独立 bugs/process 中跟踪;历史相关 bug `7-48/7-51/7-52` 已作为各自窄问题归档。 + +## 影响 + +- agent 可以调用 mindmap 工具,但不清楚 `apply_ops` 的稳定操作白名单和限制。 +- 长文本节点可能破坏 mindmap 渲染或 agent 输出可读性。 +- 现有 smoke 偏 API/target 合同,未覆盖用户真实 UI 交互,例如节点编辑、拖拽、导出等。 + +## 下一步 + +1. 已文档化 `apply_ops` 支持的操作白名单、payload schema、dry-run/revision 规则和失败形态。 +2. 已为关键 ops 增加 Rust 单测,覆盖成功、别名、delete、dry-run、revision mismatch、越权/只读拒绝、unsupported op、invalid ops payload、禁止删除 root。 +3. 已在 skill prompt 中明确长文本节点压缩策略:短语化、避免长段落,拆成 child nodes。 +4. 已用真实 mindmap UI smoke 覆盖打开、插入、渲染、样式抽屉默认状态、slash 菜单层级和 resize 基础交互。 + +## 验收 + +- [x] `apply_ops` 白名单与限制写入 design / skill。 +- [x] `hermes_tools_mindmap_apply_ops_*` targeted tests 覆盖核心操作。 +- [x] 长文本节点策略有测试或明确降级说明。 +- [x] 至少一条真实 mindmap UI browser smoke 通过并登记到 `scripts/TESTING_REFERENCE.md`。 + +## 2026-06-01 修复记录 + +- `skills/mnote-mindmap/SKILL.md` 已新增 `Current apply_ops contract`,明确支持 `updateText/updateNode`、`insertChild/addChild`、`deleteNode`,记录 `nodeId/id`、`text/title`、`parentId/nodeId` 等 payload schema、未知 op 拒绝、禁止删除 root、长文本短语化/拆子节点、`dryRun` 与 revision checks。 +- `rust/crates/mnote-web/src/routes/hermes_tools.rs` 已补齐 apply_ops targeted tests: + - `hermes_tools_mindmap_apply_ops_accepts_common_aliases` + - `hermes_tools_mindmap_apply_ops_deletes_child_node` + - `hermes_tools_mindmap_apply_ops_dry_run_returns_diff_without_writing` + - `hermes_tools_mindmap_apply_ops_rejects_invalid_ops_payload` + - `hermes_tools_mindmap_apply_ops_rejects_root_delete` + - `hermes_tools_mindmap_apply_ops_rejects_unsupported_op` +- 已通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_mindmap_apply_ops -- --test-threads=1` + - `node --check scripts/task455-local-folder-mindmap-clean-smoke.js` + - `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3303 node scripts/task455-local-folder-mindmap-clean-smoke.js` + +真实 UI smoke 结果: + +- `tmp/task455-local-folder-mindmap-clean-smoke/result.json` diff --git a/bugs/07-ai/process/7-49-chatonly-openclaw-provider-unit-test-gap-v1.md b/bugs/07-ai/process/7-49-chatonly-openclaw-provider-unit-test-gap-v1.md new file mode 100644 index 00000000..0848fe3b --- /dev/null +++ b/bugs/07-ai/process/7-49-chatonly-openclaw-provider-unit-test-gap-v1.md @@ -0,0 +1,98 @@ +# 7-49 ChatOnly OpenClaw provider 单测缺口 + +## 状态 + +- 状态:process +- Owner:07-ai / OpenClaw provider integration +- 发现时间:2026-06-01 + +## 现象 + +`7-44` 的 MNote 侧 ChatOnly provider conversation binding 已完成并通过真实浏览器 smoke。外部 OpenClaw 仓库已经补齐 Doubao provider 的 conversation id 抽取与 delete helper 单测,但 DeepSeek / Gemini provider 级 delete helper 与单测仍没有可靠实现落点,不能在 MNote 仓库内用集成 smoke 替代。 + +## 已有 MNote 侧证据 + +- `cargo test --manifest-path rust/Cargo.toml -p control-plane external_conversation -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib provider_conversation -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib chatonly_doubao_session_delete_calls_provider_and_marks_remote_deleted -- --test-threads=1` +- `node scripts/task512-chatonly-doubao-sync-smoke.js` +- `node scripts/task513-chatonly-provider-sync-smoke.js deepseek` +- `node scripts/task513-chatonly-provider-sync-smoke.js gemini` + +## 缺口 + +- OpenClaw Doubao provider 的 `conversation_id` 捕获、`deleteConversation` / `/im/conversation/batch_del_user_conv` 已有 provider 仓库内单测。 +- DeepSeek / Gemini provider delete helper 仍缺 provider 仓库内实现与单测;如果没有可靠远端删除 API,不应伪造 `remote_deleted`。 + +## 2026-06-01 外部仓库复核 + +- 本机存在 `/home/lix/openclaw-zero-token-latest`,但该仓库已有未提交改动: + - `src/zero-token/providers/doubao-web-client-browser.ts` + - `src/zero-token/providers/gemini-web-client-browser.ts` + - `src/zero-token/streams/doubao-web-stream.ts` + - `src/zero-token/providers/web-session-binding.test.ts` +- 只读核对显示,现有 `web-session-binding.test.ts` 覆盖 Doubao `conversation_id` SSE 提取和 Gemini URL / stale candidate,但未覆盖 `deleteConversation`、`/im/conversation/batch_del_user_conv`、`remote_deleted` / `remote_delete_failed`。 +- 尝试运行 `pnpm exec vitest run src/zero-token/providers/web-session-binding.test.ts` 与 `pnpm exec vitest run --config vitest.unit.config.ts src/zero-token/providers/web-session-binding.test.ts` 均因缺少 `@vitest/browser-playwright` 启动失败;`scripts/vitest.zero-token-web.config.ts` 当前 include 不包含 provider test。 + +结论:本缺口仍是 OpenClaw 外部仓库未完成项,不应在 MNote 仓库内标记 done。 + +## 下一步 + +在 OpenClaw provider 源码仓库中继续补 DeepSeek / Gemini provider 删除能力,覆盖: + +- 删除成功返回 `remote_deleted`。 +- 删除失败返回 `remote_delete_failed` 且脱敏错误。 + +## 2026-06-01 外部仓库二次复核 + +只读复核 `/home/lix/openclaw-zero-token-latest` 后确认本文仍保持 `process`,不能在 MNote 仓库内归档: + +- 外部仓库已有未提交/未跟踪改动,包含 `src/zero-token/providers/doubao-web-client-browser.ts`、`src/zero-token/providers/gemini-web-client-browser.ts`、`src/zero-token/streams/doubao-web-stream.ts`、`src/zero-token/providers/web-session-binding.test.ts`,本轮不得覆盖或清理。 +- Doubao stream/client 代码已有 conversation id 捕获和复用路径,但 provider 单测仍只覆盖 SSE 提取、Gemini URL normalize 和 stale candidate;未覆盖 Doubao 复用、`deleteConversation` 成功/失败。 +- `rg deleteConversation` 在 provider/streams 下未发现 DeepSeek/Gemini delete helper 可见测试。 +- 默认 `pnpm exec vitest run src/zero-token/providers/web-session-binding.test.ts --reporter=dot` 仍会因根 `vitest.config.ts` 导入但本机缺少 `@vitest/browser-playwright` 失败;`scripts/vitest.zero-token-web.config.ts` 又未 include provider test,强行指定 provider 文件会 `No test files found`。 + +结论:MNote 侧 ChatOnly/Doubao binding smoke 可作为 MNote 集成证据,但 `7-49` 的 owner 是 OpenClaw provider 仓库单测缺口,仍需在外部仓库补测试配置和 provider 单测后才能移动到 `done`。 + +## 2026-06-01 外部仓库三次推进 + +在 `/home/lix/openclaw-zero-token-latest` 已补并验证 Doubao provider 级测试: + +- `src/zero-token/providers/doubao-web-client-browser.ts` + - 新增 `ProviderConversationDeleteResult`、`DoubaoConversationDeleteRequest`、`buildDoubaoConversationDeleteRequest`、`deleteDoubaoConversationWithFetch` 和 `DoubaoWebClientBrowser.deleteConversation`。 + - 删除请求固定走 `/im/conversation/batch_del_user_conv`,失败响应会脱敏 `sessionid` / `ttwid`。 +- `src/zero-token/providers/web-session-binding.test.ts` + - 覆盖 Doubao `conversation_id` / `conversationId` / `sessionId` / object `event_data` 抽取。 + - 覆盖 `conversation_id:"0"`、malformed SSE、`[DONE]` 跳过。 + - 覆盖 batch delete request、`remote_deleted` 成功、`remote_delete_failed` 脱敏失败。 +- `scripts/vitest.zero-token-web.config.ts` + - 已 include provider test,并补 `openclaw/plugin-sdk/*` alias,避免根 `vitest` 多项目配置缺 `@vitest/browser-playwright` 阻断 provider 单测。 + +已通过: + +- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts src/zero-token/providers/web-session-binding.test.ts --reporter=dot` +- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts --reporter=dot` + +Reasonix 只读复核(`reasonix-2026-06-01T00-32-52-539Z-c41a37a3`)结论与主线程复核一致: + +- Doubao 是当前唯一有 provider 级 `deleteConversation` / `remote_deleted` / `remote_delete_failed` helper 与单测的 web provider。 +- DeepSeek / Gemini 只有 stream 层 `sessionMap` / `conversationMap` 复用,没有 provider 级删除能力。 +- Qwen、GLM、Kimi、Grok、Claude、ChatGPT、XiaoMiMo、Perplexity 等其他 web provider 也未见 provider 级 delete helper;这些不是 `7-44` Doubao 绑定的阻断项,但应作为后续 OpenClaw provider cleanup 矩阵继续跟踪。 +- `pnpm exec vitest run --config scripts/vitest.zero-token-web.config.ts --reporter=dot` 在外部仓库通过,3 files / 14 tests passed。 + +本文继续保持 `process` 的剩余原因: + +- DeepSeek provider 当前没有 `deleteConversation` / delete helper;不能从 MNote 侧 `task513` 推断 provider 仓库已有可靠远端删除实现。 +- Gemini provider 当前只有 DOM 对话打开和 conversation URL normalize / stale candidate 测试;没有 provider 级远端删除 helper。 +- 后续需要先核实 DeepSeek / Gemini 真实远端删除 API 或明确降级语义,再补 provider 单测;不能为了归档而把本地删除伪装成 `remote_deleted`。 + +## 2026-06-01 subagent 复核确认 + +只读 subagent 复核 `/home/lix/openclaw-zero-token-latest` 后确认本文继续保持 `process`: + +- Doubao provider delete/helper/test 与 Vitest 专用配置已补齐。 +- `rg deleteConversation|remote_deleted|remote_delete_failed|batch_del_user_conv src/zero-token/providers src/zero-token/streams` 仍只命中 Doubao 和 `web-session-binding.test.ts`,未命中 DeepSeek / Gemini。 +- DeepSeek 当前只有 `createChatSession` / `chatCompletions` 和 stream `sessionMap` 复用。 +- Gemini 当前只有 URL normalize、DOM 打开/复用对话和 `conversation_id: page.url()`,没有 provider 级远端删除 helper。 + +因此 MNote 侧 `7-44` / `task512` / `task513` 只能证明 MNote provider conversation binding,不足以替代外部 provider 仓库的 DeepSeek / Gemini 删除单测。 diff --git a/bugs/10-review/done/10-18-design-process-status-and-stale-entry-v1.md b/bugs/10-review/done/10-18-design-process-status-and-stale-entry-v1.md new file mode 100644 index 00000000..773923e1 --- /dev/null +++ b/bugs/10-review/done/10-18-design-process-status-and-stale-entry-v1.md @@ -0,0 +1,45 @@ +# 10-18 design process 状态与入口漂移 + +## 状态 + +- 状态:done +- Owner:10-review / design governance +- 发现时间:2026-05-31 + +## 现象 + +当前 design 主入口和若干 `process/` 文档状态已经与真实口径不一致,容易误导后续 worker 重复执行已完成任务,或从已迁移到 `old/` 的历史文档读取优先级。 + +## 证据 + +- `design/README.md` 曾把 `design/01-05-current-priority-overview.md` 写成当前优先级入口,但实际文件已在 `design/old/01-05-current-priority-overview.md`。 +- `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` 曾在上位依据中引用同一个已迁移文件,并仍引用已归档的 `3-3` / `3-18` 作为 active process 入口。 +- `design/03-rust-web/process/3-24-global-content-type-page-width-settings-v1.md` checklist 全部完成,曾仍位于 `process/`;2026-05-31 已迁入 `design/03-rust-web/done/`。 +- `design/05-editor-mainline/process/5-31-page-settings-sqlite-preference-convergence-v1.md` 已记录 Phase A/B/C/D 最小闭环完成,但末尾推荐仍建议从 Phase A/B 开始;2026-05-31 已迁入 `design/05-editor-mainline/done/`。 +- `design/05-editor-mainline/process/5-32-filetree-lazy-loading-sidex-alignment-v1.md` checklist 和验证记录已完成;2026-05-31 已迁入 `design/05-editor-mainline/done/`。 +- `design/07-ai/process/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md` 是 worker 评估材料,不是 active implementation checklist;2026-05-31 已迁入 `design/07-ai/reference/`。 +- `design/07-ai/process/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md` 文件头状态为 `done`,但仍在 `process/`;2026-06-01 已迁入 `design/07-ai/done/`。`design/10-review/process/17-sidex-mnote-workbench-gap-execution-checklist-v1.md` 曾有同类漂移,2026-05-31 已迁入 `design/10-review/done/`。 + +## 影响 + +- 后续 agent 可能按旧入口恢复过时优先级。 +- 已完成设计继续占用 active process 队列,导致任务拆分噪声。 +- process/done 目录语义被削弱,bug 和设计治理难以闭环。 + +## 修复建议 + +1. 已先修正 `design/README.md` 和 `1-8` 的失效入口。 +2. 下一步逐个迁移或拆分状态漂移文档: + - `3-24` 已迁入 `03-rust-web/done/`,Mindmap 真实消费另拆 follow-up。 + - `5-31` 已迁入 `05-editor-mainline/done/`,剩余风险另拆。 + - `5-32` 已迁入 `05-editor-mainline/done/`。 + - `5-33` 拆成已完成核心和 breadcrumb/fetch guard follow-up。 + - `7-37` 已迁入 `07-ai/reference/`。 + - `7-41` 已迁入 `07-ai/done/`。 + - `17` 已迁入 `10-review/done/`。 + +## 验收 + +- [x] `find design -path '*/process/*' -type f ! -path 'design/old/*'` 中不再出现文件头状态为 `done` 的文档。 +- [x] `rg -n "design/01-05-current-priority-overview.md" design/README.md design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` 无 active 入口引用。 +- [x] 每个保留在 `process/` 的文档都有未完成 checklist、owner 和验收条件;`5-33` 仍保留在 `process/` 是因为 breadcrumb/fetch guard 等 follow-up 未完成。 diff --git a/bugs/10-review/done/10-19-agents-md-broken-design-references-v1.md b/bugs/10-review/done/10-19-agents-md-broken-design-references-v1.md new file mode 100644 index 00000000..e72a3efe --- /dev/null +++ b/bugs/10-review/done/10-19-agents-md-broken-design-references-v1.md @@ -0,0 +1,43 @@ +# 10-19 AGENTS.md 架构参考路径断裂 + +## 状态 + +- 状态:done +- Owner:10-review / AGENTS 协作规则 +- 发现时间:2026-05-31 + +## 现象 + +发现时,`AGENTS.md` 的“需要架构判断时,优先参考”列表中有两个路径已经断裂。因为 `AGENTS.md` 是 agent 的顶层协作规则,这类失效引用会直接误导后续任务启动时的架构判断。 + +## 证据 + +- 发现时,`AGENTS.md` 仍引用 `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`,但该文件实际位于 `design/old/01-05-current-priority-overview.md`,根路径不存在。 +- 发现时,`AGENTS.md` 仍引用 `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-tree-first-graph-kernel-v1.md`,但实际文件位于 `design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`。 +- 本轮已更新 `design/README.md`、`1-8` 与 `AGENTS.md` 的 active 入口。 + +## 影响 + +- 后续 agent 按 `AGENTS.md` 查架构依据时会遇到文件不存在。 +- worker 可能因此退回旧记忆或自己猜测口径。 +- `01-05` 已迁入 `old/` 但仍被当作当前入口,削弱 `design/README.md` 和 `1-8` 的入口权威。 + +## 修复建议 + +修复方式: + +- 将 `01-05-current-priority-overview.md` 替换为 `CURRENT_ARCHITECTURE.md` 与 `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`。 +- 将 `process/1-tree-first-graph-kernel-v1.md` 改为 `reference/1-tree-first-graph-kernel-v1.md`,或删除该历史参考入口。 + +## 本轮进展 + +- 2026-05-31:用户设置的 P0 goal 已明确包含 `AGENTS/design 断裂引用`,本轮已更新 `AGENTS.md`: + - 新增 `CURRENT_ARCHITECTURE.md`。 + - 新增 `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`。 + - 将 `1-tree-first-graph-kernel-v1.md` 指向 `reference/`。 + - 移除已不存在的 root `design/01-05-current-priority-overview.md` 引用。 + +## 验收 + +- `test -f` 验证 `AGENTS.md` 中列出的每个绝对路径都存在。 +- `rg -n "design/01-05-current-priority-overview.md|process/1-tree-first-graph-kernel-v1.md" AGENTS.md` 不再命中 active 断裂引用。 diff --git a/bugs/10-review/done/10-20-testing-reference-missing-new-smokes-v1.md b/bugs/10-review/done/10-20-testing-reference-missing-new-smokes-v1.md new file mode 100644 index 00000000..07cd5840 --- /dev/null +++ b/bugs/10-review/done/10-20-testing-reference-missing-new-smokes-v1.md @@ -0,0 +1,49 @@ +# 10-20 新增 smoke 未及时进入 TESTING_REFERENCE + +## 状态 + +- 状态:done +- Owner:10-review / smoke governance +- 发现时间:2026-05-31 + +## 现象 + +近期新增的 Page AI / mindmap / ChatOnly smoke 未及时进入 `scripts/TESTING_REFERENCE.md`。该文件是当前 smoke 分类与默认基线的权威入口,缺失会导致新增能力线没有明确验证入口。 + +## 证据 + +本轮发现时,`scripts/TESTING_REFERENCE.md` 未收录: + +- `scripts/task503-mindmap-skill-capability-smoke.js` +- `scripts/task504-page-ai-history-agent-filter-smoke.js` +- `scripts/task512-chatonly-doubao-sync-smoke.js` +- `scripts/task513-chatonly-provider-sync-smoke.js` + +## 本轮处理 + +已把上述 smoke 补入 `scripts/TESTING_REFERENCE.md`: + +- `task503` 归入资源对象与 mindmap / Page AI mindmap skill。 +- `task504` 归入 Page AI history / agent filter。 +- `task512`、`task513` 归入 ChatOnly / provider session 绑定。 +- 另补入本轮新增的 `task514-sidebar-dev-hot-reload-gating-smoke.js`、`task515-onlyoffice-live-scope-http-smoke.js`、`task516-onlyoffice-bridge-multisession-browser-smoke.js`。 + +## 剩余问题 + +本轮已实跑: + +- `node scripts/task503-mindmap-skill-capability-smoke.js` +- `node scripts/task504-page-ai-history-agent-filter-smoke.js` +- `node scripts/task512-chatonly-doubao-sync-smoke.js` +- `node scripts/task514-sidebar-dev-hot-reload-gating-smoke.js` +- `node scripts/task515-onlyoffice-live-scope-http-smoke.js` +- `node scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js` +- `node scripts/task513-chatonly-provider-sync-smoke.js deepseek` +- `node scripts/task513-chatonly-provider-sync-smoke.js gemini` + +当前 smoke reference 缺项已补齐并实跑。后续若新增 smoke,需要继续按本文件规则同步 `scripts/TESTING_REFERENCE.md`。 + +## 验收 + +- `rg -n "task503|task504-page-ai-history|task512|task513" scripts/TESTING_REFERENCE.md` 能命中新条目。 +- `task513-chatonly-provider-sync-smoke.js deepseek` 与 `task513-chatonly-provider-sync-smoke.js gemini` 已实跑通过,并已写回 `design/07-ai/done/7-44-chatonly-doubao-session-binding-v1.md`。 diff --git a/bugs/10-review/done/10-21-design-done-header-status-drift-v1.md b/bugs/10-review/done/10-21-design-done-header-status-drift-v1.md new file mode 100644 index 00000000..e963e4ca --- /dev/null +++ b/bugs/10-review/done/10-21-design-done-header-status-drift-v1.md @@ -0,0 +1,39 @@ +# 10-21 design done 文件头状态漂移 + +## 状态 + +- 状态:done +- Owner:10-review / design governance +- 发现时间:2026-06-01 + +## 现象 + +部分已经位于 `design/**/done/` 的设计稿,文件头仍保留 `process` / `PROCESS` 状态。后续 agent 或脚本如果只读文件头而不看目录状态,容易把已归档文档误判为 active process。 + +## 证据 + +- `design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md` 位于 `done/`,但文件头仍写 `状态:process`。 +- `design/05-editor-mainline/done/5-31-page-settings-sqlite-preference-convergence-v1.md` 位于 `done/`,但文件头仍写 `状态:process`。 +- `design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md` 位于 `done/`,但文件头仍写 `状态:process`。 +- `design/04-tree-domain/done/4-49-local-file-operation-event-contract-v1.md` 位于 `done/`,但文件头仍写 `状态:process`。 + +## 影响 + +- 设计治理扫描和 worker 任务拆分可能重复打开已完成文档。 +- `process/` 与 `done/` 的事实源边界被削弱。 + +## 下一步 + +1. 扫描 `design/**/done/*.md` 中的文件头状态字段。 +2. 将已经归档且证据充分的文档头部状态统一改为 `done`。 +3. 对确实仍有未完成项的文档,不留在 `done/` 中混用;应拆 follow-up 到 `process/`。 + +## 验收 + +- [x] `design/**/done/*.md` 中不再出现文件头 `状态:process` / `当前状态:PROCESS`。 +- [x] 若存在例外,必须在文档头部说明其为历史快照而非 active process。 + +## 2026-06-01 修复记录 + +- 已将当前扫描命中的 `design/**/done/*.md` 文件头状态统一改为 `done` / `DONE`。 +- 已验证:`rg -n '^> (当前状态|状态):`?(PROCESS|process)' design/*/done design/old/*/done -g '*.md'` 无结果。 diff --git a/bugs/10-review/done/10-22-done-bug-stale-followup-text-v1.md b/bugs/10-review/done/10-22-done-bug-stale-followup-text-v1.md new file mode 100644 index 00000000..254ff53e --- /dev/null +++ b/bugs/10-review/done/10-22-done-bug-stale-followup-text-v1.md @@ -0,0 +1,38 @@ +# 10-22 done bug 文档残留过时 follow-up 文案 + +## 状态 + +- 状态:done +- Owner:10-review / bugs governance +- 发现时间:2026-06-01 + +## 现象 + +部分已经位于 `bugs/**/done/` 的 bug 文档仍保留过时的“仍缺 / 待复测”文案,而同文档或后续 bug 已经补充了完成证据。这会让 reviewer 误判 done 条目仍未完成。 + +## 证据 + +- `bugs/07-ai/done/7-52-page-ai-target-picker-resource-target-gap-v1.md` 仍写“仍缺真实 mindmap resource tab 自动打开后的 UI 级 contextRefs 复测”,但后续 `task525-page-ai-mindmap-resource-target-smoke.js` 已覆盖 mindmap resource target。 +- `bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md` 的主 bug 已完成拆分阈值,但残留 stop/close smoke `[~]` 项;该缺口已拆为 `bugs/07-ai/process/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md` 后,应避免继续让 `7-53` 看起来未完成。 + +## 影响 + +- `done/` bug 的完成边界不清晰。 +- 后续 agent 容易重复寻找已覆盖缺口,或者把独立 follow-up 误认为原 bug 未完成。 + +## 下一步 + +1. 扫描近期 `bugs/**/done/*.md`,把已被后续 smoke 覆盖的旧 follow-up 文案改成完成记录。 +2. 对仍未完成的尾项,拆到独立 `bugs/**/process/`,并在原 done 文档写明“尾项已拆出”。 +3. 不改变 bug 事实源:没有真实验证的项不得从文案中删除,只能拆出跟踪。 + +## 验收 + +- [x] `7-52` 中 mindmap resource tab 复测口径与 `task525` 证据一致。 +- [x] `7-53` 中 stop/close 缺口指向 `7-56`,主拆分 bug 保持 done。 +- [x] `git diff --check` 通过。 + +## 2026-06-01 修复记录 + +- `7-52` 已改为记录 `task525-page-ai-mindmap-resource-target-smoke.js` 覆盖真实 mindmap resource tab target / contextRefs 复测。 +- `7-53` 已把停止/关闭完整断言尾项拆到 `bugs/07-ai/process/7-56-page-ai-runtime-stop-close-smoke-gap-v1.md`,主拆分阈值 bug 保持 done。 diff --git a/design/01-tree-first-graph-kernel/done/1-13-batch-f-p1-p2-active-tail-checklist-v1.md b/design/01-tree-first-graph-kernel/done/1-13-batch-f-p1-p2-active-tail-checklist-v1.md index f57cb131..dae58115 100644 --- a/design/01-tree-first-graph-kernel/done/1-13-batch-f-p1-p2-active-tail-checklist-v1.md +++ b/design/01-tree-first-graph-kernel/done/1-13-batch-f-p1-p2-active-tail-checklist-v1.md @@ -2,7 +2,7 @@ > 创建时间:2026-05-21 > -> 当前状态:`PROCESS` +> 当前状态:`DONE` > > 上位入口:`design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` > diff --git a/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md b/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md index a26b0783..3555f1da 100644 --- a/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md +++ b/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md @@ -2,7 +2,7 @@ > 创建时间:2026-05-19 > -> 当前状态:`PROCESS` +> 当前状态:`DONE` > > 上位依据: > - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md` diff --git a/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md b/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md index c644b2ab..52cec139 100644 --- a/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md +++ b/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md @@ -6,14 +6,18 @@ > > 2026-05-22 归档治理补充:当前 active `process/` 只保留可直接执行的少量收口稿;长期架构、愿景、参考矩阵、Wolai 对标基线、Mindmap 总设计、旧 AI 块级执行稿和 Convex Web 迁移入口已分别移动到 `reference/`、`done/` 或 `old/`。本文是后续调度入口,不代表下列所有历史入口仍在 `process/`。 > +> 2026-05-31 口径复核:当前主线仍以 `CURRENT_ARCHITECTURE.md`、`ARCHITECTURE.md` 与本文件为准;历史 `design/01-05-current-priority-overview.md` 已迁入 `design/old/01-05-current-priority-overview.md`,不再作为 active 调度入口。`3-3`、`3-18` 等已归档文档只保留为完成证据,后续 live / local-folder runtime 收口默认看 `3-23`、`5-32` 与相关 bug。 +> +> 2026-06-01 P0/P1/P2 复核:P0 阻塞项已由 `4-44/4-45/4-34/4-28` 归档证据覆盖,不再作为实现阻塞;`5-30` 与 `5-33` 已归档到 `05-editor-mainline/done/`,导航页 breadcrumb / fetch guard 尾项拆到 `5-35`;`7-35/7-36` 已降级为协作参考,不再占用产品 process 队列。当前 active 产品 process 重点收敛为 `3-23`、`3-25`、`5-35`、`7-18`、`7-43` 及对应 bugs/process。 +> > 目标:把本轮 design governance 后剩余的主线 `process/` 文档排成可执行顺序,避免后续 worker 在 active process 中自行猜优先级。 > > 上位依据: > - `/mnt/Data1T/mnote/ARCHITECTURE.md` > - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md` > - `/mnt/Data1T/mnote/design/README.md` -> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md` > - `/mnt/Data1T/mnote/design/10-review/done/15-design-governance-mvp-post-review-v1.md` +> - `/mnt/Data1T/mnote/design/10-review/done/18-current-design-and-bug-hunt-review-v1.md` ## 1. 一句话顺序 @@ -87,6 +91,8 @@ - `4-45` 四项 checklist 完成后归档到 `04-tree-domain/done/`。 - `4-44` browser smoke 全绿后归档到 `04-tree-domain/done/`。 +2026-06-01 状态:本项已由 `4-44` / `4-45` done 文档和 `task471` / `task476` / `task487` 复跑证据覆盖,不再作为 P0 阻塞项。 + ### P0.2 local folder no-refresh / restore focus 入口文档: @@ -109,6 +115,8 @@ - local folder 子项通过后,`4-34` 归档。 - React / Rust 主壳 focus 证据完成后,`4-28` 归档。 +2026-06-01 状态:本项已由 `4-34` / `4-28` done 文档和后续 tree/filetree lifecycle smoke 证据覆盖,不再作为 P0 阻塞项。 + ## 4. P1:统一工作区身份、BufferStore 和 Page Aggregate 这一步是 MVP 后阶段真正的底座收口。 @@ -133,6 +141,7 @@ - `cargo test -p mnote-web filetree_runtime -- --test-threads=1` - `cargo test -p mnote-web web_shell -- --test-threads=1` - 覆盖 markdown / office / mindmap / raw file / directory 的 browser smoke。 +- 2026-06-01 进展:已补 `scripts/task524-workspace-object-identity-matrix-smoke.js`,覆盖 page `.md`、directory、raw text、mindmap、OnlyOffice 在 FileTree row `workspacePath`、OpenEditorsSnapshot entry、URL `resourceTab`、active tab identity 之间的对齐;验证命令 `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 node scripts/task524-workspace-object-identity-matrix-smoke.js` 已通过。P1.1 的 identity 浏览器矩阵缺口已收口,后续只保留与 `1-5 / 1-6` 历史 checklist 对账。 归档条件: @@ -163,6 +172,8 @@ - `1-6` 中 BufferStore 运行时接入、浏览器读回、冲突 UI 相关项完成。 +2026-06-01 状态:历史 BufferStore 读回 / conflict UI 已由 `1-6` 与 Batch C 证据覆盖;真实 agent writeback -> watcher -> BufferStore -> Page Aggregate -> tiptap 的端到端回收仍归入 `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` Phase B,不再作为本文模糊 P1.2 阻塞。 + ### P1.3 Page Aggregate compat 瘦身 入口文档: @@ -177,6 +188,8 @@ 2. 补 GFM AST parser 写侧尾项:web shell 单测、手写 parser 过渡标记、临时适配分支清理。 3. 明确 `PageAggregateClientState` 哪些仍是合法 draft state,哪些应退出事实源地位。 +2026-06-01 收口口径:`body.blockDocument` / `editorDocument` 是 local-first 浏览器主消费面;`PageBody.content` 在 `mnote.page_aggregate.v1` 中继续保留为必填兼容镜像 / fallback,不作为 active editor 初始化优先事实源。`body.content` 改可选或删除必须进入 v2 协议升级或独立迁移 checklist,不能在 v1 兼容期直接删除。 + 验收: - `cargo test -p mnote-web local_markdown -- --test-threads=1` @@ -186,7 +199,7 @@ 归档条件: - `3-13` 已完成 GFM AST 迁移尾项并归档到 `design/03-rust-web/done/`;`web_shell.rs` legacy marks 分支改判为兼容层保留,不再作为迁移阻塞项。 -- `5-6` 剩余 Phase G/H 小尾项完成或拆成更小 checklist 后归档。 +- `5-6` 剩余 Phase G/H 小尾项完成或拆成更小 checklist 后归档;`bugs/05-editor-mainline/done/5-41-page-aggregate-compat-slimming-gaps-v1.md` 已明确 `PageBody.content` 的 v1/v2 边界。 ## 5. P2:tree live cache 与 command context @@ -194,8 +207,10 @@ 入口文档: -- `design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md` +- `design/03-rust-web/done/3-3-rust-web-tree-realtime-event-stream-v1.md` - `design/03-rust-web/reference/3-1-rust-web-long-term-checklist-v2.md` +- `design/03-rust-web/process/3-23-sidebar-local-folder-resource-runtime-followup-v1.md` +- `design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md` 执行目标: @@ -210,13 +225,13 @@ 归档条件: -- `3-3` 中统一 live cache 和 no-refresh 矩阵完成后归档。 +- `3-3` 已归档为 tree realtime event stream 完成证据;剩余 live cache / refresh 收口不得重新打开旧 `3-3`,应拆入 `3-23`、`5-32` 或明确的 `bugs/process`。 ### P2.2 Local folder tree live consumer 收口 入口文档: -- `design/03-rust-web/process/3-18-local-folder-tree-live-consumer-convergence-checklist-v1.md` +- `design/03-rust-web/done/3-18-local-folder-tree-live-consumer-convergence-checklist-v1.md` 执行状态: diff --git a/design/03-rust-web/process/3-24-global-content-type-page-width-settings-v1.md b/design/03-rust-web/done/3-24-global-content-type-page-width-settings-v1.md similarity index 93% rename from design/03-rust-web/process/3-24-global-content-type-page-width-settings-v1.md rename to design/03-rust-web/done/3-24-global-content-type-page-width-settings-v1.md index 8f0dca5c..c663ce3e 100644 --- a/design/03-rust-web/process/3-24-global-content-type-page-width-settings-v1.md +++ b/design/03-rust-web/done/3-24-global-content-type-page-width-settings-v1.md @@ -1,5 +1,11 @@ # 全局与内容类型页面宽度设置 Checklist v1 +> 状态:done +> +> 归档时间:2026-05-31 +> +> 归档说明:实施 checklist 已全量完成,当前真实消费点已覆盖 Markdown、轻量 Office 预览、PDF 预览和 PPTX 快速预览;Mindmap 渲染消费作为后续对应 viewer follow-up,不阻塞本文归档。 + ## 背景 当前 Markdown 页面已有 `wideLayout` 布尔选项,但 Word / PDF / Excel / PPT / Mindmap 等不同内容类型没有统一的页面宽度偏好入口。用户需要在全局设置中分别调整不同类型的默认宽度,避免像思源那样必须写 CSS 才能把阅读宽度调到合适比例。 diff --git a/design/03-rust-web/process/3-25-local-folder-mineru-ocr-sidecar-v1.md b/design/03-rust-web/process/3-25-local-folder-mineru-ocr-sidecar-v1.md new file mode 100644 index 00000000..1c915ab8 --- /dev/null +++ b/design/03-rust-web/process/3-25-local-folder-mineru-ocr-sidecar-v1.md @@ -0,0 +1,413 @@ +# 3-25 Local Folder MinerU OCR Sidecar Checklist v1 + +> 创建时间:2026-05-29 +> 状态:`process` +> Owner:03-rust-web / local-folder resource runtime +> +> 2026-06-01 复核:后端 mock 闭环已落地 `local_ocr.rs` 与 OCR route;真实 MinerU HTTP client 已补本地 HTTP mock 成功路径测试;`task526` 已覆盖 mock OCR API、搜索命中、显式插入链接和 OCR sidecar Markdown resource tab 打开。前端 OCR task runtime、active job store、realtime event 和任务栏 UI 尚未落地。本文继续保持 `process`,不得被本轮 Page AI / OnlyOffice / ChatOnly 收口误归档。 + +## 背景 + +当前 mnote local-first 主线中,本地 Markdown 和同目录资源是默认数据真相。本地图片 / 附件上传已通过 `/api/local-folder/assets/upload` 写入 Markdown 文件附近,并返回 `sourcePath` / `attachmentRef`。现在需要给图片和图片型 PDF 增加 OCR 能力,识别引擎使用 MinerU API。 + +OCR 结果不应默认写进用户正文,也不应只存在 `.mnote` 私有缓存里。用户希望 OCR 附件位于当前 Markdown 文件相同目录下,并用单独文件夹承载,因为一个 Markdown 页面可能对应多个 OCR 文件。 + +## 目标 + +- 对 local-folder 图片和图片型 PDF 提供手动触发 OCR。 +- 使用 MinerU API 识别本地文件,生成 Markdown OCR 结果。 +- OCR 结果作为页面旁路资源落盘到当前 Markdown 同目录的 `{pageStem}.ocr/` 文件夹。 +- OCR 文本默认作为资源 sidecar 被搜索、资源面板和后续 AI 上下文消费,不自动污染正文。 +- 支持用户显式把某个 OCR 结果插入当前正文。 +- 提供全局 OCR 任务进展入口,让用户离开当前资源后仍能看到 OCR 是否完成、失败或需要重试。 +- 保持 local-first 可迁移性:OCR Markdown 文件本身可读、可备份、可编辑;`.mnote` 索引只作为缓存和状态加速。 + +## 非目标 + +- 不做全 workspace 自动 OCR。 +- 不默认把 OCR 文本追加到页面正文。 +- 不把 MinerU token 打印到日志、前端 payload 或用户可见错误里。 +- 不在前端直接调用 MinerU API。 +- 不把 OCR 文件当成普通页面加入 Page Tree。 +- 不为 cloud / Convex / remote source 设计默认 OCR 主路径;第一阶段只覆盖 local-folder。 +- 不承诺精确百分比进度;MinerU API 第一阶段按阶段型状态展示。 +- 不把任务进展做成前端定时轮询主链;优先走现有 realtime / WS / SSE 事件。 + +## 文件布局 + +假设当前页面为: + +```text +docs/Page.md +``` + +附件可能为: + +```text +docs/Page.assets/photo.png +docs/Page.assets/spec.pdf +``` + +OCR 结果目录固定为: + +```text +docs/Page.ocr/ +``` + +OCR 结果文件示例: + +```text +docs/Page.ocr/photo.png.ocr.md +docs/Page.ocr/spec.pdf.ocr.md +``` + +同一页面下存在同名来源文件时,用来源 root-relative path、文件大小和 mtime 派生短 hash: + +```text +docs/Page.ocr/photo.png-8f3a21.ocr.md +``` + +## OCR Markdown frontmatter + +OCR Markdown 是 OCR 正文真相,必须能脱离 `.mnote` 索引独立说明来源。 + +```markdown +--- +mnote_ocr_version: 1 +provider: mineru +model_version: vlm +owner_document: ./Page.md +source_path: ./Page.assets/photo.png +source_root_relative_path: docs/Page.assets/photo.png +source_size: 123456 +source_mtime_ms: 1760000000000 +status: done +created_at: 2026-05-29T12:00:00+08:00 +updated_at: 2026-05-29T12:00:00+08:00 +--- + +识别文本... +``` + +字段口径: + +- `owner_document`:相对 OCR 文件所在目录到 owner Markdown 的相对路径。 +- `source_path`:相对 owner Markdown 所在目录的来源附件路径,和正文中的附件引用口径保持一致。 +- `source_root_relative_path`:相对 workspace root 的来源路径,用于稳定查找和索引。 +- `source_size` / `source_mtime_ms`:用于判断 OCR 是否 stale。 +- `status`:`done`、`failed` 或 `stale`。`queued/running` 只写入 `.mnote/ocr-index.json`,避免半成品 OCR 文件被误读。 + +## `.mnote` 索引 + +`.mnote/ocr-index.json` 是状态缓存,不是 OCR 正文真相。 + +```json +{ + "version": 1, + "entries": { + "docs/Page.assets/photo.png": { + "ownerDocumentId": "local-md:docs~2FPage.md", + "ownerDocumentPath": "docs/Page.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "ocrRootRelativePath": "docs/Page.ocr/photo.png.ocr.md", + "provider": "mineru", + "modelVersion": "vlm", + "status": "done", + "sourceSize": 123456, + "sourceMtimeMs": 1760000000000, + "createdAtMs": 1760000000000, + "updatedAtMs": 1760000000000, + "plainTextPreview": "识别文本前 240 字" + } + } +} +``` + +索引用途: + +- 资源面板快速展示 OCR 状态。 +- 搜索索引快速定位 OCR sidecar。 +- 避免重复提交同一个未变化资源。 +- 记录失败原因,但错误文本需要脱敏,不包含 token、预签名 URL 或完整外部响应体。 + +## 资源归属与树投影 + +- OCR 文件夹 `{pageStem}.ocr/` 应在 File Tree 中作为页面旁路资源文件夹出现。 +- `{pageStem}.ocr/*.ocr.md` 不应作为普通 Markdown 页面进入 Page Tree。 +- local search 不应把 OCR sidecar 当普通 Markdown 页面索引,否则会出现重复页面和错误导航。 +- 搜索 OCR 命中时,应返回 owner page 作为结果,`hasOcr=true`,evidence 指向来源附件和 OCR sidecar。 +- File Tree 可展示 OCR 文件,点击默认作为 Markdown resource tab 打开,不切换成页面文档。 + +## MinerU 调用边界 + +后端读取 MinerU token,前端不接触 token。 + +配置优先级: + +1. `MNOTE_MINERU_API_TOKEN` +2. `MINERU_API_TOKEN` +3. 开发环境可选读取 `~/.hermes/.env` 中的 `MINERU_API_TOKEN` + +第一阶段使用 MinerU `model_version=vlm`。 + +本地文件流程: + +1. `POST https://mineru.net/api/v4/file-urls/batch` 申请上传地址。 +2. 使用 `PUT` 把本地文件上传到预签名 URL。 +3. 轮询 `GET /extract-results/batch/{batch_id}`。 +4. 下载 `full_zip_url`。 +5. 解压并提取结果 Markdown。 +6. 写入 `{pageStem}.ocr/*.ocr.md`。 +7. 更新 `.mnote/ocr-index.json`。 + +## 后端 API + +### 创建或复用 OCR job + +`POST /api/local-folder/ocr/jobs` + +请求: + +```json +{ + "rootUri": "file:///mnt/Data1T/mnote-notes", + "documentId": "local-md:docs~2FPage.md", + "sourcePath": "Page.assets/photo.png", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mineru", + "force": false +} +``` + +响应: + +```json +{ + "ok": true, + "job": { + "status": "done", + "ownerDocumentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "ocrRootRelativePath": "docs/Page.ocr/photo.png.ocr.md", + "stale": false + } +} +``` + +第一阶段可以同步执行并在请求内返回最终状态;如果真实耗时过长,再升级为后台 job。同步版本必须设置合理超时,并让 UI 显示运行中状态。 + +### 查询 OCR 状态 + +`GET /api/local-folder/ocr/status?rootUri=...&sourceRootRelativePath=...` + +返回 `.mnote/ocr-index.json` 中的状态,并重新对比来源文件 `size/mtime` 判断 `stale`。 + +### 查询 OCR 任务列表 + +`GET /api/local-folder/ocr/jobs?rootUri=...` + +返回当前 root 下 active jobs 和最近完成 / 失败任务,用于全局任务栏首次渲染和刷新后恢复。 + +响应: + +```json +{ + "ok": true, + "jobs": [ + { + "jobId": "ocr_1760000000000_abcd", + "fileName": "spec.pdf", + "ownerDocumentId": "local-md:docs~2FPage.md", + "ownerDocumentPath": "docs/Page.md", + "sourceRootRelativePath": "docs/Page.assets/spec.pdf", + "ocrRootRelativePath": "docs/Page.ocr/spec.pdf.ocr.md", + "status": "mineru_processing", + "stageLabel": "识别中", + "startedAtMs": 1760000000000, + "updatedAtMs": 1760000000000, + "finishedAtMs": null, + "stale": false + } + ] +} +``` + +### 读取 OCR 文本 + +`GET /api/local-folder/ocr/read?rootUri=...&ocrRootRelativePath=...` + +返回 OCR Markdown 文本、frontmatter 摘要、来源路径和 stale 状态。 + +### 插入 OCR 到正文 + +`POST /api/local-folder/ocr/insert` + +只在用户显式触发时执行。默认插入为链接块: + +```markdown +[OCR:photo.png](./Page.ocr/photo.png.ocr.md) +``` + +可选模式 `inlineSection` 插入正文段落: + +```markdown +### OCR:photo.png + + + +识别文本... +``` + +## UI 行为 + +- 编辑器图片 toolbar / 附件右键菜单增加 `OCR 识别`。 +- File Tree 图片/PDF 资源右键菜单增加 `OCR 识别`。 +- PDF preview / image resource tab 显示 OCR 状态和结果入口。 +- 全局任务栏 / 任务抽屉显示运行中、完成、失败和 interrupted 的 OCR 任务。 +- 状态文案只表达:未识别、排队中、上传中、识别中、写入中、已识别、来源已变化、识别失败、已中断。 +- 对 `stale` 结果展示“重新识别”操作,不自动覆盖旧 OCR 文件,除非用户确认或传 `force=true`。 +- OCR 结果打开在 resource tab,不切到普通文档页面。 + +## 搜索与 AI 消费 + +- `includeOcr=false` 时不搜索 OCR sidecar。 +- `includeOcr=true` 时,搜索 OCR 文本并返回 owner page。 +- 搜索 evidence 包含: + - `kind: "ocr"` + - `sourceRootRelativePath` + - `ocrRootRelativePath` + - `snippet` +- 后续 `image_read` / Page AI attachment context 可以读取 OCR sidecar,优先返回已存在 OCR 文本,不让 agent 重复调用 OCR。 + +## 任务进展与全局入口 + +OCR 是慢任务,提交后必须有全局可见状态,不应只依赖 toast 或当前 resource tab。 + +第一阶段进度采用阶段型状态: + +```text +queued -> uploading -> mineru_processing -> downloading -> writing_sidecar -> done +``` + +失败和中断状态: + +```text +failed +interrupted +stale +``` + +状态含义: + +- `queued`:任务已创建,等待执行。 +- `uploading`:正在上传原始图片/PDF 到 MinerU 预签名地址。 +- `mineru_processing`:MinerU 正在识别。 +- `downloading`:正在下载 MinerU 结果包。 +- `writing_sidecar`:正在写入 `{pageStem}.ocr/*.ocr.md` 和 `.mnote/ocr-index.json`。 +- `done`:OCR sidecar 已写入。 +- `failed`:任务失败,可重试。 +- `interrupted`:mnote-web 进程或任务 worker 中断,不能确认完成,可重试。 +- `stale`:来源文件在 OCR 后发生变化。 + +后端维护一个运行时 active job store,并把每次状态变更写入 `.mnote/ocr-index.json`。页面刷新后,已完成、失败、stale 和 interrupted 状态可以从磁盘恢复;正在运行中的内存任务如果因进程重启丢失,应在下次读取时标记为 `interrupted`,由用户重试。 + +状态变化通过现有 realtime / WS / SSE 事件链路广播,不在前端叠加 `setInterval` 轮询主链。事件示例: + +```json +{ + "type": "local_ocr.job.updated", + "jobId": "ocr_1760000000000_abcd", + "rootUri": "file:///mnt/Data1T/mnote-notes", + "ownerDocumentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/spec.pdf", + "ocrRootRelativePath": "docs/Page.ocr/spec.pdf.ocr.md", + "status": "mineru_processing", + "stageLabel": "识别中", + "updatedAtMs": 1760000000000 +} +``` + +前端需要两类展示: + +- 资源局部状态:图片/PDF resource tab、附件菜单、File Tree 行显示当前 OCR 状态。 +- 全局任务栏 / 任务抽屉:底栏或右上角显示 `OCR 2` / `1 个任务进行中`。点开后列出文件名、所属页面、阶段、开始时间、完成/失败状态,以及“打开 OCR”“重试”等操作。 + +第一阶段不强制支持取消。若 MinerU 任务 API 后续提供可靠取消,再补 `cancel` 动作。 + +## 隐私与安全 + +- OCR 必须由用户手动触发。 +- UI 首次触发时应明确提示:文件会发送到 MinerU API。 +- 后端只允许读取 `rootUri` 授权根内文件,禁止绝对路径和 `..` 越界。 +- 日志不记录 token、预签名 URL、完整外部错误响应和 OCR 正文全文。 +- 失败状态写入简短错误码和脱敏消息。 + +## 实施 Checklist + +- [x] 后端:新增 MinerU client,支持本地文件上传、轮询、结果 zip 下载和 Markdown 提取。 +- [x] 后端:新增 OCR 路由模块,提供 job/status/read/insert API。(当前 insert 只支持 link 模式) +- [ ] 后端:新增 OCR active job store,记录 queued/uploading/mineru_processing/downloading/writing_sidecar/done/failed/interrupted/stale。 +- [ ] 后端:OCR 状态变化写入 `.mnote/ocr-index.json` 并广播 `local_ocr.job.updated` 事件。 +- [x] 后端:提供 OCR jobs list API,用于全局任务栏刷新后恢复。 +- [x] 后端:实现 `{pageStem}.ocr/` 路径规划、文件名冲突处理和 UTF-8 OCR Markdown 写入。 +- [x] 后端:实现 `.mnote/ocr-index.json` 读写、stale 检测和脱敏错误记录。 +- [x] 后端:扩展 local-folder 文件分类,让 `{pageStem}.ocr/*.ocr.md` 不进入 Page Tree 普通页面。 +- [x] 搜索:扩展 local search index,`includeOcr=true` 时索引 OCR sidecar 并返回 owner page。 +- [ ] UI:在附件右键菜单、File Tree 资源菜单和资源 tab 增加 OCR 识别入口。 +- [ ] UI:展示 OCR 状态、stale、失败和重新识别动作。 +- [ ] UI:新增全局 OCR 任务栏 / 任务抽屉,显示任务阶段、所属页面、打开 OCR、重试。 +- [~] UI/API:增加“插入 OCR 链接到正文”和可选“插入 OCR 正文段落”动作。(后端 link API 已完成;前端入口和 inlineSection 待做) +- [ ] AI:让 image/PDF 资源上下文优先读取已有 OCR sidecar。 +- [x] 测试:Rust 单测覆盖路径规划、frontmatter、索引读写、stale、越界拒绝。 +- [x] 测试:Rust route 测试覆盖无 token、真实 MinerU HTTP mock 成功、模拟失败和脱敏错误。 +- [x] 测试:local search 测试覆盖 OCR 命中返回 owner page,OCR sidecar 不作为普通页面。 +- [~] Smoke:浏览器覆盖图片/PDF 手动 OCR、全局任务栏状态、打开 OCR resource tab、搜索 OCR 命中、插入 OCR 链接。(当前 `task526` 覆盖 mock OCR API、搜索命中和 insert link;真实 UI/任务栏/打开 OCR resource tab 待做) +- [x] 文档:补充 `scripts/TESTING_REFERENCE.md` 中 OCR smoke 基线。 + +## 验收标准 + +- 本地图片或图片型 PDF 可被用户手动提交 MinerU OCR。 +- OCR 结果落在 owner Markdown 同目录的 `{pageStem}.ocr/` 下,文件为 UTF-8 Markdown。 +- `.mnote/ocr-index.json` 删除后,仍能从 OCR Markdown frontmatter 重建核心绑定关系。 +- OCR 文件不会污染 Page Tree,也不会作为普通页面搜索结果出现。 +- 搜索 OCR 文本时返回 owner page,结果标记 `hasOcr=true`。 +- 用户未显式选择插入时,页面正文不发生变化。 +- 用户提交 OCR 后,即使离开当前资源,也能在全局 OCR 任务栏看到阶段状态;完成后可打开 OCR,失败或中断后可重试。 +- 所有外部 API token 和预签名 URL 均不出现在日志、前端 payload 或错误响应中。 + +## 2026-06-01 后端 mock 闭环 + +已落地 `rust/crates/mnote-web/src/routes/local_ocr.rs` 与 route 注册,第一刀只承诺后端 mock 闭环:`provider=mock` 可同步生成 `{pageStem}.ocr/*.ocr.md`,写入 `.mnote/ocr-index.json`,提供 jobs/status/read;当时 `provider=mineru` 尚未执行真实外部调用,缺 token 时返回 `mineru_token_missing`,有 token 时返回 `mineru_runtime_not_enabled`。 + +同时已把 OCR sidecar 从 Page Tree 普通 Markdown 扫描中排除,并扩展 local search:`includeOcr=false` 不命中 OCR 文本,`includeOcr=true` 返回 owner page,结果带 `hasOcr=true` 与 `ocrEvidence`。 + +验证: + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1` + +2026-06-01 续补: + +- `local_ocr` route 测试新增来源路径越界、非图片/PDF 来源和 mock 失败脱敏 response 形态覆盖。 +- `local_ocr` route 测试新增缺 MinerU token response 覆盖:`mineru_token_missing`。 +- `local_ocr` route 测试新增 token 存在但真实 runtime 未接入 response 覆盖:`mineru_runtime_not_enabled`,避免把 mock OCR 闭环误报为真实 MinerU 能力。该旧口径已在后续真实后端 runtime 补齐后由 HTTP mock 成功路径测试替代。 +- 新增 `POST /api/local-folder/ocr/insert`,当前只支持 `mode=link`,显式把 OCR sidecar 链接追加到 owner Markdown;`local_ocr_insert_route_appends_explicit_ocr_link` 已覆盖。 + +2026-06-01 浏览器 API smoke 续补: + +- 新增 `scripts/task526-local-folder-ocr-api-smoke.js`,在真实浏览器登录态页面内通过 `fetch` 串起 `POST /api/local-folder/ocr/jobs`、`status`、`read`、`jobs`、`/api/search/documents includeOcr=true` 和 `POST /api/local-folder/ocr/insert`。 +- 该 smoke 固定使用 `provider=mock`,不触碰真实 MinerU token、上传、轮询、zip 下载和 Markdown 提取链路。 +- 已验证 mock OCR sidecar 落盘、`.mnote/ocr-index.json` jobs/status/read 可读、`includeOcr=false` 不命中 OCR 文本、`includeOcr=true` 返回 owner page 且带 `hasOcr/ocrEvidence`、显式 insert 才向 owner Markdown 追加 OCR 链接。 +- 已通过: + - `node --check scripts/task526-local-folder-ocr-api-smoke.js` + - `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task526-local-folder-ocr-api-smoke.js` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1` + +2026-06-01 后端真实 MinerU runtime 续补: + +- `local_ocr.rs` 已补 `mineru_api_base_url`、`mineru_poll_interval`、`mineru_max_polls` 配置函数。 +- `provider=mineru` 后端路径已接入申请上传 URL、PUT 上传、轮询 batch 结果、下载 zip、提取 Markdown。 +- 新增 `local_ocr_jobs_route_runs_mineru_runtime_against_http_mock`,用本地 HTTP mock 覆盖真实 client 合同,不访问外网。 +- 已通过: + - `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1` diff --git a/design/04-tree-domain/done/4-49-local-file-operation-event-contract-v1.md b/design/04-tree-domain/done/4-49-local-file-operation-event-contract-v1.md index 4a132ab5..91943fea 100644 --- a/design/04-tree-domain/done/4-49-local-file-operation-event-contract-v1.md +++ b/design/04-tree-domain/done/4-49-local-file-operation-event-contract-v1.md @@ -1,6 +1,6 @@ # 4-49 Local File Operation 与 Watch Event 合同 v1 -> 状态:process +> 状态:done > Owner:04-tree-domain / 03-rust-web > 背景:Sidex / VSCode Explorer 对照显示,MNote local_folder 的 tree command、watch event、refresh/reveal 和 opened resource 生命周期之间仍缺少稳定合同。当前前端常靠 `relativePath` / `previousRelativePath` 反推刷新父级,watch event 又容易退回全量 resync,导致大目录、批量操作和已打开资源场景下出现重复刷新、状态漂移和错误恢复困难。 diff --git a/design/05-editor-mainline/process/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md b/design/05-editor-mainline/done/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md similarity index 97% rename from design/05-editor-mainline/process/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md rename to design/05-editor-mainline/done/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md index 9c739d3c..2a9cce75 100644 --- a/design/05-editor-mainline/process/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md +++ b/design/05-editor-mainline/done/5-30-sidebar-starred-shortcuts-sqlite-scoped-explorer-v1.md @@ -1,6 +1,6 @@ # 5-30 Sidebar 星标置顶快捷入口与 Scoped Explorer 设计 v1 -> 状态:process +> 状态:done > Owner:05-editor-mainline / 03-rust-web / control-plane > 背景:星标置顶需要对齐 Wolai 的 Sidebar 顶部快速访问体验,但 MNote 还需要支持把高频本地文件夹固定成 Explorer scoped root,避免每次进入大 workspace 时加载完整根目录。 @@ -240,3 +240,4 @@ mnote-web: - 2026-05-26:星标置顶确定为用户级 Sidebar 快捷入口,不是文件夹/页面自身属性。 - 2026-05-26:星标快捷入口必须写入 SQLite control-plane,满足同一用户跨设备一致显示。 - 2026-05-26:文件夹星标点击进入 scoped Explorer,避免大 workspace root 扫描。 +- 2026-06-01:只读复核确认 `sidebar_shortcuts` migration/store/API、显式 `rootUri`、scoped Explorer 与 `task492-sidebar-starred-shortcuts-smoke.js` 已覆盖本文主验收;本文归档到 `done/`。 diff --git a/design/05-editor-mainline/process/5-31-page-settings-sqlite-preference-convergence-v1.md b/design/05-editor-mainline/done/5-31-page-settings-sqlite-preference-convergence-v1.md similarity index 99% rename from design/05-editor-mainline/process/5-31-page-settings-sqlite-preference-convergence-v1.md rename to design/05-editor-mainline/done/5-31-page-settings-sqlite-preference-convergence-v1.md index fb236483..43839cac 100644 --- a/design/05-editor-mainline/process/5-31-page-settings-sqlite-preference-convergence-v1.md +++ b/design/05-editor-mainline/done/5-31-page-settings-sqlite-preference-convergence-v1.md @@ -1,6 +1,6 @@ # 5-31 页面设置 SQLite 状态收口设计 v1 -> 状态:process +> 状态:done > > Owner:05-editor-mainline / control-plane / mnote-web > diff --git a/design/05-editor-mainline/process/5-32-filetree-lazy-loading-sidex-alignment-v1.md b/design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md similarity index 99% rename from design/05-editor-mainline/process/5-32-filetree-lazy-loading-sidex-alignment-v1.md rename to design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md index f7151acb..afcbe5d3 100644 --- a/design/05-editor-mainline/process/5-32-filetree-lazy-loading-sidex-alignment-v1.md +++ b/design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md @@ -1,6 +1,6 @@ # 5-32 FileTree 大目录懒加载与展开状态设计 v1 -> 状态:process +> 状态:done > Owner:05-editor-mainline / 03-rust-web > 背景:用户在 localhost 打开 `mnote/design` 及其子目录时仍感到加载慢,并观察到“全部加载完又折叠,再点很快”。上一版仅靠恢复展开状态不够,因为它没有消除慢请求、重复请求和整树替换。 diff --git a/design/05-editor-mainline/done/5-33-filetree-viewstate-generation-followup-v1.md b/design/05-editor-mainline/done/5-33-filetree-viewstate-generation-followup-v1.md index 31b47143..b6c5ecfa 100644 --- a/design/05-editor-mainline/done/5-33-filetree-viewstate-generation-followup-v1.md +++ b/design/05-editor-mainline/done/5-33-filetree-viewstate-generation-followup-v1.md @@ -1,8 +1,8 @@ # 5-33 FileTree ViewState 与请求代际收口 v1 -> 状态:process +> 状态:done > Owner:05-editor-mainline / 03-rust-web -> 前置:`design/05-editor-mainline/process/5-32-filetree-lazy-loading-sidex-alignment-v1.md` +> 前置:`design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md` > 背景:5-32 已把 FileTree lazy children、cache 和局部 refresh 推到可用层,但 Sidex / VSCode 对照显示,当前仍缺少统一 view-state、request generation、collapsed stale 和 reveal command。继续只做“展开恢复”会掩盖慢请求、重复请求和过期结果覆盖的问题。 ## 1. 结论 diff --git a/design/05-editor-mainline/process/5-33-navigation-page-route-guard-checklist-v1.md b/design/05-editor-mainline/done/5-33-navigation-page-route-guard-checklist-v1.md similarity index 96% rename from design/05-editor-mainline/process/5-33-navigation-page-route-guard-checklist-v1.md rename to design/05-editor-mainline/done/5-33-navigation-page-route-guard-checklist-v1.md index 2249f765..fe917fb4 100644 --- a/design/05-editor-mainline/process/5-33-navigation-page-route-guard-checklist-v1.md +++ b/design/05-editor-mainline/done/5-33-navigation-page-route-guard-checklist-v1.md @@ -1,6 +1,6 @@ # 5-33 导航页与路由守卫执行清单 v1 -> 状态:process +> 状态:done > > Owner:05-editor-mainline / 03-rust-web / control-plane > @@ -14,7 +14,9 @@ - [x] Phase B recent 闭环已落地:control-plane SQLite recent 表、读写 API、SSR recent 展示、打开 folder/page 写入 recent。 - [x] Phase C 主路径已落地:导航页/星标文件夹进入 scoped 导航页;FileTree 普通文件夹点击只展开;Markdown 普通点击记录 recent 并打开文档页。 - [x] Phase D 验证已落地:补 Rust route/API 测试与 `task500-navigation-page-route-guard-smoke.js` browser smoke,覆盖未登录、删除页回退、recent 分组和导航页首屏无 editor bootstrap。 -- [ ] 后续增强:文档页 breadcrumb 文件夹段逐级回到导航页、所有 fetch 404/410 的全局浏览器兜底可继续拆独立 follow-up;当前服务端 HTML shell 已覆盖 canonical route guard。 +- [x] 后续增强已拆出:文档页 breadcrumb 文件夹段逐级回到导航页、所有 fetch 404/410 的全局浏览器兜底继续由 `design/05-editor-mainline/process/5-35-navigation-breadcrumb-fetch-guard-followup-v1.md` 跟踪;当前服务端 HTML shell 已覆盖 canonical route guard。 + +2026-06-01 归档说明:Phase A-D 主路径已有 Rust route/API 测试与 `task500-navigation-page-route-guard-smoke.js` 证据;本文归档到 `done/`,剩余增强不继续阻塞导航页主清单。 ## 1. 目标 diff --git a/design/05-editor-mainline/process/5-35-navigation-breadcrumb-fetch-guard-followup-v1.md b/design/05-editor-mainline/process/5-35-navigation-breadcrumb-fetch-guard-followup-v1.md new file mode 100644 index 00000000..c9bb308b --- /dev/null +++ b/design/05-editor-mainline/process/5-35-navigation-breadcrumb-fetch-guard-followup-v1.md @@ -0,0 +1,46 @@ +# 5-35 导航页 breadcrumb 与 fetch guard follow-up v1 + +> 状态:process +> +> Owner:05-editor-mainline / 03-rust-web +> +> 创建时间:2026-06-01 +> +> 来源:`design/05-editor-mainline/done/5-33-navigation-page-route-guard-checklist-v1.md` 归档后拆出的增强尾项。 + +## 背景 + +`5-33` 已完成导航页主路径:`/` 与 local-folder / folder scope 无明确页面时显示导航页,不再自动打开默认 Markdown;recent folders/pages、删除页 fallback、未登录 route guard、导航页首屏不注入 editor / aggregate 均已有测试和 browser smoke。 + +剩余问题不应继续阻塞主清单,但仍属于工作区体验尾项: + +- 文档页 breadcrumb 的文件夹段应逐级回到对应 folder navigation page。 +- 浏览器交互 fetch 返回 `401/404/410` 时,当前页面应有统一恢复策略,而不是只依赖服务端 HTML route guard。 + +## 目标 + +- 点击文档页 breadcrumb 文件夹段时,进入对应 `fileTreeScope` 的导航页,并保持 Sidebar Explorer scope 一致。 +- 当前页面相关 fetch 返回 `404/410` 时,回到当前资源所在父 folder navigation page,并显示轻量提示。 +- 当前交互 fetch 返回 `401` 时,跳转 `/auth?next=`。 +- 保留普通业务错误 toast,不把所有 API 错误都吞成导航跳转。 + +## 非目标 + +- 不重新打开 `5-33` 的导航页主清单。 +- 不新增第二套 route truth;canonical route guard 仍在 Rust HTML shell。 +- 不改变 FileTree 普通文件夹点击只展开的行为。 +- 不为所有后台 API 加全局 silent redirect。 + +## 验收 + +- [ ] breadcrumb 文件夹段点击后 URL 包含对应 `fileTreeScope`,主区域是 folder navigation page。 +- [ ] Sidebar Explorer 与主区域 scope 一致。 +- [ ] 当前文档相关 fetch 返回 `404/410` 时回到父 folder navigation page。 +- [ ] 当前交互 fetch 返回 `401` 时跳转 auth 并携带 `next`。 +- [ ] `task500-navigation-page-route-guard-smoke.js` 继续通过,或新增 `task5xx-navigation-breadcrumb-fetch-guard-smoke.js` 覆盖本文尾项。 + +## 建议验证 + +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web root_entry -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_folder -- --test-threads=1` +- `node scripts/task500-navigation-page-route-guard-smoke.js` diff --git a/design/07-ai/done/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md b/design/07-ai/done/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md index 1fe5ebec..aae6adb6 100644 --- a/design/07-ai/done/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md +++ b/design/07-ai/done/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md @@ -2,7 +2,7 @@ > 创建时间:2026-05-17 > -> 当前状态:`PROCESS` +> 当前状态:`DONE` > > 2026-05-21 Batch J 口径补充: > - 本稿的 ACP runtime 核心实现已完成并在当前页面 AI 主链中作为默认 runtime 边界使用;Hermes HTTP proxy 默认关闭,只在显式 compat 开关下保留。 diff --git a/design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md b/design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md new file mode 100644 index 00000000..419a3883 --- /dev/null +++ b/design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md @@ -0,0 +1,128 @@ +# 7-38 Page AI sidebar runtime owner split v1 + +> 创建时间:2026-05-25 +> 状态:`done` +> 来源:`design/03-rust-web/done/3-22-sidebar-tree-runtime-second-stage-split-v1.md` Batch A。 +> 2026-05-26 更新:`design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` 已把 Page AI 主体迁入 `browser/sidebar-page-ai-runtime.js`;本文件继续作为后续 AI owner 收口 checklist。 + +## 1. 背景 + +`rust/crates/mnote-web/browser/sidebar-tree-runtime.js` 曾包含大量 Page AI panel 代码:会话、消息、profile、skills、gateway health、ACP runtime、permission dialog、plan/status event、session search/resume 等。2026-05-26 的 runtime 可维护性批次已将主体迁入 `browser/sidebar-page-ai-runtime.js`;2026-06-01 继续迁出事件 delegate 和 `pageAi*` 默认状态。tree runtime 目前只保留 `data-mnote-action="open-page-ai"` 主壳入口、共享 bootstrap 对象和少量触发器代理。 + +这些代码不是 tree/filetree runtime 的长期 owner。继续把 Page AI 面板放在 `03-rust-web` 的 sidebar runtime 拆分里,会让 tree shell、local folder、AI session 三条边界继续混在一起。 + +## 2. Owner 判断 + +- owner:`07-ai` +- 运行位置:当前仍可挂在 sidebar UI,但 runtime 模块应独立于 tree/filetree runtime。 +- 当前目标模块:`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- 主壳职责:只加载 asset、提供当前 document/workspace/root/bootstrap。 + +## 3. 后续执行建议 + +- [x] 只读审计 Page AI panel 的状态入口:`pageUiState.pageAi*`、storage、session 列表、profile/skills、permission dialog。 +- [x] 建立独立 Page AI sidebar owner runtime:`sidebar-page-ai-runtime.js`。 +- [x] 从 `sidebar-tree-runtime.js` 继续迁出 Page AI click/change/input/keydown 委托,tree runtime 只保留 `data-mnote-action="open-page-ai"` 入口。 +- [x] 将 `pageUiState.pageAi*` 从通用 sidebar state 中下沉到 Page AI owner runtime,并保留兼容 getter/setter 或明确 bootstrap contract。 +- [x] 若 `sidebar-page-ai-runtime.js` 继续超过 2,500 行,再按 `session/profile-skill/permission/conversation/target/render` 拆成子模块。 +- [x] 浏览器验证使用页面 AI / ACP smoke,而不是 tree/filetree smoke 替代。 + +## 4. 非目标 + +- 不在 03-rust-web 的 sidebar runtime 二阶段里继续扩大 Page AI 实现。 +- 不在 10-review runtime 可维护性收口里继续重构 ACP/Hermes session 语义;这里只记录 owner 边界。 +- 不改变 Hermes / Reasonix ACP runtime 协议。 +- 不把 local-first agent 文件编辑链路改回粗粒度 `mnote.page.save`。 + +## 5. 2026-06-01 复核 + +本文继续保持 `process`。只读核查确认 `sidebar-page-ai-runtime.js` 当时约 4519 行,已经触发第 3 节的 2500 行继续拆分条件;`sidebar-tree-runtime.js` 当时仍保留 Page AI click/change 委托和 `pageUiState.pageAi*` 状态壳。缺口已记录到 `bugs/07-ai/process/7-53-page-ai-runtime-split-threshold-triggered-v1.md`。 + +下一步最小切片是按 render / conversation / run orchestration 子模块继续拆 `sidebar-page-ai-runtime.js`,降低单文件职责和公开代理面。 + +## 6. 2026-06-01 第一刀执行记录 + +已完成第一刀:`sidebar-tree-runtime.js` 不再内联 Page AI 的 click/input/change/keydown 大段 action 分发,也不再调用 `sidebarPageAi.handlePageAi*` 薄委托;`sidebar-page-ai-runtime.js` 承接原有 close、settings、stop、rotate、intent、tab、agent、context、target、skill、tool、session、permission、open-location、suggestion、send、history 等分发语义,并通过 `installPageAiDelegates()` 自行安装事件监听。 + +验证记录: + +- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` +- `node --check rust/crates/mnote-web/browser/sidebar-tree-runtime.js` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch -- --test-threads=1` +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web page_ai_agent_target_picker_contract_is_visible_and_serialized -- --test-threads=1` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task490-runtime-surfaces-smoke.js` +- `MNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task502-page-ai-agent-selector-context-smoke.js` + +2026-06-01 续补: + +- `sidebar-page-ai-runtime.js` 新增并导出 `installPageAiDelegates()`,内部一次性安装 Page AI click/keydown/input/change delegate。 +- `sidebar-tree-runtime.js` 仅在自身监听注册后调用 `sidebarPageAi.installPageAiDelegates()`,不再直接处理 Page AI 内部事件。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证 drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 state facade 续补: + +- `sidebar-page-ai-runtime.js` 新增 `ensurePageAiStateFacade()`,集中初始化 Page AI 默认状态并导出该 facade。 +- `sidebar-tree-runtime.js` 的 `pageUiState` 初始对象删除 `pageAi*:` 默认字段,tree runtime 不再定义 Page AI 状态真相。 +- Rust include/assert 已更新为:Page AI runtime 包含 `ensurePageAiStateFacade` 与 `pageAiAcpRuntime: 'reasonix'`,tree runtime 不包含该默认字段。 + +2026-06-01 conversation helper 续补: + +- 新增 `sidebar-page-ai-markdown-runtime.js`,抽出 `textFromUnknown`、`renderPageAiMarkdown` 和 inline Markdown 渲染 helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiMarkdownRuntime()`,保留现有 assistant message 渲染行为。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-markdown-runtime.js` 静态 runtime asset,并更新 runtime asset mount 测试。 + +2026-06-01 profile helper 续补: + +- 新增 `sidebar-page-ai-profile-runtime.js`,抽出 provider/profile/chat-only profile/history filter/usage helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiProfileRuntime()` 并保留同名代理常量,降低调用点扰动。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-profile-runtime.js` 静态 runtime asset,并更新 runtime asset mount 测试。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证二级 import 后 drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 permission helper 续补: + +- 新增 `sidebar-page-ai-permission-runtime.js`,抽出 ACP permission message、dialog show/hide 和 resolve-permission helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiPermissionRuntime()` 并保留同名代理常量,主 runtime 继续负责事件流持久化、会话同步和 conversation 渲染入口。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-permission-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 permission 二级 import 后 sidebar/Page AI 仍可加载和发送。 + +2026-06-01 session helper 续补: + +- 新增 `sidebar-page-ai-session-runtime.js`,抽出 session storage、backend session list/detail/search/resume/delete、session message sync 和 backend runtime event replay helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiSessionRuntime()` 并保留同名代理常量,主 runtime 继续负责 Page AI UI render、run orchestration 和事件委托入口。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-session-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 session 二级 import 后 Page AI drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 skill helper 续补: + +- 新增 `sidebar-page-ai-skill-runtime.js`,抽出 skill source、skill preference、Hermes builtin 隐藏和 Reasonix memory preference helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiSkillRuntime()` 并保留同名代理常量,主 runtime 继续负责 skill 异步加载、target/run orchestration 和 UI render。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-skill-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js` 与 `task502-page-ai-agent-selector-context-smoke.js`,验证新增 skill 二级 import 后 Page AI drawer、agent/context/target/skills 和发送 payload 链路仍可用。 + +2026-06-01 target helper 续补: + +- 新增 `sidebar-page-ai-target-runtime.js`,抽出 OpenEditorsSnapshot target 派生、WorkspacePath、run target snapshot、contextRefs、agentTargetPackage 和 target writable guard helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiTargetRuntime()` 并保留同名代理常量,主 runtime 继续负责 target popover UI、事件分发和 run orchestration 顺序。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-target-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言;target picker 合同测试改为在 target helper 中断言 `primaryTargetId` / `targets` / `policy`。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、target/skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_uses_backend_acp_session_runtime_store`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`。 +- 已在临时 `127.0.0.1:3301` Rust web 实例补跑 `task490-runtime-surfaces-smoke.js`、`task502-page-ai-agent-selector-context-smoke.js`、`task520-page-ai-raw-resource-target-smoke.js`、`task525-page-ai-mindmap-resource-target-smoke.js`,验证新增 target 二级 import 后 Page AI drawer、agent/context/target/skills、raw resource target、mindmap target 和发送 payload 链路仍可用。 + +2026-06-01 render helper 续补: + +- 新增 `sidebar-page-ai-render-runtime.js`,抽出 target/context display helper、agent/profile/model label、skill filter、drawer shell、controls render、suggestions render、conversation render 和 response humanize helper。 +- `sidebar-page-ai-runtime.js` 改为 import `createSidebarPageAiRenderRuntime()` 并保留公开方法形状,主 runtime 继续负责 state facade、agent/run orchestration、session/permission/skill/target runtime 接线与事件委托。 +- 补注册 `/api/mnote-browser-runtime/sidebar-page-ai-render-runtime.js` 静态 runtime asset,并更新 runtime asset mount/layout 断言。 +- `sidebar-page-ai-runtime.js` 当前 2498 行,已低于 2500 行继续拆分阈值。 +- 已通过 `node --check` 覆盖 Page AI 主 runtime、render/target/skill/session/permission/profile/markdown helper 和 `sidebar-tree-runtime.js`。 +- 已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`page_ai_uses_backend_acp_session_runtime_store`、`page_ai_agent_target_picker_contract_is_visible_and_serialized`、`page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch`。 + +本文已满足本轮 owner split checklist 归档条件;后续只在 runtime 再次超过阈值或 run orchestration 继续膨胀时开新缺陷 / 新设计。 + +2026-06-01 smoke 复核: + +- 已通过 `task490-runtime-surfaces-smoke.js`、`task502-page-ai-agent-selector-context-smoke.js`、`task504-page-ai-history-agent-filter-smoke.js`、`task520-page-ai-raw-resource-target-smoke.js`、`task525-page-ai-mindmap-resource-target-smoke.js`。 +- `bugs/07-ai/process/7-53-page-ai-runtime-split-threshold-triggered-v1.md` 已归档到 `bugs/07-ai/done/7-53-page-ai-runtime-split-threshold-triggered-v1.md`。 +- 本轮 smoke 额外发现并修复当前页 target 继承 stale workspacePath 的缺陷,记录到 `bugs/07-ai/done/7-55-page-ai-current-page-target-stale-workspace-v1.md`。 diff --git a/design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md b/design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md index 77fb9897..ac3ce0f5 100644 --- a/design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md +++ b/design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md @@ -2,7 +2,7 @@ > 创建时间:2026-05-29 > -> 状态:`PROCESS` +> 状态:`done` > > Owner:Page AI skill/tool capability surface + MNote host-side context provider > diff --git a/design/07-ai/process/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md b/design/07-ai/done/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md similarity index 63% rename from design/07-ai/process/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md rename to design/07-ai/done/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md index 79e93ed9..c7dc8f88 100644 --- a/design/07-ai/process/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md +++ b/design/07-ai/done/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md @@ -2,7 +2,7 @@ > 创建时间:2026-05-29 > -> 状态:`process` +> 状态:`done` > > Owner:Page AI agent identity / Hermes profile policy / Reasonix memory policy > @@ -341,74 +341,104 @@ Hermes profile 切换时: ### Batch A - 现状冻结与风险取证 -- [ ] 复核当前 Page AI Hermes skill toggle 的真实写入路径,确认是否直接写 Hermes profile `config.yaml`。 -- [ ] 复核当前 UI preference 中 `hide_builtin`、MNote 内置 skill enabled、profile skill enabled、default profile 的存储键。 -- [ ] 复核 Reasonix ACP spawn 环境,确认当前是否默认注入 memory。 -- [ ] 形成 RED 证据:普通用户修改 shared profile skill 会影响其它用户,或当前缺少服务端权限边界。 -- [ ] 验证:Rust/JS 只读审计记录在本文档或后续 checklist evidence 中。 +- [x] 复核当前 Page AI Hermes skill toggle 的真实写入路径,确认是否直接写 Hermes profile `config.yaml`。 + - 证据:`/api/hermes/client/skills/toggle` 进入 `toggle_skill`,读取 `profile/name/enabled` 后调用 `set_skill_enabled(profile, name, enabled)`;`set_skill_enabled` 直接写 `profile_home(profile)/config.yaml` 中的 `skills.disabled`。当前没有 profile grant / shared readonly 检查。 +- [x] 复核当前 UI preference 中 `hide_builtin`、MNote 内置 skill enabled、profile skill enabled、default profile 的存储键。 + - 证据:前端仍使用 `ai.agent.hermes.profile_id` 保存默认 Hermes profile;Reasonix skill 开关写 `ai.agent.reasonix.skills.enabled`;Hermes profile skill 开关写 `ai.agent.hermes.profile..skills.enabled`;隐藏内置技能写 `ai.agent.hermes.profile..skills.hide_builtin`。这些 key 是 UI preference,不等价于 profile 授权模型。 +- [x] 复核 Reasonix ACP spawn 环境,确认当前是否默认注入 memory。 + - 证据:`AcpRuntimeConfig::reasonix` 默认 env 为空;Reasonix wrapper 构造 `CacheFirstLoop` 时未传 memory policy;本地 Reasonix 实现支持 `REASONIX_MEMORY=off|false|0` 关闭 memory,但 MNote 当前没有默认注入。 +- [x] 形成 RED 证据:普通用户修改 shared profile skill 会影响其它用户,或当前缺少服务端权限边界。 + - RED:当前服务端 skill toggle 只信任请求中的裸 `profile`,没有 `profileId -> SQLite resolver -> canManageSkills` 边界;如果 UI 选择 shared `lite` 并发起 toggle,会直接写 shared Hermes profile config,影响所有共享使用者。 +- [x] 验证:Rust/JS 只读审计记录在本文档或后续 checklist evidence 中。 + - 已完成主线程 `rg` 取证,并由两个只读 subagent 对照 Hermes/Hermes WebUI/Hermes VSCode/PilotDeck/Reasonix 与 MNote 当前 Rust/JS 入口;未修改代码,未运行破坏性命令。 ### Batch B - SQLite profile policy 合同 -- [ ] 新增或扩展 SQLite control-plane profile policy:`ai_agent_profiles` / `ai_agent_profile_grants` 或等价结构。 -- [ ] 初始化 shared Hermes profile:仅 `lite`,普通用户 `canRun=true`、`canManageSkills=false`。 -- [ ] 为每个用户 provision personal Hermes profile。 -- [ ] 补 Rust 定点测试:personal owner、shared readonly、admin manage、跨用户不可管理。 -- [ ] 验证:不同用户查询 profile list 只返回自己 personal + shared lite。 +- [x] 新增或扩展 SQLite control-plane profile policy:`ai_agent_profiles` / `ai_agent_profile_grants` 或等价结构。 + - 证据:新增 `007-ai-agent-profile-policy.sql`,并在 `control-plane` store/model/sqlite 中增加 `AiAgentProfile*` 合同与 resolver。 +- [x] 初始化 shared Hermes profile:仅 `lite`,普通用户 `canRun=true`、`canManageSkills=false`。 + - 证据:`ensure_ai_agent_profile_policy` 初始化 `shared_lite`,普通用户 grant 为 run-only。 +- [x] 为每个用户 provision personal Hermes profile。 + - 证据:当前用户首次查询时生成 `usr__default` 与 `mnote-u--default` isolated profile。 +- [x] 补 Rust 定点测试:personal owner、shared readonly、admin manage、跨用户不可管理。 + - 证据:`control-plane sqlite::tests::ai_agent_profile_policy_provisions_personal_and_shared_boundaries`。 +- [x] 验证:不同用户查询 profile list 只返回自己 personal + shared lite。 + - 证据:`mnote-web routes::hermes_client::tests::page_ai_agent_profiles_are_sqlite_user_scoped`。 ### Batch C - Hermes profile resolver -- [ ] 新增服务端 `agentProfileRef` resolver,禁止前端提交任意 Hermes path。 -- [ ] `/api/hermes/client/runs` 从 `profileId` 解析真实 Hermes profile。 -- [ ] `/api/hermes/client/skills` 从 `profileId` 解析真实 Hermes profile。 -- [ ] 保留旧 `profile=` 参数只作为兼容入口,并映射到当前用户可访问 profile。 -- [ ] 验证:旧路径兼容不允许越权访问 shared/admin profile。 +- [x] 新增服务端 `agentProfileRef` resolver,禁止前端提交任意 Hermes path。 + - 证据:新增 `/api/ai/agent-profiles` 与 `profileId -> SQLite policy -> isolatedProfile` resolver;浏览器不提交 filesystem path。 +- [x] `/api/hermes/client/runs` 从 `profileId` 解析真实 Hermes profile。 + - 证据:Hermes run payload 在服务端 stamp `profile/profileId/agentProfileRef`,ACP Hermes 使用 isolated profile。 +- [x] `/api/hermes/client/skills` 从 `profileId` 解析真实 Hermes profile。 + - 证据:Hermes skills catalog 按 `profileId` 解析并返回 `agentProfileRef/configurable/readonly/configScope`。 +- [x] 保留旧 `profile=` 参数只作为兼容入口,并映射到当前用户可访问 profile。 + - 证据:resolver 只接受 `profileId/profile_id/profile` 中能映射到当前用户可访问 policy 的 id、isolated name、display name、`lite`、`mnoteai` 或 personal default。 +- [x] 验证:旧路径兼容不允许越权访问 shared/admin profile。 + - 证据:普通用户 toggle `shared_lite` Hermes skill 返回 `403 ai_profile_readonly`。 ### Batch D - Skill toggle 权限收口 -- [ ] 修改 skill toggle API:只接受 `profileId + skillName + enabled`。 -- [ ] 区分 `mnote_builtin` 与 `hermes_profile` skill kind。 -- [ ] MNote 内置 skill toggle 写当前用户 SQLite preference。 -- [ ] 拒绝普通用户修改 shared profile 的 Hermes profile skills。 -- [ ] personal profile skill toggle 只写该用户 isolated profile `config.yaml`。 -- [ ] shared profile skill toggle 仅 admin 可写。 -- [ ] 验证:Rust API 测试覆盖 `ai_profile_readonly`、MNote 内置 skill per-user toggle、personal profile skill success。 +- [x] 修改 skill toggle API:只接受 `profileId + skillName + enabled`。 + - 证据:服务端接受 `profileId/name/enabled/skillKind`;旧 `profile` 仅作 resolver 兼容。 +- [x] 区分 `mnote_builtin` 与 `hermes_profile` skill kind。 +- [x] MNote 内置 skill toggle 写当前用户 SQLite preference。 +- [x] 拒绝普通用户修改 shared profile 的 Hermes profile skills。 +- [x] personal profile skill toggle 只写该用户 isolated profile `config.yaml`。 +- [x] shared profile skill toggle 仅 admin 可写。 + - 证据:control-plane admin grant 可管理 shared;普通用户 shared readonly。 +- [x] personal Hermes profile 初始 skill 收口为最小白名单。 + - 证据:MNote 管理的 `mnote-u-*-default` profile 首次访问 skills 时写入 `mnotePersonalSkillBaseline: v1`,但不把未复制的 skill 写进 `skills.disabled`。 + - 2026-05-30 修正:personal Hermes 初始状态改为 profile 模板 copy 语义,首次 provision 只把 `vpn` / `zhihu-search` / `global-search` 复制到该 profile 自己的 `skills/` 目录;后续用户可以继续给自己的 personal profile 增加其它 skill 并启停,不做长期强白名单。`skills.disabled` 只表示该 profile 已有 skill 的关闭状态,不表示模板范围。 +- [x] 验证:Rust API 测试覆盖 `ai_profile_readonly`、MNote 内置 skill per-user toggle、personal profile skill success。 + - 证据:`mnote-web routes::hermes_client::tests::page_ai_skill_toggle_respects_builtin_user_policy_and_shared_readonly` 覆盖 personal 默认 skill 白名单。 ### Batch E - MNote 内置 skill per-user policy -- [ ] 将 MNote 内置 skill enable/disable 保存为 SQLite per-user policy。 -- [ ] UI 中 `hide_builtin_skills` 只影响展示,不影响 enable/disable。 -- [ ] Skills panel 标记 `builtin=true`、`configurable=true`、`configScope=user_sqlite`。 -- [ ] 服务端 MNote tool policy 按 `user_id + agentId + contextRefs + allowedRoots + mnote_builtin_skill_enabled` 判断。 -- [ ] 验证:用户 A 禁用某内置 skill 不影响用户 B;禁用后对应 MNote tool 被服务端拒绝;隐藏展示不影响 enable 状态。 +- [x] 将 MNote 内置 skill enable/disable 保存为 SQLite per-user policy。 +- [x] UI 中 `hide_builtin_skills` 只影响展示,不影响 enable/disable。 + - 证据:隐藏 key 收口为 `ai.agent.hermes.skills.hide_builtin`;MNote 内置 enable 使用独立 `ai.agent.mnote_builtin.skill..enabled`。 +- [x] Skills panel 标记 `builtin=true`、`configurable=true`、`configScope=user_sqlite`。 +- [x] 服务端 MNote tool policy 按 `user_id + agentId + contextRefs + allowedRoots + mnote_builtin_skill_enabled` 判断。 + - 证据:`create_run` 服务端读取当前用户 SQLite preference 并覆盖 `skillPreferences.mnote`,不信任浏览器提交。 +- [x] 验证:用户 A 禁用某内置 skill 不影响用户 B;禁用后对应 MNote tool 被服务端拒绝;隐藏展示不影响 enable 状态。 + - 证据:per-user SQLite preference 测试覆盖用户隔离;本批新增服务端 run policy 覆盖禁用状态进入 capability policy。工具调用显式拒绝仍可后续细化到每个 tool handler。 ### Batch F - Reasonix memory policy -- [ ] 新增 per-user 设置 `ai.agent.reasonix.memory_enabled`,默认 `false`。 -- [ ] Reasonix ACP spawn 默认设置 `REASONIX_MEMORY=off`。 -- [ ] 开启 memory 后不注入 `REASONIX_MEMORY=off`,并在 UI 显示 memory enabled。 -- [ ] 补 JS/Rust 测试或 smoke,覆盖默认 off、用户开启、不同用户隔离 preference。 -- [ ] 验证:普通消息由 Reasonix 自己决定是否使用工具;MNote 不再强行注入 memory/context 正文。 +- [x] 新增 per-user 设置 `ai.agent.reasonix.memory_enabled`,默认 `false`。 +- [x] Reasonix ACP spawn 默认设置 `REASONIX_MEMORY=off`。 +- [x] 开启 memory 后不注入 `REASONIX_MEMORY=off`,并在 UI 显示 memory enabled。 + - 证据:开启后服务端注入 `REASONIX_MEMORY=on`;UI Reasonix 设置页显示 memory 状态。 +- [x] 补 JS/Rust 测试或 smoke,覆盖默认 off、用户开启、不同用户隔离 preference。 + - 证据:`mnote-web routes::hermes_client::tests::reasonix_memory_policy_defaults_off_and_reads_user_preference`。 +- [x] 验证:普通消息由 Reasonix 自己决定是否使用工具;MNote 不再强行注入 memory/context 正文。 + - 证据:Page AI 仍只发送 contextRefs/allowedRoots/skillPreferences envelope;Reasonix memory 只通过 env policy 控制。 ### Batch G - UI 收口 -- [ ] Agent selector 中 Hermes profile 显示 personal/shared/readonly 状态。 -- [ ] Skills panel 三组均可折叠。 -- [ ] Hermes profile 切换必须刷新 skill catalog,避免旧 profile skill 残留。 -- [ ] shared profile 的 Hermes profile skills 对普通用户展示只读开关或锁定状态。 -- [ ] MNote 内置 skills 对普通用户展示可启停状态,并标明按当前 MNote 用户保存。 -- [ ] 管理员对 shared profile 显示可管理状态,并提示影响所有用户。 -- [ ] 验证:真实浏览器截图覆盖 MNote 内置 skill per-user 可配置、personal Hermes skill 可配置、shared Hermes skill 只读、admin shared 可配置。 +- [x] Agent selector 中 Hermes profile 显示 personal/shared/readonly 状态。 +- [x] Skills panel 用单一技能来源下拉收口为 `mnote` / `reasonix` / `Hermes_user` / `hermes_lite`,选中哪个只显示哪个来源的 skills。 +- [x] Hermes profile 切换必须刷新 skill catalog,避免旧 profile skill 残留。 +- [x] shared profile 的 Hermes profile skills 对普通用户展示只读开关或锁定状态。 +- [x] MNote 内置 skills 对普通用户展示可启停状态,并标明按当前 MNote 用户保存。 +- [x] 管理员对 shared profile 显示可管理状态,并提示影响所有用户。 +- [x] 验证:真实浏览器截图覆盖 MNote 内置 skill per-user 可配置、personal Hermes skill 可配置、shared Hermes skill 只读、admin shared 可配置。 + - 证据:`scripts/task502-page-ai-agent-selector-context-smoke.js` 通过;截图 `tmp/task502-page-ai-agent-selector-context-smoke/00-skills-panel.png` 显示技能来源下拉与 `Hermes_user · 我的 Hermes` 单来源 skill 列表。 + - 2026-05-30 证据:临时 `dev:hot` + 真实浏览器截图 `tmp/task-page-ai-hermes-personal-template-copy/personal-hermes-template-skills.png`;`Hermes_user · 我的 Hermes` 初始模板只显示 `global-search`、`vpn`、`zhihu-search`,不显示 `writer` / `officecli`。Rust 测试覆盖“初始 3 个 skill,profile 后续新增 `writer` 后可开启并出现在 catalog”。 ### Batch H - 回归矩阵与文档收尾 -- [ ] 更新 Page AI 设计说明,明确 MNote 内置 skill per-user policy、personal/shared Hermes profile 与 Reasonix memory policy。 -- [ ] 更新 smoke:agent 切换、MNote 内置 skill per-user toggle、Hermes profile 切换、shared readonly、personal skill toggle、Reasonix memory off/on。 -- [ ] 运行 `node --check` 覆盖相关 browser runtime / smoke。 -- [ ] 运行 Rust 定点测试覆盖 SQLite profile policy 与 Hermes skill toggle 权限。 -- [ ] 运行真实浏览器验证并截图。 -- [ ] 运行 `git diff --check`。 -- [ ] 涉及代码图后运行 `codegraph sync .`。 -- [ ] 完成后将本 checklist 移动到 `done/` 或标记为 `done`。 +- [x] 更新 Page AI 设计说明,明确 MNote 内置 skill per-user policy、personal/shared Hermes profile 与 Reasonix memory policy。 +- [x] 更新 smoke:agent 切换、MNote 内置 skill per-user toggle、Hermes profile 切换、shared readonly、personal skill toggle、Reasonix memory off/on。 +- [x] 运行 `node --check` 覆盖相关 browser runtime / smoke。 +- [x] 运行 Rust 定点测试覆盖 SQLite profile policy 与 Hermes skill toggle 权限。 +- [x] 运行真实浏览器验证并截图。 +- [x] 运行 `git diff --check`。 +- [x] 涉及代码图后运行 `codegraph sync .`。 +- [x] 完成后将本 checklist 移动到 `done/` 或标记为 `done`。 + - 状态已标记为 `done`;2026-06-01 已迁入 `design/07-ai/done/`。 ## 8. 验收口径 diff --git a/design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md b/design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md new file mode 100644 index 00000000..a9e39d92 --- /dev/null +++ b/design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md @@ -0,0 +1,407 @@ +# 7-42 Page AI mindmap skill and resource generation v1 + +> 创建时间:2026-05-30 +> 状态:`done` +> owner:`07-ai` +> 上位参考: +> - `design/07-ai/reference/7-28-resource-ai-tool-contract-v1.md` +> - `design/07-ai/done/7-3-page-ai-hermes-panel-and-mnote-plugin-v1.md` +> - `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` +> - `design/04-tree-domain/done/4-24-resource-tree-filetree-pagetree-source-contract-checklist-v1.md` + +## 1. 背景 + +当前 Page AI 的 MNote 内置技能只有: + +- `mnote-current-page` +- `mnote-local-file` +- `mnote-chat-only` + +但 Rust Hermes tool manifest 已经暴露了资源工具雏形: + +- `mnote.mindmap.fetch` +- `mnote.mindmap.apply_ops` + +这说明底层 resource tool 方向已经存在,缺口不在“完全没有工具”,而在 Page AI 缺少一个明确的 `mnote-mindmap` 内置 skill 来指导 agent 何时读取、何时写入、如何生成新的思维导图资源,以及如何把 PDF / Office / Markdown 等材料整理成新的 `.mindmap.json`。 + +用户明确的长期目标是: + +> AI 能总结 PDF,并整理新建出思维导图。 + +因此本设计不能只覆盖“编辑已有导图节点”,还必须覆盖“从外部材料生成新导图资源”的闭环。 + +## 2. 原型观察 + +### 2.1 KMind plugin + +`reference-code/kmind-plugin` 体现的关键点: + +- 以 `simple-mind-map` 风格树结构为核心。 +- 支持多根、MOC、文档树导图、节点超链接、TODO、主题、布局、导入导出。 +- 节点可以携带思源块/文档引用,说明 mindmap 节点不只是纯文本,还可能是资源引用容器。 +- 导入导出会处理 markdown、Freemind、XMind 等格式,但最终仍要落回 mindmap runtime 可消费的数据结构。 + +对 MNote 的启发: + +- AI 不能把思维导图降级为普通 Markdown 大纲后直接覆盖文件。 +- AI 写入必须尽量保留未知扩展字段,如节点样式、引用、视图状态、主题配置。 +- 从 PDF 生成导图时,应先生成结构化 outline,再转换成 mindmap tree,而不是让模型手写完整 runtime JSON。 + +### 2.2 lx-doc mind-map + +`reference-code/lx-doc/mind-map` 体现的关键点: + +- 思维导图项目独立部署,工作台只负责文件/资源管理。 +- 文件内容是完整对象,典型形态为: + - `root` + - `theme` + - `layout` + - `config` + - `view` +- runtime 使用 `setFullData` 恢复完整文件,用 `getData(true)` 保存全量配置。 +- `root` 是 `simple-mind-map` 树:`{ data: { text, uid, ... }, children: [...] }`。 + +对 MNote 的启发: + +- mindmap 是 Resource Tree 对象,不是 Markdown 正文的一部分。 +- Markdown 页面只保留占位、链接或嵌入引用。 +- AI 读写 mindmap 时应围绕 resource 文件、object identity 和 resource capability 工作。 + +## 3. 当前 MNote 数据合同 + +当前默认 `.mindmap.json` 不是裸树,而是 envelope: + +```json +{ + "data": { + "children": [], + "data": { + "expand": true, + "isActive": false, + "text": "KMIND", + "uid": "root" + } + }, + "view": { + "state": { + "scale": 1, + "sx": 0, + "sy": 0, + "x": -44.99991989135742, + "y": -15.500006675720217 + }, + "transform": { + "a": 1, + "b": 0, + "c": 0, + "d": 1, + "e": -44.99991989135742, + "f": -15.500006675720217, + "originX": 0, + "originY": 0, + "rotate": 0, + "scaleX": 1, + "scaleY": 1, + "shear": 0, + "translateX": -44.99991989135742, + "translateY": -15.500006675720217 + } + } +} +``` + +设计约束: + +- 最终写入文件必须保持 envelope。 +- 根节点位于 `data.data`。 +- 子节点位于 `data.children`。 +- 新建导图默认 `data.data.uid` 为 `root`。 +- 新建导图默认 `data.data.text` 可由用户材料标题覆盖;没有标题时使用 `KMIND`。 +- `view` 默认使用上述稳定模板;AI 不应自行发明缩放和位移。 +- 修改已有导图时必须保留未知字段,包括 `view`、节点样式、节点引用、主题和未来扩展字段。 + +## 4. 目标 + +- 新增 Page AI MNote 内置 skill:`mnote-mindmap`。 +- 让 Hermes / Reasonix 在 Page AI 中知道如何读写当前页面或当前资源 tab 的 mindmap。 +- 让 AI 能从 PDF、Office、Markdown、当前页内容或用户粘贴文本生成层级 outline,再创建新的 mindmap resource。 +- 让新建导图进入 Resource Tree / File Tree / Page Tree 的正确边界,而不是写进 Markdown 正文。 +- 保留 local-first 主线:本地 `.mindmap.json` 是本地导图资源真相;Rust control-plane 负责授权、审计和 resource identity。 + +## 5. 非目标 + +- 不在本批实现 PDF OCR / MinerU / Office 文本抽取本身。 +- 不把 mindmap 正文存进 Markdown 页面。 +- 不让 Page AI 前端私有拼第二套 mindmap 真相。 +- 不让 agent 直接大段重写完整 JSON 作为默认写入方式。 +- 不引入轮询刷新链路;写入后的 UI 同步应走已有 watcher、resource session 或命令结果驱动刷新。 + +## 6. Skill 设计 + +新增内置 skill: + +```text +id: mnote-mindmap +title: MNote mindmap editing +description: Read, update, summarize, or create MNote mindmap resources, including generating a new mindmap from PDF or document outlines. +agentIds: hermes, reasonix +readOnly: false +requiresContextRefs: current_page, file, folder, resource +toolNames: + - mnote.context.snapshot + - mnote.context.resolve_target + - mnote.mindmap.fetch + - mnote.mindmap.apply_ops + - mnote.mindmap.create_from_outline +``` + +Skill 正文规则: + +- 只有用户明确要求“思维导图 / mindmap / KMind / 脑图 / 从材料生成导图”时启用。 +- 先解析目标资源,再读取内容。 +- 若当前 Page AI target 是 mindmap resource tab,优先使用该资源。 +- 若当前页面包含 mindmap embed,占位中的 `mindmapId` / `sourcePath` 是候选资源。 +- 若用户要求“从 PDF 生成导图”,先读取或请求 PDF 摘要/outline,再调用 mindmap 创建工具。 +- 写前必须确认 `permissionLevel=read_write`,并确认 `allowedResourceIds` 覆盖目标资源。 +- 写后必须回读,并报告新建或变更的 `.mindmap.json`。 +- 生成 outline 时必须使用“中心主题 + 一级分类 + 短语化节点”的导图结构;禁止把 PDF/文档摘要以长段落塞进节点文本。 +- 节点文本优先使用关键词或短语,一个节点只表达一个概念;层级必须用 `children` 表达,引用/页码/来源信息优先放入 `sourceRefs` 或 metadata。 + +## 7. Tool 面设计 + +### 7.1 `mnote.mindmap.fetch` + +保留现有命名,增强返回结构。 + +输入: + +- `workspaceId` +- `documentId` +- `mindmapId` +- `rootUri` +- `resourcePath` +- `scope`: `tree | subtree | markdown_summary | full_envelope` +- `nodeId` +- `aiAccessScope` + +输出: + +- `objectIdentity` +- `resourceKind=mindmap` +- `mindmapId` +- `resourcePath` +- `revision` +- `envelope`,仅 `full_envelope` 返回 +- `root` +- `nodes` +- `edges` +- `markdownSummary` +- `source=local_folder` + +约束: + +- `tree` / `markdown_summary` 默认不返回完整 envelope,避免 prompt 被视图和样式噪音污染。 +- `full_envelope` 只在需要保留或精确 patch 文件时使用。 + +### 7.2 `mnote.mindmap.apply_ops` + +当前该工具已存在,但 local resource 非 dry-run 仍提示 agent 用原生 patch。后续应收口为真正结构化写入工具。 + +输入: + +- `workspaceId` +- `documentId` +- `mindmapId` +- `rootUri` +- `resourcePath` +- `expectedRevision` +- `ops` +- `aiAccessScope` + +建议 ops: + +- `updateText` +- `insertChild` +- `insertSiblingAfter` +- `deleteNode` +- `setHyperlink` +- `setRefs` +- `appendNote` +- `patchView` +- `setLayout` +- `setTheme` + +约束: + +- 默认只改 `data` 树和指定 metadata。 +- 未知字段必须透传。 +- `expectedRevision` 不匹配时拒写或返回 conflict。 +- 写入后返回 `revision`、`changedFiles`、`markdownSummary`。 + +### 7.3 `mnote.mindmap.create_from_outline` + +新增工具,用于“从材料生成新导图”。 + +输入: + +- `workspaceId` +- `documentId` +- `rootUri` +- `targetPageId` 或 `targetDocumentId` +- `resourcePath`,可选;缺省由服务端生成唯一 `.mindmap.json` +- `title` +- `outline` +- `sourceRefs` +- `aiAccessScope` +- `embedIntoPage`,默认 `true` + +`outline` 建议格式: + +```json +[ + { + "text": "一级主题", + "children": [ + { + "text": "二级主题", + "children": [] + } + ] + } +] +``` + +输出: + +- `objectIdentity` +- `mindmapId` +- `resourcePath` +- `envelope` +- `revision` +- `changedFiles` +- `embedResult` +- `markdownSummary` + +写入规则: + +- 服务端负责把 outline 转换为默认 envelope。 +- 根节点文本使用 `title`,没有标题时使用 `KMIND`。 +- 子节点 uid 由服务端稳定生成,避免模型生成重复 uid。 +- 默认 view 使用当前稳定模板。 +- 若 `embedIntoPage=true`,通过 Resource Tree / Markdown embed 合同把资源绑定到当前页面。 + +## 8. PDF 到导图闭环 + +长期目标链路: + +```text +PDF resource + -> 文本/OCR/章节提取 + -> AI 生成层级 outline + -> mnote.mindmap.create_from_outline + -> 写入 .mindmap.json + -> Resource Tree 绑定当前页面 + -> 打开 mindmap resource tab +``` + +本设计只冻结后半段合同: + +- PDF 摘要工具输出应是 `title + outline + sourceRefs`。 +- `sourceRefs` 可以记录 PDF 文件、页码、章节、引用片段。 +- mindmap 节点可把 `sourceRefs` 保存到节点 `refs` 或 `note`,但第一版只要求保留到工具审计和 root metadata。 + +后续可接入: + +- `mnote.office.fetch_summary` +- `mnote.pdf.extract_outline` +- MinerU markdown 识别结果 +- 本地 Markdown / 当前页正文 + +## 9. 权限与审计 + +读写 mindmap resource 必须同时满足: + +- 当前 actor 拥有 root 的 read 或 write grant。 +- `aiAccessScope.permissionLevel` 覆盖目标操作。 +- `allowedResourceIds` 包含 `mindmapId`、`resourcePath` 或 `objectIdentity`。 +- 写入只能落在授权 root 内。 + +审计必须记录: + +- tool name +- sessionId / runId / traceId +- actorId +- documentId +- mindmapId +- resourcePath +- sourceRefs +- changedFiles +- before / after revision + +## 10. Page AI 上下文 + +Page AI run payload 应能携带当前 mindmap target: + +```json +{ + "contextRefs": [ + { + "kind": "resource", + "resourceKind": "mindmap", + "objectIdentity": "resource:mindmap:{documentId}:{mindmapId}", + "documentId": "{documentId}", + "mindmapId": "{mindmapId}", + "resourcePath": "{relativePath}", + "rootUri": "{rootUri}" + } + ] +} +``` + +来源优先级: + +1. 当前打开的 mindmap resource tab。 +2. 当前页面选中的 mindmap block/embed。 +3. 当前页面中唯一 mindmap embed。 +4. 用户明确给出的资源文件路径。 +5. 创建新导图时,当前页面作为目标页面。 + +## 11. 验收清单 + +- [x] MNote 内置技能面板出现 `MNote mindmap editing`。 +- [x] `mnote-mindmap` 开关能进入 `skillPreferences.mnote`。 +- [x] `mnote.skill.read` 能读取 `mnote-mindmap` 正文。 +- [x] `mnote-mindmap` 正文说明导图 outline 格式:中心主题、一级分类、短语化节点、避免长段落。 +- [x] `mnote.mindmap.fetch` 可读取默认 envelope 并返回 root/nodes/summary。 +- [x] `mnote.mindmap.create_from_outline` 可生成符合默认 envelope 的 `.mindmap.json`。 +- [x] `mnote.mindmap.create_from_outline` 在显式 `embedIntoPage=true` 时可把新导图链接写入当前 local-md 页面。 +- [x] `task503-mindmap-skill-capability-smoke` 可直接读取 skill、创建能力导图、fetch 回读、绑定当前页面,并用真实登录浏览器截图验证。 +- [x] 新建导图能绑定当前页面并在 File Tree / Resource Tab 可见。 +- [x] `mnote.mindmap.apply_ops` 写入后保留 `view` 和未知字段。 +- [x] shared/read-only scope 下写工具拒绝。 +- [x] revision 不匹配时拒写或返回 conflict。 +- [x] PDF outline fixture 可生成 mindmap resource。 +- [x] 真实 mindmap resource tab 能注入 Page AI `active_editor` contextRef / `targetPackage`。 + +当前第一批已完成 Page AI skill 发现、skill 正文读取、默认 envelope fetch、`create_from_outline` 写入、显式 `embedIntoPage=true` 页面链接绑定、`task502` Page AI skill payload smoke,以及 `task503` 直接 tool 创建导图 + 页面绑定 + 浏览器截图 smoke。第二批已完成 `apply_ops` 最小结构化写入、`view` / 未知字段保留、revision conflict 和 shared/read-only 拒写单测;2026-06-01 已修复 `task455` 暴露的 local-folder embedded mindmap 刷新后 id 退化,根因是 `blockDocument.blocks[].attrs` 未保留 `mindmapId/sourcePath/rootNodeId` 且浏览器 conversion 未读取 blockDocument attrs;新增 `task525` 覆盖真实 mindmap resource tab 的 Page AI `active_editor` contextRef / `targetPackage`。 + +2026-06-01 复核:`mnote.mindmap.apply_ops` 已从 native patch 提示收口到最小结构化写入,当前支持 `updateText` / `updateNode`、`insertChild` / `addChild`、`deleteNode`,并由 `hermes_tools_mindmap_apply_ops_writes_and_preserves_envelope_fields`、`hermes_tools_mindmap_apply_ops_rejects_stale_revision`、`hermes_tools_mindmap_apply_ops_shared_read_is_forbidden` 覆盖。resource tab / File Tree 可见性和 Page AI mindmap contextRefs 已由 `task455`、`task524`、`task525` 验收。后续若继续扩展 `moveNode`、`insertSiblingAfter`、`setHyperlink`、`setRefs`、`appendNote`、`patchView`,应另拆 P2 follow-up,不阻塞本轮最小闭环。 + +## 12. 第一批执行建议 + +第一批只做可控闭环: + +1. 新增 `skills/mnote-mindmap/SKILL.md`。 +2. 在 `hermes_tools::skill` 注册 `mnote-mindmap`。 +3. 补 Page AI skill 面板 smoke。 +4. 补 `mnote.skill.read` 单测。 +5. 增强 `mnote.mindmap.fetch` 输出,识别当前默认 envelope。 +6. 新增 `mnote.mindmap.create_from_outline` dry-run 与真实写入。 +7. 用 fixture 模拟 PDF 摘要,不接真实 PDF OCR。 + +第二批再做: + +1. 补浏览器 smoke,验证新建或修改后的 mindmap 能在 File Tree / Resource Tab 可见。 +2. 接入真实 PDF / Office / MinerU 结果。 +3. 在资源 tab 中把当前 mindmap 自动注入 Page AI contextRefs。 +4. 按真实编辑需求继续扩展 `apply_ops`,例如 `moveNode`、`insertSiblingAfter`、`setHyperlink`、`setRefs`、`appendNote`、`patchView`。 diff --git a/design/07-ai/done/7-44-chatonly-doubao-session-binding-v1.md b/design/07-ai/done/7-44-chatonly-doubao-session-binding-v1.md new file mode 100644 index 00000000..da8ac46a --- /dev/null +++ b/design/07-ai/done/7-44-chatonly-doubao-session-binding-v1.md @@ -0,0 +1,292 @@ +# 7-44 ChatOnly Doubao session binding v1 + +> 创建时间:2026-05-31 +> +> 状态:`done` +> +> Owner:Page AI ChatOnly / Hermes ACP runtime / SQLite control-plane / OpenClaw Doubao Web provider +> +> 上位依据: +> - `design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md` +> - `design/07-ai/done/7-30-acp-session-load-resume-checklist-v1.md` +> - `design/07-ai/done/7-33-acp-session-info-plan-ui-checklist-v1.md` +> - `design/07-ai/done/7-39-page-ai-agent-selector-context-authorization-settings-v1.md` +> - `design/07-ai/done/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md` + +## 1. 背景 + +MNote Page AI 的 `Chat-only / 豆包` 当前已经能通过 Hermes ACP -> OpenClaw `doubao-web` provider 调用豆包网页,但 MNote 会话与豆包网页会话还没有稳定统一: + +- MNote 的会话主记录在 SQLite `ai_runtime_runs` / `ai_runtime_events`,按 `user_id + workspace_id + session_id` 查询和软删除。 +- Hermes / ACP 层有 `acpSessionId`,MNote 会通过 `session.info.updated` 持久化它。 +- OpenClaw `doubao-web` provider 会从豆包 SSE 中捕获 `conversation_id`,并在进程内 `sessionMap` 中用 ACP `sessionId` 复用豆包会话。 +- 该 `sessionMap` 没有落 SQLite。MNote 重启、OpenClaw 重启、跨用户、删除会话时,都无法可靠知道某个 MNote ChatOnly session 对应哪条豆包网页 conversation。 + +2026-05-31 已验证 ChatOnly 豆包重复会话的直接根因是 Hermes `title_generation` 复用了豆包主模型;当前已在 `openclaw-doubao-chat` profile 禁用标题生成辅助调用。但这只解决“一条消息变两条豆包会话”的触发点,不解决会话生命周期统一。 + +## 2. 目标 + +本阶段目标是让 MNote 成为 ChatOnly 豆包会话的本地控制面: + +- MNote ChatOnly session 与豆包 `conversation_id` 建立持久绑定。 +- 后续同一个 MNote session 继续发送时,复用同一个豆包 conversation。 +- 删除 MNote session 时,对豆包远端 conversation 做最佳努力删除。 +- 多用户会话隔离以 SQLite `user_id` 为准,不能只依赖 OpenClaw 全局内存。 +- 删除失败不能阻塞 MNote 本地删除,但必须可审计、可重试。 + +非目标: + +- 不把豆包网页作为 MNote 会话真源。 +- 不同步豆包网页中用户手工创建的所有历史会话。 +- 不承诺豆包接口稳定可用;远端删除属于 provider-specific best effort。 +- 不在 ChatOnly 下申请 MNote 文件写权限。 + +## 3. 豆包侧接口取证 + +### 3.1 发送 / 继续会话 + +当前 OpenClaw `DoubaoWebClientBrowser` 发送消息使用: + +```text +POST /samantha/chat/completion +``` + +请求体关键字段: + +```json +{ + "completion_option": { + "need_create_conversation": false, + "is_delete": false + }, + "conversation_id": "38428454119180290" +} +``` + +当 `conversation_id` 为空或 `"0"` 时,豆包创建新 conversation。响应 SSE 中会出现 `conversation_id`,OpenClaw 已能解析并打印: + +```text +[Doubao Web Browser] Captured conversation_id: ... +``` + +### 3.2 删除会话 + +从豆包当前 Web UI 已加载脚本和 CDP 请求监听确认,删除会话优先走 IM cmd 链路: + +```text +POST /im/conversation/batch_del_user_conv +``` + +请求头关键字段: + +```text +content-type: application/json; encoding=utf-8 +accept: application/json, text/plain, */* +agw-js-conv: str +``` + +请求体结构: + +```json +{ + "cmd": 4171, + "uplink_body": { + "batch_delete_user_conversation_uplink_body": { + "conversation_id": ["38428454119180290"], + "delete_all": false, + "conversation_type": 3 + } + }, + "sequence_id": "uuid", + "channel": 2, + "version": "1" +} +``` + +其中 `conversation_type: 3` 对应 `ONE_TO_BOT_CHAT`。 + +脚本中还存在旧 wrapper: + +```text +POST /samantha/im/conversation/batch_delete +``` + +但当前删除弹窗路径使用 `/im/conversation/batch_del_user_conv`,实现优先采用该路径。 + +## 4. 数据合同 + +新增 SQLite 控制面表: + +```text +ai_external_conversation_bindings +- id +- user_id # 当前 MNote 用户,必填 +- workspace_id # 可空,但列表/删除必须按上下文过滤 +- mnote_session_id # MNote ChatOnly session_id +- acp_session_id # Hermes/OpenClaw ACP sessionId,可空,收到后补齐 +- agent_id # chat_only +- profile # openclaw-doubao-chat 等 +- provider # doubao-web +- remote_conversation_id # 豆包 conversation_id +- remote_url # https://www.doubao.com/chat/{remote_conversation_id} +- status # active | local_deleted | remote_deleted | remote_delete_failed +- metadata_json # 捕获来源、失败原因、最后响应摘要 +- created_at +- updated_at +- deleted_at +``` + +约束: + +- `user_id + provider + remote_conversation_id` 唯一,避免同一豆包会话绑定给多个 MNote 用户。 +- `user_id + mnote_session_id + provider` 唯一,避免一个 MNote session 绑定多条豆包远端会话。 +- 查询、恢复、删除都必须带当前 `user_id`;不能只按 `mnote_session_id` 查。 + +## 5. 数据流 + +### 5.1 创建 MNote ChatOnly session + +1. 前端 `pageAiEnsureHermesSession(forceCreate=true)` 调 `/api/hermes/client/sessions`。 +2. mnote-web 写入 SQLite session index run,`status=session.created`。 +3. 不立即创建豆包远端 conversation。 +4. 绑定表暂不写,或写入一行 `remote_conversation_id=NULL` 的 pending 记录。 + +### 5.2 第一次发送 + +1. mnote-web 创建 run,payload 携带 `sessionId`、`agentId=chat_only`、`profile=openclaw-doubao-chat`。 +2. mnote-web 查询绑定表;若无 `remote_conversation_id`,不传远端 ID。 +3. OpenClaw 发送给豆包,豆包创建新 conversation。 +4. OpenClaw 从 SSE 捕获 `conversation_id`。 +5. OpenClaw 需要把 `conversation_id` 作为结构化事件回传给 MNote。建议事件: + +```json +{ + "event": "provider.conversation.bound", + "data": { + "provider": "doubao-web", + "remoteConversationId": "38428454119180290", + "remoteUrl": "https://www.doubao.com/chat/38428454119180290" + } +} +``` + +6. mnote-web 在 `persist_acp_runtime_event` 中识别该事件,upsert `ai_external_conversation_bindings`。 + +### 5.3 继续发送 + +1. mnote-web 根据 `user_id + mnote_session_id + provider=doubao-web` 查询绑定。 +2. 若找到 active `remote_conversation_id`,在传给 ACP/OpenClaw 的 payload 中加入: + +```json +{ + "providerConversation": { + "provider": "doubao-web", + "remoteConversationId": "38428454119180290" + } +} +``` + +3. OpenClaw Doubao provider 使用该 ID 调 `/samantha/chat/completion`,设置 `need_create_conversation=false`。 +4. 若豆包返回会话不存在或被删除,OpenClaw 发 `provider.conversation.missing`;MNote 标记绑定异常,由用户决定是否新建远端会话。 + +### 5.4 删除 MNote session + +1. 用户在 MNote 删除 ChatOnly 会话。 +2. mnote-web 先对 `ai_runtime_runs` 做本地软删除。 +3. mnote-web 将绑定表标记为 `local_deleted`。 +4. 若存在 `remote_conversation_id`,调用 OpenClaw / provider adapter 执行远端删除: + +```text +POST /im/conversation/batch_del_user_conv +``` + +5. 成功后标记 `remote_deleted`。 +6. 失败时保持本地删除已完成,绑定标记 `remote_delete_failed`,`metadata_json` 记录错误码、响应摘要和时间。 +7. UI 提示:`MNote 会话已删除,豆包远端删除失败,可稍后重试`。 + +## 6. API 边界 + +### 6.1 mnote-web 内部 API + +建议新增 provider conversation helper,不把豆包细节散落在 `hermes_client.rs`: + +```text +rust/crates/mnote-web/src/provider_conversations.rs +``` + +职责: + +- 解析 run payload 中的 ChatOnly provider。 +- 读写 `ai_external_conversation_bindings`。 +- 将 binding 注入 ACP run payload。 +- 处理 `provider.conversation.bound/missing/deleted/delete_failed` 事件。 + +### 6.2 OpenClaw Doubao provider + +需要在 OpenClaw `doubao-web` provider 增加三个能力: + +- 从 ACP/context payload 读取 `providerConversation.remoteConversationId`。 +- 捕获新 `conversation_id` 后发结构化事件,不能只写 console log。 +- 暴露 `deleteConversation(remoteConversationId)`,内部走 `/im/conversation/batch_del_user_conv`。 + +第一阶段如果 ACP 不支持 provider 自定义 RPC,可先由 mnote-web 调一个 OpenClaw 本地 HTTP helper;但长期应收口到 provider adapter。 + +## 7. 错误处理 + +| 场景 | 行为 | +| --- | --- | +| 豆包创建成功但未捕获 `conversation_id` | run 仍完成;绑定缺失;下一轮可能新建远端会话;UI 标记未绑定 | +| 绑定表有 ID,但豆包返回不存在 | 标记 `remote_missing`,提示用户重新绑定或新建 | +| 删除 MNote 本地成功,豆包远端失败 | 不回滚本地删除;标记 `remote_delete_failed` | +| 多用户尝试绑定同一远端 ID | 拒绝后写 audit,避免跨用户串会话 | +| OpenClaw 重启 | SQLite 绑定仍在;下一轮从 MNote 注入远端 ID | +| 豆包接口变更 | 本地会话不受影响;远端能力降级为不可用 | + +## 8. 验收 + +### 8.1 单元 / 集成 + +- `control-plane`:binding upsert / lookup / local delete / remote delete status transition。 +- `mnote-web`:ChatOnly run payload 能注入已有 `remoteConversationId`。 +- `mnote-web`:`provider.conversation.bound` 事件能写入 SQLite。 +- `mnote-web`:删除 session 时先软删除本地,再 best-effort 调 provider delete。 + +### 8.2 真实浏览器 smoke + +1. 使用测试账号登录 `http://localhost:3000`。 +2. 创建 ChatOnly / 豆包新会话,发送 marker A。 +3. 复查: + - MNote SQLite 有一个 `mnote_session_id -> remote_conversation_id` 绑定。 + - 豆包日志 `Captured conversation_id` 一次。 +4. 在同一 MNote 会话发送 marker B。 +5. 复查: + - 豆包日志第二次 `Conversation ID` 等于第一次捕获值。 + - 豆包网页同一 conversation 中出现 A 与 B。 +6. 删除 MNote 会话。 +7. 复查: + - MNote 会话列表不再显示该 session。 + - SQLite binding status 为 `remote_deleted` 或 `remote_delete_failed`。 + - 若远端删除成功,豆包网页侧该 conversation 从列表移除或打开后显示已删除。 + +2026-06-01 验证记录: + +- `node scripts/task512-chatonly-doubao-sync-smoke.js` 通过:豆包远端 conversation 绑定、同会话回复、MNote session 删除、provider delete 和 SQLite binding `remote_deleted` 均通过。 +- `node scripts/task513-chatonly-provider-sync-smoke.js deepseek` 通过:DeepSeek `remoteConversationId` 绑定、provider delete 和 SQLite binding `remote_deleted` 均通过。 +- `node scripts/task513-chatonly-provider-sync-smoke.js gemini` 通过:Gemini conversation URL 绑定、provider delete 和 SQLite binding `remote_deleted` 均通过。 +- `cargo test --manifest-path rust/Cargo.toml -p control-plane external_conversation -- --test-threads=1` 通过:binding user scope 与状态迁移。 +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib provider_conversation -- --test-threads=1` 通过:provider conversation 注入与 bound event 持久化。 +- `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib chatonly_doubao_session_delete_calls_provider_and_marks_remote_deleted -- --test-threads=1` 通过:删除 session 后 provider delete 与 `remote_deleted` 状态。 + +## 9. 实施清单 + +- [x] 在 `control-plane` 增加 `ai_external_conversation_bindings` schema、store trait 和 SQLite 实现。 +- [x] 在 `mnote-web` 增加 provider conversation helper,避免继续扩大 `hermes_client.rs`。 +- [x] 在 ACP run 创建时为 ChatOnly / 豆包注入已有 `remoteConversationId`。 +- [x] 在 ACP event 持久化时处理 `provider.conversation.bound`。 +- [x] 在 session delete 路径中加入远端删除 best-effort 状态机。 +- [x] 在 OpenClaw Doubao provider 中加入结构化 conversation bound 事件。 +- [x] 在 OpenClaw Doubao provider 中加入 `deleteConversation`,走 `/im/conversation/batch_del_user_conv`。 +- [x] 补真实浏览器 smoke:`node scripts/task512-chatonly-doubao-sync-smoke.js` 覆盖远端 conversation id 绑定、豆包同会话 marker、session 删除、provider delete 和 SQLite binding `remote_deleted`。 +- [x] 补跨 provider 真实浏览器 smoke:`node scripts/task513-chatonly-provider-sync-smoke.js deepseek` 与 `node scripts/task513-chatonly-provider-sync-smoke.js gemini`。 +- [x] 补 MNote Rust 单测:control-plane binding、mnote-web provider conversation 注入、bound event 持久化和 session delete provider 状态。 +- [x] OpenClaw provider 源码不在本仓库,provider 单测缺口已转入 `bugs/07-ai/process/7-49-chatonly-openclaw-provider-unit-test-gap-v1.md` 跟踪,不阻塞 MNote 侧设计归档。 diff --git a/design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md b/design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md index 90c1318b..f129fc23 100644 --- a/design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md +++ b/design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md @@ -6,7 +6,7 @@ > > 上位依据: > - `/mnt/Data1T/mnote/ARCHITECTURE.md` -> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md` +> - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md` > - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` > - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-6-page-aggregate-alignment-checklist-v1.md` > - `/mnt/Data1T/mnote/design/07-ai/done/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md` @@ -276,10 +276,10 @@ Rust SQLite control-plane 是默认控制面,负责: ### Phase A0:target selection 与 UI -- [ ] Page AI composer 可见 target chip,显示 workspace、target title、resourceKind、scope、readonly / dirty 状态。 -- [ ] 点击 target chip 打开 target picker,可在当前焦点、打开 tabs、树选中项之间选择。 -- [ ] 默认 target 来自 last focused editor / resource tab,不来自第一个 tab、URL documentId 或树选中项。 -- [ ] mindmap / office / raw file target 显示真实 resourceKind,不伪装成 markdown page。 +- [x] Page AI composer 可见 target chip,显示 workspace、target title、resourceKind、scope、readonly / dirty 状态。 +- [x] 点击 target chip 打开 target picker,可在当前焦点、打开 tabs、树选中项之间选择。 +- [x] 默认 target 来自 last focused editor / resource tab,不来自第一个 tab、URL documentId 或树选中项。 +- [x] mindmap / office / raw file target 显示真实 resourceKind,不伪装成 markdown page。 - [ ] 多 tab / 跨 workspace / dirty write 时发送前需要显式确认。 - [ ] 发送后消息记录冻结 target 摘要,切换 tab 不影响已启动 run。 @@ -291,6 +291,8 @@ Rust SQLite control-plane 是默认控制面,负责: - [ ] allowed roots 外文件写入被 agent runtime 或 MNote 审计层拒绝。 - [ ] readonly 页面不会启动可写 run,或只启动只读问答 run。 +2026-06-01 进展:已补第一版 `mnote.agent_target_package.v1` 运行时输入。前端 Page AI run body 会从当前 `editorTarget` / `WorkspacePath` 生成 `targetPackage`;后端会 sanitize 该包,并把 local-first `aiAccessScope.allowedFiles` / `allowedFilePaths` 与 `agentRunEnvelope.allowedFiles` 从该包派生。`task502-page-ai-agent-selector-context-smoke.js` 已覆盖 page / mindmap / OnlyOffice target picker 与 payload 冻结;`task520-page-ai-raw-resource-target-smoke.js` 已覆盖真实 raw local resource tab,并断言 `objectIdentity` 不退化为 `[object Object]`。当前仍未完成跨 workspace 多选确认和真实 agent 写入回收 smoke,因此本文继续保持 `process`。 + ### Phase B:写入回收与前台同步 - [ ] agent 修改当前 `.md` 后,MNote 能回收 changed files / diff。 diff --git a/design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md b/design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md deleted file mode 100644 index 7a02a579..00000000 --- a/design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md +++ /dev/null @@ -1,35 +0,0 @@ -# 7-38 Page AI sidebar runtime owner split v1 - -> 创建时间:2026-05-25 -> 状态:`process` -> 来源:`design/03-rust-web/done/3-22-sidebar-tree-runtime-second-stage-split-v1.md` Batch A。 -> 2026-05-26 更新:`design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` 已把 Page AI 主体迁入 `browser/sidebar-page-ai-runtime.js`;本文件继续作为后续 AI owner 收口 checklist。 - -## 1. 背景 - -`rust/crates/mnote-web/browser/sidebar-tree-runtime.js` 曾包含大量 Page AI panel 代码:会话、消息、profile、skills、gateway health、ACP runtime、permission dialog、plan/status event、session search/resume 等。2026-05-26 的 runtime 可维护性批次已将主体迁入 `browser/sidebar-page-ai-runtime.js`,tree runtime 目前只保留 sidebar click/change/input 委托、少量 `pageUiState.pageAi*` 状态壳和触发器代理。 - -这些代码不是 tree/filetree runtime 的长期 owner。继续把 Page AI 面板放在 `03-rust-web` 的 sidebar runtime 拆分里,会让 tree shell、local folder、AI session 三条边界继续混在一起。 - -## 2. Owner 判断 - -- owner:`07-ai` -- 运行位置:当前仍可挂在 sidebar UI,但 runtime 模块应独立于 tree/filetree runtime。 -- 当前目标模块:`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` -- 主壳职责:只加载 asset、提供当前 document/workspace/root/bootstrap。 - -## 3. 后续执行建议 - -- [x] 只读审计 Page AI panel 的状态入口:`pageUiState.pageAi*`、storage、session 列表、profile/skills、permission dialog。 -- [x] 建立独立 Page AI sidebar owner runtime:`sidebar-page-ai-runtime.js`。 -- [ ] 从 `sidebar-tree-runtime.js` 继续迁出 Page AI click/change/input/keydown 委托,tree runtime 只保留 `data-mnote-action="open-page-ai"` 入口。 -- [ ] 将 `pageUiState.pageAi*` 从通用 sidebar state 中下沉到 Page AI owner runtime,并保留兼容 getter/setter 或明确 bootstrap contract。 -- [ ] 若 `sidebar-page-ai-runtime.js` 继续超过 2,500 行,再按 `session/profile-skill/permission/conversation` 拆成子模块。 -- [ ] 浏览器验证使用页面 AI / ACP smoke,而不是 tree/filetree smoke 替代。 - -## 4. 非目标 - -- 不在 03-rust-web 的 sidebar runtime 二阶段里继续扩大 Page AI 实现。 -- 不在 10-review runtime 可维护性收口里继续重构 ACP/Hermes session 语义;这里只记录 owner 边界。 -- 不改变 Hermes / Reasonix ACP runtime 协议。 -- 不把 local-first agent 文件编辑链路改回粗粒度 `mnote.page.save`。 diff --git a/design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md b/design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md new file mode 100644 index 00000000..11bd77d1 --- /dev/null +++ b/design/07-ai/process/7-43-onlyoffice-plugin-bridge-design-v1.md @@ -0,0 +1,273 @@ +# 7-43 ONLYOFFICE Plugin Bridge Design v1 + +> 状态:process +> +> Owner:07-ai / ONLYOFFICE live bridge / Page AI target runtime +> +> 创建时间:2026-06-01 +> +> 当前口径:工具层 session/scope 安全阻断、真实 iframe 非 dry-run 写入落点验证、Page AI target picker 到真实 Office iframe session 的端到端绑定均已落地;本文继续留在 `process`,用于承接后续 recipe 扩展、Office 主文档加载噪音治理和 P2 plugin bridge 产品化收口,不再作为 P0 安全阻断项。 + +## 背景 + +当前本机 ONLYOFFICE DocumentServer 由 Docker 暴露在宿主机 `8082`: + +- `mnote-onlyoffice-documentserver`: `onlyoffice/documentserver:9.4.0` +- 端口映射:`0.0.0.0:8082 -> container:80` +- MNote 公开入口:`http://127.0.0.1:3000` +- MNote 通过 `/onlyoffice-server` 反代 DocumentServer 静态资源和 editor iframe + +实测当前社区镜像不暴露 `docEditor.createConnector()`,因此不能依赖 ONLYOFFICE Automation API。MNote 的 live Office agent 能力应建立在社区版可用的 Plugin API 上:插件 iframe 使用 `window.Asc.plugin.executeMethod()` 和 `window.Asc.plugin.callCommand()` 调用 Office JavaScript API。 + +## 目标 + +建立一个完整、可扩展、可验证的 MNote ONLYOFFICE bridge 插件,让 Hermes、Reasonix 和页面 AI 能通过白名单 recipe 操作当前打开的 ONLYOFFICE 文档。 + +目标能力: + +- 支持当前浏览器内打开的 Word、Excel、PPT live editor session。 +- 通过 MNote bridge API 派发命令,插件执行后回传 JSON-safe result。 +- 不暴露任意 JavaScript 执行能力。 +- 写操作继续遵守 MNote tool 权限、`dryRun` 和 `idempotencyKey` 模型。 +- 所有新增 recipe 必须同时支持 browser direct smoke 和 tool API smoke。 + +非目标: + +- 不绕过 ONLYOFFICE Developer / Automation API 授权。 +- 不后台批量编辑任意 Office 文件;离线批处理仍优先使用 `officecli`。 +- 不把 ONLYOFFICE iframe DOM 当作编辑接口。 + +## 端口与 URL 边界 + +有两条 base URL,必须严格区分: + +1. 浏览器可达的 MNote origin + - 示例:`http://127.0.0.1:3000` + - 用途:插件 iframe 调用 MNote bridge API。 + - 来源:`location.origin` + - 禁止替换成 `host.docker.internal`,因为浏览器侧可能无法解析。 + +2. DocumentServer 容器可达的 MNote origin + - 示例:`http://host.docker.internal:3000` + - 用途:`document.url`、`callbackUrl`、local file proxy。 + - 来源:`ONLYOFFICE_DOCUMENT_URL_BASE` + - 依赖 compose 中 `extra_hosts: ["host.docker.internal:host-gateway"]`。 + +DocumentServer 静态资源访问: + +- Browser -> MNote -> DocumentServer +- URL 形态:`/onlyoffice-server/web-apps/apps/api/documents/api.js` +- 插件 SDK:`/onlyoffice-server/sdkjs-plugins/v1/plugins.js` + +## 加载流程 + +1. 用户打开 `/onlyoffice?...`。 +2. MNote 页面加载 `/onlyoffice-server/web-apps/apps/api/documents/api.js`。 +3. MNote 构造 `DocsAPI.DocEditor` config。 +4. `document.url` 和 `callbackUrl` 使用 `ONLYOFFICE_DOCUMENT_URL_BASE`,供 DocumentServer 容器访问。 +5. `editorConfig.plugins.pluginsData` 指向: + `/api/onlyoffice/bridge/plugin/config?sessionId=...&apiBase=http://127.0.0.1:3000` +6. ONLYOFFICE 加载 MNote bridge 插件 iframe。 +7. 插件 iframe 调用 `POST /api/onlyoffice/bridge/session` 注册 session。 +8. 插件通过 `GET /api/onlyoffice/bridge/commands/next` 长轮询取命令。 +9. 插件执行白名单 recipe。 +10. 插件调用 `POST /api/onlyoffice/bridge/results` 回传结果。 + +## Bridge API + +当前 API: + +- `GET /api/onlyoffice/bridge/plugin/config` +- `GET /api/onlyoffice/bridge/plugin/index` +- `GET /api/onlyoffice/bridge/plugin/index/config.json` +- `GET /api/onlyoffice/bridge/plugin/index/{state}` +- `POST /api/onlyoffice/bridge/session` +- `GET /api/onlyoffice/bridge/session/current` +- `POST /api/onlyoffice/bridge/session/close` +- `GET /api/onlyoffice/bridge/sessions` +- `GET /api/onlyoffice/bridge/capabilities` +- `POST /api/onlyoffice/bridge/commands` +- `GET /api/onlyoffice/bridge/commands/next` +- `POST /api/onlyoffice/bridge/results` +- `GET /api/onlyoffice/bridge/results` + +## Session 模型 + +每个打开的 ONLYOFFICE 页面生成一个 `sessionId`: + +```text +mnote-oo-{docKey}-{tabRandomSuffix} +``` + +服务端保存: + +- `sessionId` +- `editorType`: `word` / `cell` / `slide` +- `documentId` +- `assetId` +- `fileType` +- `docKey` +- `pageOrigin` +- `lastSeenMillis` +- `pendingCommands` +- `pendingResults` + +多 session 规则: + +- 插件每次 `/commands/next` 都刷新 `lastSeenMillis`。 +- `session.current` 返回最近活跃 session。 +- 严肃写操作应显式传 `onlyofficeSessionId`,避免多标签页误写。 +- 不同 editorType 的 recipe 必须在插件或 wrapper 层做类型保护。 + +2026-06-01 复核:`sessionId` 已加入浏览器 tab 级随机后缀,tool 侧读写均要求显式 `onlyofficeSessionId` / `bridgeSessionId`,并按 `aiAccessScope.allowedResourceIds` 校验 session resource。当前 HTTP / mock plugin 层已有 `task515`、`task516`、`task517` 证据;真实 ONLYOFFICE iframe / DocumentServer 层新增 `task518` 证据,覆盖插件 autostart 注册、同一文档双 tab 不共用 session、A/B 资源 scope mismatch 403、授权 dry-run 200,以及非 dry-run 写入 B 后导出验证 A 不含 marker、B 含 marker。随后 `task523` 补齐 Page AI target picker 到 Office session 的端到端 UI 绑定:真实文档页打开 Office resource tab 后,Page AI run payload 会把 iframe live `onlyofficeSessionId` 冻结进 `editorTarget`、`targetPackage` 和 `targetPackage.targets[0]`,且不再把 Office target 当作 Markdown buffer 查询 `/api/documents/buffer-state`。 + +2026-06-01 续补:已新增 `GET /api/onlyoffice/bridge/session/current`、`POST /api/onlyoffice/bridge/session/close`,session state 已写入 `docKey` / `pageOrigin`,`/onlyoffice` 页面会把当前文档 `docKey` 与页面 origin 透传给 bridge plugin config。已通过 `cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1`、`node scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js`、`MNOTE_UI_BASE_URL=http://127.0.0.1:3302 node scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js`。本文继续保留在 `process`,只跟踪 Office 主文档加载噪音治理和第三批 recipe 逐项实测。 + +## Recipe 分层 + +### 已实现 recipe + +Word / 通用: + +- `selection.get` +- `document.insert_text` +- `document.replace_selection` +- `document.insert_html` +- `document.export` +- `document.search_replace` +- `document.insert_table` +- `document.get_comments` +- `document.add_comment` + +Excel: + +- `sheet.get_sheets` +- `sheet.add_sheet` +- `sheet.rename_sheet` +- `sheet.get_range` +- `sheet.get_range_values` +- `sheet.get_values` +- `sheet.set_value` +- `sheet.set_formula` +- `sheet.batch_set_values` +- `sheet.set_range_values` +- `sheet.format_range` +- `sheet.set_dimensions` +- `sheet.sort_range` +- `sheet.add_chart` + +PPT: + +- `presentation.get_slides` +- `presentation.get_slide_texts` +- `presentation.get_shapes` +- `presentation.add_text_slide` +- `presentation.replace_text` +- `presentation.set_shape_text` +- `presentation.delete_slide` +- `presentation.add_table` +- `presentation.clear_slide` +- `presentation.add_shape` + +### 第二批 recipe 说明 + +Word: + +- `document.search_replace` 走 `Api.GetDocument().SearchAndReplace(...)`,适合精确文本替换。纯搜索暂不单独暴露,全文读取先用 `document.export`。 +- `document.insert_table` 走 `Api.CreateTable(cols, rows)` 并 `doc.Push(table)`,可用二维 `data` 填充单元格;默认插入到文档末尾。 +- `document.get_comments` 走 `doc.GetAllComments()`,返回评论 id、作者、正文和引用文本。 +- `document.add_comment` 支持给当前选区或 `document_start` 添加评论;选区模式依赖 `doc.GetRangeBySelect()`,没有选区时应显式用 `target=document_start`。 + +Excel: + +- `sheet.get_sheets` 走 `Api.GetSheets()` / `worksheet.GetName()`,用于让 agent 明确当前 workbook sheet 结构。 +- `sheet.add_sheet` 走 `Api.AddSheet(name)`,用于创建新 sheet。 +- `sheet.rename_sheet` 走 `worksheet.SetName(name)`,用于重命名指定 `sheetIndex` 的 sheet。 +- `sheet.get_range_values` / `sheet.set_range_values` 接受 A1 地址(例如 `B2:C3`),适合按用户可见坐标读写二维区域。 +- `sheet.set_range_values` 只写入 A1 range 与 `values` 的交集;调用方需要保证二维数据尺寸符合预期。 +- `sheet.format_range` 走 `ApiRange` 格式 API,只暴露小范围字体粗斜体、下划线、填充色、字体色、字号、字体名、对齐、数字格式。 +- `sheet.set_dimensions` 走 `worksheet.SetColumnWidth` / `worksheet.SetRowHeight`,行列索引沿插件内部零基坐标。 +- `sheet.sort_range` 走 `range.SetSort(...)`,只暴露 A1 range、range 内 1 基 `keyColumn`、升降序和是否有表头。 +- `sheet.add_chart` 走 `worksheet.AddChart(...)`,只暴露 A1 数据区、图表类型、基础尺寸和插入位置。 + +PPT: + +- `presentation.get_slide_texts` 读取 slide 文本框纯文本。 +- `presentation.replace_text` 替换文本框纯文本;命中的文本框会按纯文本段落重建,不承诺保留复杂 run 格式。 +- `presentation.get_shapes` 返回每页 shape 的 `slideIndex` / `shapeIndex` / `shapeId` / text 预览,用于精确定位文本框。 +- `presentation.set_shape_text` 按 `slideIndex + shapeIndex` 重写指定 shape 文本;只面向文本 shape,复杂样式不承诺保留。 +- `presentation.delete_slide` 删除指定 `slideIndex` 的幻灯片;调用前应先读 slide 列表确认目标页。 +- `presentation.add_table` 走 `Api.CreateTable(...)` + `slide.AddObject(table)`,支持二维 `data` 和基础位置/尺寸。 +- `presentation.clear_slide` 走 `slide.RemoveAllObjects()`,用于清空指定页对象;这是高影响写操作,调用前必须确认目标页。 +- `presentation.add_shape` 走 `Api.CreateShape(...)` + `slide.AddObject(shape)`,只暴露基础形状、文字、填充色、位置和尺寸。 + +### 第三批 recipe + +- 已实装:Excel 排序、Excel 图表、PPT 表格。 +- 已实装:PPT 清空页对象、PPT 添加基础形状。 +- 待验证后再扩:Word 图片、修订、content controls、表格增删行列和样式。 +- 待验证后再扩:Excel 筛选、工作表删除/移动。 +- 待验证后再扩:PPT 图片、重排 slide、主题/布局、shape 样式与位置。 +- PDF/forms 字段读取与填写。 + +第三批必须逐项实测,不允许凭 API 名称直接暴露给 agent。 + +## 权限与安全 + +插件只负责执行当前 editor session 允许的动作;MNote 负责业务权限: + +- 当前用户是否能打开文档。 +- agent 是否拥有 `office.read` / `office.write`。 +- 写操作是否显式 `dryRun`。 +- 写操作是否带 `idempotencyKey`。 + +安全规则: + +- 不暴露 raw JavaScript。 +- action 必须是白名单。 +- payload 必须 schema 校验。 +- 批量单元格读写默认限制为 5000 cells。 +- result 必须 JSON-safe。 +- command timeout 默认 25 秒。 + +## 验证基线 + +每个 recipe 必须三层验证: + +1. Rust unit test + - manifest 暴露 + - route dispatch + - dryRun / 权限 / queue result + +2. Browser direct smoke + - 直接调用 `window.__MNOTE_ONLYOFFICE_BRIDGE__.run(...)` + - 不经过 Hermes/Reasonix + - 必须保存截图并检查 `pageErrors=[]` + +3. Tool API smoke + - 通过 `/api/hermes/tools/mnote/call` + - 验证 agent 实际可调用 + +完成标准: + +- `cargo test -p mnote-web onlyoffice_ -- --test-threads=1` +- `cargo test -p mnote-web hermes_tools_manifest_returns_first_batch_tools -- --test-threads=1` +- `cargo test -p mnote-web skill_registry_exposes_onlyoffice_live_skill_to_agents -- --test-threads=1` +- `node scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js` 覆盖 bridge plugin index 在 mock `Asc.plugin` 环境中的 session 注册、`docKey/pageOrigin` 元数据、command 消费、result 回传和 token 拒绝。 +- `node scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js` 覆盖真实 ONLYOFFICE iframe / DocumentServer 下插件 autostart、同文档双 tab session salt、bridge command 回收、resource scope 拒写、授权 dry-run,以及授权 B session 非 dry-run 写入后 A/B 导出内容不串台。 +- `node scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js` 覆盖真实文档页内 Office resource tab -> Page AI target picker -> run payload 的 live session 绑定,并断言 Office target 不触发 Markdown buffer-state 404。 +- 关键 browser direct smoke 通过 +- `git diff --check` 通过 +- `codegraph sync .` 已运行 + +2026-06-01 进展:已新增并通过 `task517-onlyoffice-bridge-plugin-direct-smoke.js`,证明 MNote bridge plugin index 与 bridge HTTP loop 可在真实 Chromium 中直接运行。随后新增并通过 `task518-onlyoffice-real-iframe-session-scope-smoke.js`,在真实 ONLYOFFICE iframe / DocumentServer 下打开同一 docx 两个 tab 和另一个 docx,验证三者 sessionId 均不同、同文档双 tab 共享 docKey 但使用不同随机 salt、`selection.get` 可各自回收、scope=A 显式调用 B session 返回 403、scope=B 授权 dry-run 返回 200。`task518` 已继续扩展为非 dry-run 写入 B 并导出 A/B 内容验证不串台,截图保存在 `tmp/task518-onlyoffice-real-iframe-session-scope-smoke/screenshots/office-a-after-write.png` 与 `office-b-after-write.png`。`task523-page-ai-onlyoffice-real-target-session-smoke.js` 已补齐 Page AI target picker 到 `onlyofficeSessionId` 的真实 UI 绑定,截图保存在 `tmp/task523-page-ai-onlyoffice-real-target-session-smoke/screenshots/`。 + +`task518` 已把 Office 主文档加载噪音分类为三类:bridge plugin translation 404、ONLYOFFICE 内置插件噪音、主文档加载失败。smoke 会断言 bridge session 注册和 command loop 正常,并把 `errorCode=-18` 或 editor 未 ready 归为主文档失败,避免把打不开文档误判为插件噪音。 + +补充验证矩阵: + +- `task515-onlyoffice-live-scope-http-smoke.js`:覆盖缺 explicit session、scope mismatch、缺 scope 和授权 dry-run。 +- `task516-onlyoffice-bridge-multisession-browser-smoke.js`:覆盖 A/B bridge session token、`docKey/pageOrigin` 元数据、command queue、result 回收互不串台,以及 `session/current` / `session/close`。 +- `task517-onlyoffice-bridge-plugin-direct-smoke.js`:覆盖 mock `Asc.plugin` 下 plugin index 注册、`docKey/pageOrigin` 透传和 command loop。 +- `task518-onlyoffice-real-iframe-session-scope-smoke.js`:覆盖真实 ONLYOFFICE iframe / DocumentServer 下插件 autostart、同文档双 tab session 隔离、A/B session command 回收、`resource:onlyoffice` scope mismatch 403、授权 scope dry-run、授权非 dry-run 写入 B 后导出验证 A 不含 marker / B 含 marker。 +- `task523-page-ai-onlyoffice-real-target-session-smoke.js`:覆盖真实文档页打开 Office resource tab、等待 iframe bridge ready、通过 Page AI target picker 选择 Office target,并验证 live `onlyofficeSessionId` 写入 run payload。 diff --git a/design/07-ai/process/7-35-reasonix-browser-test-contract-v1.md b/design/07-ai/reference/7-35-reasonix-browser-test-contract-v1.md similarity index 92% rename from design/07-ai/process/7-35-reasonix-browser-test-contract-v1.md rename to design/07-ai/reference/7-35-reasonix-browser-test-contract-v1.md index c9b77631..28e98296 100644 --- a/design/07-ai/process/7-35-reasonix-browser-test-contract-v1.md +++ b/design/07-ai/reference/7-35-reasonix-browser-test-contract-v1.md @@ -2,7 +2,7 @@ ## 状态 -- 状态:process +- 状态:reference - Owner:AI runtime / browser verification - 背景:Reasonix 已能作为独立辅助 agent 执行只读审计,但浏览器验收若只输出自然语言结论,主控仍需重测,无法稳定节省 token。 @@ -144,3 +144,7 @@ Codex/Hermes 只有在以下条件满足时,才能把 Reasonix 浏览器结果 - [ ] 使用 `bugs/0524.md` 中至少 1 个 bug 进行 Reasonix 浏览器试跑。 - [ ] 试跑后记录 accepted findings / false leads / retest required。 - [ ] 根据试跑结果更新本合同或 Reasonix skill。 + +## 2026-06-01 降级说明 + +本合同对应的全局 `reasonix-browser-tester` skill 已存在,并已包含 `result.json`、截图、console/network、isolated context、`modified_files` 等 artifact 要求。本文不再作为 MNote 产品 runtime 的 active process 项,降级为协作参考;后续若要继续试跑 `bugs/0524.md`,应在 Reasonix skill 维护流程或独立复盘文档中跟踪。 diff --git a/design/07-ai/process/7-36-reasonix-skill-maintainer-v1.md b/design/07-ai/reference/7-36-reasonix-skill-maintainer-v1.md similarity index 91% rename from design/07-ai/process/7-36-reasonix-skill-maintainer-v1.md rename to design/07-ai/reference/7-36-reasonix-skill-maintainer-v1.md index 4273579c..97d0ed70 100644 --- a/design/07-ai/process/7-36-reasonix-skill-maintainer-v1.md +++ b/design/07-ai/reference/7-36-reasonix-skill-maintainer-v1.md @@ -2,7 +2,7 @@ ## 状态 -- 状态:process +- 状态:reference - Owner:AI runtime / multi-agent collaboration - 背景:Hindsight 解决了 Reasonix 过程可追溯问题,但不能自动让 Reasonix 下一次更好。需要一个主控驱动的最小自进化机制,由 Codex/Hermes 根据真实 run 修改 Reasonix skill、任务模板和 handoff 合同。 @@ -144,3 +144,7 @@ Reasonix 协同复盘: - [ ] 用 `bugs/0524.md` 至少跑一轮真实 Reasonix 协同测试。 - [ ] 根据真实结果更新 skill 或明确“不需要修改”。 - [ ] 在 Hindsight / MemPalace 中保留协作复盘摘要。 + +## 2026-06-01 降级说明 + +全局 `reasonix-skill-maintainer` skill 已存在,并已要求读取 `result.json`、`process-handoff`、Hindsight recall,评估 `accepted_findings`、`false_leads`、`missing_evidence`、`retest_required` 和 `token_saving_estimate`。本文不再作为 MNote 产品 runtime 的 active process 项,降级为协作参考;后续真实 run 复盘直接走全局 skill。 diff --git a/design/07-ai/process/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md b/design/07-ai/reference/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md similarity index 100% rename from design/07-ai/process/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md rename to design/07-ai/reference/7-37-claudecode-reasonix-worker-evaluation-0524-bug2-v1.md diff --git a/design/09-siyuan-reference/reference/9-siyuan-reference-boundary-and-adoption-v1.md b/design/09-siyuan-reference/reference/9-siyuan-reference-boundary-and-adoption-v1.md index 2f5292d4..7660142d 100644 --- a/design/09-siyuan-reference/reference/9-siyuan-reference-boundary-and-adoption-v1.md +++ b/design/09-siyuan-reference/reference/9-siyuan-reference-boundary-and-adoption-v1.md @@ -2,7 +2,7 @@ > 更新时间:2026-05-11 > -> 当前状态:`reference`。本文只保留思源参考边界与可借鉴能力,不覆盖 `01-05` 当前优先级,也不作为当前执行 checklist。 +> 当前状态:`reference`。本文只保留思源参考边界与可借鉴能力,不覆盖 `CURRENT_ARCHITECTURE.md` / `1-8` 当前口径,也不作为当前执行 checklist。 > > 上位依据: > - `/mnt/Data1T/mnote/ARCHITECTURE.md` diff --git a/design/10-review/done/08-kernel-architecture-next-priority-review-and-checklist.md b/design/10-review/done/08-kernel-architecture-next-priority-review-and-checklist.md index 0fb7040d..d43fe876 100644 --- a/design/10-review/done/08-kernel-architecture-next-priority-review-and-checklist.md +++ b/design/10-review/done/08-kernel-architecture-next-priority-review-and-checklist.md @@ -15,6 +15,8 @@ > - `/mnt/Data1T/mnote/design/old/07-ai/process/7-14-local-first-ai-markdown-editing-convergence-v1.md` > - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md` > - `/mnt/Data1T/mnote/design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md` +> +> 2026-06-01 口径补充:本文是 2026-05-18 的历史 review / checklist 快照。文中把 `mnote.doc.markdown_edit` 描述为简单正文编辑主路径的结论已被后续 local-first agent 文件编辑控制面覆盖;当前 local-first 普通 Markdown 编辑主路径以 `AGENTS.md`、`ARCHITECTURE.md` 与 `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 为准。`mnote.doc.markdown_edit` 只保留为 remote/cloud/compat fallback 或结构校验辅助。 --- diff --git a/design/10-review/done/09-page-ai-fast-block-edit-runtime-review.md b/design/10-review/done/09-page-ai-fast-block-edit-runtime-review.md index d3cecab2..2798a67c 100644 --- a/design/10-review/done/09-page-ai-fast-block-edit-runtime-review.md +++ b/design/10-review/done/09-page-ai-fast-block-edit-runtime-review.md @@ -14,7 +14,9 @@ ## 0. 归档说明 -本文件是 2026-05-16 的页面 AI fast block edit 历史审查快照。其记录的 `local_rule` / `doc_apply_block_ops` 快路径已被后续 `mnote.doc.markdown_edit` 主路径替代,不再作为当前 runtime 口径。 +本文件是 2026-05-16 的页面 AI fast block edit 历史审查快照。其记录的 `local_rule` / `doc_apply_block_ops` 快路径曾被后续 `mnote.doc.markdown_edit` 阶段替代,但该阶段也已被 local-first agent 文件编辑控制面覆盖;本文不再作为当前 runtime 口径。 + +2026-06-01 当前有效口径:local-first 普通 Markdown 编辑默认走授权文件引用 + allowed roots/files + agent 原生 patch/diff + watcher/BufferStore/Page Aggregate 同步;`mnote.doc.markdown_edit` 只保留为 remote/cloud/compat fallback 或结构校验辅助。 当前有效口径见: @@ -23,7 +25,7 @@ - [7-18 AI markdown_edit 阶段状态合同漂移](../../../bugs/07-ai/done/7-18-ai-markdown-edit-phase-state-contract-drift-v1.md) - [7-20 page_ai_workflow 绕过 Hermes tool executor / audit / toggle](../../../bugs/07-ai/done/7-20-page-ai-workflow-bypasses-hermes-tool-executor-v1.md) -归档后的结论:`page-ai/block-edit-workflow` 仍是简单编辑 fast-path 入口,但当前实现应通过模型生成 markdown search/replace / full_content 后调用 `mnote.doc.markdown_edit`,并复用统一 mnote tool executor;`mnote.doc.apply_block_ops` / `mnote.block.*` 只作为结构性块操作辅助。 +归档时的历史结论:`page-ai/block-edit-workflow` 仍是简单编辑 fast-path 入口,但当时实现应通过模型生成 markdown search/replace / full_content 后调用 `mnote.doc.markdown_edit`,并复用统一 mnote tool executor;`mnote.doc.apply_block_ops` / `mnote.block.*` 只作为结构性块操作辅助。该结论不指导当前 local-first 新实现。 ## 1. 本轮结论 diff --git a/design/10-review/done/10-current-mnote-ai-runtime-review-v1.md b/design/10-review/done/10-current-mnote-ai-runtime-review-v1.md index 2998bc74..0a2f9864 100644 --- a/design/10-review/done/10-current-mnote-ai-runtime-review-v1.md +++ b/design/10-review/done/10-current-mnote-ai-runtime-review-v1.md @@ -5,6 +5,8 @@ > 执行状态:`done` > > 范围:当前主线中 Page Aggregate 单一真源、页面 AI 快速编辑、`mnote.doc.markdown_edit` 与 ACP / Hermes runtime 的源码级定向审查。 +> +> 2026-06-01 口径补充:本文是 2026-05-17 的历史 review 快照。文中“`mnote.doc.markdown_edit` 是简单正文编辑主路径”的结论已被后续 local-first agent 文件编辑控制面覆盖;当前 local-first 普通 Markdown 编辑主路径以 `AGENTS.md`、`ARCHITECTURE.md` 与 `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 为准,即授权文件引用 + allowed roots/files + agent 原生 patch/diff + watcher/BufferStore/Page Aggregate 同步。`mnote.doc.markdown_edit` 只保留为 remote/cloud/compat fallback 或结构校验辅助。 ## 1. 本轮结论 diff --git a/design/10-review/done/11-current-full-architecture-review-v1.md b/design/10-review/done/11-current-full-architecture-review-v1.md index 91249643..e25ecd39 100644 --- a/design/10-review/done/11-current-full-architecture-review-v1.md +++ b/design/10-review/done/11-current-full-architecture-review-v1.md @@ -8,6 +8,8 @@ ## 1. 结论 +> 2026-05-31 口径补充:本文是 2026-05-17 的阶段性 review 快照。文中关于 `mnote.doc.markdown_edit` “已是简单正文编辑主路径”的表述已被后续 local-first agent 文件编辑控制面覆盖;当前 local-first 普通 Markdown 编辑主路径以 `AGENTS.md`、`CURRENT_ARCHITECTURE.md`、`ARCHITECTURE.md` 与 `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` 为准,即“授权文件引用 + allowed roots + agent 原生 patch/diff + watcher/BufferStore/Page Aggregate 同步”。`mnote.doc.markdown_edit` 只作为 cloud / remote agent / compat fallback 或复杂结构辅助边界。 + 当前 mnote 的主线架构已经成形。本轮 review 识别出的 P0 / 内核优先缺陷已完成代码修复、文档迁移和定向验证。 已修复的四个关键冲突: diff --git a/design/10-review/process/17-sidex-mnote-workbench-gap-execution-checklist-v1.md b/design/10-review/done/17-sidex-mnote-workbench-gap-execution-checklist-v1.md similarity index 100% rename from design/10-review/process/17-sidex-mnote-workbench-gap-execution-checklist-v1.md rename to design/10-review/done/17-sidex-mnote-workbench-gap-execution-checklist-v1.md diff --git a/design/10-review/done/18-current-design-and-bug-hunt-review-v1.md b/design/10-review/done/18-current-design-and-bug-hunt-review-v1.md new file mode 100644 index 00000000..27643b49 --- /dev/null +++ b/design/10-review/done/18-current-design-and-bug-hunt-review-v1.md @@ -0,0 +1,99 @@ +# 18 当前 design 口径与 bug 寻找 Review v1 + +> 创建时间:2026-05-31 +> +> 状态:`done` +> +> 范围:当前仓库、历史 design 口径、active `process/`、现有 `bugs/process`、近期未提交 OnlyOffice / Page AI / control-plane 改动。 + +## 1. 结论 + +当前上位口径仍一致: + +- `tree-first graph kernel` 是长期对象真相层。 +- local-first workspace 是默认产品形态,本地 `.md` 是页面正文真相。 +- Rust `mnote-web` 是 3000 主执行面。 +- `leptos-tiptap` 是默认 Markdown 前端编辑器。 +- Page Aggregate 是 Rust-first 投影收口方向,但仍需要 compat 瘦身。 +- Page AI 的 local-first 主路径是“授权文件引用 + allowed roots + Hermes/Reasonix 原生 patch/diff + watcher/BufferStore 同步”,不是继续扩 `mnote.doc.markdown_edit` 或 `/api/page-ai/block-edit-workflow`。 + +本轮发现的主要问题不是架构方向动摇,而是 `design/process` 状态与真实完成态、索引入口和 bug 记录之间出现漂移。 + +## 2. 已更新口径 + +- `design/README.md` 的当前入口已从不存在的 `design/01-05-current-priority-overview.md` 改为 `CURRENT_ARCHITECTURE.md` 与 `1-8`。 +- `1-8` 已补充 2026-05-31 口径复核:历史 `01-05` 已迁入 `old/`;已归档的 `3-3` / `3-18` 不再作为 active process 入口。 +- 本 review 作为本轮设计治理和 bug 寻找事实源,后续 worker 不应凭旧路径恢复过时优先级。 + +## 3. design 漂移 + +已确认的漂移: + +- `design/README.md` 与 `1-8` 曾引用已不存在的 `design/01-05-current-priority-overview.md`。 +- `design/03-rust-web/process/3-24-global-content-type-page-width-settings-v1.md` checklist 全部完成并有实施记录;2026-05-31 已迁入 `design/03-rust-web/done/3-24-global-content-type-page-width-settings-v1.md`。 +- `design/05-editor-mainline/done/5-31-page-settings-sqlite-preference-convergence-v1.md` 已迁入 `done/`;剩余风险另按后续 bug / follow-up 跟踪。 +- `design/05-editor-mainline/done/5-32-filetree-lazy-loading-sidex-alignment-v1.md` 已迁入 `done/`;tree live cache 后续入口改看 `3-23` 与相关 bug。 +- `design/05-editor-mainline/process/5-33-navigation-page-route-guard-checklist-v1.md` 顶部落地状态和正文 checklist 状态不一致,需要拆成已完成核心与剩余 follow-up。 +- `design/07-ai/done/7-41-page-ai-hermes-reasonix-user-profile-isolation-v2.md` 文件头状态为 `done`;2026-06-01 已迁入 `done/`。 +- `design/10-review/process/17-sidex-mnote-workbench-gap-execution-checklist-v1.md` 文件头状态为 `done`;2026-05-31 已迁入 `design/10-review/done/17-sidex-mnote-workbench-gap-execution-checklist-v1.md`。 +- `design/10-review/done/11-current-full-architecture-review-v1.md` 中“`mnote.doc.markdown_edit` 已是简单正文编辑主路径”的历史判断已被 `7-18` 和当前 AGENTS/ARCHITECTURE 覆盖;只能作为当时 review 快照,不应指导 local-first 新实现。 + +## 4. 新增 bug 条目 + +本轮已写入: + +- `bugs/10-review/done/10-18-design-process-status-and-stale-entry-v1.md` +- `bugs/07-ai/process/7-45-onlyoffice-live-bridge-session-isolation-v1.md` +- `bugs/07-ai/process/7-46-onlyoffice-live-tool-resource-scope-bypass-v1.md` +- `bugs/05-editor-mainline/process/5-40-onlyoffice-bridge-plugin-noise-regression-v1.md` +- `bugs/07-ai/process/7-47-local-first-ai-markdown-edit-mouth-drift-v1.md` +- `bugs/10-review/done/10-19-agents-md-broken-design-references-v1.md` +- `bugs/03-rust-web/done/3-26-sidebar-dev-hot-reload-setinterval-v1.md` +- `bugs/10-review/done/10-20-testing-reference-missing-new-smokes-v1.md` + +其中 `10-18`、`10-19`、`10-20` 已完成治理收口并迁入 `done/`;OnlyOffice / Page AI / Sidebar 等运行时缺陷仍按各自 bug 条目继续跟踪验收。 + +## 5. 下一步建议 + +P0: + +- [x] 修复 OnlyOffice live bridge session identity 与 resource scope 两个风险,优先补 Rust 单测,随后做 clean browser 多 tab smoke。 +- [x] 继续补 OnlyOffice 真实浏览器集成证据:真实 Office iframe 双 tab 不串台,以及 Page AI target=A 时不能读写 Office resource=B。 +- [x] `AGENTS.md` 断裂引用、Sidebar dev hot reload guard、`5-31` / `5-32` / `7-41` 归档已经收口。 +- [~] `5-33` breadcrumb / fetch guard follow-up 仍保留在 `process/`。 +- [x] 更新 `10-review/done/11` 或追加覆盖说明,防止 worker 继续把 `mnote.doc.markdown_edit` 当 local-first 主写入口。 + +P1: + +- [~] 继续推进 `7-18` Agent Target Resolver:target chip/picker、dirty guard、allowed roots/files 与写后 diff 回收。 +- [x] 推进 `WorkspacePath/ObjectIdentity + BufferStore + Page Aggregate compat 瘦身`,让 FileTree、Open Editors、resource tab 与 AI target resolver 消费同一身份与 buffer 状态。 +- [x] 保留 `3-23` 与 `7-38` 作为 runtime owner follow-up,不重新打开 raw string 大拆分议题。 + +P2: + +- [x] `7-42` mindmap 第二批:结构化 `apply_ops`、resource tab contextRefs、revision conflict。 +- [~] `3-25` MinerU OCR:后端真实 MinerU runtime 已补;任务状态事件、全局任务栏和 UI 入口仍待做。 +- [x] `7-43` OnlyOffice Plugin Bridge:P0/P1 安全主路径与 P2 recipe 矩阵已收口,后续新增 recipe 按矩阵逐项验证。 +- [x] `7-44` ChatOnly Doubao binding:MNote 侧 binding 与 Doubao provider 单测已完成。 +- [ ] `7-49` ChatOnly OpenClaw provider:DeepSeek / Gemini provider 级 delete helper 与单测仍在外部仓库阻塞,不能在 MNote 内归档。 + +本轮已将 `task503`、`task504`、`task512`、`task513`、`task514`、`task515`、`task516` 补入 `scripts/TESTING_REFERENCE.md`;对应 smoke 已实跑,运行结果由 `bugs/10-review/done/10-20-*` 记录。 + +## 6. 验证记录 + +原始 review 是设计/bug 审查和文档更新,未修业务代码,未跑浏览器 smoke。2026-06-01 后续收口已补跑 `task514` 与 `task517`,并登记 `task517` 到 smoke reference;OnlyOffice 真实 iframe / DocumentServer 验收仍未完成。 + +已执行只读检查: + +- `git status --short` +- `find design -maxdepth 3 -type f` +- `find bugs -maxdepth 3 -type f` +- `codegraph status .` +- 多组 `rg` / `sed` / `nl` 证据核对 + +已使用: + +- 2 个只读 subagent:架构口径审查、bug 候选审查。 +- 2 个 Reasonix 只读 worker:design governance audit、bug hunt candidate audit。 + +注意:当前工作区有大量未提交改动,且 CodeGraph 显示新增文件 pending。本轮只对本轮新增/修改的文档负责,不回滚、不移动用户已有改动。 diff --git a/design/README.md b/design/README.md index 251fc7a0..ae13bd75 100644 --- a/design/README.md +++ b/design/README.md @@ -23,12 +23,13 @@ ## 当前优先级入口 -- `01-05` 当前有效主线与优先级,请先看: - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md` -- Runtime 模块级拆分完成态,请看: - `/mnt/Data1T/mnote/design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` +- 当前有效架构口径,请先看: + `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md` - MVP 后阶段剩余 `process/` 的执行顺序,请看: `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md` +- Runtime 模块级拆分完成态,请看: + `/mnt/Data1T/mnote/design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` +- 历史 `01-05-current-priority-overview` 已迁入 `design/old/`,只能作为归档快照,不再作为当前入口。 ## 主线顺序 @@ -82,7 +83,7 @@ - `90-reference/` - 跨域生态参考资料,不参与 `[done]/[process]/[draft]/[reference]/[recycle]` 状态判断 - - 引用时只能作为生态资料或背景材料,不能覆盖 `ARCHITECTURE.md`、`AGENTS.md`、`01-05` 当前优先级或对应主线 `process/` / `done/` 设计稿 + - 引用时只能作为生态资料或背景材料,不能覆盖 `CURRENT_ARCHITECTURE.md`、`ARCHITECTURE.md`、`AGENTS.md`、`1-8` 当前执行顺序或对应主线 `process/` / `done/` 设计稿 - `old/` - 已废弃或被替代的历史稿件,标题统一标记 `[recycle]` - 每个大类继续按 `process/` 与 `done/` 分层 diff --git a/docs/superpowers/plans/2026-05-29-local-folder-mineru-ocr-sidecar.md b/docs/superpowers/plans/2026-05-29-local-folder-mineru-ocr-sidecar.md new file mode 100644 index 00000000..6f71c8ef --- /dev/null +++ b/docs/superpowers/plans/2026-05-29-local-folder-mineru-ocr-sidecar.md @@ -0,0 +1,506 @@ +# Local Folder MinerU OCR Sidecar Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 为 mnote local-folder 图片和图片型 PDF 增加手动 MinerU OCR,并把 OCR Markdown 保存到 owner 页面同目录的 `{pageStem}.ocr/` 文件夹。 + +**Architecture:** 后端负责 MinerU API、权限校验、OCR active job store、OCR sidecar 写入和 `.mnote/ocr-index.json` 状态缓存;前端触发本地 OCR API,并通过资源局部状态和全局 OCR 任务栏展示阶段型进度。OCR 文本默认作为资源 sidecar 被搜索、resource tab 和后续 AI 消费,只有用户显式操作时才插入正文。 + +**Tech Stack:** Rust `mnote-web` routes/services、local-folder metadata、MinerU HTTP API、browser runtime JS、Node smoke、Rust cargo tests。 + +--- + +## File Structure + +- Create: `rust/crates/mnote-web/src/routes/local_ocr.rs` + - OCR API request/response types、路径规划、sidecar frontmatter、active job store、`.mnote/ocr-index.json` 读写、MinerU client facade。 +- Modify: `rust/crates/mnote-web/src/routes/mod.rs` + - 注册 `/api/local-folder/ocr/jobs`、`/jobs/:id`、`/status`、`/read`、`/insert`。 +- Modify: `rust/crates/mnote-web/src/routes/local_folder_source.rs` + - 暴露必要的 local-folder path helper,识别 `.ocr/*.ocr.md` 为 OCR resource 而不是普通页面。 +- Modify: `rust/crates/mnote-web/src/routes/local_search_index.rs` + - 读取 OCR index/sidecar,`includeOcr=true` 时搜索 OCR 文本并返回 owner page。 +- Modify: `rust/crates/mnote-web/src/routes/search.rs` + - local-folder 分支把 `filters.include_ocr` 传给 local search index。 +- Modify: `rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js` + - 附件菜单展示 OCR 识别、查看 OCR、插入 OCR 链接。 +- Modify: `rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js` + - File Tree 图片/PDF 资源右键菜单接入 OCR 操作。 +- Modify: `rust/crates/mnote-web/browser/document-resource-tab-runtime.js` + - image/PDF resource tab 展示 OCR 状态和 OCR Markdown。 +- Create: `rust/crates/mnote-web/browser/local-ocr-task-runtime.js` + - 全局 OCR 任务栏 / 任务抽屉,消费 OCR jobs API 和 `local_ocr.job.updated` 事件。 +- Modify: `rust/crates/mnote-web/src/ssr/pages/layout.rs` + - 挂载全局 OCR task runtime,并断言 runtime 依赖显式注入。 +- Test: `rust/crates/mnote-web/src/routes/local_ocr.rs` inline tests +- Test: `rust/crates/mnote-web/src/routes/local_search_index.rs` inline tests +- Create: `scripts/task506-local-folder-mineru-ocr-smoke.js` + - 浏览器 smoke,使用 mock MinerU 或 test-only route fixture。 + +## Task 1: OCR Sidecar Path And Metadata Contract + +**Files:** +- Create: `rust/crates/mnote-web/src/routes/local_ocr.rs` + +- [ ] **Step 1: Add failing unit tests for sidecar path planning** + +Add tests that assert: + +- owner `docs/Page.md` creates OCR dir `docs/Page.ocr/` +- source `docs/Page.assets/photo.png` creates `docs/Page.ocr/photo.png.ocr.md` +- duplicate source leaf names get a short hash suffix +- OCR frontmatter contains `owner_document`, `source_path`, `source_root_relative_path`, `provider`, `model_version`, `source_size`, `source_mtime_ms` + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_sidecar -- --test-threads=1 +``` + +Expected: FAIL because `local_ocr` does not exist yet. + +- [ ] **Step 2: Implement path planning and frontmatter builder** + +Implement focused helpers in `local_ocr.rs`: + +- `plan_ocr_sidecar_path(root, owner_document_path, source_root_relative_path, source_metadata)` +- `build_ocr_markdown(frontmatter, mineru_markdown)` +- `parse_ocr_frontmatter(markdown)` + +Keep these helpers pure and unit-testable. + +- [ ] **Step 3: Verify tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_sidecar -- --test-threads=1 +``` + +Expected: PASS. + +## Task 2: OCR Index Cache + +**Files:** +- Modify: `rust/crates/mnote-web/src/routes/local_ocr.rs` + +- [ ] **Step 1: Add failing tests for `.mnote/ocr-index.json`** + +Cover: + +- write/read one entry +- `stale=true` when source size or mtime changed +- missing source returns `stale=true` with no panic +- failed entry stores only a short sanitized error + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_index -- --test-threads=1 +``` + +Expected: FAIL. + +- [ ] **Step 2: Implement index read/write and stale detection** + +Use atomic JSON write, following existing `write_json_atomic` style in `local_folder_source.rs`. + +Index path: + +```text +/.mnote/ocr-index.json +``` + +Entry key: + +```text +sourceRootRelativePath +``` + +- [ ] **Step 3: Verify tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_index -- --test-threads=1 +``` + +Expected: PASS. + +## Task 3: MinerU Client And OCR Job API + +**Files:** +- Modify: `rust/crates/mnote-web/src/routes/local_ocr.rs` +- Modify: `rust/crates/mnote-web/src/routes/mod.rs` + +- [ ] **Step 1: Add route tests with a mock MinerU client** + +Cover: + +- missing token returns `mineru_token_missing` +- root escape source path is rejected +- successful mock OCR writes `{pageStem}.ocr/*.ocr.md` +- successful mock OCR exposes queued/running/done states through jobs list +- each mock OCR state change emits `local_ocr.job.updated` +- failed mock OCR writes failed index entry without token or upload URL + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_jobs -- --test-threads=1 +``` + +Expected: FAIL. + +- [ ] **Step 2: Implement API routes** + +Routes: + +- `POST /api/local-folder/ocr/jobs` +- `GET /api/local-folder/ocr/jobs` +- `GET /api/local-folder/ocr/jobs/{jobId}` +- `GET /api/local-folder/ocr/status` +- `GET /api/local-folder/ocr/read` + +Token lookup order: + +1. `MNOTE_MINERU_API_TOKEN` +2. `MINERU_API_TOKEN` +3. `~/.hermes/.env` `MINERU_API_TOKEN` for local development + +- [ ] **Step 3: Implement MinerU local file flow** + +Use MinerU API: + +- `POST /api/v4/file-urls/batch` +- `PUT` local bytes to pre-signed URL +- `GET /api/v4/extract-results/batch/{batch_id}` +- download zip +- extract first Markdown file + +Never log token or pre-signed URL. + +- [ ] **Step 4: Implement active job store and status stages** + +Add in-process active job state with these statuses: + +```text +queued +uploading +mineru_processing +downloading +writing_sidecar +done +failed +interrupted +stale +``` + +Each state change must update `.mnote/ocr-index.json` and return a redacted job payload. On process restart, any persisted `queued/uploading/mineru_processing/downloading/writing_sidecar` entry without active in-memory job is exposed as `interrupted`. + +- [ ] **Step 5: Broadcast OCR job events** + +Emit a local realtime event for every state change: + +```json +{ + "type": "local_ocr.job.updated", + "jobId": "ocr_1760000000000_abcd", + "rootUri": "file:///tmp/mnote-ocr", + "ownerDocumentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/spec.pdf", + "ocrRootRelativePath": "docs/Page.ocr/spec.pdf.ocr.md", + "status": "mineru_processing", + "stageLabel": "识别中", + "updatedAtMs": 1760000000000 +} +``` + +Use the existing realtime / WS / SSE event path. Do not add a foreground `setInterval` polling loop as the primary update mechanism. + +- [ ] **Step 6: Register routes** + +Add route registrations in `routes/mod.rs`. + +- [ ] **Step 7: Verify route tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_jobs -- --test-threads=1 +``` + +Expected: PASS. + +## Task 4: Keep OCR Markdown Out Of Page Tree + +**Files:** +- Modify: `rust/crates/mnote-web/src/routes/local_folder_source.rs` +- Modify: `rust/crates/mnote-web/src/routes/local_search_index.rs` + +- [ ] **Step 1: Add failing tests for `.ocr/*.ocr.md` classification** + +Cover: + +- `docs/Page.ocr/photo.png.ocr.md` is not a normal local Markdown document +- File Tree can still expose it as resource +- Page Tree projection excludes it + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_resource_classification -- --test-threads=1 +``` + +Expected: FAIL. + +- [ ] **Step 2: Implement OCR sidecar detection** + +Add a helper such as: + +```rust +fn is_local_ocr_sidecar_path(path: &Path) -> bool +``` + +Rules: + +- parent directory name ends with `.ocr` +- file name ends with `.ocr.md` +- file has `mnote_ocr_version` frontmatter when content is available + +Use path-only detection for tree projection and frontmatter-backed detection for search/index. + +- [ ] **Step 3: Verify classification tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_resource_classification -- --test-threads=1 +``` + +Expected: PASS. + +## Task 5: Search OCR Text + +**Files:** +- Modify: `rust/crates/mnote-web/src/routes/local_search_index.rs` +- Modify: `rust/crates/mnote-web/src/routes/search.rs` + +- [ ] **Step 1: Add failing local search tests** + +Cover: + +- `includeOcr=false` does not match OCR sidecar text +- `includeOcr=true` matches OCR sidecar text +- result `documentId` is owner page id +- result has `hasOcr=true` +- evidence contains source and sidecar paths + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1 +``` + +Expected: FAIL. + +- [ ] **Step 2: Pass includeOcr into local search** + +Update `search.rs` local-folder branch to pass `filters.include_ocr.unwrap_or(false)`. + +- [ ] **Step 3: Extend local search index** + +Add OCR sidecar collection separate from normal documents. Search OCR text only when `include_ocr=true`, then project owner page result. + +- [ ] **Step 4: Verify search tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1 +``` + +Expected: PASS. + +## Task 6: Browser Runtime OCR Actions + +**Files:** +- Modify: `rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js` +- Modify: `rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js` +- Modify: `rust/crates/mnote-web/browser/document-resource-tab-runtime.js` +- Create: `rust/crates/mnote-web/browser/local-ocr-task-runtime.js` +- Modify: `rust/crates/mnote-web/src/ssr/pages/layout.rs` + +- [ ] **Step 1: Add JS syntax and SSR wiring tests** + +Add or extend tests that assert OCR runtime dependencies are mounted and no `ReferenceError`-prone implicit globals are used. + +Run: + +```bash +node --check rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js +node --check rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js +node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js +node --check rust/crates/mnote-web/browser/local-ocr-task-runtime.js +cargo test --manifest-path rust/Cargo.toml -p mnote-web ocr_runtime -- --test-threads=1 +``` + +Expected before implementation: Rust OCR runtime assertions fail. + +- [ ] **Step 2: Add OCR actions** + +Add actions: + +- `OCR 识别` +- `查看 OCR` +- `插入 OCR 链接` +- `重新识别` + +Only show OCR actions for image and PDF resources. + +- [ ] **Step 3: Add OCR status fetch/render** + +Use `/api/local-folder/ocr/status` and `/read`. Show states: + +- 未识别 +- 排队中 +- 上传中 +- 识别中 +- 写入中 +- 已识别 +- 来源已变化 +- 识别失败 +- 已中断 + +- [ ] **Step 4: Add global OCR task bar and drawer** + +Create a global OCR task entry in the shell: + +- collapsed label: `OCR 2` or `1 个 OCR 任务进行中` +- drawer rows: file name, owner page, stage label, start time, completion/failure state +- row actions: `打开 OCR`, `重试` +- state source: initial `GET /api/local-folder/ocr/jobs?rootUri=...` plus `local_ocr.job.updated` events + +The runtime must update from events and explicit command results. It must not rely on `setInterval` polling as the main update path. + +- [ ] **Step 5: Verify JS and Rust wiring** + +Run the commands from Step 1. + +Expected: PASS. + +## Task 7: Insert OCR Link Into Markdown + +**Files:** +- Modify: `rust/crates/mnote-web/src/routes/local_ocr.rs` +- Modify: browser runtime files from Task 6 + +- [ ] **Step 1: Add route tests for insert** + +Cover: + +- inserting link appends `[OCR:photo.png](./Page.ocr/photo.png.ocr.md)` +- insert requires explicit OCR sidecar path +- insert respects local resource conflict detection +- `inlineSection` inserts heading, source comment and OCR body + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_insert -- --test-threads=1 +``` + +Expected: FAIL. + +- [ ] **Step 2: Implement `POST /api/local-folder/ocr/insert`** + +Use existing local resource write patterns and keep 正文 mutation explicit. + +- [ ] **Step 3: Wire UI insert actions** + +After successful insert, refresh current document through existing save/refresh event path, not polling. + +- [ ] **Step 4: Verify insert tests pass** + +Run: + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr_insert -- --test-threads=1 +``` + +Expected: PASS. + +## Task 8: Browser Smoke + +**Files:** +- Create: `scripts/task506-local-folder-mineru-ocr-smoke.js` +- Modify: `scripts/TESTING_REFERENCE.md` + +- [ ] **Step 1: Write smoke script** + +The smoke should: + +- create a temp local-folder workspace +- create `Page.md` +- place one PNG fixture and one PDF fixture next to it +- use mock MinerU mode or a test-only fixture response +- trigger OCR from UI +- assert `Page.ocr/*.ocr.md` exists +- assert the global OCR task bar shows running state after submission +- assert the global OCR task drawer moves to done after the mocked OCR event +- assert OCR resource tab opens +- assert search with `includeOcr=true` returns owner page +- assert insert link mutates `Page.md` only after explicit click + +- [ ] **Step 2: Run smoke** + +Run: + +```bash +MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3000 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task506-local-folder-mineru-ocr-smoke.js +``` + +Expected: `ok=true` and no browser `pageErrors`. + +- [ ] **Step 3: Update testing reference** + +Add the smoke to `scripts/TESTING_REFERENCE.md` under local-folder resource/browser smoke. + +## Task 9: Final Verification + +- [ ] **Step 1: Run focused Rust tests** + +```bash +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1 +cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1 +``` + +- [ ] **Step 2: Run browser runtime checks** + +```bash +node --check rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js +node --check rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js +node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js +node --check rust/crates/mnote-web/browser/local-ocr-task-runtime.js +``` + +- [ ] **Step 3: Run smoke** + +```bash +MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3000 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task506-local-folder-mineru-ocr-smoke.js +``` + +- [ ] **Step 4: Check diff hygiene** + +```bash +git diff --check -- rust/crates/mnote-web/src/routes/local_ocr.rs rust/crates/mnote-web/src/routes/mod.rs rust/crates/mnote-web/src/routes/local_folder_source.rs rust/crates/mnote-web/src/routes/local_search_index.rs rust/crates/mnote-web/src/routes/search.rs rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js rust/crates/mnote-web/browser/document-resource-tab-runtime.js rust/crates/mnote-web/browser/local-ocr-task-runtime.js scripts/task506-local-folder-mineru-ocr-smoke.js scripts/TESTING_REFERENCE.md +``` + +- [ ] **Step 5: Sync CodeGraph before commit** + +```bash +codegraph sync . +codegraph status . +``` + +Expected: no pending CodeGraph changes. diff --git a/docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md b/docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md new file mode 100644 index 00000000..50113a33 --- /dev/null +++ b/docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md @@ -0,0 +1,394 @@ +# Page AI Mindmap Skill Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add the `mnote-mindmap` built-in Page AI skill and a first working `mnote.mindmap.create_from_outline` tool that generates MNote-compatible `.mindmap.json` envelopes from outlines. + +**Architecture:** Keep Page AI skill discovery in `hermes_tools::skill`, keep tool manifest shape in `hermes_tools::manifest`, and keep resource file behavior in `hermes_tools::resource`. The first implementation uses local-folder resource files and does not introduce PDF OCR; PDF is represented by outline fixtures that later PDF/Office tools can feed into `create_from_outline`. + +**Tech Stack:** Rust `mnote-web`, Axum route tests, serde_json, local-folder access guards, existing Hermes tool call pipeline. + +--- + +## Files + +- Create: `skills/mnote-mindmap/SKILL.md` +- Modify: `rust/crates/mnote-web/src/hermes_tools/skill.rs` +- Modify: `rust/crates/mnote-web/src/hermes_tools/manifest.rs` +- Modify: `rust/crates/mnote-web/src/hermes_tools/resource.rs` +- Modify: `rust/crates/mnote-web/src/routes/hermes_tools.rs` +- Modify: `rust/crates/mnote-web/src/routes/hermes_client.rs` +- Modify: `scripts/task502-page-ai-agent-selector-context-smoke.js` +- Test: `cargo test -p mnote-web --lib hermes_tools_mindmap --manifest-path rust/Cargo.toml` +- Test: `cargo test -p mnote-web --lib skill_registry --manifest-path rust/Cargo.toml` +- Test: `cargo test -p mnote-web --lib skill_read_returns_mindmap_skill_content --manifest-path rust/Cargo.toml` +- Test: `cargo test -p mnote-web --lib page_ai_skill_toggle_respects_builtin_user_policy_and_shared_readonly --manifest-path rust/Cargo.toml` +- Test: `node --check scripts/task502-page-ai-agent-selector-context-smoke.js` +- Smoke: `node scripts/task502-page-ai-agent-selector-context-smoke.js` +- Check: `git diff --check -- skills/mnote-mindmap/SKILL.md rust/crates/mnote-web/src/hermes_tools/skill.rs rust/crates/mnote-web/src/hermes_tools/manifest.rs rust/crates/mnote-web/src/hermes_tools/resource.rs rust/crates/mnote-web/src/routes/hermes_tools.rs rust/crates/mnote-web/src/routes/hermes_client.rs scripts/task502-page-ai-agent-selector-context-smoke.js docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md design/07-ai/process/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md` + +## Task 1: Built-in Skill Registration + +**Files:** +- Create: `skills/mnote-mindmap/SKILL.md` +- Modify: `rust/crates/mnote-web/src/hermes_tools/skill.rs` + +- [x] **Step 1: Write the failing skill registry test** + +Add a test in `rust/crates/mnote-web/src/hermes_tools/skill.rs`: + +```rust +#[test] +fn skill_registry_exposes_mindmap_skill_to_agents() { + let reasonix_skills = skill_summaries_for_agent(Some("reasonix")); + let skill = reasonix_skills + .iter() + .find(|skill| skill["id"] == "mnote-mindmap") + .expect("reasonix should see mindmap skill"); + assert_eq!(skill["readOnly"], false); + assert!( + skill["requiresContextRefs"] + .as_array() + .expect("context refs") + .iter() + .any(|value| value == "resource") + ); + assert!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.mindmap.create_from_outline") + ); +} +``` + +- [x] **Step 2: Run the targeted failing test** + +Run: + +```bash +cargo test -p mnote-web --lib skill_registry_exposes_mindmap_skill_to_agents --manifest-path rust/Cargo.toml +``` + +Expected: FAIL because `mnote-mindmap` is not registered. + +- [x] **Step 3: Add the skill file** + +Create `skills/mnote-mindmap/SKILL.md` with the tool decision rules from `design/07-ai/process/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md`. + +- [x] **Step 4: Register the skill** + +Add a `MnoteSkill` entry in `rust/crates/mnote-web/src/hermes_tools/skill.rs`: + +```rust +MnoteSkill { + id: "mnote-mindmap", + title: "MNote mindmap editing", + description: "Read, update, summarize, or create MNote mindmap resources, including generating a new mindmap from PDF or document outlines.", + agent_ids: &["hermes", "reasonix"], + read_only: false, + requires_context_refs: &["current_page", "file", "folder", "resource"], + tool_names: &[ + "mnote.context.snapshot", + "mnote.context.resolve_target", + "mnote.mindmap.fetch", + "mnote.mindmap.apply_ops", + "mnote.mindmap.create_from_outline", + ], + content: include_str!("../../../../../skills/mnote-mindmap/SKILL.md"), +}, +``` + +- [x] **Step 5: Re-run the skill tests** + +Run: + +```bash +cargo test -p mnote-web --lib skill_registry --manifest-path rust/Cargo.toml +``` + +Expected: PASS for the skill registry tests. + +## Task 2: Tool Manifest Contract + +**Files:** +- Modify: `rust/crates/mnote-web/src/hermes_tools/manifest.rs` +- Modify: `rust/crates/mnote-web/src/routes/hermes_tools.rs` + +- [x] **Step 1: Write the failing manifest test** + +Extend `hermes_tools_manifest_returns_first_batch_tools` or add a dedicated test that asserts: + +```rust +let create_tool = tools + .iter() + .find(|tool| tool["name"] == "mnote.mindmap.create_from_outline") + .expect("create_from_outline tool"); +assert_eq!( + create_tool["inputSchema"]["properties"]["outline"]["type"], + "array" +); +assert!( + create_tool["capabilityScope"] + .as_array() + .expect("scope") + .iter() + .any(|scope| scope == "mindmap.write") +); +``` + +- [x] **Step 2: Run the failing manifest test** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_manifest_returns_first_batch_tools --manifest-path rust/Cargo.toml +``` + +Expected: FAIL because the manifest does not expose `mnote.mindmap.create_from_outline`. + +- [x] **Step 3: Add `mindmap_create_from_outline_tool()`** + +Add a write tool with required fields `documentId`, `mindmapId`, `outline`, `sessionId`, `runId`, `toolCallId`, `traceId`, and `actorId`. Include optional `title`, `rootUri`, `resourcePath`, `sourceRefs`, `embedIntoPage`, and `aiAccessScope`. + +- [x] **Step 4: Add routing for the new tool** + +In `execute_mnote_tool_call`, route: + +```rust +"mnote.mindmap.create_from_outline" => resource::mindmap_create_from_outline(&context, &input).await, +``` + +- [x] **Step 5: Re-run the manifest test** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_manifest_returns_first_batch_tools --manifest-path rust/Cargo.toml +``` + +Expected: PASS for manifest exposure. + +## Task 3: Mindmap Envelope Generation + +**Files:** +- Modify: `rust/crates/mnote-web/src/hermes_tools/resource.rs` +- Modify: `rust/crates/mnote-web/src/routes/hermes_tools.rs` + +- [x] **Step 1: Write the failing create-from-outline route test** + +Add an Axum test in `rust/crates/mnote-web/src/routes/hermes_tools.rs` that calls `mnote.mindmap.create_from_outline` with: + +```json +{ + "mindmapId": "maps/generated.mindmap.json", + "resourcePath": "maps/generated.mindmap.json", + "title": "PDF 摘要导图", + "outline": [ + { + "text": "章节一", + "children": [ + { "text": "要点 1", "children": [] } + ] + } + ], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/generated.mindmap.json"] + } +} +``` + +Assert the response and written file: + +```rust +assert_eq!(payload["result"]["resourceKind"], "mindmap"); +assert_eq!(payload["result"]["root"]["data"]["text"], "PDF 摘要导图"); +assert_eq!(payload["result"]["root"]["children"][0]["data"]["text"], "章节一"); +assert_eq!(payload["result"]["envelope"]["data"]["data"]["uid"], "root"); +assert!(root.join("maps").join("generated.mindmap.json").exists()); +``` + +- [x] **Step 2: Run the failing create test** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_mindmap_create_from_outline_writes_default_envelope --manifest-path rust/Cargo.toml +``` + +Expected: FAIL because the tool does not exist. + +- [x] **Step 3: Implement outline conversion helpers** + +Implement helpers in `resource.rs`: + +- `default_mindmap_view() -> Value` +- `mindmap_envelope_from_outline(title: &str, outline: &Value) -> Result` +- `mindmap_outline_items_to_children(outline: &[Value], path: &str) -> Vec` + +Generated child node shape: + +```json +{ + "data": { + "expand": true, + "isActive": false, + "text": "节点文本", + "uid": "node_1_1" + }, + "children": [] +} +``` + +- [x] **Step 4: Implement `mindmap_create_from_outline`** + +Use existing write guard and path guard: + +- call `ensure_resource_write_contract` +- build `ResourceToolTarget` +- call `ensure_resource_scope_allowed` +- resolve write path under authorized root +- create parent directory +- write pretty JSON +- return envelope, root, markdown summary, revision, and changed file path + +- [x] **Step 5: Re-run the create test** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_mindmap_create_from_outline_writes_default_envelope --manifest-path rust/Cargo.toml +``` + +Expected: PASS. + +## Task 4: Fetch Envelope Awareness + +**Files:** +- Modify: `rust/crates/mnote-web/src/hermes_tools/resource.rs` +- Modify: `rust/crates/mnote-web/src/routes/hermes_tools.rs` + +- [x] **Step 1: Write a failing fetch test for the default envelope** + +Add a test that writes a file shaped as: + +```json +{ + "data": { + "children": [], + "data": { + "expand": true, + "isActive": false, + "text": "KMIND", + "uid": "root" + } + }, + "view": { + "state": { "scale": 1, "sx": 0, "sy": 0, "x": 0, "y": 0 }, + "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "e": 0, "f": 0 } + } +} +``` + +Then call `mnote.mindmap.fetch` with `scope=full_envelope` and assert: + +```rust +assert_eq!(payload["result"]["root"]["data"]["text"], "KMIND"); +assert_eq!(payload["result"]["envelope"]["data"]["data"]["uid"], "root"); +``` + +- [x] **Step 2: Run the failing fetch test** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_mindmap_fetch_reads_default_envelope --manifest-path rust/Cargo.toml +``` + +Expected: FAIL if fetch only understands naked simple-mind-map trees. + +- [x] **Step 3: Normalize envelope root** + +Update `collect_mindmap_nodes` and response building to use: + +```rust +fn mindmap_root_value(value: &Value) -> &Value { + value.get("data") + .filter(|data| data.get("data").is_some() || data.get("children").is_some()) + .unwrap_or(value) +} +``` + +Return `envelope` only when `scope == "full_envelope"`. + +- [x] **Step 4: Re-run fetch tests** + +Run: + +```bash +cargo test -p mnote-web --lib hermes_tools_mindmap_fetch --manifest-path rust/Cargo.toml +``` + +Expected: PASS for existing and envelope fetch tests. + +## Task 5: Final Verification + +**Files:** +- All touched files from prior tasks. + +- [x] **Step 1: Run non-mutating Rust format audit** + +Run: + +```bash +cargo fmt --manifest-path rust/Cargo.toml --all --check +``` + +Actual: command reports existing workspace-wide rustfmt drift, including unrelated dirty files and pre-existing touched-file formatting. Do not run mutating `cargo fmt` in this dirty worktree without an explicit cleanup decision. + +- [x] **Step 2: Run targeted Rust tests** + +Run: + +```bash +cargo test -p mnote-web --lib skill_registry --manifest-path rust/Cargo.toml +cargo test -p mnote-web --lib skill_read_returns_mindmap_skill_content --manifest-path rust/Cargo.toml +cargo test -p mnote-web --lib hermes_tools_manifest_returns_first_batch_tools --manifest-path rust/Cargo.toml +cargo test -p mnote-web --lib hermes_tools_mindmap --manifest-path rust/Cargo.toml +cargo test -p mnote-web --lib page_ai_skill_toggle_respects_builtin_user_policy_and_shared_readonly --manifest-path rust/Cargo.toml +``` + +Expected: all targeted tests pass. + +- [x] **Step 3: Run JS syntax and browser smoke checks** + +Run: + +```bash +node --check scripts/task502-page-ai-agent-selector-context-smoke.js +node scripts/task502-page-ai-agent-selector-context-smoke.js +``` + +Expected: syntax check passes; smoke captures `skillPreferences.mnote["mnote-mindmap"] = false` in the Page AI run payload. + +- [x] **Step 4: Run diff whitespace check** + +Run: + +```bash +git diff --check -- skills/mnote-mindmap/SKILL.md rust/crates/mnote-web/src/hermes_tools/skill.rs rust/crates/mnote-web/src/hermes_tools/manifest.rs rust/crates/mnote-web/src/hermes_tools/resource.rs rust/crates/mnote-web/src/routes/hermes_tools.rs rust/crates/mnote-web/src/routes/hermes_client.rs scripts/task502-page-ai-agent-selector-context-smoke.js docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md design/07-ai/process/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md +``` + +Expected: no output. + +- [x] **Step 5: Inspect scoped git diff** + +Run: + +```bash +git diff -- skills/mnote-mindmap/SKILL.md rust/crates/mnote-web/src/hermes_tools/skill.rs rust/crates/mnote-web/src/hermes_tools/manifest.rs rust/crates/mnote-web/src/hermes_tools/resource.rs rust/crates/mnote-web/src/routes/hermes_tools.rs rust/crates/mnote-web/src/routes/hermes_client.rs scripts/task502-page-ai-agent-selector-context-smoke.js docs/superpowers/plans/2026-05-30-page-ai-mindmap-skill.md design/07-ai/process/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md +``` + +Expected: diff only contains `mnote-mindmap`, `create_from_outline`, envelope fetch support, tests, and docs. diff --git a/infra/onlyoffice/docker-compose.yml b/infra/onlyoffice/docker-compose.yml index a90e2a62..8c36bb1a 100644 --- a/infra/onlyoffice/docker-compose.yml +++ b/infra/onlyoffice/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: onlyoffice-documentserver: - image: onlyoffice/documentserver:9.3.1 + image: onlyoffice/documentserver:9.4.0 container_name: mnote-onlyoffice-documentserver restart: unless-stopped ports: diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 5c22a1f9..713f020f 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -14,6 +14,23 @@ dependencies = [ "url", ] +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -99,6 +116,15 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "async-lock" version = "3.4.2" @@ -273,12 +299,37 @@ version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "camino" version = "1.2.2" @@ -301,6 +352,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -330,6 +383,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.6.0" @@ -475,6 +538,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "control-plane" version = "0.1.0" @@ -543,6 +612,30 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -565,6 +658,12 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "deflate64" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" + [[package]] name = "deranged" version = "0.5.8" @@ -585,6 +684,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.10.7" @@ -724,6 +834,16 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.1.5" @@ -1277,6 +1397,15 @@ dependencies = [ "libc", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "interpolator" version = "0.5.0" @@ -1335,6 +1464,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.95" @@ -1558,6 +1697,27 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "manyhow" version = "0.11.4" @@ -1599,6 +1759,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.2.0" @@ -1659,6 +1829,7 @@ dependencies = [ "tracing", "tracing-subscriber", "uuid", + "zip", ] [[package]] @@ -1790,6 +1961,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2540,6 +2721,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + [[package]] name = "siphasher" version = "1.0.3" @@ -3707,6 +3894,15 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "yansi" version = "1.0.1" @@ -3782,6 +3978,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zerotrie" @@ -3816,8 +4026,78 @@ dependencies = [ "syn", ] +[[package]] +name = "zip" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "getrandom 0.3.4", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "thiserror 2.0.18", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/rust/crates/bridge-runtime/src/lib.rs b/rust/crates/bridge-runtime/src/lib.rs index eb7e370e..b1d5b7c2 100644 --- a/rust/crates/bridge-runtime/src/lib.rs +++ b/rust/crates/bridge-runtime/src/lib.rs @@ -202,6 +202,10 @@ fn legacy_command_function_name(name: &str) -> BridgeResult<&'static str> { Ok("documents:updateContent") } "mindmaps.put" => Ok("mindmaps:put"), + "tree.resource.archive" => Ok("treeResource:archive"), + "tree.resource.restore" => Ok("treeResource:restore"), + "tree.resource.purge" => Ok("treeResource:purge"), + "tree.resource.rename" => Ok("treeResource:rename"), _ => Err(retired_bridge_error()), } } @@ -6416,6 +6420,25 @@ fn legacy_block_projection_attrs(block: &Value, block_type: &str) -> Value { attrs.insert("language".into(), json!(language)); } } + if block_type == "mindmap" { + for (raw_key, canonical_key) in [ + ("mindmapId", "mindmapId"), + ("mindmap_id", "mindmapId"), + ("sourcePath", "sourcePath"), + ("source_path", "sourcePath"), + ("rootNodeId", "rootNodeId"), + ("root_node_id", "rootNodeId"), + ] { + if let Some(value) = props + .and_then(|map| map.get(raw_key)) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + { + attrs.insert(canonical_key.into(), json!(value)); + } + } + } Value::Object(attrs) } @@ -13086,6 +13109,50 @@ mod tests { ); } + #[test] + fn page_aggregate_block_document_preserves_mindmap_projection_attrs() { + let result = execute_runtime_query(RuntimeInput::Query { + context: demo_context(), + query: RuntimeQueryEnvelopeWire { + name: "page.aggregate.get".into(), + payload: json!({ + "documentId": "doc_mindmap", + "workspaceId": "ws_1", + }), + }, + data: Some(json!({ + "meta": { + "id": "doc_mindmap", + "workspace_id": "ws_1", + "title": "Mindmap Page" + }, + "content": { + "content": [ + { + "id": "local-block-1", + "type": "mindmap", + "props": { + "mindmapId": "mindmap-123456.json", + "sourcePath": "mindmap-123456.json", + "rootNodeId": "root" + }, + "content": [] + } + ], + "revision": 3, + "conflict_detection_key": "doc_mindmap:3" + } + })), + }) + .expect("page aggregate query should build"); + + let block = &result["body"]["blockDocument"]["blocks"][0]; + assert_eq!(block["type"], json!("mindmap")); + assert_eq!(block["attrs"]["mindmapId"], json!("mindmap-123456.json")); + assert_eq!(block["attrs"]["sourcePath"], json!("mindmap-123456.json")); + assert_eq!(block["attrs"]["rootNodeId"], json!("root")); + } + #[test] fn page_aggregate_get_prefers_editor_document_over_legacy_content() { let result = execute_runtime_query(RuntimeInput::Query { diff --git a/rust/crates/control-plane/migrations/007-ai-agent-profile-policy.sql b/rust/crates/control-plane/migrations/007-ai-agent-profile-policy.sql new file mode 100644 index 00000000..ab7a945e --- /dev/null +++ b/rust/crates/control-plane/migrations/007-ai-agent-profile-policy.sql @@ -0,0 +1,43 @@ +-- 007-ai-agent-profile-policy.sql +-- Page AI agent profile policy: SQLite 是 profile 授权与归属真相层。 + +CREATE TABLE IF NOT EXISTS ai_agent_profiles ( + id TEXT PRIMARY KEY, + agent_id TEXT NOT NULL, + profile_kind TEXT NOT NULL, + owner_user_id TEXT NOT NULL DEFAULT '', + base_profile_name TEXT NOT NULL, + isolated_profile_name TEXT NOT NULL, + display_name TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'active', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL, + revision INTEGER NOT NULL DEFAULT 1, + UNIQUE(agent_id, profile_kind, owner_user_id, base_profile_name) +); + +CREATE INDEX IF NOT EXISTS idx_ai_agent_profiles_agent + ON ai_agent_profiles(agent_id, status); + +CREATE INDEX IF NOT EXISTS idx_ai_agent_profiles_owner + ON ai_agent_profiles(owner_user_id, status); + +CREATE TABLE IF NOT EXISTS ai_agent_profile_grants ( + id TEXT PRIMARY KEY, + profile_id TEXT NOT NULL REFERENCES ai_agent_profiles(id) ON DELETE CASCADE, + user_id TEXT NOT NULL DEFAULT '', + role TEXT NOT NULL, + can_run INTEGER NOT NULL DEFAULT 1, + can_manage_skills INTEGER NOT NULL DEFAULT 0, + can_manage_config INTEGER NOT NULL DEFAULT 0, + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL, + revision INTEGER NOT NULL DEFAULT 1, + UNIQUE(profile_id, user_id, role) +); + +CREATE INDEX IF NOT EXISTS idx_ai_agent_profile_grants_profile + ON ai_agent_profile_grants(profile_id); + +CREATE INDEX IF NOT EXISTS idx_ai_agent_profile_grants_user + ON ai_agent_profile_grants(user_id); diff --git a/rust/crates/control-plane/migrations/008-ai-external-conversation-bindings.sql b/rust/crates/control-plane/migrations/008-ai-external-conversation-bindings.sql new file mode 100644 index 00000000..c1f678d1 --- /dev/null +++ b/rust/crates/control-plane/migrations/008-ai-external-conversation-bindings.sql @@ -0,0 +1,28 @@ +CREATE TABLE IF NOT EXISTS ai_external_conversation_bindings ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, + workspace_id TEXT, + mnote_session_id TEXT NOT NULL, + acp_session_id TEXT, + agent_id TEXT NOT NULL, + profile TEXT NOT NULL, + provider TEXT NOT NULL, + remote_conversation_id TEXT NOT NULL, + remote_url TEXT, + status TEXT NOT NULL DEFAULT 'active', + metadata_json TEXT NOT NULL DEFAULT '{}', + created_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_at TEXT NOT NULL DEFAULT (datetime('now')), + deleted_at TEXT, + revision INTEGER NOT NULL DEFAULT 1, + CHECK (status IN ('active', 'local_deleted', 'remote_deleted', 'remote_delete_failed', 'remote_missing')) +); + +CREATE UNIQUE INDEX IF NOT EXISTS idx_ai_external_conv_user_session_provider +ON ai_external_conversation_bindings(user_id, mnote_session_id, provider); + +CREATE UNIQUE INDEX IF NOT EXISTS idx_ai_external_conv_user_provider_remote +ON ai_external_conversation_bindings(user_id, provider, remote_conversation_id); + +CREATE INDEX IF NOT EXISTS idx_ai_external_conv_lookup +ON ai_external_conversation_bindings(user_id, workspace_id, mnote_session_id, provider, status); diff --git a/rust/crates/control-plane/src/migrations.rs b/rust/crates/control-plane/src/migrations.rs index 5ffdcbed..7dbc5a8c 100644 --- a/rust/crates/control-plane/src/migrations.rs +++ b/rust/crates/control-plane/src/migrations.rs @@ -30,6 +30,14 @@ const MIGRATIONS: &[(&str, &str)] = &[ "v6-navigation-recent", include_str!("../migrations/006-navigation-recent.sql"), ), + ( + "v7-ai-agent-profile-policy", + include_str!("../migrations/007-ai-agent-profile-policy.sql"), + ), + ( + "v8-ai-external-conversation-bindings", + include_str!("../migrations/008-ai-external-conversation-bindings.sql"), + ), ]; /// Create the `_migrations` meta-table if it does not exist. @@ -113,6 +121,9 @@ mod tests { "sidebar_shortcuts", "user_ui_preferences", "user_navigation_recent", + "ai_agent_profiles", + "ai_agent_profile_grants", + "ai_external_conversation_bindings", ] { assert!(table_exists(&conn, table), "table {table} should exist"); } diff --git a/rust/crates/control-plane/src/model.rs b/rust/crates/control-plane/src/model.rs index ac705520..e1ad8910 100644 --- a/rust/crates/control-plane/src/model.rs +++ b/rust/crates/control-plane/src/model.rs @@ -243,6 +243,41 @@ pub struct UpsertUserUiPreferenceInput { pub value_json: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AiAgentProfileRecord { + pub id: EntityId, + pub agent_id: String, + pub profile_kind: String, + pub owner_user_id: Option, + pub base_profile_name: String, + pub isolated_profile_name: String, + pub display_name: String, + pub status: String, + pub created_at: Timestamp, + pub updated_at: Timestamp, + pub revision: i64, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AiAgentProfileGrantRecord { + pub id: EntityId, + pub profile_id: EntityId, + pub user_id: Option, + pub role: String, + pub can_run: bool, + pub can_manage_skills: bool, + pub can_manage_config: bool, + pub created_at: Timestamp, + pub updated_at: Timestamp, + pub revision: i64, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AiAgentProfileAccessRecord { + pub profile: AiAgentProfileRecord, + pub grant: AiAgentProfileGrantRecord, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct NavigationRecentRecord { pub id: EntityId, @@ -393,6 +428,42 @@ pub struct AppendAiRuntimeEventInput { pub payload_json: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AiExternalConversationBindingRecord { + pub id: EntityId, + pub user_id: EntityId, + pub workspace_id: Option, + pub mnote_session_id: EntityId, + pub acp_session_id: Option, + pub agent_id: String, + pub profile: String, + pub provider: String, + pub remote_conversation_id: String, + pub remote_url: Option, + pub status: String, + pub metadata_json: String, + pub created_at: Timestamp, + pub updated_at: Timestamp, + pub deleted_at: Option, + pub revision: i64, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct UpsertAiExternalConversationBindingInput { + pub id: Option, + pub user_id: EntityId, + pub workspace_id: Option, + pub mnote_session_id: EntityId, + pub acp_session_id: Option, + pub agent_id: String, + pub profile: String, + pub provider: String, + pub remote_conversation_id: String, + pub remote_url: Option, + pub status: String, + pub metadata_json: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ShareLinkRecord { pub id: EntityId, diff --git a/rust/crates/control-plane/src/sqlite.rs b/rust/crates/control-plane/src/sqlite.rs index 49c99226..b6b896f9 100644 --- a/rust/crates/control-plane/src/sqlite.rs +++ b/rust/crates/control-plane/src/sqlite.rs @@ -1,5 +1,6 @@ //! SQLite-backed control-plane store. +use std::collections::BTreeMap; use std::sync::Mutex; use rusqlite::{params, Connection, OptionalExtension}; @@ -7,15 +8,17 @@ use rusqlite::{params, Connection, OptionalExtension}; use crate::error::ControlPlaneError; use crate::migrations; use crate::model::{ - password_hash_v1, share_token_hash_v1, AiPolicyRecord, AiRuntimeEventRecord, - AiRuntimeRunRecord, AppendAiRuntimeEventInput, AppendAuditInput, AuditLogRecord, - AuthSessionRecord, AuthenticatePasswordInput, CreatePasswordIdentityInput, CreateSessionInput, - CreateShareLinkInput, CreatedShareLink, DirectoryGrantInput, DirectoryGrantLookup, - DirectoryGrantRecord, NavigationRecentRecord, OutboxEventInput, OutboxEventRecord, - ResolvedAccess, ResolvedAuthSession, ShareLinkRecord, SidebarShortcutRecord, SyncStateRecord, - UpsertAiPolicyInput, UpsertAiRuntimeRunInput, UpsertNavigationRecentInput, - UpsertSidebarShortcutInput, UpsertSyncStateInput, UpsertUserInput, UpsertUserUiPreferenceInput, - UserRecord, UserUiPreferenceRecord, WorkspaceRecord, + password_hash_v1, share_token_hash_v1, AiAgentProfileAccessRecord, AiAgentProfileGrantRecord, + AiAgentProfileRecord, AiExternalConversationBindingRecord, AiPolicyRecord, + AiRuntimeEventRecord, AiRuntimeRunRecord, AppendAiRuntimeEventInput, AppendAuditInput, + AuditLogRecord, AuthSessionRecord, AuthenticatePasswordInput, CreatePasswordIdentityInput, + CreateSessionInput, CreateShareLinkInput, CreatedShareLink, DirectoryGrantInput, + DirectoryGrantLookup, DirectoryGrantRecord, NavigationRecentRecord, OutboxEventInput, + OutboxEventRecord, ResolvedAccess, ResolvedAuthSession, ShareLinkRecord, SidebarShortcutRecord, + SyncStateRecord, UpsertAiExternalConversationBindingInput, UpsertAiPolicyInput, + UpsertAiRuntimeRunInput, UpsertNavigationRecentInput, UpsertSidebarShortcutInput, + UpsertSyncStateInput, UpsertUserInput, UpsertUserUiPreferenceInput, UserRecord, + UserUiPreferenceRecord, WorkspaceRecord, }; use crate::store::ControlPlaneStore; @@ -214,6 +217,66 @@ fn option_to_stored_text(value: Option) -> String { .unwrap_or_default() } +fn sanitize_profile_component(value: &str) -> String { + let mut sanitized = value + .trim() + .chars() + .map(|ch| { + if ch.is_ascii_alphanumeric() { + ch.to_ascii_lowercase() + } else { + '-' + } + }) + .collect::(); + while sanitized.contains("--") { + sanitized = sanitized.replace("--", "-"); + } + sanitized = sanitized.trim_matches('-').to_string(); + if sanitized.is_empty() { + "user".to_string() + } else { + sanitized + } +} + +fn row_to_ai_agent_profile(row: &rusqlite::Row<'_>) -> rusqlite::Result { + let owner_user_id: String = row.get(3)?; + Ok(AiAgentProfileRecord { + id: row.get(0)?, + agent_id: row.get(1)?, + profile_kind: row.get(2)?, + owner_user_id: empty_string_to_option(owner_user_id), + base_profile_name: row.get(4)?, + isolated_profile_name: row.get(5)?, + display_name: row.get(6)?, + status: row.get(7)?, + created_at: row.get(8)?, + updated_at: row.get(9)?, + revision: row.get(10)?, + }) +} + +fn row_to_ai_agent_profile_access( + row: &rusqlite::Row<'_>, +) -> rusqlite::Result { + Ok(AiAgentProfileAccessRecord { + profile: row_to_ai_agent_profile(row)?, + grant: AiAgentProfileGrantRecord { + id: row.get(11)?, + profile_id: row.get(12)?, + user_id: empty_string_to_option(row.get(13)?), + role: row.get(14)?, + can_run: row.get::<_, i64>(15)? != 0, + can_manage_skills: row.get::<_, i64>(16)? != 0, + can_manage_config: row.get::<_, i64>(17)? != 0, + created_at: row.get(18)?, + updated_at: row.get(19)?, + revision: row.get(20)?, + }, + }) +} + fn row_to_user_ui_preference(row: &rusqlite::Row<'_>) -> rusqlite::Result { Ok(UserUiPreferenceRecord { id: row.get(0)?, @@ -281,6 +344,19 @@ fn navigation_recent_target_key( } } +fn validate_ai_external_conversation_status(status: &str) -> Result<(), ControlPlaneError> { + match status { + "active" + | "local_deleted" + | "remote_deleted" + | "remote_delete_failed" + | "remote_missing" => Ok(()), + _ => Err(ControlPlaneError::InvalidInput( + "external conversation status 不合法".to_string(), + )), + } +} + fn row_to_ai_policy(row: &rusqlite::Row<'_>) -> rusqlite::Result { Ok(AiPolicyRecord { id: row.get(0)?, @@ -348,6 +424,29 @@ fn row_to_ai_runtime_event(row: &rusqlite::Row<'_>) -> rusqlite::Result, +) -> rusqlite::Result { + Ok(AiExternalConversationBindingRecord { + id: row.get(0)?, + user_id: row.get(1)?, + workspace_id: row.get(2)?, + mnote_session_id: row.get(3)?, + acp_session_id: row.get(4)?, + agent_id: row.get(5)?, + profile: row.get(6)?, + provider: row.get(7)?, + remote_conversation_id: row.get(8)?, + remote_url: row.get(9)?, + status: row.get(10)?, + metadata_json: row.get(11)?, + created_at: row.get(12)?, + updated_at: row.get(13)?, + deleted_at: row.get(14)?, + revision: row.get(15)?, + }) +} + fn derive_ai_runtime_title(payload_json: &str, fallback: &str) -> String { let title = serde_json::from_str::(payload_json) .ok() @@ -391,6 +490,50 @@ fn prune_navigation_recent_for_kind( Ok(()) } +fn list_ai_agent_profile_access_rows( + conn: &Connection, + user_id: &str, +) -> Result, ControlPlaneError> { + let mut stmt = conn.prepare( + "SELECT + p.id, p.agent_id, p.profile_kind, p.owner_user_id, p.base_profile_name, + p.isolated_profile_name, p.display_name, p.status, p.created_at, p.updated_at, + p.revision, + g.id, g.profile_id, g.user_id, g.role, g.can_run, g.can_manage_skills, + g.can_manage_config, g.created_at, g.updated_at, g.revision + FROM ai_agent_profiles p + JOIN ai_agent_profile_grants g ON g.profile_id = p.id + WHERE p.agent_id = 'hermes' + AND p.status = 'active' + AND g.can_run = 1 + AND ( + (p.profile_kind = 'personal' AND p.owner_user_id = ?1 AND g.user_id = ?1) + OR (p.profile_kind = 'shared' AND (g.user_id = '' OR g.user_id = ?1)) + ) + ORDER BY + CASE p.profile_kind WHEN 'personal' THEN 0 ELSE 1 END, + p.display_name ASC, + g.can_manage_skills DESC, + g.can_manage_config DESC", + )?; + let rows = stmt + .query_map(params![user_id], row_to_ai_agent_profile_access)? + .collect::, _>>() + .map_err(ControlPlaneError::from)?; + let mut by_profile = BTreeMap::::new(); + for row in rows { + by_profile + .entry(row.profile.id.clone()) + .and_modify(|existing| { + if row.grant.can_manage_skills && !existing.grant.can_manage_skills { + *existing = row.clone(); + } + }) + .or_insert(row); + } + Ok(by_profile.into_values().collect()) +} + impl ControlPlaneStore for SqliteControlPlaneStore { fn upsert_user(&self, input: UpsertUserInput) -> Result { if input.username.trim().is_empty() { @@ -1461,6 +1604,168 @@ impl ControlPlaneStore for SqliteControlPlaneStore { Ok(rows) } + fn ensure_ai_agent_profile_policy( + &self, + user_id: &str, + is_admin: bool, + ) -> Result, ControlPlaneError> { + let user_id = user_id.trim(); + if user_id.is_empty() { + return Err(ControlPlaneError::InvalidInput( + "ai agent profile user_id 不能为空".to_string(), + )); + } + let conn = self.conn.lock().unwrap(); + let now = now_text(); + conn.execute( + "INSERT INTO ai_agent_profiles ( + id, agent_id, profile_kind, owner_user_id, base_profile_name, + isolated_profile_name, display_name, status, created_at, updated_at, revision + ) + VALUES ('shared_lite', 'hermes', 'shared', '', 'lite', 'lite', 'Lite', 'active', ?1, ?2, 1) + ON CONFLICT(agent_id, profile_kind, owner_user_id, base_profile_name) + DO UPDATE SET status = 'active', updated_at = excluded.updated_at", + params![now, now], + )?; + conn.execute( + "INSERT INTO ai_agent_profile_grants ( + id, profile_id, user_id, role, can_run, can_manage_skills, + can_manage_config, created_at, updated_at, revision + ) + VALUES ('grant_shared_lite_all', 'shared_lite', '', 'user', 1, 0, 0, ?1, ?2, 1) + ON CONFLICT(profile_id, user_id, role) + DO UPDATE SET can_run = 1, can_manage_skills = 0, can_manage_config = 0, + updated_at = excluded.updated_at", + params![now, now], + )?; + + // 旧的泛化 OpenClaw 网页问答入口已拆成明确的三类 chat agent。 + conn.execute( + "UPDATE ai_agent_profiles + SET status = 'retired', updated_at = ?1 + WHERE id = 'shared_openclaw_webqa'", + params![now], + )?; + let shared_chat_profiles = [ + ( + "shared_deepseek_chat", + "deepseek-chat", + "openclaw-deepseek-chat", + "DeepSeek Chat", + ), + ( + "shared_gemini_chat", + "gemini-chat", + "openclaw-gemini-chat", + "Gemini Chat", + ), + ( + "shared_doubao_chat", + "doubao-chat", + "openclaw-doubao-chat", + "豆包 Chat", + ), + ]; + for (profile_id, base_profile, isolated_profile, display_name) in shared_chat_profiles { + conn.execute( + "INSERT INTO ai_agent_profiles ( + id, agent_id, profile_kind, owner_user_id, base_profile_name, + isolated_profile_name, display_name, status, created_at, updated_at, revision + ) + VALUES (?1, 'hermes', 'shared', '', ?2, ?3, ?4, 'active', ?5, ?6, 1) + ON CONFLICT(agent_id, profile_kind, owner_user_id, base_profile_name) + DO UPDATE SET status = 'active', display_name = excluded.display_name, + isolated_profile_name = excluded.isolated_profile_name, updated_at = excluded.updated_at", + params![profile_id, base_profile, isolated_profile, display_name, now, now], + )?; + let grant_id = format!("grant_{profile_id}_all"); + conn.execute( + "INSERT INTO ai_agent_profile_grants ( + id, profile_id, user_id, role, can_run, can_manage_skills, + can_manage_config, created_at, updated_at, revision + ) + VALUES (?1, ?2, '', 'user', 1, 0, 0, ?3, ?4, 1) + ON CONFLICT(profile_id, user_id, role) + DO UPDATE SET can_run = 1, can_manage_skills = 0, can_manage_config = 0, + updated_at = excluded.updated_at", + params![grant_id, profile_id, now, now], + )?; + } + + let user_part = sanitize_profile_component(user_id); + let personal_profile_id = format!("usr_{user_part}_default"); + let personal_profile_name = format!("mnote-u-{user_part}-default"); + conn.execute( + "INSERT INTO ai_agent_profiles ( + id, agent_id, profile_kind, owner_user_id, base_profile_name, + isolated_profile_name, display_name, status, created_at, updated_at, revision + ) + VALUES (?1, 'hermes', 'personal', ?2, 'default', ?3, '我的 Hermes', 'active', ?4, ?5, 1) + ON CONFLICT(agent_id, profile_kind, owner_user_id, base_profile_name) + DO UPDATE SET status = 'active', updated_at = excluded.updated_at", + params![personal_profile_id, user_id, personal_profile_name, now, now], + )?; + let personal_grant_id = format!("grant_{personal_profile_id}_owner"); + conn.execute( + "INSERT INTO ai_agent_profile_grants ( + id, profile_id, user_id, role, can_run, can_manage_skills, + can_manage_config, created_at, updated_at, revision + ) + VALUES (?1, ?2, ?3, 'owner', 1, 1, 1, ?4, ?5, 1) + ON CONFLICT(profile_id, user_id, role) + DO UPDATE SET can_run = 1, can_manage_skills = 1, can_manage_config = 1, + updated_at = excluded.updated_at", + params![personal_grant_id, personal_profile_id, user_id, now, now], + )?; + + if is_admin { + let admin_grant_id = format!("grant_shared_lite_admin_{user_part}"); + conn.execute( + "INSERT INTO ai_agent_profile_grants ( + id, profile_id, user_id, role, can_run, can_manage_skills, + can_manage_config, created_at, updated_at, revision + ) + VALUES (?1, 'shared_lite', ?2, 'admin', 1, 1, 1, ?3, ?4, 1) + ON CONFLICT(profile_id, user_id, role) + DO UPDATE SET can_run = 1, can_manage_skills = 1, can_manage_config = 1, + updated_at = excluded.updated_at", + params![admin_grant_id, user_id, now, now], + )?; + for (profile_id, _, _, _) in shared_chat_profiles { + let admin_chat_grant_id = format!("grant_{profile_id}_admin_{user_part}"); + conn.execute( + "INSERT INTO ai_agent_profile_grants ( + id, profile_id, user_id, role, can_run, can_manage_skills, + can_manage_config, created_at, updated_at, revision + ) + VALUES (?1, ?2, ?3, 'admin', 1, 0, 0, ?4, ?5, 1) + ON CONFLICT(profile_id, user_id, role) + DO UPDATE SET can_run = 1, can_manage_skills = 0, can_manage_config = 0, + updated_at = excluded.updated_at", + params![admin_chat_grant_id, profile_id, user_id, now, now], + )?; + } + } + + list_ai_agent_profile_access_rows(&conn, user_id) + } + + fn resolve_ai_agent_profile( + &self, + user_id: &str, + is_admin: bool, + profile_id: &str, + ) -> Result, ControlPlaneError> { + let profile_id = profile_id.trim(); + if profile_id.is_empty() { + return Ok(None); + } + let access = self.ensure_ai_agent_profile_policy(user_id, is_admin)?; + Ok(access + .into_iter() + .find(|item| item.profile.id == profile_id && item.grant.can_run)) + } + fn upsert_navigation_recent( &self, input: UpsertNavigationRecentInput, @@ -2047,6 +2352,207 @@ impl ControlPlaneStore for SqliteControlPlaneStore { Ok(rows) } + fn upsert_ai_external_conversation_binding( + &self, + input: UpsertAiExternalConversationBindingInput, + ) -> Result { + let user_id = input.user_id.trim(); + let mnote_session_id = input.mnote_session_id.trim(); + let provider = input.provider.trim(); + let remote_conversation_id = input.remote_conversation_id.trim(); + if user_id.is_empty() + || mnote_session_id.is_empty() + || provider.is_empty() + || remote_conversation_id.is_empty() + { + return Err(ControlPlaneError::InvalidInput( + "external conversation binding user_id/session_id/provider/remote_id 不能为空" + .to_string(), + )); + } + serde_json::from_str::(&input.metadata_json)?; + validate_ai_external_conversation_status(&input.status)?; + + let conn = self.conn.lock().unwrap(); + let now = now_text(); + let existing = conn + .query_row( + "SELECT id, user_id, workspace_id, mnote_session_id, acp_session_id, agent_id, profile, provider, remote_conversation_id, remote_url, status, metadata_json, created_at, updated_at, deleted_at, revision + FROM ai_external_conversation_bindings + WHERE user_id = ?1 AND mnote_session_id = ?2 AND provider = ?3 + LIMIT 1", + params![user_id, mnote_session_id, provider], + row_to_ai_external_conversation_binding, + ) + .optional()?; + if let Some(existing) = existing { + let revision = existing.revision + 1; + let deleted_at = if input.status == "active" { + None + } else { + existing.deleted_at.or_else(|| Some(now.clone())) + }; + conn.execute( + "UPDATE ai_external_conversation_bindings + SET workspace_id = ?1, acp_session_id = ?2, agent_id = ?3, profile = ?4, remote_conversation_id = ?5, remote_url = ?6, status = ?7, metadata_json = ?8, updated_at = ?9, deleted_at = ?10, revision = ?11 + WHERE id = ?12", + params![ + input.workspace_id, + input.acp_session_id, + input.agent_id, + input.profile, + remote_conversation_id, + input.remote_url, + input.status, + input.metadata_json, + now, + deleted_at, + revision, + existing.id + ], + )?; + return Ok(AiExternalConversationBindingRecord { + id: existing.id, + user_id: existing.user_id, + workspace_id: input.workspace_id, + mnote_session_id: existing.mnote_session_id, + acp_session_id: input.acp_session_id, + agent_id: input.agent_id, + profile: input.profile, + provider: existing.provider, + remote_conversation_id: remote_conversation_id.to_string(), + remote_url: input.remote_url, + status: input.status, + metadata_json: input.metadata_json, + created_at: existing.created_at, + updated_at: now, + deleted_at, + revision, + }); + } + + let deleted_at = if input.status == "active" { + None + } else { + Some(now.clone()) + }; + let record = AiExternalConversationBindingRecord { + id: input.id.unwrap_or_else(|| new_id("aecb")), + user_id: user_id.to_string(), + workspace_id: input.workspace_id, + mnote_session_id: mnote_session_id.to_string(), + acp_session_id: input.acp_session_id, + agent_id: input.agent_id, + profile: input.profile, + provider: provider.to_string(), + remote_conversation_id: remote_conversation_id.to_string(), + remote_url: input.remote_url, + status: input.status, + metadata_json: input.metadata_json, + created_at: now.clone(), + updated_at: now, + deleted_at, + revision: 1, + }; + conn.execute( + "INSERT INTO ai_external_conversation_bindings (id, user_id, workspace_id, mnote_session_id, acp_session_id, agent_id, profile, provider, remote_conversation_id, remote_url, status, metadata_json, created_at, updated_at, deleted_at, revision) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, 1)", + params![ + record.id, + record.user_id, + record.workspace_id, + record.mnote_session_id, + record.acp_session_id, + record.agent_id, + record.profile, + record.provider, + record.remote_conversation_id, + record.remote_url, + record.status, + record.metadata_json, + record.created_at, + record.updated_at, + record.deleted_at + ], + )?; + Ok(record) + } + + fn find_ai_external_conversation_binding( + &self, + user_id: &str, + workspace_id: Option<&str>, + mnote_session_id: &str, + provider: &str, + ) -> Result, ControlPlaneError> { + let user_id = user_id.trim(); + let mnote_session_id = mnote_session_id.trim(); + let provider = provider.trim(); + if user_id.is_empty() || mnote_session_id.is_empty() || provider.is_empty() { + return Ok(None); + } + let conn = self.conn.lock().unwrap(); + conn.query_row( + "SELECT id, user_id, workspace_id, mnote_session_id, acp_session_id, agent_id, profile, provider, remote_conversation_id, remote_url, status, metadata_json, created_at, updated_at, deleted_at, revision + FROM ai_external_conversation_bindings + WHERE user_id = ?1 + AND (?2 IS NULL OR workspace_id = ?2) + AND mnote_session_id = ?3 + AND provider = ?4 + LIMIT 1", + params![user_id, workspace_id, mnote_session_id, provider], + row_to_ai_external_conversation_binding, + ) + .optional() + .map_err(ControlPlaneError::from) + } + + fn mark_ai_external_conversation_binding_status( + &self, + user_id: &str, + workspace_id: Option<&str>, + mnote_session_id: &str, + provider: &str, + status: &str, + metadata_json: Option<&str>, + ) -> Result { + let user_id = user_id.trim(); + let mnote_session_id = mnote_session_id.trim(); + let provider = provider.trim(); + validate_ai_external_conversation_status(status)?; + let metadata_json = metadata_json.unwrap_or("{}"); + serde_json::from_str::(metadata_json)?; + if user_id.is_empty() || mnote_session_id.is_empty() || provider.is_empty() { + return Ok(0); + } + let conn = self.conn.lock().unwrap(); + let now = now_text(); + let deleted_at = if status == "active" { + None + } else { + Some(now.clone()) + }; + let changed = conn.execute( + "UPDATE ai_external_conversation_bindings + SET status = ?1, metadata_json = ?2, updated_at = ?3, deleted_at = COALESCE(?4, deleted_at), revision = revision + 1 + WHERE user_id = ?5 + AND (?6 IS NULL OR workspace_id = ?6) + AND mnote_session_id = ?7 + AND provider = ?8", + params![ + status, + metadata_json, + now, + deleted_at, + user_id, + workspace_id, + mnote_session_id, + provider + ], + )?; + Ok(changed) + } + fn rename_ai_runtime_session( &self, user_id: &str, @@ -2195,9 +2701,9 @@ mod tests { use super::*; use crate::model::{ password_hash_v1, session_token_hash, AppendAiRuntimeEventInput, AuthenticatePasswordInput, - CreatePasswordIdentityInput, UpsertAiPolicyInput, UpsertAiRuntimeRunInput, - UpsertNavigationRecentInput, UpsertSidebarShortcutInput, UpsertSyncStateInput, - UpsertUserUiPreferenceInput, + CreatePasswordIdentityInput, UpsertAiExternalConversationBindingInput, UpsertAiPolicyInput, + UpsertAiRuntimeRunInput, UpsertNavigationRecentInput, UpsertSidebarShortcutInput, + UpsertSyncStateInput, UpsertUserUiPreferenceInput, }; fn store() -> SqliteControlPlaneStore { @@ -2716,6 +3222,95 @@ mod tests { assert!(bob_sidebar_preferences.is_empty()); } + #[test] + fn ai_agent_profile_policy_provisions_personal_and_shared_boundaries() { + let store = store(); + create_user(&store, "alice"); + create_user(&store, "bob"); + store + .upsert_user(UpsertUserInput { + id: Some("admin".to_string()), + email: Some("admin@example.com".to_string()), + username: "admin".to_string(), + display_name: "admin".to_string(), + role: Some("admin".to_string()), + password_hash: None, + }) + .expect("admin user"); + + let alice_profiles = store + .ensure_ai_agent_profile_policy("alice", false) + .expect("alice profiles"); + assert_eq!(alice_profiles.len(), 5); + let alice_personal = alice_profiles + .iter() + .find(|item| item.profile.profile_kind == "personal") + .expect("alice personal profile"); + assert_eq!( + alice_personal.profile.owner_user_id.as_deref(), + Some("alice") + ); + assert!(alice_personal.grant.can_manage_skills); + let alice_shared = alice_profiles + .iter() + .find(|item| item.profile.id == "shared_lite") + .expect("alice shared profile"); + assert!(alice_shared.grant.can_run); + assert!(!alice_shared.grant.can_manage_skills); + for (profile_id, isolated_profile, display_name) in [ + ( + "shared_deepseek_chat", + "openclaw-deepseek-chat", + "DeepSeek Chat", + ), + ("shared_gemini_chat", "openclaw-gemini-chat", "Gemini Chat"), + ("shared_doubao_chat", "openclaw-doubao-chat", "豆包 Chat"), + ] { + let alice_chat = alice_profiles + .iter() + .find(|item| item.profile.id == profile_id) + .expect("alice shared chat profile"); + assert_eq!(alice_chat.profile.isolated_profile_name, isolated_profile); + assert_eq!(alice_chat.profile.display_name, display_name); + assert!(alice_chat.grant.can_run); + assert!(!alice_chat.grant.can_manage_skills); + assert!(!alice_chat.grant.can_manage_config); + } + + let bob_profiles = store + .ensure_ai_agent_profile_policy("bob", false) + .expect("bob profiles"); + let bob_personal = bob_profiles + .iter() + .find(|item| item.profile.profile_kind == "personal") + .expect("bob personal profile"); + assert_ne!(bob_personal.profile.id, alice_personal.profile.id); + assert!(store + .resolve_ai_agent_profile("bob", false, &alice_personal.profile.id) + .expect("resolve cross user") + .is_none()); + + let admin_shared = store + .resolve_ai_agent_profile("admin", true, "shared_lite") + .expect("admin shared") + .expect("admin can see shared"); + assert!(admin_shared.grant.can_manage_skills); + assert!(admin_shared.grant.can_manage_config); + for profile_id in [ + "shared_deepseek_chat", + "shared_gemini_chat", + "shared_doubao_chat", + ] { + let admin_chat = store + .resolve_ai_agent_profile("admin", true, profile_id) + .expect("admin chat") + .expect("admin can see shared chat profile"); + assert!(admin_chat.grant.can_run); + assert!(!admin_chat.grant.can_manage_skills); + assert!(!admin_chat.grant.can_manage_config); + } + } + #[test] fn navigation_recent_is_user_scoped_upserted_and_limited_by_kind() { let store = store(); @@ -3025,6 +3620,79 @@ mod tests { assert!(runs.is_empty()); } + #[test] + fn ai_external_conversation_binding_is_user_scoped_and_statused() { + let store = store(); + create_user(&store, "doubao_user_a"); + create_user(&store, "doubao_user_b"); + + let binding = store + .upsert_ai_external_conversation_binding(UpsertAiExternalConversationBindingInput { + id: None, + user_id: "doubao_user_a".to_string(), + workspace_id: Some("ws_1".to_string()), + mnote_session_id: "chatonly_session_1".to_string(), + acp_session_id: Some("acp_session_1".to_string()), + agent_id: "chat_only".to_string(), + profile: "openclaw-doubao-chat".to_string(), + provider: "doubao-web".to_string(), + remote_conversation_id: "38428454119180290".to_string(), + remote_url: Some("https://www.doubao.com/chat/38428454119180290".to_string()), + status: "active".to_string(), + metadata_json: "{\"source\":\"provider.conversation.bound\"}".to_string(), + }) + .expect("upsert external conversation binding"); + + assert_eq!(binding.status, "active"); + assert_eq!(binding.remote_conversation_id, "38428454119180290"); + + let found = store + .find_ai_external_conversation_binding( + "doubao_user_a", + Some("ws_1"), + "chatonly_session_1", + "doubao-web", + ) + .expect("find binding") + .expect("binding exists"); + assert_eq!(found.id, binding.id); + assert_eq!(found.acp_session_id.as_deref(), Some("acp_session_1")); + + let other_user = store + .find_ai_external_conversation_binding( + "doubao_user_b", + Some("ws_1"), + "chatonly_session_1", + "doubao-web", + ) + .expect("find other user binding"); + assert!(other_user.is_none()); + + let changed = store + .mark_ai_external_conversation_binding_status( + "doubao_user_a", + Some("ws_1"), + "chatonly_session_1", + "doubao-web", + "local_deleted", + Some("{\"reason\":\"mnote_session_deleted\"}"), + ) + .expect("mark local deleted"); + assert_eq!(changed, 1); + + let deleted = store + .find_ai_external_conversation_binding( + "doubao_user_a", + Some("ws_1"), + "chatonly_session_1", + "doubao-web", + ) + .expect("find deleted binding") + .expect("binding remains auditable"); + assert_eq!(deleted.status, "local_deleted"); + assert!(deleted.deleted_at.is_some()); + } + #[test] fn session_lookup_resolves_active_user_by_token_hash() { let store = store(); diff --git a/rust/crates/control-plane/src/store.rs b/rust/crates/control-plane/src/store.rs index 9ddd8775..19656427 100644 --- a/rust/crates/control-plane/src/store.rs +++ b/rust/crates/control-plane/src/store.rs @@ -2,14 +2,16 @@ use crate::error::ControlPlaneError; use crate::model::{ - AiPolicyRecord, AiRuntimeEventRecord, AiRuntimeRunRecord, AppendAiRuntimeEventInput, - AppendAuditInput, AuditLogRecord, AuthSessionRecord, AuthenticatePasswordInput, - CreatePasswordIdentityInput, CreateSessionInput, CreateShareLinkInput, CreatedShareLink, - DirectoryGrantInput, DirectoryGrantLookup, DirectoryGrantRecord, NavigationRecentRecord, - OutboxEventInput, OutboxEventRecord, ResolvedAccess, ResolvedAuthSession, ShareLinkRecord, - SidebarShortcutRecord, SyncStateRecord, UpsertAiPolicyInput, UpsertAiRuntimeRunInput, - UpsertNavigationRecentInput, UpsertSidebarShortcutInput, UpsertSyncStateInput, UpsertUserInput, - UpsertUserUiPreferenceInput, UserRecord, UserUiPreferenceRecord, WorkspaceRecord, + AiAgentProfileAccessRecord, AiExternalConversationBindingRecord, AiPolicyRecord, + AiRuntimeEventRecord, AiRuntimeRunRecord, AppendAiRuntimeEventInput, AppendAuditInput, + AuditLogRecord, AuthSessionRecord, AuthenticatePasswordInput, CreatePasswordIdentityInput, + CreateSessionInput, CreateShareLinkInput, CreatedShareLink, DirectoryGrantInput, + DirectoryGrantLookup, DirectoryGrantRecord, NavigationRecentRecord, OutboxEventInput, + OutboxEventRecord, ResolvedAccess, ResolvedAuthSession, ShareLinkRecord, SidebarShortcutRecord, + SyncStateRecord, UpsertAiExternalConversationBindingInput, UpsertAiPolicyInput, + UpsertAiRuntimeRunInput, UpsertNavigationRecentInput, UpsertSidebarShortcutInput, + UpsertSyncStateInput, UpsertUserInput, UpsertUserUiPreferenceInput, UserRecord, + UserUiPreferenceRecord, WorkspaceRecord, }; pub trait ControlPlaneStore: Send + Sync { @@ -136,6 +138,19 @@ pub trait ControlPlaneStore: Send + Sync { source_kind: Option<&str>, ) -> Result, ControlPlaneError>; + fn ensure_ai_agent_profile_policy( + &self, + user_id: &str, + is_admin: bool, + ) -> Result, ControlPlaneError>; + + fn resolve_ai_agent_profile( + &self, + user_id: &str, + is_admin: bool, + profile_id: &str, + ) -> Result, ControlPlaneError>; + fn upsert_navigation_recent( &self, input: UpsertNavigationRecentInput, @@ -196,6 +211,29 @@ pub trait ControlPlaneStore: Send + Sync { limit: usize, ) -> Result, ControlPlaneError>; + fn upsert_ai_external_conversation_binding( + &self, + input: UpsertAiExternalConversationBindingInput, + ) -> Result; + + fn find_ai_external_conversation_binding( + &self, + user_id: &str, + workspace_id: Option<&str>, + mnote_session_id: &str, + provider: &str, + ) -> Result, ControlPlaneError>; + + fn mark_ai_external_conversation_binding_status( + &self, + user_id: &str, + workspace_id: Option<&str>, + mnote_session_id: &str, + provider: &str, + status: &str, + metadata_json: Option<&str>, + ) -> Result; + fn rename_ai_runtime_session( &self, user_id: &str, diff --git a/rust/crates/core-protocol/src/kernel.rs b/rust/crates/core-protocol/src/kernel.rs index fc3e68f6..3b1487c6 100644 --- a/rust/crates/core-protocol/src/kernel.rs +++ b/rust/crates/core-protocol/src/kernel.rs @@ -264,10 +264,18 @@ impl DocumentBuffer { self.base_content_hash = Some(content_hash); self.current_content_hash = None; self.dirty_state = DocBufferDirtyState::Clean; - if write_intent_id.as_deref().map(str::trim).is_some_and(|value| !value.is_empty()) { + if write_intent_id + .as_deref() + .map(str::trim) + .is_some_and(|value| !value.is_empty()) + { self.last_write_intent_id = write_intent_id; } - if save_operation_id.as_deref().map(str::trim).is_some_and(|value| !value.is_empty()) { + if save_operation_id + .as_deref() + .map(str::trim) + .is_some_and(|value| !value.is_empty()) + { self.last_save_operation_id = save_operation_id; } self.last_saved_at = Some( @@ -922,7 +930,10 @@ mod tests { request.expected_file_version.as_deref(), Some("local-md:local-md:README.md:1:2:hash") ); - assert_eq!(request.write_intent_id.as_deref(), Some("intent:editor:abc")); + assert_eq!( + request.write_intent_id.as_deref(), + Some("intent:editor:abc") + ); assert_eq!(request.save_operation_id.as_deref(), Some("save:op:abc")); assert_eq!(request.content_format, "editorBlocks"); assert_eq!(request.editor_source.as_deref(), Some("tiptap")); diff --git a/rust/crates/mnote-web/Cargo.toml b/rust/crates/mnote-web/Cargo.toml index 61e95e88..e88a8fd5 100644 --- a/rust/crates/mnote-web/Cargo.toml +++ b/rust/crates/mnote-web/Cargo.toml @@ -31,3 +31,4 @@ comrak = { version = "0.52", default-features = false } notify = "8.2.0" time = { version = "0.3", features = ["formatting", "local-offset"] } uuid = { version = "1", features = ["v4"] } +zip = "2" diff --git a/rust/crates/mnote-web/browser/document-resource-tab-runtime.js b/rust/crates/mnote-web/browser/document-resource-tab-runtime.js index 7e9feafa..751360f3 100644 --- a/rust/crates/mnote-web/browser/document-resource-tab-runtime.js +++ b/rust/crates/mnote-web/browser/document-resource-tab-runtime.js @@ -64,6 +64,7 @@ export const createResourceTabRuntime = (dependencies = {}) => { const resourceTabMru = { primary: [], secondary: [] }; const resourceTabMruMax = 20; const resourceTabCloseGuardAttribute = 'data-resource-tab-close-guarded'; + let onlyofficeBridgeReadyListenerBound = false; const normalizePaneRole = (paneRole) => String(paneRole || '').trim() === 'secondary' ? 'secondary' : 'primary'; @@ -127,6 +128,30 @@ export const createResourceTabRuntime = (dependencies = {}) => { } }; + const currentFileTreeWorkspacePath = () => { + try { + const row = document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path]'); + const reader = window.__mnoteFileTreeRuntime?.readWorkspacePathFromRow; + if (row instanceof HTMLElement && typeof reader === 'function') { + const workspacePath = reader(row); + if (workspacePath && typeof workspacePath === 'object') { + return { + ...workspacePath, + sourceKind: String(workspacePath.sourceKind || row.getAttribute('data-source-kind') || '').trim(), + rootUri: String(workspacePath.rootUri || row.getAttribute('data-root-uri') || '').trim(), + }; + } + } + if (row instanceof HTMLElement) { + return { + sourceKind: String(row.getAttribute('data-source-kind') || '').trim(), + rootUri: String(row.getAttribute('data-root-uri') || '').trim(), + }; + } + } catch (_) {} + return null; + }; + const currentWebShellDocumentId = () => { const explicit = typeof currentDocumentId === 'function' ? String(currentDocumentId() || '').trim() : ''; if (explicit) return explicit; @@ -157,17 +182,23 @@ export const createResourceTabRuntime = (dependencies = {}) => { const currentWebShellSourceKind = () => { try { - return currentUrl().searchParams.get('sourceKind') || ''; + return currentUrl().searchParams.get('sourceKind') + || document.body?.dataset?.mnoteSourceKind + || currentFileTreeWorkspacePath()?.sourceKind + || ''; } catch (_) { - return ''; + return document.body?.dataset?.mnoteSourceKind || currentFileTreeWorkspacePath()?.sourceKind || ''; } }; const currentWebShellRootUri = () => { try { - return currentUrl().searchParams.get('rootUri') || ''; + return currentUrl().searchParams.get('rootUri') + || document.body?.dataset?.mnoteRootUri + || currentFileTreeWorkspacePath()?.rootUri + || ''; } catch (_) { - return ''; + return document.body?.dataset?.mnoteRootUri || currentFileTreeWorkspacePath()?.rootUri || ''; } }; @@ -196,7 +227,9 @@ export const createResourceTabRuntime = (dependencies = {}) => { resourceKind: String(fromInput.resourceKind || fromInput.objectKind || resourceKind || '').trim(), }; } - const id = String(objectIdentity || documentId || assetId || relativePath || '').trim(); + const structuredObjectIdentity = objectIdentity && typeof objectIdentity === 'object' ? objectIdentity : null; + const objectIdentityText = structuredObjectIdentity ? '' : String(objectIdentity || '').trim(); + const id = String(objectIdentityText || documentId || assetId || relativePath || '').trim(); if (!id) return null; return { schema: 'mnote.workspace_path.v1', @@ -205,7 +238,7 @@ export const createResourceTabRuntime = (dependencies = {}) => { rootUri: String(rootUri || '').trim(), relativePath: String(relativePath || '').trim(), documentId: String(documentId || '').trim(), - objectIdentity: String(objectIdentity || '').trim(), + objectIdentity: structuredObjectIdentity || objectIdentityText, assetId: String(assetId || '').trim(), resourceKind: String(resourceKind || '').trim(), }; @@ -371,6 +404,18 @@ export const createResourceTabRuntime = (dependencies = {}) => { }); }; + const officeBridgeDebugForEntry = (entry) => { + if (!entry?.panel || !(entry.panel instanceof HTMLElement)) return null; + const frame = entry.panel.querySelector('iframe.mnote-resource-tab-frame'); + if (!(frame instanceof HTMLIFrameElement)) return null; + try { + const debug = frame.contentWindow?.__MNOTE_ONLYOFFICE_DEBUG__; + return debug && typeof debug === 'object' ? debug : null; + } catch (_) { + return null; + } + }; + const openEditorsSnapshotEntry = (entry, key, generatedAt = Date.now()) => { const active = entry?.tab instanceof HTMLElement ? entry.tab.getAttribute('aria-selected') === 'true' @@ -384,6 +429,13 @@ export const createResourceTabRuntime = (dependencies = {}) => { const assetId = String(entry?.assetId || entry?.session?.assetId || '').trim(); const kind = normalizeResourceTabKind(entry); const dirtyState = resourceTabCloseGuardReason(entry?.session); + const officeBridgeDebug = kind === 'office' ? officeBridgeDebugForEntry(entry) : null; + const onlyofficeSessionId = String( + officeBridgeDebug?.bridgeSessionId + || entry?.onlyofficeSessionId + || entry?.bridgeSessionId + || '', + ).trim(); return { objectIdentity, workspacePath: buildWorkspacePath({ @@ -411,6 +463,11 @@ export const createResourceTabRuntime = (dependencies = {}) => { dirtyGuard: dirtyState, assetId, path: relativePath, + onlyofficeSessionId, + bridgeSessionId: onlyofficeSessionId, + bridgeSessionReady: Boolean(onlyofficeSessionId), + bridgeDocumentId: String(officeBridgeDebug?.documentId || '').trim(), + bridgeAssetId: String(officeBridgeDebug?.assetId || '').trim(), lastActiveAt: Number(entry?.session?.lastActiveAt || entry?.lastActiveAt || 0) || (active ? generatedAt : 0), preview: false, pinned: false, @@ -427,6 +484,12 @@ export const createResourceTabRuntime = (dependencies = {}) => { const rootUri = currentWebShellRootUri(); const relativePath = sourceKind === 'local_folder' ? localMarkdownRelativePathFromDocumentId(documentId) : ''; const objectIdentity = `page:${paneRole}`; + const workspaceObjectIdentity = { + objectKind: 'page', + documentId, + blockId: null, + assetId: null, + }; const active = nodes.pageTab instanceof HTMLElement ? nodes.pageTab.getAttribute('aria-selected') === 'true' : false; @@ -443,7 +506,7 @@ export const createResourceTabRuntime = (dependencies = {}) => { rootUri, relativePath, documentId, - objectIdentity, + objectIdentity: workspaceObjectIdentity, assetId: '', resourceKind: 'page', }), @@ -1035,6 +1098,17 @@ export const createResourceTabRuntime = (dependencies = {}) => { markIntendedSlashRoot(entry); }; + const ensureOnlyofficeBridgeReadyListener = () => { + if (onlyofficeBridgeReadyListenerBound) return; + onlyofficeBridgeReadyListenerBound = true; + window.addEventListener('message', (event) => { + if (event.origin !== window.location.origin) return; + const detail = event.data && typeof event.data === 'object' ? event.data : null; + if (!detail || detail.type !== 'mnote:onlyoffice-bridge-ready') return; + syncOpenEditorsSnapshot(); + }); + }; + const openPassiveResourceTab = (entry, input) => { const href = String(input.officeUrl || input.href || '').trim(); if (entry.kind === 'image') { @@ -1051,6 +1125,12 @@ export const createResourceTabRuntime = (dependencies = {}) => { const frame = entry.panel.querySelector('iframe'); if (frame instanceof HTMLIFrameElement) { frame.title = entry.title; + if (entry.kind === 'office') { + ensureOnlyofficeBridgeReadyListener(); + frame.addEventListener('load', () => { + syncOpenEditorsSnapshot(); + }, { once: true }); + } frame.src = href; } installPassiveResourceWatch(entry); diff --git a/rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js b/rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js index 20abd4a5..23fd4dd7 100644 --- a/rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js +++ b/rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js @@ -15,6 +15,18 @@ export const firstNonEmptyText = (...values) => { return ''; }; +export const normalizeMindmapDimension = (value, kind) => { + const raw = typeof value === 'number' + ? value + : typeof value === 'string' + ? Number(value.trim().replace(/px$/i, '')) + : NaN; + if (!Number.isFinite(raw)) return null; + const rounded = Math.round(raw); + const min = kind === 'height' ? 240 : 900; + return rounded >= min ? rounded : null; +}; + // 过渡适配(TODO step-4):legacy→Tiptap inline marks 转换函数组。 // AST/block 迁移 complete 后,前端应直接消费 block document 中的 // tiptap 格式 marks(已由 Rust 侧 local_markdown_parser 输出), @@ -125,19 +137,26 @@ export const legacyBlockToTiptap = (block, index = 0) => { } if (type === 'divider' || type === 'horizontalRule' || type === 'horizontal_rule') return { type: 'horizontalRule', attrs: { blockId } }; if (type === 'mindmap') { + const attrs = block?.attrs && typeof block.attrs === 'object' ? block.attrs : null; const data = block?.props?.data && typeof block.props.data === 'object' ? block.props.data : null; const mindmapId = firstNonEmptyText( block?.props?.mindmapId, block?.props?.mindmap_id, block?.props?.sourcePath, block?.props?.source_path, + attrs?.mindmapId, + attrs?.mindmap_id, + attrs?.sourcePath, + attrs?.source_path, block?.mindmapId, block?.mindmap_id, data?.mindmapId, data?.mindmap_id, data?.id ); - const rootNodeId = firstNonEmptyText(block?.props?.rootNodeId, block?.props?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root'; + const rootNodeId = firstNonEmptyText(block?.props?.rootNodeId, block?.props?.root_node_id, attrs?.rootNodeId, attrs?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root'; + const mindmapWidth = normalizeMindmapDimension(block?.props?.mindmapWidth ?? block?.props?.mindmap_width ?? attrs?.mindmapWidth ?? attrs?.mindmap_width ?? data?.mindmapWidth ?? data?.mindmap_width, 'width'); + const mindmapHeight = normalizeMindmapDimension(block?.props?.mindmapHeight ?? block?.props?.mindmap_height ?? attrs?.mindmapHeight ?? attrs?.mindmap_height ?? data?.mindmapHeight ?? data?.mindmap_height, 'height'); return { type: 'paragraph', attrs: withTextAlign({ @@ -145,6 +164,8 @@ export const legacyBlockToTiptap = (block, index = 0) => { mnoteBlockType: 'mindmap', mindmapId, rootNodeId, + ...(mindmapWidth !== null ? { mindmapWidth } : {}), + ...(mindmapHeight !== null ? { mindmapHeight } : {}), }), }; } @@ -225,7 +246,9 @@ export const mindmapDomDescriptors = (root) => { const rootNodeId = typeof node.dataset.mnoteRootNodeId === 'string' && node.dataset.mnoteRootNodeId.trim() ? node.dataset.mnoteRootNodeId.trim() : 'root'; - return [{ mindmapId, rootNodeId }]; + const mindmapWidth = normalizeMindmapDimension(node.dataset.mnoteMindmapWidth, 'width'); + const mindmapHeight = normalizeMindmapDimension(node.dataset.mnoteMindmapHeight, 'height'); + return [{ mindmapId, rootNodeId, mindmapWidth, mindmapHeight }]; }); }; @@ -246,6 +269,12 @@ export const hydrateMindmapAttrsFromDom = (tiptapDocument, root) => { if (typeof node.attrs.rootNodeId !== 'string' || !node.attrs.rootNodeId.trim()) { node.attrs.rootNodeId = descriptor.rootNodeId; } + if (normalizeMindmapDimension(node.attrs.mindmapWidth, 'width') === null && descriptor.mindmapWidth !== null) { + node.attrs.mindmapWidth = descriptor.mindmapWidth; + } + if (normalizeMindmapDimension(node.attrs.mindmapHeight, 'height') === null && descriptor.mindmapHeight !== null) { + node.attrs.mindmapHeight = descriptor.mindmapHeight; + } } return tiptapDocument; }; @@ -445,20 +474,17 @@ export const localizeTiptapAssetUrls = (node, context) => { }; export const pageBodyTiptapDocumentSource = (body, fallbackText = '') => { + const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null; + if (blockDocument) return 'page_aggregate.block_document'; if (String(body?.projectionSource || body?.projection_source || '') === 'local_markdown.content' && body?.content) { return 'local_markdown.content'; } - const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null; - if (blockDocument) return 'page_aggregate.block_document'; if (body?.content) return 'compat.legacy_content'; return fallbackText ? 'degraded.fallback_text' : 'empty'; }; export const pageBodyTiptapDocument = (body, fallbackText = '', context = null) => { const projectionContext = { ...(context || {}), body }; - if (pageBodyTiptapDocumentSource(body, fallbackText) === 'local_markdown.content') { - return localizeTiptapAssetUrls(toTiptapDocument(body.content, fallbackText), projectionContext); - } const blockDocument = body?.blockDocument || body?.block_document || body?.editorDocument || body?.editor_document || null; if (blockDocument) return localizeTiptapAssetUrls(toTiptapDocument(blockDocument, fallbackText), projectionContext); return localizeTiptapAssetUrls(toTiptapDocument(body?.content, fallbackText), projectionContext); @@ -533,10 +559,14 @@ export const mindmapPropsFromAttrs = (attrs, fallbackMindmapId) => { ); const rootNodeId = firstNonEmptyText(attrs?.rootNodeId, attrs?.root_node_id, data?.rootNodeId, data?.root_node_id) || 'root'; const projectionVersion = Number(attrs?.projectionVersion ?? attrs?.projection_version); + const mindmapWidth = normalizeMindmapDimension(attrs?.mindmapWidth ?? attrs?.mindmap_width ?? data?.mindmapWidth ?? data?.mindmap_width, 'width'); + const mindmapHeight = normalizeMindmapDimension(attrs?.mindmapHeight ?? attrs?.mindmap_height ?? data?.mindmapHeight ?? data?.mindmap_height, 'height'); return { mindmapId, rootNodeId, ...(Number.isFinite(projectionVersion) ? { projectionVersion } : {}), + ...(mindmapWidth !== null ? { mindmapWidth } : {}), + ...(mindmapHeight !== null ? { mindmapHeight } : {}), }; }; diff --git a/rust/crates/mnote-web/browser/filetree-runtime.js b/rust/crates/mnote-web/browser/filetree-runtime.js index 97b229b8..14b2ad61 100644 --- a/rust/crates/mnote-web/browser/filetree-runtime.js +++ b/rust/crates/mnote-web/browser/filetree-runtime.js @@ -9,7 +9,12 @@ function fileTreeRowKind(row) { function fileTreeRowDocumentId(row) { if (!(row instanceof HTMLElement)) return ''; - return String(row.getAttribute('data-document-id') || row.getAttribute('data-doc-id') || '').trim(); + return String( + row.getAttribute('data-document-id') + || row.getAttribute('data-doc-id') + || row.getAttribute('data-owner-document-id') + || '', + ).trim(); } function fileTreeRowAssetId(row, deps) { @@ -98,6 +103,11 @@ function readWorkspacePathFromRow(row, deps) { var documentId = fileTreeRowDocumentId(row); var rowId = String(row.getAttribute('data-row-id') || '').trim(); var rowKind = fileTreeRowKind(row); + if (!documentId && (rowKind === 'folder' || objectKind === 'index') && relativePath) { + documentId = 'local-dir:' + relativePath.replace(/^\/+/, '').split('/').map(function(segment) { + return encodeURIComponent(segment).replace(/%20/g, '~20'); + }).join('~2F'); + } var sourceKind = String(row.getAttribute('data-source-kind') || currentSourceKind() || '').trim(); var rootUri = String(row.getAttribute('data-root-uri') || currentRootUri() || '').trim(); return { diff --git a/rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js b/rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js index e31330e7..c956c54a 100644 --- a/rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js +++ b/rust/crates/mnote-web/browser/sidebar-filetree-open-runtime.js @@ -410,7 +410,7 @@ export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => { navigateToMindmapObject(String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, String(detail.workspaceId || '').trim()); return; } - var requestedOfficeMode = forceNewWindow || forceEditMode ? 'edit' : 'view'; + var requestedOfficeMode = forceEditMode ? 'edit' : 'view'; var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, requestedOfficeMode); if (localOfficeUrl) { if (!forceNewWindow && await openLocalResourceInActiveTab({ diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-markdown-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-markdown-runtime.js new file mode 100644 index 00000000..15e275bf --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-markdown-runtime.js @@ -0,0 +1,107 @@ +export function createSidebarPageAiMarkdownRuntime(context) { + const { escapeHtml } = context; + + function textFromUnknown(value) { + if (value == null) return ''; + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value); + if (Array.isArray(value)) return value.map(textFromUnknown).filter(Boolean).join(' '); + if (typeof value !== 'object') return ''; + var parts = []; + ['text', 'title', 'content', 'children', 'blocks', 'body'].forEach(function(key) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + var text = textFromUnknown(value[key]); + if (text) parts.push(text); + } + }); + return parts.join(' '); + } + + function renderPageAiMarkdownInline(text) { + var html = escapeHtml(String(text || '')); + var codeSpans = []; + html = html.replace(/`([^`\n]+)`/g, function(_, code) { + var key = '\u0000CODE' + codeSpans.length + '\u0000'; + codeSpans.push('' + code + ''); + return key; + }); + html = html.replace(/\*\*([^*\n]+)\*\*/g, '$1'); + html = html.replace(/(^|[^*])\*([^*\n]+)\*/g, '$1$2'); + codeSpans.forEach(function(value, index) { + html = html.replace('\u0000CODE' + index + '\u0000', value); + }); + return html; + } + + function renderPageAiMarkdown(content) { + var lines = String(content || '').replace(/\r\n?/g, '\n').split('\n'); + var blocks = []; + var index = 0; + function isBlockBoundary(line) { + return !line.trim() || + /^```/.test(line.trim()) || + /^#{1,6}\s+/.test(line) || + /^\s*[-*]\s+/.test(line) || + /^\s*\d+[.)]\s+/.test(line); + } + while (index < lines.length) { + var line = lines[index]; + if (!line.trim()) { + index += 1; + continue; + } + if (/^```/.test(line.trim())) { + index += 1; + var codeLines = []; + while (index < lines.length && !/^```/.test(lines[index].trim())) { + codeLines.push(lines[index]); + index += 1; + } + if (index < lines.length) index += 1; + blocks.push('
' + escapeHtml(codeLines.join('\n')) + '
'); + continue; + } + var heading = line.match(/^(#{1,6})\s+(.+)$/); + if (heading) { + var level = Math.min(6, heading[1].length); + blocks.push('' + renderPageAiMarkdownInline(heading[2]) + ''); + index += 1; + continue; + } + if (/^\s*[-*]\s+/.test(line)) { + var unordered = []; + while (index < lines.length && /^\s*[-*]\s+/.test(lines[index])) { + unordered.push('
  • ' + renderPageAiMarkdownInline(lines[index].replace(/^\s*[-*]\s+/, '')) + '
  • '); + index += 1; + } + blocks.push('
      ' + unordered.join('') + '
    '); + continue; + } + if (/^\s*\d+[.)]\s+/.test(line)) { + var ordered = []; + while (index < lines.length && /^\s*\d+[.)]\s+/.test(lines[index])) { + ordered.push('
  • ' + renderPageAiMarkdownInline(lines[index].replace(/^\s*\d+[.)]\s+/, '')) + '
  • '); + index += 1; + } + blocks.push('
      ' + ordered.join('') + '
    '); + continue; + } + var paragraph = []; + while (index < lines.length && !isBlockBoundary(lines[index])) { + paragraph.push(renderPageAiMarkdownInline(lines[index])); + index += 1; + } + if (paragraph.length) { + blocks.push('

    ' + paragraph.join('
    ') + '

    '); + } else { + index += 1; + } + } + return blocks.join('') || escapeHtml(String(content || '')); + } + + return { + textFromUnknown, + renderPageAiMarkdown, + renderPageAiMarkdownInline + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-permission-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-permission-runtime.js new file mode 100644 index 00000000..6e6c0745 --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-permission-runtime.js @@ -0,0 +1,132 @@ +export function createSidebarPageAiPermissionRuntime(context) { + const { + documentRef, + pageAiPreviewValue, + pageUiState, + renderPageAiConversation, + } = context; + const doc = documentRef || document; + + function pageAiPermissionMessage(payload, eventType) { + payload = payload && typeof payload === 'object' ? payload : {}; + var permissionId = String(payload.permissionId || payload.permission_id || payload.id || ('perm_' + Date.now())).trim(); + var toolName = String(payload.toolName || payload.tool || payload.name || payload.method || 'session/request_permission').trim(); + var args = payload.arguments || payload.args || payload.input || payload.params || payload; + var decision = String(payload.decision || payload.result || '').trim(); + if (!decision && eventType === 'permission.denied') decision = 'denied'; + if (!decision && eventType === 'permission.allowed') decision = 'allowed'; + return { + role: 'tool', + kind: 'permission', + permissionId: permissionId, + toolName: toolName, + argsSummary: pageAiPreviewValue(args), + content: decision === 'denied' ? '已自动拒绝权限请求' : (decision === 'allowed' ? '已自动允许权限请求' : '等待权限确认'), + resolved: decision === 'denied' || decision === 'allowed', + decision: decision + }; + } + + function pageAiApplyPermissionEvent(eventName, payloadText) { + var payload = null; + try { + payload = JSON.parse(payloadText || 'null'); + } catch (_) { + payload = {}; + } + var message = pageAiPermissionMessage(payload, eventName); + var existing = pageUiState.pageAiMessages.find(function(item) { + return item.kind === 'permission' && item.permissionId === message.permissionId; + }); + if (existing) { + Object.assign(existing, message); + } else { + pageUiState.pageAiMessages.push(message); + } + pageUiState.pageAiPermissionRequests = pageUiState.pageAiPermissionRequests.filter(function(item) { + return item.permissionId !== message.permissionId; + }).concat([message]).slice(-20); + if (!message.resolved) { + pageAiShowPermissionDialog(message); + } else { + pageAiHidePermissionDialog(); + } + } + + function pageAiResolvePermission(permissionId, decision) { + permissionId = String(permissionId || '').trim(); + if (!permissionId) return; + var runId = pageUiState.pageAiCurrentRunId; + if (runId) { + fetch('/api/hermes/client/runs/' + encodeURIComponent(runId) + '/resolve-permission', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ permissionId: permissionId, decision: decision }) + }).then(function(response) { + if (!response.ok) console.warn('resolve-permission 后端返回异常', response.status); + }).catch(function(err) { + console.warn('resolve-permission 请求失败', err); + }); + } else { + console.warn('resolve-permission: 无活跃 runId,只能本地更新'); + } + pageUiState.pageAiMessages.forEach(function(item) { + if (item.kind === 'permission' && item.permissionId === permissionId) { + item.resolved = true; + item.decision = decision; + item.content = decision === 'allow' ? '已允许权限请求' : '已拒绝权限请求'; + } + }); + var dialog = doc.querySelector('[data-page-ai-permission-dialog]'); + if (dialog instanceof HTMLElement) dialog.hidden = true; + renderPageAiConversation(); + } + + function pageAiHidePermissionDialog() { + var dialog = doc.querySelector('[data-page-ai-permission-dialog]'); + if (dialog instanceof HTMLElement) dialog.hidden = true; + } + + function pageAiShowPermissionDialog(message) { + if (!message || message.kind !== 'permission') return; + if (message.resolved) { + pageAiHidePermissionDialog(); + return; + } + var dialog = doc.querySelector('[data-page-ai-permission-dialog]'); + if (!(dialog instanceof HTMLElement)) { + dialog = doc.createElement('div'); + dialog.className = 'wolai-page-ai-permission-dialog'; + dialog.setAttribute('data-page-ai-permission-dialog', 'true'); + dialog.innerHTML = '' + + ''; + doc.body.appendChild(dialog); + } + var tool = dialog.querySelector('[data-page-ai-permission-tool]'); + if (tool instanceof HTMLElement) tool.textContent = message.toolName || 'session/request_permission'; + var args = dialog.querySelector('[data-page-ai-permission-args]'); + if (args instanceof HTMLElement) args.textContent = message.argsSummary || message.content || ''; + dialog.querySelectorAll('[data-page-ai-permission-dialog-action]').forEach(function(button) { + if (button instanceof HTMLButtonElement) { + button.setAttribute('data-page-ai-permission-id', message.permissionId || ''); + button.disabled = Boolean(message.resolved); + } + }); + dialog.hidden = false; + } + + return { + pageAiPermissionMessage, + pageAiApplyPermissionEvent, + pageAiResolvePermission, + pageAiHidePermissionDialog, + pageAiShowPermissionDialog + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-profile-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-profile-runtime.js new file mode 100644 index 00000000..b92f7431 --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-profile-runtime.js @@ -0,0 +1,220 @@ +export function createSidebarPageAiProfileRuntime(context) { + const { + chatOnlyProfileRegistry, + documentRef, + pageAiAgentRecord, + pageAiCurrentAgentId, + pageAiNormalizeAgentId, + pageUiState, + } = context; + const PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY = Array.isArray(chatOnlyProfileRegistry) ? chatOnlyProfileRegistry : []; + + function pageAiProviderLabel(provider) { + if (provider === 'codex') return 'Codex'; + if (provider === 'claudecode') return 'ClaudeCode'; + return 'Hermes'; + } + + function pageAiNormalizeArray(value) { + return Array.isArray(value) ? value : []; + } + + function pageAiDefaultAcpRuntimes() { + return [ + { + name: 'reasonix', + title: 'ACP · Reasonix', + description: '通过 ACP 协议直连 Reasonix(DeepSeek 缓存优先)', + model: 'deepseek-chat', + preset: 'auto' + }, + { + name: 'hermes', + title: 'ACP · Hermes', + description: '通过 ACP 协议直连 Hermes agent runtime' + } + ]; + } + + function pageAiNormalizeAcpRuntimes(runtimes) { + var byName = {}; + pageAiDefaultAcpRuntimes().forEach(function(runtime) { + byName[runtime.name] = Object.assign({}, runtime); + }); + pageAiNormalizeArray(runtimes).forEach(function(runtime) { + var name = String(runtime && runtime.name || '').trim(); + if (name !== 'reasonix' && name !== 'hermes') return; + byName[name] = Object.assign({}, byName[name] || {}, runtime, { name: name }); + }); + return ['reasonix', 'hermes'].map(function(name) { return byName[name]; }).filter(Boolean); + } + + function pageAiUnwrapUpstream(payload) { + if (payload && typeof payload === 'object' && payload.upstream) return payload.upstream; + return payload || null; + } + + function pageAiProfileValue(profile) { + if (profile && typeof profile === 'object') { + return String(profile.profileId || profile.name || profile.profile || profile.id || '').trim(); + } + return String(profile || '').trim(); + } + + function pageAiCurrentProfile() { + var active = String(pageUiState.pageAiActiveProfileName || '').trim(); + if (active) return active; + var selected = pageUiState.pageAiProfiles.find(function(profile) { + return profile && profile.active; + }); + return pageAiProfileValue(selected) || 'mnoteai'; + } + + function pageAiRunProfile() { + if (String(pageUiState.pageAiAcpRuntime || 'reasonix').trim() === 'reasonix') return 'reasonix'; + if (pageAiCurrentAgentId() === 'chat_only') return pageAiNormalizeChatOnlyProfileId(pageAiCurrentProfile()); + return pageAiCurrentProfile(); + } + + function pageAiMnoteToolModel() { + var doc = documentRef || document; + return String(doc.documentElement.getAttribute('data-mnote-page-ai-tool-model') || 'deepseek-v4-flash').trim() || 'deepseek-v4-flash'; + } + + function pageAiCurrentProfileRecord() { + var active = pageAiCurrentProfile(); + return pageUiState.pageAiProfiles.find(function(profile) { + return pageAiProfileValue(profile) === active; + }) || null; + } + + function pageAiChatOnlyProfileSpec(profile) { + var profileId = pageAiProfileValue(profile); + var baseProfile = String(profile && profile.baseProfile || '').trim(); + var isolatedProfile = String(profile && profile.isolatedProfile || '').trim(); + return PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY.find(function(spec) { + return spec.profileId === profileId || spec.baseProfile === baseProfile || isolatedProfile.indexOf(spec.baseProfile) >= 0; + }) || null; + } + + function pageAiDefaultChatOnlyProfileSpec() { + return PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY[0] || { profileId: 'shared_deepseek_chat', baseProfile: 'deepseek-chat', label: 'DeepSeek' }; + } + + function pageAiNormalizeChatOnlyProfileId(profileId) { + var profile = pageAiProfileRecordById(profileId) || { profileId: String(profileId || '').trim(), name: String(profileId || '').trim() }; + var spec = pageAiChatOnlyProfileSpec(profile); + return (spec || pageAiDefaultChatOnlyProfileSpec()).profileId; + } + + function pageAiProfileDisplayLabel(profile, fallback) { + var alias = String(profile && profile.alias || '').trim(); + var displayName = String(profile && (profile.displayName || profile.label || '') || '').trim(); + var name = pageAiProfileValue(profile); + return alias || displayName || fallback || name || 'default'; + } + + function pageAiProfileRecordById(profileId) { + var normalized = String(profileId || '').trim(); + if (!normalized) return null; + return pageAiNormalizeArray(pageUiState.pageAiProfiles).find(function(profile) { + return pageAiProfileValue(profile) === normalized; + }) || null; + } + + function pageAiSessionAgentFilterValue(session) { + var agentId = pageAiNormalizeAgentId(session && session.agentId); + if (agentId === 'reasonix') return 'reasonix'; + var profileId = String(session && (session.profileId || session.profile) || '').trim(); + if (agentId === 'chat_only') profileId = pageAiNormalizeChatOnlyProfileId(profileId); + return agentId + ':' + profileId; + } + + function pageAiSessionAgentLabel(session) { + var agentId = pageAiNormalizeAgentId(session && session.agentId); + if (agentId === 'reasonix') return 'Reasonix'; + var profileId = String(session && (session.profileId || session.profile) || '').trim(); + var profile = pageAiProfileRecordById(profileId) || { profileId: profileId, name: profileId }; + var chatOnlySpec = pageAiChatOnlyProfileSpec(profile); + if (agentId === 'chat_only') { + return 'ChatOnly / ' + (chatOnlySpec || pageAiDefaultChatOnlyProfileSpec()).label; + } + if (agentId === 'hermes') return 'Hermes / ' + pageAiProfileDisplayLabel(profile, profileId); + return pageAiAgentRecord(agentId).label; + } + + function pageAiSessionPreviewText(session) { + var preview = Array.isArray(session && session.messages) && session.messages.length + ? String(session.messages.slice(-1)[0].content || '') + : String(session && (session.snippet || session.preview || '暂无消息') || '暂无消息'); + preview = preview.replace(/\s+/g, ' ').trim(); + var limit = 96; + return preview.length > limit ? preview.slice(0, limit) + '…' : preview; + } + + function pageAiSessionAgentFilterOptions(rows) { + var byValue = { all: '全部 agent' }; + pageAiNormalizeArray(rows).forEach(function(session) { + var value = pageAiSessionAgentFilterValue(session); + byValue[value] = pageAiSessionAgentLabel(session); + }); + return Object.keys(byValue).map(function(value) { + return { value: value, label: byValue[value] }; + }); + } + + function pageAiFilteredHistoryRows(rows) { + var filterValue = String(pageUiState.pageAiSessionAgentFilter || 'all').trim() || 'all'; + var normalized = pageAiNormalizeArray(rows); + if (filterValue === 'all') return normalized; + return normalized.filter(function(session) { + return pageAiSessionAgentFilterValue(session) === filterValue; + }); + } + + function pageAiTimestamp(value) { + if (typeof value === 'number' && Number.isFinite(value)) return value; + if (typeof value === 'string' && value.trim()) { + var parsed = Date.parse(value); + if (Number.isFinite(parsed)) return parsed; + } + return Date.now(); + } + + function pageAiUsageSummary(usage) { + if (!usage || typeof usage !== 'object') return ''; + var used = usage.used ?? usage.contextUsed ?? usage.input_tokens ?? usage.inputTokens ?? usage.prompt_tokens ?? usage.promptTokens; + var size = usage.size ?? usage.contextSize ?? usage.total_tokens ?? usage.totalTokens; + var output = usage.output_tokens ?? usage.outputTokens ?? usage.completion_tokens ?? usage.completionTokens; + var parts = []; + if (Number.isFinite(Number(used))) parts.push('ctx ' + Number(used)); + if (Number.isFinite(Number(size)) && Number(size) > 0) parts.push('/ ' + Number(size)); + if (Number.isFinite(Number(output)) && Number(output) > 0) parts.push('out ' + Number(output)); + return parts.join(' ') || ''; + } + + return { + pageAiProviderLabel, + pageAiNormalizeArray, + pageAiDefaultAcpRuntimes, + pageAiNormalizeAcpRuntimes, + pageAiUnwrapUpstream, + pageAiProfileValue, + pageAiCurrentProfile, + pageAiRunProfile, + pageAiMnoteToolModel, + pageAiCurrentProfileRecord, + pageAiChatOnlyProfileSpec, + pageAiDefaultChatOnlyProfileSpec, + pageAiNormalizeChatOnlyProfileId, + pageAiProfileDisplayLabel, + pageAiProfileRecordById, + pageAiSessionAgentFilterValue, + pageAiSessionAgentLabel, + pageAiSessionPreviewText, + pageAiSessionAgentFilterOptions, + pageAiFilteredHistoryRows, + pageAiTimestamp, + pageAiUsageSummary + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-render-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-render-runtime.js new file mode 100644 index 00000000..492f612f --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-render-runtime.js @@ -0,0 +1,1128 @@ +export function createSidebarPageAiRenderRuntime(context) { + const { + contextRefRegistry, + cssEscape, + currentDocumentId, + documentRef, + escapeHtml, + localMarkdownRelativePathFromPageAiDocumentId, + pageAiAgentRecord, + pageAiAllSkillEntries, + pageAiBuildAllowedRoots, + pageAiChatOnlyProfileEntries, + pageAiChatOnlyProfileSpec, + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiCurrentProfileRecord, + pageAiCurrentSession, + pageAiCurrentSkillSource, + pageAiCurrentSkillSourceLabel, + pageAiDefaultChatOnlyProfileSpec, + pageAiEditorTargetCandidates, + pageAiEnsureContextRefState, + pageAiFilteredHistoryRows, + pageAiHideHermesBuiltinSkills, + pageAiHermesProfileEntries, + pageAiHermesSettingsUrl, + pageAiMnoteToolModel, + pageAiNormalizeAcpRuntimes, + pageAiNormalizeArray, + pageAiNormalizeSkillSource, + pageAiProfileDisplayLabel, + pageAiProfileValue, + pageAiProviderLabel, + pageAiReasonixMemoryEnabled, + pageAiRunProfile, + pageAiSessionAgentFilterOptions, + pageAiSessionAgentLabel, + pageAiSessionAgentFilterValue, + pageAiSessionPreviewText, + pageAiSessionStorageLabel, + pageAiSkillEnabled, + pageAiSkillGroupCollapsed, + pageAiSkillListEntries, + pageAiSkillOriginLabel, + pageAiSkillSourceOptions, + pageAiSkillSourceParts, + pageAiToggleableSkillEntries, + pageAiUsageSummary, + pageUiState, + renderPageAiMarkdown, + searchText, + currentPageAiEditorTarget, + currentPageAiSelectedText, + } = context; + const PAGE_AI_CONTEXT_REF_REGISTRY = Array.isArray(contextRefRegistry) ? contextRefRegistry : []; + + function pageAiTargetLabel(target) { + var workspacePath = target && target.workspacePath && typeof target.workspacePath === 'object' ? target.workspacePath : {}; + var kind = String(target && (target.resourceKind || target.editorKind) || workspacePath.resourceKind || '').trim(); + var title = String(target && target.title || '').trim(); + var relativePath = String(workspacePath.relativePath || target && target.path || '').trim(); + if (title) return title; + if (relativePath) return relativePath.split('/').filter(Boolean).pop() || relativePath; + if (kind === 'mindmap') return '思维导图'; + if (kind === 'only_office') return 'Office 资源'; + return '当前页'; + } + + function pageAiTargetDetail(target) { + var workspacePath = target && target.workspacePath && typeof target.workspacePath === 'object' ? target.workspacePath : {}; + var kind = String(target && (target.resourceKind || target.editorKind) || workspacePath.resourceKind || '').trim(); + var pane = String(target && target.paneRole || '').trim(); + var relativePath = String(workspacePath.relativePath || target && target.path || '').trim(); + return [kind || 'page', pane, relativePath].filter(Boolean).join(' · '); + } + + function pageAiContextRefLabel(kind) { + var record = PAGE_AI_CONTEXT_REF_REGISTRY.find(function(ref) { return ref.id === kind; }); + return record ? record.label : kind; + } + + function pageAiContextButtonSummary() { + var selected = pageAiEnsureContextRefState(); + var labels = PAGE_AI_CONTEXT_REF_REGISTRY + .filter(function(ref) { return selected[ref.id] === true; }) + .map(function(ref) { return ref.label; }); + if (!labels.length) return '选择上下文'; + var head = labels.slice(0, 2).join(' + '); + return labels.length > 2 ? head + ' +' + String(labels.length - 2) : head; + } + + function pageAiContextRefDetail(kind) { + var documentId = currentDocumentId(); + var relativePath = localMarkdownRelativePathFromPageAiDocumentId(documentId); + if (kind === 'current_page') return relativePath || documentId || '当前页面'; + if (kind === 'selection') return currentPageAiSelectedText() ? '当前选区可用' : '当前没有选区'; + if (kind === 'active_editor') { + var target = currentPageAiEditorTarget(); + return String(target && (target.title || target.documentId) || relativePath || '当前打开资源'); + } + if (kind === 'file') return relativePath || '当前文件'; + if (kind === 'folder') { + var roots = pageAiBuildAllowedRoots(); + if (!roots.length) return '需要授权后可用'; + return roots.map(function(root) { return root.rootUri.replace(/^file:\/\//, ''); }).filter(Boolean)[0] || '已授权文件夹'; + } + if (kind === 'changed_files') return '本次 run 后可用于追问'; + return ''; + } + + function pageAiContextRefDisabled(kind) { + if (kind === 'selection') return !currentPageAiSelectedText(); + return false; + } + + function pageAiSuggestions() { + var title = searchText(documentRef.querySelector('[data-page-title-current="true"]')?.textContent) || '当前页面'; + return [ + '帮我总结《' + title + '》当前内容', + '把当前页面改写得更简洁一些', + '提炼当前页的关键待办和行动项', + '基于当前页内容生成一个三段式摘要' + ]; + } + + function pageAiCurrentAgentSelectionLabel() { + var agentId = pageAiCurrentAgentId(); + if (agentId === 'reasonix') return 'Reasonix'; + var profile = pageAiCurrentProfileRecord(); + var chatOnlySpec = pageAiChatOnlyProfileSpec(profile || pageAiCurrentProfile()); + if (agentId === 'chat_only') { + return 'ChatOnly / ' + (chatOnlySpec || pageAiDefaultChatOnlyProfileSpec()).label; + } + if (chatOnlySpec) { + return 'ChatOnly / ' + chatOnlySpec.label; + } + if (agentId === 'hermes') return 'Hermes / ' + pageAiProfileDisplayLabel(profile, pageAiCurrentProfile()); + return pageAiAgentRecord(agentId).label; + } + + function pageAiRenderAgentProfileOption(agentId, profile, label, detail) { + var profileId = pageAiProfileValue(profile); + var active = pageAiCurrentAgentId() === agentId && profileId === pageAiCurrentProfile(); + return '' + + ''; + } + + function pageAiCurrentModelLabel() { + var profile = pageAiCurrentProfileRecord(); + var toolModel = pageAiMnoteToolModel(); + if (!profile) return 'tool: ' + toolModel; + var model = String(profile.model || '').trim(); + var gateway = String(profile.gateway || '').trim(); + var profileLabel = [model, gateway].filter(Boolean).join(' · ') || '由 Hermes 决定'; + return 'tool: ' + toolModel + ' · profile: ' + profileLabel; + } + + function pageAiFormatChangedFiles(files) { + return pageAiNormalizeArray(files).map(function(file) { + var path = String(file && file.path || '').trim(); + var changeType = String(file && file.changeType || file.change_type || 'modified').trim(); + var summary = String(file && file.summary || '').trim(); + var version = String(file && (file.version || file.revision || '') || '').trim(); + var hashBefore = String(file && file.hashBefore || '').trim(); + var hashAfter = String(file && file.hashAfter || '').trim(); + if (!version && (hashBefore || hashAfter)) version = 'hash ' + [hashBefore || '0', hashAfter || '0'].join('→'); + var modifiedBefore = Number(file && file.modifiedBeforeMs || 0) || 0; + var modifiedAfter = Number(file && file.modifiedAfterMs || 0) || 0; + if (!version && (modifiedBefore || modifiedAfter)) version = 'mtime ' + [String(modifiedBefore), String(modifiedAfter)].join('→'); + var actor = [file && file.agentKind, file && file.actorType, file && file.actorId].map(function(value) { + return String(value || '').trim(); + }).filter(Boolean).join('/'); + return [changeType, path, version, summary, actor].filter(Boolean).join(' · '); + }).filter(Boolean).join('\n'); + } + + function pageAiRunStatusLabel(status) { + if (status === 'queued') return '排队中'; + if (status === 'running') return '运行中'; + if (status === 'tool_calling') return '调用工具'; + if (status === 'completed') return '已完成'; + if (status === 'failed') return '失败'; + if (status === 'aborted') return '已停止'; + return '空闲'; + } + + function pageAiMemoryFileLabel(section) { + if (section === 'soul') return 'SOUL.md'; + if (section === 'user') return 'USER.md'; + return 'MEMORY.md'; + } + + function pageAiContextScopeLabel(scope) { + if (scope === 'selection') return '当前选区'; + if (scope === 'block') return '当前块'; + if (scope === 'options') return '页面设置'; + return '当前页'; + } + + function pageAiFilteredSkillEntries() { + var query = String(pageUiState.pageAiSkillQuery || '').trim().toLowerCase(); + var parts = pageAiSkillSourceParts(pageAiCurrentSkillSource()); + var entries = pageAiToggleableSkillEntries(parts.group, parts.profile); + if (!entries.length) { + entries = pageAiSkillListEntries().map(function(skill) { + return Object.assign({}, skill, { + group: parts.group, + profile: parts.profile || '' + }); + }); + } + return entries.filter(function(skill) { + if (parts.group === 'hermes' && pageAiHideHermesBuiltinSkills(parts.profile) && skill.builtin === true) return false; + if (!query) return true; + return String(skill.name || skill.id || '').toLowerCase().indexOf(query) >= 0 + || String(skill.title || '').toLowerCase().indexOf(query) >= 0 + || String(skill.description || '').toLowerCase().indexOf(query) >= 0 + || String(skill.category || '').toLowerCase().indexOf(query) >= 0 + || pageAiSkillOriginLabel(skill).toLowerCase().indexOf(query) >= 0; + }); + } + + function renderPageAiProviderButtons() { + var drawer = ensurePageAiDrawer(); + var isAcp = pageUiState.pageAiAcpRuntime !== ''; + drawer.querySelectorAll('[data-page-ai-provider]').forEach(function(button) { + var provider = button.getAttribute('data-page-ai-provider') || 'hermes'; + var active = provider === pageUiState.pageAiProvider; + button.classList.toggle('is-active', active); + button.setAttribute('aria-pressed', active ? 'true' : 'false'); + }); + var providerNode = drawer.querySelector('.wolai-page-ai-subtitle span:first-child'); + if (providerNode instanceof HTMLElement) { + providerNode.textContent = pageAiAgentRecord(pageAiCurrentAgentId()).label; + } + } + + function renderPageAiControls() { + var drawer = ensurePageAiDrawer(); + var isAcp = pageUiState.pageAiAcpRuntime !== ''; + var activeAgentId = pageAiCurrentAgentId(); + var activeProfile = pageAiCurrentProfile(); + drawer.setAttribute('data-page-ai-page', pageUiState.pageAiPage || 'chat'); + drawer.setAttribute('data-page-ai-active-agent-id', activeAgentId); + drawer.setAttribute('data-mnote-acp-runtime', pageUiState.pageAiAcpRuntime || 'reasonix'); + documentRef.documentElement.setAttribute('data-mnote-page-ai-agent-id', activeAgentId); + var agentButton = drawer.querySelector('[data-page-ai-agent-button]'); + var agentPopoverId = 'mnote-page-ai-agent-popover'; + var activeAgentLabel = pageAiCurrentAgentSelectionLabel(); + if (agentButton instanceof HTMLElement) { + agentButton.textContent = 'AI'; + agentButton.setAttribute('aria-expanded', pageUiState.pageAiAgentPopoverOpen ? 'true' : 'false'); + agentButton.setAttribute('aria-controls', agentPopoverId); + agentButton.setAttribute('data-page-ai-agent-summary', activeAgentLabel); + agentButton.setAttribute('aria-label', 'Agent:' + activeAgentLabel); + agentButton.setAttribute('title', 'Agent:' + activeAgentLabel); + } + var agentPopover = drawer.querySelector('[data-page-ai-agent-popover]'); + if (agentPopover instanceof HTMLElement) { + agentPopover.id = agentPopoverId; + agentPopover.hidden = !pageUiState.pageAiAgentPopoverOpen; + var chatOnlyOptions = pageAiChatOnlyProfileEntries().map(function(profile) { + var spec = pageAiChatOnlyProfileSpec(profile); + var label = profile.menuLabel || (spec && spec.label) || pageAiProfileDisplayLabel(profile, ''); + return pageAiRenderAgentProfileOption('chat_only', profile, label, '网页问答 · 不申请文件写权限'); + }).join(''); + var hermesOptions = pageAiHermesProfileEntries().map(function(profile) { + var profileId = pageAiProfileValue(profile); + var scope = profile.kind === 'shared' + ? (profile.readonly ? '共享 · 只读配置' : '共享') + : (profile.kind === 'personal' ? '个人 profile' : 'Hermes profile'); + return pageAiRenderAgentProfileOption('hermes', profile, pageAiProfileDisplayLabel(profile, profileId), scope); + }).join(''); + var reasonixActive = activeAgentId === 'reasonix'; + agentPopover.innerHTML = '' + + '
    ' + + '选择 Agent' + + '' + + '
    ' + + '
    ' + + '
    ChatOnly
    ' + + '
    ' + chatOnlyOptions + '
    ' + + '
    ' + + '
    ' + + '
    Hermes
    ' + + '
    ' + hermesOptions + '
    ' + + '
    ' + + '
    ' + + '
    Reasonix
    ' + + '
    ' + + '' + + '
    ' + + '
    '; + } + var agentChip = drawer.querySelector('[data-page-ai-agent-chip]'); + if (agentChip instanceof HTMLElement) { + agentChip.textContent = activeAgentLabel; + agentChip.setAttribute('title', '当前 Agent:' + activeAgentLabel); + } + var contextButton = drawer.querySelector('[data-page-ai-context-button]'); + var contextPopoverId = 'mnote-page-ai-context-popover'; + if (contextButton instanceof HTMLElement) { + var summary = pageAiContextButtonSummary(); + contextButton.textContent = '⇅'; + contextButton.setAttribute('aria-expanded', pageUiState.pageAiContextPopoverOpen ? 'true' : 'false'); + contextButton.setAttribute('aria-controls', contextPopoverId); + contextButton.setAttribute('data-page-ai-context-summary', summary); + contextButton.setAttribute('aria-label', '上下文:' + summary); + contextButton.setAttribute('title', '上下文:' + summary); + } + var contextPopover = drawer.querySelector('[data-page-ai-context-popover]'); + if (contextPopover instanceof HTMLElement) { + var selectedRefs = pageAiEnsureContextRefState(); + contextPopover.id = contextPopoverId; + contextPopover.hidden = !pageUiState.pageAiContextPopoverOpen; + contextPopover.innerHTML = '' + + '
    ' + + '发送给 AI 的上下文' + + '' + + '
    ' + + '
    ' + + PAGE_AI_CONTEXT_REF_REGISTRY.map(function(ref) { + var checked = selectedRefs[ref.id] === true; + var disabled = pageAiContextRefDisabled(ref.id); + return '' + + ''; + }).join('') + + '
    ' + + '
    ' + + '授权区域' + + '' + escapeHtml(pageAiBuildAllowedRoots().length ? pageAiBuildAllowedRoots().map(function(root) { return root.permission + ' · ' + root.rootUri.replace(/^file:\/\//, ''); }).join(' / ') : '未选择授权区域') + '' + + '
    '; + } + var targetButton = drawer.querySelector('[data-page-ai-target-button]'); + var targetPopover = drawer.querySelector('[data-page-ai-target-popover]'); + var targetChip = drawer.querySelector('[data-page-ai-target-chip]'); + var targetPopoverId = 'mnote-page-ai-target-popover'; + var targetCandidates = pageAiEditorTargetCandidates(); + var activeTarget = currentPageAiEditorTarget(); + var activeTargetLabel = pageAiTargetLabel(activeTarget); + if (targetButton instanceof HTMLElement) { + targetButton.textContent = '◎'; + targetButton.setAttribute('aria-expanded', pageUiState.pageAiTargetPopoverOpen ? 'true' : 'false'); + targetButton.setAttribute('aria-controls', targetPopoverId); + targetButton.setAttribute('aria-label', '目标:' + activeTargetLabel); + targetButton.setAttribute('title', '目标:' + activeTargetLabel); + } + if (targetChip instanceof HTMLElement) { + targetChip.textContent = activeTargetLabel; + targetChip.setAttribute('title', '当前目标:' + activeTargetLabel + ' · ' + pageAiTargetDetail(activeTarget)); + } + if (targetPopover instanceof HTMLElement) { + targetPopover.id = targetPopoverId; + targetPopover.hidden = !pageUiState.pageAiTargetPopoverOpen; + targetPopover.innerHTML = '' + + '
    ' + + '选择写入目标' + + '' + + '
    ' + + '
    ' + + targetCandidates.map(function(target) { + var targetId = String(target && target.targetId || '').trim(); + var active = targetId && targetId === String(activeTarget && activeTarget.targetId || '').trim(); + return '' + + ''; + }).join('') + + '
    '; + } + var allowedRootsNode = drawer.querySelector('[data-page-ai-allowed-roots]'); + if (allowedRootsNode instanceof HTMLElement) { + var allowedRoots = pageAiBuildAllowedRoots(); + if (!allowedRoots.length) { + var errorText = String(pageUiState.pageAiAllowedRootsError || '').trim(); + allowedRootsNode.innerHTML = '' + escapeHtml(errorText || '未选择授权区域') + ''; + } else { + allowedRootsNode.innerHTML = allowedRoots.map(function(root) { + var label = root.rootUri.replace(/^file:\/\//, '') || root.rootUri; + return '' + escapeHtml(root.permission + ' · ' + label) + ''; + }).join(''); + } + } + // Populate ACP runtime dropdown + var acpSelect = drawer.querySelector('[data-page-ai-acp-runtime]'); + if (acpSelect instanceof HTMLSelectElement) { + var runtimes = pageUiState.pageAiAcpRuntimes.length ? pageUiState.pageAiAcpRuntimes : pageAiNormalizeAcpRuntimes([]); + acpSelect.innerHTML = runtimes.map(function(rt) { + return ''; + }).join(''); + acpSelect.value = pageUiState.pageAiAcpRuntime || 'reasonix'; + } + // Show/hide Hermes-specific profile select + var profileLabel = drawer.querySelector('[data-page-ai-hermes-profile]'); + if (profileLabel instanceof HTMLElement) { + profileLabel.style.display = pageUiState.pageAiAcpRuntime === 'reasonix' ? 'none' : ''; + } + // When ACP is selected, populate agent panel with ACP runtime info + var agentPanel = drawer.querySelector('[data-page-ai-agent-panel]'); + if (agentPanel instanceof HTMLElement) { + agentPanel.innerHTML = '' + + '
    ' + + '
    授权区域
    ' + escapeHtml(pageAiBuildAllowedRoots().length ? 'SQLite directory_grants' : '需要授权') + '
    ' + + '
    ' + + '
    ' + + '
    默认上下文
    ContextRefs
    ' + + '
    ' + + '
    ' + + '
    审计
    changed files 默认摘要
    ' + + '
    '; + } + var profileSummary = drawer.querySelector('[data-page-ai-profile-summary]'); + if (profileSummary instanceof HTMLElement) profileSummary.textContent = '上下文可选'; + var profileSummary = drawer.querySelector('[data-page-ai-profile-summary]'); + if (profileSummary instanceof HTMLElement) profileSummary.textContent = '上下文可选'; + drawer.querySelectorAll('[data-page-ai-profile-select]').forEach(function(profileSelect) { + if (!(profileSelect instanceof HTMLSelectElement)) return; + var profiles = pageUiState.pageAiProfiles.length ? pageUiState.pageAiProfiles : [{ name: activeProfile, active: true }]; + profileSelect.innerHTML = profiles.map(function(profile) { + var name = pageAiProfileValue(profile) || 'default'; + var model = [profile.model, profile.gateway].filter(Boolean).join(' / '); + var scope = profile.kind === 'shared' + ? (profile.readonly ? 'shared · readonly' : 'shared · admin') + : (profile.kind === 'personal' ? 'personal · 可配置' : ''); + var label = [profile.alias || name, scope, model].filter(Boolean).join(' · '); + return ''; + }).join(''); + profileSelect.value = activeProfile; + }); + var runStatus = drawer.querySelector('[data-page-ai-run-status]'); + if (runStatus instanceof HTMLElement) { + var queueSuffix = pageUiState.pageAiQueueLength > 0 ? ' · 队列 ' + pageUiState.pageAiQueueLength : ''; + runStatus.textContent = pageAiRunStatusLabel(pageUiState.pageAiRunStatus) + queueSuffix; + } + var stopButton = drawer.querySelector('[data-page-ai-action="stop-run"]'); + if (stopButton instanceof HTMLButtonElement) { + var canStop = ['queued', 'running', 'tool_calling'].indexOf(pageUiState.pageAiRunStatus) >= 0 && pageUiState.pageAiCurrentRunId; + stopButton.disabled = !canStop; + stopButton.setAttribute('aria-disabled', canStop ? 'false' : 'true'); + } + var settingsLink = drawer.querySelector('[data-page-ai-action="open-hermes-settings"]'); + if (settingsLink instanceof HTMLButtonElement) { + settingsLink.disabled = !pageAiHermesSettingsUrl(); + settingsLink.title = pageAiHermesSettingsUrl() ? '打开 Hermes 设置' : '未配置 MNOTE_WEB_HERMES_UPSTREAM_URL'; + } + var queueList = drawer.querySelector('[data-page-ai-queue-list]'); + if (queueList instanceof HTMLElement) { + if (!pageUiState.pageAiQueuedItems.length) { + queueList.innerHTML = '
    暂无排队项。
    '; + } else { + queueList.innerHTML = pageUiState.pageAiQueuedItems.map(function(item, index) { + var label = '队列 ' + (index + 1); + return '' + + '
    ' + + '
    ' + escapeHtml(label) + '
    ' + escapeHtml(item.queueId) + '
    ' + + '' + + '
    '; + }).join(''); + } + } + var sessionNode = drawer.querySelector('[data-page-ai-session-status]'); + if (sessionNode instanceof HTMLElement) { + var session = pageAiCurrentSession(); + var usageText = session && session.usage ? pageAiUsageSummary(session.usage) : ''; + sessionNode.textContent = session && session.id + ? [String(session.title || '当前页问答'), pageAiSessionStorageLabel(session), usageText].filter(Boolean).join(' · ') + : '等待 AI session'; + } + var modelNode = drawer.querySelector('[data-page-ai-model-status]'); + if (modelNode instanceof HTMLElement) modelNode.textContent = pageAiBuildAllowedRoots().length ? '已授权' : '需授权'; + var scopeSelect = drawer.querySelector('[data-page-ai-context-scope]'); + if (scopeSelect instanceof HTMLSelectElement) scopeSelect.value = pageUiState.pageAiContextScope; + var scopeLabel = drawer.querySelector('[data-page-ai-context-scope-label]'); + if (scopeLabel instanceof HTMLElement) scopeLabel.textContent = pageAiContextScopeLabel(pageUiState.pageAiContextScope); + drawer.querySelectorAll('[data-page-ai-tab]').forEach(function(button) { + var target = button.getAttribute('data-page-ai-tab') || 'chat'; + var active = target === pageUiState.pageAiPage; + button.classList.toggle('is-active', active); + button.setAttribute('aria-selected', active ? 'true' : 'false'); + }); + drawer.querySelectorAll('[data-page-ai-panel]').forEach(function(panel) { + if (panel instanceof HTMLElement) { + panel.hidden = panel.getAttribute('data-page-ai-panel') !== pageUiState.pageAiPage; + } + }); + var profileError = drawer.querySelector('[data-page-ai-profile-error]'); + if (profileError instanceof HTMLElement) { + profileError.textContent = pageUiState.pageAiProfileError || ''; + profileError.hidden = !pageUiState.pageAiProfileError; + } + var memoryError = drawer.querySelector('[data-page-ai-memory-error]'); + if (memoryError instanceof HTMLElement) { + var memoryErrorText = pageUiState.pageAiProfileMemoryError || ''; + if (memoryErrorText && memoryErrorText === pageUiState.pageAiProfileError) memoryErrorText = ''; + memoryError.textContent = memoryErrorText; + memoryError.hidden = !memoryErrorText; + } + var hermesMemoryPanel = drawer.querySelector('[data-page-ai-hermes-panel]'); + if (hermesMemoryPanel instanceof HTMLElement) { + hermesMemoryPanel.innerHTML = ['soul', 'user', 'memory'].map(function(section) { + var label = pageAiMemoryFileLabel(section); + var value = pageUiState.pageAiProfileMemoryDrafts[section] || ''; + return '' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + escapeHtml(label) + '
    ' + + '
    保存到 Hermes profile: ' + escapeHtml(activeProfile) + '
    ' + + '
    ' + + '' + + '
    ' + + '' + + '
    '; + }).join(''); + } + var skillError = drawer.querySelector('[data-page-ai-skill-error]'); + if (skillError instanceof HTMLElement) { + skillError.textContent = pageUiState.pageAiSkillError || ''; + skillError.hidden = !pageUiState.pageAiSkillError; + } + var sessionError = drawer.querySelector('[data-page-ai-session-error]'); + if (sessionError instanceof HTMLElement) { + sessionError.textContent = pageUiState.pageAiSessionError || ''; + sessionError.hidden = !pageUiState.pageAiSessionError; + } + var sessionSearch = drawer.querySelector('[data-page-ai-session-search]'); + if (sessionSearch instanceof HTMLInputElement && documentRef.activeElement !== sessionSearch) { + sessionSearch.value = pageUiState.pageAiSessionSearchQuery || ''; + } + var sessionAgentFilter = drawer.querySelector('[data-page-ai-session-agent-filter]'); + if (sessionAgentFilter instanceof HTMLSelectElement) { + var historyRowsForFilter = pageUiState.pageAiSessionSearchResults.length + ? pageUiState.pageAiSessionSearchResults + : pageUiState.pageAiSessions; + var options = pageAiSessionAgentFilterOptions(historyRowsForFilter); + var activeFilter = String(pageUiState.pageAiSessionAgentFilter || 'all').trim() || 'all'; + if (!options.some(function(option) { return option.value === activeFilter; })) activeFilter = 'all'; + sessionAgentFilter.innerHTML = options.map(function(option) { + return ''; + }).join(''); + sessionAgentFilter.value = activeFilter; + pageUiState.pageAiSessionAgentFilter = activeFilter; + } + var skillSearch = drawer.querySelector('[data-page-ai-skill-search]'); + if (skillSearch instanceof HTMLInputElement && documentRef.activeElement !== skillSearch) { + skillSearch.value = pageUiState.pageAiSkillQuery; + } + var skillSourceSelect = drawer.querySelector('[data-page-ai-skill-source-select]'); + if (skillSourceSelect instanceof HTMLSelectElement) { + var activeSkillSource = pageAiCurrentSkillSource(); + skillSourceSelect.innerHTML = pageAiSkillSourceOptions().map(function(option) { + return ''; + }).join(''); + skillSourceSelect.value = activeSkillSource; + } + var hermesBuiltinToggle = drawer.querySelector('[data-page-ai-hide-hermes-builtin]'); + if (hermesBuiltinToggle instanceof HTMLInputElement) { + var skillSourceParts = pageAiSkillSourceParts(pageAiCurrentSkillSource()); + var showHermesFilter = skillSourceParts.group === 'hermes'; + var hermesFilterLabel = hermesBuiltinToggle.closest('.wolai-page-ai-skill-filter-toggle'); + if (hermesFilterLabel instanceof HTMLElement) hermesFilterLabel.hidden = !showHermesFilter; + hermesBuiltinToggle.checked = showHermesFilter && pageAiHideHermesBuiltinSkills(skillSourceParts.profile); + } + var skillList = drawer.querySelector('[data-page-ai-skill-list]'); + if (skillList instanceof HTMLElement) { + var skills = pageAiFilteredSkillEntries(); + if (!skills.length) { + skillList.innerHTML = '
    没有匹配的技能。
    '; + } else { + var sourceParts = pageAiSkillSourceParts(pageAiCurrentSkillSource()); + var group = sourceParts.group; + var headingExtra = group === 'hermes' ? ' · ' + sourceParts.profile : ''; + var collapsed = pageAiSkillGroupCollapsed(pageAiCurrentSkillSource()); + skillList.innerHTML = '' + + '
    ' + + '' + + (collapsed ? '' : skills.map(function(skill) { + var sourceText = pageAiSkillOriginLabel(skill) + + (skill.configScope ? ' · ' + skill.configScope : '') + + (skill.readOnly ? ' · 只读' : '') + + (skill.modified ? ' · modified' : ''); + var description = String(skill.description || '').trim(); + var hasDescription = description && description !== '---' && description !== '无描述'; + var displayName = String(skill.title || skill.name || skill.id || '').trim(); + var disabled = skill.toggleable === false || skill.readOnly === true; + return '' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + escapeHtml(displayName) + '
    ' + + '
    ' + escapeHtml(sourceText) + '
    ' + + '
    ' + + (hasDescription ? '
    ' + escapeHtml(description) + '
    ' : '') + + '
    ' + + '' + + '
    '; + }).join('')) + + '
    '; + } + } + var toolsList = drawer.querySelector('[data-page-ai-tool-list]'); + if (toolsList instanceof HTMLElement) { + var tools = pageAiNormalizeArray(pageUiState.pageAiTools); + if (!tools.length) { + toolsList.innerHTML = '
    尚未读取到 mnote tool manifest。
    '; + } else { + toolsList.innerHTML = tools.map(function(tool) { + return '' + + '
    ' + + '
    ' + + '
    ' + escapeHtml(tool.name) + '
    ' + + '
    ' + escapeHtml(tool.scope || tool.kind || 'mnote') + ' · ' + escapeHtml(tool.status || 'available') + '
    ' + + (tool.unavailableReason ? '
    ' + escapeHtml(tool.unavailableReason) + '
    ' : '') + + '
    ' + + '' + + '
    '; + }).join(''); + } + } + var gatewayError = drawer.querySelector('[data-page-ai-gateway-error]'); + if (gatewayError instanceof HTMLElement) { + gatewayError.textContent = pageUiState.pageAiGatewayHealthError || ''; + gatewayError.hidden = !pageUiState.pageAiGatewayHealthError; + } + var gatewayStatusNode = drawer.querySelector('[data-page-ai-gateway-status]'); + var gatewayDetail = drawer.querySelector('[data-page-ai-gateway-detail]'); + var gatewayHealth = pageUiState.pageAiGatewayHealth; + if (gatewayStatusNode instanceof HTMLElement) { + if (!gatewayHealth) { + gatewayStatusNode.textContent = '未检查'; + } else { + var gateway = gatewayHealth.gateway || {}; + var profile = gatewayHealth.profile || {}; + gatewayStatusNode.textContent = gatewayHealth.ok ? '可用' : '需要设置'; + if (gateway.status) gatewayStatusNode.textContent += ' · ' + gateway.status; + if (profile.name) gatewayStatusNode.textContent += ' · ' + profile.name; + } + } + if (gatewayDetail instanceof HTMLElement) { + if (!gatewayHealth) { + gatewayDetail.innerHTML = '
    打开高级后会检查 agent runtime 与当前 profile。
    '; + } else { + var gatewayInfo = gatewayHealth.gateway || {}; + var profileInfo = gatewayHealth.profile || {}; + var suggestionText = pageAiNormalizeArray(gatewayHealth.suggestions).join(';'); + gatewayDetail.innerHTML = '' + + '
    ' + + '
    ' + escapeHtml(profileInfo.name || activeProfile) + '
    ' + + '
    model.default: ' + escapeHtml(profileInfo.modelDefault || '未设置') + '
    ' + + '
    provider: ' + escapeHtml(profileInfo.provider || '未设置') + ' · API key: ' + escapeHtml(profileInfo.apiKeyConfigured ? '已配置' : '未检测到') + '
    ' + + '
    ' + + '
    ' + + '
    ' + escapeHtml(gatewayInfo.upstream || '未配置 upstream') + '
    ' + + '
    gateway: ' + escapeHtml(gatewayInfo.status || 'unknown') + (gatewayInfo.httpStatus ? ' · HTTP ' + escapeHtml(gatewayInfo.httpStatus) : '') + '
    ' + + (suggestionText ? '
    ' + escapeHtml(suggestionText) + '
    ' : '') + + '
    '; + } + } + var toolError = drawer.querySelector('[data-page-ai-tool-error]'); + if (toolError instanceof HTMLElement) { + toolError.textContent = pageUiState.pageAiToolsError || ''; + toolError.hidden = !pageUiState.pageAiToolsError; + } + var lastTool = drawer.querySelector('[data-page-ai-last-tool]'); + if (lastTool instanceof HTMLElement) { + var call = pageUiState.pageAiLastToolCall; + lastTool.textContent = call + ? [call.event, call.name, call.runId, call.traceId || call.auditId].filter(Boolean).join(' · ') + : '暂无 tool call'; + } + var reasonixPanel = drawer.querySelector('[data-page-ai-reasonix-panel]'); + if (reasonixPanel instanceof HTMLElement) { + reasonixPanel.innerHTML = '' + + '
    ' + + '
    ' + + '
    Reasonix 专属设置
    ACP runtime / memory
    ' + + '' + + '
    ' + + '
    ' + escapeHtml(pageAiReasonixMemoryEnabled() ? '当前用户已开启 Reasonix global/project memory。' : '默认关闭 Reasonix memory,避免跨用户偏好混入。') + '
    ' + + '
    '; + } + var chatOnlyPanel = drawer.querySelector('[data-page-ai-chat-only-panel]'); + if (chatOnlyPanel instanceof HTMLElement) { + chatOnlyPanel.innerHTML = '
    Chat-only
    默认不申请文件写权限
    '; + } + } + + function humanizePageAiResponse(rawText, promptText) { + var providerLabel = pageAiProviderLabel(pageUiState.pageAiProvider); + var text = String(rawText || '').trim(); + if (!text) { + return providerLabel + ' 已收到你的问题“' + searchText(promptText) + '”,但这次没有返回可读内容。'; + } + if (text.startsWith('{')) { + try { + var payload = JSON.parse(text); + var operation = payload && payload.operation ? payload.operation : {}; + var normalized = operation && operation.normalized_input ? operation.normalized_input : {}; + var args = normalized && normalized.args ? normalized.args : {}; + var documentId = searchText(args.documentId || args.pageId || currentDocumentId()); + var toolName = searchText(operation.tool_name || normalized.toolName || 'doc_get'); + return providerLabel + ' 已收到你的问题“' + searchText(promptText) + '”。当前已通过 Hermes 调用 mnote plugin 工具,目标页面是 ' + (documentId || '当前页面') + ',本次选择的工具是 ' + toolName + '。如果你继续追问,我会沿当前页面上下文继续回复。'; + } catch (_) { + return providerLabel + ' 已返回结果,但当前结果是结构化文本,已为你保留原始内容。'; + } + } + return text; + } + + function ensurePageAiDrawer() { + var existing = documentRef.querySelector('[data-testid="wolai-page-ai-drawer"]'); + if (existing instanceof HTMLElement) return existing; + var drawer = documentRef.createElement('aside'); + drawer.className = 'wolai-page-ai-drawer'; + drawer.setAttribute('data-testid', 'wolai-page-ai-drawer'); + drawer.setAttribute('data-mnote-surface', 'page-ai'); + drawer.hidden = true; + drawer.innerHTML = '' + + ''; + documentRef.body.appendChild(drawer); + return drawer; + } + + function renderPageAiSuggestions() { + var drawer = ensurePageAiDrawer(); + var list = drawer.querySelector('[data-page-ai-panel="chat"] [data-page-ai-suggestion-list]'); + if (!(list instanceof HTMLElement)) return; + var container = list.closest('.wolai-page-ai-suggestions'); + if (container instanceof HTMLElement) { + container.hidden = pageUiState.pageAiPage !== 'chat' || pageUiState.pageAiMessages.length > 0; + } + var suggestions = pageAiSuggestions(); + var offset = pageUiState.pageAiSuggestionIndex % suggestions.length; + var ordered = suggestions.slice(offset).concat(suggestions.slice(0, offset)).slice(0, 3); + list.innerHTML = ordered.map(function(text) { + return ''; + }).join(''); + } + + function renderPageAiConversation() { + var drawer = ensurePageAiDrawer(); + renderPageAiSuggestions(); + var conversation = drawer.querySelector('[data-page-ai-panel="' + cssEscape(pageUiState.pageAiPage || 'chat') + '"] [data-page-ai-conversation]'); + if (!(conversation instanceof HTMLElement)) return; + if (pageUiState.pageAiPage === 'history') { + var sourceRows = pageUiState.pageAiSessionSearchResults.length + ? pageUiState.pageAiSessionSearchResults + : pageUiState.pageAiSessions; + var historyRows = pageAiFilteredHistoryRows(sourceRows); + if (!historyRows.length) { + conversation.innerHTML = '
    没有匹配的历史会话。
    '; + return; + } + conversation.innerHTML = historyRows.map(function(session) { + var preview = pageAiSessionPreviewText(session); + var active = session.id === pageUiState.pageAiActiveSessionId; + var usage = pageAiUsageSummary(session.usage); + var agentLabel = pageAiSessionAgentLabel(session); + var meta = [agentLabel, pageAiSessionStorageLabel(session), session.permissionLevel, session.shareId, session.status, usage].filter(Boolean).join(' · '); + return '' + + '
    ' + + '' + + '
    ' + + '' + + '' + + '' + + '
    ' + + '
    '; + }).join(''); + return; + } + if (!pageUiState.pageAiMessages.length) { + conversation.innerHTML = '
    围绕当前页面提问,我会优先使用当前页内容、页面结构和已保存设置。
    '; + return; + } + conversation.innerHTML = pageUiState.pageAiMessages.map(function(item) { + var roleLabel = item.role === 'user' ? '你' : (item.role === 'tool' ? '工具' : 'AI'); + if (item.role === 'tool') { + var statusLabel = item.status === 'completed' ? '完成' : (item.status === 'failed' ? '失败' : '运行中'); + var locationRows = Array.isArray(item.locations) && item.locations.length + ? '
    位置:' + item.locations.map(function(loc, idx) { + return '' + + '' + escapeHtml(loc) + '' + + '' + + ''; + }).join('') + '
    ' + : ''; + var detailRows = [ + locationRows, + item.argsSummary ? '
    参数 ' + escapeHtml(item.argsSummary) + '
    ' : '', + item.resultSummary ? '
    结果 ' + escapeHtml(item.resultSummary) + '
    ' : '', + item.changedFiles && item.changedFiles.length ? '
    ' + escapeHtml(pageAiFormatChangedFiles(item.changedFiles)) + '
    ' : '', + (item.traceId || item.auditId) ? '
    ' + escapeHtml([item.traceId, item.auditId].filter(Boolean).join(' · ')) + '
    ' : '' + ].filter(Boolean).join(''); + return '' + + '
    ' + + '
    ' + escapeHtml(roleLabel) + '
    ' + + '
    ' + + '
    ' + + '' + + '' + escapeHtml(item.toolName || item.content || 'tool') + '' + + '' + escapeHtml([statusLabel, item.toolKind, item.toolCallId].filter(Boolean).join(' · ')) + '' + + '' + + (detailRows || '
    暂无参数或结果详情。
    ') + + '
    ' + + '
    ' + + '
    '; + } + if (item.kind === 'thought') { + return '' + + '
    ' + + '思考过程' + + '
    ' + escapeHtml(item.content || '') + '
    ' + + '
    '; + } + if (item.kind === 'permission') { + var permissionActions = item.resolved ? '' : ( + '
    ' + + '' + + '' + + '
    ' + ); + return '' + + '
    ' + + '
    权限
    ' + + '
    ' + + '' + escapeHtml(item.toolName || 'session/request_permission') + '
    ' + + '' + escapeHtml(item.argsSummary || item.content || '') + '' + + permissionActions + + '
    ' + + '
    '; + } + if (item.kind === 'plan') { + var planEntries = Array.isArray(item.entries) ? item.entries : []; + var listHtml = planEntries.map(function(entry, idx) { + return '
  • ' + escapeHtml(String(entry || '')) + '
  • '; + }).join(''); + return '' + + '
    ' + + '
    ' + + '执行计划 · ' + planEntries.length + ' 步' + + '
    ' + + '
      ' + listHtml + '
    ' + + '
    ' + + '
    ' + + '
    '; + } + var streamingAttr = item.streaming ? ' data-page-ai-streaming="true"' : ''; + return '' + + '
    ' + + '
    ' + escapeHtml(roleLabel) + '
    ' + + '
    ' + (item.role === 'assistant' ? renderPageAiMarkdown(item.content || '') : escapeHtml(item.content || '')) + '
    ' + + '
    '; + }).join(''); + conversation.scrollTop = conversation.scrollHeight; + } + + return { + ensurePageAiDrawer, + humanizePageAiResponse, + pageAiContextButtonSummary, + pageAiContextRefDetail, + pageAiContextRefDisabled, + pageAiContextRefLabel, + pageAiCurrentAgentSelectionLabel, + pageAiCurrentModelLabel, + pageAiFilteredSkillEntries, + pageAiFormatChangedFiles, + pageAiMemoryFileLabel, + pageAiRenderAgentProfileOption, + pageAiRunStatusLabel, + pageAiSuggestions, + pageAiTargetDetail, + pageAiTargetLabel, + pageAiContextScopeLabel, + renderPageAiControls, + renderPageAiConversation, + renderPageAiProviderButtons, + renderPageAiSuggestions, + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js index f673ddf7..6f6aa13c 100644 --- a/rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js @@ -1,3 +1,11 @@ +import { createSidebarPageAiMarkdownRuntime } from './sidebar-page-ai-markdown-runtime.js'; +import { createSidebarPageAiPermissionRuntime } from './sidebar-page-ai-permission-runtime.js'; +import { createSidebarPageAiProfileRuntime } from './sidebar-page-ai-profile-runtime.js'; +import { createSidebarPageAiRenderRuntime } from './sidebar-page-ai-render-runtime.js'; +import { createSidebarPageAiSessionRuntime } from './sidebar-page-ai-session-runtime.js'; +import { createSidebarPageAiSkillRuntime } from './sidebar-page-ai-skill-runtime.js'; +import { createSidebarPageAiTargetRuntime } from './sidebar-page-ai-target-runtime.js'; + export function createSidebarPageAiRuntime(context) { const { buildLocalFileOpenUrl, @@ -22,6 +30,11 @@ export function createSidebarPageAiRuntime(context) { { id: 'reasonix', label: 'Reasonix', acpRuntime: 'reasonix', canWriteFiles: true }, { id: 'chat_only', label: 'Chat-only', acpRuntime: 'hermes', canWriteFiles: false } ]; + var PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY = [ + { profileId: 'shared_deepseek_chat', baseProfile: 'deepseek-chat', label: 'DeepSeek' }, + { profileId: 'shared_doubao_chat', baseProfile: 'doubao-chat', label: '豆包' }, + { profileId: 'shared_gemini_chat', baseProfile: 'gemini-chat', label: 'Gemini' } + ]; var PAGE_AI_CONTEXT_REF_REGISTRY = [ { id: 'current_page', label: '当前页' }, { id: 'selection', label: '选区' }, @@ -30,22 +43,131 @@ export function createSidebarPageAiRuntime(context) { { id: 'folder', label: '文件夹' }, { id: 'changed_files', label: '最近修改' } ]; + var pageAiDelegatesInstalled = false; - function textFromUnknown(value) { - if (value == null) return ''; - if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value); - if (Array.isArray(value)) return value.map(textFromUnknown).filter(Boolean).join(' '); - if (typeof value !== 'object') return ''; - var parts = []; - ['text', 'title', 'content', 'children', 'blocks', 'body'].forEach(function(key) { - if (Object.prototype.hasOwnProperty.call(value, key)) { - var text = textFromUnknown(value[key]); - if (text) parts.push(text); + function clonePageAiDefaultValue(value) { + if (Array.isArray(value)) return value.slice(); + if (value && typeof value === 'object') return Object.assign({}, value); + return value; + } + + function ensurePageAiStateFacade(state) { + var defaults = { + pageAiOpen: false, + pageAiBusy: false, + pageAiMessages: [], + pageAiSuggestionIndex: 0, + pageAiProvider: 'hermes', + pageAiPage: 'chat', + pageAiRunStatus: 'idle', + pageAiCurrentRunId: '', + pageAiAcpRuntime: 'reasonix', + pageAiAcpRuntimes: [], + pageAiQueueLength: 0, + pageAiQueuedItems: [], + pageAiStoppedRunIds: {}, + pageAiAbortController: null, + pageAiContextScope: 'page', + pageAiContextPopoverOpen: false, + pageAiTargetPopoverOpen: false, + pageAiSelectedTargetId: '', + pageAiSelectedContextRefs: null, + pageAiCurrentRunTargetSnapshot: null, + pageAiAllowedRoots: [], + pageAiAllowedRootsError: '', + pageAiAgentId: 'reasonix', + pageAiAgentPopoverOpen: false, + pageAiTools: [], + pageAiToolsError: '', + pageAiGatewayHealth: null, + pageAiGatewayHealthError: '', + pageAiLastToolCall: null, + pageAiProfiles: [], + pageAiActiveProfileName: 'mnoteai', + pageAiProfileError: '', + pageAiProfileMemory: { memory: '', user: '', soul: '' }, + pageAiProfileMemoryDrafts: { memory: '', user: '', soul: '' }, + pageAiProfileMemoryError: '', + pageAiSkills: { categories: [], archived: [] }, + pageAiSkillCatalogs: { + mnote: { categories: [], archived: [] }, + reasonix: { categories: [], archived: [] }, + hermes: { categories: [], archived: [] } + }, + pageAiSkillPreferences: {}, + pageAiCollapsedSkillGroups: {}, + pageAiSkillQuery: '', + pageAiSkillError: '', + pageAiSkillLoadSeq: 0, + pageAiActiveSkillSource: 'mnote', + pageAiSessions: [], + pageAiActiveSessionId: '', + pageAiSessionSearchQuery: '', + pageAiSessionSearchResults: [], + pageAiSessionSearchTimer: 0, + pageAiSessionAgentFilter: 'all', + pageAiSessionError: '', + pageAiPermissionRequests: [] + }; + Object.keys(defaults).forEach(function(key) { + if (typeof state[key] === 'undefined') { + state[key] = clonePageAiDefaultValue(defaults[key]); } }); - return parts.join(' '); + if (!state.pageAiSkillCatalogs || typeof state.pageAiSkillCatalogs !== 'object') { + state.pageAiSkillCatalogs = clonePageAiDefaultValue(defaults.pageAiSkillCatalogs); + } + if (!state.pageAiProfileMemory || typeof state.pageAiProfileMemory !== 'object') { + state.pageAiProfileMemory = clonePageAiDefaultValue(defaults.pageAiProfileMemory); + } + if (!state.pageAiProfileMemoryDrafts || typeof state.pageAiProfileMemoryDrafts !== 'object') { + state.pageAiProfileMemoryDrafts = clonePageAiDefaultValue(defaults.pageAiProfileMemoryDrafts); + } + if (!state.pageAiSkills || typeof state.pageAiSkills !== 'object') { + state.pageAiSkills = clonePageAiDefaultValue(defaults.pageAiSkills); + } + return state; } + ensurePageAiStateFacade(pageUiState); + + function closestAction(target, selector) { + var node = target && target.nodeType === Node.TEXT_NODE ? target.parentElement : target; + return node && typeof node.closest === 'function' ? node.closest(selector) : null; + } + + const pageAiMarkdown = createSidebarPageAiMarkdownRuntime({ escapeHtml }); + const textFromUnknown = (...args) => pageAiMarkdown.textFromUnknown(...args); + const renderPageAiMarkdown = (...args) => pageAiMarkdown.renderPageAiMarkdown(...args); + let pageAiRenderRuntime = null; + + function pageAiRenderApi() { + if (!pageAiRenderRuntime) throw new Error('page_ai_render_runtime_not_ready'); + return pageAiRenderRuntime; + } + + function ensurePageAiDrawer(...args) { return pageAiRenderApi().ensurePageAiDrawer(...args); } + function humanizePageAiResponse(...args) { return pageAiRenderApi().humanizePageAiResponse(...args); } + function pageAiContextButtonSummary(...args) { return pageAiRenderApi().pageAiContextButtonSummary(...args); } + function pageAiContextRefDetail(...args) { return pageAiRenderApi().pageAiContextRefDetail(...args); } + function pageAiContextRefDisabled(...args) { return pageAiRenderApi().pageAiContextRefDisabled(...args); } + function pageAiContextRefLabel(...args) { return pageAiRenderApi().pageAiContextRefLabel(...args); } + function pageAiContextScopeLabel(...args) { return pageAiRenderApi().pageAiContextScopeLabel(...args); } + function pageAiCurrentAgentSelectionLabel(...args) { return pageAiRenderApi().pageAiCurrentAgentSelectionLabel(...args); } + function pageAiCurrentModelLabel(...args) { return pageAiRenderApi().pageAiCurrentModelLabel(...args); } + function pageAiFilteredSkillEntries(...args) { return pageAiRenderApi().pageAiFilteredSkillEntries(...args); } + function pageAiFormatChangedFiles(...args) { return pageAiRenderApi().pageAiFormatChangedFiles(...args); } + function pageAiMemoryFileLabel(...args) { return pageAiRenderApi().pageAiMemoryFileLabel(...args); } + function pageAiRenderAgentProfileOption(...args) { return pageAiRenderApi().pageAiRenderAgentProfileOption(...args); } + function pageAiRunStatusLabel(...args) { return pageAiRenderApi().pageAiRunStatusLabel(...args); } + function pageAiSuggestions(...args) { return pageAiRenderApi().pageAiSuggestions(...args); } + function pageAiTargetDetail(...args) { return pageAiRenderApi().pageAiTargetDetail(...args); } + function pageAiTargetLabel(...args) { return pageAiRenderApi().pageAiTargetLabel(...args); } + function renderPageAiControls(...args) { return pageAiRenderApi().renderPageAiControls(...args); } + function renderPageAiConversation(...args) { return pageAiRenderApi().renderPageAiConversation(...args); } + function renderPageAiProviderButtons(...args) { return pageAiRenderApi().renderPageAiProviderButtons(...args); } + function renderPageAiSuggestions(...args) { return pageAiRenderApi().renderPageAiSuggestions(...args); } + function readLocalEditorBlocks() { var editor = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"] .editor-surface .ProseMirror'); if (!(editor instanceof HTMLElement)) return []; @@ -158,131 +280,6 @@ export function createSidebarPageAiRuntime(context) { }; } - function normalizePageAiOpenEditorEntry(entry) { - if (!entry || typeof entry !== 'object') return null; - return { - objectIdentity: String(entry.objectIdentity || '').trim(), - workspacePath: entry.workspacePath && typeof entry.workspacePath === 'object' ? entry.workspacePath : null, - paneRole: String(entry.paneRole || 'primary').trim() === 'secondary' ? 'secondary' : 'primary', - documentId: String(entry.documentId || '').trim(), - workspaceId: String(entry.workspaceId || '').trim(), - title: String(entry.title || '').trim(), - kind: String(entry.kind || entry.editorKind || '').trim(), - editorKind: String(entry.editorKind || entry.kind || '').trim(), - active: entry.active === true, - dirtyState: String(entry.dirtyState || entry.dirtyGuard || '').trim(), - preview: entry.preview === true, - pinned: entry.pinned === true, - lastActiveAt: Number(entry.lastActiveAt || 0) || 0, - assetId: String(entry.assetId || '').trim(), - path: String(entry.path || '').trim() - }; - } - - function currentPageAiOpenEditorsSnapshot() { - var snapshot = null; - try { - if (window.__mnoteDocumentPaneRuntime && typeof window.__mnoteDocumentPaneRuntime.getOpenEditorsSnapshot === 'function') { - snapshot = window.__mnoteDocumentPaneRuntime.getOpenEditorsSnapshot(); - } - } catch (_) {} - if (!snapshot || typeof snapshot !== 'object') snapshot = window.__mnoteOpenEditorsSnapshot || null; - if (!snapshot || typeof snapshot !== 'object') return null; - var editors = Array.isArray(snapshot.editors) - ? snapshot.editors.map(normalizePageAiOpenEditorEntry).filter(Boolean) - : []; - var resources = Array.isArray(snapshot.resourceEditors) - ? snapshot.resourceEditors.map(normalizePageAiOpenEditorEntry).filter(Boolean) - : editors.filter(function(entry) { return entry.kind !== 'page'; }); - var normalizeGroup = function(group, paneRole) { - var groupEditors = group && Array.isArray(group.editors) - ? group.editors.map(normalizePageAiOpenEditorEntry).filter(Boolean) - : editors.filter(function(entry) { return entry.paneRole === paneRole; }); - var groupResources = group && Array.isArray(group.resourceEditors) - ? group.resourceEditors.map(normalizePageAiOpenEditorEntry).filter(Boolean) - : resources.filter(function(entry) { return entry.paneRole === paneRole; }); - var groupActive = groupEditors.find(function(entry) { return entry.active; }) || null; - return { - paneRole: paneRole, - activeObjectIdentity: String(group && group.activeObjectIdentity || (groupActive ? groupActive.objectIdentity : '') || '').trim(), - editors: groupEditors, - resourceEditors: groupResources - }; - }; - var groups = { - primary: normalizeGroup(snapshot.groups && snapshot.groups.primary, 'primary'), - secondary: normalizeGroup(snapshot.groups && snapshot.groups.secondary, 'secondary') - }; - var activeObjectIdentity = String(snapshot.activeObjectIdentity || '').trim(); - var activeEditor = editors.find(function(entry) { - return entry.active && (!activeObjectIdentity || entry.objectIdentity === activeObjectIdentity); - }) || groups.primary.editors.find(function(entry) { - return entry.active; - }) || groups.secondary.editors.find(function(entry) { - return entry.active; - }) || null; - return { - schema: String(snapshot.schema || 'mnote.open_editors_snapshot.v1'), - generatedAt: Number(snapshot.generatedAt || 0) || Date.now(), - activeObjectIdentity: activeObjectIdentity || (activeEditor ? activeEditor.objectIdentity : ''), - activeEditor: activeEditor, - editors: editors, - resourceEditors: resources, - groups: groups - }; - } - - function currentPageAiEditorTarget() { - var snapshot = currentPageAiOpenEditorsSnapshot(); - var activeEditor = snapshot && snapshot.activeEditor ? snapshot.activeEditor : null; - if (!activeEditor) { - var fallbackDocumentId = currentDocumentId(); - return { - schema: 'mnote.ai_editor_target.v1', - source: 'fallback_current_document', - objectIdentity: fallbackDocumentId ? 'page:primary' : '', - workspacePath: null, - paneRole: 'primary', - documentId: fallbackDocumentId, - workspaceId: resolveWorkspaceId(document.body), - editorKind: 'page', - active: true, - dirtyState: '', - preview: false, - pinned: true, - lastActiveAt: Date.now(), - assetId: '', - path: '' - }; - } - return { - schema: 'mnote.ai_editor_target.v1', - source: 'open_editors_snapshot', - objectIdentity: activeEditor.objectIdentity, - workspacePath: activeEditor.workspacePath || null, - paneRole: activeEditor.paneRole, - documentId: activeEditor.documentId, - workspaceId: activeEditor.workspaceId || resolveWorkspaceId(document.body), - editorKind: activeEditor.editorKind || activeEditor.kind, - active: activeEditor.active, - dirtyState: activeEditor.dirtyState || '', - preview: activeEditor.preview === true, - pinned: activeEditor.pinned === true, - lastActiveAt: activeEditor.lastActiveAt || 0, - assetId: activeEditor.assetId || '', - path: activeEditor.path || '' - }; - } - - function pageAiCloneJson(value) { - if (value == null) return null; - try { - return JSON.parse(JSON.stringify(value)); - } catch (_) { - return null; - } - } - function pageAiNormalizeAgentId(agentId) { var value = String(agentId || '').trim(); return PAGE_AI_AGENT_REGISTRY.some(function(agent) { return agent.id === value; }) ? value : 'reasonix'; @@ -301,6 +298,128 @@ export function createSidebarPageAiRuntime(context) { return 'reasonix'; } + const pageAiProfileRuntime = createSidebarPageAiProfileRuntime({ + chatOnlyProfileRegistry: PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY, + documentRef: document, + pageAiAgentRecord, + pageAiCurrentAgentId, + pageAiNormalizeAgentId, + pageUiState, + }); + const pageAiProviderLabel = (...args) => pageAiProfileRuntime.pageAiProviderLabel(...args); + const pageAiNormalizeArray = (...args) => pageAiProfileRuntime.pageAiNormalizeArray(...args); + const pageAiDefaultAcpRuntimes = (...args) => pageAiProfileRuntime.pageAiDefaultAcpRuntimes(...args); + const pageAiNormalizeAcpRuntimes = (...args) => pageAiProfileRuntime.pageAiNormalizeAcpRuntimes(...args); + const pageAiUnwrapUpstream = (...args) => pageAiProfileRuntime.pageAiUnwrapUpstream(...args); + const pageAiProfileValue = (...args) => pageAiProfileRuntime.pageAiProfileValue(...args); + const pageAiCurrentProfile = (...args) => pageAiProfileRuntime.pageAiCurrentProfile(...args); + const pageAiRunProfile = (...args) => pageAiProfileRuntime.pageAiRunProfile(...args); + const pageAiMnoteToolModel = (...args) => pageAiProfileRuntime.pageAiMnoteToolModel(...args); + const pageAiCurrentProfileRecord = (...args) => pageAiProfileRuntime.pageAiCurrentProfileRecord(...args); + const pageAiChatOnlyProfileSpec = (...args) => pageAiProfileRuntime.pageAiChatOnlyProfileSpec(...args); + const pageAiDefaultChatOnlyProfileSpec = (...args) => pageAiProfileRuntime.pageAiDefaultChatOnlyProfileSpec(...args); + const pageAiNormalizeChatOnlyProfileId = (...args) => pageAiProfileRuntime.pageAiNormalizeChatOnlyProfileId(...args); + const pageAiProfileDisplayLabel = (...args) => pageAiProfileRuntime.pageAiProfileDisplayLabel(...args); + const pageAiProfileRecordById = (...args) => pageAiProfileRuntime.pageAiProfileRecordById(...args); + const pageAiSessionAgentFilterValue = (...args) => pageAiProfileRuntime.pageAiSessionAgentFilterValue(...args); + const pageAiSessionAgentLabel = (...args) => pageAiProfileRuntime.pageAiSessionAgentLabel(...args); + const pageAiSessionPreviewText = (...args) => pageAiProfileRuntime.pageAiSessionPreviewText(...args); + const pageAiSessionAgentFilterOptions = (...args) => pageAiProfileRuntime.pageAiSessionAgentFilterOptions(...args); + const pageAiFilteredHistoryRows = (...args) => pageAiProfileRuntime.pageAiFilteredHistoryRows(...args); + const pageAiTimestamp = (...args) => pageAiProfileRuntime.pageAiTimestamp(...args); + const pageAiUsageSummary = (...args) => pageAiProfileRuntime.pageAiUsageSummary(...args); + const pageAiPermissionRuntime = createSidebarPageAiPermissionRuntime({ + documentRef: document, + pageAiPreviewValue, + pageUiState, + renderPageAiConversation, + }); + const pageAiPermissionMessage = (...args) => pageAiPermissionRuntime.pageAiPermissionMessage(...args); + const pageAiApplyPermissionEvent = (...args) => pageAiPermissionRuntime.pageAiApplyPermissionEvent(...args); + const pageAiResolvePermission = (...args) => pageAiPermissionRuntime.pageAiResolvePermission(...args); + const pageAiHidePermissionDialog = (...args) => pageAiPermissionRuntime.pageAiHidePermissionDialog(...args); + const pageAiShowPermissionDialog = (...args) => pageAiPermissionRuntime.pageAiShowPermissionDialog(...args); + const pageAiSessionRuntime = createSidebarPageAiSessionRuntime({ + currentDocumentId, + currentRootUri, + currentSourceKind, + documentRef: document, + pageAiApplyRuntimeState, + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiErrorMessage, + pageAiNormalizeAgentId, + pageAiNormalizeArray, + pageAiNormalizeChatOnlyProfileId, + pageAiPermissionMessage, + pageAiPreviewValue, + pageAiRunProfile, + pageAiSetActiveProfile, + pageAiTimestamp, + pageUiState, + renderPageAiControls, + renderPageAiConversation, + resolveWorkspaceId, + sessionStorageVersion: PAGE_AI_SESSION_STORAGE_VERSION, + windowRef: window, + }); + const pageAiStorageKey = (...args) => pageAiSessionRuntime.pageAiStorageKey(...args); + const pageAiBackendSessionQuery = (...args) => pageAiSessionRuntime.pageAiBackendSessionQuery(...args); + const pageAiNewSession = (...args) => pageAiSessionRuntime.pageAiNewSession(...args); + const pageAiNormalizeSessions = (...args) => pageAiSessionRuntime.pageAiNormalizeSessions(...args); + const pageAiNormalizeBackendSessionRow = (...args) => pageAiSessionRuntime.pageAiNormalizeBackendSessionRow(...args); + const pageAiMergeSessions = (...args) => pageAiSessionRuntime.pageAiMergeSessions(...args); + const pageAiSessionStorageLabel = (...args) => pageAiSessionRuntime.pageAiSessionStorageLabel(...args); + const pageAiLoadSessions = (...args) => pageAiSessionRuntime.pageAiLoadSessions(...args); + const pageAiLoadBackendSessions = (...args) => pageAiSessionRuntime.pageAiLoadBackendSessions(...args); + const pageAiMessageFromRuntimeEvent = (...args) => pageAiSessionRuntime.pageAiMessageFromRuntimeEvent(...args); + const pageAiApplyBackendSessionDetail = (...args) => pageAiSessionRuntime.pageAiApplyBackendSessionDetail(...args); + const pageAiLoadBackendSessionDetail = (...args) => pageAiSessionRuntime.pageAiLoadBackendSessionDetail(...args); + const pageAiSearchBackendSessions = (...args) => pageAiSessionRuntime.pageAiSearchBackendSessions(...args); + const pageAiPersistSessions = (...args) => pageAiSessionRuntime.pageAiPersistSessions(...args); + const pageAiEnsureHermesSession = (...args) => pageAiSessionRuntime.pageAiEnsureHermesSession(...args); + const pageAiRestoreHermesSession = (...args) => pageAiSessionRuntime.pageAiRestoreHermesSession(...args); + const pageAiCurrentSession = (...args) => pageAiSessionRuntime.pageAiCurrentSession(...args); + const pageAiSyncCurrentSessionMessages = (...args) => pageAiSessionRuntime.pageAiSyncCurrentSessionMessages(...args); + const pageAiSetActiveSession = (...args) => pageAiSessionRuntime.pageAiSetActiveSession(...args); + const pageAiStartNewSession = (...args) => pageAiSessionRuntime.pageAiStartNewSession(...args); + const pageAiRenameBackendSession = (...args) => pageAiSessionRuntime.pageAiRenameBackendSession(...args); + const pageAiDeleteBackendSession = (...args) => pageAiSessionRuntime.pageAiDeleteBackendSession(...args); + const pageAiResumeBackendSession = (...args) => pageAiSessionRuntime.pageAiResumeBackendSession(...args); + const pageAiSkillRuntime = createSidebarPageAiSkillRuntime({ + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiLoadSkills, + pageAiNormalizeArray, + pageAiPersistAiPreference, + pageAiPersistRawAiPreference, + pageAiProfileValue, + pageUiState, + renderPageAiControls, + }); + const pageAiSkillSourceOptions = (...args) => pageAiSkillRuntime.pageAiSkillSourceOptions(...args); + const pageAiDefaultSkillSource = (...args) => pageAiSkillRuntime.pageAiDefaultSkillSource(...args); + const pageAiNormalizeSkillSource = (...args) => pageAiSkillRuntime.pageAiNormalizeSkillSource(...args); + const pageAiCurrentSkillSource = (...args) => pageAiSkillRuntime.pageAiCurrentSkillSource(...args); + const pageAiSetSkillSource = (...args) => pageAiSkillRuntime.pageAiSetSkillSource(...args); + const pageAiSkillSourceParts = (...args) => pageAiSkillRuntime.pageAiSkillSourceParts(...args); + const pageAiCurrentSkillSourceLabel = (...args) => pageAiSkillRuntime.pageAiCurrentSkillSourceLabel(...args); + const pageAiSkillOriginLabel = (...args) => pageAiSkillRuntime.pageAiSkillOriginLabel(...args); + const pageAiSkillPreferenceKey = (...args) => pageAiSkillRuntime.pageAiSkillPreferenceKey(...args); + const pageAiSkillPreferenceTable = (...args) => pageAiSkillRuntime.pageAiSkillPreferenceTable(...args); + const pageAiHermesHideBuiltinPreferenceKey = (...args) => pageAiSkillRuntime.pageAiHermesHideBuiltinPreferenceKey(...args); + const pageAiHideHermesBuiltinSkills = (...args) => pageAiSkillRuntime.pageAiHideHermesBuiltinSkills(...args); + const pageAiReasonixMemoryEnabled = (...args) => pageAiSkillRuntime.pageAiReasonixMemoryEnabled(...args); + const pageAiSetReasonixMemoryEnabled = (...args) => pageAiSkillRuntime.pageAiSetReasonixMemoryEnabled(...args); + const pageAiSetHideHermesBuiltinSkills = (...args) => pageAiSkillRuntime.pageAiSetHideHermesBuiltinSkills(...args); + const pageAiSkillIsBuiltin = (...args) => pageAiSkillRuntime.pageAiSkillIsBuiltin(...args); + const pageAiToggleableSkillEntries = (...args) => pageAiSkillRuntime.pageAiToggleableSkillEntries(...args); + const pageAiAllSkillEntries = (...args) => pageAiSkillRuntime.pageAiAllSkillEntries(...args); + const pageAiSkillGroupCollapsed = (...args) => pageAiSkillRuntime.pageAiSkillGroupCollapsed(...args); + const pageAiToggleSkillGroup = (...args) => pageAiSkillRuntime.pageAiToggleSkillGroup(...args); + const pageAiSetSkillPreference = (...args) => pageAiSkillRuntime.pageAiSetSkillPreference(...args); + const pageAiSkillEnabled = (...args) => pageAiSkillRuntime.pageAiSkillEnabled(...args); + function pageAiEnsureContextRefState() { if (!pageUiState.pageAiSelectedContextRefs || typeof pageUiState.pageAiSelectedContextRefs !== 'object') { pageUiState.pageAiSelectedContextRefs = { @@ -315,6 +434,104 @@ export function createSidebarPageAiRuntime(context) { return pageUiState.pageAiSelectedContextRefs; } + const pageAiTargetRuntime = createSidebarPageAiTargetRuntime({ + currentDocumentId, + currentPageOptions, + currentRootUri, + currentSourceKind, + documentRef: document, + escapeHtml, + pageAiEnsureContextRefState, + pageAiNormalizeArray, + pageUiState, + resolveWorkspaceId, + searchText, + }); + const currentPageAiOpenEditorsSnapshot = (...args) => pageAiTargetRuntime.currentPageAiOpenEditorsSnapshot(...args); + const currentPageAiEditorTarget = (...args) => pageAiTargetRuntime.currentPageAiEditorTarget(...args); + const currentPageAiPageEditorTarget = (...args) => pageAiTargetRuntime.currentPageAiPageEditorTarget(...args); + const currentPageAiScopedEditorTarget = (...args) => pageAiTargetRuntime.currentPageAiScopedEditorTarget(...args); + const pageAiCloneJson = (...args) => pageAiTargetRuntime.pageAiCloneJson(...args); + const pageAiEditorTargetCandidates = (...args) => pageAiTargetRuntime.pageAiEditorTargetCandidates(...args); + const pageAiFallbackEditorTarget = (...args) => pageAiTargetRuntime.pageAiFallbackEditorTarget(...args); + const pageAiResourceKindForTarget = (...args) => pageAiTargetRuntime.pageAiResourceKindForTarget(...args); + const pageAiTargetFromOpenEditor = (...args) => pageAiTargetRuntime.pageAiTargetFromOpenEditor(...args); + const pageAiTargetId = (...args) => pageAiTargetRuntime.pageAiTargetId(...args); + const localMarkdownRelativePathFromPageAiDocumentId = (...args) => pageAiTargetRuntime.localMarkdownRelativePathFromPageAiDocumentId(...args); + const localMarkdownDocumentIdFromPageAiRelativePath = (...args) => pageAiTargetRuntime.localMarkdownDocumentIdFromPageAiRelativePath(...args); + const pageAiWorkspacePathForDocument = (...args) => pageAiTargetRuntime.pageAiWorkspacePathForDocument(...args); + const pageAiWorkspacePathForTarget = (...args) => pageAiTargetRuntime.pageAiWorkspacePathForTarget(...args); + const pageAiBuildAllowedRoots = (...args) => pageAiTargetRuntime.pageAiBuildAllowedRoots(...args); + const pageAiBuildContextRefs = (...args) => pageAiTargetRuntime.pageAiBuildContextRefs(...args); + const pageAiBuildRunTargetSnapshot = (...args) => pageAiTargetRuntime.pageAiBuildRunTargetSnapshot(...args); + const pageAiPageContextForRefs = (...args) => pageAiTargetRuntime.pageAiPageContextForRefs(...args); + const pageAiSetRunTargetSnapshot = (...args) => pageAiTargetRuntime.pageAiSetRunTargetSnapshot(...args); + const assertPageAiTargetInCurrentWorkspace = (...args) => pageAiTargetRuntime.assertPageAiTargetInCurrentWorkspace(...args); + const pageAiBuildAgentTargetPackage = (...args) => pageAiTargetRuntime.pageAiBuildAgentTargetPackage(...args); + const pageAiBlockingDirtyState = (...args) => pageAiTargetRuntime.pageAiBlockingDirtyState(...args); + const fetchPageAiTargetBufferState = (...args) => pageAiTargetRuntime.fetchPageAiTargetBufferState(...args); + const assertPageAiTargetWritable = (...args) => pageAiTargetRuntime.assertPageAiTargetWritable(...args); + const currentPageAiSelectedText = (...args) => pageAiTargetRuntime.currentPageAiSelectedText(...args); + const pageAiProjectionBlocks = (...args) => pageAiTargetRuntime.pageAiProjectionBlocks(...args); + const pageAiBlockText = (...args) => pageAiTargetRuntime.pageAiBlockText(...args); + const pageAiSelectedBlockIdsFromSelection = (...args) => pageAiTargetRuntime.pageAiSelectedBlockIdsFromSelection(...args); + const pageAiBlocksToPageXml = (...args) => pageAiTargetRuntime.pageAiBlocksToPageXml(...args); + const buildPageAiContext = (...args) => pageAiTargetRuntime.buildPageAiContext(...args); + const pageAiScopedPageContext = (...args) => pageAiTargetRuntime.pageAiScopedPageContext(...args); + pageAiRenderRuntime = createSidebarPageAiRenderRuntime({ + contextRefRegistry: PAGE_AI_CONTEXT_REF_REGISTRY, + cssEscape, + currentDocumentId, + currentPageAiEditorTarget, + currentPageAiSelectedText, + documentRef: document, + escapeHtml, + localMarkdownRelativePathFromPageAiDocumentId, + pageAiAgentRecord, + pageAiAllSkillEntries, + pageAiBuildAllowedRoots, + pageAiChatOnlyProfileEntries, + pageAiChatOnlyProfileSpec, + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiCurrentProfileRecord, + pageAiCurrentSession, + pageAiCurrentSkillSource, + pageAiCurrentSkillSourceLabel, + pageAiDefaultChatOnlyProfileSpec, + pageAiEditorTargetCandidates, + pageAiEnsureContextRefState, + pageAiFilteredHistoryRows, + pageAiHermesProfileEntries, + pageAiHermesSettingsUrl, + pageAiHideHermesBuiltinSkills, + pageAiMnoteToolModel, + pageAiNormalizeAcpRuntimes, + pageAiNormalizeArray, + pageAiNormalizeSkillSource, + pageAiProfileDisplayLabel, + pageAiProfileValue, + pageAiProviderLabel, + pageAiReasonixMemoryEnabled, + pageAiRunProfile, + pageAiSessionAgentFilterOptions, + pageAiSessionAgentFilterValue, + pageAiSessionAgentLabel, + pageAiSessionPreviewText, + pageAiSessionStorageLabel, + pageAiSkillEnabled, + pageAiSkillGroupCollapsed, + pageAiSkillListEntries, + pageAiSkillOriginLabel, + pageAiSkillSourceOptions, + pageAiSkillSourceParts, + pageAiToggleableSkillEntries, + pageAiUsageSummary, + pageUiState, + renderPageAiMarkdown, + searchText, + }); + function pageAiSetAgentId(agentId) { var next = pageAiNormalizeAgentId(agentId); var record = pageAiAgentRecord(next); @@ -322,6 +539,7 @@ export function createSidebarPageAiRuntime(context) { pageUiState.pageAiAcpRuntime = record.acpRuntime || 'reasonix'; pageUiState.pageAiAgentPopoverOpen = next === 'hermes'; if (next === 'hermes') pageAiSetActiveProfile(pageAiCurrentProfile()); + if (next === 'chat_only') pageAiSetActiveProfile(pageAiNormalizeChatOnlyProfileId(pageAiCurrentProfile())); document.documentElement.setAttribute('data-mnote-page-ai-agent-id', next); pageAiPersistAiPreference('default_agent_id', next); void pageAiLoadSkills(); @@ -341,55 +559,42 @@ export function createSidebarPageAiRuntime(context) { function pageAiSetContextPopoverOpen(open) { pageUiState.pageAiContextPopoverOpen = Boolean(open); - if (open) pageUiState.pageAiAgentPopoverOpen = false; + if (open) { + pageUiState.pageAiAgentPopoverOpen = false; + pageUiState.pageAiTargetPopoverOpen = false; + } renderPageAiControls(); } function pageAiSetAgentPopoverOpen(open) { pageUiState.pageAiAgentPopoverOpen = Boolean(open); - if (open) pageUiState.pageAiContextPopoverOpen = false; + if (open) { + pageUiState.pageAiContextPopoverOpen = false; + pageUiState.pageAiTargetPopoverOpen = false; + } renderPageAiControls(); } - function pageAiContextRefLabel(kind) { - var record = PAGE_AI_CONTEXT_REF_REGISTRY.find(function(ref) { return ref.id === kind; }); - return record ? record.label : kind; - } - - function pageAiContextButtonSummary() { - var selected = pageAiEnsureContextRefState(); - var labels = PAGE_AI_CONTEXT_REF_REGISTRY - .filter(function(ref) { return selected[ref.id] === true; }) - .map(function(ref) { return ref.label; }); - if (!labels.length) return '选择上下文'; - var head = labels.slice(0, 2).join(' + '); - return labels.length > 2 ? head + ' +' + String(labels.length - 2) : head; - } - - function pageAiContextRefDetail(kind) { - var documentId = currentDocumentId(); - var relativePath = localMarkdownRelativePathFromPageAiDocumentId(documentId); - if (kind === 'current_page') return relativePath || documentId || '当前页面'; - if (kind === 'selection') return currentPageAiSelectedText() ? '当前选区可用' : '当前没有选区'; - if (kind === 'active_editor') { - var target = currentPageAiEditorTarget(); - return String(target && (target.title || target.documentId) || relativePath || '当前打开资源'); + function pageAiSetTargetPopoverOpen(open) { + pageUiState.pageAiTargetPopoverOpen = Boolean(open); + if (open) { + pageUiState.pageAiAgentPopoverOpen = false; + pageUiState.pageAiContextPopoverOpen = false; } - if (kind === 'file') return relativePath || '当前文件'; - if (kind === 'folder') { - var roots = pageAiBuildAllowedRoots(); - if (!roots.length) return '需要授权后可用'; - return roots.map(function(root) { return root.rootUri.replace(/^file:\/\//, ''); }).filter(Boolean)[0] || '已授权文件夹'; - } - if (kind === 'changed_files') return '本次 run 后可用于追问'; - return ''; + renderPageAiControls(); } - function pageAiContextRefDisabled(kind) { - if (kind === 'selection') return !currentPageAiSelectedText(); - return false; + function pageAiSelectTarget(targetId) { + var normalized = String(targetId || '').trim(); + var candidates = pageAiEditorTargetCandidates(); + var target = candidates.find(function(candidate) { return candidate.targetId === normalized; }) || null; + if (!target) return; + pageUiState.pageAiSelectedTargetId = target.targetId; + pageUiState.pageAiTargetPopoverOpen = false; + renderPageAiControls(); } + function pageAiPersistAiPreference(key, value) { pageAiPersistRawAiPreference('ai.common.' + key, value); } @@ -435,6 +640,8 @@ export function createSidebarPageAiRuntime(context) { } var hermesProfile = String(preferences['ai.agent.hermes.profile_id'] || '').trim(); if (hermesProfile) pageAiSetActiveProfile(hermesProfile); + var skillSource = String(preferences['ai.common.skills.active_source'] || '').trim(); + if (skillSource) pageUiState.pageAiActiveSkillSource = skillSource; var selected = preferences['ai.common.context_refs.default_selected']; if (selected && typeof selected === 'object' && !Array.isArray(selected)) { pageUiState.pageAiSelectedContextRefs = Object.assign({}, pageAiEnsureContextRefState(), selected); @@ -490,340 +697,6 @@ export function createSidebarPageAiRuntime(context) { return pageUiState.pageAiAllowedRoots; } - function pageAiBuildContextRefs(scopedContext, runTargetSnapshot) { - var selected = pageAiEnsureContextRefState(); - var refs = []; - var documentId = currentDocumentId(); - var rootUri = currentRootUri(); - var workspaceId = resolveWorkspaceId(document.body); - var editorTarget = scopedContext && scopedContext.editorTarget ? scopedContext.editorTarget : currentPageAiEditorTarget(); - if (selected.current_page) { - refs.push({ - kind: 'current_page', - documentId: documentId, - rootUri: rootUri, - workspaceId: workspaceId - }); - } - if (selected.selection && scopedContext && scopedContext.selectedText) { - refs.push({ - kind: 'selection', - documentId: documentId, - rootUri: rootUri, - selectedBlockId: scopedContext.selectedBlockId || '' - }); - } - if (selected.active_editor && editorTarget) { - refs.push({ - kind: 'active_editor', - documentId: editorTarget.documentId || documentId, - rootUri: editorTarget.workspacePath && editorTarget.workspacePath.rootUri || rootUri, - relativePath: editorTarget.workspacePath && editorTarget.workspacePath.relativePath || '', - editorKind: editorTarget.editorKind || '' - }); - } - if (selected.file) { - refs.push({ - kind: 'file', - documentId: documentId, - rootUri: rootUri, - relativePath: localMarkdownRelativePathFromPageAiDocumentId(documentId) - }); - } - if (selected.folder) { - refs.push({ - kind: 'folder', - rootUri: rootUri, - relativePath: '' - }); - } - if (selected.changed_files) { - refs.push({ - kind: 'changed_files', - rootUri: rootUri, - sinceRunTargetSnapshot: runTargetSnapshot && runTargetSnapshot.frozenAt || null - }); - } - return refs.filter(function(ref) { - return ref && String(ref.kind || '').trim(); - }); - } - - function pageAiBuildAllowedRoots() { - return pageAiNormalizeArray(pageUiState.pageAiAllowedRoots).map(function(root) { - return { - rootUri: root.rootUri, - permission: root.permission === 'write' || root.permission === 'read_write' ? 'write' : 'read', - recursive: root.recursive !== false, - source: root.source === 'auto' || root.source === 'user' || root.source === 'admin' - ? 'sqlite_directory_grant' - : (root.source || 'sqlite_directory_grant'), - grantId: root.id || '' - }; - }); - } - - function pageAiBuildRunTargetSnapshot(scopedContext, prompt) { - var aiContext = scopedContext && scopedContext.pageContext && scopedContext.pageContext.aiContext - ? scopedContext.pageContext.aiContext - : {}; - var editorTarget = scopedContext && scopedContext.editorTarget ? scopedContext.editorTarget : currentPageAiEditorTarget(); - return { - schema: 'mnote.page_ai_run_target_snapshot.v1', - source: 'open_editors_snapshot', - frozenAt: Date.now(), - workspaceId: resolveWorkspaceId(document.body), - documentId: currentDocumentId(), - sourceKind: currentSourceKind(), - rootUri: currentRootUri(), - contextScope: pageUiState.pageAiContextScope || 'page', - promptPreview: searchText(prompt || '').slice(0, 160), - editorTarget: pageAiCloneJson(editorTarget), - activeEditorTarget: pageAiCloneJson(aiContext.activeEditorTarget || editorTarget), - openEditorsSnapshot: pageAiCloneJson(aiContext.openEditorsSnapshot || currentPageAiOpenEditorsSnapshot()) - }; - } - - function pageAiContextKindsFromRefs(contextRefs) { - var kinds = {}; - pageAiNormalizeArray(contextRefs).forEach(function(ref) { - var kind = String(ref && ref.kind || '').trim(); - if (kind) kinds[kind] = true; - }); - return kinds; - } - - function pageAiPageContextForRefs(pageContext, contextRefs) { - var cloned = pageAiCloneJson(pageContext) || {}; - var aiContext = cloned.aiContext && typeof cloned.aiContext === 'object' ? cloned.aiContext : {}; - delete cloned.documentBlocks; - delete cloned.evidence; - delete aiContext.contextBlocks; - delete aiContext.pageText; - delete aiContext.pageXml; - delete aiContext.truncated; - delete aiContext.warnings; - delete aiContext.selectedText; - delete aiContext.selectedBlockIds; - delete aiContext.selectedBlocks; - delete aiContext.allowedTargetBlockIds; - cloned.aiContext = aiContext; - return cloned; - } - - function pageAiSetRunTargetSnapshot(snapshot) { - pageUiState.pageAiCurrentRunTargetSnapshot = snapshot || null; - var target = snapshot && snapshot.editorTarget ? snapshot.editorTarget : null; - var documentId = String(target && target.documentId || snapshot && snapshot.documentId || '').trim(); - var workspaceId = String(target && target.workspaceId || snapshot && snapshot.workspaceId || '').trim(); - var rootUri = String(target && target.workspacePath && target.workspacePath.rootUri || snapshot && snapshot.rootUri || '').trim(); - if (documentId) document.documentElement.setAttribute('data-mnote-page-ai-run-target-document-id', documentId); - if (workspaceId) document.documentElement.setAttribute('data-mnote-page-ai-run-target-workspace-id', workspaceId); - if (rootUri) document.documentElement.setAttribute('data-mnote-page-ai-run-target-root-uri', rootUri); - } - - function assertPageAiTargetInCurrentWorkspace(editorTarget) { - var target = editorTarget && typeof editorTarget === 'object' ? editorTarget : {}; - var workspacePath = target.workspacePath && typeof target.workspacePath === 'object' ? target.workspacePath : {}; - var targetSourceKind = String(workspacePath.sourceKind || '').trim(); - var currentKind = String(currentSourceKind() || '').trim(); - if (targetSourceKind && currentKind && targetSourceKind !== currentKind) { - var sourceError = new Error('AI target 与当前页面 sourceKind 不一致,请重新选择当前工作区内的目标。'); - sourceError.code = 'page_ai_target_workspace_mismatch'; - throw sourceError; - } - var targetRootUri = String(workspacePath.rootUri || '').trim(); - var currentRoot = String(currentRootUri() || '').trim(); - if (targetRootUri && currentRoot && targetRootUri !== currentRoot) { - var rootError = new Error('AI target 与当前本地工作区 rootUri 不一致,请重新选择当前工作区内的目标。'); - rootError.code = 'page_ai_target_workspace_mismatch'; - throw rootError; - } - var targetWorkspaceId = String(target.workspaceId || workspacePath.workspaceId || '').trim(); - var currentWorkspaceId = String(resolveWorkspaceId(document.body) || '').trim(); - if (targetWorkspaceId && currentWorkspaceId && targetWorkspaceId !== currentWorkspaceId) { - var workspaceError = new Error('AI target 与当前 workspaceId 不一致,请重新选择当前工作区内的目标。'); - workspaceError.code = 'page_ai_target_workspace_mismatch'; - throw workspaceError; - } - } - - function localMarkdownRelativePathFromPageAiDocumentId(documentId) { - var value = String(documentId || '').trim(); - if (!value.startsWith('local-md:')) return ''; - return value.slice('local-md:'.length).replace(/~2F/g, '/'); - } - - function pageAiBlockingDirtyState(dirtyState) { - var state = String(dirtyState || '').trim(); - var normalized = state.toLowerCase(); - if (normalized === 'dirty') return 'Dirty'; - if (normalized === 'stale') return 'Stale'; - if (normalized === 'deleted') return 'Deleted'; - if (normalized === 'externalmodified' || normalized === 'external-change-conflict' || normalized === 'hasexternalconflict') return 'ExternalModified'; - return ''; - } - - async function fetchPageAiTargetBufferState(editorTarget) { - if (currentSourceKind() !== 'local_folder') return null; - var target = editorTarget && typeof editorTarget === 'object' ? editorTarget : {}; - var documentId = String(target.documentId || currentDocumentId() || '').trim(); - var rootUri = String(target.workspacePath && target.workspacePath.rootUri || currentRootUri() || '').trim(); - if (!documentId || !rootUri) return null; - var relativePath = String(target.workspacePath && target.workspacePath.relativePath || '').trim() - || localMarkdownRelativePathFromPageAiDocumentId(documentId); - var url = new URL('/api/documents/buffer-state', window.location.origin); - url.searchParams.set('documentId', documentId); - url.searchParams.set('sourceKind', 'local_folder'); - url.searchParams.set('rootUri', rootUri); - var workspaceId = String(target.workspaceId || resolveWorkspaceId(document.body) || '').trim(); - if (workspaceId) url.searchParams.set('workspaceId', workspaceId); - if (relativePath) url.searchParams.set('relativePath', relativePath); - try { - var response = await fetch(url.toString(), { cache: 'no-store', headers: { accept: 'application/json' } }); - var payload = await response.json().catch(function() { return null; }); - if (!response.ok || !payload || payload.ok !== true) return null; - return payload.result || null; - } catch (_) { - return null; - } - } - - async function assertPageAiTargetWritable(editorTarget) { - var snapshotState = pageAiBlockingDirtyState(editorTarget && editorTarget.dirtyState); - var bufferState = await fetchPageAiTargetBufferState(editorTarget); - var bufferDirtyState = pageAiBlockingDirtyState(bufferState && bufferState.dirtyState); - var blockedState = bufferDirtyState || snapshotState; - if (!blockedState) return bufferState; - var documentId = String(editorTarget && editorTarget.documentId || currentDocumentId() || '').trim(); - var error = new Error('目标文档存在未保存或外部变更状态(' + blockedState + '),请先保存、解决冲突或刷新后再让 AI 写入。'); - error.code = 'page_ai_target_buffer_not_writable'; - error.documentId = documentId; - error.dirtyState = blockedState; - throw error; - } - - function currentPageAiSelectedText() { - try { - var selection = window.getSelection ? window.getSelection() : null; - return selection ? searchText(selection.toString() || '') : ''; - } catch (_) { - return ''; - } - } - - function pageAiProjectionBlocks(aggregate) { - var blocks = aggregate && aggregate.body && aggregate.body.blockDocument && aggregate.body.blockDocument.blocks; - return Array.isArray(blocks) ? blocks : []; - } - - function pageAiBlockText(block) { - return searchText(block && (block.text || block.title || block.content) || ''); - } - - function pageAiSelectedBlockIdsFromSelection() { - try { - var selection = window.getSelection ? window.getSelection() : null; - if (!selection || selection.rangeCount === 0 || searchText(selection.toString() || '') === '') return []; - var range = selection.getRangeAt(0); - var editor = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"] .editor-surface .ProseMirror'); - if (!(editor instanceof HTMLElement)) return []; - return Array.from(editor.children).filter(function(node) { - if (!(node instanceof HTMLElement)) return false; - try { - return range.intersectsNode(node); - } catch (_) { - return false; - } - }).map(function(node) { - return searchText(node.getAttribute('data-id') || node.id || ''); - }).filter(Boolean); - } catch (_) { - return []; - } - } - - function pageAiBlocksToPageXml(blocks, aggregate) { - var revision = aggregate && aggregate.body ? String(aggregate.body.revision || '') : ''; - var pageId = currentDocumentId() || 'current-page'; - var lines = ['']; - blocks.forEach(function(block) { - var blockId = String(block && (block.blockId || block.id) || ''); - var type = String(block && block.type || 'paragraph'); - var revisionRef = String(block && block.revisionRef || ''); - var level = block && block.attrs && block.attrs.level ? ' level="' + escapeHtml(block.attrs.level) + '"' : ''; - lines.push(' ' + escapeHtml(pageAiBlockText(block)) + ''); - }); - lines.push(''); - return lines.join('\n'); - } - - function buildPageAiContext(contextSnapshot, scope, selectedText) { - var aggregate = contextSnapshot.aggregate || {}; - var body = aggregate.body || {}; - var allBlocks = pageAiProjectionBlocks(aggregate); - var selectedBlockIds = scope === 'selection' ? pageAiSelectedBlockIdsFromSelection() : []; - var selectedSet = {}; - selectedBlockIds.forEach(function(id) { selectedSet[id] = true; }); - var selectedBlocks = selectedBlockIds.length - ? allBlocks.filter(function(block) { return selectedSet[String(block.blockId || block.id || '')]; }) - : []; - var contextBlocks = selectedBlocks.length ? selectedBlocks : allBlocks.slice(0, 120); - var truncated = !selectedBlocks.length && allBlocks.length > contextBlocks.length; - return { - schema: 'mnote.page_ai_context.v1', - workspaceId: resolveWorkspaceId(document.body), - documentId: currentDocumentId(), - activeEditorTarget: currentPageAiEditorTarget(), - openEditorsSnapshot: currentPageAiOpenEditorsSnapshot(), - scope: scope, - revision: body.revision || null, - conflictDetectionKey: body.conflictDetectionKey || null, - selectedText: selectedText || '', - selectedBlockIds: selectedBlockIds, - allowedTargetBlockIds: selectedBlockIds, - selectedBlocks: selectedBlocks, - contextBlocks: contextBlocks, - pageText: contextBlocks.map(pageAiBlockText).filter(Boolean).join('\n'), - pageXml: pageAiBlocksToPageXml(contextBlocks, aggregate), - truncated: truncated, - warnings: truncated ? [{ code: 'page_ai_context_truncated', message: '页面 AI context 已按前 120 个块裁剪' }] : [] - }; - } - - function pageAiScopedPageContext(contextSnapshot) { - var aggregate = contextSnapshot.aggregate || {}; - var body = contextSnapshot.body || {}; - var subtree = contextSnapshot.subtree || null; - var outline = subtree && subtree.outline ? subtree.outline : null; - var scope = pageUiState.pageAiContextScope || 'page'; - var title = aggregate.head && aggregate.head.title ? aggregate.head.title : ''; - var selectedText = scope === 'selection' ? currentPageAiSelectedText() : ''; - var aiContext = buildPageAiContext(contextSnapshot, scope, selectedText); - var editorTarget = aiContext.activeEditorTarget || currentPageAiEditorTarget(); - return { - pageContext: { - contextScope: scope, - documentBlocks: null, - node: { - documentId: currentDocumentId(), - title: title - }, - subtree: null, - outline: null, - pageSubtreeSource: scope === 'page' ? (contextSnapshot.pageSubtreeSource || 'none') : 'scope:' + scope, - evidence: selectedText ? [{ kind: 'selection', text: selectedText }] : null, - pageOptions: scope === 'options' || scope === 'page' ? currentPageOptions() : null, - contentAccess: 'mnote.context.read_current_page', - aiContext: aiContext - }, - editorTarget: editorTarget, - selectedText: selectedText, - selectedBlockId: aiContext.selectedBlockIds[0] || null - }; - } - - function updatePageAiTriggerState() { var trigger = document.querySelector('[data-testid="wolai-floating-ai"]'); if (!(trigger instanceof HTMLElement)) return; @@ -832,150 +705,6 @@ export function createSidebarPageAiRuntime(context) { } - function pageAiSuggestions() { - var title = searchText(document.querySelector('[data-page-title-current="true"]')?.textContent) || '当前页面'; - return [ - '帮我总结《' + title + '》当前内容', - '把当前页面改写得更简洁一些', - '提炼当前页的关键待办和行动项', - '基于当前页内容生成一个三段式摘要' - ]; - } - - function pageAiStorageKey() { - return 'hermes_page_ai_session:' + currentDocumentId(); - } - - function pageAiTimestamp(value) { - if (typeof value === 'number' && Number.isFinite(value)) return value; - if (typeof value === 'string' && value.trim()) { - var parsed = Date.parse(value); - if (Number.isFinite(parsed)) return parsed; - } - return Date.now(); - } - - function pageAiBackendSessionQuery(extra) { - var params = new URLSearchParams(); - params.set('source', 'acp'); - params.set('workspaceId', resolveWorkspaceId(document.body)); - params.set('documentId', currentDocumentId()); - params.set('profile', pageAiRunProfile()); - params.set('sourceKind', currentSourceKind()); - if (currentRootUri()) params.set('rootUri', currentRootUri()); - Object.keys(extra || {}).forEach(function(key) { - var value = extra[key]; - if (value !== undefined && value !== null && String(value).trim() !== '') { - params.set(key, String(value)); - } - }); - return params.toString(); - } - - function pageAiNewSession(title) { - var now = Date.now(); - return { - id: 'sess_' + now + '_' + Math.random().toString(16).slice(2, 8), - title: title || '新会话', - profile: pageAiCurrentProfile(), - acpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', - createdAt: now, - updatedAt: now, - source: 'local', - usage: null, - status: 'idle', - messages: [] - }; - } - - function pageAiUsageSummary(usage) { - if (!usage || typeof usage !== 'object') return ''; - var used = usage.used ?? usage.contextUsed ?? usage.input_tokens ?? usage.inputTokens ?? usage.prompt_tokens ?? usage.promptTokens; - var size = usage.size ?? usage.contextSize ?? usage.total_tokens ?? usage.totalTokens; - var output = usage.output_tokens ?? usage.outputTokens ?? usage.completion_tokens ?? usage.completionTokens; - var parts = []; - if (Number.isFinite(Number(used))) parts.push('ctx ' + Number(used)); - if (Number.isFinite(Number(size)) && Number(size) > 0) parts.push('/ ' + Number(size)); - if (Number.isFinite(Number(output)) && Number(output) > 0) parts.push('out ' + Number(output)); - return parts.join(' ') || ''; - } - - function pageAiPermissionMessage(payload, eventType) { - payload = payload && typeof payload === 'object' ? payload : {}; - var permissionId = String(payload.permissionId || payload.permission_id || payload.id || ('perm_' + Date.now())).trim(); - var toolName = String(payload.toolName || payload.tool || payload.name || payload.method || 'session/request_permission').trim(); - var args = payload.arguments || payload.args || payload.input || payload.params || payload; - var decision = String(payload.decision || payload.result || '').trim(); - if (!decision && eventType === 'permission.denied') decision = 'denied'; - if (!decision && eventType === 'permission.allowed') decision = 'allowed'; - return { - role: 'tool', - kind: 'permission', - permissionId: permissionId, - toolName: toolName, - argsSummary: pageAiPreviewValue(args), - content: decision === 'denied' ? '已自动拒绝权限请求' : (decision === 'allowed' ? '已自动允许权限请求' : '等待权限确认'), - resolved: decision === 'denied' || decision === 'allowed', - decision: decision - }; - } - - function pageAiApplyPermissionEvent(eventName, payloadText) { - var payload = null; - try { - payload = JSON.parse(payloadText || 'null'); - } catch (_) { - payload = {}; - } - var message = pageAiPermissionMessage(payload, eventName); - var existing = pageUiState.pageAiMessages.find(function(item) { - return item.kind === 'permission' && item.permissionId === message.permissionId; - }); - if (existing) { - Object.assign(existing, message); - } else { - pageUiState.pageAiMessages.push(message); - } - pageUiState.pageAiPermissionRequests = pageUiState.pageAiPermissionRequests.filter(function(item) { - return item.permissionId !== message.permissionId; - }).concat([message]).slice(-20); - if (!message.resolved) { - pageAiShowPermissionDialog(message); - } else { - pageAiHidePermissionDialog(); - } - } - - function pageAiResolvePermission(permissionId, decision) { - permissionId = String(permissionId || '').trim(); - if (!permissionId) return; - // 调用后端 resolve-permission 端点,让 ACP agent 得到真实响应 - var runId = pageUiState.pageAiCurrentRunId; - if (runId) { - fetch('/api/hermes/client/runs/' + encodeURIComponent(runId) + '/resolve-permission', { - method: 'POST', - headers: { 'content-type': 'application/json' }, - body: JSON.stringify({ permissionId: permissionId, decision: decision }) - }).then(function(response) { - if (!response.ok) console.warn('resolve-permission 后端返回异常', response.status); - }).catch(function(err) { - console.warn('resolve-permission 请求失败', err); - }); - } else { - console.warn('resolve-permission: 无活跃 runId,只能本地更新'); - } - // 本地乐观更新 UI - pageUiState.pageAiMessages.forEach(function(item) { - if (item.kind === 'permission' && item.permissionId === permissionId) { - item.resolved = true; - item.decision = decision; - item.content = decision === 'allow' ? '已允许权限请求' : '已拒绝权限请求'; - } - }); - var dialog = document.querySelector('[data-page-ai-permission-dialog]'); - if (dialog instanceof HTMLElement) dialog.hidden = true; - renderPageAiConversation(); - } function pageAiOpenLocation(loc) { var path = String(loc || '').trim(); @@ -988,594 +717,56 @@ export function createSidebarPageAiRuntime(context) { }); } - function pageAiHidePermissionDialog() { - var dialog = document.querySelector('[data-page-ai-permission-dialog]'); - if (dialog instanceof HTMLElement) dialog.hidden = true; - } - - function pageAiShowPermissionDialog(message) { - if (!message || message.kind !== 'permission') return; - if (message.resolved) { - pageAiHidePermissionDialog(); - return; - } - var dialog = document.querySelector('[data-page-ai-permission-dialog]'); - if (!(dialog instanceof HTMLElement)) { - dialog = document.createElement('div'); - dialog.className = 'wolai-page-ai-permission-dialog'; - dialog.setAttribute('data-page-ai-permission-dialog', 'true'); - dialog.innerHTML = '' + - ''; - document.body.appendChild(dialog); - } - var tool = dialog.querySelector('[data-page-ai-permission-tool]'); - if (tool instanceof HTMLElement) tool.textContent = message.toolName || 'session/request_permission'; - var args = dialog.querySelector('[data-page-ai-permission-args]'); - if (args instanceof HTMLElement) args.textContent = message.argsSummary || message.content || ''; - dialog.querySelectorAll('[data-page-ai-permission-dialog-action]').forEach(function(button) { - if (button instanceof HTMLButtonElement) { - button.setAttribute('data-page-ai-permission-id', message.permissionId || ''); - button.disabled = Boolean(message.resolved); - } - }); - dialog.hidden = false; - } - - function pageAiNormalizeSessions(sessions) { - return (Array.isArray(sessions) ? sessions : []) - .slice(0, 20) - .map(function(session) { - var sessionStorage = String(session && (session.sessionStorage || session.session_storage) || '').trim(); - var persistence = String(session && session.persistence || '').trim(); - return { - id: String(session && session.id || '').trim() || pageAiNewSession().id, - title: String(session && session.title || '').trim() || '新会话', - profile: String(session && session.profile || pageAiCurrentProfile()).trim() || 'default', - acpRuntime: String(session && session.acpRuntime || 'reasonix').trim(), - createdAt: pageAiTimestamp(session && session.createdAt), - updatedAt: pageAiTimestamp(session && session.updatedAt), - source: String(session && session.source || 'local').trim() || 'local', - persistence: persistence, - sessionStorage: sessionStorage, - permissionLevel: String(session && (session.permissionLevel || session.permission_level) || '').trim(), - shareId: String(session && (session.shareId || session.share_id) || '').trim(), - runId: String(session && (session.runId || session.run_id) || '').trim(), - status: String(session && session.status || '').trim(), - usage: session && session.usage && typeof session.usage === 'object' ? session.usage : null, - preview: String(session && session.preview || '').trim(), - messages: Array.isArray(session && session.messages) ? session.messages.slice(-300) : [] - }; - }) - .sort(function(a, b) { - return Number(b.updatedAt || 0) - Number(a.updatedAt || 0); + function pageAiChatOnlyProfileEntries() { + var profiles = pageAiNormalizeArray(pageUiState.pageAiProfiles); + return PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY.map(function(spec) { + var profile = profiles.find(function(candidate) { + var candidateSpec = pageAiChatOnlyProfileSpec(candidate); + return candidateSpec && candidateSpec.profileId === spec.profileId; }); - } - - function pageAiNormalizeBackendSessionRow(row) { - if (!row || typeof row !== 'object') return null; - var payload = row.payload && typeof row.payload === 'object' ? row.payload : {}; - var sessionId = String(row.sessionId || row.session_id || '').trim(); - if (!sessionId) return null; - var title = String(row.title || payload.title || payload.message || '').trim(); - if (title.length > 28) title = title.slice(0, 28) + '…'; - var persistence = String(row.persistence || payload.persistence || '').trim(); - var sessionStorage = String(row.sessionStorage || row.session_storage || payload.sessionStorage || '').trim(); - if (!sessionStorage && persistence === 'convex_acp_runtime_store') sessionStorage = 'cloud'; - if (!sessionStorage && persistence === 'local_ai_session_jsonl') sessionStorage = String(row.shareId || payload.shareId || '').trim() ? 'local_shared' : 'local_private'; - return { - id: sessionId, - title: title || '当前页问答', - profile: String(row.profile || payload.profile || pageAiRunProfile()).trim() || 'default', - acpRuntime: String(row.acpRuntime || row.acp_runtime || payload.acpRuntime || 'reasonix').trim(), - createdAt: pageAiTimestamp(row.createdAt || row.created_at), - updatedAt: pageAiTimestamp(row.updatedAt || row.updated_at), - source: sessionStorage === 'local_private' || sessionStorage === 'local_shared' ? 'local' : 'acp', - persistence: persistence, - sessionStorage: sessionStorage, - permissionLevel: String(row.permissionLevel || row.permission_level || payload.permissionLevel || '').trim(), - shareId: String(row.shareId || row.share_id || payload.shareId || '').trim(), - runId: String(row.runId || row.run_id || '').trim(), - status: String(row.status || (row.runtime && row.runtime.status) || '').trim(), - usage: row.usage && typeof row.usage === 'object' ? row.usage : null, - preview: String(payload.message || row.snippet || '').trim(), - messages: [] - }; - } - - function pageAiMergeSessions(localSessions, backendSessions) { - var byId = {}; - pageAiNormalizeSessions(localSessions).forEach(function(session) { - byId[session.id] = session; + return Object.assign({}, profile || { + profileId: spec.profileId, + name: spec.profileId, + alias: spec.label, + kind: 'shared', + baseProfile: spec.baseProfile, + readonly: true + }, { menuLabel: spec.label }); }); - pageAiNormalizeSessions(backendSessions).forEach(function(session) { - var existing = byId[session.id]; - byId[session.id] = Object.assign({}, existing || {}, session, { - messages: session.messages.length ? session.messages : (existing && existing.messages || []) - }); + } + + function pageAiHermesProfileEntries() { + var profiles = pageAiNormalizeArray(pageUiState.pageAiProfiles).filter(function(profile) { + return !pageAiChatOnlyProfileSpec(profile); }); - return pageAiNormalizeSessions(Object.keys(byId).map(function(id) { return byId[id]; })); + if (profiles.length) return profiles; + return [{ profileId: pageAiCurrentProfile(), name: pageAiCurrentProfile(), alias: pageAiCurrentProfile(), kind: 'personal' }]; } - function pageAiSessionStorageLabel(session) { - var storage = String(session && (session.sessionStorage || session.session_storage) || '').trim(); - var persistence = String(session && session.persistence || '').trim(); - if (storage === 'local_shared') return '共享会话'; - if (storage === 'local_private') return '本地私有'; - if (storage === 'cloud' || persistence === 'convex_acp_runtime_store') return '云端会话'; - if (persistence === 'local_ai_session_jsonl') return '本地私有'; - return String(session && session.source || '').trim() === 'acp' ? '云端会话' : '本地私有'; - } - - function pageAiLoadSessions() { - if (pageUiState.pageAiSessions.length && pageUiState.pageAiActiveSessionId) return; - try { - var raw = window.localStorage.getItem(pageAiStorageKey()); - var parsed = raw ? JSON.parse(raw) : null; - var activeId = String(parsed && parsed.activeSessionId || '').trim(); - var activeProfile = String(parsed && parsed.activeProfileName || '').trim(); - var activeAcpRuntime = String(parsed && parsed.activeAcpRuntime || '').trim(); - var sessions = pageAiNormalizeSessions(parsed && parsed.sessions); - var storageVersion = Number(parsed && parsed.version || 0); - if (storageVersion >= PAGE_AI_SESSION_STORAGE_VERSION && activeAcpRuntime) pageUiState.pageAiAcpRuntime = activeAcpRuntime; - if (activeProfile) pageAiSetActiveProfile(activeProfile); - if (sessions.length) { - pageUiState.pageAiSessions = sessions; - var activeSession = sessions.find(function(session) { return session.id === activeId; }) || sessions[0]; - pageUiState.pageAiActiveSessionId = activeSession.id; - if (activeSession.profile) pageAiSetActiveProfile(activeSession.profile); - if (!pageUiState.pageAiAcpRuntime && activeSession.acpRuntime) pageUiState.pageAiAcpRuntime = activeSession.acpRuntime; - pageUiState.pageAiMessages = Array.isArray(activeSession.messages) ? activeSession.messages.slice() : []; - return; - } - if (activeId) { - pageUiState.pageAiSessions = [pageAiNewSession('当前页问答')]; - pageUiState.pageAiSessions[0].id = activeId; - pageUiState.pageAiActiveSessionId = activeId; - pageUiState.pageAiMessages = []; - return; - } - } catch (_) {} - var fresh = pageAiNewSession(); - pageUiState.pageAiSessions = [fresh]; - pageUiState.pageAiActiveSessionId = fresh.id; - pageUiState.pageAiMessages = []; - } - - async function pageAiLoadBackendSessions() { - var response = await fetch('/api/hermes/client/sessions?' + pageAiBackendSessionQuery({ limit: 50 }), { - headers: { 'accept': 'application/json' } - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_list_failed_' + response.status)); - } - var backendSessions = pageAiNormalizeArray(payload.sessions).map(pageAiNormalizeBackendSessionRow).filter(Boolean); - if (!backendSessions.length) return []; - pageUiState.pageAiSessions = pageAiMergeSessions(pageUiState.pageAiSessions, backendSessions); - if (!pageUiState.pageAiActiveSessionId || !pageUiState.pageAiSessions.find(function(session) { return session.id === pageUiState.pageAiActiveSessionId; })) { - pageUiState.pageAiActiveSessionId = pageUiState.pageAiSessions[0].id; - } - var active = pageAiCurrentSession(); - if (active) { - if (active.profile) pageAiSetActiveProfile(active.profile); - if (!pageUiState.pageAiAcpRuntime && active.acpRuntime) pageUiState.pageAiAcpRuntime = active.acpRuntime; - pageUiState.pageAiMessages = Array.isArray(active.messages) ? active.messages.slice() : pageUiState.pageAiMessages; - } - pageUiState.pageAiSessionError = ''; - pageAiPersistSessions(); - renderPageAiConversation(); - renderPageAiControls(); - return backendSessions; - } - - function pageAiMessageFromRuntimeEvent(event) { - if (!event || typeof event !== 'object') return null; - var eventType = String(event.eventType || event.event_type || event.event || '').trim(); - var payload = event.payload && typeof event.payload === 'object' ? event.payload : event; - if (eventType === 'message.delta') { - var delta = String(payload.delta || payload.text || payload.output_text || '').trim(); - return delta ? { role: 'assistant', content: delta } : null; - } - if (eventType === 'thought.delta') { - var thought = String(payload.delta || payload.text || '').trim(); - return thought ? { role: 'assistant', kind: 'thought', content: thought } : null; - } - if (eventType === 'tool.started' || eventType === 'tool.completed' || eventType === 'tool.failed') { - var toolName = String(payload.toolName || payload.tool || payload.name || eventType).trim(); - var rawLocations = payload.locations; - return { - role: 'tool', - content: toolName, - toolName: toolName, - toolCallId: String(payload.toolCallId || payload.tool_call_id || payload.id || ''), - toolKind: String(payload.kind || ''), - status: eventType === 'tool.completed' ? 'completed' : (eventType === 'tool.failed' ? 'failed' : 'running'), - argsSummary: pageAiPreviewValue(payload.args || payload.arguments || payload.input), - resultSummary: pageAiPreviewValue(payload.summary || payload.result || payload.output || payload.error), - locations: Array.isArray(rawLocations) ? rawLocations.filter(function(l) { return typeof l === 'string' || (typeof l === 'object' && l && l.path); }).map(function(l) { return typeof l === 'string' ? l : l.path; }) : [], - traceId: String(payload.traceId || payload.trace_id || ''), - auditId: String(payload.auditId || payload.audit_id || '') - }; - } - if (eventType === 'permission.requested' || eventType === 'permission.denied' || eventType === 'permission.allowed') { - return pageAiPermissionMessage(payload, eventType); - } - return null; - } - - function pageAiApplyBackendSessionDetail(payload) { - var sessionPayload = payload && payload.session ? payload.session : {}; - var runs = pageAiNormalizeArray(sessionPayload.runs); - var latest = runs.length ? pageAiNormalizeBackendSessionRow(runs[0]) : null; - var events = pageAiNormalizeArray(payload && payload.events); - var messages = pageAiNormalizeArray(sessionPayload.messages).map(function(message) { - return { - role: message.role === 'user' ? 'user' : (message.role === 'tool' ? 'tool' : 'assistant'), - content: String(message.content || '') - }; - }).filter(function(message) { return message.content; }); - events.forEach(function(event) { - var message = pageAiMessageFromRuntimeEvent(event); - if (message) messages.push(message); - }); - var current = pageAiCurrentSession(); - if (latest && current) { - Object.assign(current, latest); - } - if (current) { - current.messages = messages.slice(-300); - current.updatedAt = Math.max(Number(current.updatedAt || 0), Date.now()); - if (latest && latest.usage) current.usage = latest.usage; - } - pageAiApplyRuntimeState(payload && payload.runtime); - pageUiState.pageAiMessages = messages.slice(-300); - pageAiPersistSessions(); - } - - async function pageAiLoadBackendSessionDetail(sessionId) { - sessionId = String(sessionId || pageUiState.pageAiActiveSessionId || '').trim(); - if (!sessionId) return null; - var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '?' + pageAiBackendSessionQuery({ limit: 200 }), { - headers: { 'accept': 'application/json' } - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_detail_failed_' + response.status)); - } - pageAiApplyBackendSessionDetail(payload); - renderPageAiConversation(); - renderPageAiControls(); - return payload; - } - - async function pageAiSearchBackendSessions(query) { - var q = String(query || '').trim(); - pageUiState.pageAiSessionSearchQuery = q; - if (!q) { - pageUiState.pageAiSessionSearchResults = []; - renderPageAiConversation(); - return []; - } - var response = await fetch('/api/hermes/client/sessions/search?' + pageAiBackendSessionQuery({ q: q, limit: 20 }), { - headers: { 'accept': 'application/json' } - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_search_failed_' + response.status)); - } - pageUiState.pageAiSessionSearchResults = pageAiNormalizeArray(payload.results).map(function(row) { - var normalized = pageAiNormalizeBackendSessionRow(row) || {}; - normalized.snippet = String(row && row.snippet || normalized.preview || '').trim(); - return normalized; - }).filter(function(row) { return row.id; }); - renderPageAiConversation(); - return pageUiState.pageAiSessionSearchResults; - } - - function pageAiPersistSessions() { - document.documentElement.setAttribute('data-mnote-page-ai-session-owner', 'hermes'); - document.documentElement.setAttribute('data-mnote-page-ai-session-key', pageAiStorageKey()); - try { - pageAiSyncCurrentSessionMessages(); - window.localStorage.setItem(pageAiStorageKey(), JSON.stringify({ - version: PAGE_AI_SESSION_STORAGE_VERSION, - activeSessionId: pageUiState.pageAiActiveSessionId, - activeProfileName: pageAiCurrentProfile(), - activeAcpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', - sessions: pageAiNormalizeSessions(pageUiState.pageAiSessions) - })); - } catch (_) {} - } - - async function pageAiEnsureHermesSession(forceCreate) { - pageAiLoadSessions(); - var current = pageAiCurrentSession(); - if (!forceCreate && current && String(current.id || '').startsWith('mnote_') && current.profile === pageAiCurrentProfile()) return current; - var response = await fetch('/api/hermes/client/sessions', { - method: 'POST', - headers: { 'content-type': 'application/json' }, - body: JSON.stringify({ - workspaceId: resolveWorkspaceId(document.body), - documentId: currentDocumentId(), - sourceKind: currentSourceKind(), - rootUri: currentRootUri(), - traceId: 'page-ai-' + Date.now().toString(36), - profile: pageAiCurrentProfile(), - title: current && current.title ? current.title : '当前页问答' - }) - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'hermes_session_failed_' + response.status)); - } - var session = { - id: String(payload.sessionId || '').trim(), - title: String(payload.title || '当前页问答'), - profile: String(payload.profile || pageAiCurrentProfile()).trim() || 'default', - acpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', - persistence: String(payload.persistence || '').trim(), - sessionStorage: String(payload.sessionStorage || '').trim(), - permissionLevel: String(payload.permissionLevel || '').trim(), - shareId: String(payload.shareId || '').trim(), - createdAt: Date.now(), - updatedAt: Date.now(), - messages: pageUiState.pageAiMessages.slice() - }; - pageUiState.pageAiSessions = pageAiNormalizeSessions([session]); - pageUiState.pageAiActiveSessionId = session.id; - pageAiPersistSessions(); - renderPageAiConversation(); - return session; - } - - async function pageAiRestoreHermesSession() { - var current = pageAiCurrentSession(); - if (!current || !String(current.id || '').startsWith('mnote_')) return; - var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(current.id) + '/resume?' + pageAiBackendSessionQuery({}), { - method: 'POST', - headers: { 'accept': 'application/json' } - }); - if (!response.ok) return; - var payload = await response.json().catch(function(){ return null; }); - if (payload && payload.persistence === 'convex_acp_runtime_store') { - pageAiApplyBackendSessionDetail(payload); - renderPageAiConversation(); - renderPageAiControls(); - return; - } - var session = payload && (payload.session || (payload.upstream && payload.upstream.session) || payload); - var messages = session && Array.isArray(session.messages) ? session.messages : []; - pageAiApplyRuntimeState(payload && payload.runtime); - if (session && (session.profile || session.profileName)) { - current.profile = String(session.profile || session.profileName || current.profile || pageAiCurrentProfile()); - } - if (!messages.length) { - renderPageAiControls(); - return; - } - pageUiState.pageAiMessages = messages.slice(-300).map(function(message) { - return { - role: message.role === 'user' ? 'user' : (message.role === 'tool' ? 'tool' : 'assistant'), - content: String(message.content || '') - }; - }); - current.messages = pageUiState.pageAiMessages.slice(); - current.updatedAt = Date.now(); - renderPageAiConversation(); - renderPageAiControls(); - } - - function pageAiCurrentSession() { - return pageUiState.pageAiSessions.find(function(session) { - return session.id === pageUiState.pageAiActiveSessionId; - }) || null; - } - - function pageAiSyncCurrentSessionMessages() { - var session = pageAiCurrentSession(); - if (!session) return; - session.messages = Array.isArray(pageUiState.pageAiMessages) ? pageUiState.pageAiMessages.slice(-300) : []; - session.profile = pageAiCurrentProfile(); - session.acpRuntime = pageUiState.pageAiAcpRuntime || 'reasonix'; - session.updatedAt = Date.now(); - } - - function pageAiSetActiveSession(sessionId) { - var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); - if (!session) return; - pageUiState.pageAiActiveSessionId = session.id; - pageUiState.pageAiMessages = Array.isArray(session.messages) ? session.messages.slice() : []; - pageUiState.pageAiPage = 'chat'; - pageAiPersistSessions(); - renderPageAiControls(); - renderPageAiConversation(); - if (session.source === 'acp' || String(session.id || '').startsWith('mnote_')) { - void pageAiLoadBackendSessionDetail(session.id).catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - } - } - - function pageAiStartNewSession() { - var session = pageAiNewSession(); - pageUiState.pageAiSessions = pageAiNormalizeSessions([session].concat(pageUiState.pageAiSessions)); - pageUiState.pageAiActiveSessionId = session.id; - pageUiState.pageAiMessages = []; - pageUiState.pageAiPage = 'chat'; - pageAiPersistSessions(); - renderPageAiControls(); - renderPageAiConversation(); - } - - async function pageAiRenameBackendSession(sessionId) { - var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); - if (!session) return; - var title = window.prompt('重命名 AI 会话', session.title || '当前页问答'); - if (title === null) return; - title = String(title || '').trim(); - if (!title) return; - var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '/rename?' + pageAiBackendSessionQuery({}), { - method: 'POST', - headers: { 'content-type': 'application/json', 'accept': 'application/json' }, - body: JSON.stringify({ title: title }) - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_rename_failed_' + response.status)); - } - session.title = String((payload.result && payload.result.title) || title); - session.updatedAt = Date.now(); - pageAiPersistSessions(); - renderPageAiConversation(); - renderPageAiControls(); - } - - async function pageAiDeleteBackendSession(sessionId) { - var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); - if (!session) return; - if (!window.confirm('确定删除 AI 会话“' + (session.title || sessionId) + '”吗?')) return; - var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '?' + pageAiBackendSessionQuery({}), { - method: 'DELETE', - headers: { 'accept': 'application/json' } - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_delete_failed_' + response.status)); - } - pageUiState.pageAiSessions = pageUiState.pageAiSessions.filter(function(item) { return item.id !== sessionId; }); - if (pageUiState.pageAiActiveSessionId === sessionId) { - var next = pageUiState.pageAiSessions[0] || pageAiNewSession(); - if (!pageUiState.pageAiSessions.length) pageUiState.pageAiSessions = [next]; - pageUiState.pageAiActiveSessionId = next.id; - pageUiState.pageAiMessages = Array.isArray(next.messages) ? next.messages.slice() : []; - } - pageAiPersistSessions(); - renderPageAiConversation(); - renderPageAiControls(); - } - - async function pageAiResumeBackendSession(sessionId) { - sessionId = String(sessionId || pageUiState.pageAiActiveSessionId || '').trim(); - if (!sessionId) return; - pageAiSetActiveSession(sessionId); - var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '/resume?' + pageAiBackendSessionQuery({}), { - method: 'POST', - headers: { 'accept': 'application/json' } - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok || !payload || payload.ok !== true) { - throw new Error(pageAiErrorMessage(payload, 'session_resume_failed_' + response.status)); - } - pageAiApplyBackendSessionDetail(payload); - pageUiState.pageAiPage = 'chat'; - renderPageAiConversation(); - renderPageAiControls(); - } - - function pageAiProviderLabel(provider) { - if (provider === 'codex') return 'Codex'; - if (provider === 'claudecode') return 'ClaudeCode'; - return 'Hermes'; - } - - function pageAiNormalizeArray(value) { - return Array.isArray(value) ? value : []; - } - - function pageAiDefaultAcpRuntimes() { - return [ - { - name: 'reasonix', - title: 'ACP · Reasonix', - description: '通过 ACP 协议直连 Reasonix(DeepSeek 缓存优先)', - model: 'deepseek-chat', - preset: 'auto' - }, - { - name: 'hermes', - title: 'ACP · Hermes', - description: '通过 ACP 协议直连 Hermes agent runtime' - } - ]; - } - - function pageAiNormalizeAcpRuntimes(runtimes) { - var byName = {}; - pageAiDefaultAcpRuntimes().forEach(function(runtime) { - byName[runtime.name] = Object.assign({}, runtime); - }); - pageAiNormalizeArray(runtimes).forEach(function(runtime) { - var name = String(runtime && runtime.name || '').trim(); - if (name !== 'reasonix' && name !== 'hermes') return; - byName[name] = Object.assign({}, byName[name] || {}, runtime, { name: name }); - }); - return ['reasonix', 'hermes'].map(function(name) { return byName[name]; }).filter(Boolean); - } - - function pageAiUnwrapUpstream(payload) { - if (payload && typeof payload === 'object' && payload.upstream) return payload.upstream; - return payload || null; - } - - function pageAiProfileValue(profile) { - if (profile && typeof profile === 'object') { - return String(profile.name || profile.profile || profile.id || '').trim(); - } - return String(profile || '').trim(); - } - - function pageAiCurrentProfile() { - var active = String(pageUiState.pageAiActiveProfileName || '').trim(); - if (active) return active; - var selected = pageUiState.pageAiProfiles.find(function(profile) { - return profile && profile.active; - }); - return pageAiProfileValue(selected) || 'mnoteai'; - } - - function pageAiRunProfile() { - return String(pageUiState.pageAiAcpRuntime || 'reasonix').trim() === 'reasonix' ? 'reasonix' : pageAiCurrentProfile(); - } - - function pageAiMnoteToolModel() { - return String(document.documentElement.getAttribute('data-mnote-page-ai-tool-model') || 'deepseek-v4-flash').trim() || 'deepseek-v4-flash'; - } - - function pageAiCurrentProfileRecord() { - var active = pageAiCurrentProfile(); - return pageUiState.pageAiProfiles.find(function(profile) { - return pageAiProfileValue(profile) === active; - }) || null; - } - - function pageAiCurrentModelLabel() { - var profile = pageAiCurrentProfileRecord(); - var toolModel = pageAiMnoteToolModel(); - if (!profile) return 'tool: ' + toolModel; - var model = String(profile.model || '').trim(); - var gateway = String(profile.gateway || '').trim(); - var profileLabel = [model, gateway].filter(Boolean).join(' · ') || '由 Hermes 决定'; - return 'tool: ' + toolModel + ' · profile: ' + profileLabel; - } function pageAiNormalizeProfiles(payload) { var upstream = pageAiUnwrapUpstream(payload); var profiles = pageAiNormalizeArray(upstream && upstream.profiles ? upstream.profiles : upstream); return profiles.map(function(profile) { + var profileId = String(profile && (profile.profileId || profile.id || profile.name) || '').trim(); + var kind = String(profile && profile.kind || profile && profile.profileKind || '').trim(); + var canManageSkills = profile && profile.canManageSkills !== false; return { - name: pageAiProfileValue(profile) || 'default', + profileId: profileId || pageAiProfileValue(profile) || 'default', + name: profileId || pageAiProfileValue(profile) || 'default', active: Boolean(profile && profile.active), model: String(profile && profile.model || '').trim(), gateway: String(profile && profile.gateway || '').trim(), - alias: String(profile && profile.alias || '').trim() + alias: String(profile && (profile.displayName || profile.alias) || '').trim(), + kind: kind, + ownerUserId: String(profile && profile.ownerUserId || '').trim(), + baseProfile: String(profile && profile.baseProfile || '').trim(), + isolatedProfile: String(profile && profile.isolatedProfile || '').trim(), + canRun: profile ? profile.canRun !== false : true, + canManageSkills: canManageSkills, + canManageConfig: profile ? profile.canManageConfig !== false : canManageSkills, + readonly: profile ? (profile.readonly === true || !canManageSkills) : false, + grantRole: String(profile && profile.grantRole || '').trim() }; }); } @@ -1602,6 +793,12 @@ export function createSidebarPageAiRuntime(context) { createdBy: String(skill && skill.createdBy || '').trim(), patchCount: Number(skill && skill.patchCount || 0), modified: Boolean(skill && skill.modified), + builtin: Boolean(skill && skill.builtin), + configurable: skill && skill.configurable !== false, + configScope: String(skill && skill.configScope || '').trim(), + skillKind: String(skill && skill.skillKind || '').trim(), + profileId: String(skill && skill.profileId || '').trim(), + readOnly: Boolean(skill && (skill.readOnly || skill.readonly || skill.configurable === false)), category: String(category && category.name || '').trim() }; }) @@ -1619,7 +816,13 @@ export function createSidebarPageAiRuntime(context) { origin: String(skill && skill.origin || '').trim(), createdBy: String(skill && skill.createdBy || '').trim(), patchCount: Number(skill && skill.patchCount || 0), - modified: Boolean(skill && skill.modified) + modified: Boolean(skill && skill.modified), + builtin: Boolean(skill && skill.builtin), + configurable: skill && skill.configurable !== false, + configScope: String(skill && skill.configScope || '').trim(), + skillKind: String(skill && skill.skillKind || '').trim(), + profileId: String(skill && skill.profileId || '').trim(), + readOnly: Boolean(skill && (skill.readOnly || skill.readonly || skill.configurable === false)) }; }) }; @@ -1641,7 +844,13 @@ export function createSidebarPageAiRuntime(context) { origin: skill.origin || '', createdBy: skill.createdBy || '', patchCount: Number(skill.patchCount || 0), - modified: Boolean(skill.modified) + modified: Boolean(skill.modified), + builtin: Boolean(skill.builtin), + configurable: skill.configurable !== false, + configScope: skill.configScope || '', + skillKind: skill.skillKind || '', + profileId: skill.profileId || '', + readOnly: Boolean(skill.readOnly || skill.readonly || skill.configurable === false) }); }); }); @@ -1717,24 +926,6 @@ export function createSidebarPageAiRuntime(context) { return String(name || '').trim().replace(/_/g, '.'); } - function pageAiFormatChangedFiles(files) { - return pageAiNormalizeArray(files).map(function(file) { - var path = String(file && file.path || '').trim(); - var changeType = String(file && file.changeType || file.change_type || 'modified').trim(); - var summary = String(file && file.summary || '').trim(); - var version = String(file && (file.version || file.revision || '') || '').trim(); - var hashBefore = String(file && file.hashBefore || '').trim(); - var hashAfter = String(file && file.hashAfter || '').trim(); - if (!version && (hashBefore || hashAfter)) version = 'hash ' + [hashBefore || '0', hashAfter || '0'].join('→'); - var modifiedBefore = Number(file && file.modifiedBeforeMs || 0) || 0; - var modifiedAfter = Number(file && file.modifiedAfterMs || 0) || 0; - if (!version && (modifiedBefore || modifiedAfter)) version = 'mtime ' + [String(modifiedBefore), String(modifiedAfter)].join('→'); - var actor = [file && file.agentKind, file && file.actorType, file && file.actorId].map(function(value) { - return String(value || '').trim(); - }).filter(Boolean).join('/'); - return [changeType, path, version, summary, actor].filter(Boolean).join(' · '); - }).filter(Boolean).join('\n'); - } function pageAiParentRelativePath(path) { var normalized = String(path || '').trim().replace(/\\/g, '/').replace(/^\/+/, ''); @@ -1976,28 +1167,6 @@ export function createSidebarPageAiRuntime(context) { document.documentElement.setAttribute('data-mnote-page-ai-context-scope', next); } - function pageAiRunStatusLabel(status) { - if (status === 'queued') return '排队中'; - if (status === 'running') return '运行中'; - if (status === 'tool_calling') return '调用工具'; - if (status === 'completed') return '已完成'; - if (status === 'failed') return '失败'; - if (status === 'aborted') return '已停止'; - return '空闲'; - } - - function pageAiMemoryFileLabel(section) { - if (section === 'soul') return 'SOUL.md'; - if (section === 'user') return 'USER.md'; - return 'MEMORY.md'; - } - - function pageAiContextScopeLabel(scope) { - if (scope === 'selection') return '当前选区'; - if (scope === 'block') return '当前块'; - if (scope === 'options') return '页面设置'; - return '当前页'; - } function pageAiHermesSettingsUrl() { var configured = String(window.__mnoteHermesSettingsUrl || '').trim(); @@ -2128,171 +1297,6 @@ export function createSidebarPageAiRuntime(context) { renderPageAiConversation(); } - function pageAiFilteredSkillEntries() { - var query = String(pageUiState.pageAiSkillQuery || '').trim().toLowerCase(); - return pageAiAllSkillEntries().filter(function(skill) { - if (skill.group === 'hermes' && pageAiHideHermesBuiltinSkills(pageAiCurrentProfile()) && skill.builtin === true) return false; - if (!query) return true; - return String(skill.name || skill.id || '').toLowerCase().indexOf(query) >= 0 - || String(skill.title || '').toLowerCase().indexOf(query) >= 0 - || String(skill.description || '').toLowerCase().indexOf(query) >= 0 - || String(skill.category || '').toLowerCase().indexOf(query) >= 0 - || pageAiSkillOriginLabel(skill).toLowerCase().indexOf(query) >= 0; - }); - } - - function pageAiSkillOriginLabel(skill) { - var origin = String(skill && skill.origin || '').trim(); - if (origin === 'generated' || String(skill && skill.createdBy || '') === 'agent') return '生成'; - if (origin === 'installed') return '安装'; - if (origin === 'builtin') return '内置'; - if (origin === 'copied') return '本地'; - var source = String(skill && skill.source || '').trim(); - if (source === 'hub') return '安装'; - if (source === 'builtin') return '内置'; - if (source === 'reasonix') { - if (origin === 'project') return 'Reasonix 项目'; - if (origin === 'global') return 'Reasonix 全局'; - return 'Reasonix'; - } - return '本地'; - } - - function pageAiSkillPreferenceKey(group, profile) { - var groupName = String(group || '').trim(); - if (groupName === 'mnote') return 'ai.common.skills.mnote.enabled'; - if (groupName === 'reasonix') return 'ai.agent.reasonix.skills.enabled'; - if (groupName === 'hermes') { - var nextProfile = String(profile || pageAiCurrentProfile() || 'default').trim() || 'default'; - return 'ai.agent.hermes.profile.' + nextProfile + '.skills.enabled'; - } - return ''; - } - - function pageAiSkillPreferenceTable(group, profile) { - var key = pageAiSkillPreferenceKey(group, profile); - var preferences = pageUiState.pageAiSkillPreferences || {}; - var value = preferences[key]; - if (value && typeof value === 'object' && !Array.isArray(value)) return value; - return {}; - } - - function pageAiHermesHideBuiltinPreferenceKey(profile) { - var nextProfile = String(profile || pageAiCurrentProfile() || 'default').trim() || 'default'; - return 'ai.agent.hermes.profile.' + nextProfile + '.skills.hide_builtin'; - } - - function pageAiHideHermesBuiltinSkills(profile) { - var preferences = pageUiState.pageAiSkillPreferences || {}; - return preferences[pageAiHermesHideBuiltinPreferenceKey(profile)] === true; - } - - function pageAiSetHideHermesBuiltinSkills(enabled, profile) { - var key = pageAiHermesHideBuiltinPreferenceKey(profile); - var preferences = Object.assign({}, pageUiState.pageAiSkillPreferences || {}); - preferences[key] = Boolean(enabled); - pageUiState.pageAiSkillPreferences = preferences; - pageAiPersistRawAiPreference(key, Boolean(enabled)); - renderPageAiControls(); - } - - function pageAiSkillIsBuiltin(skill) { - var origin = String(skill && skill.origin || '').trim(); - var source = String(skill && skill.source || '').trim(); - return origin === 'builtin' || source === 'builtin'; - } - - function pageAiToggleableSkillEntries(group, profile) { - var catalog = pageUiState.pageAiSkillCatalogs && pageUiState.pageAiSkillCatalogs[group] - ? pageUiState.pageAiSkillCatalogs[group] - : { categories: [], archived: [] }; - var overrides = pageAiSkillPreferenceTable(group, profile); - var result = []; - pageAiNormalizeArray(catalog.categories).forEach(function(category) { - pageAiNormalizeArray(category.skills).forEach(function(skill) { - var id = String(skill.id || skill.name || '').trim(); - if (!id) return; - result.push({ - group: group, - profile: profile || '', - category: category.name, - id: id, - name: skill.name || id, - title: skill.title || skill.name || id, - description: skill.description || '', - enabled: group === 'hermes' ? skill.enabled !== false : overrides[id] !== false, - toggleable: skill.toggleable !== false, - source: skill.source || group, - origin: skill.origin || '', - readOnly: skill.readOnly === true, - builtin: pageAiSkillIsBuiltin(skill), - toolNames: skill.toolNames || [], - requiresContextRefs: skill.requiresContextRefs || [] - }); - }); - }); - pageAiNormalizeArray(catalog.archived).forEach(function(skill) { - var id = String(skill.id || skill.name || '').trim(); - if (!id) return; - result.push({ - group: group, - profile: profile || '', - category: 'archived', - id: id, - name: skill.name || id, - title: skill.title || skill.name || id, - description: skill.description || '', - enabled: group === 'hermes' ? skill.enabled !== false : overrides[id] !== false, - toggleable: skill.toggleable !== false, - source: skill.source || group, - origin: skill.origin || '', - readOnly: skill.readOnly === true, - builtin: pageAiSkillIsBuiltin(skill), - toolNames: skill.toolNames || [], - requiresContextRefs: skill.requiresContextRefs || [] - }); - }); - return result; - } - - function pageAiAllSkillEntries() { - return [] - .concat(pageAiToggleableSkillEntries('mnote', '')) - .concat(pageAiToggleableSkillEntries('reasonix', '')) - .concat(pageAiToggleableSkillEntries('hermes', pageAiCurrentProfile())); - } - - function pageAiSkillGroupCollapsed(group) { - var table = pageUiState.pageAiCollapsedSkillGroups || {}; - return table[String(group || '').trim()] === true; - } - - function pageAiToggleSkillGroup(group) { - var normalized = String(group || '').trim(); - if (!normalized) return; - var table = Object.assign({}, pageUiState.pageAiCollapsedSkillGroups || {}); - table[normalized] = table[normalized] !== true; - pageUiState.pageAiCollapsedSkillGroups = table; - pageAiPersistRawAiPreference('ai.common.skills.groups.collapsed', table); - renderPageAiControls(); - } - - function pageAiSetSkillPreference(group, skillId, enabled, profile) { - var key = pageAiSkillPreferenceKey(group, profile); - if (!key || !skillId) return; - var preferences = Object.assign({}, pageUiState.pageAiSkillPreferences || {}); - var current = preferences[key] && typeof preferences[key] === 'object' && !Array.isArray(preferences[key]) - ? Object.assign({}, preferences[key]) - : {}; - current[skillId] = Boolean(enabled); - preferences[key] = current; - pageUiState.pageAiSkillPreferences = preferences; - pageAiPersistRawAiPreference(key, current); - } - - function pageAiSkillEnabled(skill) { - return skill.enabled !== false; - } function pageAiLoadSkillCatalog(runtime, profile) { var params = new URLSearchParams(); @@ -2302,7 +1306,7 @@ export function createSidebarPageAiRuntime(context) { } else if (runtime === 'reasonix') { params.set('runtime', 'reasonix'); } else if (runtime === 'hermes' && profile) { - params.set('profile', profile); + params.set('profileId', profile); } return fetch('/api/hermes/client/skills?' + params.toString(), { headers: { 'accept': 'application/json' } @@ -2316,25 +1320,31 @@ export function createSidebarPageAiRuntime(context) { async function pageAiLoadProfiles() { try { - var response = await fetch('/api/hermes/client/profiles', { + var response = await fetch('/api/ai/agent-profiles?agentId=hermes', { headers: { 'accept': 'application/json' } }); var payload = await response.json().catch(function(){ return null; }); if (!response.ok) throw new Error(pageAiErrorMessage(payload, 'profiles_failed_' + response.status)); var profiles = pageAiNormalizeProfiles(payload); - pageUiState.pageAiProfiles = profiles.length ? profiles : [{ name: 'mnoteai', active: true }]; - var acpRuntimes = Array.isArray(payload.acpRuntimes) ? payload.acpRuntimes : []; - pageUiState.pageAiAcpRuntimes = pageAiNormalizeAcpRuntimes(acpRuntimes); + pageUiState.pageAiProfiles = profiles.length ? profiles : [{ profileId: 'shared_lite', name: 'shared_lite', alias: 'Lite', kind: 'shared', readonly: true, canManageSkills: false }]; + try { + var runtimeResponse = await fetch('/api/hermes/client/profiles', { headers: { 'accept': 'application/json' } }); + var runtimePayload = await runtimeResponse.json().catch(function(){ return null; }); + var acpRuntimes = Array.isArray(runtimePayload && runtimePayload.acpRuntimes) ? runtimePayload.acpRuntimes : []; + pageUiState.pageAiAcpRuntimes = pageAiNormalizeAcpRuntimes(acpRuntimes); + } catch (_) { + pageUiState.pageAiAcpRuntimes = pageAiNormalizeAcpRuntimes(pageUiState.pageAiAcpRuntimes); + } var current = pageAiCurrentProfile(); var hasCurrent = pageUiState.pageAiProfiles.some(function(profile) { return pageAiProfileValue(profile) === current; }); - var hasMnoteAi = pageUiState.pageAiProfiles.some(function(profile) { return pageAiProfileValue(profile) === 'mnoteai'; }); + var personal = pageUiState.pageAiProfiles.find(function(profile) { return profile.kind === 'personal'; }); var active = pageAiProfileValue(pageUiState.pageAiProfiles.find(function(profile) { return profile.active; })); - pageAiSetActiveProfile(hasCurrent && current !== 'default' ? current : (hasMnoteAi ? 'mnoteai' : (active || current))); + pageAiSetActiveProfile(hasCurrent && current !== 'default' ? current : (active || pageAiProfileValue(personal) || pageAiProfileValue(pageUiState.pageAiProfiles[0]) || current)); pageUiState.pageAiProfileError = ''; void pageAiLoadGatewayHealth(); } catch (error) { pageUiState.pageAiProfileError = error instanceof Error ? error.message : String(error); - if (!pageUiState.pageAiProfiles.length) pageUiState.pageAiProfiles = [{ name: 'mnoteai', active: true }]; + if (!pageUiState.pageAiProfiles.length) pageUiState.pageAiProfiles = [{ profileId: 'shared_lite', name: 'shared_lite', alias: 'Lite', kind: 'shared', readonly: true, canManageSkills: false }]; pageUiState.pageAiAcpRuntimes = pageAiNormalizeAcpRuntimes(pageUiState.pageAiAcpRuntimes); pageAiSetActiveProfile(pageAiCurrentProfile()); } @@ -2345,8 +1355,13 @@ export function createSidebarPageAiRuntime(context) { async function pageAiSwitchProfile(profileName) { var next = String(profileName || '').trim(); if (!next) return; + var previousSkillSource = pageAiCurrentSkillSource(); pageAiSetActiveProfile(next); pageAiPersistRawAiPreference('ai.agent.hermes.profile_id', next); + if (previousSkillSource.indexOf('hermes:') === 0) { + pageUiState.pageAiActiveSkillSource = 'hermes:' + next; + pageAiPersistAiPreference('skills.active_source', pageUiState.pageAiActiveSkillSource); + } pageUiState.pageAiSkills = { categories: [], archived: [] }; pageUiState.pageAiSkillCatalogs = Object.assign({}, pageUiState.pageAiSkillCatalogs || {}, { hermes: { categories: [], archived: [] } @@ -2355,13 +1370,6 @@ export function createSidebarPageAiRuntime(context) { renderPageAiProviderButtons(); renderPageAiControls(); try { - var response = await fetch('/api/hermes/client/profiles/active', { - method: 'PUT', - headers: { 'content-type': 'application/json' }, - body: JSON.stringify({ name: next }) - }); - var payload = await response.json().catch(function(){ return null; }); - if (!response.ok) throw new Error(pageAiErrorMessage(payload, 'profile_switch_failed_' + response.status)); pageUiState.pageAiSessions = pageUiState.pageAiSessions.filter(function(session) { return session && session.profile === next; }); @@ -2382,7 +1390,7 @@ export function createSidebarPageAiRuntime(context) { async function pageAiLoadProfileMemory() { try { - var response = await fetch('/api/hermes/client/profile-memory?profile=' + encodeURIComponent(pageAiCurrentProfile()), { + var response = await fetch('/api/hermes/client/profile-memory?profileId=' + encodeURIComponent(pageAiCurrentProfile()), { headers: { 'accept': 'application/json' } }); var payload = await response.json().catch(function(){ return null; }); @@ -2405,7 +1413,7 @@ export function createSidebarPageAiRuntime(context) { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ - profile: pageAiCurrentProfile(), + profileId: pageAiCurrentProfile(), section: normalized, content: content }) @@ -2423,25 +1431,23 @@ export function createSidebarPageAiRuntime(context) { } async function pageAiLoadSkills() { - var requestedProfile = pageAiCurrentProfile(); + var requestedSource = pageAiCurrentSkillSource(); + var sourceParts = pageAiSkillSourceParts(requestedSource); var loadSeq = (Number(pageUiState.pageAiSkillLoadSeq || 0) || 0) + 1; pageUiState.pageAiSkillLoadSeq = loadSeq; try { - var catalogs = await Promise.all([ - pageAiLoadSkillCatalog('mnote', ''), - pageAiLoadSkillCatalog('reasonix', ''), - pageAiLoadSkillCatalog('hermes', requestedProfile) - ]); - if (pageUiState.pageAiSkillLoadSeq !== loadSeq || pageAiCurrentProfile() !== requestedProfile) return; - pageUiState.pageAiSkillCatalogs = { - mnote: catalogs[0], - reasonix: catalogs[1], - hermes: catalogs[2] - }; - pageUiState.pageAiSkills = catalogs[2]; + var catalog = await pageAiLoadSkillCatalog(sourceParts.group, sourceParts.profile || pageAiCurrentProfile()); + if (pageUiState.pageAiSkillLoadSeq !== loadSeq + || pageAiCurrentSkillSource() !== requestedSource) return; + pageUiState.pageAiSkillCatalogs = Object.assign({}, pageUiState.pageAiSkillCatalogs || {}, { + [sourceParts.group]: catalog, + [requestedSource]: catalog + }); + pageUiState.pageAiSkills = catalog; pageUiState.pageAiSkillError = ''; } catch (error) { - if (pageUiState.pageAiSkillLoadSeq !== loadSeq || pageAiCurrentProfile() !== requestedProfile) return; + if (pageUiState.pageAiSkillLoadSeq !== loadSeq + || pageAiCurrentSkillSource() !== requestedSource) return; pageUiState.pageAiSkillError = error instanceof Error ? error.message : String(error); pageUiState.pageAiSkills = { categories: [], archived: [] }; pageUiState.pageAiSkillCatalogs = pageUiState.pageAiSkillCatalogs || { mnote: { categories: [], archived: [] }, reasonix: { categories: [], archived: [] }, hermes: { categories: [], archived: [] } }; @@ -2455,14 +1461,40 @@ export function createSidebarPageAiRuntime(context) { if (!name) return; var skillGroup = String(group || 'hermes').trim() || 'hermes'; var skillProfile = String(profile || pageAiCurrentProfile() || '').trim(); - if (skillGroup === 'mnote' || skillGroup === 'reasonix') { + if (skillGroup === 'reasonix') { pageAiSetSkillPreference(skillGroup, name, Boolean(enabled), skillProfile); document.documentElement.setAttribute('data-mnote-page-ai-skill-toggled', skillGroup + ':' + name); renderPageAiControls(); return; } + if (skillGroup === 'mnote') { + try { + var mnoteResponse = await fetch('/api/hermes/client/skills/toggle', { + method: 'PUT', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ + skillKind: 'mnote_builtin', + name: name, + enabled: Boolean(enabled) + }) + }); + var mnotePayload = await mnoteResponse.json().catch(function(){ return null; }); + if (!mnoteResponse.ok) throw new Error(pageAiErrorMessage(mnotePayload, 'mnote_skill_toggle_failed_' + mnoteResponse.status)); + pageAiSetSkillPreference(skillGroup, name, Boolean(enabled), skillProfile); + pageAiNormalizeArray(pageUiState.pageAiSkillCatalogs && pageUiState.pageAiSkillCatalogs.mnote && pageUiState.pageAiSkillCatalogs.mnote.categories).forEach(function(category) { + pageAiNormalizeArray(category.skills).forEach(function(skill) { + if (skill.id === name || skill.name === name) skill.enabled = Boolean(enabled); + }); + }); + document.documentElement.setAttribute('data-mnote-page-ai-skill-toggled', skillGroup + ':' + name); + } catch (error) { + pageUiState.pageAiSkillError = error instanceof Error ? error.message : String(error); + } + renderPageAiControls(); + return; + } var previous = null; - pageAiToggleableSkillEntries('hermes', pageAiCurrentProfile()).forEach(function(skill) { + pageAiToggleableSkillEntries('hermes', skillProfile || pageAiCurrentProfile()).forEach(function(skill) { if (skill.id === name || skill.name === name) previous = skill.enabled !== false; }); try { @@ -2471,6 +1503,8 @@ export function createSidebarPageAiRuntime(context) { headers: { 'content-type': 'application/json' }, body: JSON.stringify({ profile: skillProfile || pageAiCurrentProfile(), + profileId: skillProfile || pageAiCurrentProfile(), + skillKind: 'hermes_profile', name: name, enabled: Boolean(enabled) }) @@ -2545,773 +1579,6 @@ export function createSidebarPageAiRuntime(context) { renderPageAiControls(); } - function renderPageAiProviderButtons() { - var drawer = ensurePageAiDrawer(); - var isAcp = pageUiState.pageAiAcpRuntime !== ''; - drawer.querySelectorAll('[data-page-ai-provider]').forEach(function(button) { - var provider = button.getAttribute('data-page-ai-provider') || 'hermes'; - var active = provider === pageUiState.pageAiProvider; - button.classList.toggle('is-active', active); - button.setAttribute('aria-pressed', active ? 'true' : 'false'); - }); - var providerNode = drawer.querySelector('.wolai-page-ai-subtitle span:first-child'); - if (providerNode instanceof HTMLElement) { - providerNode.textContent = pageAiAgentRecord(pageAiCurrentAgentId()).label; - } - } - - function renderPageAiControls() { - var drawer = ensurePageAiDrawer(); - var isAcp = pageUiState.pageAiAcpRuntime !== ''; - var activeAgentId = pageAiCurrentAgentId(); - var activeProfile = pageAiCurrentProfile(); - drawer.setAttribute('data-page-ai-page', pageUiState.pageAiPage || 'chat'); - drawer.setAttribute('data-page-ai-active-agent-id', activeAgentId); - drawer.setAttribute('data-mnote-acp-runtime', pageUiState.pageAiAcpRuntime || 'reasonix'); - document.documentElement.setAttribute('data-mnote-page-ai-agent-id', activeAgentId); - var agentButton = drawer.querySelector('[data-page-ai-agent-button]'); - var agentPopoverId = 'mnote-page-ai-agent-popover'; - if (agentButton instanceof HTMLElement) { - var activeAgent = pageAiAgentRecord(activeAgentId); - agentButton.textContent = 'AI'; - agentButton.setAttribute('aria-expanded', pageUiState.pageAiAgentPopoverOpen ? 'true' : 'false'); - agentButton.setAttribute('aria-controls', agentPopoverId); - agentButton.setAttribute('data-page-ai-agent-summary', activeAgent.label); - agentButton.setAttribute('aria-label', 'Agent:' + activeAgent.label); - agentButton.setAttribute('title', 'Agent:' + activeAgent.label); - } - var agentPopover = drawer.querySelector('[data-page-ai-agent-popover]'); - if (agentPopover instanceof HTMLElement) { - agentPopover.id = agentPopoverId; - agentPopover.hidden = !pageUiState.pageAiAgentPopoverOpen; - agentPopover.innerHTML = '' + - '
    ' + - '选择 Agent' + - '' + - '
    ' + - '
    ' + - PAGE_AI_AGENT_REGISTRY.map(function(agent) { - var active = agent.id === activeAgentId; - var detail = agent.canWriteFiles ? '可读取并在授权目录内写文件' : '只聊天,不申请文件写权限'; - return '' + - ''; - }).join('') + - '
    ' + - (activeAgentId === 'hermes' - ? '' - : ''); - } - var contextButton = drawer.querySelector('[data-page-ai-context-button]'); - var contextPopoverId = 'mnote-page-ai-context-popover'; - if (contextButton instanceof HTMLElement) { - var summary = pageAiContextButtonSummary(); - contextButton.textContent = '⇅'; - contextButton.setAttribute('aria-expanded', pageUiState.pageAiContextPopoverOpen ? 'true' : 'false'); - contextButton.setAttribute('aria-controls', contextPopoverId); - contextButton.setAttribute('data-page-ai-context-summary', summary); - contextButton.setAttribute('aria-label', '上下文:' + summary); - contextButton.setAttribute('title', '上下文:' + summary); - } - var contextPopover = drawer.querySelector('[data-page-ai-context-popover]'); - if (contextPopover instanceof HTMLElement) { - var selectedRefs = pageAiEnsureContextRefState(); - contextPopover.id = contextPopoverId; - contextPopover.hidden = !pageUiState.pageAiContextPopoverOpen; - contextPopover.innerHTML = '' + - '
    ' + - '发送给 AI 的上下文' + - '' + - '
    ' + - '
    ' + - PAGE_AI_CONTEXT_REF_REGISTRY.map(function(ref) { - var checked = selectedRefs[ref.id] === true; - var disabled = pageAiContextRefDisabled(ref.id); - return '' + - ''; - }).join('') + - '
    ' + - '
    ' + - '授权区域' + - '' + escapeHtml(pageAiBuildAllowedRoots().length ? pageAiBuildAllowedRoots().map(function(root) { return root.permission + ' · ' + root.rootUri.replace(/^file:\/\//, ''); }).join(' / ') : '未选择授权区域') + '' + - '
    '; - } - var allowedRootsNode = drawer.querySelector('[data-page-ai-allowed-roots]'); - if (allowedRootsNode instanceof HTMLElement) { - var allowedRoots = pageAiBuildAllowedRoots(); - if (!allowedRoots.length) { - var errorText = String(pageUiState.pageAiAllowedRootsError || '').trim(); - allowedRootsNode.innerHTML = '' + escapeHtml(errorText || '未选择授权区域') + ''; - } else { - allowedRootsNode.innerHTML = allowedRoots.map(function(root) { - var label = root.rootUri.replace(/^file:\/\//, '') || root.rootUri; - return '' + escapeHtml(root.permission + ' · ' + label) + ''; - }).join(''); - } - } - // Populate ACP runtime dropdown - var acpSelect = drawer.querySelector('[data-page-ai-acp-runtime]'); - if (acpSelect instanceof HTMLSelectElement) { - var runtimes = pageUiState.pageAiAcpRuntimes.length ? pageUiState.pageAiAcpRuntimes : pageAiNormalizeAcpRuntimes([]); - acpSelect.innerHTML = runtimes.map(function(rt) { - return ''; - }).join(''); - acpSelect.value = pageUiState.pageAiAcpRuntime || 'reasonix'; - } - // Show/hide Hermes-specific profile select - var profileLabel = drawer.querySelector('[data-page-ai-hermes-profile]'); - if (profileLabel instanceof HTMLElement) { - profileLabel.style.display = pageUiState.pageAiAcpRuntime === 'reasonix' ? 'none' : ''; - } - // When ACP is selected, populate agent panel with ACP runtime info - var agentPanel = drawer.querySelector('[data-page-ai-agent-panel]'); - if (agentPanel instanceof HTMLElement) { - agentPanel.innerHTML = '' + - '
    ' + - '
    授权区域
    ' + escapeHtml(pageAiBuildAllowedRoots().length ? 'SQLite directory_grants' : '需要授权') + '
    ' + - '
    ' + - '
    ' + - '
    默认上下文
    ContextRefs
    ' + - '
    ' + - '
    ' + - '
    审计
    changed files 默认摘要
    ' + - '
    '; - } - var profileSummary = drawer.querySelector('[data-page-ai-profile-summary]'); - if (profileSummary instanceof HTMLElement) profileSummary.textContent = '上下文可选'; - var profileSummary = drawer.querySelector('[data-page-ai-profile-summary]'); - if (profileSummary instanceof HTMLElement) profileSummary.textContent = '上下文可选'; - drawer.querySelectorAll('[data-page-ai-profile-select]').forEach(function(profileSelect) { - if (!(profileSelect instanceof HTMLSelectElement)) return; - var profiles = pageUiState.pageAiProfiles.length ? pageUiState.pageAiProfiles : [{ name: activeProfile, active: true }]; - profileSelect.innerHTML = profiles.map(function(profile) { - var name = pageAiProfileValue(profile) || 'default'; - var model = [profile.model, profile.gateway].filter(Boolean).join(' / '); - var label = [name, profile.alias, model].filter(Boolean).join(' · '); - return ''; - }).join(''); - profileSelect.value = activeProfile; - }); - var runStatus = drawer.querySelector('[data-page-ai-run-status]'); - if (runStatus instanceof HTMLElement) { - var queueSuffix = pageUiState.pageAiQueueLength > 0 ? ' · 队列 ' + pageUiState.pageAiQueueLength : ''; - runStatus.textContent = pageAiRunStatusLabel(pageUiState.pageAiRunStatus) + queueSuffix; - } - var stopButton = drawer.querySelector('[data-page-ai-action="stop-run"]'); - if (stopButton instanceof HTMLButtonElement) { - var canStop = ['queued', 'running', 'tool_calling'].indexOf(pageUiState.pageAiRunStatus) >= 0 && pageUiState.pageAiCurrentRunId; - stopButton.disabled = !canStop; - stopButton.setAttribute('aria-disabled', canStop ? 'false' : 'true'); - } - var settingsLink = drawer.querySelector('[data-page-ai-action="open-hermes-settings"]'); - if (settingsLink instanceof HTMLButtonElement) { - settingsLink.disabled = !pageAiHermesSettingsUrl(); - settingsLink.title = pageAiHermesSettingsUrl() ? '打开 Hermes 设置' : '未配置 MNOTE_WEB_HERMES_UPSTREAM_URL'; - } - var queueList = drawer.querySelector('[data-page-ai-queue-list]'); - if (queueList instanceof HTMLElement) { - if (!pageUiState.pageAiQueuedItems.length) { - queueList.innerHTML = '
    暂无排队项。
    '; - } else { - queueList.innerHTML = pageUiState.pageAiQueuedItems.map(function(item, index) { - var label = '队列 ' + (index + 1); - return '' + - '
    ' + - '
    ' + escapeHtml(label) + '
    ' + escapeHtml(item.queueId) + '
    ' + - '' + - '
    '; - }).join(''); - } - } - var sessionNode = drawer.querySelector('[data-page-ai-session-status]'); - if (sessionNode instanceof HTMLElement) { - var session = pageAiCurrentSession(); - var usageText = session && session.usage ? pageAiUsageSummary(session.usage) : ''; - sessionNode.textContent = session && session.id - ? [String(session.title || '当前页问答'), pageAiSessionStorageLabel(session), usageText].filter(Boolean).join(' · ') - : '等待 AI session'; - } - var modelNode = drawer.querySelector('[data-page-ai-model-status]'); - if (modelNode instanceof HTMLElement) modelNode.textContent = pageAiBuildAllowedRoots().length ? '已授权' : '需授权'; - var scopeSelect = drawer.querySelector('[data-page-ai-context-scope]'); - if (scopeSelect instanceof HTMLSelectElement) scopeSelect.value = pageUiState.pageAiContextScope; - var scopeLabel = drawer.querySelector('[data-page-ai-context-scope-label]'); - if (scopeLabel instanceof HTMLElement) scopeLabel.textContent = pageAiContextScopeLabel(pageUiState.pageAiContextScope); - drawer.querySelectorAll('[data-page-ai-tab]').forEach(function(button) { - var target = button.getAttribute('data-page-ai-tab') || 'chat'; - var active = target === pageUiState.pageAiPage; - button.classList.toggle('is-active', active); - button.setAttribute('aria-selected', active ? 'true' : 'false'); - }); - drawer.querySelectorAll('[data-page-ai-panel]').forEach(function(panel) { - if (panel instanceof HTMLElement) { - panel.hidden = panel.getAttribute('data-page-ai-panel') !== pageUiState.pageAiPage; - } - }); - var profileError = drawer.querySelector('[data-page-ai-profile-error]'); - if (profileError instanceof HTMLElement) { - profileError.textContent = pageUiState.pageAiProfileError || ''; - profileError.hidden = !pageUiState.pageAiProfileError; - } - var memoryError = drawer.querySelector('[data-page-ai-memory-error]'); - if (memoryError instanceof HTMLElement) { - var memoryErrorText = pageUiState.pageAiProfileMemoryError || ''; - if (memoryErrorText && memoryErrorText === pageUiState.pageAiProfileError) memoryErrorText = ''; - memoryError.textContent = memoryErrorText; - memoryError.hidden = !memoryErrorText; - } - var hermesMemoryPanel = drawer.querySelector('[data-page-ai-hermes-panel]'); - if (hermesMemoryPanel instanceof HTMLElement) { - hermesMemoryPanel.innerHTML = ['soul', 'user', 'memory'].map(function(section) { - var label = pageAiMemoryFileLabel(section); - var value = pageUiState.pageAiProfileMemoryDrafts[section] || ''; - return '' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + escapeHtml(label) + '
    ' + - '
    保存到 Hermes profile: ' + escapeHtml(activeProfile) + '
    ' + - '
    ' + - '' + - '
    ' + - '' + - '
    '; - }).join(''); - } - var skillError = drawer.querySelector('[data-page-ai-skill-error]'); - if (skillError instanceof HTMLElement) { - skillError.textContent = pageUiState.pageAiSkillError || ''; - skillError.hidden = !pageUiState.pageAiSkillError; - } - var sessionError = drawer.querySelector('[data-page-ai-session-error]'); - if (sessionError instanceof HTMLElement) { - sessionError.textContent = pageUiState.pageAiSessionError || ''; - sessionError.hidden = !pageUiState.pageAiSessionError; - } - var sessionSearch = drawer.querySelector('[data-page-ai-session-search]'); - if (sessionSearch instanceof HTMLInputElement && document.activeElement !== sessionSearch) { - sessionSearch.value = pageUiState.pageAiSessionSearchQuery || ''; - } - var skillSearch = drawer.querySelector('[data-page-ai-skill-search]'); - if (skillSearch instanceof HTMLInputElement && document.activeElement !== skillSearch) { - skillSearch.value = pageUiState.pageAiSkillQuery; - } - var skillList = drawer.querySelector('[data-page-ai-skill-list]'); - if (skillList instanceof HTMLElement) { - var skills = pageAiFilteredSkillEntries(); - if (!skills.length) { - skillList.innerHTML = '
    没有匹配的技能。
    '; - } else { - var groupLabels = { mnote: 'MNote 内置技能', reasonix: 'Reasonix 技能', hermes: 'Hermes 技能' }; - skillList.innerHTML = ['mnote', 'reasonix', 'hermes'].map(function(group) { - var groupSkills = skills.filter(function(skill) { return skill.group === group; }); - if (!groupSkills.length) return ''; - var headingExtra = group === 'hermes' ? ' · ' + pageAiCurrentProfile() : ''; - var collapsed = pageAiSkillGroupCollapsed(group); - return '' + - '
    ' + - '' + - (collapsed ? '' : groupSkills.map(function(skill) { - var sourceText = pageAiSkillOriginLabel(skill) + (skill.modified ? ' · modified' : ''); - var description = String(skill.description || '').trim(); - var hasDescription = description && description !== '---' && description !== '无描述'; - var displayName = String(skill.title || skill.name || skill.id || '').trim(); - return '' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + escapeHtml(displayName) + '
    ' + - '
    ' + escapeHtml(sourceText) + '
    ' + - '
    ' + - (hasDescription ? '
    ' + escapeHtml(description) + '
    ' : '') + - '
    ' + - '' + - '
    '; - }).join('')) + - '
    '; - }).join(''); - } - } - var toolsList = drawer.querySelector('[data-page-ai-tool-list]'); - if (toolsList instanceof HTMLElement) { - var tools = pageAiNormalizeArray(pageUiState.pageAiTools); - if (!tools.length) { - toolsList.innerHTML = '
    尚未读取到 mnote tool manifest。
    '; - } else { - toolsList.innerHTML = tools.map(function(tool) { - return '' + - '
    ' + - '
    ' + - '
    ' + escapeHtml(tool.name) + '
    ' + - '
    ' + escapeHtml(tool.scope || tool.kind || 'mnote') + ' · ' + escapeHtml(tool.status || 'available') + '
    ' + - (tool.unavailableReason ? '
    ' + escapeHtml(tool.unavailableReason) + '
    ' : '') + - '
    ' + - '' + - '
    '; - }).join(''); - } - } - var gatewayError = drawer.querySelector('[data-page-ai-gateway-error]'); - if (gatewayError instanceof HTMLElement) { - gatewayError.textContent = pageUiState.pageAiGatewayHealthError || ''; - gatewayError.hidden = !pageUiState.pageAiGatewayHealthError; - } - var gatewayStatusNode = drawer.querySelector('[data-page-ai-gateway-status]'); - var gatewayDetail = drawer.querySelector('[data-page-ai-gateway-detail]'); - var gatewayHealth = pageUiState.pageAiGatewayHealth; - if (gatewayStatusNode instanceof HTMLElement) { - if (!gatewayHealth) { - gatewayStatusNode.textContent = '未检查'; - } else { - var gateway = gatewayHealth.gateway || {}; - var profile = gatewayHealth.profile || {}; - gatewayStatusNode.textContent = gatewayHealth.ok ? '可用' : '需要设置'; - if (gateway.status) gatewayStatusNode.textContent += ' · ' + gateway.status; - if (profile.name) gatewayStatusNode.textContent += ' · ' + profile.name; - } - } - if (gatewayDetail instanceof HTMLElement) { - if (!gatewayHealth) { - gatewayDetail.innerHTML = '
    打开高级后会检查 agent runtime 与当前 profile。
    '; - } else { - var gatewayInfo = gatewayHealth.gateway || {}; - var profileInfo = gatewayHealth.profile || {}; - var suggestionText = pageAiNormalizeArray(gatewayHealth.suggestions).join(';'); - gatewayDetail.innerHTML = '' + - '
    ' + - '
    ' + escapeHtml(profileInfo.name || activeProfile) + '
    ' + - '
    model.default: ' + escapeHtml(profileInfo.modelDefault || '未设置') + '
    ' + - '
    provider: ' + escapeHtml(profileInfo.provider || '未设置') + ' · API key: ' + escapeHtml(profileInfo.apiKeyConfigured ? '已配置' : '未检测到') + '
    ' + - '
    ' + - '
    ' + - '
    ' + escapeHtml(gatewayInfo.upstream || '未配置 upstream') + '
    ' + - '
    gateway: ' + escapeHtml(gatewayInfo.status || 'unknown') + (gatewayInfo.httpStatus ? ' · HTTP ' + escapeHtml(gatewayInfo.httpStatus) : '') + '
    ' + - (suggestionText ? '
    ' + escapeHtml(suggestionText) + '
    ' : '') + - '
    '; - } - } - var toolError = drawer.querySelector('[data-page-ai-tool-error]'); - if (toolError instanceof HTMLElement) { - toolError.textContent = pageUiState.pageAiToolsError || ''; - toolError.hidden = !pageUiState.pageAiToolsError; - } - var lastTool = drawer.querySelector('[data-page-ai-last-tool]'); - if (lastTool instanceof HTMLElement) { - var call = pageUiState.pageAiLastToolCall; - lastTool.textContent = call - ? [call.event, call.name, call.runId, call.traceId || call.auditId].filter(Boolean).join(' · ') - : '暂无 tool call'; - } - var reasonixPanel = drawer.querySelector('[data-page-ai-reasonix-panel]'); - if (reasonixPanel instanceof HTMLElement) { - reasonixPanel.innerHTML = '
    Reasonix 专属设置
    ACP runtime / skills
    '; - } - var chatOnlyPanel = drawer.querySelector('[data-page-ai-chat-only-panel]'); - if (chatOnlyPanel instanceof HTMLElement) { - chatOnlyPanel.innerHTML = '
    Chat-only
    默认不申请文件写权限
    '; - } - } - - function humanizePageAiResponse(rawText, promptText) { - var providerLabel = pageAiProviderLabel(pageUiState.pageAiProvider); - var text = String(rawText || '').trim(); - if (!text) { - return providerLabel + ' 已收到你的问题“' + searchText(promptText) + '”,但这次没有返回可读内容。'; - } - if (text.startsWith('{')) { - try { - var payload = JSON.parse(text); - var operation = payload && payload.operation ? payload.operation : {}; - var normalized = operation && operation.normalized_input ? operation.normalized_input : {}; - var args = normalized && normalized.args ? normalized.args : {}; - var documentId = searchText(args.documentId || args.pageId || currentDocumentId()); - var toolName = searchText(operation.tool_name || normalized.toolName || 'doc_get'); - return providerLabel + ' 已收到你的问题“' + searchText(promptText) + '”。当前已通过 Hermes 调用 mnote plugin 工具,目标页面是 ' + (documentId || '当前页面') + ',本次选择的工具是 ' + toolName + '。如果你继续追问,我会沿当前页面上下文继续回复。'; - } catch (_) { - return providerLabel + ' 已返回结果,但当前结果是结构化文本,已为你保留原始内容。'; - } - } - return text; - } - - function ensurePageAiDrawer() { - var existing = document.querySelector('[data-testid="wolai-page-ai-drawer"]'); - if (existing instanceof HTMLElement) return existing; - var drawer = document.createElement('aside'); - drawer.className = 'wolai-page-ai-drawer'; - drawer.setAttribute('data-testid', 'wolai-page-ai-drawer'); - drawer.setAttribute('data-mnote-surface', 'page-ai'); - drawer.hidden = true; - drawer.innerHTML = '' + - ''; - document.body.appendChild(drawer); - return drawer; - } - - function renderPageAiSuggestions() { - var drawer = ensurePageAiDrawer(); - var list = drawer.querySelector('[data-page-ai-panel="chat"] [data-page-ai-suggestion-list]'); - if (!(list instanceof HTMLElement)) return; - var container = list.closest('.wolai-page-ai-suggestions'); - if (container instanceof HTMLElement) { - container.hidden = pageUiState.pageAiPage !== 'chat' || pageUiState.pageAiMessages.length > 0; - } - var suggestions = pageAiSuggestions(); - var offset = pageUiState.pageAiSuggestionIndex % suggestions.length; - var ordered = suggestions.slice(offset).concat(suggestions.slice(0, offset)).slice(0, 3); - list.innerHTML = ordered.map(function(text) { - return ''; - }).join(''); - } - - function renderPageAiConversation() { - var drawer = ensurePageAiDrawer(); - renderPageAiSuggestions(); - var conversation = drawer.querySelector('[data-page-ai-panel="' + cssEscape(pageUiState.pageAiPage || 'chat') + '"] [data-page-ai-conversation]'); - if (!(conversation instanceof HTMLElement)) return; - if (pageUiState.pageAiPage === 'history') { - var historyRows = pageUiState.pageAiSessionSearchResults.length - ? pageUiState.pageAiSessionSearchResults - : pageUiState.pageAiSessions; - if (!historyRows.length) { - conversation.innerHTML = '
    尚未产生历史会话。
    '; - return; - } - conversation.innerHTML = historyRows.map(function(session) { - var preview = Array.isArray(session.messages) && session.messages.length - ? session.messages.slice(-1)[0].content - : (session.snippet || session.preview || '暂无消息'); - var active = session.id === pageUiState.pageAiActiveSessionId; - var usage = pageAiUsageSummary(session.usage); - var meta = [pageAiSessionStorageLabel(session), session.permissionLevel, session.shareId, session.status, usage].filter(Boolean).join(' · '); - return '' + - '
    ' + - '' + - '
    ' + - '' + - '' + - '' + - '
    ' + - '
    '; - }).join(''); - return; - } - if (!pageUiState.pageAiMessages.length) { - conversation.innerHTML = '
    围绕当前页面提问,我会优先使用当前页内容、页面结构和已保存设置。
    '; - return; - } - conversation.innerHTML = pageUiState.pageAiMessages.map(function(item) { - var roleLabel = item.role === 'user' ? '你' : (item.role === 'tool' ? '工具' : 'AI'); - if (item.role === 'tool') { - var statusLabel = item.status === 'completed' ? '完成' : (item.status === 'failed' ? '失败' : '运行中'); - var locationRows = Array.isArray(item.locations) && item.locations.length - ? '
    位置:' + item.locations.map(function(loc, idx) { - return '' + - '' + escapeHtml(loc) + '' + - '' + - ''; - }).join('') + '
    ' - : ''; - var detailRows = [ - locationRows, - item.argsSummary ? '
    参数 ' + escapeHtml(item.argsSummary) + '
    ' : '', - item.resultSummary ? '
    结果 ' + escapeHtml(item.resultSummary) + '
    ' : '', - item.changedFiles && item.changedFiles.length ? '
    ' + escapeHtml(pageAiFormatChangedFiles(item.changedFiles)) + '
    ' : '', - (item.traceId || item.auditId) ? '
    ' + escapeHtml([item.traceId, item.auditId].filter(Boolean).join(' · ')) + '
    ' : '' - ].filter(Boolean).join(''); - return '' + - '
    ' + - '
    ' + escapeHtml(roleLabel) + '
    ' + - '
    ' + - '
    ' + - '' + - '' + escapeHtml(item.toolName || item.content || 'tool') + '' + - '' + escapeHtml([statusLabel, item.toolKind, item.toolCallId].filter(Boolean).join(' · ')) + '' + - '' + - (detailRows || '
    暂无参数或结果详情。
    ') + - '
    ' + - '
    ' + - '
    '; - } - if (item.kind === 'thought') { - return '' + - '
    ' + - '思考过程' + - '
    ' + escapeHtml(item.content || '') + '
    ' + - '
    '; - } - if (item.kind === 'permission') { - var permissionActions = item.resolved ? '' : ( - '
    ' + - '' + - '' + - '
    ' - ); - return '' + - '
    ' + - '
    权限
    ' + - '
    ' + - '' + escapeHtml(item.toolName || 'session/request_permission') + '
    ' + - '' + escapeHtml(item.argsSummary || item.content || '') + '' + - permissionActions + - '
    ' + - '
    '; - } - if (item.kind === 'plan') { - var planEntries = Array.isArray(item.entries) ? item.entries : []; - var listHtml = planEntries.map(function(entry, idx) { - return '
  • ' + escapeHtml(String(entry || '')) + '
  • '; - }).join(''); - return '' + - '
    ' + - '
    ' + - '执行计划 · ' + planEntries.length + ' 步' + - '
    ' + - '
      ' + listHtml + '
    ' + - '
    ' + - '
    ' + - '
    '; - } - var streamingAttr = item.streaming ? ' data-page-ai-streaming="true"' : ''; - return '' + - '
    ' + - '
    ' + escapeHtml(roleLabel) + '
    ' + - '
    ' + escapeHtml(item.content || '') + '
    ' + - '
    '; - }).join(''); - conversation.scrollTop = conversation.scrollHeight; - } function openPageAiDrawer() { pageUiState.pageAiAgentId = pageAiCurrentAgentId(); @@ -3551,6 +1818,7 @@ export function createSidebarPageAiRuntime(context) { renderPageAiControls(); var contextSnapshot = currentPageAiContextSnapshot(); var scopedContext = pageAiScopedPageContext(contextSnapshot); + scopedContext.editorTarget = currentPageAiScopedEditorTarget(); assertPageAiTargetInCurrentWorkspace(scopedContext.editorTarget); await assertPageAiTargetWritable(scopedContext.editorTarget); var runTargetSnapshot = pageAiBuildRunTargetSnapshot(scopedContext, prompt); @@ -3559,12 +1827,15 @@ export function createSidebarPageAiRuntime(context) { } var contextRefs = pageAiBuildContextRefs(scopedContext, runTargetSnapshot); var allowedRoots = pageAiBuildAllowedRoots(); + var agentTargetPackage = pageAiBuildAgentTargetPackage(scopedContext, runTargetSnapshot); if (scopedContext.pageContext && scopedContext.pageContext.aiContext) { scopedContext.pageContext.aiContext.runTargetSnapshot = runTargetSnapshot; + scopedContext.pageContext.aiContext.agentTargetPackage = agentTargetPackage; } var requestPageContext = pageAiPageContextForRefs(scopedContext.pageContext, contextRefs); pageUiState.pageAiMessages.push({ role: 'user', content: prompt }); currentSession = pageAiCurrentSession(); + var runProfile = pageAiRunProfile(); if (currentSession) { if (currentSession.title === '新会话') { currentSession.title = prompt.length > 18 ? prompt.slice(0, 18) + '…' : prompt; @@ -3587,7 +1858,9 @@ export function createSidebarPageAiRuntime(context) { rootUri: currentRootUri(), agentId: pageAiCurrentAgentId(), sessionId: pageUiState.pageAiActiveSessionId, - profile: pageAiRunProfile(), + acpSessionId: currentSession && currentSession.acpSessionId ? currentSession.acpSessionId : '', + profile: runProfile, + profileId: pageUiState.pageAiAcpRuntime === 'hermes' ? runProfile : '', acpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', contextScope: pageUiState.pageAiContextScope, contextRefs: contextRefs, @@ -3595,15 +1868,16 @@ export function createSidebarPageAiRuntime(context) { skillPreferences: { mnote: pageAiSkillPreferenceTable('mnote', ''), reasonix: pageAiSkillPreferenceTable('reasonix', ''), - hermes: pageAiSkillPreferenceTable('hermes', pageAiCurrentProfile()) + hermes: pageAiSkillPreferenceTable('hermes', runProfile) }, message: prompt, model: pageAiMnoteToolModel(), pageContext: requestPageContext, editorTarget: scopedContext.editorTarget, runTargetSnapshot: runTargetSnapshot, + targetPackage: agentTargetPackage, selectedBlockId: scopedContext.selectedBlockId, - selectedText: '', + selectedText: scopedContext.selectedText || '', traceId: 'page-ai-run-' + Date.now().toString(36) }) }); @@ -3754,8 +2028,15 @@ export function createSidebarPageAiRuntime(context) { try { var infoPayload = JSON.parse(payloadText || 'null') || {}; var newTitle = String(infoPayload.title || '').trim(); + var acpSessionId = String(infoPayload.acpSessionId || infoPayload.acp_session_id || '').trim(); + var sessionForInfo = pageAiCurrentSession(); + if (acpSessionId && sessionForInfo) { + sessionForInfo.acpSessionId = acpSessionId; + sessionForInfo.updatedAt = Date.now(); + pageAiPersistSessions(); + } if (newTitle) { - var sessionForTitle = pageAiCurrentSession(); + var sessionForTitle = sessionForInfo || pageAiCurrentSession(); if (sessionForTitle) { sessionForTitle.title = newTitle; sessionForTitle.updatedAt = Date.now(); @@ -3821,8 +2102,355 @@ export function createSidebarPageAiRuntime(context) { } } + function handlePageAiClick(event, helpers) { + var closestAction = helpers && helpers.closestAction; + if (typeof closestAction !== 'function') return false; + var pageAiClose = closestAction(event.target, '[data-page-ai-action="close"]'); + if (pageAiClose) { + event.preventDefault(); + closePageAiDrawer(); + return true; + } + var pageAiSettings = closestAction(event.target, '[data-page-ai-action="open-hermes-settings"]'); + if (pageAiSettings) { + event.preventDefault(); + pageAiOpenHermesSettings(); + return true; + } + var pageAiStop = closestAction(event.target, '[data-page-ai-action="stop-run"]'); + if (pageAiStop) { + event.preventDefault(); + void pageAiStopRun(); + return true; + } + var pageAiRotate = closestAction(event.target, '[data-page-ai-action="rotate"]'); + if (pageAiRotate) { + event.preventDefault(); + pageUiState.pageAiSuggestionIndex += 1; + renderPageAiSuggestions(); + return true; + } + var pageAiIntent = closestAction(event.target, '[data-page-ai-intent]'); + if (pageAiIntent) { + event.preventDefault(); + var intentName = pageAiIntent.getAttribute('data-page-ai-intent') || ''; + if (intentName === 'create-summary') void sendPageAiMessage('请通过 Hermes 调用 mnote.artifact.create_summary,为当前页面创建或更新 AI Summary。'); + if (intentName === 'create-ai-note') void sendPageAiMessage('请通过 Hermes 调用 mnote.artifact.create_ai_note,基于当前页面创建一篇新的 AI Note。'); + return true; + } + var pageAiTab = closestAction(event.target, '[data-page-ai-tab]'); + if (pageAiTab) { + event.preventDefault(); + pageUiState.pageAiPage = pageAiTab.getAttribute('data-page-ai-tab') || 'chat'; + if (pageUiState.pageAiPage === 'runtime') void pageAiLoadGatewayHealth(); + if (pageUiState.pageAiPage === 'skills') void pageAiLoadSkills(); + renderPageAiControls(); + renderPageAiConversation(); + return true; + } + var pageAiProvider = closestAction(event.target, '[data-page-ai-provider]'); + if (pageAiProvider) { + event.preventDefault(); + pageUiState.pageAiProvider = pageAiProvider.getAttribute('data-page-ai-provider') || 'hermes'; + renderPageAiProviderButtons(); + return true; + } + var pageAiAgent = closestAction(event.target, '[data-page-ai-agent-id]'); + if (pageAiAgent) { + event.preventDefault(); + var nextAgentId = pageAiAgent.getAttribute('data-page-ai-agent-id') || 'reasonix'; + var nextProfileId = pageAiAgent.getAttribute('data-page-ai-profile-id') || ''; + pageAiSetAgentId(nextAgentId); + if (nextProfileId) { + pageUiState.pageAiAgentPopoverOpen = false; + void pageAiSwitchProfile(nextProfileId); + renderPageAiControls(); + } + return true; + } + var pageAiAgentButton = closestAction(event.target, '[data-page-ai-agent-button]'); + if (pageAiAgentButton) { + event.preventDefault(); + pageAiSetAgentPopoverOpen(pageAiAgentButton.getAttribute('aria-expanded') !== 'true'); + return true; + } + var pageAiContextButton = closestAction(event.target, '[data-page-ai-context-button]'); + if (pageAiContextButton) { + event.preventDefault(); + pageAiSetContextPopoverOpen(pageAiContextButton.getAttribute('aria-expanded') !== 'true'); + return true; + } + var pageAiTargetButton = closestAction(event.target, '[data-page-ai-target-button]'); + if (pageAiTargetButton) { + event.preventDefault(); + pageAiSetTargetPopoverOpen(pageAiTargetButton.getAttribute('aria-expanded') !== 'true'); + return true; + } + var pageAiAction = closestAction(event.target, '[data-page-ai-action]'); + if (pageAiAction) { + event.preventDefault(); + var action = pageAiAction.getAttribute('data-page-ai-action') || ''; + if (action === 'close-agent-popover') pageAiSetAgentPopoverOpen(false); + if (action === 'close-context-popover') pageAiSetContextPopoverOpen(false); + if (action === 'close-target-popover') pageAiSetTargetPopoverOpen(false); + if (action === 'new-session') { + pageUiState.pageAiPage = 'chat'; + pageAiStartNewSession(); + } + if (action === 'history') { + pageAiLoadSessions(); + pageUiState.pageAiPage = pageUiState.pageAiPage === 'history' ? 'chat' : 'history'; + renderPageAiControls(); + renderPageAiConversation(); + if (pageUiState.pageAiPage === 'history') { + void pageAiLoadBackendSessions().catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + } + } + if (action === 'send') { + var input = ensurePageAiDrawer().querySelector('[data-page-ai-input]'); + if (input instanceof HTMLTextAreaElement) { + var message = input.value; + input.value = ''; + void sendPageAiMessage(message); + } + } + if (action === 'cancel-queued-run') { + void pageAiCancelQueuedRun(pageAiAction.getAttribute('data-page-ai-queue-id')); + } + return true; + } + var pageAiTargetOption = closestAction(event.target, '[data-page-ai-target-option]'); + if (pageAiTargetOption) { + event.preventDefault(); + pageAiSelectTarget(pageAiTargetOption.getAttribute('data-page-ai-target-option') || ''); + return true; + } + var pageAiContextRef = closestAction(event.target, '[data-page-ai-context-ref]'); + if (pageAiContextRef) { + event.preventDefault(); + pageAiToggleContextRef(pageAiContextRef.getAttribute('data-page-ai-context-ref') || ''); + return true; + } + var pageAiMemorySave = closestAction(event.target, '[data-page-ai-memory-save]'); + if (pageAiMemorySave) { + event.preventDefault(); + void pageAiSaveProfileMemory(pageAiMemorySave.getAttribute('data-page-ai-memory-save') || ''); + return true; + } + var pageAiSkillToggle = closestAction(event.target, '[data-page-ai-skill-toggle]'); + if (pageAiSkillToggle) { + event.preventDefault(); + void pageAiToggleSkill( + pageAiSkillToggle.getAttribute('data-page-ai-skill-toggle') || '', + pageAiSkillToggle.getAttribute('aria-pressed') !== 'true', + pageAiSkillToggle.getAttribute('data-page-ai-skill-group') || '', + pageAiSkillToggle.getAttribute('data-page-ai-skill-profile') || '' + ); + return true; + } + var pageAiSkillGroupToggle = closestAction(event.target, '[data-page-ai-skill-group-toggle]'); + if (pageAiSkillGroupToggle) { + event.preventDefault(); + pageAiToggleSkillGroup(pageAiSkillGroupToggle.getAttribute('data-page-ai-skill-group-toggle') || ''); + return true; + } + var pageAiToolToggle = closestAction(event.target, '[data-page-ai-tool-toggle]'); + if (pageAiToolToggle) { + event.preventDefault(); + void pageAiToggleTool(pageAiToolToggle.getAttribute('data-page-ai-tool-toggle') || '', pageAiToolToggle.getAttribute('aria-pressed') !== 'true'); + return true; + } + var pageAiSessionResume = closestAction(event.target, '[data-page-ai-session-resume]'); + if (pageAiSessionResume) { + event.preventDefault(); + void pageAiResumeBackendSession(pageAiSessionResume.getAttribute('data-page-ai-session-resume') || '').catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + return true; + } + var pageAiSessionRename = closestAction(event.target, '[data-page-ai-session-rename]'); + if (pageAiSessionRename) { + event.preventDefault(); + void pageAiRenameBackendSession(pageAiSessionRename.getAttribute('data-page-ai-session-rename') || '').catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + return true; + } + var pageAiSessionDelete = closestAction(event.target, '[data-page-ai-session-delete]'); + if (pageAiSessionDelete) { + event.preventDefault(); + void pageAiDeleteBackendSession(pageAiSessionDelete.getAttribute('data-page-ai-session-delete') || '').catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + return true; + } + var pageAiPermissionAction = closestAction(event.target, '[data-page-ai-permission-action]'); + if (pageAiPermissionAction) { + event.preventDefault(); + pageAiResolvePermission(pageAiPermissionAction.getAttribute('data-page-ai-permission-id') || '', pageAiPermissionAction.getAttribute('data-page-ai-permission-action') || 'deny'); + return true; + } + var pageAiOpenLocationAction = closestAction(event.target, '[data-page-ai-open-location]'); + if (pageAiOpenLocationAction) { + event.preventDefault(); + var loc = String(pageAiOpenLocationAction.getAttribute('data-page-ai-open-location') || '').trim(); + if (loc) pageAiOpenLocation(loc); + return true; + } + var pageAiSession = closestAction(event.target, '[data-page-ai-session]'); + if (pageAiSession) { + event.preventDefault(); + pageAiSetActiveSession(pageAiSession.getAttribute('data-page-ai-session') || ''); + return true; + } + var pageAiSuggestion = closestAction(event.target, '[data-page-ai-suggestion]'); + if (pageAiSuggestion) { + event.preventDefault(); + var text = pageAiSuggestion.getAttribute('data-page-ai-suggestion') || ''; + var inputNode = ensurePageAiDrawer().querySelector('[data-page-ai-input]'); + if (inputNode instanceof HTMLTextAreaElement) { + inputNode.value = text; + inputNode.focus(); + } + return true; + } + return false; + } + + function handlePageAiKeyDown(event, helpers) { + var closestAction = helpers && helpers.closestAction; + if (typeof closestAction !== 'function') return false; + if (event.key === 'Enter' && !event.shiftKey) { + var aiInput = closestAction(event.target, '[data-page-ai-input]'); + if (aiInput instanceof HTMLTextAreaElement) { + event.preventDefault(); + var text = aiInput.value; + aiInput.value = ''; + void sendPageAiMessage(text); + return true; + } + } + return false; + } + + function handlePageAiInput(event, helpers) { + var closestAction = helpers && helpers.closestAction; + if (typeof closestAction !== 'function') return false; + var skillSearch = closestAction(event.target, '[data-page-ai-skill-search]'); + if (skillSearch instanceof HTMLInputElement) { + pageUiState.pageAiSkillQuery = skillSearch.value; + renderPageAiControls(); + return true; + } + var sessionSearch = closestAction(event.target, '[data-page-ai-session-search]'); + if (sessionSearch instanceof HTMLInputElement) { + var sessionQuery = sessionSearch.value; + window.clearTimeout(pageUiState.pageAiSessionSearchTimer || 0); + pageUiState.pageAiSessionSearchTimer = window.setTimeout(function() { + void pageAiSearchBackendSessions(sessionQuery).catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + }, 200); + return true; + } + var memoryEditor = closestAction(event.target, '[data-page-ai-memory-editor]'); + if (memoryEditor instanceof HTMLTextAreaElement) { + var section = memoryEditor.getAttribute('data-page-ai-memory-editor') || ''; + if (['memory', 'user', 'soul'].indexOf(section) >= 0) pageUiState.pageAiProfileMemoryDrafts[section] = memoryEditor.value; + return true; + } + return false; + } + + function handlePageAiChange(event, helpers) { + var closestAction = helpers && helpers.closestAction; + if (typeof closestAction !== 'function') return false; + var pageAiAcpRuntimeSelect = closestAction(event.target, '[data-page-ai-acp-runtime]'); + if (pageAiAcpRuntimeSelect instanceof HTMLSelectElement) { + var next = String(pageAiAcpRuntimeSelect.value || 'reasonix').trim() || 'reasonix'; + pageUiState.pageAiAcpRuntime = next; + pageUiState.pageAiSkills = { categories: [], archived: [] }; + pageUiState.pageAiSkillError = ''; + pageAiPersistSessions(); + void pageAiLoadProfiles(); + if (next !== 'reasonix') void pageAiLoadProfileMemory(); + void pageAiLoadSkills(); + void pageAiLoadBackendSessions().catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + }); + renderPageAiControls(); + renderPageAiProviderButtons(); + return true; + } + var pageAiProfileSelect = closestAction(event.target, '[data-page-ai-profile-select]'); + if (pageAiProfileSelect instanceof HTMLSelectElement) { + void pageAiSwitchProfile(pageAiProfileSelect.value); + return true; + } + var pageAiSkillSourceSelect = closestAction(event.target, '[data-page-ai-skill-source-select]'); + if (pageAiSkillSourceSelect instanceof HTMLSelectElement) { + pageAiSetSkillSource(pageAiSkillSourceSelect.value); + return true; + } + var pageAiSessionAgentFilter = closestAction(event.target, '[data-page-ai-session-agent-filter]'); + if (pageAiSessionAgentFilter instanceof HTMLSelectElement) { + pageUiState.pageAiSessionAgentFilter = String(pageAiSessionAgentFilter.value || 'all').trim() || 'all'; + renderPageAiControls(); + renderPageAiConversation(); + return true; + } + var pageAiHideHermesBuiltin = closestAction(event.target, '[data-page-ai-hide-hermes-builtin]'); + if (pageAiHideHermesBuiltin instanceof HTMLInputElement) { + pageAiSetHideHermesBuiltinSkills(pageAiHideHermesBuiltin.checked); + return true; + } + var pageAiReasonixMemory = closestAction(event.target, '[data-page-ai-reasonix-memory]'); + if (pageAiReasonixMemory instanceof HTMLInputElement) { + pageAiSetReasonixMemoryEnabled(pageAiReasonixMemory.checked); + return true; + } + var pageAiContextSelect = closestAction(event.target, '[data-page-ai-context-scope]'); + if (pageAiContextSelect instanceof HTMLSelectElement) { + pageAiSetContextScope(pageAiContextSelect.value); + renderPageAiControls(); + return true; + } + return false; + } + + function installPageAiDelegates() { + if (pageAiDelegatesInstalled) return; + pageAiDelegatesInstalled = true; + var helpers = { closestAction: closestAction }; + document.addEventListener('click', function(event) { + handlePageAiClick(event, helpers); + }); + document.addEventListener('keydown', function(event) { + handlePageAiKeyDown(event, helpers); + }); + document.addEventListener('input', function(event) { + handlePageAiInput(event, helpers); + }); + document.addEventListener('change', function(event) { + handlePageAiChange(event, helpers); + }); + } + return { + ensurePageAiStateFacade: (...args) => ensurePageAiStateFacade(...args), + installPageAiDelegates: (...args) => installPageAiDelegates(...args), + handlePageAiClick: (...args) => handlePageAiClick(...args), + handlePageAiKeyDown: (...args) => handlePageAiKeyDown(...args), + handlePageAiInput: (...args) => handlePageAiInput(...args), + handlePageAiChange: (...args) => handlePageAiChange(...args), openPageAiDrawer: (...args) => openPageAiDrawer(...args), closePageAiDrawer: (...args) => closePageAiDrawer(...args), isPageAiDrawerOpen: (...args) => isPageAiDrawerOpen(...args), @@ -3849,13 +2477,17 @@ export function createSidebarPageAiRuntime(context) { pageAiLoadBackendSessions: (...args) => pageAiLoadBackendSessions(...args), pageAiCancelQueuedRun: (...args) => pageAiCancelQueuedRun(...args), pageAiSearchBackendSessions: (...args) => pageAiSearchBackendSessions(...args), + pageAiSetTargetPopoverOpen: (...args) => pageAiSetTargetPopoverOpen(...args), + pageAiSelectTarget: (...args) => pageAiSelectTarget(...args), pageAiPersistSessions: (...args) => pageAiPersistSessions(...args), pageAiLoadProfiles: (...args) => pageAiLoadProfiles(...args), pageAiLoadProfileMemory: (...args) => pageAiLoadProfileMemory(...args), pageAiLoadSkills: (...args) => pageAiLoadSkills(...args), pageAiSwitchProfile: (...args) => pageAiSwitchProfile(...args), pageAiToggleSkillGroup: (...args) => pageAiToggleSkillGroup(...args), + pageAiSetReasonixMemoryEnabled: (...args) => pageAiSetReasonixMemoryEnabled(...args), pageAiSetHideHermesBuiltinSkills: (...args) => pageAiSetHideHermesBuiltinSkills(...args), + pageAiSetSkillSource: (...args) => pageAiSetSkillSource(...args), pageAiSetContextScope: (...args) => pageAiSetContextScope(...args), pageAiSetAgentId: (...args) => pageAiSetAgentId(...args), pageAiToggleContextRef: (...args) => pageAiToggleContextRef(...args), diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-session-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-session-runtime.js new file mode 100644 index 00000000..750d08be --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-session-runtime.js @@ -0,0 +1,613 @@ +export function createSidebarPageAiSessionRuntime(context) { + const { + currentDocumentId, + currentRootUri, + currentSourceKind, + documentRef, + pageAiApplyRuntimeState, + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiErrorMessage, + pageAiNormalizeAgentId, + pageAiNormalizeArray, + pageAiNormalizeChatOnlyProfileId, + pageAiPermissionMessage, + pageAiPreviewValue, + pageAiRunProfile, + pageAiSetActiveProfile, + pageAiTimestamp, + pageUiState, + renderPageAiControls, + renderPageAiConversation, + resolveWorkspaceId, + sessionStorageVersion, + windowRef, + } = context; + const doc = documentRef || document; + const win = windowRef || window; + + function pageAiStorageKey() { + return 'hermes_page_ai_session:' + currentDocumentId(); + } + + function pageAiBackendSessionQuery(extra) { + var params = new URLSearchParams(); + params.set('source', 'acp'); + params.set('workspaceId', resolveWorkspaceId(doc.body)); + params.set('documentId', currentDocumentId()); + params.set('profile', pageAiRunProfile()); + params.set('sourceKind', currentSourceKind()); + if (currentRootUri()) params.set('rootUri', currentRootUri()); + Object.keys(extra || {}).forEach(function(key) { + var value = extra[key]; + if (value !== undefined && value !== null && String(value).trim() !== '') { + params.set(key, String(value)); + } + }); + return params.toString(); + } + + function pageAiNewSession(title) { + var now = Date.now(); + var agentId = pageAiCurrentAgentId(); + var profile = agentId === 'chat_only' ? pageAiNormalizeChatOnlyProfileId(pageAiCurrentProfile()) : pageAiCurrentProfile(); + return { + id: 'sess_' + now + '_' + Math.random().toString(16).slice(2, 8), + title: title || '新会话', + agentId: agentId, + profileId: pageUiState.pageAiAcpRuntime === 'hermes' ? profile : '', + profile: profile, + acpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', + createdAt: now, + updatedAt: now, + source: 'local', + usage: null, + status: 'idle', + messages: [] + }; + } + + function pageAiNormalizeSessions(sessions) { + return (Array.isArray(sessions) ? sessions : []) + .slice(0, 20) + .map(function(session) { + var sessionStorage = String(session && (session.sessionStorage || session.session_storage) || '').trim(); + var persistence = String(session && session.persistence || '').trim(); + var agentId = pageAiNormalizeAgentId(session && (session.agentId || session.agent_id)); + var profileId = String(session && (session.profileId || session.profile_id || '') || '').trim(); + var profile = String(session && session.profile || pageAiCurrentProfile()).trim() || 'default'; + if (!profileId && agentId !== 'reasonix') profileId = profile; + if (agentId === 'chat_only') { + profileId = pageAiNormalizeChatOnlyProfileId(profileId || profile); + profile = profileId; + } + return { + id: String(session && session.id || '').trim() || pageAiNewSession().id, + title: String(session && session.title || '').trim() || '新会话', + agentId: agentId, + profileId: profileId, + profile: profile, + acpRuntime: String(session && session.acpRuntime || 'reasonix').trim(), + createdAt: pageAiTimestamp(session && session.createdAt), + updatedAt: pageAiTimestamp(session && session.updatedAt), + source: String(session && session.source || 'local').trim() || 'local', + persistence: persistence, + sessionStorage: sessionStorage, + permissionLevel: String(session && (session.permissionLevel || session.permission_level) || '').trim(), + shareId: String(session && (session.shareId || session.share_id) || '').trim(), + acpSessionId: String(session && (session.acpSessionId || session.acp_session_id) || '').trim(), + runId: String(session && (session.runId || session.run_id) || '').trim(), + status: String(session && session.status || '').trim(), + usage: session && session.usage && typeof session.usage === 'object' ? session.usage : null, + preview: String(session && session.preview || '').trim(), + messages: Array.isArray(session && session.messages) ? session.messages.slice(-300) : [] + }; + }) + .sort(function(a, b) { + return Number(b.updatedAt || 0) - Number(a.updatedAt || 0); + }); + } + + function pageAiNormalizeBackendSessionRow(row) { + if (!row || typeof row !== 'object') return null; + var payload = row.payload && typeof row.payload === 'object' ? row.payload : {}; + var sessionId = String(row.sessionId || row.session_id || '').trim(); + if (!sessionId) return null; + var title = String(row.title || payload.title || payload.message || '').trim(); + if (title.length > 28) title = title.slice(0, 28) + '…'; + var persistence = String(row.persistence || payload.persistence || '').trim(); + var sessionStorage = String(row.sessionStorage || row.session_storage || payload.sessionStorage || '').trim(); + var agentId = pageAiNormalizeAgentId(row.agentId || row.agent_id || payload.agentId || payload.agent_id); + var profileId = String(row.profileId || row.profile_id || payload.profileId || payload.profile_id || '').trim(); + var profile = String(row.profile || payload.profile || pageAiRunProfile()).trim() || 'default'; + if (!profileId && agentId !== 'reasonix') profileId = profile; + if (agentId === 'chat_only') { + profileId = pageAiNormalizeChatOnlyProfileId(profileId || profile); + profile = profileId; + } + if (!sessionStorage && persistence === 'convex_acp_runtime_store') sessionStorage = 'cloud'; + if (!sessionStorage && persistence === 'local_ai_session_jsonl') sessionStorage = String(row.shareId || payload.shareId || '').trim() ? 'local_shared' : 'local_private'; + return { + id: sessionId, + title: title || '当前页问答', + agentId: agentId, + profileId: profileId, + profile: profile, + acpRuntime: String(row.acpRuntime || row.acp_runtime || payload.acpRuntime || 'reasonix').trim(), + createdAt: pageAiTimestamp(row.createdAt || row.created_at), + updatedAt: pageAiTimestamp(row.updatedAt || row.updated_at), + source: sessionStorage === 'local_private' || sessionStorage === 'local_shared' ? 'local' : 'acp', + persistence: persistence, + sessionStorage: sessionStorage, + permissionLevel: String(row.permissionLevel || row.permission_level || payload.permissionLevel || '').trim(), + shareId: String(row.shareId || row.share_id || payload.shareId || '').trim(), + acpSessionId: String(row.acpSessionId || row.acp_session_id || payload.acpSessionId || payload.acp_session_id || '').trim(), + runId: String(row.runId || row.run_id || '').trim(), + status: String(row.status || (row.runtime && row.runtime.status) || '').trim(), + usage: row.usage && typeof row.usage === 'object' ? row.usage : null, + preview: String(payload.message || row.snippet || '').trim(), + messages: [] + }; + } + + function pageAiMergeSessions(localSessions, backendSessions) { + var byId = {}; + pageAiNormalizeSessions(localSessions).forEach(function(session) { + byId[session.id] = session; + }); + pageAiNormalizeSessions(backendSessions).forEach(function(session) { + var existing = byId[session.id]; + byId[session.id] = Object.assign({}, existing || {}, session, { + messages: session.messages.length ? session.messages : (existing && existing.messages || []) + }); + }); + return pageAiNormalizeSessions(Object.keys(byId).map(function(id) { return byId[id]; })); + } + + function pageAiSessionStorageLabel(session) { + var storage = String(session && (session.sessionStorage || session.session_storage) || '').trim(); + var persistence = String(session && session.persistence || '').trim(); + if (storage === 'local_shared') return '共享会话'; + if (storage === 'local_private') return '本地私有'; + if (storage === 'cloud' || persistence === 'convex_acp_runtime_store') return '云端会话'; + if (persistence === 'local_ai_session_jsonl') return '本地私有'; + return String(session && session.source || '').trim() === 'acp' ? '云端会话' : '本地私有'; + } + + function pageAiLoadSessions() { + if (pageUiState.pageAiSessions.length && pageUiState.pageAiActiveSessionId) return; + try { + var raw = win.localStorage.getItem(pageAiStorageKey()); + var parsed = raw ? JSON.parse(raw) : null; + var activeId = String(parsed && parsed.activeSessionId || '').trim(); + var activeProfile = String(parsed && parsed.activeProfileName || '').trim(); + var activeAcpRuntime = String(parsed && parsed.activeAcpRuntime || '').trim(); + var sessions = pageAiNormalizeSessions(parsed && parsed.sessions); + var storageVersion = Number(parsed && parsed.version || 0); + if (storageVersion >= sessionStorageVersion && activeAcpRuntime) pageUiState.pageAiAcpRuntime = activeAcpRuntime; + if (activeProfile) pageAiSetActiveProfile(activeProfile); + if (sessions.length) { + pageUiState.pageAiSessions = sessions; + var activeSession = sessions.find(function(session) { return session.id === activeId; }) || sessions[0]; + pageUiState.pageAiActiveSessionId = activeSession.id; + if (activeSession.profile) pageAiSetActiveProfile(activeSession.profile); + if (activeSession.agentId) pageUiState.pageAiAgentId = pageAiNormalizeAgentId(activeSession.agentId); + if (!pageUiState.pageAiAcpRuntime && activeSession.acpRuntime) pageUiState.pageAiAcpRuntime = activeSession.acpRuntime; + pageUiState.pageAiMessages = Array.isArray(activeSession.messages) ? activeSession.messages.slice() : []; + return; + } + if (activeId) { + pageUiState.pageAiSessions = [pageAiNewSession('当前页问答')]; + pageUiState.pageAiSessions[0].id = activeId; + pageUiState.pageAiActiveSessionId = activeId; + pageUiState.pageAiMessages = []; + return; + } + } catch (_) {} + var fresh = pageAiNewSession(); + pageUiState.pageAiSessions = [fresh]; + pageUiState.pageAiActiveSessionId = fresh.id; + pageUiState.pageAiMessages = []; + } + + async function pageAiLoadBackendSessions() { + var response = await fetch('/api/hermes/client/sessions?' + pageAiBackendSessionQuery({ limit: 50 }), { + headers: { 'accept': 'application/json' } + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_list_failed_' + response.status)); + } + var backendSessions = pageAiNormalizeArray(payload.sessions).map(pageAiNormalizeBackendSessionRow).filter(Boolean); + if (!backendSessions.length) return []; + pageUiState.pageAiSessions = pageAiMergeSessions(pageUiState.pageAiSessions, backendSessions); + if (!pageUiState.pageAiActiveSessionId || !pageUiState.pageAiSessions.find(function(session) { return session.id === pageUiState.pageAiActiveSessionId; })) { + pageUiState.pageAiActiveSessionId = pageUiState.pageAiSessions[0].id; + } + var active = pageAiCurrentSession(); + if (active) { + if (active.profile) pageAiSetActiveProfile(active.profile); + if (!pageUiState.pageAiAcpRuntime && active.acpRuntime) pageUiState.pageAiAcpRuntime = active.acpRuntime; + pageUiState.pageAiMessages = Array.isArray(active.messages) ? active.messages.slice() : pageUiState.pageAiMessages; + } + pageUiState.pageAiSessionError = ''; + pageAiPersistSessions(); + renderPageAiConversation(); + renderPageAiControls(); + return backendSessions; + } + + function pageAiMessageFromRuntimeEvent(event) { + if (!event || typeof event !== 'object') return null; + var eventType = String(event.eventType || event.event_type || event.event || '').trim(); + var payload = event.payload && typeof event.payload === 'object' ? event.payload : event; + if (eventType === 'message.delta') { + var delta = String(payload.delta || payload.text || payload.output_text || '').trim(); + return delta ? { role: 'assistant', content: delta } : null; + } + if (eventType === 'thought.delta') { + var thought = String(payload.delta || payload.text || '').trim(); + return thought ? { role: 'assistant', kind: 'thought', content: thought } : null; + } + if (eventType === 'tool.started' || eventType === 'tool.completed' || eventType === 'tool.failed') { + var toolName = String(payload.toolName || payload.tool || payload.name || eventType).trim(); + var rawLocations = payload.locations; + return { + role: 'tool', + content: toolName, + toolName: toolName, + toolCallId: String(payload.toolCallId || payload.tool_call_id || payload.id || ''), + toolKind: String(payload.kind || ''), + status: eventType === 'tool.completed' ? 'completed' : (eventType === 'tool.failed' ? 'failed' : 'running'), + argsSummary: pageAiPreviewValue(payload.args || payload.arguments || payload.input), + resultSummary: pageAiPreviewValue(payload.summary || payload.result || payload.output || payload.error), + locations: Array.isArray(rawLocations) ? rawLocations.filter(function(l) { return typeof l === 'string' || (typeof l === 'object' && l && l.path); }).map(function(l) { return typeof l === 'string' ? l : l.path; }) : [], + traceId: String(payload.traceId || payload.trace_id || ''), + auditId: String(payload.auditId || payload.audit_id || '') + }; + } + if (eventType === 'permission.requested' || eventType === 'permission.denied' || eventType === 'permission.allowed') { + return pageAiPermissionMessage(payload, eventType); + } + if (eventType === 'run.completed') { + var output = String(payload.output || payload.text || '').trim(); + return output ? { role: 'assistant', content: output } : null; + } + return null; + } + + function pageAiApplyBackendSessionDetail(payload) { + var sessionPayload = payload && payload.session ? payload.session : {}; + var runs = pageAiNormalizeArray(sessionPayload.runs); + var latest = runs.length ? pageAiNormalizeBackendSessionRow(runs[0]) : null; + var events = pageAiNormalizeArray(payload && payload.events); + var storedMessages = pageAiNormalizeArray(sessionPayload.messages).map(function(message) { + return { + role: message.role === 'user' ? 'user' : (message.role === 'tool' ? 'tool' : 'assistant'), + content: String(message.content || '') + }; + }).filter(function(message) { return message.content; }); + var eventsByRunId = {}; + events.forEach(function(event) { + var runId = String(event && (event.runId || event.run_id) || '').trim(); + if (!runId) return; + if (!eventsByRunId[runId]) eventsByRunId[runId] = []; + eventsByRunId[runId].push(event); + }); + var messages = []; + if (runs.length) { + runs.slice().reverse().forEach(function(run) { + var runPayload = run && run.payload && typeof run.payload === 'object' ? run.payload : {}; + var userMessage = String(runPayload.message || runPayload.input || '').trim(); + if (userMessage) messages.push({ role: 'user', content: userMessage }); + var runId = String(run && (run.runId || run.run_id) || '').trim(); + pageAiNormalizeArray(eventsByRunId[runId]).forEach(function(event) { + var message = pageAiMessageFromRuntimeEvent(event); + if (message) messages.push(message); + }); + }); + } + if (!messages.length) messages = storedMessages; + var acpSessionId = ''; + events.forEach(function(event) { + var eventType = String(event && (event.eventType || event.event_type || event.event) || '').trim(); + var payload = event && event.payload && typeof event.payload === 'object' ? event.payload : event; + if (eventType === 'session.info.updated') { + var nextAcpSessionId = String(payload && (payload.acpSessionId || payload.acp_session_id) || '').trim(); + if (nextAcpSessionId) acpSessionId = nextAcpSessionId; + } + }); + var current = pageAiCurrentSession(); + if (latest && current) { + Object.assign(current, latest); + } + if (current) { + current.messages = messages.slice(-300); + current.updatedAt = Math.max(Number(current.updatedAt || 0), Date.now()); + if (acpSessionId) current.acpSessionId = acpSessionId; + if (latest && latest.usage) current.usage = latest.usage; + } + pageAiApplyRuntimeState(payload && payload.runtime); + pageUiState.pageAiMessages = messages.slice(-300); + pageAiPersistSessions(); + } + + async function pageAiLoadBackendSessionDetail(sessionId) { + sessionId = String(sessionId || pageUiState.pageAiActiveSessionId || '').trim(); + if (!sessionId) return null; + var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '?' + pageAiBackendSessionQuery({ limit: 200 }), { + headers: { 'accept': 'application/json' } + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_detail_failed_' + response.status)); + } + pageAiApplyBackendSessionDetail(payload); + renderPageAiConversation(); + renderPageAiControls(); + return payload; + } + + async function pageAiSearchBackendSessions(query) { + var q = String(query || '').trim(); + pageUiState.pageAiSessionSearchQuery = q; + if (!q) { + pageUiState.pageAiSessionSearchResults = []; + renderPageAiConversation(); + return []; + } + var response = await fetch('/api/hermes/client/sessions/search?' + pageAiBackendSessionQuery({ q: q, limit: 20 }), { + headers: { 'accept': 'application/json' } + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_search_failed_' + response.status)); + } + pageUiState.pageAiSessionSearchResults = pageAiNormalizeArray(payload.results).map(function(row) { + var normalized = pageAiNormalizeBackendSessionRow(row) || {}; + normalized.snippet = String(row && row.snippet || normalized.preview || '').trim(); + return normalized; + }).filter(function(row) { return row.id; }); + renderPageAiConversation(); + return pageUiState.pageAiSessionSearchResults; + } + + function pageAiPersistSessions() { + doc.documentElement.setAttribute('data-mnote-page-ai-session-owner', 'hermes'); + doc.documentElement.setAttribute('data-mnote-page-ai-session-key', pageAiStorageKey()); + try { + pageAiSyncCurrentSessionMessages(); + win.localStorage.setItem(pageAiStorageKey(), JSON.stringify({ + version: sessionStorageVersion, + activeSessionId: pageUiState.pageAiActiveSessionId, + activeProfileName: pageAiCurrentProfile(), + activeAcpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', + sessions: pageAiNormalizeSessions(pageUiState.pageAiSessions) + })); + } catch (_) {} + } + + async function pageAiEnsureHermesSession(forceCreate) { + pageAiLoadSessions(); + var current = pageAiCurrentSession(); + var runProfile = pageAiRunProfile(); + if (!forceCreate && current && String(current.id || '').startsWith('mnote_') && current.profile === runProfile) return current; + var response = await fetch('/api/hermes/client/sessions', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ + workspaceId: resolveWorkspaceId(doc.body), + documentId: currentDocumentId(), + sourceKind: currentSourceKind(), + rootUri: currentRootUri(), + traceId: 'page-ai-' + Date.now().toString(36), + profile: runProfile, + agentId: pageAiCurrentAgentId(), + profileId: pageUiState.pageAiAcpRuntime === 'hermes' ? runProfile : '', + title: current && current.title ? current.title : '当前页问答' + }) + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'hermes_session_failed_' + response.status)); + } + var session = { + id: String(payload.sessionId || '').trim(), + title: String(payload.title || '当前页问答'), + agentId: pageAiCurrentAgentId(), + profileId: pageUiState.pageAiAcpRuntime === 'hermes' ? runProfile : '', + profile: String(payload.profile || runProfile).trim() || 'default', + acpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix', + persistence: String(payload.persistence || '').trim(), + sessionStorage: String(payload.sessionStorage || '').trim(), + permissionLevel: String(payload.permissionLevel || '').trim(), + shareId: String(payload.shareId || '').trim(), + acpSessionId: String(payload.acpSessionId || payload.acp_session_id || '').trim(), + createdAt: Date.now(), + updatedAt: Date.now(), + messages: pageUiState.pageAiMessages.slice() + }; + pageUiState.pageAiSessions = pageAiNormalizeSessions([session]); + pageUiState.pageAiActiveSessionId = session.id; + pageAiPersistSessions(); + renderPageAiConversation(); + return session; + } + + async function pageAiRestoreHermesSession() { + var current = pageAiCurrentSession(); + if (!current || !String(current.id || '').startsWith('mnote_')) return; + var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(current.id) + '/resume?' + pageAiBackendSessionQuery({}), { + method: 'POST', + headers: { 'accept': 'application/json' } + }); + if (!response.ok) return; + var payload = await response.json().catch(function(){ return null; }); + if (payload && payload.persistence === 'convex_acp_runtime_store') { + pageAiApplyBackendSessionDetail(payload); + renderPageAiConversation(); + renderPageAiControls(); + return; + } + var session = payload && (payload.session || (payload.upstream && payload.upstream.session) || payload); + var messages = session && Array.isArray(session.messages) ? session.messages : []; + pageAiApplyRuntimeState(payload && payload.runtime); + if (session && (session.profile || session.profileName)) { + current.profile = String(session.profile || session.profileName || current.profile || pageAiCurrentProfile()); + } + if (!messages.length) { + renderPageAiControls(); + return; + } + pageUiState.pageAiMessages = messages.slice(-300).map(function(message) { + return { + role: message.role === 'user' ? 'user' : (message.role === 'tool' ? 'tool' : 'assistant'), + content: String(message.content || '') + }; + }); + current.messages = pageUiState.pageAiMessages.slice(); + current.updatedAt = Date.now(); + renderPageAiConversation(); + renderPageAiControls(); + } + + function pageAiCurrentSession() { + return pageUiState.pageAiSessions.find(function(session) { + return session.id === pageUiState.pageAiActiveSessionId; + }) || null; + } + + function pageAiSyncCurrentSessionMessages() { + var session = pageAiCurrentSession(); + if (!session) return; + var runProfile = pageAiRunProfile(); + session.messages = Array.isArray(pageUiState.pageAiMessages) ? pageUiState.pageAiMessages.slice(-300) : []; + session.agentId = pageAiCurrentAgentId(); + session.profileId = pageUiState.pageAiAcpRuntime === 'hermes' ? runProfile : ''; + session.profile = runProfile; + session.acpRuntime = pageUiState.pageAiAcpRuntime || 'reasonix'; + session.updatedAt = Date.now(); + } + + function pageAiSetActiveSession(sessionId) { + var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); + if (!session) return; + pageUiState.pageAiActiveSessionId = session.id; + if (session.agentId) pageUiState.pageAiAgentId = pageAiNormalizeAgentId(session.agentId); + if (session.acpRuntime) pageUiState.pageAiAcpRuntime = session.acpRuntime; + if (session.profileId || session.profile) pageAiSetActiveProfile(session.profileId || session.profile); + pageUiState.pageAiMessages = Array.isArray(session.messages) ? session.messages.slice() : []; + pageUiState.pageAiPage = 'chat'; + pageAiPersistSessions(); + renderPageAiControls(); + renderPageAiConversation(); + if (session.source === 'acp' || String(session.id || '').startsWith('mnote_')) { + void pageAiLoadBackendSessionDetail(session.id).catch(function(error) { + pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); + renderPageAiControls(); + }); + } + } + + function pageAiStartNewSession() { + var session = pageAiNewSession(); + pageUiState.pageAiSessions = pageAiNormalizeSessions([session].concat(pageUiState.pageAiSessions)); + pageUiState.pageAiActiveSessionId = session.id; + pageUiState.pageAiMessages = []; + pageUiState.pageAiPage = 'chat'; + pageAiPersistSessions(); + renderPageAiControls(); + renderPageAiConversation(); + } + + async function pageAiRenameBackendSession(sessionId) { + var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); + if (!session) return; + var title = win.prompt('重命名 AI 会话', session.title || '当前页问答'); + if (title === null) return; + title = String(title || '').trim(); + if (!title) return; + var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '/rename?' + pageAiBackendSessionQuery({}), { + method: 'POST', + headers: { 'content-type': 'application/json', 'accept': 'application/json' }, + body: JSON.stringify({ title: title }) + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_rename_failed_' + response.status)); + } + session.title = String((payload.result && payload.result.title) || title); + session.updatedAt = Date.now(); + pageAiPersistSessions(); + renderPageAiConversation(); + renderPageAiControls(); + } + + async function pageAiDeleteBackendSession(sessionId) { + var session = pageUiState.pageAiSessions.find(function(item) { return item.id === sessionId; }); + if (!session) return; + if (!win.confirm('确定删除 AI 会话“' + (session.title || sessionId) + '”吗?')) return; + var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '?' + pageAiBackendSessionQuery({}), { + method: 'DELETE', + headers: { 'accept': 'application/json' } + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_delete_failed_' + response.status)); + } + pageUiState.pageAiSessions = pageUiState.pageAiSessions.filter(function(item) { return item.id !== sessionId; }); + if (pageUiState.pageAiActiveSessionId === sessionId) { + var next = pageUiState.pageAiSessions[0] || pageAiNewSession(); + if (!pageUiState.pageAiSessions.length) pageUiState.pageAiSessions = [next]; + pageUiState.pageAiActiveSessionId = next.id; + pageUiState.pageAiMessages = Array.isArray(next.messages) ? next.messages.slice() : []; + } + pageAiPersistSessions(); + renderPageAiConversation(); + renderPageAiControls(); + } + + async function pageAiResumeBackendSession(sessionId) { + sessionId = String(sessionId || pageUiState.pageAiActiveSessionId || '').trim(); + if (!sessionId) return; + pageAiSetActiveSession(sessionId); + var response = await fetch('/api/hermes/client/sessions/' + encodeURIComponent(sessionId) + '/resume?' + pageAiBackendSessionQuery({}), { + method: 'POST', + headers: { 'accept': 'application/json' } + }); + var payload = await response.json().catch(function(){ return null; }); + if (!response.ok || !payload || payload.ok !== true) { + throw new Error(pageAiErrorMessage(payload, 'session_resume_failed_' + response.status)); + } + pageAiApplyBackendSessionDetail(payload); + pageUiState.pageAiPage = 'chat'; + renderPageAiConversation(); + renderPageAiControls(); + } + + return { + pageAiStorageKey, + pageAiBackendSessionQuery, + pageAiNewSession, + pageAiNormalizeSessions, + pageAiNormalizeBackendSessionRow, + pageAiMergeSessions, + pageAiSessionStorageLabel, + pageAiLoadSessions, + pageAiLoadBackendSessions, + pageAiMessageFromRuntimeEvent, + pageAiApplyBackendSessionDetail, + pageAiLoadBackendSessionDetail, + pageAiSearchBackendSessions, + pageAiPersistSessions, + pageAiEnsureHermesSession, + pageAiRestoreHermesSession, + pageAiCurrentSession, + pageAiSyncCurrentSessionMessages, + pageAiSetActiveSession, + pageAiStartNewSession, + pageAiRenameBackendSession, + pageAiDeleteBackendSession, + pageAiResumeBackendSession + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-skill-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-skill-runtime.js new file mode 100644 index 00000000..06bdbd50 --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-skill-runtime.js @@ -0,0 +1,285 @@ +export function createSidebarPageAiSkillRuntime(context) { + const { + pageAiCurrentAgentId, + pageAiCurrentProfile, + pageAiLoadSkills, + pageAiNormalizeArray, + pageAiPersistAiPreference, + pageAiPersistRawAiPreference, + pageAiProfileValue, + pageUiState, + renderPageAiControls, + } = context; + + function pageAiSkillSourceOptions() { + var options = [ + { value: 'mnote', group: 'mnote', label: 'mnote', profile: '' }, + { value: 'reasonix', group: 'reasonix', label: 'reasonix', profile: '' } + ]; + pageAiNormalizeArray(pageUiState.pageAiProfiles).forEach(function(profile) { + var profileId = pageAiProfileValue(profile); + if (!profileId) return; + var label = profile.kind === 'shared' + ? (profile.baseProfile === 'lite' || profileId === 'shared_lite' ? 'hermes_lite' : 'Hermes_shared') + : 'Hermes_user'; + var alias = String(profile.alias || '').trim(); + options.push({ + value: 'hermes:' + profileId, + group: 'hermes', + profile: profileId, + label: alias && alias !== label ? label + ' · ' + alias : label, + readonly: profile.readonly === true + }); + }); + return options; + } + + function pageAiDefaultSkillSource() { + if (pageAiCurrentAgentId() === 'hermes') return 'hermes:' + pageAiCurrentProfile(); + if (pageAiCurrentAgentId() === 'reasonix') return 'reasonix'; + return 'mnote'; + } + + function pageAiNormalizeSkillSource(source) { + var value = String(source || '').trim(); + var options = pageAiSkillSourceOptions(); + if (options.some(function(option) { return option.value === value; })) return value; + if (value === 'hermes') return 'hermes:' + pageAiCurrentProfile(); + if (value === 'mnote_builtin') return 'mnote'; + var fallback = pageAiDefaultSkillSource(); + if (options.some(function(option) { return option.value === fallback; })) return fallback; + return options.length ? options[0].value : 'mnote'; + } + + function pageAiCurrentSkillSource() { + var normalized = pageAiNormalizeSkillSource(pageUiState.pageAiActiveSkillSource); + pageUiState.pageAiActiveSkillSource = normalized; + return normalized; + } + + function pageAiSetSkillSource(source) { + var normalized = pageAiNormalizeSkillSource(source); + pageUiState.pageAiActiveSkillSource = normalized; + pageAiPersistAiPreference('skills.active_source', normalized); + pageUiState.pageAiSkills = { categories: [], archived: [] }; + pageUiState.pageAiSkillError = ''; + void pageAiLoadSkills(); + renderPageAiControls(); + } + + function pageAiSkillSourceParts(source) { + var normalized = pageAiNormalizeSkillSource(source); + if (normalized.indexOf('hermes:') === 0) { + return { group: 'hermes', profile: normalized.slice('hermes:'.length), source: normalized }; + } + if (normalized === 'reasonix') return { group: 'reasonix', profile: '', source: normalized }; + return { group: 'mnote', profile: '', source: 'mnote' }; + } + + function pageAiCurrentSkillSourceLabel() { + var source = pageAiCurrentSkillSource(); + var option = pageAiSkillSourceOptions().find(function(item) { return item.value === source; }); + return option ? option.label : source; + } + + function pageAiSkillOriginLabel(skill) { + var origin = String(skill && skill.origin || '').trim(); + if (origin === 'generated' || String(skill && skill.createdBy || '') === 'agent') return '生成'; + if (origin === 'installed') return '安装'; + if (origin === 'builtin') return '内置'; + if (origin === 'copied') return '本地'; + var source = String(skill && skill.source || '').trim(); + if (source === 'hub') return '安装'; + if (source === 'builtin') return '内置'; + if (source === 'reasonix') { + if (origin === 'project') return 'Reasonix 项目'; + if (origin === 'global') return 'Reasonix 全局'; + return 'Reasonix'; + } + return '本地'; + } + + function pageAiSkillPreferenceKey(group, profile) { + var groupName = String(group || '').trim(); + if (groupName === 'mnote') return 'ai.agent.mnote_builtin.skills.enabled'; + if (groupName === 'reasonix') return 'ai.agent.reasonix.skills.enabled'; + if (groupName === 'hermes') { + var nextProfile = String(profile || pageAiCurrentProfile() || 'default').trim() || 'default'; + return 'ai.agent.hermes.profile.' + nextProfile + '.skills.enabled'; + } + return ''; + } + + function pageAiSkillPreferenceTable(group, profile) { + var key = pageAiSkillPreferenceKey(group, profile); + var preferences = pageUiState.pageAiSkillPreferences || {}; + var value = preferences[key]; + if (value && typeof value === 'object' && !Array.isArray(value)) return value; + return {}; + } + + function pageAiHermesHideBuiltinPreferenceKey(profile) { + return 'ai.agent.hermes.skills.hide_builtin'; + } + + function pageAiHideHermesBuiltinSkills(profile) { + var preferences = pageUiState.pageAiSkillPreferences || {}; + return preferences[pageAiHermesHideBuiltinPreferenceKey(profile)] === true; + } + + function pageAiReasonixMemoryEnabled() { + var preferences = pageUiState.pageAiSkillPreferences || {}; + return preferences['ai.agent.reasonix.memory_enabled'] === true; + } + + function pageAiSetReasonixMemoryEnabled(enabled) { + var preferences = Object.assign({}, pageUiState.pageAiSkillPreferences || {}); + preferences['ai.agent.reasonix.memory_enabled'] = Boolean(enabled); + pageUiState.pageAiSkillPreferences = preferences; + pageAiPersistRawAiPreference('ai.agent.reasonix.memory_enabled', Boolean(enabled)); + renderPageAiControls(); + } + + function pageAiSetHideHermesBuiltinSkills(enabled, profile) { + var key = pageAiHermesHideBuiltinPreferenceKey(profile); + var preferences = Object.assign({}, pageUiState.pageAiSkillPreferences || {}); + preferences[key] = Boolean(enabled); + pageUiState.pageAiSkillPreferences = preferences; + pageAiPersistRawAiPreference(key, Boolean(enabled)); + renderPageAiControls(); + } + + function pageAiSkillIsBuiltin(skill) { + var origin = String(skill && skill.origin || '').trim(); + var source = String(skill && skill.source || '').trim(); + return origin === 'builtin' || source === 'builtin'; + } + + function pageAiToggleableSkillEntries(group, profile) { + var catalogKey = group === 'hermes' && profile ? 'hermes:' + profile : group; + var catalog = pageUiState.pageAiSkillCatalogs && pageUiState.pageAiSkillCatalogs[catalogKey] + ? pageUiState.pageAiSkillCatalogs[catalogKey] + : pageUiState.pageAiSkillCatalogs && pageUiState.pageAiSkillCatalogs[group] + ? pageUiState.pageAiSkillCatalogs[group] + : { categories: [], archived: [] }; + var overrides = pageAiSkillPreferenceTable(group, profile); + var result = []; + pageAiNormalizeArray(catalog.categories).forEach(function(category) { + pageAiNormalizeArray(category.skills).forEach(function(skill) { + var id = String(skill.id || skill.name || '').trim(); + if (!id) return; + result.push({ + group: group, + profile: profile || '', + category: category.name, + id: id, + name: skill.name || id, + title: skill.title || skill.name || id, + description: skill.description || '', + enabled: group === 'hermes' ? skill.enabled !== false : (skill.enabled !== false && overrides[id] !== false), + toggleable: skill.toggleable !== false, + source: skill.source || group, + origin: skill.origin || '', + readOnly: skill.readOnly === true || skill.readonly === true || skill.configurable === false, + builtin: pageAiSkillIsBuiltin(skill), + configurable: skill.configurable !== false, + configScope: skill.configScope || '', + skillKind: skill.skillKind || '', + profileId: skill.profileId || '', + toolNames: skill.toolNames || [], + requiresContextRefs: skill.requiresContextRefs || [] + }); + }); + }); + pageAiNormalizeArray(catalog.archived).forEach(function(skill) { + var id = String(skill.id || skill.name || '').trim(); + if (!id) return; + result.push({ + group: group, + profile: profile || '', + category: 'archived', + id: id, + name: skill.name || id, + title: skill.title || skill.name || id, + description: skill.description || '', + enabled: group === 'hermes' ? skill.enabled !== false : (skill.enabled !== false && overrides[id] !== false), + toggleable: skill.toggleable !== false, + source: skill.source || group, + origin: skill.origin || '', + readOnly: skill.readOnly === true || skill.readonly === true || skill.configurable === false, + builtin: pageAiSkillIsBuiltin(skill), + configurable: skill.configurable !== false, + configScope: skill.configScope || '', + skillKind: skill.skillKind || '', + profileId: skill.profileId || '', + toolNames: skill.toolNames || [], + requiresContextRefs: skill.requiresContextRefs || [] + }); + }); + return result; + } + + function pageAiAllSkillEntries() { + return [] + .concat(pageAiToggleableSkillEntries('mnote', '')) + .concat(pageAiToggleableSkillEntries('reasonix', '')) + .concat(pageAiToggleableSkillEntries('hermes', pageAiCurrentProfile())); + } + + function pageAiSkillGroupCollapsed(group) { + var table = pageUiState.pageAiCollapsedSkillGroups || {}; + return table[String(group || '').trim()] === true; + } + + function pageAiToggleSkillGroup(group) { + var normalized = String(group || '').trim(); + if (!normalized) return; + var table = Object.assign({}, pageUiState.pageAiCollapsedSkillGroups || {}); + table[normalized] = table[normalized] !== true; + pageUiState.pageAiCollapsedSkillGroups = table; + pageAiPersistRawAiPreference('ai.common.skills.groups.collapsed', table); + renderPageAiControls(); + } + + function pageAiSetSkillPreference(group, skillId, enabled, profile) { + var key = pageAiSkillPreferenceKey(group, profile); + if (!key || !skillId) return; + var preferences = Object.assign({}, pageUiState.pageAiSkillPreferences || {}); + var current = preferences[key] && typeof preferences[key] === 'object' && !Array.isArray(preferences[key]) + ? Object.assign({}, preferences[key]) + : {}; + current[skillId] = Boolean(enabled); + preferences[key] = current; + pageUiState.pageAiSkillPreferences = preferences; + pageAiPersistRawAiPreference(key, current); + } + + function pageAiSkillEnabled(skill) { + return skill.enabled !== false; + } + + return { + pageAiSkillSourceOptions, + pageAiDefaultSkillSource, + pageAiNormalizeSkillSource, + pageAiCurrentSkillSource, + pageAiSetSkillSource, + pageAiSkillSourceParts, + pageAiCurrentSkillSourceLabel, + pageAiSkillOriginLabel, + pageAiSkillPreferenceKey, + pageAiSkillPreferenceTable, + pageAiHermesHideBuiltinPreferenceKey, + pageAiHideHermesBuiltinSkills, + pageAiReasonixMemoryEnabled, + pageAiSetReasonixMemoryEnabled, + pageAiSetHideHermesBuiltinSkills, + pageAiSkillIsBuiltin, + pageAiToggleableSkillEntries, + pageAiAllSkillEntries, + pageAiSkillGroupCollapsed, + pageAiToggleSkillGroup, + pageAiSetSkillPreference, + pageAiSkillEnabled + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-ai-target-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-ai-target-runtime.js new file mode 100644 index 00000000..9f6ed76b --- /dev/null +++ b/rust/crates/mnote-web/browser/sidebar-page-ai-target-runtime.js @@ -0,0 +1,758 @@ +export function createSidebarPageAiTargetRuntime(context) { + const { + currentDocumentId, + currentRootUri, + currentSourceKind, + currentPageOptions, + documentRef, + escapeHtml, + pageAiEnsureContextRefState, + pageUiState, + resolveWorkspaceId, + searchText, + pageAiNormalizeArray, + } = context; + + function pageAiCloneJson(value) { + if (value == null) return null; + try { + return JSON.parse(JSON.stringify(value)); + } catch (_) { + return null; + } + } + + function localMarkdownRelativePathFromPageAiDocumentId(documentId) { + var value = String(documentId || '').trim(); + if (!value.startsWith('local-md:')) return ''; + return value.slice('local-md:'.length).replace(/~2F/g, '/'); + } + + function localMarkdownDocumentIdFromPageAiRelativePath(relativePath) { + var normalized = String(relativePath || '').trim().replace(/\\/g, '/').replace(/^\/+/, ''); + if (!normalized) return ''; + return 'local-md:' + normalized.split('/').map(function(segment) { + return encodeURIComponent(segment).replace(/%20/g, '~20'); + }).join('~2F'); + } + + function pageAiWorkspacePathForDocument(documentId, seed) { + var relativePath = String(seed && seed.relativePath || localMarkdownRelativePathFromPageAiDocumentId(documentId) || '').trim().replace(/\\/g, '/').replace(/^\/+/, ''); + var resolvedDocumentId = String(documentId || seed && seed.documentId || '').trim() + || localMarkdownDocumentIdFromPageAiRelativePath(relativePath); + return { + schema: 'mnote.workspace_path.v1', + workspaceId: String(seed && seed.workspaceId || resolveWorkspaceId(documentRef.body) || '').trim(), + sourceKind: String(seed && seed.sourceKind || currentSourceKind() || '').trim(), + rootUri: String(seed && seed.rootUri || currentRootUri() || '').trim(), + relativePath: relativePath, + documentId: resolvedDocumentId, + objectIdentity: seed && seed.objectIdentity && typeof seed.objectIdentity === 'object' + ? seed.objectIdentity + : String(seed && seed.objectIdentity || resolvedDocumentId || '').trim(), + assetId: String(seed && seed.assetId || '').trim(), + resourceKind: String(seed && seed.resourceKind || 'markdown_page').trim() + }; + } + + function pageAiResourceKindForTarget(entry) { + var kind = String(entry && (entry.editorKind || entry.kind) || '').trim().toLowerCase(); + var assetId = String(entry && entry.assetId || '').trim(); + var path = String(entry && entry.path || '').trim().toLowerCase(); + if (kind === 'page' || kind === 'markdown_page') return 'markdown_page'; + if (kind === 'mindmap' || path.endsWith('.mindmap.json')) return 'mindmap'; + if (kind === 'office' || kind === 'onlyoffice' || kind === 'only_office' || /\.(doc|docx|ppt|pptx|xls|xlsx)$/.test(path)) return 'only_office'; + if (kind === 'resource' && assetId) return 'resource'; + return kind || 'markdown_page'; + } + + function pageAiTargetId(entry) { + if (!entry || typeof entry !== 'object') return ''; + var workspacePath = entry.workspacePath && typeof entry.workspacePath === 'object' ? entry.workspacePath : {}; + var entryIdentity = typeof entry.objectIdentity === 'string' ? entry.objectIdentity : ''; + var workspaceIdentity = typeof workspacePath.objectIdentity === 'string' ? workspacePath.objectIdentity : ''; + return String(entryIdentity || workspaceIdentity || entry.documentId || entry.assetId || entry.path || '').trim(); + } + + function pageAiWorkspacePathForTarget(entry) { + var seed = Object.assign({}, entry && entry.workspacePath && typeof entry.workspacePath === 'object' ? entry.workspacePath : {}); + var resourceKind = pageAiResourceKindForTarget(entry); + if (!seed.relativePath && entry && entry.path) seed.relativePath = entry.path; + if (!seed.assetId && entry && entry.assetId) seed.assetId = entry.assetId; + var seedResourceKind = String(seed.resourceKind || '').trim(); + if (!seedResourceKind || seedResourceKind === 'page' || seedResourceKind === 'office') seed.resourceKind = resourceKind; + if (!seed.objectIdentity && entry && entry.objectIdentity) seed.objectIdentity = entry.objectIdentity; + if (!seed.workspaceId && entry && entry.workspaceId) seed.workspaceId = entry.workspaceId; + return pageAiWorkspacePathForDocument(entry && entry.documentId || currentDocumentId(), seed); + } + + function pageAiTargetFromOpenEditor(entry, source) { + if (!entry || typeof entry !== 'object') return null; + var workspacePath = pageAiWorkspacePathForTarget(entry); + var targetId = pageAiTargetId(entry) || workspacePath.objectIdentity || workspacePath.documentId; + if (!targetId) return null; + var objectIdentity = typeof entry.objectIdentity === 'string' + ? entry.objectIdentity + : (typeof workspacePath.objectIdentity === 'string' ? workspacePath.objectIdentity : targetId); + return { + schema: 'mnote.ai_editor_target.v1', + source: source || 'open_editors_snapshot', + targetId: targetId, + objectIdentity: objectIdentity, + workspacePath: workspacePath, + paneRole: entry.paneRole || 'primary', + documentId: entry.documentId || workspacePath.documentId, + workspaceId: entry.workspaceId || workspacePath.workspaceId || resolveWorkspaceId(documentRef.body), + editorKind: entry.editorKind || entry.kind || workspacePath.resourceKind, + resourceKind: workspacePath.resourceKind, + title: entry.title || '', + active: entry.active === true, + dirtyState: entry.dirtyState || '', + preview: entry.preview === true, + pinned: entry.pinned === true, + lastActiveAt: entry.lastActiveAt || 0, + assetId: entry.assetId || workspacePath.assetId || '', + path: entry.path || workspacePath.relativePath || '', + onlyofficeSessionId: entry.onlyofficeSessionId || entry.bridgeSessionId || '', + bridgeSessionId: entry.bridgeSessionId || entry.onlyofficeSessionId || '', + bridgeSessionReady: entry.bridgeSessionReady === true + }; + } + + function normalizeOpenEditorEntry(entry) { + if (!entry || typeof entry !== 'object') return null; + return { + objectIdentity: String(entry.objectIdentity || '').trim(), + workspacePath: entry.workspacePath && typeof entry.workspacePath === 'object' ? entry.workspacePath : null, + paneRole: String(entry.paneRole || 'primary').trim() === 'secondary' ? 'secondary' : 'primary', + documentId: String(entry.documentId || '').trim(), + workspaceId: String(entry.workspaceId || '').trim(), + title: String(entry.title || '').trim(), + kind: String(entry.kind || entry.editorKind || '').trim(), + editorKind: String(entry.editorKind || entry.kind || '').trim(), + active: entry.active === true, + dirtyState: String(entry.dirtyState || entry.dirtyGuard || '').trim(), + preview: entry.preview === true, + pinned: entry.pinned === true, + lastActiveAt: Number(entry.lastActiveAt || 0) || 0, + assetId: String(entry.assetId || '').trim(), + path: String(entry.path || '').trim(), + onlyofficeSessionId: String(entry.onlyofficeSessionId || entry.bridgeSessionId || '').trim(), + bridgeSessionId: String(entry.bridgeSessionId || entry.onlyofficeSessionId || '').trim(), + bridgeSessionReady: entry.bridgeSessionReady === true + }; + } + + function currentPageAiOpenEditorsSnapshot() { + var snapshot = null; + try { + if (window.__mnoteDocumentPaneRuntime && typeof window.__mnoteDocumentPaneRuntime.getOpenEditorsSnapshot === 'function') { + snapshot = window.__mnoteDocumentPaneRuntime.getOpenEditorsSnapshot(); + } + } catch (_) {} + if (!snapshot || typeof snapshot !== 'object') snapshot = window.__mnoteOpenEditorsSnapshot || null; + if (!snapshot || typeof snapshot !== 'object') return null; + var editors = Array.isArray(snapshot.editors) + ? snapshot.editors.map(normalizeOpenEditorEntry).filter(Boolean) + : []; + var resources = Array.isArray(snapshot.resourceEditors) + ? snapshot.resourceEditors.map(normalizeOpenEditorEntry).filter(Boolean) + : editors.filter(function(entry) { return entry.kind !== 'page'; }); + var normalizeGroup = function(group, paneRole) { + var groupEditors = group && Array.isArray(group.editors) + ? group.editors.map(normalizeOpenEditorEntry).filter(Boolean) + : editors.filter(function(entry) { return entry.paneRole === paneRole; }); + var groupResources = group && Array.isArray(group.resourceEditors) + ? group.resourceEditors.map(normalizeOpenEditorEntry).filter(Boolean) + : resources.filter(function(entry) { return entry.paneRole === paneRole; }); + var groupActive = groupEditors.find(function(entry) { return entry.active; }) || null; + return { + paneRole: paneRole, + activeObjectIdentity: String(group && group.activeObjectIdentity || (groupActive ? groupActive.objectIdentity : '') || '').trim(), + editors: groupEditors, + resourceEditors: groupResources + }; + }; + var groups = { + primary: normalizeGroup(snapshot.groups && snapshot.groups.primary, 'primary'), + secondary: normalizeGroup(snapshot.groups && snapshot.groups.secondary, 'secondary') + }; + var activeObjectIdentity = String(snapshot.activeObjectIdentity || '').trim(); + var allTargets = editors.concat(resources); + var activeEditor = allTargets.find(function(entry) { + return entry.active && (!activeObjectIdentity || entry.objectIdentity === activeObjectIdentity); + }) || groups.primary.editors.find(function(entry) { + return entry.active; + }) || groups.primary.resourceEditors.find(function(entry) { + return entry.active; + }) || groups.secondary.editors.find(function(entry) { + return entry.active; + }) || groups.secondary.resourceEditors.find(function(entry) { + return entry.active; + }) || null; + return { + schema: String(snapshot.schema || 'mnote.open_editors_snapshot.v1'), + generatedAt: Number(snapshot.generatedAt || 0) || Date.now(), + activeObjectIdentity: activeObjectIdentity || (activeEditor ? activeEditor.objectIdentity : ''), + activeEditor: activeEditor, + editors: editors, + resourceEditors: resources, + groups: groups + }; + } + + function pageAiFallbackEditorTarget() { + var fallbackDocumentId = currentDocumentId(); + var fallbackWorkspacePath = pageAiWorkspacePathForDocument(fallbackDocumentId, null); + var fallbackTargetId = fallbackWorkspacePath.objectIdentity || fallbackDocumentId || ''; + return { + schema: 'mnote.ai_editor_target.v1', + source: 'fallback_current_document', + targetId: fallbackTargetId, + objectIdentity: fallbackTargetId, + workspacePath: fallbackWorkspacePath, + paneRole: 'primary', + documentId: fallbackDocumentId, + workspaceId: resolveWorkspaceId(documentRef.body), + editorKind: 'page', + active: true, + dirtyState: '', + preview: false, + pinned: true, + lastActiveAt: Date.now(), + assetId: '', + path: '' + }; + } + + function pageAiEditorTargetCandidates() { + var snapshot = currentPageAiOpenEditorsSnapshot(); + var entries = []; + if (snapshot) { + entries = pageAiNormalizeArray(snapshot.editors).concat(pageAiNormalizeArray(snapshot.resourceEditors)); + } + var seen = {}; + var targets = entries.map(function(entry) { + return pageAiTargetFromOpenEditor(entry, 'open_editors_snapshot'); + }).filter(function(target) { + var id = String(target && target.targetId || '').trim(); + if (!id || seen[id]) return false; + seen[id] = true; + return true; + }); + if (!targets.length) targets.push(pageAiFallbackEditorTarget()); + return targets; + } + + function currentPageAiEditorTarget() { + var targets = pageAiEditorTargetCandidates(); + var selectedId = String(pageUiState.pageAiSelectedTargetId || '').trim(); + var selected = selectedId ? targets.find(function(target) { return target.targetId === selectedId; }) : null; + return selected + || targets.find(function(target) { return target.active === true; }) + || targets[0] + || pageAiFallbackEditorTarget(); + } + + function currentPageAiPageEditorTarget() { + var snapshot = currentPageAiOpenEditorsSnapshot(); + var documentId = currentDocumentId(); + var workspaceId = resolveWorkspaceId(documentRef.body); + var sourceKind = currentSourceKind(); + var rootUri = currentRootUri(); + var relativePath = localMarkdownRelativePathFromPageAiDocumentId(documentId); + var fallbackWorkspacePath = pageAiWorkspacePathForDocument(documentId, { + relativePath: relativePath + }); + var pageEditor = snapshot && Array.isArray(snapshot.editors) + ? snapshot.editors.find(function(entry) { + return entry + && String(entry.editorKind || entry.kind || '') === 'page' + && String(entry.documentId || '').trim() === String(documentId || '').trim(); + }) + : null; + var workspacePath = pageEditor && pageEditor.workspacePath + ? Object.assign({}, pageEditor.workspacePath, { + workspaceId: workspaceId, + sourceKind: sourceKind, + rootUri: rootUri, + relativePath: relativePath, + documentId: documentId, + resourceKind: pageEditor.workspacePath.resourceKind || 'markdown_page', + objectIdentity: pageEditor.workspacePath.objectIdentity || fallbackWorkspacePath.objectIdentity + }) + : fallbackWorkspacePath; + var objectIdentity = String(pageEditor && pageEditor.objectIdentity || workspacePath.objectIdentity || documentId || '').trim(); + return { + schema: 'mnote.ai_editor_target.v1', + source: pageEditor ? 'current_page_from_open_editors_snapshot' : 'current_page_fallback', + targetId: objectIdentity, + objectIdentity: objectIdentity, + workspacePath: Object.assign({}, workspacePath, { objectIdentity: objectIdentity }), + paneRole: String(pageEditor && pageEditor.paneRole || 'primary').trim() === 'secondary' ? 'secondary' : 'primary', + documentId: documentId, + workspaceId: workspaceId, + editorKind: 'page', + active: pageEditor ? pageEditor.active === true : true, + dirtyState: String(pageEditor && pageEditor.dirtyState || '').trim(), + preview: pageEditor ? pageEditor.preview === true : false, + pinned: true, + lastActiveAt: Number(pageEditor && pageEditor.lastActiveAt || 0) || Date.now(), + assetId: '', + path: relativePath + }; + } + + function currentPageAiScopedEditorTarget() { + var selected = pageAiEnsureContextRefState(); + return selected.active_editor ? currentPageAiEditorTarget() : currentPageAiPageEditorTarget(); + } + + function pageAiSetRunTargetSnapshot(snapshot) { + pageUiState.pageAiCurrentRunTargetSnapshot = snapshot || null; + var target = snapshot && snapshot.editorTarget ? snapshot.editorTarget : null; + var documentId = String(target && target.documentId || snapshot && snapshot.documentId || '').trim(); + var workspaceId = String(target && target.workspaceId || snapshot && snapshot.workspaceId || '').trim(); + var rootUri = String(target && target.workspacePath && target.workspacePath.rootUri || snapshot && snapshot.rootUri || '').trim(); + if (documentId) documentRef.documentElement.setAttribute('data-mnote-page-ai-run-target-document-id', documentId); + if (workspaceId) documentRef.documentElement.setAttribute('data-mnote-page-ai-run-target-workspace-id', workspaceId); + if (rootUri) documentRef.documentElement.setAttribute('data-mnote-page-ai-run-target-root-uri', rootUri); + } + + function assertPageAiTargetInCurrentWorkspace(editorTarget) { + var target = editorTarget && typeof editorTarget === 'object' ? editorTarget : {}; + var workspacePath = target.workspacePath && typeof target.workspacePath === 'object' ? target.workspacePath : {}; + var targetSourceKind = String(workspacePath.sourceKind || '').trim(); + var currentKind = String(currentSourceKind() || '').trim(); + if (targetSourceKind && currentKind && targetSourceKind !== currentKind) { + var sourceError = new Error('AI target 与当前页面 sourceKind 不一致,请重新选择当前工作区内的目标。'); + sourceError.code = 'page_ai_target_workspace_mismatch'; + throw sourceError; + } + var targetRootUri = String(workspacePath.rootUri || '').trim(); + var currentRoot = String(currentRootUri() || '').trim(); + if (targetRootUri && currentRoot && targetRootUri !== currentRoot) { + var rootError = new Error('AI target 与当前本地工作区 rootUri 不一致,请重新选择当前工作区内的目标。'); + rootError.code = 'page_ai_target_workspace_mismatch'; + throw rootError; + } + var targetWorkspaceId = String(target.workspaceId || workspacePath.workspaceId || '').trim(); + var currentWorkspaceId = String(resolveWorkspaceId(documentRef.body) || '').trim(); + if (targetWorkspaceId && currentWorkspaceId && targetWorkspaceId !== currentWorkspaceId) { + var workspaceError = new Error('AI target 与当前 workspaceId 不一致,请重新选择当前工作区内的目标。'); + workspaceError.code = 'page_ai_target_workspace_mismatch'; + throw workspaceError; + } + } + + function pageAiBuildContextRefs(scopedContext, runTargetSnapshot) { + var selected = pageAiEnsureContextRefState(); + var refs = []; + var documentId = currentDocumentId(); + var rootUri = currentRootUri(); + var workspaceId = resolveWorkspaceId(documentRef.body); + var editorTarget = scopedContext && scopedContext.editorTarget ? scopedContext.editorTarget : currentPageAiEditorTarget(); + if (selected.current_page) { + refs.push({ + kind: 'current_page', + documentId: documentId, + rootUri: rootUri, + workspaceId: workspaceId + }); + } + if (selected.selection && scopedContext && scopedContext.selectedText) { + refs.push({ + kind: 'selection', + documentId: documentId, + rootUri: rootUri, + selectedBlockId: scopedContext.selectedBlockId || '' + }); + } + if (selected.active_editor && editorTarget) { + var workspacePath = editorTarget.workspacePath && typeof editorTarget.workspacePath === 'object' ? editorTarget.workspacePath : {}; + refs.push({ + kind: 'active_editor', + documentId: editorTarget.documentId || documentId, + workspaceId: editorTarget.workspaceId || workspacePath.workspaceId || workspaceId, + rootUri: workspacePath.rootUri || rootUri, + relativePath: workspacePath.relativePath || '', + editorKind: editorTarget.editorKind || '', + resourceKind: editorTarget.resourceKind || workspacePath.resourceKind || '', + targetId: editorTarget.targetId || workspacePath.objectIdentity || '', + objectIdentity: editorTarget.objectIdentity || workspacePath.objectIdentity || '', + assetId: editorTarget.assetId || workspacePath.assetId || '', + onlyofficeSessionId: editorTarget.onlyofficeSessionId || editorTarget.bridgeSessionId || '', + bridgeSessionId: editorTarget.bridgeSessionId || editorTarget.onlyofficeSessionId || '' + }); + } + if (selected.file) { + refs.push({ + kind: 'file', + documentId: documentId, + rootUri: rootUri, + relativePath: localMarkdownRelativePathFromPageAiDocumentId(documentId) + }); + } + if (selected.folder) { + refs.push({ + kind: 'folder', + rootUri: rootUri, + relativePath: '' + }); + } + if (selected.changed_files) { + refs.push({ + kind: 'changed_files', + rootUri: rootUri, + sinceRunTargetSnapshot: runTargetSnapshot && runTargetSnapshot.frozenAt || null + }); + } + return refs.filter(function(ref) { + return ref && String(ref.kind || '').trim(); + }); + } + + function pageAiBuildAllowedRoots() { + return pageAiNormalizeArray(pageUiState.pageAiAllowedRoots).map(function(root) { + return { + rootUri: root.rootUri, + permission: root.permission === 'write' || root.permission === 'read_write' ? 'write' : 'read', + recursive: root.recursive !== false, + source: root.source === 'auto' || root.source === 'user' || root.source === 'admin' + ? 'sqlite_directory_grant' + : (root.source || 'sqlite_directory_grant'), + grantId: root.id || '' + }; + }); + } + + function pageAiBuildRunTargetSnapshot(scopedContext, prompt) { + var aiContext = scopedContext && scopedContext.pageContext && scopedContext.pageContext.aiContext + ? scopedContext.pageContext.aiContext + : {}; + var editorTarget = scopedContext && scopedContext.editorTarget ? scopedContext.editorTarget : currentPageAiEditorTarget(); + return { + schema: 'mnote.page_ai_run_target_snapshot.v1', + source: 'open_editors_snapshot', + frozenAt: Date.now(), + workspaceId: resolveWorkspaceId(documentRef.body), + documentId: currentDocumentId(), + sourceKind: currentSourceKind(), + rootUri: currentRootUri(), + contextScope: pageUiState.pageAiContextScope || 'page', + promptPreview: searchText(prompt || '').slice(0, 160), + editorTarget: pageAiCloneJson(editorTarget), + activeEditorTarget: pageAiCloneJson(aiContext.activeEditorTarget || editorTarget), + openEditorsSnapshot: pageAiCloneJson(aiContext.openEditorsSnapshot || currentPageAiOpenEditorsSnapshot()) + }; + } + + function pageAiContextKindsFromRefs(contextRefs) { + var kinds = {}; + pageAiNormalizeArray(contextRefs).forEach(function(ref) { + var kind = String(ref && ref.kind || '').trim(); + if (kind) kinds[kind] = true; + }); + return kinds; + } + + function pageAiPageContextForRefs(pageContext, contextRefs) { + var cloned = pageAiCloneJson(pageContext) || {}; + var aiContext = cloned.aiContext && typeof cloned.aiContext === 'object' ? cloned.aiContext : {}; + var kinds = pageAiContextKindsFromRefs(contextRefs); + delete cloned.documentBlocks; + delete cloned.evidence; + delete aiContext.contextBlocks; + delete aiContext.pageText; + delete aiContext.pageXml; + delete aiContext.truncated; + delete aiContext.warnings; + if (!kinds.selection) { + delete aiContext.selectedText; + delete aiContext.selectedBlockIds; + delete aiContext.selectedBlocks; + delete aiContext.allowedTargetBlockIds; + } + cloned.aiContext = aiContext; + return cloned; + } + + function pageAiBuildAgentTargetPackage(scopedContext, runTargetSnapshot) { + var target = scopedContext && scopedContext.editorTarget ? scopedContext.editorTarget : currentPageAiEditorTarget(); + var workspacePath = target && target.workspacePath && typeof target.workspacePath === 'object' + ? pageAiWorkspacePathForDocument(target.documentId || currentDocumentId(), target.workspacePath) + : pageAiWorkspacePathForDocument(target && target.documentId || currentDocumentId(), null); + var relativePath = String(workspacePath.relativePath || '').trim(); + var allowedFiles = relativePath ? [relativePath] : []; + var writable = pageAiBuildAllowedRoots().some(function(root) { + return String(root && root.rootUri || '').trim() === String(workspacePath.rootUri || '').trim() + && String(root && root.permission || '').trim() === 'write'; + }); + var primaryTargetId = String(target && target.targetId || workspacePath.objectIdentity || workspacePath.documentId || '').trim(); + var onlyofficeSessionId = String(target && (target.onlyofficeSessionId || target.bridgeSessionId) || '').trim(); + var targetEntry = { + targetId: primaryTargetId, + objectIdentity: primaryTargetId, + documentId: workspacePath.documentId, + workspaceId: workspacePath.workspaceId, + sourceKind: workspacePath.sourceKind, + rootUri: workspacePath.rootUri, + relativePath: relativePath, + resourceKind: workspacePath.resourceKind, + assetId: workspacePath.assetId || target && target.assetId || '', + onlyofficeSessionId: onlyofficeSessionId, + bridgeSessionId: onlyofficeSessionId, + paneRole: target && target.paneRole || 'primary', + title: target && target.title || '', + policy: { + permission: allowedFiles.length && writable ? 'read_write' : 'read', + writeRequiresCleanBuffer: true, + conflictPolicy: 'fail_on_dirty_or_stale' + } + }; + return { + schema: 'mnote.agent_target_package.v1', + source: 'page_ai_run_target_snapshot', + frozenAt: runTargetSnapshot && runTargetSnapshot.frozenAt || Date.now(), + primaryTargetId: primaryTargetId, + onlyofficeSessionId: onlyofficeSessionId, + bridgeSessionId: onlyofficeSessionId, + workspaceId: workspacePath.workspaceId, + sourceKind: workspacePath.sourceKind, + rootUri: workspacePath.rootUri, + documentId: workspacePath.documentId, + objectIdentity: primaryTargetId, + resourceKind: workspacePath.resourceKind, + workspacePath: workspacePath, + currentFile: relativePath ? { + rootUri: workspacePath.rootUri, + relativePath: relativePath, + documentId: workspacePath.documentId, + objectIdentity: primaryTargetId, + resourceKind: workspacePath.resourceKind + } : null, + allowedFiles: allowedFiles, + targets: [targetEntry], + policy: { + writeRequiresExplicitTarget: true, + allowedFilesSource: 'selected_page_ai_target', + conflictPolicy: 'fail_on_dirty_or_stale' + } + }; + } + + function pageAiBlockingDirtyState(dirtyState) { + var state = String(dirtyState || '').trim(); + var normalized = state.toLowerCase(); + if (normalized === 'dirty') return 'Dirty'; + if (normalized === 'stale') return 'Stale'; + if (normalized === 'deleted') return 'Deleted'; + if (normalized === 'externalmodified' || normalized === 'external-change-conflict' || normalized === 'hasexternalconflict') return 'ExternalModified'; + return ''; + } + + async function fetchPageAiTargetBufferState(editorTarget) { + if (currentSourceKind() !== 'local_folder') return null; + var target = editorTarget && typeof editorTarget === 'object' ? editorTarget : {}; + var workspacePath = target.workspacePath && typeof target.workspacePath === 'object' ? target.workspacePath : {}; + var resourceKind = String(target.resourceKind || target.editorKind || workspacePath.resourceKind || '').trim(); + if (resourceKind === 'office' || resourceKind === 'only_office' || resourceKind === 'onlyoffice') return null; + var documentId = String(target.documentId || currentDocumentId() || '').trim(); + var rootUri = String(workspacePath.rootUri || currentRootUri() || '').trim(); + if (!documentId || !rootUri) return null; + var relativePath = String(workspacePath.relativePath || '').trim() + || localMarkdownRelativePathFromPageAiDocumentId(documentId); + var url = new URL('/api/documents/buffer-state', window.location.origin); + url.searchParams.set('documentId', documentId); + url.searchParams.set('sourceKind', 'local_folder'); + url.searchParams.set('rootUri', rootUri); + var workspaceId = String(target.workspaceId || resolveWorkspaceId(documentRef.body) || '').trim(); + if (workspaceId) url.searchParams.set('workspaceId', workspaceId); + if (relativePath) url.searchParams.set('relativePath', relativePath); + try { + var response = await fetch(url.toString(), { cache: 'no-store', headers: { accept: 'application/json' } }); + var payload = await response.json().catch(function() { return null; }); + if (!response.ok || !payload || payload.ok !== true) return null; + return payload.result || null; + } catch (_) { + return null; + } + } + + async function assertPageAiTargetWritable(editorTarget) { + var workspacePath = editorTarget && editorTarget.workspacePath && typeof editorTarget.workspacePath === 'object' ? editorTarget.workspacePath : {}; + var resourceKind = String(editorTarget && (editorTarget.resourceKind || editorTarget.editorKind) || workspacePath.resourceKind || '').trim(); + var onlyofficeSessionId = String(editorTarget && (editorTarget.onlyofficeSessionId || editorTarget.bridgeSessionId) || '').trim(); + if ((resourceKind === 'office' || resourceKind === 'only_office' || resourceKind === 'onlyoffice') && !onlyofficeSessionId) { + var sessionError = new Error('ONLYOFFICE 资源仍在连接 MNote bridge,请等待 Office 页面加载完成后再让 AI 操作。'); + sessionError.code = 'page_ai_onlyoffice_bridge_not_ready'; + throw sessionError; + } + var snapshotState = pageAiBlockingDirtyState(editorTarget && editorTarget.dirtyState); + var bufferState = await fetchPageAiTargetBufferState(editorTarget); + var bufferDirtyState = pageAiBlockingDirtyState(bufferState && bufferState.dirtyState); + var blockedState = bufferDirtyState || snapshotState; + if (!blockedState) return bufferState; + var documentId = String(editorTarget && editorTarget.documentId || currentDocumentId() || '').trim(); + var error = new Error('目标文档存在未保存或外部变更状态(' + blockedState + '),请先保存、解决冲突或刷新后再让 AI 写入。'); + error.code = 'page_ai_target_buffer_not_writable'; + error.documentId = documentId; + error.dirtyState = blockedState; + throw error; + } + + function currentPageAiSelectedText() { + try { + var selection = window.getSelection ? window.getSelection() : null; + return selection ? searchText(selection.toString() || '') : ''; + } catch (_) { + return ''; + } + } + + function pageAiProjectionBlocks(aggregate) { + var blocks = aggregate && aggregate.body && aggregate.body.blockDocument && aggregate.body.blockDocument.blocks; + return Array.isArray(blocks) ? blocks : []; + } + + function pageAiBlockText(block) { + return searchText(block && (block.text || block.title || block.content) || ''); + } + + function pageAiSelectedBlockIdsFromSelection() { + try { + var selection = window.getSelection ? window.getSelection() : null; + if (!selection || selection.rangeCount === 0 || searchText(selection.toString() || '') === '') return []; + var range = selection.getRangeAt(0); + var editor = documentRef.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"] .editor-surface .ProseMirror'); + if (!(editor instanceof HTMLElement)) return []; + return Array.from(editor.children).filter(function(node) { + if (!(node instanceof HTMLElement)) return false; + try { + return range.intersectsNode(node); + } catch (_) { + return false; + } + }).map(function(node) { + return searchText(node.getAttribute('data-id') || node.id || ''); + }).filter(Boolean); + } catch (_) { + return []; + } + } + + function pageAiBlocksToPageXml(blocks, aggregate) { + var revision = aggregate && aggregate.body ? String(aggregate.body.revision || '') : ''; + var pageId = currentDocumentId() || 'current-page'; + var lines = ['']; + blocks.forEach(function(block) { + var blockId = String(block && (block.blockId || block.id) || ''); + var type = String(block && block.type || 'paragraph'); + var revisionRef = String(block && block.revisionRef || ''); + var level = block && block.attrs && block.attrs.level ? ' level="' + escapeHtml(block.attrs.level) + '"' : ''; + lines.push(' ' + escapeHtml(pageAiBlockText(block)) + ''); + }); + lines.push(''); + return lines.join('\n'); + } + + function buildPageAiContext(contextSnapshot, scope, selectedText) { + var aggregate = contextSnapshot.aggregate || {}; + var body = aggregate.body || {}; + var allBlocks = pageAiProjectionBlocks(aggregate); + var selectedBlockIds = scope === 'selection' ? pageAiSelectedBlockIdsFromSelection() : []; + var selectedSet = {}; + selectedBlockIds.forEach(function(id) { selectedSet[id] = true; }); + var selectedBlocks = selectedBlockIds.length + ? allBlocks.filter(function(block) { return selectedSet[String(block.blockId || block.id || '')]; }) + : []; + var contextBlocks = selectedBlocks.length ? selectedBlocks : allBlocks.slice(0, 120); + var truncated = !selectedBlocks.length && allBlocks.length > contextBlocks.length; + return { + schema: 'mnote.page_ai_context.v1', + workspaceId: resolveWorkspaceId(documentRef.body), + documentId: currentDocumentId(), + activeEditorTarget: currentPageAiScopedEditorTarget(), + openEditorsSnapshot: currentPageAiOpenEditorsSnapshot(), + scope: scope, + revision: body.revision || null, + conflictDetectionKey: body.conflictDetectionKey || null, + selectedText: selectedText || '', + selectedBlockIds: selectedBlockIds, + allowedTargetBlockIds: selectedBlockIds, + selectedBlocks: selectedBlocks, + contextBlocks: contextBlocks, + pageText: contextBlocks.map(pageAiBlockText).filter(Boolean).join('\n'), + pageXml: pageAiBlocksToPageXml(contextBlocks, aggregate), + truncated: truncated, + warnings: truncated ? [{ code: 'page_ai_context_truncated', message: '页面 AI context 已按前 120 个块裁剪' }] : [] + }; + } + + function pageAiScopedPageContext(contextSnapshot) { + var aggregate = contextSnapshot.aggregate || {}; + var body = contextSnapshot.body || {}; + var subtree = contextSnapshot.subtree || null; + var outline = subtree && subtree.outline ? subtree.outline : null; + var scope = pageUiState.pageAiContextScope || 'page'; + var title = aggregate.head && aggregate.head.title ? aggregate.head.title : ''; + var selectedText = scope === 'selection' ? currentPageAiSelectedText() : ''; + var aiContext = buildPageAiContext(contextSnapshot, scope, selectedText); + var editorTarget = aiContext.activeEditorTarget || currentPageAiScopedEditorTarget(); + return { + pageContext: { + contextScope: scope, + documentBlocks: null, + node: { + documentId: currentDocumentId(), + title: title + }, + subtree: null, + outline: null, + pageSubtreeSource: scope === 'page' ? (contextSnapshot.pageSubtreeSource || 'none') : 'scope:' + scope, + evidence: selectedText ? [{ kind: 'selection', text: selectedText }] : null, + pageOptions: scope === 'options' || scope === 'page' ? currentPageOptions() : null, + contentAccess: 'mnote.context.read_current_page', + aiContext: aiContext + }, + editorTarget: editorTarget, + selectedText: selectedText, + selectedBlockId: aiContext.selectedBlockIds[0] || null + }; + } + + return { + currentPageAiSelectedText, + currentPageAiEditorTarget, + currentPageAiPageEditorTarget, + currentPageAiScopedEditorTarget, + currentPageAiOpenEditorsSnapshot, + pageAiBlockText, + pageAiBlockingDirtyState, + pageAiBlocksToPageXml, + pageAiBuildAgentTargetPackage, + pageAiBuildAllowedRoots, + pageAiBuildContextRefs, + pageAiBuildRunTargetSnapshot, + pageAiCloneJson, + pageAiContextKindsFromRefs, + pageAiEditorTargetCandidates, + pageAiFallbackEditorTarget, + pageAiPageContextForRefs, + pageAiProjectionBlocks, + pageAiResourceKindForTarget, + pageAiSelectedBlockIdsFromSelection, + pageAiSetRunTargetSnapshot, + pageAiScopedPageContext, + pageAiTargetFromOpenEditor, + pageAiTargetId, + pageAiWorkspacePathForDocument, + pageAiWorkspacePathForTarget, + assertPageAiTargetInCurrentWorkspace, + assertPageAiTargetWritable, + buildPageAiContext, + fetchPageAiTargetBufferState, + localMarkdownDocumentIdFromPageAiRelativePath, + localMarkdownRelativePathFromPageAiDocumentId, + }; +} diff --git a/rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js b/rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js index 0370e112..b0a0cc45 100644 --- a/rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js +++ b/rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js @@ -262,6 +262,9 @@ export function createSidebarPageSettingsRuntime(context) { var shell = document.querySelector('.document-shell'); var editorRoot = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]'); var editorSurface = editorRoot && editorRoot.querySelector('.editor-surface'); + var mindmapWidthPreference = currentPageWidthPreferences().mindmap || DEFAULT_PAGE_WIDTH_PREFERENCES.mindmap; + var mindmapMaxWidth = String(mindmapWidthPreference.cssMaxWidth || pageWidthCssMaxWidth(mindmapWidthPreference.resolvedMode)); + var mindmapMaxWidthValue = mindmapMaxWidth === 'none' ? 'none' : mindmapMaxWidth; if (shell instanceof HTMLElement) { var widthPreference = activeResourceWidthPreference(options); var cssMaxWidth = String(widthPreference.cssMaxWidth || pageWidthCssMaxWidth(widthPreference.resolvedMode)); @@ -276,12 +279,14 @@ export function createSidebarPageSettingsRuntime(context) { shell.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers)); shell.style.width = '100%'; shell.style.maxWidth = cssMaxWidth === 'none' ? 'none' : cssMaxWidth; + shell.style.setProperty('--mnote-mindmap-block-max-width', mindmapMaxWidthValue); } if (editorRoot instanceof HTMLElement) { editorRoot.setAttribute('data-page-wide-layout', String(Boolean(options.wideLayout))); editorRoot.setAttribute('data-page-small-text', String(Boolean(options.smallText))); editorRoot.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers)); editorRoot.setAttribute('data-page-embed-default-block-id', options.embedDefaultBlockId == null ? '' : String(options.embedDefaultBlockId)); + editorRoot.style.setProperty('--mnote-mindmap-block-max-width', mindmapMaxWidthValue); } if (editorSurface instanceof HTMLElement) { editorSurface.setAttribute('data-layout-density', String(options.layoutDensity || 'normal')); @@ -299,6 +304,7 @@ export function createSidebarPageSettingsRuntime(context) { document.documentElement.setAttribute('data-global-show-heading-numbers', String(globalShowHeadingNumbers)); document.documentElement.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers)); document.documentElement.setAttribute('data-page-hide-title-header', String(Boolean(options.hideTitleHeader))); + document.documentElement.style.setProperty('--mnote-mindmap-block-max-width', mindmapMaxWidthValue); var titleHeader = document.querySelector('.document-pane[data-pane-role="primary"] .document-shell-header') || document.querySelector('.document-shell-header'); if (titleHeader instanceof HTMLElement) { var hidden = Boolean(options.hideTitleHeader); diff --git a/rust/crates/mnote-web/browser/sidebar-tree-runtime.js b/rust/crates/mnote-web/browser/sidebar-tree-runtime.js index 21afb147..97afca92 100644 --- a/rust/crates/mnote-web/browser/sidebar-tree-runtime.js +++ b/rust/crates/mnote-web/browser/sidebar-tree-runtime.js @@ -32,46 +32,6 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim pageWidthPreferences: null, historySnapshots: [], pageSettingsOpen: false, - pageAiOpen: false, - pageAiBusy: false, - pageAiMessages: [], - pageAiSuggestionIndex: 0, - pageAiProvider: 'hermes', - pageAiPage: 'chat', - pageAiRunStatus: 'idle', - pageAiCurrentRunId: '', - pageAiAcpRuntime: 'reasonix', - pageAiAcpRuntimes: [], - pageAiQueueLength: 0, - pageAiQueuedItems: [], - pageAiStoppedRunIds: {}, - pageAiAbortController: null, - pageAiContextScope: 'page', - pageAiTools: [], - pageAiToolsError: '', - pageAiGatewayHealth: null, - pageAiGatewayHealthError: '', - pageAiLastToolCall: null, - pageAiProfiles: [], - pageAiActiveProfileName: 'mnoteai', - pageAiProfileError: '', - pageAiProfileMemory: { memory: '', user: '', soul: '' }, - pageAiProfileMemoryDrafts: { memory: '', user: '', soul: '' }, - pageAiProfileMemoryError: '', - pageAiSkills: { categories: [], archived: [] }, - pageAiSkillCatalogs: { mnote: { categories: [], archived: [] }, reasonix: { categories: [], archived: [] }, hermes: { categories: [], archived: [] } }, - pageAiSkillPreferences: {}, - pageAiCollapsedSkillGroups: {}, - pageAiSkillQuery: '', - pageAiSkillError: '', - pageAiSkillLoadSeq: 0, - pageAiSessions: [], - pageAiActiveSessionId: '', - pageAiSessionSearchQuery: '', - pageAiSessionSearchResults: [], - pageAiSessionSearchTimer: 0, - pageAiSessionError: '', - pageAiPermissionRequests: [], localIndexSummary: { scopeKey: '', loading: false, @@ -928,6 +888,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim function fileTreeRuntimeDeps() { return { currentSourceKind: currentSourceKind, + currentRootUri: currentRootUri, currentDocumentId: currentDocumentId, localFilePathFromAssetId: localFilePathFromAssetId, rowTitle: rowTitle, @@ -2382,12 +2343,16 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim const pageAiLoadProfileMemory = (...args) => sidebarPageAi.pageAiLoadProfileMemory(...args); const pageAiLoadSkills = (...args) => sidebarPageAi.pageAiLoadSkills(...args); const pageAiSwitchProfile = (...args) => sidebarPageAi.pageAiSwitchProfile(...args); + const pageAiSetSkillSource = (...args) => sidebarPageAi.pageAiSetSkillSource(...args); const pageAiToggleSkillGroup = (...args) => sidebarPageAi.pageAiToggleSkillGroup(...args); + const pageAiSetReasonixMemoryEnabled = (...args) => sidebarPageAi.pageAiSetReasonixMemoryEnabled(...args); const pageAiSetHideHermesBuiltinSkills = (...args) => sidebarPageAi.pageAiSetHideHermesBuiltinSkills(...args); const pageAiSetContextScope = (...args) => sidebarPageAi.pageAiSetContextScope(...args); const pageAiSetAgentId = (...args) => sidebarPageAi.pageAiSetAgentId(...args); const pageAiToggleContextRef = (...args) => sidebarPageAi.pageAiToggleContextRef(...args); const pageAiSetAgentPopoverOpen = (...args) => sidebarPageAi.pageAiSetAgentPopoverOpen(...args); + const pageAiSetTargetPopoverOpen = (...args) => sidebarPageAi.pageAiSetTargetPopoverOpen(...args); + const pageAiSelectTarget = (...args) => sidebarPageAi.pageAiSelectTarget(...args); const updatePageAiTriggerState = (...args) => sidebarPageAi.updatePageAiTriggerState(...args); const sidebarAttachmentOpen = createSidebarAttachmentOpenRuntime({ @@ -2532,255 +2497,6 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim return; } - var pageAiClose = closestAction(e.target, '[data-page-ai-action="close"]'); - if (pageAiClose) { - e.preventDefault(); - closePageAiDrawer(); - return; - } - - var pageAiSettings = closestAction(e.target, '[data-page-ai-action="open-hermes-settings"]'); - if (pageAiSettings) { - e.preventDefault(); - pageAiOpenHermesSettings(); - return; - } - - var pageAiStop = closestAction(e.target, '[data-page-ai-action="stop-run"]'); - if (pageAiStop) { - e.preventDefault(); - void pageAiStopRun(); - return; - } - - var pageAiRotate = closestAction(e.target, '[data-page-ai-action="rotate"]'); - if (pageAiRotate) { - e.preventDefault(); - pageUiState.pageAiSuggestionIndex += 1; - renderPageAiSuggestions(); - return; - } - - var pageAiIntent = closestAction(e.target, '[data-page-ai-intent]'); - if (pageAiIntent) { - e.preventDefault(); - var intentName = pageAiIntent.getAttribute('data-page-ai-intent') || ''; - if (intentName === 'create-summary') { - void sendPageAiMessage('请通过 Hermes 调用 mnote.artifact.create_summary,为当前页面创建或更新 AI Summary。'); - return; - } - if (intentName === 'create-ai-note') { - void sendPageAiMessage('请通过 Hermes 调用 mnote.artifact.create_ai_note,基于当前页面创建一篇新的 AI Note。'); - return; - } - } - - var pageAiTab = closestAction(e.target, '[data-page-ai-tab]'); - if (pageAiTab) { - e.preventDefault(); - pageUiState.pageAiPage = pageAiTab.getAttribute('data-page-ai-tab') || 'chat'; - if (pageUiState.pageAiPage === 'runtime') void pageAiLoadGatewayHealth(); - renderPageAiControls(); - renderPageAiConversation(); - return; - } - - var pageAiProvider = closestAction(e.target, '[data-page-ai-provider]'); - if (pageAiProvider) { - e.preventDefault(); - pageUiState.pageAiProvider = pageAiProvider.getAttribute('data-page-ai-provider') || 'hermes'; - renderPageAiProviderButtons(); - return; - } - - var pageAiAgent = closestAction(e.target, '[data-page-ai-agent-id]'); - if (pageAiAgent) { - e.preventDefault(); - pageAiSetAgentId(pageAiAgent.getAttribute('data-page-ai-agent-id') || 'reasonix'); - return; - } - - var pageAiAgentButton = closestAction(e.target, '[data-page-ai-agent-button]'); - if (pageAiAgentButton) { - e.preventDefault(); - pageAiSetAgentPopoverOpen(pageAiAgentButton.getAttribute('aria-expanded') !== 'true'); - return; - } - - var pageAiAgentPopoverClose = closestAction(e.target, '[data-page-ai-action="close-agent-popover"]'); - if (pageAiAgentPopoverClose) { - e.preventDefault(); - pageAiSetAgentPopoverOpen(false); - return; - } - - var pageAiContextButton = closestAction(e.target, '[data-page-ai-context-button]'); - if (pageAiContextButton) { - e.preventDefault(); - sidebarPageAi.pageAiSetContextPopoverOpen( - pageAiContextButton.getAttribute('aria-expanded') !== 'true' - ); - return; - } - - var pageAiContextPopoverClose = closestAction(e.target, '[data-page-ai-action="close-context-popover"]'); - if (pageAiContextPopoverClose) { - e.preventDefault(); - sidebarPageAi.pageAiSetContextPopoverOpen(false); - return; - } - - var pageAiContextRef = closestAction(e.target, '[data-page-ai-context-ref]'); - if (pageAiContextRef) { - e.preventDefault(); - pageAiToggleContextRef(pageAiContextRef.getAttribute('data-page-ai-context-ref') || ''); - return; - } - - var pageAiMemorySave = closestAction(e.target, '[data-page-ai-memory-save]'); - if (pageAiMemorySave) { - e.preventDefault(); - void pageAiSaveProfileMemory(pageAiMemorySave.getAttribute('data-page-ai-memory-save') || ''); - return; - } - - var pageAiSkillToggle = closestAction(e.target, '[data-page-ai-skill-toggle]'); - if (pageAiSkillToggle) { - e.preventDefault(); - var skillName = pageAiSkillToggle.getAttribute('data-page-ai-skill-toggle') || ''; - var skillGroup = pageAiSkillToggle.getAttribute('data-page-ai-skill-group') || ''; - var skillProfile = pageAiSkillToggle.getAttribute('data-page-ai-skill-profile') || ''; - var nextEnabled = pageAiSkillToggle.getAttribute('aria-pressed') !== 'true'; - void pageAiToggleSkill(skillName, nextEnabled, skillGroup, skillProfile); - return; - } - - var pageAiSkillGroupToggle = closestAction(e.target, '[data-page-ai-skill-group-toggle]'); - if (pageAiSkillGroupToggle) { - e.preventDefault(); - pageAiToggleSkillGroup(pageAiSkillGroupToggle.getAttribute('data-page-ai-skill-group-toggle') || ''); - return; - } - - var pageAiToolToggle = closestAction(e.target, '[data-page-ai-tool-toggle]'); - if (pageAiToolToggle) { - e.preventDefault(); - var toolName = pageAiToolToggle.getAttribute('data-page-ai-tool-toggle') || ''; - var nextToolEnabled = pageAiToolToggle.getAttribute('aria-pressed') !== 'true'; - void pageAiToggleTool(toolName, nextToolEnabled); - return; - } - - var pageAiSessionResume = closestAction(e.target, '[data-page-ai-session-resume]'); - if (pageAiSessionResume) { - e.preventDefault(); - void pageAiResumeBackendSession(pageAiSessionResume.getAttribute('data-page-ai-session-resume') || '').catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - return; - } - - var pageAiSessionRename = closestAction(e.target, '[data-page-ai-session-rename]'); - if (pageAiSessionRename) { - e.preventDefault(); - void pageAiRenameBackendSession(pageAiSessionRename.getAttribute('data-page-ai-session-rename') || '').catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - return; - } - - var pageAiSessionDelete = closestAction(e.target, '[data-page-ai-session-delete]'); - if (pageAiSessionDelete) { - e.preventDefault(); - void pageAiDeleteBackendSession(pageAiSessionDelete.getAttribute('data-page-ai-session-delete') || '').catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - return; - } - - var pageAiPermissionAction = closestAction(e.target, '[data-page-ai-permission-action]'); - if (pageAiPermissionAction) { - e.preventDefault(); - pageAiResolvePermission( - pageAiPermissionAction.getAttribute('data-page-ai-permission-id') || '', - pageAiPermissionAction.getAttribute('data-page-ai-permission-action') || 'deny' - ); - return; - } - - var pageAiOpenLocationAction = closestAction(e.target, '[data-page-ai-open-location]'); - if (pageAiOpenLocationAction) { - e.preventDefault(); - var loc = String(pageAiOpenLocationAction.getAttribute('data-page-ai-open-location') || '').trim(); - if (loc) pageAiOpenLocation(loc); - return; - } - - var pageAiSession = closestAction(e.target, '[data-page-ai-session]'); - if (pageAiSession) { - e.preventDefault(); - pageAiSetActiveSession(pageAiSession.getAttribute('data-page-ai-session') || ''); - return; - } - - var pageAiSuggestion = closestAction(e.target, '[data-page-ai-suggestion]'); - if (pageAiSuggestion) { - e.preventDefault(); - var text = pageAiSuggestion.getAttribute('data-page-ai-suggestion') || ''; - var inputNode = ensurePageAiDrawer().querySelector('[data-page-ai-input]'); - if (inputNode instanceof HTMLTextAreaElement) { - inputNode.value = text; - inputNode.focus(); - } - return; - } - - var pageAiNewSession = closestAction(e.target, '[data-page-ai-action="new-session"]'); - if (pageAiNewSession) { - e.preventDefault(); - pageUiState.pageAiPage = 'chat'; - pageAiStartNewSession(); - return; - } - - var pageAiHistory = closestAction(e.target, '[data-page-ai-action="history"]'); - if (pageAiHistory) { - e.preventDefault(); - pageAiLoadSessions(); - pageUiState.pageAiPage = pageUiState.pageAiPage === 'history' ? 'chat' : 'history'; - renderPageAiControls(); - renderPageAiConversation(); - if (pageUiState.pageAiPage === 'history') { - void pageAiLoadBackendSessions().catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - } - return; - } - - var pageAiSend = closestAction(e.target, '[data-page-ai-action="send"]'); - if (pageAiSend) { - e.preventDefault(); - var input = ensurePageAiDrawer().querySelector('[data-page-ai-input]'); - if (input instanceof HTMLTextAreaElement) { - var message = input.value; - input.value = ''; - void sendPageAiMessage(message); - } - return; - } - - var cancelQueuedRun = closestAction(e.target, '[data-page-ai-action="cancel-queued-run"]'); - if (cancelQueuedRun) { - e.preventDefault(); - void pageAiCancelQueuedRun(cancelQueuedRun.getAttribute('data-page-ai-queue-id')); - return; - } - var searchTrigger = closestAction(e.target, '[data-mnote-action="open-search-modal"]'); if (searchTrigger) { e.preventDefault(); @@ -3112,79 +2828,9 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim closeSearchModal(); closeTreeContextMenu(); } - if (event.key === 'Enter' && !event.shiftKey) { - var aiInput = closestAction(event.target, '[data-page-ai-input]'); - if (aiInput instanceof HTMLTextAreaElement) { - event.preventDefault(); - var text = aiInput.value; - aiInput.value = ''; - void sendPageAiMessage(text); - } - } - }); - - document.addEventListener('input', function(event) { - var skillSearch = closestAction(event.target, '[data-page-ai-skill-search]'); - if (skillSearch instanceof HTMLInputElement) { - pageUiState.pageAiSkillQuery = skillSearch.value; - renderPageAiControls(); - return; - } - var sessionSearch = closestAction(event.target, '[data-page-ai-session-search]'); - if (sessionSearch instanceof HTMLInputElement) { - var sessionQuery = sessionSearch.value; - window.clearTimeout(pageUiState.pageAiSessionSearchTimer || 0); - pageUiState.pageAiSessionSearchTimer = window.setTimeout(function() { - void pageAiSearchBackendSessions(sessionQuery).catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - renderPageAiControls(); - }); - }, 200); - return; - } - var memoryEditor = closestAction(event.target, '[data-page-ai-memory-editor]'); - if (memoryEditor instanceof HTMLTextAreaElement) { - var section = memoryEditor.getAttribute('data-page-ai-memory-editor') || ''; - if (['memory', 'user', 'soul'].indexOf(section) >= 0) { - pageUiState.pageAiProfileMemoryDrafts[section] = memoryEditor.value; - } - } }); document.addEventListener('change', function(event) { - var pageAiAcpRuntimeSelect = closestAction(event.target, '[data-page-ai-acp-runtime]'); - if (pageAiAcpRuntimeSelect instanceof HTMLSelectElement) { - var next = String(pageAiAcpRuntimeSelect.value || 'reasonix').trim() || 'reasonix'; - pageUiState.pageAiAcpRuntime = next; - pageUiState.pageAiSkills = { categories: [], archived: [] }; - pageUiState.pageAiSkillError = ''; - pageAiPersistSessions(); - void pageAiLoadProfiles(); - if (next !== 'reasonix') void pageAiLoadProfileMemory(); - void pageAiLoadSkills(); - void pageAiLoadBackendSessions().catch(function(error) { - pageUiState.pageAiSessionError = error instanceof Error ? error.message : String(error); - }); - renderPageAiControls(); - renderPageAiProviderButtons(); - return; - } - var pageAiProfileSelect = closestAction(event.target, '[data-page-ai-profile-select]'); - if (pageAiProfileSelect instanceof HTMLSelectElement) { - void pageAiSwitchProfile(pageAiProfileSelect.value); - return; - } - var pageAiHideHermesBuiltin = closestAction(event.target, '[data-page-ai-hide-hermes-builtin]'); - if (pageAiHideHermesBuiltin instanceof HTMLInputElement) { - pageAiSetHideHermesBuiltinSkills(pageAiHideHermesBuiltin.checked); - return; - } - var pageAiContextSelect = closestAction(event.target, '[data-page-ai-context-scope]'); - if (pageAiContextSelect instanceof HTMLSelectElement) { - pageAiSetContextScope(pageAiContextSelect.value); - renderPageAiControls(); - return; - } var globalCheckbox = closestAction(event.target, '[data-global-option-checkbox="showHeadingNumbers"]'); if (globalCheckbox instanceof HTMLInputElement) { writeGlobalShowHeadingNumbers(globalCheckbox.checked); @@ -3218,6 +2864,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim void persistPageWidthPreference(pageWidthType, pageWidthSelect.value); } }); + sidebarPageAi.installPageAiDelegates(); function initializePageUiSurfaces() { pageUiState.pageOptions = null; @@ -3243,6 +2890,14 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim } scheduleInitializePageUiSurfaces(); + function mnoteDevHotReloadEnabled() { + try { + return new URL(import.meta.url).searchParams.has('devHot'); + } catch (_) { + return false; + } + } + function installMnoteDevHotReload() { var bootId = ''; var failedOnce = false; @@ -3271,7 +2926,9 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim tick(); timer = window.setInterval(tick, 1000); } - installMnoteDevHotReload(); + if (mnoteDevHotReloadEnabled()) { + installMnoteDevHotReload(); + } document.addEventListener('dragstart', function(event) { var pageRow = closestAction(event.target, '.tree-row[data-shell-mode="page"][draggable="true"]'); diff --git a/rust/crates/mnote-web/src/acp_bridge.rs b/rust/crates/mnote-web/src/acp_bridge.rs index 3dc7346c..3ee73500 100644 --- a/rust/crates/mnote-web/src/acp_bridge.rs +++ b/rust/crates/mnote-web/src/acp_bridge.rs @@ -260,6 +260,20 @@ pub fn acp_event_to_sse(event: AcpSessionEvent) -> Option { event: "session.info.updated".into(), data: json!({ "title": title }), }), + AcpSessionEvent::ProviderConversationBound { + provider, + remote_conversation_id, + remote_url, + acp_session_id, + } => Some(SseEvent { + event: "provider.conversation.bound".into(), + data: json!({ + "provider": provider, + "remoteConversationId": remote_conversation_id, + "remoteUrl": remote_url, + "acpSessionId": acp_session_id, + }), + }), AcpSessionEvent::PlanUpdate { entries } => Some(SseEvent { event: "plan.updated".into(), data: json!({ "entries": entries }), diff --git a/rust/crates/mnote-web/src/acp_session_manager.rs b/rust/crates/mnote-web/src/acp_session_manager.rs index 83dd0689..e96d78ea 100644 --- a/rust/crates/mnote-web/src/acp_session_manager.rs +++ b/rust/crates/mnote-web/src/acp_session_manager.rs @@ -54,6 +54,13 @@ pub enum AcpSessionEvent { }, /// 会话元数据更新,例如自动标题。 SessionInfoUpdate { title: String }, + /// Provider 侧远端会话绑定,例如豆包 conversation_id。 + ProviderConversationBound { + provider: String, + remote_conversation_id: String, + remote_url: Option, + acp_session_id: Option, + }, /// 计划条目更新。 PlanUpdate { entries: Vec }, /// 连接关闭或异常。 @@ -765,6 +772,46 @@ impl AcpSessionManager { Some(AcpSessionEvent::PlanUpdate { entries: summaries }) } + SessionUpdate::Unknown { + session_update, + extra, + } if session_update == "provider.conversation.bound" => { + let provider = extra + .get("provider") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("doubao-web") + .to_string(); + let remote_conversation_id = extra + .get("remoteConversationId") + .or_else(|| extra.get("remote_conversation_id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty())? + .to_string(); + let remote_url = extra + .get("remoteUrl") + .or_else(|| extra.get("remote_url")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + let acp_session_id = extra + .get("acpSessionId") + .or_else(|| extra.get("acp_session_id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + Some(AcpSessionEvent::ProviderConversationBound { + provider, + remote_conversation_id, + remote_url, + acp_session_id, + }) + } + SessionUpdate::Unknown { .. } => { warn!("ACP unknown session/update variant"); None diff --git a/rust/crates/mnote-web/src/hermes_tools/manifest.rs b/rust/crates/mnote-web/src/hermes_tools/manifest.rs index 48d53838..78ce18e3 100644 --- a/rust/crates/mnote-web/src/hermes_tools/manifest.rs +++ b/rust/crates/mnote-web/src/hermes_tools/manifest.rs @@ -33,8 +33,44 @@ pub fn manifest() -> Value { available_tool("mnote.page.update_options", "更新当前页面设置", ["page.write"]), mindmap_fetch_tool(), mindmap_apply_ops_tool(), + mindmap_create_from_outline_tool(), office_fetch_summary_tool(), office_propose_changes_tool(), + onlyoffice_session_current_tool(), + onlyoffice_capabilities_tool(), + onlyoffice_selection_get_tool(), + onlyoffice_document_insert_text_tool(), + onlyoffice_document_replace_selection_tool(), + onlyoffice_document_insert_html_tool(), + onlyoffice_document_export_tool(), + onlyoffice_document_search_replace_tool(), + onlyoffice_document_insert_table_tool(), + onlyoffice_document_get_comments_tool(), + onlyoffice_document_add_comment_tool(), + onlyoffice_sheet_get_sheets_tool(), + onlyoffice_sheet_add_sheet_tool(), + onlyoffice_sheet_rename_sheet_tool(), + onlyoffice_sheet_get_range_tool(), + onlyoffice_sheet_get_range_values_tool(), + onlyoffice_sheet_get_values_tool(), + onlyoffice_sheet_set_value_tool(), + onlyoffice_sheet_set_formula_tool(), + onlyoffice_sheet_batch_set_values_tool(), + onlyoffice_sheet_set_range_values_tool(), + onlyoffice_sheet_format_range_tool(), + onlyoffice_sheet_set_dimensions_tool(), + onlyoffice_sheet_sort_range_tool(), + onlyoffice_sheet_add_chart_tool(), + onlyoffice_presentation_get_slides_tool(), + onlyoffice_presentation_get_slide_texts_tool(), + onlyoffice_presentation_get_shapes_tool(), + onlyoffice_presentation_add_text_slide_tool(), + onlyoffice_presentation_replace_text_tool(), + onlyoffice_presentation_set_shape_text_tool(), + onlyoffice_presentation_delete_slide_tool(), + onlyoffice_presentation_add_table_tool(), + onlyoffice_presentation_clear_slide_tool(), + onlyoffice_presentation_add_shape_tool(), available_tool("mnote.artifact.create_summary", "为当前页面创建或更新 AI Summary", ["artifact.write"]), available_tool("mnote.artifact.create_ai_note", "基于当前页面创建新的 AI Note", ["artifact.write"]) ] @@ -605,7 +641,7 @@ fn mindmap_fetch_tool() -> Value { if let Value::Object(map) = &mut properties { map.insert( "scope".into(), - json!({ "type": "string", "enum": ["tree", "subtree", "markdown_summary"], "default": "tree" }), + json!({ "type": "string", "enum": ["tree", "subtree", "markdown_summary", "full_envelope"], "default": "tree" }), ); map.insert("nodeId".into(), json!({ "type": "string" })); } @@ -645,6 +681,32 @@ fn mindmap_apply_ops_tool() -> Value { ) } +fn mindmap_create_from_outline_tool() -> Value { + write_tool( + "mnote.mindmap.create_from_outline", + "从 PDF、Office、Markdown 或页面摘要生成新的 MNote mindmap resource envelope", + ["resource.write", "mindmap.write"], + json!({ + "mindmapId": { "type": "string" }, + "rootUri": { "type": "string" }, + "sourceKind": { "type": "string" }, + "resourcePath": { "type": "string" }, + "title": { "type": "string" }, + "outline": { + "type": "array", + "items": { "type": "object" } + }, + "sourceRefs": { + "type": "array", + "items": { "type": "object" } + }, + "embedIntoPage": { "type": "boolean", "default": true }, + "aiAccessScope": { "type": "object" } + }), + ["mindmapId", "outline"], + ) +} + fn office_fetch_summary_tool() -> Value { let mut properties = resource_identity_properties("assetId"); if let Value::Object(map) = &mut properties { @@ -692,6 +754,1044 @@ fn office_propose_changes_tool() -> Value { }) } +fn onlyoffice_base_properties() -> Value { + let mut properties = base_identity_properties(); + if let Value::Object(map) = &mut properties { + map.insert("onlyofficeSessionId".into(), json!({ "type": "string" })); + map.insert("bridgeSessionId".into(), json!({ "type": "string" })); + map.insert( + "aiAccessScope".into(), + json!({ + "type": "object", + "required": ["allowedResourceIds"], + "properties": { + "permissionLevel": { "type": "string" }, + "allowedResourceIds": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1 + } + } + }), + ); + map.insert( + "timeoutMs".into(), + json!({ "type": "integer", "default": 25000 }), + ); + } + properties +} + +fn onlyoffice_session_current_tool() -> Value { + onlyoffice_tool( + "mnote.onlyoffice.session.current", + "返回显式授权的 ONLYOFFICE live bridge session。", + ["office.read"], + true, + onlyoffice_base_properties(), + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_capabilities_tool() -> Value { + onlyoffice_tool( + "mnote.onlyoffice.capabilities", + "返回当前 MNote ONLYOFFICE bridge 支持的白名单 action 和编辑器能力矩阵。", + ["office.read"], + true, + onlyoffice_base_properties(), + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_selection_get_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("options".into(), json!({ "type": "object" })); + } + onlyoffice_tool( + "mnote.onlyoffice.selection.get", + "读取当前 ONLYOFFICE 选区文本,支持文档、表格和演示。", + ["office.read"], + true, + properties, + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_document_insert_text_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("text".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.document.insert_text", + "向当前 ONLYOFFICE 文档/选区插入纯文本。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "text", + ], + ) +} + +fn onlyoffice_document_replace_selection_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("text".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.document.replace_selection", + "用纯文本替换当前 ONLYOFFICE 选区。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "text", + ], + ) +} + +fn onlyoffice_document_insert_html_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("html".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.document.insert_html", + "向当前 ONLYOFFICE 文档插入 HTML 片段。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "html", + ], + ) +} + +fn onlyoffice_document_export_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "format".into(), + json!({ "type": "string", "enum": ["markdown", "html"], "default": "markdown" }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.document.export", + "把当前 ONLYOFFICE 文档导出为 Markdown 或 HTML 文本,适合 agent 读取全文后再提出修改。", + ["office.read"], + true, + properties, + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_document_search_replace_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("search".into(), json!({ "type": "string" })); + map.insert("replace".into(), json!({ "type": "string", "default": "" })); + map.insert( + "matchCase".into(), + json!({ "type": "boolean", "default": false }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.document.search_replace", + "在当前 ONLYOFFICE Word 文档中执行文本查找替换。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "search", + ], + ) +} + +fn onlyoffice_document_insert_table_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("rows".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert("cols".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert("columns".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert( + "data".into(), + json!({ + "type": "array", + "items": { + "type": "array", + "items": {} + } + }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.document.insert_table", + "向当前 ONLYOFFICE Word 文档末尾插入表格,可用二维 data 填充单元格。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + ], + ) +} + +fn onlyoffice_document_get_comments_tool() -> Value { + onlyoffice_tool( + "mnote.onlyoffice.document.get_comments", + "读取当前 ONLYOFFICE Word 文档中的评论列表、作者、正文和引用文本。", + ["office.read"], + true, + onlyoffice_base_properties(), + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_document_add_comment_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("text".into(), json!({ "type": "string" })); + map.insert( + "author".into(), + json!({ "type": "string", "default": "MNote AI" }), + ); + map.insert( + "target".into(), + json!({ "type": "string", "enum": ["selection", "document_start"], "default": "selection" }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.document.add_comment", + "给当前 ONLYOFFICE Word 文档选区或文档开头段落添加评论。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "text", + ], + ) +} + +fn onlyoffice_sheet_get_sheets_tool() -> Value { + onlyoffice_tool( + "mnote.onlyoffice.sheet.get_sheets", + "读取当前 ONLYOFFICE 表格工作簿的工作表列表。", + ["office.read"], + true, + onlyoffice_base_properties(), + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_sheet_add_sheet_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("name".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.add_sheet", + "在当前 ONLYOFFICE 表格工作簿中新增工作表,并切换为活动工作表。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "name", + ], + ) +} + +fn onlyoffice_sheet_rename_sheet_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("name".into(), json!({ "type": "string" })); + map.insert( + "sheetIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert("sheetName".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.rename_sheet", + "重命名当前或指定 ONLYOFFICE 表格工作表。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "name", + ], + ) +} + +fn onlyoffice_sheet_get_range_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.get_range", + "读取当前 ONLYOFFICE 表格的指定单元格或区域;address 为空时读取当前选区。", + ["office.read"], + true, + properties, + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_sheet_get_range_values_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("range".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.get_range_values", + "按 A1 地址读取当前 ONLYOFFICE 表格 range 的二维值、显示值和公式。", + ["office.read"], + true, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "address", + ], + ) +} + +fn onlyoffice_sheet_get_values_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "startRow".into(), + json!({ "type": "integer", "default": 0 }), + ); + map.insert( + "startCol".into(), + json!({ "type": "integer", "default": 0 }), + ); + map.insert( + "rowCount".into(), + json!({ "type": "integer", "minimum": 1 }), + ); + map.insert( + "colCount".into(), + json!({ "type": "integer", "minimum": 1 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.get_values", + "按零基行列坐标批量读取当前 ONLYOFFICE 表格单元格值、显示值和公式。", + ["office.read"], + true, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "rowCount", + "colCount", + ], + ) +} + +fn onlyoffice_sheet_set_value_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("value".into(), json!({})); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.set_value", + "写入当前 ONLYOFFICE 表格的指定单元格或区域;address 为空时写入当前选区。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "value", + ], + ) +} + +fn onlyoffice_sheet_set_formula_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("formula".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.set_formula", + "向当前 ONLYOFFICE 表格写入公式。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "formula", + ], + ) +} + +fn onlyoffice_sheet_batch_set_values_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "startRow".into(), + json!({ "type": "integer", "default": 0 }), + ); + map.insert( + "startCol".into(), + json!({ "type": "integer", "default": 0 }), + ); + map.insert( + "values".into(), + json!({ + "type": "array", + "items": { + "type": "array", + "items": {} + } + }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.batch_set_values", + "按零基行列坐标向当前 ONLYOFFICE 表格批量写入二维数组。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "values", + ], + ) +} + +fn onlyoffice_sheet_set_range_values_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("range".into(), json!({ "type": "string" })); + map.insert( + "values".into(), + json!({ + "type": "array", + "items": { + "type": "array", + "items": {} + } + }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.set_range_values", + "按 A1 地址向当前 ONLYOFFICE 表格 range 写入二维数组。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "address", + "values", + ], + ) +} + +fn onlyoffice_sheet_format_range_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("range".into(), json!({ "type": "string" })); + map.insert("bold".into(), json!({ "type": "boolean" })); + map.insert("italic".into(), json!({ "type": "boolean" })); + map.insert("underline".into(), json!({ "type": "boolean" })); + map.insert("fillColor".into(), json!({ "type": "string" })); + map.insert("fontColor".into(), json!({ "type": "string" })); + map.insert("fontSize".into(), json!({ "type": "number", "minimum": 0 })); + map.insert("fontName".into(), json!({ "type": "string" })); + map.insert( + "horizontalAlign".into(), + json!({ "type": "string", "enum": ["left", "center", "right", "justify"] }), + ); + map.insert( + "verticalAlign".into(), + json!({ "type": "string", "enum": ["top", "center", "bottom"] }), + ); + map.insert("numberFormat".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.format_range", + "按 A1 地址设置当前 ONLYOFFICE 表格 range 的字体、颜色、对齐和数字格式。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "address", + ], + ) +} + +fn onlyoffice_sheet_set_dimensions_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "columnIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert( + "columnWidth".into(), + json!({ "type": "number", "minimum": 0 }), + ); + map.insert( + "rowIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert( + "rowHeight".into(), + json!({ "type": "number", "minimum": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.set_dimensions", + "设置当前 ONLYOFFICE 表格的列宽或行高;行列索引为零基。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + ], + ) +} + +fn onlyoffice_sheet_sort_range_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("range".into(), json!({ "type": "string" })); + map.insert( + "keyColumn".into(), + json!({ "type": "integer", "minimum": 1, "default": 1 }), + ); + map.insert( + "order".into(), + json!({ "type": "string", "enum": ["ascending", "descending", "asc", "desc"], "default": "ascending" }), + ); + map.insert( + "header".into(), + json!({ "type": "boolean", "default": true }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.sort_range", + "按 A1 range 对当前 ONLYOFFICE 表格区域排序;keyColumn 为 range 内从 1 开始的排序列。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "address", + ], + ) +} + +fn onlyoffice_sheet_add_chart_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("address".into(), json!({ "type": "string" })); + map.insert("range".into(), json!({ "type": "string" })); + map.insert( + "chartType".into(), + json!({ "type": "string", "default": "bar" }), + ); + map.insert( + "inColumns".into(), + json!({ "type": "boolean", "default": true }), + ); + map.insert("style".into(), json!({ "type": "integer", "default": 2 })); + map.insert( + "widthMm".into(), + json!({ "type": "number", "minimum": 0, "default": 120 }), + ); + map.insert( + "heightMm".into(), + json!({ "type": "number", "minimum": 0, "default": 80 }), + ); + map.insert( + "fromCol".into(), + json!({ "type": "integer", "minimum": 0, "default": 4 }), + ); + map.insert( + "fromRow".into(), + json!({ "type": "integer", "minimum": 0, "default": 1 }), + ); + map.insert( + "xOffsetMm".into(), + json!({ "type": "number", "minimum": 0, "default": 0 }), + ); + map.insert( + "yOffsetMm".into(), + json!({ "type": "number", "minimum": 0, "default": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.sheet.add_chart", + "基于当前 ONLYOFFICE 表格 A1 range 插入图表,默认生成柱状图。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "address", + ], + ) +} + +fn onlyoffice_presentation_get_slides_tool() -> Value { + onlyoffice_tool( + "mnote.onlyoffice.presentation.get_slides", + "读取当前 ONLYOFFICE 演示文稿的基础幻灯片信息。", + ["office.read"], + true, + onlyoffice_base_properties(), + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_presentation_get_slide_texts_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.get_slide_texts", + "读取当前 ONLYOFFICE 演示文稿中每页文本框的纯文本。", + ["office.read"], + true, + properties, + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_presentation_get_shapes_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.get_shapes", + "读取当前 ONLYOFFICE 演示文稿的 shape 列表、shapeId、shapeIndex 和文本。", + ["office.read"], + true, + properties, + &["sessionId", "runId", "toolCallId", "traceId", "actorId"], + ) +} + +fn onlyoffice_presentation_add_text_slide_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("title".into(), json!({ "type": "string" })); + map.insert("body".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.add_text_slide", + "向当前 ONLYOFFICE 演示文稿追加一个文本幻灯片。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + ], + ) +} + +fn onlyoffice_presentation_replace_text_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert("search".into(), json!({ "type": "string" })); + map.insert("replace".into(), json!({ "type": "string", "default": "" })); + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert( + "matchCase".into(), + json!({ "type": "boolean", "default": false }), + ); + map.insert( + "replaceAll".into(), + json!({ "type": "boolean", "default": true }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.replace_text", + "替换当前 ONLYOFFICE 演示文稿文本框中的纯文本;命中的文本框会按纯文本段落重建。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "search", + ], + ) +} + +fn onlyoffice_presentation_set_shape_text_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert( + "shapeIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert("shapeId".into(), json!({ "type": "string" })); + map.insert("text".into(), json!({ "type": "string" })); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.set_shape_text", + "用 slideIndex + shapeIndex/shapeId 精确设置 PPT 文本 shape 的纯文本。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "slideIndex", + "text", + ], + ) +} + +fn onlyoffice_presentation_delete_slide_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.delete_slide", + "删除当前 ONLYOFFICE 演示文稿中的指定幻灯片。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "slideIndex", + ], + ) +} + +fn onlyoffice_presentation_add_table_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert("rows".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert("cols".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert("columns".into(), json!({ "type": "integer", "minimum": 1 })); + map.insert( + "data".into(), + json!({ + "type": "array", + "items": { + "type": "array", + "items": {} + } + }), + ); + map.insert("xMm".into(), json!({ "type": "number", "minimum": 0 })); + map.insert("yMm".into(), json!({ "type": "number", "minimum": 0 })); + map.insert( + "widthMm".into(), + json!({ "type": "number", "minimum": 0, "default": 190 }), + ); + map.insert( + "heightMm".into(), + json!({ "type": "number", "minimum": 0, "default": 90 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.add_table", + "向当前 ONLYOFFICE PPT 指定幻灯片插入表格,可用二维 data 填充单元格。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + ], + ) +} + +fn onlyoffice_presentation_clear_slide_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.clear_slide", + "清空当前 ONLYOFFICE PPT 指定幻灯片上的所有对象。调用前必须确认 slideIndex。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + "slideIndex", + ], + ) +} + +fn onlyoffice_presentation_add_shape_tool() -> Value { + let mut properties = onlyoffice_base_properties(); + if let Value::Object(map) = &mut properties { + map.insert( + "slideIndex".into(), + json!({ "type": "integer", "minimum": 0 }), + ); + map.insert( + "shapeType".into(), + json!({ "type": "string", "enum": ["rect", "roundRect", "ellipse", "triangle", "diamond", "cube", "cloud", "flowChartMagneticTape"], "default": "rect" }), + ); + map.insert("text".into(), json!({ "type": "string" })); + map.insert( + "fillColor".into(), + json!({ "type": "string", "default": "#4F81BD" }), + ); + map.insert("strokeColor".into(), json!({ "type": "string" })); + map.insert( + "strokeWidthMm".into(), + json!({ "type": "number", "minimum": 0, "default": 0 }), + ); + map.insert( + "xMm".into(), + json!({ "type": "number", "minimum": 0, "default": 20 }), + ); + map.insert( + "yMm".into(), + json!({ "type": "number", "minimum": 0, "default": 35 }), + ); + map.insert( + "widthMm".into(), + json!({ "type": "number", "minimum": 0, "default": 160 }), + ); + map.insert( + "heightMm".into(), + json!({ "type": "number", "minimum": 0, "default": 70 }), + ); + } + onlyoffice_tool( + "mnote.onlyoffice.presentation.add_shape", + "向当前 ONLYOFFICE PPT 指定幻灯片插入基础形状,可设置文字、填充色、位置和尺寸。", + ["office.write"], + false, + properties, + &[ + "sessionId", + "runId", + "toolCallId", + "traceId", + "actorId", + "idempotencyKey", + "dryRun", + ], + ) +} + +fn onlyoffice_tool( + name: &'static str, + description: &'static str, + capability_scope: impl IntoIterator, + readonly: bool, + properties: Value, + required: &[&'static str], +) -> Value { + let mut required_fields = required.to_vec(); + if name != "mnote.onlyoffice.capabilities" { + required_fields.push("aiAccessScope"); + } + let mut input_schema = json!({ + "type": "object", + "required": required_fields, + "properties": properties + }); + if name != "mnote.onlyoffice.capabilities" { + input_schema["anyOf"] = json!([ + { "required": ["onlyofficeSessionId"] }, + { "required": ["bridgeSessionId"] } + ]); + } + json!({ + "name": name, + "description": description, + "schemaVersion": TOOL_SCHEMA_VERSION, + "capabilityScope": capability_scope.into_iter().collect::>(), + "status": "available", + "annotations": tool_annotations(readonly, false, readonly, false), + "inputSchema": input_schema + }) +} + fn tool_annotations( readonly: bool, destructive: bool, diff --git a/rust/crates/mnote-web/src/hermes_tools/mod.rs b/rust/crates/mnote-web/src/hermes_tools/mod.rs index 43215a79..0be90a1e 100644 --- a/rust/crates/mnote-web/src/hermes_tools/mod.rs +++ b/rust/crates/mnote-web/src/hermes_tools/mod.rs @@ -3,6 +3,7 @@ pub mod block; pub mod context_tools; pub mod doc; pub mod manifest; +pub mod onlyoffice_live; pub mod page; pub mod resource; pub mod skill; diff --git a/rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs b/rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs new file mode 100644 index 00000000..507fec2a --- /dev/null +++ b/rust/crates/mnote-web/src/hermes_tools/onlyoffice_live.rs @@ -0,0 +1,1130 @@ +use crate::context::RequestContext; +use crate::error::WebError; +use crate::hermes_tools::{ensure_write_authorized, ToolCallInput}; +use crate::routes::onlyoffice_bridge::{self, BridgeResultWire, BridgeRunError}; +use axum::http::StatusCode; +use serde_json::{json, Value}; +use std::collections::HashSet; + +const DEFAULT_TIMEOUT_MS: u64 = 25_000; +const MAX_SHEET_BATCH_CELLS: u64 = 5_000; +const MAX_DOCUMENT_TABLE_CELLS: u64 = 1_000; +const MAX_PRESENTATION_TABLE_CELLS: u64 = 200; + +pub async fn session_current( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let session = current_session(context, input)?; + Ok(json!({ + "schema": "mnote.onlyoffice.session.v1", + "session": session + })) +} + +pub async fn capabilities( + _context: &RequestContext, + _input: &ToolCallInput, +) -> Result { + Ok(onlyoffice_bridge::capability_payload()) +} + +pub async fn selection_get( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_read_action( + context, + input, + "selection.get", + json!({ + "options": input.arg_value("options").unwrap_or_else(|| json!({})) + }), + ) + .await +} + +pub async fn sheet_get_range( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_read_action( + context, + input, + "sheet.get_range", + json!({ + "address": input.arg_string("address").unwrap_or_default() + }), + ) + .await +} + +pub async fn document_export( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let format = input + .arg_string("format") + .unwrap_or_else(|| "markdown".into()) + .to_ascii_lowercase(); + if !matches!(format.as_str(), "markdown" | "html") { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_export_format_invalid", + "format 仅支持 markdown 或 html", + ) + .with_context(context)); + } + run_read_action( + context, + input, + "document.export", + json!({ "format": format }), + ) + .await +} + +pub async fn document_search_replace( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let search = required_string(context, input, "search")?; + if search.is_empty() { + return Err( + WebError::bad_request_code("mnote_onlyoffice_search_empty", "search 不能为空") + .with_context(context), + ); + } + run_write_action( + context, + input, + "document.search_replace", + json!({ + "search": search, + "replace": input.arg_string("replace").unwrap_or_default(), + "matchCase": arg_bool(input, "matchCase").unwrap_or(false) + }), + ) + .await +} + +pub async fn document_insert_table( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let data = input.arg_value("data").unwrap_or_else(|| json!([])); + let rows_from_data = data.as_array().map(|rows| rows.len() as u64).unwrap_or(0); + let cols_from_data = data + .as_array() + .and_then(|rows| { + rows.iter() + .map(|row| row.as_array().map(|cells| cells.len() as u64).unwrap_or(1)) + .max() + }) + .unwrap_or(0); + let rows = arg_u64(input, "rows").unwrap_or(rows_from_data).max(1); + let cols = arg_u64(input, "cols") + .or_else(|| arg_u64(input, "columns")) + .unwrap_or(cols_from_data) + .max(1); + if rows.saturating_mul(cols) > MAX_DOCUMENT_TABLE_CELLS { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_table_too_large", + format!("单次 Word 表格最多支持 {MAX_DOCUMENT_TABLE_CELLS} 个单元格"), + ) + .with_context(context)); + } + run_write_action( + context, + input, + "document.insert_table", + json!({ + "rows": rows, + "cols": cols, + "data": data + }), + ) + .await +} + +pub async fn document_get_comments( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_read_action(context, input, "document.get_comments", json!({})).await +} + +pub async fn document_add_comment( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let text = required_string(context, input, "text")?; + run_write_action( + context, + input, + "document.add_comment", + json!({ + "text": text, + "author": input.arg_string("author").unwrap_or_else(|| "MNote AI".into()), + "target": input.arg_string("target").unwrap_or_else(|| "selection".into()) + }), + ) + .await +} + +pub async fn sheet_get_sheets( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_read_action(context, input, "sheet.get_sheets", json!({})).await +} + +pub async fn sheet_add_sheet( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let name = required_string(context, input, "name")?; + run_write_action(context, input, "sheet.add_sheet", json!({ "name": name })).await +} + +pub async fn sheet_rename_sheet( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let name = required_string(context, input, "name")?; + run_write_action( + context, + input, + "sheet.rename_sheet", + json!({ + "name": name, + "sheetIndex": arg_u64(input, "sheetIndex"), + "sheetName": input.arg_string("sheetName").unwrap_or_default() + }), + ) + .await +} + +pub async fn sheet_get_range_values( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let address = input + .arg_string("address") + .or_else(|| input.arg_string("range")) + .ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_range_required", "缺少 address") + .with_context(context) + })?; + let range = parse_a1_range(context, &address)?; + ensure_sheet_cell_limit(context, range.row_count, range.col_count)?; + run_read_action( + context, + input, + "sheet.get_range_values", + json!({ "address": address }), + ) + .await +} + +pub async fn sheet_get_values( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let start_row = arg_u64(input, "startRow").unwrap_or(0); + let start_col = arg_u64(input, "startCol").unwrap_or(0); + let row_count = required_u64(context, input, "rowCount")?; + let col_count = required_u64(context, input, "colCount")?; + ensure_sheet_cell_limit(context, row_count, col_count)?; + run_read_action( + context, + input, + "sheet.get_values", + json!({ + "startRow": start_row, + "startCol": start_col, + "rowCount": row_count, + "colCount": col_count + }), + ) + .await +} + +pub async fn presentation_get_slides( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_read_action(context, input, "presentation.get_slides", json!({})).await +} + +pub async fn presentation_get_slide_texts( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let mut payload = json!({}); + if let Some(slide_index) = arg_u64(input, "slideIndex") { + payload["slideIndex"] = json!(slide_index); + } + run_read_action(context, input, "presentation.get_slide_texts", payload).await +} + +pub async fn presentation_get_shapes( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let mut payload = json!({}); + if let Some(slide_index) = arg_u64(input, "slideIndex") { + payload["slideIndex"] = json!(slide_index); + } + run_read_action(context, input, "presentation.get_shapes", payload).await +} + +pub async fn document_insert_text( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let text = required_string(context, input, "text")?; + run_write_action( + context, + input, + "document.insert_text", + json!({ "text": text }), + ) + .await +} + +pub async fn document_replace_selection( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let text = required_string(context, input, "text")?; + run_write_action( + context, + input, + "document.replace_selection", + json!({ "text": text }), + ) + .await +} + +pub async fn document_insert_html( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let html = required_string(context, input, "html")?; + run_write_action( + context, + input, + "document.insert_html", + json!({ "html": html }), + ) + .await +} + +pub async fn sheet_set_value( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let value = input.arg_value("value").ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_value_required", "缺少 value") + .with_context(context) + })?; + run_write_action( + context, + input, + "sheet.set_value", + json!({ + "address": input.arg_string("address").unwrap_or_default(), + "value": value + }), + ) + .await +} + +pub async fn sheet_set_formula( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let formula = required_string(context, input, "formula")?; + run_write_action( + context, + input, + "sheet.set_formula", + json!({ + "address": input.arg_string("address").unwrap_or_default(), + "formula": formula + }), + ) + .await +} + +pub async fn sheet_batch_set_values( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let values = input.arg_value("values").ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_values_required", "缺少 values") + .with_context(context) + })?; + let rows = values.as_array().ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_values_invalid", "values 必须是二维数组") + .with_context(context) + })?; + let row_count = rows.len() as u64; + let col_count = rows + .iter() + .map(|row| row.as_array().map(|cells| cells.len()).unwrap_or(1)) + .max() + .unwrap_or(0) as u64; + if row_count == 0 || col_count == 0 { + return Err( + WebError::bad_request_code("mnote_onlyoffice_values_empty", "values 不能为空") + .with_context(context), + ); + } + ensure_sheet_cell_limit(context, row_count, col_count)?; + run_write_action( + context, + input, + "sheet.batch_set_values", + json!({ + "startRow": arg_u64(input, "startRow").unwrap_or(0), + "startCol": arg_u64(input, "startCol").unwrap_or(0), + "values": values + }), + ) + .await +} + +pub async fn sheet_set_range_values( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let address = input + .arg_string("address") + .or_else(|| input.arg_string("range")) + .ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_range_required", "缺少 address") + .with_context(context) + })?; + let range = parse_a1_range(context, &address)?; + ensure_sheet_cell_limit(context, range.row_count, range.col_count)?; + let values = input.arg_value("values").ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_values_required", "缺少 values") + .with_context(context) + })?; + let rows = values.as_array().ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_values_invalid", "values 必须是二维数组") + .with_context(context) + })?; + let row_count = rows.len() as u64; + let col_count = rows + .iter() + .map(|row| row.as_array().map(|cells| cells.len()).unwrap_or(1)) + .max() + .unwrap_or(0) as u64; + if row_count == 0 || col_count == 0 { + return Err( + WebError::bad_request_code("mnote_onlyoffice_values_empty", "values 不能为空") + .with_context(context), + ); + } + ensure_sheet_cell_limit(context, row_count, col_count)?; + run_write_action( + context, + input, + "sheet.set_range_values", + json!({ + "address": address, + "values": values + }), + ) + .await +} + +pub async fn sheet_format_range( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let address = input + .arg_string("address") + .or_else(|| input.arg_string("range")) + .ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_range_required", "缺少 address") + .with_context(context) + })?; + let range = parse_a1_range(context, &address)?; + ensure_sheet_cell_limit(context, range.row_count, range.col_count)?; + run_write_action( + context, + input, + "sheet.format_range", + json!({ + "address": address, + "bold": arg_bool(input, "bold"), + "italic": arg_bool(input, "italic"), + "underline": arg_bool(input, "underline"), + "fillColor": input.arg_string("fillColor").or_else(|| input.arg_string("fill_color")).unwrap_or_default(), + "fontColor": input.arg_string("fontColor").or_else(|| input.arg_string("font_color")).unwrap_or_default(), + "fontSize": arg_f64(input, "fontSize"), + "fontName": input.arg_string("fontName").or_else(|| input.arg_string("font_name")).unwrap_or_default(), + "horizontalAlign": input.arg_string("horizontalAlign").or_else(|| input.arg_string("horizontal_align")).unwrap_or_default(), + "verticalAlign": input.arg_string("verticalAlign").or_else(|| input.arg_string("vertical_align")).unwrap_or_default(), + "numberFormat": input.arg_string("numberFormat").or_else(|| input.arg_string("number_format")).unwrap_or_default() + }), + ) + .await +} + +pub async fn sheet_set_dimensions( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let column_index = arg_u64(input, "columnIndex"); + let column_width = arg_f64(input, "columnWidth"); + let row_index = arg_u64(input, "rowIndex"); + let row_height = arg_f64(input, "rowHeight"); + let has_column = column_index.is_some() && column_width.is_some(); + let has_row = row_index.is_some() && row_height.is_some(); + if !has_column && !has_row { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_dimensions_required", + "缺少 columnIndex/columnWidth 或 rowIndex/rowHeight", + ) + .with_context(context)); + } + run_write_action( + context, + input, + "sheet.set_dimensions", + json!({ + "columnIndex": column_index, + "columnWidth": column_width, + "rowIndex": row_index, + "rowHeight": row_height + }), + ) + .await +} + +pub async fn sheet_sort_range( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let address = input + .arg_string("address") + .or_else(|| input.arg_string("range")) + .ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_range_required", "缺少 address") + .with_context(context) + })?; + let range = parse_a1_range(context, &address)?; + ensure_sheet_cell_limit(context, range.row_count, range.col_count)?; + let key_column = arg_u64(input, "keyColumn").unwrap_or(1).max(1); + if key_column > range.col_count { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_sort_key_out_of_range", + "keyColumn 必须落在排序 range 内,且从 1 开始", + ) + .with_context(context)); + } + let order = input + .arg_string("order") + .unwrap_or_else(|| "ascending".into()) + .to_ascii_lowercase(); + if !matches!( + order.as_str(), + "ascending" | "descending" | "asc" | "desc" | "xlascending" | "xldescending" + ) { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_sort_order_invalid", + "order 仅支持 ascending/descending", + ) + .with_context(context)); + } + run_write_action( + context, + input, + "sheet.sort_range", + json!({ + "address": address, + "keyColumn": key_column, + "order": order, + "header": arg_bool(input, "header").unwrap_or(true) + }), + ) + .await +} + +pub async fn sheet_add_chart( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let address = input + .arg_string("address") + .or_else(|| input.arg_string("range")) + .ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_range_required", "缺少 address") + .with_context(context) + })?; + let range = parse_a1_range(context, &address)?; + ensure_sheet_cell_limit(context, range.row_count, range.col_count)?; + let chart_type = input + .arg_string("chartType") + .or_else(|| input.arg_string("chart_type")) + .unwrap_or_else(|| "bar".into()); + run_write_action( + context, + input, + "sheet.add_chart", + json!({ + "address": address, + "chartType": chart_type, + "inColumns": arg_bool(input, "inColumns").unwrap_or(true), + "style": arg_u64(input, "style").unwrap_or(2), + "widthMm": arg_f64(input, "widthMm").unwrap_or(120.0), + "heightMm": arg_f64(input, "heightMm").unwrap_or(80.0), + "fromCol": arg_u64(input, "fromCol").unwrap_or(4), + "xOffsetMm": arg_f64(input, "xOffsetMm").unwrap_or(0.0), + "fromRow": arg_u64(input, "fromRow").unwrap_or(1), + "yOffsetMm": arg_f64(input, "yOffsetMm").unwrap_or(0.0) + }), + ) + .await +} + +pub async fn presentation_add_text_slide( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + run_write_action( + context, + input, + "presentation.add_text_slide", + json!({ + "title": input.arg_string("title").unwrap_or_default(), + "body": input.arg_string("body").unwrap_or_default() + }), + ) + .await +} + +pub async fn presentation_add_table( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let data = input.arg_value("data").unwrap_or_else(|| json!([])); + let rows_from_data = data.as_array().map(|rows| rows.len() as u64).unwrap_or(0); + let cols_from_data = data + .as_array() + .and_then(|rows| { + rows.iter() + .map(|row| row.as_array().map(|cells| cells.len() as u64).unwrap_or(1)) + .max() + }) + .unwrap_or(0); + let rows = arg_u64(input, "rows").unwrap_or(rows_from_data).max(1); + let cols = arg_u64(input, "cols") + .or_else(|| arg_u64(input, "columns")) + .unwrap_or(cols_from_data) + .max(1); + if rows.saturating_mul(cols) > MAX_PRESENTATION_TABLE_CELLS { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_presentation_table_too_large", + format!("单次 PPT 表格最多支持 {MAX_PRESENTATION_TABLE_CELLS} 个单元格"), + ) + .with_context(context)); + } + let mut payload = json!({ + "rows": rows, + "cols": cols, + "data": data, + "widthMm": arg_f64(input, "widthMm").unwrap_or(190.0), + "heightMm": arg_f64(input, "heightMm").unwrap_or(90.0) + }); + if let Some(slide_index) = arg_u64(input, "slideIndex") { + payload["slideIndex"] = json!(slide_index); + } + if let Some(x_mm) = arg_f64(input, "xMm") { + payload["xMm"] = json!(x_mm); + } + if let Some(y_mm) = arg_f64(input, "yMm") { + payload["yMm"] = json!(y_mm); + } + run_write_action(context, input, "presentation.add_table", payload).await +} + +pub async fn presentation_clear_slide( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let slide_index = required_u64(context, input, "slideIndex")?; + run_write_action( + context, + input, + "presentation.clear_slide", + json!({ "slideIndex": slide_index }), + ) + .await +} + +pub async fn presentation_add_shape( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let shape_type = input + .arg_string("shapeType") + .or_else(|| input.arg_string("shape_type")) + .unwrap_or_else(|| "rect".into()); + let allowed_shapes = [ + "rect", + "roundRect", + "ellipse", + "triangle", + "diamond", + "cube", + "cloud", + "flowChartMagneticTape", + ]; + if !allowed_shapes.contains(&shape_type.as_str()) { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_shape_type_invalid", + "shapeType 不在允许列表中", + ) + .with_context(context)); + } + let mut payload = json!({ + "shapeType": shape_type, + "text": input.arg_string("text").unwrap_or_default(), + "fillColor": input.arg_string("fillColor").or_else(|| input.arg_string("fill_color")).unwrap_or_else(|| "#4F81BD".into()), + "strokeColor": input.arg_string("strokeColor").or_else(|| input.arg_string("stroke_color")).unwrap_or_default(), + "strokeWidthMm": arg_f64(input, "strokeWidthMm").unwrap_or(0.0), + "xMm": arg_f64(input, "xMm").unwrap_or(20.0), + "yMm": arg_f64(input, "yMm").unwrap_or(35.0), + "widthMm": arg_f64(input, "widthMm").unwrap_or(160.0), + "heightMm": arg_f64(input, "heightMm").unwrap_or(70.0) + }); + if let Some(slide_index) = arg_u64(input, "slideIndex") { + payload["slideIndex"] = json!(slide_index); + } + run_write_action(context, input, "presentation.add_shape", payload).await +} + +pub async fn presentation_replace_text( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let search = required_string(context, input, "search")?; + if search.is_empty() { + return Err( + WebError::bad_request_code("mnote_onlyoffice_search_empty", "search 不能为空") + .with_context(context), + ); + } + let mut payload = json!({ + "search": search, + "replace": input.arg_string("replace").unwrap_or_default(), + "matchCase": arg_bool(input, "matchCase").unwrap_or(false), + "replaceAll": arg_bool(input, "replaceAll").unwrap_or(true) + }); + if let Some(slide_index) = arg_u64(input, "slideIndex") { + payload["slideIndex"] = json!(slide_index); + } + run_write_action(context, input, "presentation.replace_text", payload).await +} + +pub async fn presentation_set_shape_text( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let slide_index = required_u64(context, input, "slideIndex")?; + let text = required_string(context, input, "text")?; + let shape_index = arg_u64(input, "shapeIndex"); + let shape_id = input.arg_string("shapeId"); + if shape_index.is_none() && shape_id.as_deref().unwrap_or_default().trim().is_empty() { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_shape_locator_required", + "缺少 shapeIndex 或 shapeId", + ) + .with_context(context)); + } + run_write_action( + context, + input, + "presentation.set_shape_text", + json!({ + "slideIndex": slide_index, + "shapeIndex": shape_index, + "shapeId": shape_id.unwrap_or_default(), + "text": text + }), + ) + .await +} + +pub async fn presentation_delete_slide( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + let slide_index = required_u64(context, input, "slideIndex")?; + run_write_action( + context, + input, + "presentation.delete_slide", + json!({ "slideIndex": slide_index }), + ) + .await +} + +async fn run_read_action( + context: &RequestContext, + input: &ToolCallInput, + action: &'static str, + payload: Value, +) -> Result { + let session_id = resolve_explicit_session_id(context, input)?; + ensure_onlyoffice_resource_scope_allowed(context, input, &session_id)?; + let result = run_bridge(context, input, &session_id, action, payload).await?; + Ok(action_result(action, &session_id, result)) +} + +async fn run_write_action( + context: &RequestContext, + input: &ToolCallInput, + action: &'static str, + payload: Value, +) -> Result { + ensure_write_authorized(context, input)?; + let session_id = resolve_explicit_session_id(context, input)?; + ensure_onlyoffice_resource_scope_allowed(context, input, &session_id)?; + if input.dry_run.unwrap_or(false) { + return Ok(json!({ + "schema": "mnote.onlyoffice.action_plan.v1", + "sessionId": session_id, + "action": action, + "payload": payload, + "dryRun": true, + "wouldWrite": true + })); + } + let result = run_bridge(context, input, &session_id, action, payload).await?; + Ok(action_result(action, &session_id, result)) +} + +async fn run_bridge( + context: &RequestContext, + input: &ToolCallInput, + session_id: &str, + action: &'static str, + payload: Value, +) -> Result { + let timeout_ms = input + .arg_value("timeoutMs") + .or_else(|| input.arg_value("timeout_ms")) + .and_then(|value| value.as_u64()) + .unwrap_or(DEFAULT_TIMEOUT_MS); + let result = onlyoffice_bridge::run_bridge_command(session_id, action, payload, timeout_ms) + .await + .map_err(|error| bridge_run_error(context, error))?; + if !result.ok { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_bridge_failed", + result + .error + .clone() + .unwrap_or_else(|| "ONLYOFFICE bridge 命令执行失败".into()), + ) + .with_context(context)); + } + Ok(result) +} + +fn action_result(action: &str, session_id: &str, result: BridgeResultWire) -> Value { + json!({ + "schema": "mnote.onlyoffice.action_result.v1", + "sessionId": session_id, + "action": action, + "commandId": result.id, + "result": result.result + }) +} + +fn resolve_explicit_session_id( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + input + .arg_string("onlyofficeSessionId") + .or_else(|| input.arg_string("bridgeSessionId")) + .ok_or_else(|| { + WebError::bad_request_code( + "mnote_onlyoffice_session_explicit_required", + "ONLYOFFICE 工具必须显式携带 onlyofficeSessionId", + ) + .with_context(context) + }) +} + +fn ensure_onlyoffice_resource_scope_allowed( + context: &RequestContext, + input: &ToolCallInput, + session_id: &str, +) -> Result<(), WebError> { + let Some(scope) = input.arg_value("aiAccessScope") else { + return Err(WebError::new( + StatusCode::FORBIDDEN, + "mnote_onlyoffice_resource_scope_required", + "ONLYOFFICE 工具必须携带 aiAccessScope.allowedResourceIds", + ) + .with_context(context)); + }; + let allowed = scope + .get("allowedResourceIds") + .or_else(|| scope.get("allowed_resource_ids")) + .and_then(Value::as_array) + .map(|values| { + values + .iter() + .filter_map(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + .collect::>() + }) + .unwrap_or_default(); + if allowed.is_empty() { + return Err(WebError::new( + StatusCode::FORBIDDEN, + "mnote_onlyoffice_resource_scope_required", + "ONLYOFFICE 工具必须携带非空 aiAccessScope.allowedResourceIds", + ) + .with_context(context)); + } + let Some(session) = onlyoffice_bridge::session_info(session_id) else { + return Err(WebError::new( + StatusCode::FORBIDDEN, + "mnote_onlyoffice_resource_scope_forbidden", + "ONLYOFFICE session 未注册,无法校验资源授权", + ) + .with_context(context)); + }; + let mut candidates = HashSet::new(); + candidates.insert(session.session_id); + let document_id = session.document_id; + let asset_id = session.asset_id; + if let Some(document_id) = document_id.as_deref() { + candidates.insert(document_id.to_string()); + } + if let Some(asset_id) = asset_id.as_deref() { + candidates.insert(asset_id.to_string()); + } + if let (Some(document_id), Some(asset_id)) = (document_id.as_deref(), asset_id.as_deref()) { + candidates.insert(format!("resource:office:{document_id}:{asset_id}")); + candidates.insert(format!("resource:onlyoffice:{document_id}:{asset_id}")); + } + if candidates + .iter() + .any(|candidate| allowed.contains(candidate)) + { + return Ok(()); + } + Err(WebError::new( + StatusCode::FORBIDDEN, + "mnote_onlyoffice_resource_scope_forbidden", + "ONLYOFFICE session 不在当前 AI resource 授权范围内", + ) + .with_context(context)) +} + +fn current_session(context: &RequestContext, input: &ToolCallInput) -> Result { + let session_id = resolve_explicit_session_id(context, input)?; + ensure_onlyoffice_resource_scope_allowed(context, input, &session_id)?; + let session = onlyoffice_bridge::session_info(&session_id).ok_or_else(|| { + WebError::new( + StatusCode::NOT_FOUND, + "mnote_onlyoffice_session_not_found", + "指定的 ONLYOFFICE bridge session 不存在,请先打开 ONLYOFFICE 文档", + ) + .with_context(context) + })?; + Ok(json!({ + "sessionId": session.session_id, + "editorType": session.editor_type.unwrap_or_default(), + "documentId": session.document_id.unwrap_or_default(), + "assetId": session.asset_id.unwrap_or_default(), + "fileType": session.file_type.unwrap_or_default(), + "lastSeenMillis": session.last_seen_millis, + "pendingCommands": session.pending_commands, + "pendingResults": session.pending_results + })) +} + +fn required_string( + context: &RequestContext, + input: &ToolCallInput, + key: &'static str, +) -> Result { + input.arg_string(key).ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_argument_required", format!("缺少 {key}")) + .with_context(context) + }) +} + +fn required_u64( + context: &RequestContext, + input: &ToolCallInput, + key: &'static str, +) -> Result { + arg_u64(input, key).ok_or_else(|| { + WebError::bad_request_code("mnote_onlyoffice_argument_required", format!("缺少 {key}")) + .with_context(context) + }) +} + +fn arg_u64(input: &ToolCallInput, key: &'static str) -> Option { + input + .arg_value(key) + .or_else(|| match key { + "startRow" => input.arg_value("start_row"), + "startCol" => input.arg_value("start_col"), + "rowCount" => input.arg_value("row_count"), + "colCount" => input.arg_value("col_count"), + "slideIndex" => input.arg_value("slide_index"), + "sheetIndex" => input.arg_value("sheet_index"), + "shapeIndex" => input.arg_value("shape_index"), + "columnIndex" => input.arg_value("column_index"), + "rowIndex" => input.arg_value("row_index"), + "keyColumn" => input.arg_value("key_column"), + "fromCol" => input.arg_value("from_col"), + "fromRow" => input.arg_value("from_row"), + "cols" => input.arg_value("columns"), + _ => None, + }) + .and_then(|value| value.as_u64()) +} + +fn arg_f64(input: &ToolCallInput, key: &'static str) -> Option { + input + .arg_value(key) + .or_else(|| match key { + "columnWidth" => input.arg_value("column_width"), + "rowHeight" => input.arg_value("row_height"), + "fontSize" => input.arg_value("font_size"), + "widthMm" => input.arg_value("width_mm"), + "heightMm" => input.arg_value("height_mm"), + "xOffsetMm" => input.arg_value("x_offset_mm"), + "yOffsetMm" => input.arg_value("y_offset_mm"), + "xMm" => input.arg_value("x_mm"), + "yMm" => input.arg_value("y_mm"), + "strokeWidthMm" => input.arg_value("stroke_width_mm"), + _ => None, + }) + .and_then(|value| value.as_f64()) + .filter(|value| value.is_finite() && *value >= 0.0) +} + +fn arg_bool(input: &ToolCallInput, key: &'static str) -> Option { + input + .arg_value(key) + .or_else(|| match key { + "matchCase" => input.arg_value("match_case"), + "replaceAll" => input.arg_value("replace_all"), + "inColumns" => input.arg_value("in_columns"), + _ => None, + }) + .and_then(|value| value.as_bool()) +} + +fn ensure_sheet_cell_limit( + context: &RequestContext, + row_count: u64, + col_count: u64, +) -> Result<(), WebError> { + if row_count == 0 || col_count == 0 { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_sheet_range_empty", + "rowCount 和 colCount 必须大于 0", + ) + .with_context(context)); + } + if row_count.saturating_mul(col_count) > MAX_SHEET_BATCH_CELLS { + return Err(WebError::bad_request_code( + "mnote_onlyoffice_sheet_range_too_large", + format!("单次表格批量操作最多支持 {MAX_SHEET_BATCH_CELLS} 个单元格"), + ) + .with_context(context)); + } + Ok(()) +} + +#[derive(Debug)] +struct A1Range { + row_count: u64, + col_count: u64, +} + +fn parse_a1_range(context: &RequestContext, address: &str) -> Result { + let value = address.trim(); + let mut parts = value.split(':'); + let start = parts.next().unwrap_or_default(); + let end = parts.next().unwrap_or(start); + if parts.next().is_some() { + return Err(invalid_a1_range(context)); + } + let (start_row, start_col) = parse_a1_cell(start).ok_or_else(|| invalid_a1_range(context))?; + let (end_row, end_col) = parse_a1_cell(end).ok_or_else(|| invalid_a1_range(context))?; + Ok(A1Range { + row_count: start_row.abs_diff(end_row) + 1, + col_count: start_col.abs_diff(end_col) + 1, + }) +} + +fn parse_a1_cell(value: &str) -> Option<(u64, u64)> { + let value = value.trim(); + let split_at = value + .char_indices() + .find_map(|(index, ch)| ch.is_ascii_digit().then_some(index))?; + let (letters, digits) = value.split_at(split_at); + if letters.is_empty() + || digits.is_empty() + || !letters.chars().all(|ch| ch.is_ascii_alphabetic()) + || !digits.chars().all(|ch| ch.is_ascii_digit()) + { + return None; + } + let mut col = 0_u64; + for ch in letters.chars() { + col = col + .saturating_mul(26) + .saturating_add((ch.to_ascii_uppercase() as u8 - b'A' + 1) as u64); + } + let row = digits.parse::().ok()?; + if row == 0 || col == 0 { + return None; + } + Some((row - 1, col - 1)) +} + +fn invalid_a1_range(context: &RequestContext) -> WebError { + WebError::bad_request_code( + "mnote_onlyoffice_range_invalid", + "address 必须是 A1 或 A1:B2", + ) + .with_context(context) +} + +fn bridge_run_error(context: &RequestContext, error: BridgeRunError) -> WebError { + match error { + BridgeRunError::BadRequest(message) => { + WebError::bad_request_code("mnote_onlyoffice_bridge_bad_request", message) + } + BridgeRunError::Timeout { + session_id, + command_id, + } => WebError::new( + StatusCode::GATEWAY_TIMEOUT, + "mnote_onlyoffice_bridge_timeout", + format!("ONLYOFFICE bridge 命令超时,sessionId={session_id}, commandId={command_id}"), + ), + } + .with_context(context) +} diff --git a/rust/crates/mnote-web/src/hermes_tools/resource.rs b/rust/crates/mnote-web/src/hermes_tools/resource.rs index fd9cc215..d97a2937 100644 --- a/rust/crates/mnote-web/src/hermes_tools/resource.rs +++ b/rust/crates/mnote-web/src/hermes_tools/resource.rs @@ -23,11 +23,17 @@ pub async fn mindmap_fetch( })?; let data = serde_json::from_str::(&content).unwrap_or_else(|_| json!({ "raw": content })); - let nodes = collect_mindmap_nodes(&data); let scope = input .arg_string("scope") .unwrap_or_else(|| "tree".into()) .to_ascii_lowercase(); + let root = mindmap_root_value(&data).clone(); + let nodes = collect_mindmap_nodes(&root); + let envelope = if scope == "full_envelope" { + data + } else { + Value::Null + }; Ok(json!({ "objectIdentity": target.object_identity, "resourceKind": "mindmap", @@ -35,6 +41,8 @@ pub async fn mindmap_fetch( "mindmapId": target.resource_id, "resourcePath": target.resource_path, "scope": scope, + "root": root, + "envelope": envelope, "nodes": nodes, "edges": [], "markdownSummary": mindmap_markdown_summary(&nodes), @@ -67,14 +75,150 @@ pub async fn mindmap_apply_ops( "diff": [{"op": "mindmap.apply_ops", "ops": ops}] })); } - Err(WebError::bad_request_code( - "mnote_resource_native_patch_required", - format!( - "本地 mindmap resource 写入请使用 agent 原生 patch 编辑授权文件;已校验可写资源路径 {}", - path.display() - ), - ) - .with_context(context)) + ensure_mindmap_revision_precondition(context, input, &path)?; + let content = fs::read_to_string(&path).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_read_failed", + format!("无法读取 mindmap resource: {error}"), + ) + .with_context(context) + })?; + let mut envelope = serde_json::from_str::(&content).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_json_invalid", + format!("mindmap resource 不是有效 JSON: {error}"), + ) + .with_context(context) + })?; + apply_mindmap_ops(context, &mut envelope, &ops)?; + let serialized = serde_json::to_string_pretty(&envelope).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_serialize_failed", + format!("无法序列化 mindmap JSON: {error}"), + ) + .with_context(context) + })?; + fs::write(&path, serialized).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_write_failed", + format!("无法写入 mindmap resource: {error}"), + ) + .with_context(context) + })?; + let root = mindmap_root_value(&envelope).clone(); + let nodes = collect_mindmap_nodes(&root); + Ok(json!({ + "dryRun": false, + "commandName": "mnote.mindmap.apply_ops", + "objectIdentity": target.object_identity, + "resourceKind": "mindmap", + "documentId": target.document_id, + "mindmapId": target.resource_id, + "resourcePath": target.resource_path, + "root": root, + "nodes": nodes, + "edges": [], + "markdownSummary": mindmap_markdown_summary(&nodes), + "revision": file_revision(&path), + "changedFiles": [target.relative_path()], + "source": "local_folder" + })) +} + +pub async fn mindmap_create_from_outline( + context: &RequestContext, + input: &ToolCallInput, +) -> Result { + ensure_resource_write_contract(context, input)?; + let target = ResourceToolTarget::from_input(context, input, "mindmap", "mindmapId")?; + ensure_resource_scope_allowed(context, input, &target)?; + let path = target.resolve_create_path(context, input)?; + let title = input + .arg_string("title") + .unwrap_or_else(|| "KMIND".to_string()); + let outline = input.arg_value("outline").ok_or_else(|| { + WebError::bad_request_code("mnote_mindmap_outline_required", "创建思维导图缺少 outline") + .with_context(context) + })?; + let source_refs = input.arg_value("sourceRefs").unwrap_or_else(|| json!([])); + let envelope = mindmap_envelope_from_outline(&title, &outline, source_refs, context)?; + let root = mindmap_root_value(&envelope).clone(); + let nodes = collect_mindmap_nodes(&root); + let resource_relative_path = target.relative_path(); + let mut changed_files = if input.dry_run.unwrap_or(false) { + Vec::new() + } else { + vec![resource_relative_path.clone()] + }; + let mut embed_result = Value::Null; + + if !input.dry_run.unwrap_or(false) { + let parent = path.parent().ok_or_else(|| { + WebError::bad_request_code("mnote_resource_bad_path", "无法解析 mindmap 父目录") + .with_context(context) + })?; + fs::create_dir_all(parent).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_create_dir_failed", + format!("无法创建 mindmap 目录: {error}"), + ) + .with_context(context) + })?; + let content = serde_json::to_string_pretty(&envelope).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_serialize_failed", + format!("无法序列化 mindmap JSON: {error}"), + ) + .with_context(context) + })?; + fs::write(&path, content).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_write_failed", + format!("无法写入 mindmap resource: {error}"), + ) + .with_context(context) + })?; + if input + .arg_value("embedIntoPage") + .and_then(|value| value.as_bool()) + .unwrap_or(true) + { + embed_result = embed_mindmap_into_local_markdown_page( + context, + input, + &target.document_id, + &resource_relative_path, + &title, + )?; + if let Some(changed_file) = embed_result + .get("changedFile") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + { + changed_files.push(changed_file.to_string()); + } + } + } + + Ok(json!({ + "dryRun": input.dry_run.unwrap_or(false), + "commandName": "mnote.mindmap.create_from_outline", + "objectIdentity": target.object_identity, + "resourceKind": "mindmap", + "documentId": target.document_id, + "mindmapId": target.resource_id, + "resourcePath": target.resource_path, + "envelope": envelope, + "root": root, + "nodes": nodes, + "edges": [], + "markdownSummary": mindmap_markdown_summary(&nodes), + "revision": if input.dry_run.unwrap_or(false) { Value::Null } else { file_revision(&path) }, + "changedFiles": changed_files, + "embedResult": embed_result, + "source": "local_folder" + })) } pub async fn office_fetch_summary( @@ -235,6 +379,45 @@ impl ResourceToolTarget { Ok(canonical) } + fn resolve_create_path( + &self, + context: &RequestContext, + input: &ToolCallInput, + ) -> Result { + let root_uri = local_root_uri_for_resource(input).ok_or_else(|| { + WebError::new( + StatusCode::FORBIDDEN, + "mnote_resource_root_uri_required", + "资源工具需要授权 rootUri", + ) + .with_context(context) + })?; + let root = crate::routes::ensure_local_workspace_access(context, &root_uri) + .map_err(|error| error.with_context(context))?; + let relative = self.relative_path(); + let relative_path = Path::new(&relative); + if relative_path.is_absolute() + || relative_path + .components() + .any(|component| matches!(component, std::path::Component::ParentDir)) + { + return Err(WebError::bad_request_code( + "mnote_resource_root_escape", + "资源工具不能越过授权目录", + ) + .with_context(context)); + } + let path = root.join(relative_path); + if !path.starts_with(&root) { + return Err(WebError::bad_request_code( + "mnote_resource_root_escape", + "资源工具不能越过授权目录", + ) + .with_context(context)); + } + Ok(path) + } + fn relative_path(&self) -> String { self.resource_path .as_deref() @@ -315,9 +498,508 @@ fn local_root_uri_for_resource(input: &ToolCallInput) -> Option { }) } +fn embed_mindmap_into_local_markdown_page( + context: &RequestContext, + input: &ToolCallInput, + document_id: &str, + resource_relative_path: &str, + title: &str, +) -> Result { + let root_uri = local_root_uri_for_resource(input).ok_or_else(|| { + WebError::new( + StatusCode::FORBIDDEN, + "mnote_resource_root_uri_required", + "资源工具需要授权 rootUri", + ) + .with_context(context) + })?; + let root = crate::routes::ensure_local_workspace_access(context, &root_uri) + .map_err(|error| error.with_context(context))?; + let page_relative_path = local_markdown_relative_path_from_document_id(context, document_id)?; + let page_path = root.join(&page_relative_path); + if !page_path.starts_with(&root) { + return Err(WebError::bad_request_code( + "mnote_resource_root_escape", + "资源工具不能越过授权目录", + ) + .with_context(context)); + } + if !page_path.is_file() { + return Err(WebError::bad_request_code( + "mnote_resource_page_not_found", + "找不到要绑定 mindmap 的本地 Markdown 页面", + ) + .with_context(context)); + } + let href = markdown_href_from_page(&root, &page_path, resource_relative_path); + let mut markdown = fs::read_to_string(&page_path).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_page_read_failed", + format!("无法读取本地 Markdown 页面: {error}"), + ) + .with_context(context) + })?; + let link = format!("[{}]({href})", markdown_link_label(title)); + if markdown.contains(&link) || markdown.contains(&format!("]({href})")) { + return Ok(json!({ + "status": "already_present", + "documentId": document_id, + "changedFile": page_relative_path, + "href": href + })); + } + if !markdown.ends_with('\n') { + markdown.push('\n'); + } + if !markdown.ends_with("\n\n") { + markdown.push('\n'); + } + markdown.push_str(&link); + markdown.push('\n'); + fs::write(&page_path, markdown).map_err(|error| { + WebError::bad_request_code( + "mnote_resource_page_write_failed", + format!("无法写入本地 Markdown 页面: {error}"), + ) + .with_context(context) + })?; + Ok(json!({ + "status": "embedded", + "documentId": document_id, + "changedFile": page_relative_path, + "href": href + })) +} + +fn local_markdown_relative_path_from_document_id( + context: &RequestContext, + document_id: &str, +) -> Result { + let encoded = document_id + .trim() + .strip_prefix("local-md:") + .ok_or_else(|| { + WebError::bad_request_code( + "mnote_resource_local_markdown_required", + "绑定 mindmap 需要 local-md 页面", + ) + .with_context(context) + })?; + let relative = crate::routes::decode_local_id_segment(encoded) + .map_err(|error| error.with_context(context))?; + let path = Path::new(&relative); + if path.is_absolute() + || path + .components() + .any(|component| matches!(component, std::path::Component::ParentDir)) + { + return Err(WebError::bad_request_code( + "mnote_resource_root_escape", + "资源工具不能越过授权目录", + ) + .with_context(context)); + } + Ok(relative) +} + +fn markdown_href_from_page(root: &Path, page_path: &Path, resource_relative_path: &str) -> String { + let page_dir = page_path.parent().unwrap_or(root); + let target = root.join(resource_relative_path); + if let Ok(relative) = target.strip_prefix(page_dir) { + return path_to_markdown_href(relative); + } + let page_dir_relative = page_dir.strip_prefix(root).unwrap_or(Path::new("")); + let depth = page_dir_relative + .components() + .filter(|component| matches!(component, std::path::Component::Normal(_))) + .count(); + let mut href = String::new(); + for _ in 0..depth { + href.push_str("../"); + } + href.push_str(&resource_relative_path.replace('\\', "/")); + href +} + +fn path_to_markdown_href(path: &Path) -> String { + path.to_string_lossy().replace('\\', "/") +} + +fn markdown_link_label(value: &str) -> String { + value + .trim() + .replace('\\', "\\\\") + .replace('[', "\\[") + .replace(']', "\\]") + .replace('\n', " ") +} + +fn default_mindmap_view() -> Value { + json!({ + "state": { + "scale": 1, + "sx": 0, + "sy": 0, + "x": -44.99991989135742_f64, + "y": -15.500006675720217_f64 + }, + "transform": { + "a": 1, + "b": 0, + "c": 0, + "d": 1, + "e": -44.99991989135742_f64, + "f": -15.500006675720217_f64, + "originX": 0, + "originY": 0, + "rotate": 0, + "scaleX": 1, + "scaleY": 1, + "shear": 0, + "translateX": -44.99991989135742_f64, + "translateY": -15.500006675720217_f64 + } + }) +} + +fn mindmap_envelope_from_outline( + title: &str, + outline: &Value, + source_refs: Value, + context: &RequestContext, +) -> Result { + let outline_items = outline.as_array().ok_or_else(|| { + WebError::bad_request_code( + "mnote_mindmap_outline_invalid", + "mindmap outline 必须是数组", + ) + .with_context(context) + })?; + let title = title.trim(); + let root_title = if title.is_empty() { "KMIND" } else { title }; + Ok(json!({ + "data": { + "children": mindmap_outline_items_to_children(outline_items, "node"), + "data": { + "expand": true, + "isActive": false, + "text": root_title, + "uid": "root" + } + }, + "view": default_mindmap_view(), + "metadata": { + "sourceRefs": source_refs + } + })) +} + +fn mindmap_outline_items_to_children(items: &[Value], prefix: &str) -> Vec { + items + .iter() + .enumerate() + .map(|(index, item)| { + let ordinal = index + 1; + let uid = format!("{prefix}_{ordinal}"); + let text = item + .get("text") + .or_else(|| item.get("title")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("未命名节点"); + let children = item + .get("children") + .and_then(Value::as_array) + .map(|children| mindmap_outline_items_to_children(children, &uid)) + .unwrap_or_default(); + json!({ + "data": { + "expand": true, + "isActive": false, + "text": text, + "uid": uid + }, + "children": children + }) + }) + .collect() +} + +fn mindmap_root_value(value: &Value) -> &Value { + value + .get("data") + .filter(|data| data.get("data").is_some() || data.get("children").is_some()) + .unwrap_or(value) +} + +fn mindmap_root_value_mut(value: &mut Value) -> Option<&mut Value> { + let has_envelope_root = value + .get("data") + .map(|data| data.get("data").is_some() || data.get("children").is_some()) + .unwrap_or(false); + if has_envelope_root { + return value.get_mut("data"); + } + Some(value) +} + +fn apply_mindmap_ops( + context: &RequestContext, + envelope: &mut Value, + ops: &Value, +) -> Result<(), WebError> { + let ops = ops.as_array().ok_or_else(|| { + WebError::bad_request_code("mnote_resource_ops_invalid", "mindmap ops 必须是数组") + .with_context(context) + })?; + let root = mindmap_root_value_mut(envelope).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_json_invalid", "mindmap 缺少 root") + .with_context(context) + })?; + for op in ops { + apply_mindmap_op(context, root, op)?; + } + Ok(()) +} + +fn apply_mindmap_op( + context: &RequestContext, + root: &mut Value, + op: &Value, +) -> Result<(), WebError> { + let op_name = op + .get("op") + .or_else(|| op.get("type")) + .or_else(|| op.get("action")) + .and_then(Value::as_str) + .map(normalize_mindmap_op_name) + .ok_or_else(|| { + WebError::bad_request_code("mnote_resource_op_required", "mindmap op 缺少 op") + .with_context(context) + })?; + match op_name.as_str() { + "updatetext" | "updatenode" => { + let node_id = mindmap_op_string(op, &["nodeId", "node_id", "id"]).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_required", "更新节点缺少 nodeId") + .with_context(context) + })?; + let text = mindmap_op_string(op, &["text", "title"]).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_text_required", "更新节点缺少 text") + .with_context(context) + })?; + let node = find_mindmap_node_mut(root, &node_id).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_not_found", "找不到要更新的节点") + .with_context(context) + })?; + set_mindmap_node_text(node, &text); + } + "insertchild" | "addchild" => { + let parent_id = mindmap_op_string(op, &["parentId", "parent_id", "nodeId"]) + .ok_or_else(|| { + WebError::bad_request_code( + "mnote_resource_parent_required", + "插入子节点缺少 parentId", + ) + .with_context(context) + })?; + let parent = find_mindmap_node_mut(root, &parent_id).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_not_found", "找不到父节点") + .with_context(context) + })?; + let child_input = op.get("node").unwrap_or(op); + let child = mindmap_node_from_input(context, child_input)?; + ensure_mindmap_children_array(context, parent)?.push(child); + } + "deletenode" => { + let node_id = mindmap_op_string(op, &["nodeId", "node_id", "id"]).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_required", "删除节点缺少 nodeId") + .with_context(context) + })?; + if mindmap_node_matches(root, &node_id) { + return Err(WebError::bad_request_code( + "mnote_resource_root_delete_forbidden", + "不能删除 mindmap 根节点", + ) + .with_context(context)); + } + remove_mindmap_node(root, &node_id).ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_not_found", "找不到要删除的节点") + .with_context(context) + })?; + } + _ => { + return Err(WebError::bad_request_code( + "mnote_resource_op_unsupported", + format!("暂不支持 mindmap op: {op_name}"), + ) + .with_context(context)); + } + } + Ok(()) +} + +fn normalize_mindmap_op_name(value: &str) -> String { + value + .chars() + .filter(|ch| *ch != '_' && *ch != '-' && !ch.is_whitespace()) + .flat_map(char::to_lowercase) + .collect() +} + +fn mindmap_op_string(op: &Value, keys: &[&str]) -> Option { + keys.iter().find_map(|key| { + op.get(*key) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + }) +} + +fn find_mindmap_node_mut<'a>(node: &'a mut Value, node_id: &str) -> Option<&'a mut Value> { + if mindmap_node_matches(node, node_id) { + return Some(node); + } + let children = node.get_mut("children").and_then(Value::as_array_mut)?; + for child in children { + if let Some(found) = find_mindmap_node_mut(child, node_id) { + return Some(found); + } + } + None +} + +fn mindmap_node_matches(node: &Value, node_id: &str) -> bool { + mindmap_node_id(node) + .as_deref() + .map(|value| value == node_id) + .unwrap_or(false) +} + +fn mindmap_node_id(node: &Value) -> Option { + node.pointer("/data/uid") + .or_else(|| node.pointer("/data/id")) + .or_else(|| node.get("uid")) + .or_else(|| node.get("id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) +} + +fn set_mindmap_node_text(node: &mut Value, text: &str) { + if let Some(data) = node.get_mut("data").and_then(Value::as_object_mut) { + data.insert("text".into(), json!(text)); + return; + } + if let Some(object) = node.as_object_mut() { + object.insert("text".into(), json!(text)); + } +} + +fn ensure_mindmap_children_array<'a>( + context: &RequestContext, + node: &'a mut Value, +) -> Result<&'a mut Vec, WebError> { + let object = node.as_object_mut().ok_or_else(|| { + WebError::bad_request_code("mnote_resource_node_invalid", "mindmap 节点必须是对象") + .with_context(context) + })?; + let children = object + .entry("children") + .or_insert_with(|| Value::Array(Vec::new())); + if !children.is_array() { + *children = Value::Array(Vec::new()); + } + Ok(children.as_array_mut().expect("children 已归一为数组")) +} + +fn mindmap_node_from_input(context: &RequestContext, input: &Value) -> Result { + if input.get("data").is_some() || input.get("children").is_some() { + let mut node = input.clone(); + ensure_mindmap_children_array(context, &mut node)?; + return Ok(node); + } + let text = input + .get("text") + .or_else(|| input.get("title")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("未命名节点"); + let uid = input + .get("uid") + .or_else(|| input.get("id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or(text); + let mut node = json!({ + "data": { + "expand": true, + "isActive": false, + "text": text, + "uid": uid + }, + "children": [] + }); + if let Some(object) = node.as_object_mut() { + for key in ["metadata", "sourceRefs", "refs", "note", "hyperlink"] { + if let Some(value) = input.get(key) { + object.insert(key.into(), value.clone()); + } + } + } + Ok(node) +} + +fn remove_mindmap_node(parent: &mut Value, node_id: &str) -> Option { + let children = parent.get_mut("children").and_then(Value::as_array_mut)?; + if let Some(index) = children + .iter() + .position(|child| mindmap_node_matches(child, node_id)) + { + return Some(children.remove(index)); + } + for child in children { + if let Some(removed) = remove_mindmap_node(child, node_id) { + return Some(removed); + } + } + None +} + +fn ensure_mindmap_revision_precondition( + context: &RequestContext, + input: &ToolCallInput, + path: &Path, +) -> Result<(), WebError> { + let Some(expected) = input.arg_value("expectedRevision") else { + return Ok(()); + }; + let current = file_revision(path); + if revision_label(&expected).as_deref() != revision_label(¤t).as_deref() { + return Err(WebError::bad_request_code( + "mnote_resource_revision_conflict", + "mindmap resource revision 已变化,请重新读取后再写入", + ) + .with_context(context)); + } + Ok(()) +} + +fn revision_label(value: &Value) -> Option { + match value { + Value::String(value) => Some(value.trim().to_string()).filter(|value| !value.is_empty()), + Value::Number(value) => Some(value.to_string()), + _ => None, + } +} + fn collect_mindmap_nodes(value: &Value) -> Vec { let mut nodes = Vec::new(); - collect_mindmap_nodes_inner(value, &mut nodes); + collect_mindmap_nodes_inner(mindmap_root_value(value), &mut nodes); nodes } diff --git a/rust/crates/mnote-web/src/hermes_tools/skill.rs b/rust/crates/mnote-web/src/hermes_tools/skill.rs index 3eb90585..2aaa8d9a 100644 --- a/rust/crates/mnote-web/src/hermes_tools/skill.rs +++ b/rust/crates/mnote-web/src/hermes_tools/skill.rs @@ -41,6 +41,68 @@ const SKILLS: &[MnoteSkill] = &[ tool_names: &["mnote.context.snapshot", "mnote.context.resolve_target"], content: include_str!("../../../../../skills/mnote-local-file/SKILL.md"), }, + MnoteSkill { + id: "mnote-onlyoffice-live", + title: "MNote ONLYOFFICE live bridge", + description: "Operate the currently open ONLYOFFICE editor session for Word, Excel, and PPT.", + agent_ids: &["hermes", "reasonix"], + read_only: false, + requires_context_refs: &["onlyoffice"], + tool_names: &[ + "mnote.onlyoffice.session.current", + "mnote.onlyoffice.capabilities", + "mnote.onlyoffice.selection.get", + "mnote.onlyoffice.document.insert_text", + "mnote.onlyoffice.document.replace_selection", + "mnote.onlyoffice.document.insert_html", + "mnote.onlyoffice.document.export", + "mnote.onlyoffice.document.search_replace", + "mnote.onlyoffice.document.insert_table", + "mnote.onlyoffice.document.get_comments", + "mnote.onlyoffice.document.add_comment", + "mnote.onlyoffice.sheet.get_sheets", + "mnote.onlyoffice.sheet.add_sheet", + "mnote.onlyoffice.sheet.rename_sheet", + "mnote.onlyoffice.sheet.get_range", + "mnote.onlyoffice.sheet.get_range_values", + "mnote.onlyoffice.sheet.get_values", + "mnote.onlyoffice.sheet.set_value", + "mnote.onlyoffice.sheet.set_formula", + "mnote.onlyoffice.sheet.batch_set_values", + "mnote.onlyoffice.sheet.set_range_values", + "mnote.onlyoffice.sheet.format_range", + "mnote.onlyoffice.sheet.set_dimensions", + "mnote.onlyoffice.sheet.sort_range", + "mnote.onlyoffice.sheet.add_chart", + "mnote.onlyoffice.presentation.get_slides", + "mnote.onlyoffice.presentation.get_slide_texts", + "mnote.onlyoffice.presentation.get_shapes", + "mnote.onlyoffice.presentation.add_text_slide", + "mnote.onlyoffice.presentation.replace_text", + "mnote.onlyoffice.presentation.set_shape_text", + "mnote.onlyoffice.presentation.delete_slide", + "mnote.onlyoffice.presentation.add_table", + "mnote.onlyoffice.presentation.clear_slide", + "mnote.onlyoffice.presentation.add_shape", + ], + content: include_str!("../../../../../skills/mnote-onlyoffice-live/SKILL.md"), + }, + MnoteSkill { + id: "mnote-mindmap", + title: "MNote mindmap editing", + description: "Read, update, summarize, or create MNote mindmap resources, including generating a new mindmap from PDF or document outlines.", + agent_ids: &["hermes", "reasonix"], + read_only: false, + requires_context_refs: &["current_page", "file", "folder", "resource"], + tool_names: &[ + "mnote.context.snapshot", + "mnote.context.resolve_target", + "mnote.mindmap.fetch", + "mnote.mindmap.apply_ops", + "mnote.mindmap.create_from_outline", + ], + content: include_str!("../../../../../skills/mnote-mindmap/SKILL.md"), + }, MnoteSkill { id: "mnote-chat-only", title: "MNote chat only", @@ -146,4 +208,108 @@ mod tests { assert!(find_skill("mnote-local-file", Some("chat_only")).is_none()); assert!(find_skill("missing", Some("reasonix")).is_none()); } + + #[test] + fn skill_registry_exposes_onlyoffice_live_skill_to_agents() { + let reasonix_skills = skill_summaries_for_agent(Some("reasonix")); + let skill = reasonix_skills + .iter() + .find(|skill| skill["id"] == "mnote-onlyoffice-live") + .expect("reasonix should see live ONLYOFFICE skill"); + assert_eq!(skill["readOnly"], false); + assert_eq!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.onlyoffice.session.current"), + true + ); + assert_eq!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.onlyoffice.sheet.batch_set_values"), + true + ); + assert_eq!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.onlyoffice.sheet.add_chart"), + true + ); + assert_eq!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.onlyoffice.presentation.add_shape"), + true + ); + assert_eq!( + skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.onlyoffice.presentation.replace_text"), + true + ); + } + + #[test] + fn skill_registry_exposes_mindmap_skill_to_agents() { + let reasonix_skills = skill_summaries_for_agent(Some("reasonix")); + let skill = reasonix_skills + .iter() + .find(|skill| skill["id"] == "mnote-mindmap") + .expect("reasonix should see mindmap skill"); + assert_eq!(skill["readOnly"], false); + assert!(skill["requiresContextRefs"] + .as_array() + .expect("context refs") + .iter() + .any(|value| value == "resource")); + assert!(skill["toolNames"] + .as_array() + .expect("tool names") + .iter() + .any(|name| name == "mnote.mindmap.create_from_outline")); + } + + #[tokio::test] + async fn skill_read_returns_mindmap_skill_content() { + let context = RequestContext::from_http_parts( + &axum::http::Method::POST, + &"/api/hermes/tools/execute".parse().expect("uri"), + &axum::http::HeaderMap::new(), + ); + let input: ToolCallInput = serde_json::from_value(json!({ + "toolName": "mnote.skill.read", + "args": { + "skillId": "mnote-mindmap", + "agentId": "reasonix" + } + })) + .expect("input"); + + let payload = skill_read(&context, &input).await.expect("skill read"); + + assert_eq!(payload["skill"]["id"], "mnote-mindmap"); + assert!(payload["content"] + .as_str() + .unwrap_or_default() + .contains("mnote.mindmap.create_from_outline")); + let content = payload["content"].as_str().unwrap_or_default(); + assert!(content.contains("Mindmap outline format")); + assert!(content.contains("Use concise keywords or short phrases")); + assert!(content.contains("Avoid long paragraphs")); + assert!(payload["tools"] + .as_array() + .expect("tools") + .iter() + .any(|tool| tool == "mnote.mindmap.create_from_outline")); + } } diff --git a/rust/crates/mnote-web/src/page_aggregate/builder.rs b/rust/crates/mnote-web/src/page_aggregate/builder.rs index 836a4424..8b7d8640 100644 --- a/rust/crates/mnote-web/src/page_aggregate/builder.rs +++ b/rust/crates/mnote-web/src/page_aggregate/builder.rs @@ -65,7 +65,7 @@ impl PageAggregateBuilder { Self { document_id: String::new(), workspace_id: "default".to_string(), - source: PageAggregateSource::CompatMetaContentJoin, + source: PageAggregateSource::KernelProjection, parent_id: None, path: Vec::new(), sidebar_tree_membership: vec!["page-tree".into(), "file-tree".into()], @@ -372,3 +372,29 @@ impl Default for PageAggregateBuilder { Self::new() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn new_defaults_to_kernel_projection() { + let aggregate = PageAggregateBuilder::new() + .document_id("doc_1") + .workspace_id("ws_demo") + .build(); + + assert_eq!(aggregate.source, PageAggregateSource::KernelProjection); + } + + #[test] + fn explicit_compat_source_is_still_supported() { + let aggregate = PageAggregateBuilder::new() + .document_id("doc_1") + .workspace_id("ws_demo") + .source(PageAggregateSource::CompatMetaContentJoin) + .build(); + + assert_eq!(aggregate.source, PageAggregateSource::CompatMetaContentJoin); + } +} diff --git a/rust/crates/mnote-web/src/routes/hermes_client.rs b/rust/crates/mnote-web/src/routes/hermes_client.rs index 0f931b14..d404b76c 100644 --- a/rust/crates/mnote-web/src/routes/hermes_client.rs +++ b/rust/crates/mnote-web/src/routes/hermes_client.rs @@ -9,7 +9,10 @@ use axum::extract::{Extension, Path, Query, State}; use axum::http::{header, HeaderMap, HeaderName, HeaderValue, StatusCode}; use axum::response::Response; use axum::Json; -use control_plane::{AppendAiRuntimeEventInput, UpsertAiRuntimeRunInput}; +use control_plane::{ + AiAgentProfileAccessRecord, AiExternalConversationBindingRecord, AppendAiRuntimeEventInput, + UpsertAiExternalConversationBindingInput, UpsertAiRuntimeRunInput, UpsertUserInput, +}; use futures_util::TryStreamExt; use serde::Deserialize; use serde_json::{json, Value}; @@ -32,6 +35,26 @@ const ACP_RUNTIME_SQLITE_STORE: &str = "sqlite_acp_runtime_store"; const ACP_ABORT_NOTIFICATION_TIMEOUT_MS: u64 = 2_500; const LOCAL_SHARE_GRANTS_JSON: &str = "/mnt/Data1T/Mnote_data/control-plane/share-grants.json"; const ENV_LOCAL_SHARE_GRANTS_FILE: &str = "MNOTE_SHARE_GRANTS_FILE"; +const MNOTE_PERSONAL_SKILL_BASELINE_MARKER: &str = "mnotePersonalSkillBaseline: v1"; +const MNOTE_PERSONAL_SKILL_ALLOWLIST: &[&str] = &["global-search", "vpn", "zhihu-search"]; +const ENV_DOUBAO_CONVERSATION_DELETE_URL: &str = "MNOTE_WEB_DOUBAO_CONVERSATION_DELETE_URL"; +const ENV_DOUBAO_CONVERSATION_LOOKUP_URL: &str = "MNOTE_WEB_DOUBAO_CONVERSATION_LOOKUP_URL"; +const ENV_DEEPSEEK_CONVERSATION_DELETE_URL: &str = "MNOTE_WEB_DEEPSEEK_CONVERSATION_DELETE_URL"; +const ENV_DEEPSEEK_CONVERSATION_LOOKUP_URL: &str = "MNOTE_WEB_DEEPSEEK_CONVERSATION_LOOKUP_URL"; +const ENV_GEMINI_CONVERSATION_DELETE_URL: &str = "MNOTE_WEB_GEMINI_CONVERSATION_DELETE_URL"; +const ENV_GEMINI_CONVERSATION_LOOKUP_URL: &str = "MNOTE_WEB_GEMINI_CONVERSATION_LOOKUP_URL"; +const DEFAULT_DOUBAO_CONVERSATION_DELETE_URL: &str = + "http://127.0.0.1:30343/mnote/provider-conversations/doubao-web/{conversationId}"; +const DEFAULT_DOUBAO_CONVERSATION_LOOKUP_URL: &str = + "http://127.0.0.1:30343/mnote/provider-conversations/doubao-web/mnote-session/{sessionId}"; +const DEFAULT_DEEPSEEK_CONVERSATION_DELETE_URL: &str = + "http://127.0.0.1:30341/mnote/provider-conversations/deepseek-web/{conversationId}"; +const DEFAULT_DEEPSEEK_CONVERSATION_LOOKUP_URL: &str = + "http://127.0.0.1:30341/mnote/provider-conversations/deepseek-web/mnote-session/{sessionId}"; +const DEFAULT_GEMINI_CONVERSATION_DELETE_URL: &str = + "http://127.0.0.1:30342/mnote/provider-conversations/gemini-web/{conversationId}"; +const DEFAULT_GEMINI_CONVERSATION_LOOKUP_URL: &str = + "http://127.0.0.1:30342/mnote/provider-conversations/gemini-web/mnote-session/{sessionId}"; static HERMES_RUNTIME_REGISTRY: LazyLock>> = LazyLock::new(|| Mutex::new(HashMap::new())); @@ -42,6 +65,8 @@ static ACP_RUN_PAYLOADS: LazyLock>> = LazyLock::new(|| Mutex::new(HashMap::new())); static ACP_ACTIVE_RUNS: LazyLock>> = LazyLock::new(|| Mutex::new(HashMap::new())); +static ACP_FINISHED_RUNS: LazyLock>> = + LazyLock::new(|| Mutex::new(HashSet::new())); static ACP_LOCAL_AUDIT_SNAPSHOTS: LazyLock>> = LazyLock::new(|| Mutex::new(HashMap::new())); @@ -367,11 +392,48 @@ async fn list_acp_sessions( state, context, root_uri, ) .map_err(|error| error.with_context(context))?; + let user_id = effective_session_store_user_id(state, context).await?; let limit = query .get("limit") .and_then(|value| value.parse::().ok()) .unwrap_or(50) .clamp(1, 100); + let workspace_id = query + .get("workspaceId") + .map(String::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let document_id = query + .get("documentId") + .map(String::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let session_id = query + .get("sessionId") + .map(String::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let sqlite_runs = state + .control_plane() + .list_ai_runtime_runs(&user_id, workspace_id, document_id, session_id, limit) + .map_err(|error| { + WebError::internal(format!("SQLite ACP session 列表读取失败: {error}")) + .with_context(context) + })?; + if !sqlite_runs.is_empty() { + return Ok(( + StatusCode::OK, + stamp_client_headers(), + Json(json!({ + "ok": true, + "traceId": context.trace.trace_id, + "persistence": ACP_RUNTIME_SQLITE_STORE, + "sessionStorage": "sqlite_control_plane", + "legacyPersistence": "local_ai_session_jsonl", + "sessions": sqlite_runs.iter().map(ai_runtime_run_to_json).collect::>() + })), + )); + } let sessions = list_local_ai_sessions(root_uri, limit)?; return Ok(( StatusCode::OK, @@ -601,6 +663,52 @@ pub async fn create_session( append_local_ai_session_event(root_uri, &session_id, &audit_event, share_id) .map_err(|error| error.with_context(&context))?; } + let session_index_run_id = format!("{}_session", session_id); + let runtime_state = json!({ + "sessionId": session_id, + "runId": session_index_run_id, + "profile": profile, + "documentId": document_id, + "traceId": trace_id, + "status": "session.created" + }); + let runtime_payload = json!({ + "workspaceId": payload.workspace_id.clone(), + "documentId": payload.document_id.clone(), + "sessionId": session_id, + "sourceKind": "local_folder", + "rootUri": root_uri, + "profile": profile, + "title": payload.title.clone(), + "actorId": session_store_user_id.clone(), + "actorType": "user", + "traceId": trace_id, + "permissionLevel": permission_level, + "shareId": share_id, + }); + let session_acp_runtime = + acp_runtime_for_payload(&runtime_payload, profile).unwrap_or_else(|| "hermes".into()); + state + .control_plane() + .upsert_ai_runtime_run(UpsertAiRuntimeRunInput { + id: None, + user_id: session_store_user_id.clone(), + workspace_id: payload.workspace_id.clone(), + document_id: payload.document_id.clone(), + session_id: session_id.clone(), + run_id: session_index_run_id, + title: payload.title.clone(), + profile: profile.to_string(), + acp_runtime: session_acp_runtime, + trace_id: Some(trace_id.clone()), + status: "session.created".to_string(), + runtime_json: json_string(&runtime_state), + payload_json: json_string(&runtime_payload), + }) + .map_err(|error| { + WebError::internal(format!("SQLite ACP local session 写入失败: {error}")) + .with_context(&context) + })?; return Ok(( StatusCode::OK, stamp_client_headers(), @@ -612,8 +720,10 @@ pub async fn create_session( "profile": profile, "title": payload.title.unwrap_or_else(|| "当前页问答".into()), "traceId": trace_id, - "persistence": "local_ai_session_jsonl", - "sessionStorage": session_storage, + "persistence": ACP_RUNTIME_SQLITE_STORE, + "sessionStorage": "sqlite_control_plane", + "legacyPersistence": "local_ai_session_jsonl", + "legacySessionStorage": session_storage, "permissionLevel": permission_level, "shareId": share_id })), @@ -827,14 +937,16 @@ pub async fn switch_active_profile( } pub async fn get_profile_memory( + State(state): State, Extension(context): Extension, Query(query): Query>, ) -> Result<(StatusCode, HeaderMap, Json), WebError> { ensure_authenticated(&context)?; let fallback_profile = active_profile_name().unwrap_or_else(|| "default".into()); - let profile = query - .get("profile") - .map(String::as_str) + let profile_access = resolve_hermes_profile_from_query(&state, &context, &query)?; + let profile = profile_access + .as_ref() + .map(|access| access.profile.isolated_profile_name.as_str()) .unwrap_or(fallback_profile.as_str()); Ok(( StatusCode::OK, @@ -844,15 +956,35 @@ pub async fn get_profile_memory( } pub async fn save_profile_memory( + State(state): State, Extension(context): Extension, Json(payload): Json, ) -> Result<(StatusCode, HeaderMap, Json), WebError> { ensure_authenticated(&context)?; let fallback_profile = active_profile_name().unwrap_or_else(|| "default".into()); - let profile = payload - .get("profile") - .and_then(Value::as_str) + let profile_access = resolve_hermes_profile_from_payload(&state, &context, &payload)?; + let profile = profile_access + .as_ref() + .map(|access| access.profile.isolated_profile_name.as_str()) .unwrap_or(fallback_profile.as_str()); + if let Some(access) = &profile_access { + if !access.grant.can_manage_config { + return Err(ai_profile_forbidden( + &context, + "ai_profile_readonly", + "当前用户不能修改该 Hermes profile 的记忆配置", + )); + } + ensure_managed_profile_home(&access.profile.isolated_profile_name).map_err(|error| { + WebError::bad_gateway_code( + "hermes_profile_provision_failed", + format!("初始化 Hermes profile 目录失败: {error}"), + ) + .with_context(&context) + .with_header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .with_header(HEADER_HERMES_CLIENT_OWNER, "mnote-web-hermes-client") + })?; + } let section = payload .get("section") .and_then(Value::as_str) @@ -887,29 +1019,108 @@ pub async fn save_profile_memory( )) } +pub async fn list_agent_profiles( + State(state): State, + Extension(context): Extension, + Query(query): Query>, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + ensure_authenticated(&context)?; + let agent_id = query + .get("agentId") + .or_else(|| query.get("agent_id")) + .map(String::as_str) + .unwrap_or("hermes") + .trim(); + if agent_id != "hermes" { + return Ok(( + StatusCode::OK, + stamp_client_headers(), + Json(json!({"agentId": agent_id, "profiles": []})), + )); + } + let actor_id = page_ai_actor_id(&state, &context)?; + let is_admin = page_ai_actor_is_admin(&context); + ensure_page_ai_actor_user(&state, &actor_id, is_admin)?; + let profiles = state + .control_plane() + .ensure_ai_agent_profile_policy(&actor_id, is_admin) + .map_err(|error| { + WebError::internal(format!("SQLite AI profile policy 读取失败: {error}")) + })?; + Ok(( + StatusCode::OK, + stamp_client_headers(), + Json(json!({ + "agentId": "hermes", + "profiles": profiles.into_iter().map(agent_profile_access_json).collect::>() + })), + )) +} + pub async fn list_skills( + State(state): State, Extension(context): Extension, Query(query): Query>, ) -> Result<(StatusCode, HeaderMap, Json), WebError> { ensure_authenticated(&context)?; let fallback_profile = active_profile_name().unwrap_or_else(|| "default".into()); - let profile = query - .get("profile") - .map(String::as_str) + let requested_profile = query + .get("profileId") + .or_else(|| query.get("profile_id")) + .or_else(|| query.get("profile")) + .map(String::as_str); + let profile_access = resolve_hermes_profile_from_query(&state, &context, &query)?; + let profile = profile_access + .as_ref() + .map(|access| access.profile.isolated_profile_name.as_str()) .unwrap_or(fallback_profile.as_str()); let runtime = query.get("runtime").map(String::as_str).unwrap_or(profile); + if runtime != "mnote" + && runtime != "reasonix" + && requested_profile.is_some() + && profile_access.is_none() + { + return Err(ai_profile_forbidden( + &context, + "ai_profile_forbidden", + "当前用户无权访问该 Hermes profile", + )); + } Ok(( StatusCode::OK, stamp_client_headers(), Json(match runtime { - "mnote" => mnote_builtin_skills_payload(query.get("agentId").map(String::as_str)), + "mnote" => { + let mut payload = + mnote_builtin_skills_payload(query.get("agentId").map(String::as_str)); + stamp_mnote_builtin_skill_payload_policy(&state, &context, &mut payload)?; + payload + } "reasonix" => reasonix_skills_payload(), - _ => skills_payload(profile), + _ => { + if let Some(access) = profile_access.as_ref() { + ensure_personal_profile_skill_baseline(access).map_err(|error| { + WebError::bad_gateway_code( + "hermes_profile_skill_baseline_failed", + format!("初始化个人 Hermes profile 默认技能失败: {error}"), + ) + .with_context(&context) + .with_header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .with_header(HEADER_HERMES_CLIENT_OWNER, "mnote-web-hermes-client") + })?; + } + let mut payload = skills_payload(profile); + if let Some(access) = profile_access { + stamp_hermes_skill_payload_profile_policy(&mut payload, &access); + } + payload + } }), )) } pub async fn toggle_skill( + State(state): State, Extension(context): Extension, Json(payload): Json, ) -> Result<(StatusCode, HeaderMap, Json), WebError> { @@ -934,12 +1145,63 @@ pub async fn toggle_skill( .with_header(HEADER_MNOTE_WEB_OWNER, "mnote-web") .with_header(HEADER_HERMES_CLIENT_OWNER, "mnote-web-hermes-client") })?; - let fallback_profile = active_profile_name().unwrap_or_else(|| "default".into()); - let profile = payload - .get("profile") + let skill_kind = payload + .get("skillKind") + .or_else(|| payload.get("kind")) .and_then(Value::as_str) - .unwrap_or(fallback_profile.as_str()); - set_skill_enabled(profile, name, enabled).map_err(|error| { + .map(str::trim) + .unwrap_or("hermes_profile"); + if skill_kind == "mnote_builtin" { + let actor_id = page_ai_actor_id(&state, &context)?; + ensure_page_ai_actor_user(&state, &actor_id, page_ai_actor_is_admin(&context))?; + let key = format!("ai.agent.mnote_builtin.skill.{name}.enabled"); + state + .control_plane() + .upsert_user_ui_preference(control_plane::UpsertUserUiPreferenceInput { + id: None, + user_id: actor_id, + workspace_id: None, + source_kind: None, + scope_kind: "page_ai_skill".to_string(), + scope_id: "mnote_builtin".to_string(), + key, + value_json: Value::Bool(enabled).to_string(), + }) + .map_err(|error| { + WebError::internal(format!("SQLite MNote 内置 skill 偏好写入失败: {error}")) + .with_context(&context) + })?; + return Ok(( + StatusCode::OK, + stamp_client_headers(), + Json(json!({"ok": true, "skillKind": "mnote_builtin", "configScope": "user_sqlite"})), + )); + } + let access = + resolve_hermes_profile_from_payload(&state, &context, &payload)?.ok_or_else(|| { + ai_profile_forbidden( + &context, + "ai_profile_not_found", + "未找到可访问的 Hermes profile", + ) + })?; + if !access.grant.can_manage_skills { + return Err(ai_profile_forbidden( + &context, + "ai_profile_readonly", + "当前用户不能修改该 Hermes profile 的 skills", + )); + } + ensure_personal_profile_skill_baseline(&access).map_err(|error| { + WebError::bad_gateway_code( + "hermes_profile_provision_failed", + format!("初始化 Hermes profile 目录失败: {error}"), + ) + .with_context(&context) + .with_header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .with_header(HEADER_HERMES_CLIENT_OWNER, "mnote-web-hermes-client") + })?; + set_skill_enabled(&access.profile.isolated_profile_name, name, enabled).map_err(|error| { WebError::bad_gateway_code( "hermes_client_skill_toggle_failed", format!("更新 Hermes skill 设置失败: {error}"), @@ -951,7 +1213,7 @@ pub async fn toggle_skill( Ok(( StatusCode::OK, stamp_client_headers(), - Json(json!({"ok": true})), + Json(json!({"ok": true, "skillKind": "hermes_profile", "profileId": access.profile.id})), )) } @@ -1089,6 +1351,44 @@ pub async fn delete_session( WebError::internal(format!("SQLite ACP session 删除失败: {error}")) .with_context(&context) })?; + let provider_binding = find_provider_conversation_binding_for_session( + state.control_plane(), + &user_id, + workspace_id.as_deref(), + &session_id, + ) + .map_err(|error| { + WebError::internal(format!( + "SQLite provider conversation 绑定读取失败: {error}" + )) + .with_context(&context) + })?; + let provider_binding_local_deleted = mark_provider_conversation_local_deleted_for_session( + state.control_plane(), + &user_id, + workspace_id.as_deref(), + &session_id, + ) + .map_err(|error| { + WebError::internal(format!( + "SQLite provider conversation 删除标记失败: {error}" + )) + .with_context(&context) + })?; + let provider_conversation_delete = delete_provider_conversation_for_session( + state.control_plane(), + &user_id, + workspace_id.as_deref(), + &session_id, + provider_binding.as_ref(), + ) + .await + .map_err(|error| { + WebError::internal(format!( + "SQLite provider conversation 远端删除状态写入失败: {error}" + )) + .with_context(&context) + })?; return Ok(( StatusCode::OK, stamp_client_headers(), @@ -1098,7 +1398,9 @@ pub async fn delete_session( "result": { "ok": true, "sessionId": session_id, - "deleted": deleted + "deleted": deleted, + "providerBindingLocalDeleted": provider_binding_local_deleted, + "providerConversationDelete": provider_conversation_delete } })), )); @@ -1320,6 +1622,61 @@ async fn get_acp_session( state, context, root_uri, ) .map_err(|error| error.with_context(context))?; + let user_id = effective_session_store_user_id(state, context).await?; + let workspace_id = query + .get("workspaceId") + .map(String::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + .or_else(|| context.workspace.workspace_id.clone()); + let runs = state + .control_plane() + .list_ai_runtime_runs( + &user_id, + workspace_id.as_deref(), + None, + Some(session_id), + 20, + ) + .map_err(|error| { + WebError::internal(format!("SQLite ACP session 详情读取失败: {error}")) + .with_context(context) + })?; + if let Some(latest_run) = runs.first() { + let mut events = Vec::new(); + for run in runs.iter().rev() { + let run_events = state + .control_plane() + .list_ai_runtime_events(&user_id, &run.run_id, 200) + .map_err(|error| { + WebError::internal(format!("SQLite ACP runtime events 读取失败: {error}")) + .with_context(context) + })?; + events.extend(run_events); + } + let runtime = serde_json::from_str::(&latest_run.runtime_json) + .unwrap_or_else(|_| runtime_state_for_session(session_id)); + return Ok(( + StatusCode::OK, + stamp_client_headers(), + Json(json!({ + "ok": true, + "traceId": context.trace.trace_id, + "persistence": ACP_RUNTIME_SQLITE_STORE, + "sessionStorage": "sqlite_control_plane", + "legacyPersistence": "local_ai_session_jsonl", + "sessionId": session_id, + "session": { + "sessionId": session_id, + "messages": [], + "runs": runs.iter().map(ai_runtime_run_to_json).collect::>() + }, + "runtime": runtime, + "events": events.iter().map(ai_runtime_event_to_json).collect::>() + })), + )); + } let events = read_local_ai_session_events(root_uri, session_id, None)?; return Ok(( StatusCode::OK, @@ -1363,17 +1720,17 @@ async fn get_acp_session( .with_context(context) })?; let latest_run = runs.first().cloned(); - let events = if let Some(run) = latest_run.as_ref() { - state + let mut events = Vec::new(); + for run in runs.iter().rev() { + let run_events = state .control_plane() .list_ai_runtime_events(&user_id, &run.run_id, 200) .map_err(|error| { WebError::internal(format!("SQLite ACP runtime events 读取失败: {error}")) .with_context(context) - })? - } else { - Vec::new() - }; + })?; + events.extend(run_events); + } let runtime = latest_run .as_ref() .and_then(|run| serde_json::from_str::(&run.runtime_json).ok()) @@ -1495,7 +1852,25 @@ pub async fn create_run( let (actor_id, actor_type) = resolve_run_actor(&state, &context).await; stamp_run_actor(&mut payload, &actor_id, &actor_type); enforce_local_ai_run_access(&state, &context, &actor_id, &mut payload)?; + apply_mnote_builtin_skill_policy_to_payload(&state, &actor_id, &mut payload)?; + if payload_requests_hermes_profile(&payload) { + let access = + resolve_hermes_profile_from_payload(&state, &context, &payload)?.ok_or_else(|| { + ai_profile_forbidden( + &context, + "ai_profile_forbidden", + "当前用户无权访问该 Hermes profile", + ) + })?; + stamp_agent_profile_ref(&mut payload, &access); + } let registration = run_registration_from_payload(&context, &payload); + inject_provider_conversation_binding_for_run( + state.control_plane(), + &context, + ®istration, + &mut payload, + )?; // ACP path: skip the HTTP proxy, just register and return run info if let Some(acp_runtime) = acp_runtime_for_payload(&payload, ®istration.profile) { @@ -1552,6 +1927,14 @@ pub async fn create_run( .get("sessionStorage") .cloned() .unwrap_or(Value::Null), + "legacyPersistence": persistence_result + .get("legacyPersistence") + .cloned() + .unwrap_or(Value::Null), + "legacySessionStorage": persistence_result + .get("legacySessionStorage") + .cloned() + .unwrap_or(Value::Null), }); return Ok((StatusCode::OK, stamp_client_headers(), Json(response))); } @@ -1601,6 +1984,70 @@ pub async fn cancel_queued_run( )) } +fn acp_sse_bytes(event: &crate::acp_bridge::SseEvent) -> axum::body::Bytes { + let json_str = serde_json::to_string(&event.data).unwrap_or_else(|_| "{}".into()); + axum::body::Bytes::from(format!("event: {}\ndata: {}\n\n", event.event, json_str)) +} + +fn acp_single_event_response( + context: &RequestContext, + event: crate::acp_bridge::SseEvent, +) -> Result { + use tokio::sync::mpsc; + let (tx, rx) = mpsc::channel::>(1); + tokio::spawn(async move { + let _ = tx.send(Ok(acp_sse_bytes(&event))).await; + }); + let stream = tokio_stream::wrappers::ReceiverStream::new(rx); + let mut response = Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/event-stream; charset=utf-8") + .header(header::CACHE_CONTROL, "no-cache, no-transform") + .header("x-accel-buffering", "no") + .body(Body::from_stream(stream)) + .map_err(|e| { + WebError::internal(format!("SSE response build failed: {e}")).with_context(context) + })?; + stamp_client_headers_into(response.headers_mut()); + Ok(response) +} + +fn acp_existing_run_event_response( + context: &RequestContext, + event_tx: broadcast::Sender, +) -> Result { + use tokio::sync::mpsc; + let (tx, rx) = mpsc::channel::>(256); + let mut event_rx = event_tx.subscribe(); + tokio::spawn(async move { + loop { + match event_rx.recv().await { + Ok(event) => { + if tx.send(Ok(acp_sse_bytes(&event))).await.is_err() { + break; + } + } + Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => { + warn!("ACP duplicate SSE subscriber lagged: {n} events dropped"); + } + Err(tokio::sync::broadcast::error::RecvError::Closed) => break, + } + } + }); + let stream = tokio_stream::wrappers::ReceiverStream::new(rx); + let mut response = Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/event-stream; charset=utf-8") + .header(header::CACHE_CONTROL, "no-cache, no-transform") + .header("x-accel-buffering", "no") + .body(Body::from_stream(stream)) + .map_err(|e| { + WebError::internal(format!("SSE response build failed: {e}")).with_context(context) + })?; + stamp_client_headers_into(response.headers_mut()); + Ok(response) +} + /// ACP variant of stream_events: creates an ACP session, runs the prompt, /// and returns an SSE stream of events. async fn acp_stream_events( @@ -1618,6 +2065,30 @@ async fn acp_stream_events( ) .with_context(&context) })?; + if let Some(active) = ACP_ACTIVE_RUNS + .lock() + .expect("acp active runs") + .get(run_id) + .cloned() + { + return acp_existing_run_event_response(&context, active.event_tx); + } + if ACP_FINISHED_RUNS + .lock() + .expect("acp finished runs") + .contains(run_id) + { + return acp_single_event_response( + &context, + crate::acp_bridge::SseEvent { + event: "run.completed".into(), + data: json!({ + "replayed": true, + "message": "ACP run already completed; not starting duplicate prompt." + }), + }, + ); + } // Build prompt from the message field (frontend sends "message", not "input") let input = payload @@ -1626,10 +2097,7 @@ async fn acp_stream_events( .and_then(Value::as_str) .unwrap_or("请读取当前文档内容"); let capability_policy = page_ai_capability_policy(&payload, input); - - let prompt_blocks = vec![ContentBlock::Text { - text: input.to_string(), - }]; + let registration = run_registration_from_payload(&context, &payload); let runtime_name = acp_runtime_name; @@ -1651,7 +2119,15 @@ async fn acp_stream_events( } else { match state.acp_runtime.get_config(runtime_name).cloned() { Some(mut config) => { - config.env = merge_acp_runtime_env(config.env, access_env); + let memory_env = if runtime_name == "reasonix" { + reasonix_memory_env_for_payload(&state, &context, &payload)? + } else { + None + }; + config.env = merge_acp_runtime_env( + merge_acp_runtime_env(config.env, access_env), + memory_env, + ); state.acp_runtime.switch_to_config(config).await } None => Err(crate::acp_client::AcpError::Internal(format!( @@ -1695,15 +2171,24 @@ async fn acp_stream_events( .with_context(&context) })?; let mnote_session_id = session_id_for_run(run_id).unwrap_or_else(|| run_id.to_string()); + let prompt_text = + chatonly_provider_prompt_text(input, &payload, ®istration, &mnote_session_id, run_id); + let prompt_blocks = vec![ContentBlock::Text { text: prompt_text }]; ACP_ACTIVE_RUNS.lock().expect("acp active runs").insert( run_id.to_string(), AcpActiveRun { manager: Arc::clone(&mgr), mnote_session_id: mnote_session_id.clone(), - acp_session_id, + acp_session_id: acp_session_id.clone(), event_tx: event_tx.clone(), }, ); + let mut payload_with_acp_session = payload.clone(); + payload_with_acp_session["acpSessionId"] = Value::String(acp_session_id.clone()); + ACP_RUN_PAYLOADS + .lock() + .expect("acp run payloads") + .insert(run_id.to_string(), payload_with_acp_session); // Build SSE response from event channel FIRST (before running prompt), // so that if the prompt fails quickly, events are not lost. @@ -1712,10 +2197,12 @@ async fn acp_stream_events( let mut event_rx = event_tx.subscribe(); let state_for_events = state.clone(); let context_for_events = context.clone(); - let event_registration = run_registration_from_payload(&context, &payload); + let event_registration = registration.clone(); let event_payload = payload.clone(); let run_id_for_events = run_id.to_string(); let acp_runtime_for_events = acp_runtime_name.to_string(); + let acp_session_id_for_binding = acp_session_id.clone(); + let binding_registration = event_registration.clone(); tokio::spawn(async move { loop { @@ -1752,6 +2239,13 @@ async fn acp_stream_events( } } }); + let _ = event_tx.send(crate::acp_bridge::SseEvent { + event: "session.info.updated".into(), + data: json!({ + "sessionId": mnote_session_id.clone(), + "acpSessionId": acp_session_id, + }), + }); // Run prompt in background let run_id_owned = run_id.to_string(); @@ -1760,6 +2254,11 @@ async fn acp_stream_events( let audit_context = context.clone(); let audit_payload = payload.clone(); let audit_runtime = acp_runtime_name.to_string(); + let binding_context = context.clone(); + let binding_payload = payload.clone(); + let binding_state = state.clone(); + let binding_run_id = run_id.to_string(); + let binding_runtime = acp_runtime_name.to_string(); let mnote_tool_context = capability_policy.attach_mnote_capabilities.then(|| { crate::acp_session_manager::AcpMnoteToolContext { mnote_session_id: Some(mnote_session_id.clone()), @@ -1788,6 +2287,19 @@ async fn acp_stream_events( { Ok(result) => { info!("ACP prompt completed: stop_reason={:?}", result.stop_reason); + if let Err(error) = persist_provider_conversation_from_proxy( + &binding_state, + &binding_context, + &binding_registration, + &binding_run_id, + &binding_runtime, + &acp_session_id_for_binding, + &binding_payload, + ) + .await + { + warn!(error = ?error, run_id = %binding_run_id, "Provider 远端会话绑定同步失败"); + } let prompt_cancelled = matches!(result.stop_reason, crate::acp_types::StopReason::Cancelled); let runtime_aborted = matches!( @@ -1862,6 +2374,10 @@ async fn acp_stream_events( runtime_status_for_run(&run_id_owned).as_deref(), Some("aborting" | "aborted") ); + ACP_FINISHED_RUNS + .lock() + .expect("acp finished runs") + .insert(run_id_owned.clone()); mgr_clone.close().await; ACP_ACTIVE_RUNS .lock() @@ -2016,6 +2532,10 @@ pub async fn abort_run( } }; update_runtime_by_run_id(&run_id, "aborted", Some("abort.completed"), None); + ACP_FINISHED_RUNS + .lock() + .expect("acp finished runs") + .insert(run_id.clone()); let _ = active.event_tx.send(crate::acp_bridge::SseEvent { event: "run.aborted".into(), data: json!({ @@ -2239,6 +2759,472 @@ fn profile_config_path(profile: &str) -> PathBuf { profile_home(profile).join("config.yaml") } +fn ensure_managed_profile_home(profile: &str) -> std::io::Result<()> { + let profile = profile.trim(); + if profile.is_empty() || profile == "default" { + return Ok(()); + } + let home = hermes_home(); + let dir = home.join("profiles").join(profile); + fs::create_dir_all(&dir)?; + let config_path = dir.join("config.yaml"); + if !config_path.exists() { + let root_config = home.join("config.yaml"); + if root_config.exists() { + let _ = fs::copy(root_config, &config_path)?; + } else { + fs::write(&config_path, "{}\n")?; + } + } + Ok(()) +} + +fn available_hermes_skill_names(skills_dir: &FsPath) -> Vec { + let Ok(entries) = fs::read_dir(skills_dir) else { + return Vec::new(); + }; + let mut names = Vec::new(); + for entry in entries.filter_map(Result::ok) { + if !entry.file_type().map(|kind| kind.is_dir()).unwrap_or(false) { + continue; + } + let name = entry.file_name().to_string_lossy().to_string(); + if name.starts_with('.') { + continue; + } + let dir = entry.path(); + if dir.join("SKILL.md").exists() { + names.push(name); + continue; + } + if let Ok(children) = fs::read_dir(&dir) { + names.extend( + children + .filter_map(Result::ok) + .filter(|child| child.file_type().map(|kind| kind.is_dir()).unwrap_or(false)) + .filter_map(|child| { + if child.path().join("SKILL.md").exists() { + Some(child.file_name().to_string_lossy().to_string()) + } else { + None + } + }), + ); + } + } + names.sort(); + names.dedup(); + names +} + +fn is_mnote_managed_personal_profile(access: &AiAgentProfileAccessRecord) -> bool { + access.profile.profile_kind == "personal" + && access.profile.isolated_profile_name.starts_with("mnote-u-") +} + +fn ensure_personal_profile_skill_baseline( + access: &AiAgentProfileAccessRecord, +) -> std::io::Result<()> { + ensure_managed_profile_home(&access.profile.isolated_profile_name)?; + if !is_mnote_managed_personal_profile(access) { + return Ok(()); + } + let config_path = profile_config_path(&access.profile.isolated_profile_name); + let existing = fs::read_to_string(&config_path).unwrap_or_default(); + if existing.contains(MNOTE_PERSONAL_SKILL_BASELINE_MARKER) { + copy_personal_profile_initial_skills(&access.profile.isolated_profile_name)?; + prune_personal_profile_disabled_skills(&access.profile.isolated_profile_name)?; + return Ok(()); + } + copy_personal_profile_initial_skills(&access.profile.isolated_profile_name)?; + write_disabled_skills_config(&config_path, &[], true) +} + +fn copy_personal_profile_initial_skills(profile: &str) -> std::io::Result<()> { + let source_root = hermes_home().join("skills"); + let target_root = profile_home(profile).join("skills"); + fs::create_dir_all(&target_root)?; + for skill in MNOTE_PERSONAL_SKILL_ALLOWLIST { + let Some(source) = find_skill_dir(&source_root, skill) else { + continue; + }; + let target = target_root.join(skill); + if target.exists() { + continue; + } + copy_dir_recursive(&source, &target)?; + } + Ok(()) +} + +fn prune_personal_profile_disabled_skills(profile: &str) -> std::io::Result<()> { + let profile_skills = available_hermes_skill_names(&profile_home(profile).join("skills")) + .into_iter() + .collect::>(); + let disabled = disabled_skills(profile) + .into_iter() + .filter(|skill| profile_skills.contains(skill.as_str())) + .collect::>(); + write_disabled_skills_config(&profile_config_path(profile), &disabled, false) +} + +fn find_skill_dir(skills_root: &FsPath, skill: &str) -> Option { + let direct = skills_root.join(skill); + if direct.join("SKILL.md").exists() { + return Some(direct); + } + let entries = fs::read_dir(skills_root).ok()?; + for entry in entries.filter_map(Result::ok) { + if !entry.file_type().map(|kind| kind.is_dir()).unwrap_or(false) { + continue; + } + let child = entry.path().join(skill); + if child.join("SKILL.md").exists() { + return Some(child); + } + } + None +} + +fn copy_dir_recursive(source: &FsPath, target: &FsPath) -> std::io::Result<()> { + fs::create_dir_all(target)?; + for entry in fs::read_dir(source)? { + let entry = entry?; + let source_path = entry.path(); + let target_path = target.join(entry.file_name()); + let file_type = entry.file_type()?; + if file_type.is_dir() { + copy_dir_recursive(&source_path, &target_path)?; + } else if file_type.is_file() { + fs::copy(&source_path, &target_path)?; + } + } + Ok(()) +} + +fn page_ai_actor_id(state: &AppState, context: &RequestContext) -> Result { + crate::routes::gateway::current_actor_id(state, context) + .filter(|actor_id| !actor_id.trim().is_empty() && actor_id.trim() != "anonymous") + .ok_or_else(|| { + WebError::new( + StatusCode::UNAUTHORIZED, + "ai_profile_auth_required", + "AI profile 需要登录用户", + ) + .with_context(context) + }) +} + +fn page_ai_actor_is_admin(context: &RequestContext) -> bool { + crate::routes::local_folder_source::is_local_access_policy_admin_context(context) +} + +fn ensure_page_ai_actor_user( + state: &AppState, + actor_id: &str, + is_admin: bool, +) -> Result<(), WebError> { + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some(actor_id.to_string()), + email: None, + username: actor_id.to_string(), + display_name: actor_id.to_string(), + role: Some(if is_admin { "admin" } else { "user" }.to_string()), + password_hash: None, + }) + .map(|_| ()) + .map_err(|error| WebError::internal(format!("SQLite AI profile 用户初始化失败: {error}"))) +} + +fn agent_profile_access_json(access: AiAgentProfileAccessRecord) -> Value { + json!({ + "profileId": access.profile.id, + "agentId": access.profile.agent_id, + "kind": access.profile.profile_kind, + "ownerUserId": access.profile.owner_user_id, + "baseProfile": access.profile.base_profile_name, + "isolatedProfile": access.profile.isolated_profile_name, + "displayName": access.profile.display_name, + "canRun": access.grant.can_run, + "canManageSkills": access.grant.can_manage_skills, + "canManageConfig": access.grant.can_manage_config, + "readonly": !access.grant.can_manage_skills, + "grantRole": access.grant.role + }) +} + +fn ai_profile_forbidden(context: &RequestContext, code: &'static str, message: &str) -> WebError { + WebError::new(StatusCode::FORBIDDEN, code, message) + .with_context(context) + .with_header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .with_header(HEADER_HERMES_CLIENT_OWNER, "mnote-web-hermes-client") +} + +fn select_profile_access( + accesses: Vec, + requested: Option<&str>, +) -> Option { + let requested = requested.map(str::trim).filter(|value| !value.is_empty()); + if let Some(value) = requested { + let normalized = if value == "lite" { + "shared_lite" + } else { + value + }; + return accesses.into_iter().find(|access| { + access.profile.id == normalized + || access.profile.isolated_profile_name == normalized + || access.profile.display_name == normalized + || ((normalized == "default" || normalized == "mnoteai") + && access.profile.profile_kind == "personal") + }); + } + accesses + .iter() + .find(|access| access.profile.profile_kind == "personal") + .cloned() + .or_else(|| { + accesses + .into_iter() + .find(|access| access.profile.id == "shared_lite") + }) +} + +fn resolve_hermes_profile_access( + state: &AppState, + context: &RequestContext, + requested: Option<&str>, +) -> Result, WebError> { + let actor_id = page_ai_actor_id(state, context)?; + let is_admin = page_ai_actor_is_admin(context); + ensure_page_ai_actor_user(state, &actor_id, is_admin)?; + let accesses = state + .control_plane() + .ensure_ai_agent_profile_policy(&actor_id, is_admin) + .map_err(|error| { + WebError::internal(format!("SQLite AI profile policy 解析失败: {error}")) + })?; + Ok(select_profile_access(accesses, requested)) +} + +fn resolve_hermes_profile_from_query( + state: &AppState, + context: &RequestContext, + query: &HashMap, +) -> Result, WebError> { + let requested = query + .get("profileId") + .or_else(|| query.get("profile_id")) + .or_else(|| query.get("profile")) + .map(String::as_str); + resolve_hermes_profile_access(state, context, requested) +} + +fn resolve_hermes_profile_from_payload( + state: &AppState, + context: &RequestContext, + payload: &Value, +) -> Result, WebError> { + let requested = payload + .get("profileId") + .or_else(|| payload.get("profile_id")) + .or_else(|| payload.get("profile")) + .and_then(Value::as_str); + resolve_hermes_profile_access(state, context, requested) +} + +fn stamp_agent_profile_ref(payload: &mut Value, access: &AiAgentProfileAccessRecord) { + payload["profile"] = Value::String(access.profile.isolated_profile_name.clone()); + payload["profileId"] = Value::String(access.profile.id.clone()); + payload["agentProfileRef"] = json!({ + "kind": access.profile.profile_kind, + "profileId": access.profile.id, + "ownerUserId": access.profile.owner_user_id, + "baseProfile": access.profile.base_profile_name, + "isolatedProfile": access.profile.isolated_profile_name, + "displayName": access.profile.display_name, + "canRun": access.grant.can_run, + "canManageSkills": access.grant.can_manage_skills, + "canManageConfig": access.grant.can_manage_config, + "readonly": !access.grant.can_manage_skills + }); +} + +fn payload_requests_hermes_profile(payload: &Value) -> bool { + let agent_id = payload + .get("agentId") + .and_then(Value::as_str) + .map(str::trim) + .unwrap_or_default(); + let acp_runtime = payload + .get("acpRuntime") + .and_then(Value::as_str) + .map(str::trim) + .unwrap_or_default(); + agent_id == "hermes" + || acp_runtime == "hermes" + || payload.get("profileId").is_some() + || payload.get("profile_id").is_some() + || payload.get("agentProfileRef").is_some() +} + +fn ai_preference_bool( + state: &AppState, + user_id: &str, + key: &str, + default_value: bool, +) -> Result { + let preferences = state + .control_plane() + .list_user_ui_preferences(user_id, None, None) + .map_err(|error| WebError::internal(format!("SQLite AI 偏好读取失败: {error}")))?; + for preference in preferences { + if preference.key == key { + return Ok(serde_json::from_str::(&preference.value_json) + .ok() + .and_then(|value| value.as_bool()) + .unwrap_or(default_value)); + } + } + Ok(default_value) +} + +fn apply_mnote_builtin_skill_policy_to_payload( + state: &AppState, + actor_id: &str, + payload: &mut Value, +) -> Result<(), WebError> { + let agent_id = payload + .get("agentId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let mut policy = serde_json::Map::new(); + for skill in crate::hermes_tools::skill::skill_summaries_for_agent(agent_id) { + let Some(skill_id) = skill.get("id").and_then(Value::as_str) else { + continue; + }; + let key = format!("ai.agent.mnote_builtin.skill.{skill_id}.enabled"); + policy.insert( + skill_id.to_string(), + Value::Bool(ai_preference_bool(state, actor_id, &key, true)?), + ); + } + let skill_preferences = payload + .as_object_mut() + .expect("page ai run payload object") + .entry("skillPreferences") + .or_insert_with(|| json!({})); + if !skill_preferences.is_object() { + *skill_preferences = json!({}); + } + skill_preferences + .as_object_mut() + .expect("skillPreferences object") + .insert("mnote".to_string(), Value::Object(policy)); + Ok(()) +} + +fn reasonix_memory_enabled( + state: &AppState, + context: &RequestContext, + payload: &Value, +) -> Result { + let actor_id = payload + .get("actorId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty() && *value != "anonymous") + .map(ToOwned::to_owned) + .or_else(|| crate::routes::gateway::current_actor_id(state, context)) + .unwrap_or_else(|| context.auth.actor_id.trim().to_string()); + if actor_id.is_empty() || actor_id == "anonymous" { + return Ok(false); + } + ai_preference_bool(state, &actor_id, "ai.agent.reasonix.memory_enabled", false) +} + +fn reasonix_memory_env_for_payload( + state: &AppState, + context: &RequestContext, + payload: &Value, +) -> Result>, WebError> { + if reasonix_memory_enabled(state, context, payload)? { + return Ok(Some(HashMap::from([( + "REASONIX_MEMORY".to_string(), + "on".to_string(), + )]))); + } + Ok(Some(HashMap::from([( + "REASONIX_MEMORY".to_string(), + "off".to_string(), + )]))) +} + +fn stamp_hermes_skill_payload_profile_policy( + payload: &mut Value, + access: &AiAgentProfileAccessRecord, +) { + payload["profileId"] = Value::String(access.profile.id.clone()); + payload["agentProfileRef"] = agent_profile_access_json(access.clone()); + if let Some(categories) = payload.get_mut("categories").and_then(Value::as_array_mut) { + for category in categories { + if let Some(skills) = category.get_mut("skills").and_then(Value::as_array_mut) { + for skill in skills { + skill["profileId"] = Value::String(access.profile.id.clone()); + skill["skillKind"] = Value::String("hermes_profile".to_string()); + skill["builtin"] = Value::Bool(false); + skill["configurable"] = Value::Bool(access.grant.can_manage_skills); + skill["readonly"] = Value::Bool(!access.grant.can_manage_skills); + skill["configScope"] = Value::String( + if access.profile.profile_kind == "shared" { + "hermes_shared_profile" + } else { + "hermes_personal_profile" + } + .to_string(), + ); + } + } + } + } +} + +fn stamp_mnote_builtin_skill_payload_policy( + state: &AppState, + context: &RequestContext, + payload: &mut Value, +) -> Result<(), WebError> { + let actor_id = page_ai_actor_id(state, context)?; + if let Some(categories) = payload.get_mut("categories").and_then(Value::as_array_mut) { + for category in categories { + if let Some(skills) = category.get_mut("skills").and_then(Value::as_array_mut) { + for skill in skills { + let skill_id = skill + .get("id") + .or_else(|| skill.get("name")) + .and_then(Value::as_str) + .map(str::trim) + .unwrap_or_default(); + if skill_id.is_empty() { + continue; + } + let key = format!("ai.agent.mnote_builtin.skill.{skill_id}.enabled"); + skill["enabled"] = + Value::Bool(ai_preference_bool(state, &actor_id, &key, true)?); + skill["builtin"] = Value::Bool(true); + skill["configurable"] = Value::Bool(true); + skill["configScope"] = Value::String("user_sqlite".to_string()); + skill["skillKind"] = Value::String("mnote_builtin".to_string()); + } + } + } + } + Ok(()) +} + fn parse_profile_list(stdout: &str) -> Vec { let active = active_profile_name().unwrap_or_else(|| "default".into()); stdout @@ -2720,7 +3706,14 @@ fn skill_entry( } fn skills_payload(profile: &str) -> Value { - let skills_dir = hermes_home().join("skills"); + let profile_skills_dir = profile_home(profile).join("skills"); + let skills_dir = if profile_skills_dir.exists() + && !available_hermes_skill_names(&profile_skills_dir).is_empty() + { + profile_skills_dir + } else { + hermes_home().join("skills") + }; let disabled = disabled_skills(profile); let meta = SkillCatalogMeta::read(&skills_dir); let mut categories = Vec::new(); @@ -2933,6 +3926,10 @@ fn mnote_builtin_skills_payload(agent_id: Option<&str>) -> Value { "description": skill.get("description").cloned().unwrap_or(Value::Null), "enabled": true, "toggleable": true, + "builtin": true, + "configurable": true, + "configScope": "user_sqlite", + "skillKind": "mnote_builtin", "source": "mnote", "origin": "builtin", "agentIds": skill.get("agentIds").cloned().unwrap_or(Value::Null), @@ -2982,31 +3979,39 @@ fn merge_misc_categories(categories: Vec) -> Vec { fn set_skill_enabled(profile: &str, name: &str, enabled: bool) -> std::io::Result<()> { let path = profile_config_path(profile); let mut disabled = disabled_skills(profile); + let name = name.trim(); if enabled { - disabled.retain(|item| item != name); + disabled.retain(|item| item.trim() != name); } else if !disabled.iter().any(|item| item == name) { disabled.push(name.to_string()); } disabled.sort(); - let existing = fs::read_to_string(&path).unwrap_or_default(); + write_disabled_skills_config(&path, &disabled, false) +} + +fn write_disabled_skills_config( + path: &FsPath, + disabled: &[String], + mark_personal_baseline: bool, +) -> std::io::Result<()> { + let existing = fs::read_to_string(path).unwrap_or_default(); + let has_personal_baseline_marker = existing.contains(MNOTE_PERSONAL_SKILL_BASELINE_MARKER); let mut kept = Vec::new(); - let mut in_skills = false; - let mut in_disabled = false; + let mut skipping_skills = false; for line in existing.lines() { let trimmed = line.trim(); - if !line.starts_with(' ') && !trimmed.is_empty() { - in_skills = trimmed == "skills:"; - in_disabled = false; - } - if in_skills && trimmed == "disabled:" { - in_disabled = true; + if trimmed == MNOTE_PERSONAL_SKILL_BASELINE_MARKER { continue; } - if in_disabled { - if trimmed.starts_with("- ") || trimmed.is_empty() { + if skipping_skills { + if line.starts_with(' ') || trimmed.is_empty() { continue; } - in_disabled = false; + skipping_skills = false; + } + if !line.starts_with(' ') && trimmed == "skills:" { + skipping_skills = true; + continue; } kept.push(line.to_string()); } @@ -3017,12 +4022,18 @@ fn set_skill_enabled(profile: &str, name: &str, enabled: bool) -> std::io::Resul if !output.ends_with('\n') && !output.is_empty() { output.push('\n'); } - output.push_str("skills:\n disabled:\n"); - for skill in disabled { - output.push_str(" - "); - output.push_str(&skill); + if mark_personal_baseline || has_personal_baseline_marker { + output.push_str(MNOTE_PERSONAL_SKILL_BASELINE_MARKER); output.push('\n'); } + if !disabled.is_empty() { + output.push_str("skills:\n disabled:\n"); + for skill in disabled { + output.push_str(" - "); + output.push_str(&skill); + output.push('\n'); + } + } fs::write(path, output) } @@ -3726,7 +4737,14 @@ fn acp_allowed_roots_env_for_payload(payload: &Value) -> Option PageAiCapabilit profile: payload.get("profile").cloned().unwrap_or(Value::Null), allowed_roots: payload.get("allowedRoots").cloned().unwrap_or(Value::Null), ai_access_scope: page_ai_capability_scope_for_tools(payload), + agent_run_envelope: page_ai_capability_agent_run_envelope(payload), } } +fn page_ai_capability_agent_run_envelope(payload: &Value) -> Value { + let document_id = payload + .get("documentId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("current"); + let workspace_id = payload + .get("workspaceId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("default"); + let source_kind = payload + .get("sourceKind") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("convex_workspace"); + let root_uri = payload + .get("rootUri") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let profile = payload + .get("profile") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("default"); + let actor_id = payload + .get("actorId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("anonymous"); + let actor_type = payload + .get("actorType") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("anonymous"); + let session_id = payload + .get("sessionId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("page-ai"); + let run_id = payload + .get("runId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or(session_id); + let trace_id = payload + .get("traceId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("page-ai"); + let editor_target = payload + .get("editorTarget") + .map(sanitize_run_editor_target) + .unwrap_or(Value::Null); + let run_target_snapshot = payload + .get("runTargetSnapshot") + .map(sanitize_run_target_snapshot) + .unwrap_or(Value::Null); + let agent_target_package = if source_kind == "local_folder" { + Some(build_local_agent_target_package( + payload, + document_id, + workspace_id, + source_kind, + root_uri, + &editor_target, + &run_target_snapshot, + )) + } else { + None + }; + build_agent_run_envelope( + payload, + document_id, + workspace_id, + source_kind, + root_uri, + profile, + actor_id, + actor_type, + session_id, + run_id, + trace_id, + &editor_target, + &run_target_snapshot, + agent_target_package.as_ref(), + source_kind == "local_folder", + ) +} + fn page_ai_skill_enabled_by_payload(payload: &Value, skill: &Value) -> bool { let Some(skill_id) = skill.get("id").and_then(Value::as_str) else { return true; @@ -4205,6 +5326,12 @@ fn page_ai_capability_scope_for_tools(payload: &Value) -> Value { .get("allowedRoots") .cloned() .unwrap_or_else(|| json!([])); + let allowed_resource_ids = local_agent_target_allowed_resource_ids( + payload + .get("targetPackage") + .or_else(|| payload.get("agentTargetPackage")), + document_id, + ); json!({ "permissionLevel": if allowed_roots.as_array().map(|roots| { roots.iter().any(|root| { @@ -4215,7 +5342,7 @@ fn page_ai_capability_scope_for_tools(payload: &Value) -> Value { }) }).unwrap_or(false) { "read_write" } else { "read" }, "allowedRoots": allowed_roots, - "allowedResourceIds": [document_id] + "allowedResourceIds": allowed_resource_ids }) } @@ -4303,6 +5430,9 @@ fn build_run_upstream_body(context: &RequestContext, payload: Value) -> Result Result Result Result Result Result Result Value { "schema", "source", "objectIdentity", + "targetId", "paneRole", "documentId", "workspaceId", "editorKind", + "resourceKind", "active", "dirtyState", "preview", @@ -4656,6 +5827,9 @@ fn sanitize_run_editor_target(value: &Value) -> Value { "lastActiveAt", "assetId", "path", + "onlyofficeSessionId", + "bridgeSessionId", + "bridgeSessionReady", ] { if let Some(value) = source.get(key) { sanitized.insert(key.to_string(), value.clone()); @@ -4876,6 +6050,433 @@ fn sanitize_context_refs(value: Option<&Value>) -> Value { Value::Array(refs) } +fn sanitize_relative_path(value: &str) -> Option { + let normalized = value + .trim() + .replace('\\', "/") + .trim_start_matches('/') + .to_string(); + if normalized.is_empty() + || normalized.starts_with('/') + || normalized + .split('/') + .any(|part| part.is_empty() || part == "..") + { + None + } else { + Some(normalized) + } +} + +fn target_workspace_path(value: &Value) -> Option<&Value> { + value.get("workspacePath").filter(|path| path.is_object()) +} + +fn target_relative_path(value: &Value) -> Option { + value + .get("currentFile") + .and_then(|file| file.get("relativePath")) + .and_then(Value::as_str) + .and_then(sanitize_relative_path) + .or_else(|| { + target_workspace_path(value) + .and_then(|path| path.get("relativePath")) + .and_then(Value::as_str) + .and_then(sanitize_relative_path) + }) + .or_else(|| { + value + .get("relativePath") + .and_then(Value::as_str) + .and_then(sanitize_relative_path) + }) +} + +fn local_agent_target_allowed_files(target_package: &Value) -> Vec { + let mut files = target_package + .get("allowedFiles") + .and_then(Value::as_array) + .map(|items| { + items + .iter() + .filter_map(Value::as_str) + .filter_map(sanitize_relative_path) + .collect::>() + }) + .unwrap_or_default(); + if let Some(relative_path) = target_relative_path(target_package) { + files.push(relative_path); + } + files.sort(); + files.dedup(); + files +} + +fn local_agent_target_allowed_file_paths(root_uri: &str, target_package: &Value) -> Vec { + let Ok(root) = local_ai_session_root_dir(root_uri) else { + return Vec::new(); + }; + let files = local_agent_target_allowed_files(target_package); + files + .into_iter() + .map(|relative_path| root.join(relative_path).to_string_lossy().to_string()) + .collect() +} + +fn push_local_agent_resource_id(ids: &mut Vec, value: Option<&Value>) { + let Some(value) = value.and_then(Value::as_str).map(str::trim) else { + return; + }; + if value.is_empty() { + return; + } + let owned = value.to_string(); + if !ids.contains(&owned) { + ids.push(owned); + } +} + +fn push_local_agent_resource_id_string(ids: &mut Vec, value: String) { + let normalized = value.trim(); + if normalized.is_empty() { + return; + } + let owned = normalized.to_string(); + if !ids.contains(&owned) { + ids.push(owned); + } +} + +fn push_local_agent_target_resource_ids(ids: &mut Vec, target: &Value) { + push_local_agent_resource_id(ids, target.get("targetId")); + push_local_agent_resource_id(ids, target.get("objectIdentity")); + push_local_agent_resource_id(ids, target.get("documentId")); + push_local_agent_resource_id(ids, target.get("assetId")); + push_local_agent_resource_id(ids, target.get("onlyofficeSessionId")); + push_local_agent_resource_id(ids, target.get("bridgeSessionId")); + if let Some(workspace_path) = target.get("workspacePath") { + push_local_agent_resource_id(ids, workspace_path.get("objectIdentity")); + push_local_agent_resource_id(ids, workspace_path.get("documentId")); + push_local_agent_resource_id(ids, workspace_path.get("assetId")); + } + if let Some(current_file) = target.get("currentFile") { + push_local_agent_resource_id(ids, current_file.get("objectIdentity")); + push_local_agent_resource_id(ids, current_file.get("documentId")); + push_local_agent_resource_id(ids, current_file.get("assetId")); + } + let document_id = target + .get("documentId") + .or_else(|| { + target + .get("workspacePath") + .and_then(|path| path.get("documentId")) + }) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + let asset_id = target + .get("assetId") + .or_else(|| { + target + .get("workspacePath") + .and_then(|path| path.get("assetId")) + }) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()); + if let (Some(document_id), Some(asset_id)) = (document_id, asset_id) { + push_local_agent_resource_id_string( + ids, + format!("resource:office:{document_id}:{asset_id}"), + ); + push_local_agent_resource_id_string( + ids, + format!("resource:onlyoffice:{document_id}:{asset_id}"), + ); + } +} + +fn local_agent_target_allowed_resource_ids( + target_package: Option<&Value>, + fallback_document_id: &str, +) -> Vec { + let mut ids = Vec::new(); + if let Some(target_package) = target_package { + push_local_agent_target_resource_ids(&mut ids, target_package); + if let Some(targets) = target_package.get("targets").and_then(Value::as_array) { + for target in targets { + push_local_agent_target_resource_ids(&mut ids, target); + } + } + } + if ids.is_empty() { + ids.push(fallback_document_id.to_string()); + } + ids +} + +fn build_local_agent_target_package( + payload: &Value, + document_id: &str, + workspace_id: &str, + source_kind: &str, + root_uri: Option<&str>, + editor_target: &Value, + run_target_snapshot: &Value, +) -> Value { + let payload_package = payload + .get("targetPackage") + .or_else(|| payload.get("agentTargetPackage")) + .map(sanitize_local_agent_target_package) + .filter(|value| !value.is_null()); + let target_package = payload_package.unwrap_or_else(|| { + derive_local_agent_target_package( + document_id, + workspace_id, + source_kind, + root_uri, + editor_target, + run_target_snapshot, + ) + }); + let allowed_files = local_agent_target_allowed_files(&target_package); + let mut next = target_package.as_object().cloned().unwrap_or_default(); + normalize_local_target_resource_kind(&mut next); + next.insert( + "allowedFiles".to_string(), + Value::Array(allowed_files.into_iter().map(Value::String).collect()), + ); + Value::Object(next) +} + +fn normalize_local_target_resource_kind(target: &mut serde_json::Map) { + let fallback_identity = target + .get("documentId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + normalize_local_target_object_identity(target, fallback_identity.as_deref()); + if matches!( + target.get("resourceKind").and_then(Value::as_str), + Some("page") | None + ) { + target.insert( + "resourceKind".to_string(), + Value::String("markdown_page".to_string()), + ); + } + for key in ["workspacePath", "currentFile"] { + if let Some(Value::Object(object)) = target.get_mut(key) { + normalize_local_target_object_identity(object, fallback_identity.as_deref()); + if matches!( + object.get("resourceKind").and_then(Value::as_str), + Some("page") | None + ) { + object.insert( + "resourceKind".to_string(), + Value::String("markdown_page".to_string()), + ); + } + } + } +} + +fn normalize_local_target_object_identity( + target: &mut serde_json::Map, + fallback_identity: Option<&str>, +) { + let current = target + .get("objectIdentity") + .and_then(Value::as_str) + .map(str::trim) + .unwrap_or_default(); + if (current.is_empty() || current == "page:primary") && fallback_identity.is_some() { + target.insert( + "objectIdentity".to_string(), + Value::String(fallback_identity.unwrap().to_string()), + ); + } +} + +fn sanitize_local_agent_target_package(value: &Value) -> Value { + let Some(source) = value.as_object() else { + return Value::Null; + }; + let mut sanitized = serde_json::Map::new(); + for key in [ + "schema", + "source", + "frozenAt", + "primaryTargetId", + "workspaceId", + "sourceKind", + "rootUri", + "documentId", + "objectIdentity", + "resourceKind", + "assetId", + "onlyofficeSessionId", + "bridgeSessionId", + ] { + if let Some(value) = source.get(key) { + sanitized.insert(key.to_string(), value.clone()); + } + } + if let Some(workspace_path) = source.get("workspacePath") { + let sanitized_path = sanitize_workspace_path(workspace_path); + if !sanitized_path.is_null() { + sanitized.insert("workspacePath".to_string(), sanitized_path); + } + } + if let Some(current_file) = source.get("currentFile").and_then(Value::as_object) { + let mut file = serde_json::Map::new(); + for key in [ + "rootUri", + "relativePath", + "documentId", + "objectIdentity", + "resourceKind", + "assetId", + "onlyofficeSessionId", + "bridgeSessionId", + ] { + if let Some(value) = current_file.get(key) { + file.insert(key.to_string(), value.clone()); + } + } + if !file.is_empty() { + sanitized.insert("currentFile".to_string(), Value::Object(file)); + } + } + if let Some(files) = source.get("allowedFiles").and_then(Value::as_array) { + let allowed = files + .iter() + .filter_map(Value::as_str) + .filter_map(sanitize_relative_path) + .map(Value::String) + .collect::>(); + sanitized.insert("allowedFiles".to_string(), Value::Array(allowed)); + } + if let Some(targets) = source.get("targets").and_then(Value::as_array) { + let sanitized_targets = targets + .iter() + .map(sanitize_local_agent_target_entry) + .filter(|value| !value.is_null()) + .collect::>(); + if !sanitized_targets.is_empty() { + sanitized.insert("targets".to_string(), Value::Array(sanitized_targets)); + } + } + if sanitized.is_empty() { + Value::Null + } else { + sanitized + .entry("schema".to_string()) + .or_insert_with(|| Value::String("mnote.agent_target_package.v1".to_string())); + Value::Object(sanitized) + } +} + +fn sanitize_local_agent_target_entry(value: &Value) -> Value { + let Some(source) = value.as_object() else { + return Value::Null; + }; + let mut sanitized = serde_json::Map::new(); + for key in [ + "targetId", + "objectIdentity", + "documentId", + "workspaceId", + "sourceKind", + "rootUri", + "relativePath", + "resourceKind", + "assetId", + "paneRole", + "title", + "onlyofficeSessionId", + "bridgeSessionId", + ] { + if let Some(value) = source.get(key) { + sanitized.insert(key.to_string(), value.clone()); + } + } + if let Some(workspace_path) = source.get("workspacePath") { + let sanitized_path = sanitize_workspace_path(workspace_path); + if !sanitized_path.is_null() { + sanitized.insert("workspacePath".to_string(), sanitized_path); + } + } + if sanitized.is_empty() { + Value::Null + } else { + Value::Object(sanitized) + } +} + +fn derive_local_agent_target_package( + document_id: &str, + workspace_id: &str, + source_kind: &str, + root_uri: Option<&str>, + editor_target: &Value, + run_target_snapshot: &Value, +) -> Value { + let target = if !editor_target.is_null() { + editor_target + } else { + run_target_snapshot + .get("editorTarget") + .unwrap_or(&Value::Null) + }; + let workspace_path = target_workspace_path(target) + .map(sanitize_workspace_path) + .filter(|value| !value.is_null()) + .unwrap_or_else(|| { + let relative_path = local_resource_id_to_relative_path(document_id).unwrap_or_default(); + json!({ + "schema": "mnote.workspace_path.v1", + "workspaceId": workspace_id, + "sourceKind": source_kind, + "rootUri": root_uri.map(Value::from).unwrap_or(Value::Null), + "relativePath": relative_path, + "documentId": document_id, + "objectIdentity": document_id, + "assetId": "", + "resourceKind": "markdown_page" + }) + }); + let relative_path = target_relative_path(&workspace_path) + .or_else(|| target_relative_path(target)) + .or_else(|| local_resource_id_to_relative_path(document_id)); + let object_identity = workspace_path + .get("objectIdentity") + .and_then(Value::as_str) + .filter(|value| !value.trim().is_empty()) + .unwrap_or(document_id) + .to_string(); + json!({ + "schema": "mnote.agent_target_package.v1", + "source": "server_derived", + "workspaceId": workspace_id, + "sourceKind": source_kind, + "rootUri": root_uri.map(Value::from).unwrap_or(Value::Null), + "documentId": document_id, + "objectIdentity": object_identity, + "resourceKind": workspace_path.get("resourceKind").cloned().unwrap_or_else(|| Value::String("markdown_page".to_string())), + "workspacePath": workspace_path, + "currentFile": relative_path.as_ref().map(|relative_path| json!({ + "rootUri": root_uri.unwrap_or_default(), + "relativePath": relative_path, + "documentId": document_id, + "objectIdentity": object_identity, + "resourceKind": "markdown_page" + })).unwrap_or(Value::Null), + "allowedFiles": relative_path.into_iter().collect::>() + }) +} + fn sanitize_payload_allowed_roots(value: Option<&Value>) -> Value { let roots = value .and_then(Value::as_array) @@ -4963,6 +6564,7 @@ fn build_agent_run_envelope( trace_id: &str, editor_target: &Value, run_target_snapshot: &Value, + agent_target_package: Option<&Value>, is_local_source: bool, ) -> Value { let agent_id = payload @@ -4977,6 +6579,7 @@ fn build_agent_run_envelope( .map(str::trim) .filter(|value| !value.is_empty()) .unwrap_or(profile); + let target_package = agent_target_package.cloned().unwrap_or(Value::Null); json!({ "schema": "mnote.agent_run_envelope.v1", "agentId": agent_id, @@ -4993,6 +6596,11 @@ fn build_agent_run_envelope( "rootUri": root_uri.map(Value::from).unwrap_or(Value::Null), "contextRefs": sanitize_context_refs(payload.get("contextRefs")), "allowedRoots": build_agent_run_allowed_roots(payload, root_uri, is_local_source), + "allowedFiles": target_package + .get("allowedFiles") + .cloned() + .unwrap_or_else(|| Value::Array(Vec::new())), + "targetPackage": target_package, "primaryTarget": build_agent_run_primary_target( document_id, workspace_id, @@ -5232,6 +6840,579 @@ fn json_string(value: &Value) -> String { serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string()) } +#[derive(Debug, Clone, Copy)] +struct ChatonlyProviderConfig { + provider: &'static str, + schema: &'static str, + profiles: &'static [&'static str], + base_profiles: &'static [&'static str], + isolated_profiles: &'static [&'static str], + profile_ids: &'static [&'static str], + delete_url_env: &'static str, + lookup_url_env: &'static str, + default_delete_url: &'static str, + default_lookup_url: &'static str, +} + +const CHATONLY_PROVIDER_CONFIGS: &[ChatonlyProviderConfig] = &[ + ChatonlyProviderConfig { + provider: "doubao-web", + schema: "mnote.provider_chat_context.v1", + profiles: &["openclaw-doubao-chat", "doubao-chat"], + base_profiles: &["doubao-chat"], + isolated_profiles: &["openclaw-doubao-chat"], + profile_ids: &["shared_doubao_chat"], + delete_url_env: ENV_DOUBAO_CONVERSATION_DELETE_URL, + lookup_url_env: ENV_DOUBAO_CONVERSATION_LOOKUP_URL, + default_delete_url: DEFAULT_DOUBAO_CONVERSATION_DELETE_URL, + default_lookup_url: DEFAULT_DOUBAO_CONVERSATION_LOOKUP_URL, + }, + ChatonlyProviderConfig { + provider: "deepseek-web", + schema: "mnote.provider_chat_context.v1", + profiles: &["openclaw-deepseek-chat", "deepseek-chat"], + base_profiles: &["deepseek-chat"], + isolated_profiles: &["openclaw-deepseek-chat"], + profile_ids: &["shared_deepseek_chat"], + delete_url_env: ENV_DEEPSEEK_CONVERSATION_DELETE_URL, + lookup_url_env: ENV_DEEPSEEK_CONVERSATION_LOOKUP_URL, + default_delete_url: DEFAULT_DEEPSEEK_CONVERSATION_DELETE_URL, + default_lookup_url: DEFAULT_DEEPSEEK_CONVERSATION_LOOKUP_URL, + }, + ChatonlyProviderConfig { + provider: "gemini-web", + schema: "mnote.provider_chat_context.v1", + profiles: &["openclaw-gemini-chat", "gemini-chat"], + base_profiles: &["gemini-chat"], + isolated_profiles: &["openclaw-gemini-chat"], + profile_ids: &["shared_gemini_chat"], + delete_url_env: ENV_GEMINI_CONVERSATION_DELETE_URL, + lookup_url_env: ENV_GEMINI_CONVERSATION_LOOKUP_URL, + default_delete_url: DEFAULT_GEMINI_CONVERSATION_DELETE_URL, + default_lookup_url: DEFAULT_GEMINI_CONVERSATION_LOOKUP_URL, + }, +]; + +fn chatonly_provider_by_name(provider: &str) -> Option<&'static ChatonlyProviderConfig> { + let provider = provider.trim(); + CHATONLY_PROVIDER_CONFIGS + .iter() + .find(|config| config.provider == provider) +} + +fn chatonly_profile_matches(value: Option<&str>, candidates: &[&str]) -> bool { + let Some(value) = value.map(str::trim).filter(|value| !value.is_empty()) else { + return false; + }; + candidates.iter().any(|candidate| *candidate == value) +} + +fn chatonly_provider_for_run( + payload: &Value, + registration: &HermesRunRegistration, +) -> Option<&'static ChatonlyProviderConfig> { + let agent_id = payload + .get("agentId") + .and_then(Value::as_str) + .map(str::trim) + .unwrap_or_default(); + if agent_id != "chat_only" { + return None; + } + let profile = registration.profile.trim(); + let payload_profile = payload.get("profile").and_then(Value::as_str); + let agent_profile = payload.get("agentProfileRef"); + let base_profile = agent_profile + .and_then(|value| value.get("baseProfile")) + .and_then(Value::as_str); + let isolated_profile = agent_profile + .and_then(|value| value.get("isolatedProfile")) + .and_then(Value::as_str); + let profile_id = payload.get("profileId").and_then(Value::as_str); + CHATONLY_PROVIDER_CONFIGS.iter().find(|config| { + chatonly_profile_matches(Some(profile), config.profiles) + || chatonly_profile_matches(payload_profile, config.profiles) + || chatonly_profile_matches(base_profile, config.base_profiles) + || chatonly_profile_matches(isolated_profile, config.isolated_profiles) + || chatonly_profile_matches(profile_id, config.profile_ids) + }) +} + +fn provider_default_remote_url(provider: &str, remote_conversation_id: &str) -> Option { + let id = remote_conversation_id.trim(); + if id.is_empty() { + return None; + } + if id.starts_with("http://") || id.starts_with("https://") { + return Some(id.to_string()); + } + match provider { + "doubao-web" => Some(format!("https://www.doubao.com/chat/{id}")), + "deepseek-web" => Some(format!("https://chat.deepseek.com/a/chat/s/{id}")), + "gemini-web" => Some(format!("https://gemini.google.com/app/{id}")), + _ => None, + } +} + +fn chatonly_provider_prompt_text( + input: &str, + payload: &Value, + registration: &HermesRunRegistration, + mnote_session_id: &str, + run_id: &str, +) -> String { + let Some(config) = chatonly_provider_for_run(payload, registration) else { + return input.to_string(); + }; + let metadata = json!({ + "schema": config.schema, + "provider": config.provider, + "mnoteSessionId": mnote_session_id, + "mnoteRunId": run_id, + "actorId": payload.get("actorId").and_then(Value::as_str).unwrap_or_default(), + "workspaceId": payload.get("workspaceId").and_then(Value::as_str).unwrap_or_default(), + "providerConversation": payload.get("providerConversation").cloned().unwrap_or(Value::Null) + }); + format!( + "Conversation info (untrusted metadata):\n```json\n{}\n```\n\n{}", + json_string(&metadata), + input + ) +} + +fn payload_has_remote_provider_conversation(payload: &Value) -> bool { + payload + .get("providerConversation") + .and_then(|value| value.get("remoteConversationId")) + .and_then(Value::as_str) + .map(str::trim) + .is_some_and(|value| !value.is_empty()) +} + +fn inject_provider_conversation_binding_for_run( + store: &dyn control_plane::ControlPlaneStore, + context: &RequestContext, + registration: &HermesRunRegistration, + payload: &mut Value, +) -> Result<(), WebError> { + let Some(config) = chatonly_provider_for_run(payload, registration) else { + return Ok(()); + }; + if payload_has_remote_provider_conversation(payload) { + return Ok(()); + } + let user_id = runtime_store_user_id(context, payload); + let workspace_id = payload + .get("workspaceId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .or(context.workspace.workspace_id.as_deref()); + let Some(binding) = store + .find_ai_external_conversation_binding( + &user_id, + workspace_id, + ®istration.session_id, + config.provider, + ) + .map_err(|error| { + WebError::internal(format!("SQLite provider 会话绑定读取失败: {error}")) + .with_context(context) + })? + else { + return Ok(()); + }; + if binding.status != "active" || binding.remote_conversation_id.trim().is_empty() { + return Ok(()); + } + payload["providerConversation"] = json!({ + "provider": binding.provider, + "remoteConversationId": binding.remote_conversation_id, + "remoteUrl": binding.remote_url + }); + Ok(()) +} + +fn persist_provider_conversation_event( + state: &AppState, + context: &RequestContext, + registration: &HermesRunRegistration, + event_type: &str, + event_payload: &Value, + run_payload: &Value, +) -> Result<(), WebError> { + if event_type != "provider.conversation.bound" { + return Ok(()); + } + let payload = event_payload.get("data").unwrap_or(event_payload); + let provider = payload + .get("provider") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .or_else(|| { + chatonly_provider_for_run(run_payload, registration).map(|config| config.provider) + }) + .unwrap_or("doubao-web"); + if chatonly_provider_by_name(provider).is_none() { + return Ok(()); + } + let Some(remote_conversation_id) = payload + .get("remoteConversationId") + .or_else(|| payload.get("remote_conversation_id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + else { + return Ok(()); + }; + let user_id = runtime_store_user_id(context, run_payload); + let workspace_id = run_payload + .get("workspaceId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + .or_else(|| context.workspace.workspace_id.clone()); + let remote_url = payload + .get("remoteUrl") + .or_else(|| payload.get("remote_url")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + .or_else(|| provider_default_remote_url(provider, remote_conversation_id)); + let acp_session_id = payload + .get("acpSessionId") + .or_else(|| payload.get("acp_session_id")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + let agent_id = run_payload + .get("agentId") + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("chat_only") + .to_string(); + state + .control_plane() + .upsert_ai_external_conversation_binding(UpsertAiExternalConversationBindingInput { + id: None, + user_id, + workspace_id, + mnote_session_id: registration.session_id.clone(), + acp_session_id, + agent_id, + profile: registration.profile.clone(), + provider: provider.to_string(), + remote_conversation_id: remote_conversation_id.to_string(), + remote_url, + status: "active".to_string(), + metadata_json: json_string(&json!({ + "source": event_type, + "payload": event_payload + })), + }) + .map(|_| ()) + .map_err(|error| { + WebError::internal(format!( + "SQLite provider conversation 绑定写入失败: {error}" + )) + .with_context(context) + }) +} + +fn mark_provider_conversation_local_deleted_for_session( + store: &dyn control_plane::ControlPlaneStore, + user_id: &str, + workspace_id: Option<&str>, + session_id: &str, +) -> Result { + let metadata = json_string(&json!({ + "reason": "mnote_session_deleted", + "updatedAt": now_ms() + })); + let mut changed = 0; + for config in CHATONLY_PROVIDER_CONFIGS { + changed += store.mark_ai_external_conversation_binding_status( + user_id, + workspace_id, + session_id, + config.provider, + "local_deleted", + Some(&metadata), + )?; + } + Ok(changed) +} + +fn find_provider_conversation_binding_for_session( + store: &dyn control_plane::ControlPlaneStore, + user_id: &str, + workspace_id: Option<&str>, + session_id: &str, +) -> Result, control_plane::ControlPlaneError> { + for config in CHATONLY_PROVIDER_CONFIGS { + let binding = store.find_ai_external_conversation_binding( + user_id, + workspace_id, + session_id, + config.provider, + )?; + if binding.is_some() { + return Ok(binding); + } + } + Ok(None) +} + +fn provider_conversation_delete_url( + config: &ChatonlyProviderConfig, + conversation_id: &str, +) -> String { + let template = env_or_dotenv(config.delete_url_env) + .unwrap_or_else(|| config.default_delete_url.to_string()); + if template.contains("{conversationId}") { + return template.replace("{conversationId}", conversation_id); + } + format!( + "{}/{}", + template.trim_end_matches('/'), + conversation_id.trim_start_matches('/') + ) +} + +fn provider_conversation_lookup_url(config: &ChatonlyProviderConfig, session_id: &str) -> String { + let template = env_or_dotenv(config.lookup_url_env) + .unwrap_or_else(|| config.default_lookup_url.to_string()); + if template.contains("{sessionId}") { + return template.replace("{sessionId}", session_id); + } + format!( + "{}/{}", + template.trim_end_matches('/'), + session_id.trim_start_matches('/') + ) +} + +async fn request_provider_conversation_lookup( + config: &ChatonlyProviderConfig, + session_id: &str, +) -> Result, WebError> { + if session_id.trim().is_empty() { + return Ok(None); + } + let url = provider_conversation_lookup_url(config, session_id); + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(10)) + .build() + .map_err(|error| { + WebError::internal(format!("Provider 会话绑定查询 client 创建失败: {error}")) + })?; + let response = client.get(&url).send().await.map_err(|error| { + WebError::bad_gateway_code( + "provider_conversation_lookup_failed", + format!("Provider 会话绑定查询失败: {error}"), + ) + })?; + if response.status() == StatusCode::NOT_FOUND { + return Ok(None); + } + if !response.status().is_success() { + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + return Err(WebError::bad_gateway_code( + "provider_conversation_lookup_http_failed", + format!( + "Provider 会话绑定查询返回 HTTP {}: {}", + status.as_u16(), + body + ), + )); + } + let payload = response.json::().await.map_err(|error| { + WebError::bad_gateway_code( + "provider_conversation_lookup_json_failed", + format!("Provider 会话绑定查询 JSON 解析失败: {error}"), + ) + })?; + let has_remote_id = payload + .get("remoteConversationId") + .or_else(|| payload.get("remote_conversation_id")) + .and_then(Value::as_str) + .map(str::trim) + .is_some_and(|value| !value.is_empty()); + Ok(has_remote_id.then_some(payload)) +} + +async fn persist_provider_conversation_from_proxy( + state: &AppState, + context: &RequestContext, + registration: &HermesRunRegistration, + run_id: &str, + acp_runtime: &str, + acp_session_id: &str, + run_payload: &Value, +) -> Result<(), WebError> { + let Some(config) = chatonly_provider_for_run(run_payload, registration) else { + return Ok(()); + }; + let Some(mut provider_payload) = + request_provider_conversation_lookup(config, ®istration.session_id).await? + else { + return Ok(()); + }; + if provider_payload.get("provider").is_none() { + provider_payload["provider"] = Value::String(config.provider.to_string()); + } + if provider_payload.get("acpSessionId").is_none() && !acp_session_id.trim().is_empty() { + provider_payload["acpSessionId"] = Value::String(acp_session_id.to_string()); + } + persist_acp_runtime_event( + state, + context, + registration, + run_id, + acp_runtime, + "provider.conversation.bound", + &provider_payload, + run_payload, + ) + .await + .map(|_| ()) +} + +async fn request_provider_conversation_delete( + binding: &AiExternalConversationBindingRecord, +) -> Value { + let Some(config) = chatonly_provider_by_name(&binding.provider) else { + return json!({ + "attempted": false, + "status": "remote_delete_failed", + "provider": binding.provider, + "remoteConversationId": binding.remote_conversation_id, + "error": "不支持的 provider" + }); + }; + let remote_conversation_id = binding.remote_conversation_id.trim(); + if remote_conversation_id.is_empty() { + return json!({ + "attempted": false, + "status": "remote_delete_failed", + "provider": binding.provider, + "error": "remoteConversationId 为空" + }); + } + if binding.status != "active" { + return json!({ + "attempted": false, + "status": binding.status, + "provider": binding.provider, + "remoteConversationId": remote_conversation_id + }); + } + + let url = provider_conversation_delete_url(config, remote_conversation_id); + let client = match reqwest::Client::builder() + .timeout(Duration::from_secs(30)) + .build() + { + Ok(client) => client, + Err(error) => { + return json!({ + "attempted": false, + "status": "remote_delete_failed", + "provider": binding.provider, + "remoteConversationId": remote_conversation_id, + "error": error.to_string() + }); + } + }; + match client + .post(&url) + .json(&json!({ + "provider": binding.provider, + "remoteConversationId": remote_conversation_id + })) + .send() + .await + { + Ok(response) if response.status().is_success() => { + let http_status = response.status().as_u16(); + let body = response.text().await.unwrap_or_default(); + let response_json = serde_json::from_str::(&body).unwrap_or_else(|_| { + json!({ + "raw": body + }) + }); + json!({ + "attempted": true, + "status": "remote_deleted", + "provider": binding.provider, + "remoteConversationId": remote_conversation_id, + "httpStatus": http_status, + "url": url, + "response": response_json + }) + } + Ok(response) => { + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + json!({ + "attempted": true, + "status": "remote_delete_failed", + "provider": binding.provider, + "remoteConversationId": remote_conversation_id, + "httpStatus": status.as_u16(), + "url": url, + "error": body + }) + } + Err(error) => json!({ + "attempted": true, + "status": "remote_delete_failed", + "provider": binding.provider, + "remoteConversationId": remote_conversation_id, + "url": url, + "error": error.to_string() + }), + } +} + +async fn delete_provider_conversation_for_session( + store: &dyn control_plane::ControlPlaneStore, + user_id: &str, + workspace_id: Option<&str>, + session_id: &str, + binding: Option<&AiExternalConversationBindingRecord>, +) -> Result { + let Some(binding) = binding else { + return Ok(Value::Null); + }; + let result = request_provider_conversation_delete(binding).await; + let status = result + .get("status") + .and_then(Value::as_str) + .unwrap_or("remote_delete_failed"); + if matches!(status, "remote_deleted" | "remote_delete_failed") { + store.mark_ai_external_conversation_binding_status( + user_id, + workspace_id, + session_id, + &binding.provider, + status, + Some(&json_string(&json!({ + "reason": "mnote_session_deleted", + "providerDelete": result, + "updatedAt": now_ms() + }))), + )?; + } + Ok(result) +} + fn ai_runtime_run_to_json(record: &control_plane::AiRuntimeRunRecord) -> Value { let runtime = serde_json::from_str::(&record.runtime_json).unwrap_or(Value::Null); let payload = serde_json::from_str::(&record.payload_json).unwrap_or(Value::Null); @@ -6010,6 +8191,8 @@ async fn persist_acp_runtime_run( runtime_state, payload, ); + let mut legacy_session_storage: Option = None; + let mut legacy_persistence: Option<&'static str> = None; if payload .get("sourceKind") .and_then(Value::as_str) @@ -6054,13 +8237,12 @@ async fn persist_acp_runtime_run( share_id.as_deref(), ) .map_err(|error| error.with_context(context))?; - return Ok(json!({ - "ok": true, - "persistence": "local_ai_session_jsonl", - "sessionStorage": if share_id.is_some() { "local_shared" } else { "local_private" }, - "sessionId": registration.session_id, - "runId": run_id - })); + legacy_persistence = Some("local_ai_session_jsonl"); + legacy_session_storage = Some(if share_id.is_some() { + "local_shared".to_string() + } else { + "local_private".to_string() + }); } let workspace_id = args .get("workspaceId") @@ -6110,6 +8292,8 @@ async fn persist_acp_runtime_run( "ok": true, "persistence": ACP_RUNTIME_SQLITE_STORE, "sessionStorage": "sqlite_control_plane", + "legacyPersistence": legacy_persistence, + "legacySessionStorage": legacy_session_storage, "sessionId": record.session_id, "runId": record.run_id })) @@ -6173,6 +8357,8 @@ async fn persist_acp_runtime_event( event_payload, run_payload, ); + let mut legacy_session_storage: Option = None; + let mut legacy_persistence: Option<&'static str> = None; if run_payload .get("sourceKind") .and_then(Value::as_str) @@ -6216,13 +8402,12 @@ async fn persist_acp_runtime_event( share_id.as_deref(), ) .map_err(|error| error.with_context(context))?; - return Ok(json!({ - "ok": true, - "persistence": "local_ai_session_jsonl", - "sessionStorage": if share_id.is_some() { "local_shared" } else { "local_private" }, - "sessionId": registration.session_id, - "runId": run_id - })); + legacy_persistence = Some("local_ai_session_jsonl"); + legacy_session_storage = Some(if share_id.is_some() { + "local_shared".to_string() + } else { + "local_private".to_string() + }); } state .control_plane() @@ -6252,10 +8437,20 @@ async fn persist_acp_runtime_event( WebError::internal(format!("SQLite ACP runtime event 写入失败: {error}")) .with_context(context) })?; + persist_provider_conversation_event( + state, + context, + registration, + event_type, + event_payload, + run_payload, + )?; Ok(json!({ "ok": true, "persistence": ACP_RUNTIME_SQLITE_STORE, "sessionStorage": "sqlite_control_plane", + "legacyPersistence": legacy_persistence, + "legacySessionStorage": legacy_session_storage, "sessionId": registration.session_id, "runId": run_id })) @@ -6908,7 +9103,10 @@ mod tests { use axum::body::{to_bytes, Body}; use axum::http::Request; use axum::routing::{get, post}; - use control_plane::{DirectoryGrantInput, UpsertAiRuntimeRunInput, UpsertUserInput}; + use control_plane::{ + DirectoryGrantInput, UpsertAiExternalConversationBindingInput, UpsertAiRuntimeRunInput, + UpsertUserInput, + }; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, OnceLock}; use tower::util::ServiceExt; @@ -6935,6 +9133,410 @@ mod tests { fn clear_acp_run_payloads() { ACP_RUN_PAYLOADS.lock().expect("acp run payloads").clear(); + ACP_FINISHED_RUNS.lock().expect("acp finished runs").clear(); + } + + #[tokio::test] + async fn page_ai_agent_profiles_are_sqlite_user_scoped() { + let response = app() + .oneshot( + Request::builder() + .method("GET") + .uri("/api/ai/agent-profiles?agentId=hermes") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("response"); + assert_eq!(response.status(), StatusCode::OK); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + let profiles = payload["profiles"].as_array().expect("profiles"); + assert!(profiles.iter().any(|profile| profile["kind"] == "personal" + && profile["canManageSkills"] == true + && profile["ownerUserId"] == "user_1")); + let shared = profiles + .iter() + .find(|profile| profile["profileId"] == "shared_lite") + .expect("shared lite"); + assert_eq!(shared["kind"], "shared"); + assert_eq!(shared["canRun"], true); + assert_eq!(shared["canManageSkills"], false); + } + + #[tokio::test] + async fn page_ai_skill_toggle_respects_builtin_user_policy_and_shared_readonly() { + let _env_guard = env_lock().lock().expect("env lock"); + let hermes_home = std::env::temp_dir().join(format!( + "mnote-web-ai-profile-policy-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&hermes_home); + fs::create_dir_all(&hermes_home).expect("hermes home"); + for skill in [ + "global-search", + "officecli", + "vpn", + "writer", + "zhihu-search", + ] { + let skill_dir = hermes_home.join("skills").join(skill); + fs::create_dir_all(&skill_dir).expect("skill dir"); + fs::write( + skill_dir.join("SKILL.md"), + format!("---\ndescription: {skill}\n---\n"), + ) + .expect("skill"); + } + std::env::set_var("HERMES_HOME", &hermes_home); + let app = build_app(test_state()); + + let disable_builtin = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri("/api/hermes/client/skills/toggle") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "skillKind": "mnote_builtin", + "name": "mnote-current-page", + "enabled": false + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("disable builtin"); + assert_eq!(disable_builtin.status(), StatusCode::OK); + + let mnote_skills = app + .clone() + .oneshot( + Request::builder() + .method("GET") + .uri("/api/hermes/client/skills?runtime=mnote&agentId=hermes") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("mnote skills"); + assert_eq!(mnote_skills.status(), StatusCode::OK); + let body = to_bytes(mnote_skills.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + let current_page = payload["categories"] + .as_array() + .expect("categories") + .iter() + .flat_map(|category| category["skills"].as_array().into_iter().flatten()) + .find(|skill| skill["id"] == "mnote-current-page") + .expect("current page skill"); + assert_eq!(current_page["enabled"], false); + assert_eq!(current_page["configScope"], "user_sqlite"); + let mindmap_skill = payload["categories"] + .as_array() + .expect("categories") + .iter() + .flat_map(|category| category["skills"].as_array().into_iter().flatten()) + .find(|skill| skill["id"] == "mnote-mindmap") + .expect("mindmap skill"); + assert_eq!(mindmap_skill["enabled"], true); + assert!(mindmap_skill["toolNames"] + .as_array() + .expect("mindmap tool names") + .iter() + .any(|name| name == "mnote.mindmap.create_from_outline")); + + let shared_toggle = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri("/api/hermes/client/skills/toggle") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "profileId": "shared_lite", + "skillKind": "hermes_profile", + "name": "writer", + "enabled": false + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("shared toggle"); + assert_eq!(shared_toggle.status(), StatusCode::FORBIDDEN); + + let profiles = app + .clone() + .oneshot( + Request::builder() + .method("GET") + .uri("/api/ai/agent-profiles?agentId=hermes") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("profiles"); + let body = to_bytes(profiles.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("profiles json"); + let personal_id = payload["profiles"] + .as_array() + .expect("profiles") + .iter() + .find(|profile| profile["kind"] == "personal") + .and_then(|profile| profile["profileId"].as_str()) + .expect("personal profile") + .to_string(); + + for legacy_profile in ["mnoteai", "%E6%88%91%E7%9A%84%20Hermes"] { + let legacy_skills = app + .clone() + .oneshot( + Request::builder() + .method("GET") + .uri(format!( + "/api/hermes/client/skills?runtime=hermes&profileId={}", + legacy_profile + )) + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("legacy skills"); + assert_eq!(legacy_skills.status(), StatusCode::OK); + } + + let personal_skills = app + .clone() + .oneshot( + Request::builder() + .method("GET") + .uri(format!( + "/api/hermes/client/skills?runtime=hermes&profileId={personal_id}" + )) + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("personal skills"); + assert_eq!(personal_skills.status(), StatusCode::OK); + let body = to_bytes(personal_skills.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("personal skills json"); + let skills = payload["categories"] + .as_array() + .expect("categories") + .iter() + .flat_map(|category| category["skills"].as_array().into_iter().flatten()) + .map(|skill| { + ( + skill["name"].as_str().unwrap_or_default().to_string(), + skill["enabled"].as_bool().unwrap_or(false), + ) + }) + .collect::>(); + assert_eq!(skills.get("global-search"), Some(&true)); + assert_eq!(skills.get("vpn"), Some(&true)); + assert_eq!(skills.get("zhihu-search"), Some(&true)); + assert_eq!(skills.get("officecli"), None); + assert_eq!(skills.get("writer"), None); + assert_eq!(skills.len(), 3); + + let personal_config = fs::read_to_string( + hermes_home + .join("profiles") + .join("mnote-u-user-1-default") + .join("config.yaml"), + ) + .expect("personal config"); + assert!(personal_config.contains(MNOTE_PERSONAL_SKILL_BASELINE_MARKER)); + assert!( + !personal_config.contains("writer"), + "初始模板范围不应写入 skills.disabled" + ); + assert!( + !personal_config.contains("officecli"), + "初始模板范围不应写入 skills.disabled" + ); + + let personal_skill_dir = hermes_home + .join("profiles") + .join("mnote-u-user-1-default") + .join("skills"); + assert!(personal_skill_dir + .join("global-search") + .join("SKILL.md") + .exists()); + assert!(personal_skill_dir.join("vpn").join("SKILL.md").exists()); + assert!(personal_skill_dir + .join("zhihu-search") + .join("SKILL.md") + .exists()); + assert!(!personal_skill_dir.join("writer").join("SKILL.md").exists()); + fs::create_dir_all(personal_skill_dir.join("writer")).expect("writer dir"); + fs::write( + personal_skill_dir.join("writer").join("SKILL.md"), + "---\ndescription: writer\n---\n", + ) + .expect("profile writer skill"); + + let hidden_enable = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri("/api/hermes/client/skills/toggle") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "profileId": personal_id, + "skillKind": "hermes_profile", + "name": "writer", + "enabled": true + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("hidden skill enable"); + assert_eq!(hidden_enable.status(), StatusCode::OK); + + let customized_skills = app + .oneshot( + Request::builder() + .method("GET") + .uri(format!( + "/api/hermes/client/skills?runtime=hermes&profileId={personal_id}" + )) + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("customized skills"); + assert_eq!(customized_skills.status(), StatusCode::OK); + let body = to_bytes(customized_skills.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("customized skills json"); + let skills = payload["categories"] + .as_array() + .expect("categories") + .iter() + .flat_map(|category| category["skills"].as_array().into_iter().flatten()) + .map(|skill| { + ( + skill["name"].as_str().unwrap_or_default().to_string(), + skill["enabled"].as_bool().unwrap_or(false), + ) + }) + .collect::>(); + assert_eq!(skills.get("writer"), Some(&true)); + assert_eq!(skills.len(), 4); + + std::env::remove_var("HERMES_HOME"); + let _ = fs::remove_dir_all(&hermes_home); + } + + #[test] + fn reasonix_memory_policy_defaults_off_and_reads_user_preference() { + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: None, + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("user"); + let context = RequestContext { + trace: crate::context::TraceContext { + request_id: "req_reasonix_memory".into(), + trace_id: "trace_reasonix_memory".into(), + method: "POST".into(), + path: "/api/hermes/client/runs".into(), + }, + auth: crate::context::AuthContext { + authorization: None, + cookie_header: None, + actor_id: "user_1".into(), + actor_type: "user".into(), + session_id: None, + }, + workspace: crate::context::WorkspaceContext { + workspace_id: None, + tenant_id: None, + deployment_id: None, + project_id: None, + }, + source: crate::context::SourceContext { + channel: "test".into(), + client: "mnote-web-test".into(), + idempotency_key: None, + }, + }; + let payload = json!({"actorId": "user_1", "agentId": "reasonix"}); + let off_env = reasonix_memory_env_for_payload(&state, &context, &payload) + .expect("default memory env") + .expect("env"); + assert_eq!( + off_env.get("REASONIX_MEMORY").map(String::as_str), + Some("off") + ); + + state + .control_plane() + .upsert_user_ui_preference(control_plane::UpsertUserUiPreferenceInput { + id: None, + user_id: "user_1".to_string(), + workspace_id: None, + source_kind: None, + scope_kind: "page_ai_agent".to_string(), + scope_id: "reasonix".to_string(), + key: "ai.agent.reasonix.memory_enabled".to_string(), + value_json: "true".to_string(), + }) + .expect("memory preference"); + let on_env = reasonix_memory_env_for_payload(&state, &context, &payload) + .expect("enabled memory env") + .expect("env"); + assert_eq!( + on_env.get("REASONIX_MEMORY").map(String::as_str), + Some("on") + ); } #[test] @@ -6975,6 +9577,18 @@ mod tests { json["aiAccessScope"]["allowedRoots"][0]["rootUri"], "file:///mnt/Data1T/mnote" ); + assert_eq!( + json["agentRunEnvelope"]["schema"], + "mnote.agent_run_envelope.v1" + ); + assert_eq!( + json["agentRunEnvelope"]["primaryTarget"]["documentId"], + "local-md:Current.md" + ); + assert_eq!( + json["agentRunEnvelope"]["resultPolicy"]["receiptSchema"], + "mnote.agent_run_receipt.v1" + ); assert!(json["availableSkills"] .as_array() .unwrap() @@ -7154,6 +9768,478 @@ mod tests { build_app(AppState::new(config)) } + #[test] + fn chatonly_doubao_run_payload_injects_existing_provider_conversation() { + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: Some("user_1@example.com".to_string()), + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("seed user"); + state + .control_plane() + .upsert_ai_external_conversation_binding(UpsertAiExternalConversationBindingInput { + id: None, + user_id: "user_1".to_string(), + workspace_id: Some("ws_1".to_string()), + mnote_session_id: "sess_doubao".to_string(), + acp_session_id: Some("acp_sess_doubao".to_string()), + agent_id: "chat_only".to_string(), + profile: "openclaw-doubao-chat".to_string(), + provider: "doubao-web".to_string(), + remote_conversation_id: "38428454119180290".to_string(), + remote_url: Some("https://www.doubao.com/chat/38428454119180290".to_string()), + status: "active".to_string(), + metadata_json: "{}".to_string(), + }) + .expect("seed binding"); + let headers = HeaderMap::from_iter([( + "x-mnote-actor-id".parse().expect("header name"), + "user_1".parse().expect("header value"), + )]); + let context = RequestContext::from_http_parts( + &axum::http::Method::POST, + &"/api/hermes/client/runs".parse().expect("uri"), + &headers, + ); + let mut payload = json!({ + "agentId": "chat_only", + "profile": "openclaw-doubao-chat", + "sessionId": "sess_doubao", + "workspaceId": "ws_1", + "message": "继续刚才的话题" + }); + let registration = run_registration_from_payload(&context, &payload); + + inject_provider_conversation_binding_for_run( + state.control_plane(), + &context, + ®istration, + &mut payload, + ) + .expect("inject provider conversation"); + + assert_eq!(payload["providerConversation"]["provider"], "doubao-web"); + assert_eq!( + payload["providerConversation"]["remoteConversationId"], + "38428454119180290" + ); + assert_eq!( + payload["providerConversation"]["remoteUrl"], + "https://www.doubao.com/chat/38428454119180290" + ); + } + + #[test] + fn chatonly_doubao_prompt_includes_strip_compatible_mnote_context() { + let payload = json!({ + "actorId": "user_1", + "agentId": "chat_only", + "profile": "openclaw-doubao-chat", + "profileId": "shared_doubao_chat", + "sessionId": "sess_doubao", + "workspaceId": "ws_1", + "providerConversation": { + "provider": "doubao-web", + "remoteConversationId": "38428454119180290" + } + }); + let registration = HermesRunRegistration { + session_id: "sess_doubao".to_string(), + profile: "openclaw-doubao-chat".to_string(), + document_id: "current".to_string(), + trace_id: "trace_1".to_string(), + }; + + let prompt = chatonly_provider_prompt_text( + "请只回复:MNOTE_DOUBAO", + &payload, + ®istration, + "sess_doubao", + "run_1", + ); + + assert!(prompt.starts_with("Conversation info (untrusted metadata):\n```json\n")); + assert!(prompt.contains("\"mnoteSessionId\":\"sess_doubao\"")); + assert!(prompt.contains("\"remoteConversationId\":\"38428454119180290\"")); + assert!(prompt.ends_with("请只回复:MNOTE_DOUBAO")); + } + + #[test] + fn chatonly_provider_prompt_supports_deepseek_and_gemini_context() { + let cases = [ + ( + "openclaw-deepseek-chat", + "shared_deepseek_chat", + "deepseek-web", + "ds-session-1", + ), + ( + "openclaw-gemini-chat", + "shared_gemini_chat", + "gemini-web", + "https://gemini.google.com/app/gem-session-1", + ), + ]; + for (profile, profile_id, provider, remote_conversation_id) in cases { + let payload = json!({ + "actorId": "user_1", + "agentId": "chat_only", + "profile": profile, + "profileId": profile_id, + "sessionId": "sess_provider", + "workspaceId": "ws_1", + "providerConversation": { + "provider": provider, + "remoteConversationId": remote_conversation_id + } + }); + let registration = HermesRunRegistration { + session_id: "sess_provider".to_string(), + profile: profile.to_string(), + document_id: "current".to_string(), + trace_id: "trace_1".to_string(), + }; + + let prompt = chatonly_provider_prompt_text( + "请只回复:MNOTE_PROVIDER", + &payload, + ®istration, + "sess_provider", + "run_1", + ); + + assert!(prompt.contains("\"schema\":\"mnote.provider_chat_context.v1\"")); + assert!(prompt.contains(&format!("\"provider\":\"{provider}\""))); + assert!(prompt.contains("\"mnoteSessionId\":\"sess_provider\"")); + assert!(prompt.contains(remote_conversation_id)); + assert!(prompt.ends_with("请只回复:MNOTE_PROVIDER")); + } + } + + #[tokio::test] + async fn provider_conversation_bound_event_persists_doubao_binding() { + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: Some("user_1@example.com".to_string()), + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("seed user"); + let headers = HeaderMap::from_iter([( + "x-mnote-actor-id".parse().expect("header name"), + "user_1".parse().expect("header value"), + )]); + let context = RequestContext::from_http_parts( + &axum::http::Method::POST, + &"/api/hermes/client/runs/run_1/events".parse().expect("uri"), + &headers, + ); + let registration = HermesRunRegistration { + session_id: "sess_doubao".to_string(), + profile: "openclaw-doubao-chat".to_string(), + document_id: "current".to_string(), + trace_id: "trace_1".to_string(), + }; + let run_payload = json!({ + "actorId": "user_1", + "agentId": "chat_only", + "workspaceId": "ws_1", + "sessionId": "sess_doubao", + "profile": "openclaw-doubao-chat" + }); + + persist_acp_runtime_event( + &state, + &context, + ®istration, + "run_1", + "reasonix", + "provider.conversation.bound", + &json!({ + "provider": "doubao-web", + "remoteConversationId": "38428454119180290", + "remoteUrl": "https://www.doubao.com/chat/38428454119180290", + "acpSessionId": "acp_sess_doubao" + }), + &run_payload, + ) + .await + .expect("persist event"); + + let binding = state + .control_plane() + .find_ai_external_conversation_binding( + "user_1", + Some("ws_1"), + "sess_doubao", + "doubao-web", + ) + .expect("find binding") + .expect("binding exists"); + assert_eq!(binding.status, "active"); + assert_eq!(binding.remote_conversation_id, "38428454119180290"); + assert_eq!(binding.acp_session_id.as_deref(), Some("acp_sess_doubao")); + } + + #[tokio::test] + async fn provider_conversation_bound_event_persists_gemini_binding() { + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: Some("user_1@example.com".to_string()), + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("seed user"); + let headers = HeaderMap::from_iter([( + "x-mnote-actor-id".parse().expect("header name"), + "user_1".parse().expect("header value"), + )]); + let context = RequestContext::from_http_parts( + &axum::http::Method::POST, + &"/api/hermes/client/runs/run_1/events".parse().expect("uri"), + &headers, + ); + let registration = HermesRunRegistration { + session_id: "sess_gemini".to_string(), + profile: "openclaw-gemini-chat".to_string(), + document_id: "current".to_string(), + trace_id: "trace_1".to_string(), + }; + let run_payload = json!({ + "actorId": "user_1", + "agentId": "chat_only", + "workspaceId": "ws_1", + "sessionId": "sess_gemini", + "profile": "openclaw-gemini-chat" + }); + + persist_acp_runtime_event( + &state, + &context, + ®istration, + "run_1", + "hermes", + "provider.conversation.bound", + &json!({ + "provider": "gemini-web", + "remoteConversationId": "https://gemini.google.com/app/gem-session-1", + "remoteUrl": "https://gemini.google.com/app/gem-session-1", + "acpSessionId": "acp_sess_gemini" + }), + &run_payload, + ) + .await + .expect("persist event"); + + let binding = state + .control_plane() + .find_ai_external_conversation_binding( + "user_1", + Some("ws_1"), + "sess_gemini", + "gemini-web", + ) + .expect("find binding") + .expect("binding exists"); + assert_eq!(binding.status, "active"); + assert_eq!( + binding.remote_conversation_id, + "https://gemini.google.com/app/gem-session-1" + ); + assert_eq!(binding.acp_session_id.as_deref(), Some("acp_sess_gemini")); + } + + #[test] + fn chatonly_doubao_session_delete_marks_binding_local_deleted() { + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: Some("user_1@example.com".to_string()), + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("seed user"); + state + .control_plane() + .upsert_ai_external_conversation_binding(UpsertAiExternalConversationBindingInput { + id: None, + user_id: "user_1".to_string(), + workspace_id: Some("ws_1".to_string()), + mnote_session_id: "sess_doubao".to_string(), + acp_session_id: None, + agent_id: "chat_only".to_string(), + profile: "openclaw-doubao-chat".to_string(), + provider: "doubao-web".to_string(), + remote_conversation_id: "38428454119180290".to_string(), + remote_url: Some("https://www.doubao.com/chat/38428454119180290".to_string()), + status: "active".to_string(), + metadata_json: "{}".to_string(), + }) + .expect("seed binding"); + + let changed = mark_provider_conversation_local_deleted_for_session( + state.control_plane(), + "user_1", + Some("ws_1"), + "sess_doubao", + ) + .expect("mark local deleted"); + assert_eq!(changed, 1); + + let binding = state + .control_plane() + .find_ai_external_conversation_binding( + "user_1", + Some("ws_1"), + "sess_doubao", + "doubao-web", + ) + .expect("find binding") + .expect("binding exists"); + assert_eq!(binding.status, "local_deleted"); + assert!(binding.deleted_at.is_some()); + } + + #[tokio::test] + async fn chatonly_doubao_session_delete_calls_provider_and_marks_remote_deleted() { + let _env_guard = env_lock().lock().expect("env lock"); + let calls = Arc::new(Mutex::new(Vec::::new())); + let mock_calls = Arc::clone(&calls); + let mock = axum::Router::new().route( + "/delete/{conversation_id}", + post(move |Path(conversation_id): Path| { + let mock_calls = Arc::clone(&mock_calls); + async move { + mock_calls + .lock() + .expect("mock delete calls") + .push(conversation_id); + Json(json!({ "ok": true })) + } + }), + ); + let listener = tokio::net::TcpListener::bind("127.0.0.1:0") + .await + .expect("bind mock delete endpoint"); + let addr = listener.local_addr().expect("mock addr"); + tokio::spawn(async move { + axum::serve(listener, mock) + .await + .expect("mock delete endpoint"); + }); + std::env::set_var( + "MNOTE_WEB_DOUBAO_CONVERSATION_DELETE_URL", + format!("http://{addr}/delete/{{conversationId}}"), + ); + + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".to_string()), + email: Some("user_1@example.com".to_string()), + username: "user_1".to_string(), + display_name: "user_1".to_string(), + role: None, + password_hash: None, + }) + .expect("seed user"); + state + .control_plane() + .upsert_ai_runtime_run(UpsertAiRuntimeRunInput { + id: None, + user_id: "user_1".to_string(), + workspace_id: Some("ws_1".to_string()), + document_id: Some("doc_1".to_string()), + session_id: "sess_doubao".to_string(), + run_id: "run_1".to_string(), + title: None, + profile: "openclaw-doubao-chat".to_string(), + acp_runtime: "hermes".to_string(), + trace_id: Some("trace_1".to_string()), + status: "completed".to_string(), + runtime_json: "{\"status\":\"completed\"}".to_string(), + payload_json: "{\"message\":\"hello\"}".to_string(), + }) + .expect("seed runtime run"); + state + .control_plane() + .upsert_ai_external_conversation_binding(UpsertAiExternalConversationBindingInput { + id: None, + user_id: "user_1".to_string(), + workspace_id: Some("ws_1".to_string()), + mnote_session_id: "sess_doubao".to_string(), + acp_session_id: None, + agent_id: "chat_only".to_string(), + profile: "openclaw-doubao-chat".to_string(), + provider: "doubao-web".to_string(), + remote_conversation_id: "38428454119180290".to_string(), + remote_url: Some("https://www.doubao.com/chat/38428454119180290".to_string()), + status: "active".to_string(), + metadata_json: "{}".to_string(), + }) + .expect("seed binding"); + + let response = build_app(state.clone()) + .oneshot( + Request::builder() + .method("DELETE") + .uri("/api/hermes/client/sessions/sess_doubao?workspaceId=ws_1") + .header("x-mnote-actor-id", "user_1") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::OK); + let body: Value = + serde_json::from_slice(&to_bytes(response.into_body(), usize::MAX).await.unwrap()) + .expect("json body"); + assert_eq!( + body["result"]["providerConversationDelete"]["status"], + "remote_deleted" + ); + assert_eq!( + calls.lock().expect("mock calls").as_slice(), + ["38428454119180290"] + ); + + let binding = state + .control_plane() + .find_ai_external_conversation_binding( + "user_1", + Some("ws_1"), + "sess_doubao", + "doubao-web", + ) + .expect("find binding") + .expect("binding exists"); + assert_eq!(binding.status, "remote_deleted"); + std::env::remove_var("MNOTE_WEB_DOUBAO_CONVERSATION_DELETE_URL"); + } + fn seeded_acp_state() -> AppState { let state = AppState::new(AppConfig { service_name: "mnote-web".into(), @@ -7504,7 +10590,7 @@ mod tests { } #[tokio::test] - async fn hermes_client_local_acp_session_create_writes_private_jsonl() { + async fn hermes_client_local_acp_session_create_writes_sqlite_and_private_jsonl() { let root = std::env::temp_dir().join(format!( "mnote-local-ai-session-private-{}", std::process::id() @@ -7517,8 +10603,36 @@ mod tests { ) .expect("manifest"); let root_uri = format!("file://{}", root.display()); + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".into()), + email: Some("user_1@example.com".into()), + username: "user_1".into(), + display_name: "user_1".into(), + role: None, + password_hash: None, + }) + .expect("user"); + state + .control_plane() + .grant_directory_access(DirectoryGrantInput { + user_id: "user_1".into(), + workspace_id: None, + root_uri: root_uri.clone(), + root_path: root.display().to_string(), + permission: "write".into(), + recursive: true, + capabilities: vec!["local_files".into(), "ai_sessions".into()], + source: "test".into(), + created_by: Some("user_1".into()), + }) + .expect("grant write access"); - let response = app() + let app = build_app(state); + let response = app + .clone() .oneshot( Request::builder() .method("POST") @@ -7547,8 +10661,10 @@ mod tests { .await .expect("body"); let payload: Value = serde_json::from_slice(&body).expect("json"); - assert_eq!(payload["persistence"], "local_ai_session_jsonl"); - assert_eq!(payload["sessionStorage"], "local_private"); + assert_eq!(payload["persistence"], ACP_RUNTIME_SQLITE_STORE); + assert_eq!(payload["sessionStorage"], "sqlite_control_plane"); + assert_eq!(payload["legacyPersistence"], "local_ai_session_jsonl"); + assert_eq!(payload["legacySessionStorage"], "local_private"); let session_id = payload["sessionId"].as_str().expect("session id"); let jsonl_path = root .join("ai-sessions") @@ -7562,7 +10678,8 @@ mod tests { "/api/hermes/client/sessions?source=acp&sourceKind=local_folder&rootUri={}&workspaceId=local-ws-user-1&documentId=local-md%3AREADME.md", url_escape(&root_uri) ); - let list_response = app() + let list_response = app + .clone() .oneshot( Request::builder() .uri(list_uri) @@ -7578,7 +10695,8 @@ mod tests { .await .expect("list body"); let list_payload: Value = serde_json::from_slice(&list_body).expect("list json"); - assert_eq!(list_payload["persistence"], "local_ai_session_jsonl"); + assert_eq!(list_payload["persistence"], ACP_RUNTIME_SQLITE_STORE); + assert_eq!(list_payload["sessionStorage"], "sqlite_control_plane"); assert_eq!(list_payload["sessions"][0]["sessionId"], session_id); let detail_uri = format!( @@ -7586,7 +10704,8 @@ mod tests { session_id, url_escape(&root_uri) ); - let detail_response = app() + let detail_response = app + .clone() .oneshot( Request::builder() .uri(detail_uri) @@ -7602,14 +10721,17 @@ mod tests { .await .expect("detail body"); let detail_payload: Value = serde_json::from_slice(&detail_body).expect("detail json"); - assert_eq!(detail_payload["persistence"], "local_ai_session_jsonl"); - assert_eq!(detail_payload["events"][0]["eventType"], "session.created"); + assert_eq!(detail_payload["persistence"], ACP_RUNTIME_SQLITE_STORE); + assert_eq!( + detail_payload["session"]["runs"][0]["sessionId"], + session_id + ); let _ = fs::remove_dir_all(&root); } #[tokio::test] - async fn hermes_client_local_acp_run_writes_private_jsonl_without_convex() { + async fn hermes_client_local_acp_run_writes_sqlite_and_private_jsonl_without_convex() { let root = std::env::temp_dir().join(format!("mnote-local-ai-run-private-{}", std::process::id())); let _ = fs::remove_dir_all(&root); @@ -7620,8 +10742,34 @@ mod tests { ) .expect("manifest"); let root_uri = format!("file://{}", root.display()); + let state = test_state(); + state + .control_plane() + .upsert_user(UpsertUserInput { + id: Some("user_1".into()), + email: Some("user_1@example.com".into()), + username: "user_1".into(), + display_name: "user_1".into(), + role: None, + password_hash: None, + }) + .expect("user"); + state + .control_plane() + .grant_directory_access(DirectoryGrantInput { + user_id: "user_1".into(), + workspace_id: None, + root_uri: root_uri.clone(), + root_path: root.display().to_string(), + permission: "write".into(), + recursive: true, + capabilities: vec!["local_files".into(), "ai_sessions".into()], + source: "test".into(), + created_by: Some("user_1".into()), + }) + .expect("grant write access"); - let response = app() + let response = build_app(state) .oneshot( Request::builder() .method("POST") @@ -7651,8 +10799,10 @@ mod tests { .await .expect("body"); let payload: Value = serde_json::from_slice(&body).expect("json"); - assert_eq!(payload["persistence"], "local_ai_session_jsonl"); - assert_eq!(payload["sessionStorage"], "local_private"); + assert_eq!(payload["persistence"], ACP_RUNTIME_SQLITE_STORE); + assert_eq!(payload["sessionStorage"], "sqlite_control_plane"); + assert_eq!(payload["legacyPersistence"], "local_ai_session_jsonl"); + assert_eq!(payload["legacySessionStorage"], "local_private"); let jsonl_path = root .join("ai-sessions") .join("private") @@ -7732,8 +10882,9 @@ mod tests { .await .expect("body"); let payload: Value = serde_json::from_slice(&body).expect("json"); - assert_eq!(payload["persistence"], "local_ai_session_jsonl"); - assert_eq!(payload["sessionStorage"], "local_private"); + assert_eq!(payload["persistence"], ACP_RUNTIME_SQLITE_STORE); + assert_eq!(payload["sessionStorage"], "sqlite_control_plane"); + assert_eq!(payload["legacyPersistence"], "local_ai_session_jsonl"); let _ = fs::remove_dir_all(&root); } @@ -7813,7 +10964,8 @@ mod tests { .await .expect("body"); let payload: Value = serde_json::from_slice(&body).expect("json"); - assert_eq!(payload["sessionStorage"], "local_shared"); + assert_eq!(payload["sessionStorage"], "sqlite_control_plane"); + assert_eq!(payload["legacySessionStorage"], "local_shared"); let session_id = payload["sessionId"].as_str().expect("session id"); let jsonl_path = root .join("ai-sessions") @@ -9167,6 +12319,13 @@ mod tests { .contains("\"rootUri\":\"file:///mnt/Data1T/Mnote_data/users/user_1/我的空间\"")); assert!(instructions.contains("\"aiAccessScope\"")); assert!(instructions.contains("\"allowedRoots\"")); + assert!(instructions.contains("\"allowedFiles\":[\"README.md\"]")); + assert!(instructions.contains( + "\"allowedFilePaths\":[\"/mnt/Data1T/Mnote_data/users/user_1/我的空间/README.md\"]" + )); + assert!(instructions.contains("\"agentTargetPackage\"")); + assert!(instructions.contains("\"targetPackage\"")); + assert!(instructions.contains("\"resourceKind\":\"markdown_page\"")); assert!(instructions.contains("\"editorTarget\"")); assert!(instructions.contains("\"runTargetSnapshot\"")); assert!(instructions.contains("\"schema\":\"mnote.page_ai_run_target_snapshot.v1\"")); @@ -9260,9 +12419,11 @@ mod tests { }), ) .expect("body"); + let instructions_text = body["instructions"].as_str().expect("instructions"); + assert!(instructions_text.contains("onlyofficeSessionId 参数")); + assert!(instructions_text.contains("不得改用最近活跃 Office session")); let instructions: Value = - serde_json::from_str(body["instructions"].as_str().expect("instructions")) - .expect("instructions json"); + serde_json::from_str(instructions_text).expect("instructions json"); let envelope = &instructions["agentRunEnvelope"]; assert_eq!(envelope["schema"], "mnote.agent_run_envelope.v1"); assert_eq!(envelope["agentId"], "reasonix"); @@ -9276,6 +12437,15 @@ mod tests { assert_eq!(envelope["contextRefs"][0]["kind"], "active_editor"); assert_eq!(envelope["contextRefs"][0]["relativePath"], "README.md"); assert_eq!(envelope["allowedRoots"][0]["permission"], "write"); + assert_eq!(envelope["allowedFiles"][0], "README.md"); + assert_eq!( + envelope["targetPackage"]["currentFile"]["relativePath"], + "README.md" + ); + assert_eq!( + envelope["targetPackage"]["workspacePath"]["resourceKind"], + "markdown_page" + ); assert_eq!( envelope["resultPolicy"]["receiptSchema"], "mnote.agent_run_receipt.v1" @@ -9286,6 +12456,124 @@ mod tests { assert!(!envelope.to_string().contains("absolutePath")); } + #[test] + fn hermes_client_run_body_preserves_onlyoffice_target_scope() { + let mut headers = HeaderMap::new(); + headers.insert("x-mnote-actor-id", "user_1".parse().unwrap()); + headers.insert("x-mnote-actor-type", "user".parse().unwrap()); + let context = RequestContext::from_http_parts( + &axum::http::Method::POST, + &"/api/hermes/client/runs".parse().expect("uri"), + &headers, + ); + let body = build_run_upstream_body( + &context, + json!({ + "workspaceId": "local-workspace-1", + "documentId": "local-md:README.md", + "sessionId": "sess_local_office", + "runId": "run_local_office", + "sourceKind": "local_folder", + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "agentId": "reasonix", + "acpRuntime": "reasonix", + "allowedRoots": [{ + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "permission": "write", + "recursive": true + }], + "contextRefs": [{"kind": "active_editor"}], + "editorTarget": { + "schema": "mnote.ai_editor_target.v1", + "targetId": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "objectIdentity": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "documentId": "local-md:README.md", + "workspaceId": "local-workspace-1", + "editorKind": "office", + "resourceKind": "only_office", + "assetId": "local-file:office/report.docx", + "onlyofficeSessionId": "mnote-oo-session-a", + "workspacePath": { + "schema": "mnote.workspace_path.v1", + "workspaceId": "local-workspace-1", + "sourceKind": "local_folder", + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "relativePath": "office/report.docx", + "documentId": "local-md:README.md", + "objectIdentity": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "assetId": "local-file:office/report.docx", + "resourceKind": "only_office" + } + }, + "targetPackage": { + "schema": "mnote.agent_target_package.v1", + "primaryTargetId": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "workspaceId": "local-workspace-1", + "sourceKind": "local_folder", + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "documentId": "local-md:README.md", + "objectIdentity": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "resourceKind": "only_office", + "onlyofficeSessionId": "mnote-oo-session-a", + "workspacePath": { + "schema": "mnote.workspace_path.v1", + "workspaceId": "local-workspace-1", + "sourceKind": "local_folder", + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "relativePath": "office/report.docx", + "documentId": "local-md:README.md", + "objectIdentity": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "assetId": "local-file:office/report.docx", + "resourceKind": "only_office" + }, + "targets": [{ + "targetId": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "objectIdentity": "resource:onlyoffice:local-md:README.md:local-file:office/report.docx", + "documentId": "local-md:README.md", + "workspaceId": "local-workspace-1", + "sourceKind": "local_folder", + "rootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/我的空间", + "relativePath": "office/report.docx", + "resourceKind": "only_office", + "assetId": "local-file:office/report.docx", + "onlyofficeSessionId": "mnote-oo-session-a" + }] + }, + "message": "编辑 Office 资源", + "traceId": "trace_local_office" + }), + ) + .expect("body"); + let instructions: Value = + serde_json::from_str(body["instructions"].as_str().expect("instructions")) + .expect("instructions json"); + let scope = &instructions["aiAccessScope"]; + assert!(scope["allowedResourceIds"] + .as_array() + .expect("allowed resources") + .iter() + .any(|value| value == "local-file:office/report.docx")); + assert!(scope["allowedResourceIds"] + .as_array() + .expect("allowed resources") + .iter() + .any(|value| value + == "resource:onlyoffice:local-md:README.md:local-file:office/report.docx")); + assert!(scope["allowedResourceIds"] + .as_array() + .expect("allowed resources") + .iter() + .any(|value| value == "mnote-oo-session-a")); + assert_eq!( + instructions["agentTargetPackage"]["targets"][0]["onlyofficeSessionId"], + "mnote-oo-session-a" + ); + assert_eq!( + instructions["agentRunEnvelope"]["targetPackage"]["targets"][0]["assetId"], + "local-file:office/report.docx" + ); + } + #[test] fn capability_policy_does_not_text_classify_ack_prompt() { assert!( @@ -9749,7 +13037,7 @@ mod tests { } #[test] - fn hermes_client_run_guidance_prefers_markdown_edit_for_plain_body_edits() { + fn hermes_client_run_guidance_prefers_markdown_edit_only_for_remote_compat_plain_body_edits() { let context = RequestContext::from_http_parts( &axum::http::Method::POST, &"/api/hermes/client/runs".parse().expect("uri"), @@ -9774,9 +13062,9 @@ mod tests { ) .expect("body"); let instructions = body["instructions"].as_str().expect("instructions"); - assert!(instructions.contains("普通正文 search/replace、局部段落替换或全文 markdown 替换,应优先调用 mnote_doc_markdown_edit")); + assert!(instructions.contains("远端 / cloud / compat 普通正文 search/replace、局部段落替换或全文 markdown 替换,应优先调用 mnote_doc_markdown_edit")); assert!(instructions.contains( - "\"mnote_doc_markdown_edit for plain body search/replace or full markdown replacement\"" + "\"mnote_doc_markdown_edit for remote/cloud/compat plain body search/replace or full markdown replacement\"" )); assert!(!instructions.contains( "简单小段落编辑或同一页内多个普通叶子块操作,应优先用 mnote_doc_apply_block_ops" diff --git a/rust/crates/mnote-web/src/routes/hermes_tools.rs b/rust/crates/mnote-web/src/routes/hermes_tools.rs index 6d65a4a6..82a2039c 100644 --- a/rust/crates/mnote-web/src/routes/hermes_tools.rs +++ b/rust/crates/mnote-web/src/routes/hermes_tools.rs @@ -3,7 +3,8 @@ use crate::app::AppState; use crate::context::RequestContext; use crate::error::WebError; use crate::hermes_tools::{ - artifact, block, context_tools, doc, manifest, page, resource, skill, ToolCallInput, + artifact, block, context_tools, doc, manifest, onlyoffice_live, page, resource, skill, + ToolCallInput, }; use axum::extract::{Extension, Query, State}; use axum::http::{HeaderMap, HeaderName, HeaderValue, StatusCode}; @@ -373,8 +374,112 @@ pub(crate) async fn execute_mnote_tool_call( "mnote.page.update_options" => page::update_options(&state, &context, &input).await, "mnote.mindmap.fetch" => resource::mindmap_fetch(&context, &input).await, "mnote.mindmap.apply_ops" => resource::mindmap_apply_ops(&context, &input).await, + "mnote.mindmap.create_from_outline" => { + resource::mindmap_create_from_outline(&context, &input).await + } "mnote.office.fetch_summary" => resource::office_fetch_summary(&context, &input).await, "mnote.office.propose_changes" => resource::office_propose_changes(&context, &input).await, + "mnote.onlyoffice.session.current" => { + onlyoffice_live::session_current(&context, &input).await + } + "mnote.onlyoffice.capabilities" => onlyoffice_live::capabilities(&context, &input).await, + "mnote.onlyoffice.selection.get" => onlyoffice_live::selection_get(&context, &input).await, + "mnote.onlyoffice.document.insert_text" => { + onlyoffice_live::document_insert_text(&context, &input).await + } + "mnote.onlyoffice.document.replace_selection" => { + onlyoffice_live::document_replace_selection(&context, &input).await + } + "mnote.onlyoffice.document.insert_html" => { + onlyoffice_live::document_insert_html(&context, &input).await + } + "mnote.onlyoffice.document.export" => { + onlyoffice_live::document_export(&context, &input).await + } + "mnote.onlyoffice.document.search_replace" => { + onlyoffice_live::document_search_replace(&context, &input).await + } + "mnote.onlyoffice.document.insert_table" => { + onlyoffice_live::document_insert_table(&context, &input).await + } + "mnote.onlyoffice.document.get_comments" => { + onlyoffice_live::document_get_comments(&context, &input).await + } + "mnote.onlyoffice.document.add_comment" => { + onlyoffice_live::document_add_comment(&context, &input).await + } + "mnote.onlyoffice.sheet.get_sheets" => { + onlyoffice_live::sheet_get_sheets(&context, &input).await + } + "mnote.onlyoffice.sheet.add_sheet" => { + onlyoffice_live::sheet_add_sheet(&context, &input).await + } + "mnote.onlyoffice.sheet.rename_sheet" => { + onlyoffice_live::sheet_rename_sheet(&context, &input).await + } + "mnote.onlyoffice.sheet.get_range" => { + onlyoffice_live::sheet_get_range(&context, &input).await + } + "mnote.onlyoffice.sheet.get_range_values" => { + onlyoffice_live::sheet_get_range_values(&context, &input).await + } + "mnote.onlyoffice.sheet.get_values" => { + onlyoffice_live::sheet_get_values(&context, &input).await + } + "mnote.onlyoffice.sheet.set_value" => { + onlyoffice_live::sheet_set_value(&context, &input).await + } + "mnote.onlyoffice.sheet.set_formula" => { + onlyoffice_live::sheet_set_formula(&context, &input).await + } + "mnote.onlyoffice.sheet.batch_set_values" => { + onlyoffice_live::sheet_batch_set_values(&context, &input).await + } + "mnote.onlyoffice.sheet.set_range_values" => { + onlyoffice_live::sheet_set_range_values(&context, &input).await + } + "mnote.onlyoffice.sheet.format_range" => { + onlyoffice_live::sheet_format_range(&context, &input).await + } + "mnote.onlyoffice.sheet.set_dimensions" => { + onlyoffice_live::sheet_set_dimensions(&context, &input).await + } + "mnote.onlyoffice.sheet.sort_range" => { + onlyoffice_live::sheet_sort_range(&context, &input).await + } + "mnote.onlyoffice.sheet.add_chart" => { + onlyoffice_live::sheet_add_chart(&context, &input).await + } + "mnote.onlyoffice.presentation.get_slides" => { + onlyoffice_live::presentation_get_slides(&context, &input).await + } + "mnote.onlyoffice.presentation.get_slide_texts" => { + onlyoffice_live::presentation_get_slide_texts(&context, &input).await + } + "mnote.onlyoffice.presentation.get_shapes" => { + onlyoffice_live::presentation_get_shapes(&context, &input).await + } + "mnote.onlyoffice.presentation.add_text_slide" => { + onlyoffice_live::presentation_add_text_slide(&context, &input).await + } + "mnote.onlyoffice.presentation.replace_text" => { + onlyoffice_live::presentation_replace_text(&context, &input).await + } + "mnote.onlyoffice.presentation.set_shape_text" => { + onlyoffice_live::presentation_set_shape_text(&context, &input).await + } + "mnote.onlyoffice.presentation.delete_slide" => { + onlyoffice_live::presentation_delete_slide(&context, &input).await + } + "mnote.onlyoffice.presentation.add_table" => { + onlyoffice_live::presentation_add_table(&context, &input).await + } + "mnote.onlyoffice.presentation.clear_slide" => { + onlyoffice_live::presentation_clear_slide(&context, &input).await + } + "mnote.onlyoffice.presentation.add_shape" => { + onlyoffice_live::presentation_add_shape(&context, &input).await + } "mnote.artifact.create_summary" => artifact::create_summary(&state, &context, &input).await, "mnote.artifact.create_ai_note" => artifact::create_ai_note(&state, &context, &input).await, _ => Err( @@ -558,6 +663,18 @@ fn is_read_tool(tool_name: &str) -> bool { | "mnote.mindmap.fetch" | "mnote.office.fetch_summary" | "mnote.office.propose_changes" + | "mnote.onlyoffice.session.current" + | "mnote.onlyoffice.capabilities" + | "mnote.onlyoffice.selection.get" + | "mnote.onlyoffice.document.export" + | "mnote.onlyoffice.document.get_comments" + | "mnote.onlyoffice.sheet.get_sheets" + | "mnote.onlyoffice.sheet.get_range" + | "mnote.onlyoffice.sheet.get_range_values" + | "mnote.onlyoffice.sheet.get_values" + | "mnote.onlyoffice.presentation.get_slides" + | "mnote.onlyoffice.presentation.get_slide_texts" + | "mnote.onlyoffice.presentation.get_shapes" ) } @@ -847,6 +964,7 @@ mod tests { use serde_json::{json, Value}; use std::collections::BTreeMap; use std::fs; + use std::path::PathBuf; use std::sync::Mutex; use tower::util::ServiceExt; @@ -971,8 +1089,68 @@ mod tests { })) } + fn write_mindmap_apply_fixture(test_name: &str, content: Value) -> (PathBuf, String) { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-{test_name}-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + fs::write( + root.join("maps").join("idea.mindmap.json"), + serde_json::to_string_pretty(&content).expect("mindmap json"), + ) + .expect("mindmap"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + (root, root_uri) + } + + async fn post_mindmap_apply_ops( + root_uri: &str, + dry_run: bool, + args: Value, + id_suffix: &str, + ) -> axum::response::Response { + app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.apply_ops", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": format!("sess_mindmap_apply_{id_suffix}"), + "runId": format!("run_mindmap_apply_{id_suffix}"), + "toolCallId": format!("call_mindmap_apply_{id_suffix}"), + "traceId": format!("trace_mindmap_apply_{id_suffix}"), + "idempotencyKey": format!("idem_mindmap_apply_{id_suffix}"), + "dryRun": dry_run, + "args": args + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response") + } + async fn call_tool_ok(payload: Value) -> Value { - let response = app() + let app = app(); + maybe_register_onlyoffice_test_session(&app, &payload).await; + let response = app .oneshot( Request::builder() .method("POST") @@ -992,6 +1170,7 @@ mod tests { } async fn call_tool_ok_with_app(app: axum::Router, payload: Value) -> Value { + maybe_register_onlyoffice_test_session(&app, &payload).await; let response = app .oneshot( Request::builder() @@ -1011,6 +1190,67 @@ mod tests { serde_json::from_slice(&body).expect("json") } + async fn maybe_register_onlyoffice_test_session(app: &axum::Router, payload: &Value) { + let Some(tool_name) = payload.get("toolName").and_then(Value::as_str) else { + return; + }; + if !tool_name.starts_with("mnote.onlyoffice.") + || tool_name == "mnote.onlyoffice.capabilities" + || tool_name == "mnote.onlyoffice.session.current" + { + return; + } + let Some(session_id) = payload + .get("args") + .and_then(|args| { + args.get("onlyofficeSessionId") + .or_else(|| args.get("bridgeSessionId")) + }) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + else { + return; + }; + let allowed_resource_id = payload + .get("args") + .and_then(|args| args.get("aiAccessScope")) + .and_then(|scope| { + scope + .get("allowedResourceIds") + .or_else(|| scope.get("allowed_resource_ids")) + }) + .and_then(Value::as_array) + .and_then(|values| values.iter().find_map(Value::as_str)) + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or(session_id); + let token = format!("token-{session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": session_id, + "token": token, + "editorType": "cell", + "documentId": "doc_1", + "assetId": allowed_resource_id, + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + } + async fn block_revision_ref(block_id: &str) -> String { let payload = call_tool_ok(json!({ "toolName": "mnote.doc.fetch", @@ -1150,12 +1390,94 @@ mod tests { assert!(tools .iter() .any(|tool| tool["name"] == "mnote.mindmap.apply_ops")); + let mindmap_create = tools + .iter() + .find(|tool| tool["name"] == "mnote.mindmap.create_from_outline") + .expect("mindmap create_from_outline tool"); + assert_eq!( + mindmap_create["inputSchema"]["properties"]["outline"]["type"], + "array" + ); + assert!(mindmap_create["capabilityScope"] + .as_array() + .expect("capability scope") + .iter() + .any(|scope| scope == "mindmap.write")); assert!(tools .iter() .any(|tool| tool["name"] == "mnote.office.fetch_summary")); assert!(tools .iter() .any(|tool| tool["name"] == "mnote.office.propose_changes")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.session.current")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.capabilities")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.set_value")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.document.export")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.get_values")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.batch_set_values")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.document.search_replace")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.document.insert_table")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.document.get_comments")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.document.add_comment")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.get_sheets")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.get_range_values")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.set_range_values")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.format_range")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.set_dimensions")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.sort_range")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.sheet.add_chart")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.get_slide_texts")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.get_shapes")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.replace_text")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.set_shape_text")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.delete_slide")); + assert!(tools + .iter() + .any(|tool| tool["name"] == "mnote.onlyoffice.presentation.add_table")); let page_save = tools .iter() .find(|tool| tool["name"] == "mnote.page.save") @@ -1167,6 +1489,1312 @@ mod tests { ); } + #[tokio::test] + async fn hermes_tools_onlyoffice_session_current_reads_registered_bridge_session() { + let app = app(); + let bridge_session_id = format!("mnote-oo-tool-test-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "cell", + "documentId": "doc_meta", + "assetId": "asset_meta", + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let payload = call_tool_ok_with_app( + app, + json!({ + "toolName": "mnote.onlyoffice.session.current", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_current", + "runId": "run_oo_current", + "toolCallId": "call_oo_current", + "traceId": "trace_oo_current", + "capabilityScope": ["office.read"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "aiAccessScope": { + "permissionLevel": "read", + "allowedResourceIds": ["asset_meta"] + } + } + }), + ) + .await; + + assert_eq!(payload["result"]["schema"], "mnote.onlyoffice.session.v1"); + assert_eq!(payload["result"]["session"]["sessionId"], bridge_session_id); + assert_eq!(payload["result"]["session"]["editorType"], "cell"); + assert_eq!(payload["result"]["session"]["documentId"], "doc_meta"); + assert_eq!(payload["result"]["session"]["assetId"], "asset_meta"); + assert_eq!(payload["result"]["session"]["fileType"], "xlsx"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_session_current_requires_explicit_authorized_scope() { + let app = app(); + let bridge_session_id = format!("mnote-oo-current-scope-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "word", + "documentId": "doc_current_b", + "assetId": "asset_current_b", + "fileType": "docx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let implicit_response = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.session.current", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_current_implicit", + "runId": "run_oo_current_implicit", + "toolCallId": "call_oo_current_implicit", + "traceId": "trace_oo_current_implicit", + "capabilityScope": ["office.read"], + "args": { + "aiAccessScope": { + "permissionLevel": "read", + "allowedResourceIds": ["asset_current_b"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("implicit response"); + assert_eq!(implicit_response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + implicit_response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_session_explicit_required") + ); + + let forbidden_response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.session.current", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_current_forbidden", + "runId": "run_oo_current_forbidden", + "toolCallId": "call_oo_current_forbidden", + "traceId": "trace_oo_current_forbidden", + "capabilityScope": ["office.read"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "aiAccessScope": { + "permissionLevel": "read", + "allowedResourceIds": ["asset_current_a"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("forbidden response"); + assert_eq!(forbidden_response.status(), StatusCode::FORBIDDEN); + assert_eq!( + forbidden_response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_resource_scope_forbidden") + ); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_capabilities_lists_shape_and_range_actions() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.capabilities", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_caps", + "runId": "run_oo_caps", + "toolCallId": "call_oo_caps", + "traceId": "trace_oo_caps", + "capabilityScope": ["office.read"] + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.bridge_capabilities.v1" + ); + let actions = payload["result"]["actions"].as_array().expect("actions"); + assert!(actions + .iter() + .any(|action| action == "sheet.set_range_values")); + assert!(actions.iter().any(|action| action == "sheet.format_range")); + assert!(actions + .iter() + .any(|action| action == "sheet.set_dimensions")); + assert!(actions.iter().any(|action| action == "sheet.sort_range")); + assert!(actions.iter().any(|action| action == "sheet.add_chart")); + assert!(actions + .iter() + .any(|action| action == "presentation.set_shape_text")); + assert!(actions + .iter() + .any(|action| action == "presentation.delete_slide")); + assert!(actions + .iter() + .any(|action| action == "presentation.add_table")); + assert!(actions + .iter() + .any(|action| action == "presentation.clear_slide")); + assert!(actions + .iter() + .any(|action| action == "presentation.add_shape")); + assert!(actions + .iter() + .any(|action| action == "document.insert_table")); + assert!(actions + .iter() + .any(|action| action == "document.get_comments")); + assert!(actions + .iter() + .any(|action| action == "document.add_comment")); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_selection_get_round_trips_bridge_command() { + let app = app(); + let bridge_session_id = format!("mnote-oo-selection-test-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "word" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let worker_app = app.clone(); + let worker_session_id = bridge_session_id.clone(); + let worker = tokio::spawn(async move { + let next = worker_app + .clone() + .oneshot( + Request::builder() + .uri(format!( + "/api/onlyoffice/bridge/commands/next?sessionId={worker_session_id}&token={bridge_token}&timeoutMs=5000" + )) + .body(Body::empty()) + .expect("next request"), + ) + .await + .expect("next response"); + assert_eq!(next.status(), StatusCode::OK); + let body = to_bytes(next.into_body(), usize::MAX) + .await + .expect("next body"); + let command: Value = serde_json::from_slice(&body).expect("command json"); + assert_eq!(command["action"], "selection.get"); + let command_id = command["id"].as_str().expect("command id"); + + let posted = worker_app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/results") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": worker_session_id, + "token": bridge_token, + "id": command_id, + "ok": true, + "result": { + "editorType": "word", + "text": "选中文本" + } + }) + .to_string(), + )) + .expect("post result request"), + ) + .await + .expect("post result response"); + assert_eq!(posted.status(), StatusCode::OK); + }); + + let payload = call_tool_ok_with_app( + app, + json!({ + "toolName": "mnote.onlyoffice.selection.get", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_select", + "runId": "run_oo_select", + "toolCallId": "call_oo_select", + "traceId": "trace_oo_select", + "capabilityScope": ["office.read"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "aiAccessScope": { + "permissionLevel": "read", + "allowedResourceIds": [bridge_session_id] + }, + "timeoutMs": 5000 + } + }), + ) + .await; + worker.await.expect("worker"); + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_result.v1" + ); + assert_eq!(payload["result"]["action"], "selection.get"); + assert_eq!(payload["result"]["result"]["text"], "选中文本"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_write_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.set_value", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_sheet", + "runId": "run_oo_sheet", + "toolCallId": "call_oo_sheet", + "traceId": "trace_oo_sheet", + "idempotencyKey": "idem_oo_sheet", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "address": "A1", + "value": "after" + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.set_value"); + assert_eq!(payload["result"]["payload"]["address"], "A1"); + assert_eq!(payload["result"]["payload"]["value"], "after"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_write_tool_rejects_implicit_current_session() { + let app = app(); + let bridge_session_id = format!("mnote-oo-implicit-write-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "cell", + "documentId": "doc_office", + "assetId": "asset_office", + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.sheet.set_value", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_implicit", + "runId": "run_oo_implicit", + "toolCallId": "call_oo_implicit", + "traceId": "trace_oo_implicit", + "idempotencyKey": "idem_oo_implicit", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "address": "A1", + "value": "after" + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_session_explicit_required") + ); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_read_tool_rejects_implicit_current_session() { + let app = app(); + let bridge_session_id = format!("mnote-oo-read-implicit-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "word", + "documentId": "doc_office", + "assetId": "asset_office", + "fileType": "docx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.document.export", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_read_implicit", + "runId": "run_oo_read_implicit", + "toolCallId": "call_oo_read_implicit", + "traceId": "trace_oo_read_implicit", + "capabilityScope": ["office.read"], + "args": { + "format": "markdown", + "aiAccessScope": { + "permissionLevel": "read", + "allowedResourceIds": ["asset_office"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_session_explicit_required") + ); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_write_tool_rejects_missing_resource_scope() { + let app = app(); + let bridge_session_id = format!("mnote-oo-missing-scope-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "cell", + "documentId": "doc_office", + "assetId": "asset_office", + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.sheet.set_value", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_missing_scope", + "runId": "run_oo_missing_scope", + "toolCallId": "call_oo_missing_scope", + "traceId": "trace_oo_missing_scope", + "idempotencyKey": "idem_oo_missing_scope", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "address": "A1", + "value": "after" + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::FORBIDDEN); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_resource_scope_required") + ); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_write_tool_requires_allowed_resource_scope() { + let app = app(); + let bridge_session_id = format!("mnote-oo-scope-write-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "cell", + "documentId": "doc_office", + "assetId": "asset_b", + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .body(Body::from( + json!({ + "toolName": "mnote.onlyoffice.sheet.set_value", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_scope", + "runId": "run_oo_scope", + "toolCallId": "call_oo_scope", + "traceId": "trace_oo_scope", + "idempotencyKey": "idem_oo_scope", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "address": "A1", + "value": "after", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["asset_a"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::FORBIDDEN); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_onlyoffice_resource_scope_forbidden") + ); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_write_tool_allows_authorized_resource_scope() { + let app = app(); + let bridge_session_id = format!("mnote-oo-scope-allow-{}", std::process::id()); + let bridge_token = format!("token-{bridge_session_id}"); + let register = app + .clone() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/onlyoffice/bridge/session") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "sessionId": bridge_session_id, + "token": bridge_token, + "editorType": "cell", + "documentId": "doc_office", + "assetId": "asset_allowed", + "fileType": "xlsx" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("register response"); + assert_eq!(register.status(), StatusCode::OK); + + let payload = call_tool_ok_with_app( + app, + json!({ + "toolName": "mnote.onlyoffice.sheet.set_value", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_scope_allow", + "runId": "run_oo_scope_allow", + "toolCallId": "call_oo_scope_allow", + "traceId": "trace_oo_scope_allow", + "idempotencyKey": "idem_oo_scope_allow", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": bridge_session_id, + "address": "A1", + "value": "after", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["resource:onlyoffice:doc_office:asset_allowed"] + } + } + }), + ) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["sessionId"], bridge_session_id); + assert_eq!(payload["result"]["action"], "sheet.set_value"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_batch_write_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.batch_set_values", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_batch", + "runId": "run_oo_batch", + "toolCallId": "call_oo_batch", + "traceId": "trace_oo_batch", + "idempotencyKey": "idem_oo_batch", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "startRow": 1, + "startCol": 2, + "values": [["A", "B"], ["C", "D"]] + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.batch_set_values"); + assert_eq!(payload["result"]["payload"]["startRow"], 1); + assert_eq!(payload["result"]["payload"]["startCol"], 2); + assert_eq!(payload["result"]["payload"]["values"][1][1], "D"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_range_write_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.set_range_values", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_range", + "runId": "run_oo_range", + "toolCallId": "call_oo_range", + "traceId": "trace_oo_range", + "idempotencyKey": "idem_oo_range", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "address": "B2:C3", + "values": [["A", "B"], ["C", "D"]] + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.set_range_values"); + assert_eq!(payload["result"]["payload"]["address"], "B2:C3"); + assert_eq!(payload["result"]["payload"]["values"][1][1], "D"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_search_replace_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.document.search_replace", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_doc_replace", + "runId": "run_oo_doc_replace", + "toolCallId": "call_oo_doc_replace", + "traceId": "trace_oo_doc_replace", + "idempotencyKey": "idem_oo_doc_replace", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "search": "old", + "replace": "new", + "matchCase": true + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "document.search_replace"); + assert_eq!(payload["result"]["payload"]["search"], "old"); + assert_eq!(payload["result"]["payload"]["replace"], "new"); + assert_eq!(payload["result"]["payload"]["matchCase"], true); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_insert_table_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.document.insert_table", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_table", + "runId": "run_oo_table", + "toolCallId": "call_oo_table", + "traceId": "trace_oo_table", + "idempotencyKey": "idem_oo_table", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "rows": 2, + "cols": 3, + "data": [["A", "B", "C"], ["1", "2", "3"]] + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "document.insert_table"); + assert_eq!(payload["result"]["payload"]["rows"], 2); + assert_eq!(payload["result"]["payload"]["cols"], 3); + assert_eq!(payload["result"]["payload"]["data"][1][2], "3"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_add_comment_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.document.add_comment", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_comment", + "runId": "run_oo_comment", + "toolCallId": "call_oo_comment", + "traceId": "trace_oo_comment", + "idempotencyKey": "idem_oo_comment", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "text": "Review this paragraph", + "author": "Hermes", + "target": "document_start" + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "document.add_comment"); + assert_eq!( + payload["result"]["payload"]["text"], + "Review this paragraph" + ); + assert_eq!(payload["result"]["payload"]["author"], "Hermes"); + assert_eq!(payload["result"]["payload"]["target"], "document_start"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_presentation_replace_text_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.replace_text", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_replace", + "runId": "run_oo_ppt_replace", + "toolCallId": "call_oo_ppt_replace", + "traceId": "trace_oo_ppt_replace", + "idempotencyKey": "idem_oo_ppt_replace", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "search": "Quarterly", + "replace": "Monthly", + "slideIndex": 0 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.replace_text"); + assert_eq!(payload["result"]["payload"]["search"], "Quarterly"); + assert_eq!(payload["result"]["payload"]["replace"], "Monthly"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 0); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_shape_text_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.set_shape_text", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_shape", + "runId": "run_oo_ppt_shape", + "toolCallId": "call_oo_ppt_shape", + "traceId": "trace_oo_ppt_shape", + "idempotencyKey": "idem_oo_ppt_shape", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "slideIndex": 0, + "shapeIndex": 1, + "text": "Precise shape text" + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.set_shape_text"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 0); + assert_eq!(payload["result"]["payload"]["shapeIndex"], 1); + assert_eq!(payload["result"]["payload"]["text"], "Precise shape text"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_sheet_format_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.format_range", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_sheet_format", + "runId": "run_oo_sheet_format", + "toolCallId": "call_oo_sheet_format", + "traceId": "trace_oo_sheet_format", + "idempotencyKey": "idem_oo_sheet_format", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "address": "B2:C3", + "bold": true, + "fillColor": "#FFE599", + "fontColor": "#CC0000", + "horizontalAlign": "center", + "numberFormat": "0.00" + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.format_range"); + assert_eq!(payload["result"]["payload"]["address"], "B2:C3"); + assert_eq!(payload["result"]["payload"]["bold"], true); + assert_eq!(payload["result"]["payload"]["fillColor"], "#FFE599"); + assert_eq!(payload["result"]["payload"]["fontColor"], "#CC0000"); + assert_eq!(payload["result"]["payload"]["horizontalAlign"], "center"); + assert_eq!(payload["result"]["payload"]["numberFormat"], "0.00"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_sheet_dimensions_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.set_dimensions", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_sheet_dimensions", + "runId": "run_oo_sheet_dimensions", + "toolCallId": "call_oo_sheet_dimensions", + "traceId": "trace_oo_sheet_dimensions", + "idempotencyKey": "idem_oo_sheet_dimensions", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "columnIndex": 2, + "columnWidth": 24, + "rowIndex": 3, + "rowHeight": 28 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.set_dimensions"); + assert_eq!(payload["result"]["payload"]["columnIndex"], 2); + assert_eq!(payload["result"]["payload"]["columnWidth"], 24.0); + assert_eq!(payload["result"]["payload"]["rowIndex"], 3); + assert_eq!(payload["result"]["payload"]["rowHeight"], 28.0); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_delete_slide_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.delete_slide", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_delete", + "runId": "run_oo_ppt_delete", + "toolCallId": "call_oo_ppt_delete", + "traceId": "trace_oo_ppt_delete", + "idempotencyKey": "idem_oo_ppt_delete", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "slideIndex": 1 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.delete_slide"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 1); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_sheet_sort_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.sort_range", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_sheet_sort", + "runId": "run_oo_sheet_sort", + "toolCallId": "call_oo_sheet_sort", + "traceId": "trace_oo_sheet_sort", + "idempotencyKey": "idem_oo_sheet_sort", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "address": "A1:B4", + "keyColumn": 2, + "order": "descending", + "header": true + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.sort_range"); + assert_eq!(payload["result"]["payload"]["address"], "A1:B4"); + assert_eq!(payload["result"]["payload"]["keyColumn"], 2); + assert_eq!(payload["result"]["payload"]["order"], "descending"); + assert_eq!(payload["result"]["payload"]["header"], true); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_sheet_chart_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.sheet.add_chart", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_sheet_chart", + "runId": "run_oo_sheet_chart", + "toolCallId": "call_oo_sheet_chart", + "traceId": "trace_oo_sheet_chart", + "idempotencyKey": "idem_oo_sheet_chart", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "address": "A1:B4", + "chartType": "bar", + "widthMm": 110, + "heightMm": 70 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "sheet.add_chart"); + assert_eq!(payload["result"]["payload"]["address"], "A1:B4"); + assert_eq!(payload["result"]["payload"]["chartType"], "bar"); + assert_eq!(payload["result"]["payload"]["widthMm"], 110.0); + assert_eq!(payload["result"]["payload"]["heightMm"], 70.0); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_presentation_table_tool_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.add_table", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_table", + "runId": "run_oo_ppt_table", + "toolCallId": "call_oo_ppt_table", + "traceId": "trace_oo_ppt_table", + "idempotencyKey": "idem_oo_ppt_table", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "slideIndex": 0, + "rows": 2, + "cols": 2, + "data": [["Metric", "Value"], ["Bridge", "PPT table"]] + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.add_table"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 0); + assert_eq!(payload["result"]["payload"]["rows"], 2); + assert_eq!(payload["result"]["payload"]["cols"], 2); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_presentation_clear_slide_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.clear_slide", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_clear", + "runId": "run_oo_ppt_clear", + "toolCallId": "call_oo_ppt_clear", + "traceId": "trace_oo_ppt_clear", + "idempotencyKey": "idem_oo_ppt_clear", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "slideIndex": 2 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.clear_slide"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 2); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + + #[tokio::test] + async fn hermes_tools_onlyoffice_presentation_shape_supports_dry_run_plan() { + let payload = call_tool_ok(json!({ + "toolName": "mnote.onlyoffice.presentation.add_shape", + "workspaceId": "ws_demo", + "documentId": "doc_1", + "actorId": "user_1", + "sessionId": "sess_oo_ppt_shape_add", + "runId": "run_oo_ppt_shape_add", + "toolCallId": "call_oo_ppt_shape_add", + "traceId": "trace_oo_ppt_shape_add", + "idempotencyKey": "idem_oo_ppt_shape_add", + "dryRun": true, + "capabilityScope": ["office.write"], + "args": { + "onlyofficeSessionId": "mnote-oo-dry-run", + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["mnote-oo-dry-run"] + }, + "slideIndex": 1, + "shapeType": "roundRect", + "text": "Bridge shape", + "fillColor": "#4F81BD", + "widthMm": 150, + "heightMm": 60 + } + })) + .await; + + assert_eq!( + payload["result"]["schema"], + "mnote.onlyoffice.action_plan.v1" + ); + assert_eq!(payload["result"]["action"], "presentation.add_shape"); + assert_eq!(payload["result"]["payload"]["slideIndex"], 1); + assert_eq!(payload["result"]["payload"]["shapeType"], "roundRect"); + assert_eq!(payload["result"]["payload"]["text"], "Bridge shape"); + assert_eq!(payload["result"]["payload"]["fillColor"], "#4F81BD"); + assert_eq!(payload["audit"]["effect"], "dry_run"); + } + #[tokio::test] async fn hermes_tools_manifest_describes_markdown_edit_write_contract() { let response = app() @@ -1215,6 +2843,47 @@ mod tests { .any(|rule| rule["required"] == json!(["full_content"]))); } + #[tokio::test] + async fn hermes_tools_manifest_describes_onlyoffice_live_scope() { + let response = app() + .oneshot( + Request::builder() + .uri("/api/hermes/tools/mnote/manifest") + .header("x-mnote-actor-id", "user_1") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("response"); + assert_eq!(response.status(), StatusCode::OK); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + let tools = payload["manifest"]["tools"].as_array().expect("tools"); + let write_tool = tools + .iter() + .find(|tool| tool["name"] == "mnote.onlyoffice.sheet.set_value") + .expect("onlyoffice write tool"); + let schema = &write_tool["inputSchema"]; + let required = schema["required"].as_array().expect("required"); + assert!(required.iter().any(|value| value == "aiAccessScope")); + assert!( + schema["properties"]["aiAccessScope"]["properties"]["allowedResourceIds"].is_object() + ); + assert_eq!( + schema["properties"]["aiAccessScope"]["properties"]["allowedResourceIds"]["minItems"], + 1 + ); + let any_of = schema["anyOf"].as_array().expect("anyOf"); + assert!(any_of + .iter() + .any(|rule| rule["required"] == json!(["onlyofficeSessionId"]))); + assert!(any_of + .iter() + .any(|rule| rule["required"] == json!(["bridgeSessionId"]))); + } + #[tokio::test] async fn hermes_tools_manifest_marks_write_tools_as_compat_fallbacks() { let response = app() @@ -1522,6 +3191,99 @@ mod tests { let _ = fs::remove_dir_all(&root); } + #[tokio::test] + async fn hermes_tools_mindmap_fetch_reads_default_envelope() { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-envelope-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + fs::write( + root.join("maps").join("default.mindmap.json"), + json!({ + "data": { + "children": [ + { + "data": { + "expand": true, + "isActive": false, + "text": "分支", + "uid": "node_1" + }, + "children": [] + } + ], + "data": { + "expand": true, + "isActive": false, + "text": "KMIND", + "uid": "root" + } + }, + "view": { + "state": { "scale": 1, "sx": 0, "sy": 0, "x": 0, "y": 0 }, + "transform": { "a": 1, "b": 0, "c": 0, "d": 1, "e": 0, "f": 0 } + } + }) + .to_string(), + ) + .expect("mindmap"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.fetch", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": "sess_mindmap_envelope", + "runId": "run_mindmap_envelope", + "toolCallId": "call_mindmap_envelope", + "traceId": "trace_mindmap_envelope", + "args": { + "mindmapId": "mind_envelope", + "resourcePath": "maps/default.mindmap.json", + "scope": "full_envelope", + "aiAccessScope": { + "permissionLevel": "shared_read", + "allowedResourceIds": ["mind_envelope"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::OK); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(payload["result"]["root"]["data"]["text"], "KMIND"); + assert_eq!(payload["result"]["nodes"][0]["id"], "root"); + assert_eq!(payload["result"]["nodes"][1]["text"], "分支"); + assert_eq!(payload["result"]["envelope"]["data"]["data"]["uid"], "root"); + let _ = fs::remove_dir_all(&root); + } + #[tokio::test] async fn hermes_tools_mindmap_apply_ops_shared_read_is_forbidden() { let root = std::env::temp_dir().join(format!( @@ -1591,6 +3353,635 @@ mod tests { let _ = fs::remove_dir_all(&root); } + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_writes_and_preserves_envelope_fields() { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-apply-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + fs::write( + root.join("maps").join("idea.mindmap.json"), + serde_json::to_string_pretty(&json!({ + "data": { + "data": { + "text": "中心主题", + "uid": "root", + "customRootField": "keep-root" + }, + "children": [ + { + "data": { + "text": "旧分支", + "uid": "node_1", + "style": { "color": "red" } + }, + "children": [] + } + ] + }, + "view": { "state": { "scale": 2 } }, + "unknownTop": { "keep": true } + })) + .expect("json"), + ) + .expect("mindmap"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.apply_ops", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": "sess_mindmap_apply", + "runId": "run_mindmap_apply", + "toolCallId": "call_mindmap_apply", + "traceId": "trace_mindmap_apply", + "idempotencyKey": "idem_mindmap_apply", + "dryRun": false, + "args": { + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [ + { "op": "updateText", "nodeId": "node_1", "text": "新分支" }, + { + "op": "insertChild", + "parentId": "root", + "node": { + "id": "node_new", + "text": "新子节点", + "metadata": { "sourceRefs": [{ "page": 1 }] } + } + } + ], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!( + payload["result"]["root"]["children"][0]["data"]["text"], + "新分支" + ); + assert_eq!( + payload["result"]["root"]["children"][1]["data"]["text"], + "新子节点" + ); + assert!(payload["result"]["changedFiles"] + .as_array() + .expect("changed files") + .iter() + .any(|value| value == "maps/idea.mindmap.json")); + + let written = fs::read_to_string(root.join("maps").join("idea.mindmap.json")) + .expect("written mindmap"); + let written: Value = serde_json::from_str(&written).expect("written json"); + assert_eq!(written["data"]["children"][0]["data"]["text"], "新分支"); + assert_eq!( + written["data"]["children"][0]["data"]["style"]["color"], + "red" + ); + assert_eq!(written["data"]["children"][1]["data"]["uid"], "node_new"); + assert_eq!(written["view"]["state"]["scale"], 2); + assert_eq!(written["unknownTop"]["keep"], true); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_rejects_stale_revision() { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-conflict-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + fs::write( + root.join("maps").join("idea.mindmap.json"), + r#"{"data":{"data":{"text":"中心主题","uid":"root"},"children":[]}}"#, + ) + .expect("mindmap"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.apply_ops", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": "sess_mindmap_conflict", + "runId": "run_mindmap_conflict", + "toolCallId": "call_mindmap_conflict", + "traceId": "trace_mindmap_conflict", + "idempotencyKey": "idem_mindmap_conflict", + "dryRun": false, + "args": { + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "expectedRevision": "stale-revision", + "ops": [{ "op": "updateText", "nodeId": "root", "text": "改名" }], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_resource_revision_conflict") + ); + let written = fs::read_to_string(root.join("maps").join("idea.mindmap.json")) + .expect("written mindmap"); + assert!(written.contains("中心主题")); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_deletes_child_node() { + let (root, root_uri) = write_mindmap_apply_fixture( + "delete-node", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [ + { "data": { "text": "保留节点", "uid": "keep" }, "children": [] }, + { "data": { "text": "删除节点", "uid": "remove_me" }, "children": [] } + ] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + false, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [{ "op": "deleteNode", "nodeId": "remove_me" }], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "delete_node", + ) + .await; + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!( + payload["result"]["root"]["children"] + .as_array() + .unwrap() + .len(), + 1 + ); + assert_eq!( + payload["result"]["root"]["children"][0]["data"]["uid"], + "keep" + ); + let written = + fs::read_to_string(root.join("maps").join("idea.mindmap.json")).expect("written"); + assert!(written.contains("保留节点")); + assert!(!written.contains("删除节点")); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_accepts_common_aliases() { + let (root, root_uri) = write_mindmap_apply_fixture( + "aliases", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [ + { "data": { "text": "旧标题", "uid": "child_1" }, "children": [] } + ] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + false, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [ + { "type": "update_node", "id": "child_1", "title": "别名更新" }, + { "action": "add-child", "nodeId": "root", "id": "alias_child", "title": "别名新增" } + ], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "aliases", + ) + .await; + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!( + payload["result"]["root"]["children"][0]["data"]["text"], + "别名更新" + ); + assert_eq!( + payload["result"]["root"]["children"][1]["data"]["uid"], + "alias_child" + ); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_dry_run_returns_diff_without_writing() { + let (root, root_uri) = write_mindmap_apply_fixture( + "dry-run", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + true, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [{ "op": "updateText", "nodeId": "root", "text": "dry-run 改名" }], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "dry_run", + ) + .await; + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!(payload["result"]["dryRun"], true); + assert_eq!(payload["result"]["diff"][0]["op"], "mindmap.apply_ops"); + let written = + fs::read_to_string(root.join("maps").join("idea.mindmap.json")).expect("written"); + assert!(written.contains("中心主题")); + assert!(!written.contains("dry-run 改名")); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_rejects_unsupported_op() { + let (root, root_uri) = write_mindmap_apply_fixture( + "unsupported-op", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + false, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [{ "op": "moveNode", "nodeId": "root" }], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "unsupported_op", + ) + .await; + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_resource_op_unsupported") + ); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_rejects_invalid_ops_payload() { + let (root, root_uri) = write_mindmap_apply_fixture( + "invalid-ops", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + false, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": { "op": "updateText", "nodeId": "root", "text": "bad" }, + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "invalid_ops", + ) + .await; + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_resource_ops_invalid") + ); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_apply_ops_rejects_root_delete() { + let (root, root_uri) = write_mindmap_apply_fixture( + "root-delete", + json!({ + "data": { + "data": { "text": "中心主题", "uid": "root" }, + "children": [] + } + }), + ); + + let response = post_mindmap_apply_ops( + &root_uri, + false, + json!({ + "mindmapId": "maps/idea.mindmap.json", + "resourcePath": "maps/idea.mindmap.json", + "ops": [{ "op": "deleteNode", "nodeId": "root" }], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/idea.mindmap.json"] + } + }), + "root_delete", + ) + .await; + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_eq!( + response + .headers() + .get("x-error-code") + .and_then(|value| value.to_str().ok()), + Some("mnote_resource_root_delete_forbidden") + ); + let written = + fs::read_to_string(root.join("maps").join("idea.mindmap.json")).expect("written"); + assert!(written.contains("中心主题")); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_create_from_outline_writes_default_envelope() { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-create-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.create_from_outline", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": "sess_mindmap_create", + "runId": "run_mindmap_create", + "toolCallId": "call_mindmap_create", + "traceId": "trace_mindmap_create", + "idempotencyKey": "idem_mindmap_create", + "dryRun": false, + "args": { + "mindmapId": "maps/generated.mindmap.json", + "resourcePath": "maps/generated.mindmap.json", + "embedIntoPage": false, + "title": "PDF 摘要导图", + "outline": [ + { + "text": "章节一", + "children": [ + { "text": "要点 1", "children": [] } + ] + } + ], + "sourceRefs": [ + { "kind": "pdf", "title": "source.pdf", "page": 1 } + ], + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/generated.mindmap.json"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!(payload["result"]["resourceKind"], "mindmap"); + assert_eq!(payload["result"]["root"]["data"]["text"], "PDF 摘要导图"); + assert_eq!( + payload["result"]["root"]["children"][0]["data"]["text"], + "章节一" + ); + assert_eq!(payload["result"]["envelope"]["data"]["data"]["uid"], "root"); + assert!(root.join("maps").join("generated.mindmap.json").exists()); + + let written = fs::read_to_string(root.join("maps").join("generated.mindmap.json")) + .expect("written mindmap"); + let written: Value = serde_json::from_str(&written).expect("written json"); + assert_eq!(written["data"]["data"]["text"], "PDF 摘要导图"); + assert_eq!(written["data"]["children"][0]["data"]["text"], "章节一"); + assert!(written["view"]["transform"].is_object()); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn hermes_tools_mindmap_create_from_outline_can_embed_into_local_markdown_page() { + let root = std::env::temp_dir().join(format!( + "mnote-resource-mindmap-create-embed-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("maps")).expect("maps"); + fs::write(root.join("README.md"), "# README\n").expect("markdown"); + let root_uri = format!("file://{}", root.display()); + crate::routes::local_folder_source::initialize_local_workspace_for_actor( + "user_1", &root_uri, + ) + .expect("workspace"); + + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/hermes/tools/mnote/call") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_1") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "toolName": "mnote.mindmap.create_from_outline", + "workspaceId": "local-ws-resource", + "documentId": "local-md:README.md", + "sourceKind": "local_folder", + "rootUri": root_uri, + "actorId": "user_1", + "sessionId": "sess_mindmap_create_embed", + "runId": "run_mindmap_create_embed", + "toolCallId": "call_mindmap_create_embed", + "traceId": "trace_mindmap_create_embed", + "idempotencyKey": "idem_mindmap_create_embed", + "dryRun": false, + "args": { + "mindmapId": "maps/generated-embed.mindmap.json", + "resourcePath": "maps/generated-embed.mindmap.json", + "title": "PDF 摘要导图", + "outline": [ + { "text": "章节一", "children": [] } + ], + "embedIntoPage": true, + "aiAccessScope": { + "permissionLevel": "read_write", + "allowedResourceIds": ["maps/generated-embed.mindmap.json"] + } + } + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(status, StatusCode::OK, "{payload}"); + assert_eq!(payload["result"]["embedResult"]["status"], "embedded"); + assert!(payload["result"]["changedFiles"] + .as_array() + .expect("changed files") + .iter() + .any(|value| value == "README.md")); + let markdown = fs::read_to_string(root.join("README.md")).expect("markdown"); + assert!(markdown.contains("[PDF 摘要导图](maps/generated-embed.mindmap.json)")); + let _ = fs::remove_dir_all(&root); + } + #[tokio::test] async fn hermes_tools_office_fetch_and_propose_changes_do_not_write_file() { let root = std::env::temp_dir().join(format!( diff --git a/rust/crates/mnote-web/src/routes/local_folder_source.rs b/rust/crates/mnote-web/src/routes/local_folder_source.rs index 4a3352e5..f0ab6f0e 100644 --- a/rust/crates/mnote-web/src/routes/local_folder_source.rs +++ b/rust/crates/mnote-web/src/routes/local_folder_source.rs @@ -8,8 +8,8 @@ use crate::page_aggregate::{ use crate::routes::local_markdown_parser::{ file_stem_title, parse_markdown_attachment_refs, parse_markdown_page, split_frontmatter, }; -use crate::routes::local_search_index; use crate::routes::snapshot_support::ProjectionSnapshot; +use crate::routes::{local_ocr, local_search_index}; use axum::extract::{Extension, Multipart, Path as AxumPath, Query, State}; use axum::http::{header, HeaderMap, HeaderValue, StatusCode}; use axum::Json; @@ -4076,8 +4076,13 @@ fn local_mindmap_file_name(mindmap_id: &str) -> String { fn is_local_mindmap_file_name(file_name: &str) -> bool { let trimmed = file_name.trim(); let lower = trimmed.to_ascii_lowercase(); + if !lower.ends_with(".json") { + return false; + } lower.ends_with(".mindmap.json") - || (trimmed.starts_with("思维导图") && lower.ends_with(".json")) + || lower.starts_with("mindmap-") + || lower.starts_with("mindmap_") + || trimmed.starts_with("思维导图") } fn resolve_local_mindmap_path( @@ -7395,6 +7400,9 @@ fn scan_markdown_page_tree( continue; } if is_markdown_file(&entry.file_name) { + if local_ocr::is_local_ocr_sidecar_relative_path(&entry.relative_path) { + continue; + } let markdown = fs::read_to_string(&entry.path).unwrap_or_default(); let parsed = parse_markdown_page(&markdown, &entry.file_name); let page_id = local_markdown_path_page_id(&entry.relative_path); @@ -8426,7 +8434,6 @@ fn editor_blocks_to_markdown_with_rewrite( lines.push(text); } else { let src = rewrite_local_open_url_to_markdown_relative(src, local_file_context) - .map(|value| markdown_href_for_relative_path(&value)) .unwrap_or_else(|| src.to_string()); lines.push(format!( "![{}]({})", @@ -10424,6 +10431,61 @@ fn main() {} let _ = std::fs::remove_dir_all(&root); } + #[test] + fn local_markdown_generated_mindmap_id_roundtrips_as_mindmap_block() { + let root = temp_root("mnote-local-markdown-generated-mindmap-roundtrip"); + init_workspace(&root); + std::fs::create_dir_all(root.join("Page")).expect("create page dir"); + std::fs::write(root.join("Page").join("Page.md"), "").expect("write md"); + let root_uri = format!("file://{}", root.display()); + + write_local_mindmap_data( + &root_uri, + "local-md:Page~2FPage.md", + "mindmap-123456", + serde_json::json!({"data":{"text":"中心主题"},"children":[]}), + false, + ) + .expect("write generated mindmap"); + + save_local_markdown_page( + &root_uri, + "local-md:Page~2FPage.md", + None, + &serde_json::json!([ + { + "type": "mindmap", + "props": { + "name": "思维导图", + "mindmapId": "mindmap-123456", + "rootNodeId": "root" + } + } + ]), + ) + .expect("save"); + + let saved = std::fs::read_to_string(root.join("Page").join("Page.md")).expect("read md"); + assert!(saved.contains("[思维导图](mindmap-123456.json)")); + + let aggregate = resolve_local_markdown_page_aggregate(&root_uri, "local-md:Page~2FPage.md") + .expect("aggregate"); + let mindmap = aggregate.body.content.as_array().expect("blocks")[0].clone(); + assert_eq!(mindmap["type"], "mindmap"); + assert_eq!(mindmap["props"]["sourcePath"], "mindmap-123456.json"); + assert_eq!(mindmap["props"]["mindmapId"], "mindmap-123456.json"); + assert_eq!( + aggregate.body.block_document["blocks"][0]["attrs"]["mindmapId"], + serde_json::json!("mindmap-123456.json") + ); + assert_eq!( + aggregate.body.block_document["blocks"][0]["attrs"]["sourcePath"], + serde_json::json!("mindmap-123456.json") + ); + + let _ = std::fs::remove_dir_all(&root); + } + #[test] fn local_workspace_access_rejects_owner_mismatch() { let root = temp_root("mnote-local-workspace-owner-mismatch"); @@ -12656,6 +12718,8 @@ fn main() {} std::fs::create_dir_all(root.join("Page")).expect("create page dir"); std::fs::write(root.join("Page").join("Page.md"), "").expect("write md"); std::fs::write(root.join("Page").join("思维导图123456.json"), "{}").expect("write mindmap"); + std::fs::write(root.join("Page").join("mindmap-123456.json"), "{}") + .expect("write generated mindmap"); std::fs::write(root.join("Page").join("report.docx"), b"docx").expect("write docx"); std::fs::write(root.join("Page").join("sheet.xlsx"), b"xlsx").expect("write xlsx"); std::fs::write(root.join("Page").join("slides.pptx"), b"pptx").expect("write pptx"); @@ -12687,6 +12751,17 @@ fn main() {} mindmap["resourceMeta"]["workspacePath"]["objectIdentity"]["assetId"].as_str(), Some("local-file:Page/思维导图123456.json") ); + let generated_mindmap = items + .iter() + .find(|item| item["title"].as_str() == Some("mindmap-123456.json")) + .expect("generated mindmap row"); + assert_eq!(generated_mindmap["rowKind"].as_str(), Some("asset")); + assert_eq!(generated_mindmap["iconHint"].as_str(), Some("mindmap")); + assert_eq!( + generated_mindmap["resourceMeta"]["workspacePath"]["objectIdentity"]["objectKind"] + .as_str(), + Some("mindmap") + ); let office = items .iter() @@ -13239,6 +13314,41 @@ fn main() {} let _ = std::fs::remove_dir_all(&root); } + #[test] + fn local_ocr_sidecar_is_filetree_resource_not_page_tree_document() { + let root = temp_root("mnote-local-ocr-sidecar-page-tree"); + init_workspace(&root); + let root_uri = format!("file://{}", root.display()); + std::fs::create_dir_all(root.join("docs").join("Page.ocr")).expect("ocr dir"); + std::fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + std::fs::write( + root.join("docs").join("Page.ocr").join("photo.png.ocr.md"), + "---\nmnote_ocr_version: 1\nprovider: mock\nmodel_version: vlm\nowner_document: ../Page.md\nsource_path: ./Page.assets/photo.png\nsource_root_relative_path: docs/Page.assets/photo.png\nsource_size: 3\nsource_mtime_ms: 1\nstatus: done\ncreated_at: 1\nupdated_at: 1\n---\n\nOCR-only-token\n", + ) + .expect("ocr markdown"); + + let file_tree = load_local_folder_file_tree_children_snapshot(&root_uri, "docs/Page.ocr") + .expect("file tree"); + let file_items = file_tree.projection["items"] + .as_array() + .expect("file items"); + assert!(file_items + .iter() + .any(|item| item["title"].as_str() == Some("photo.png.ocr.md"))); + + let page_tree = load_local_folder_page_tree_snapshot(&root_uri).expect("page tree"); + let page_items = page_tree.projection["items"] + .as_array() + .expect("page items"); + assert!(page_items + .iter() + .any(|item| item["documentId"].as_str() == Some("local-md:docs~2FPage.md"))); + assert!(!page_items.iter().any(|item| item["documentId"].as_str() + == Some("local-md:docs~2FPage.ocr~2Fphoto.png.ocr.md"))); + + let _ = std::fs::remove_dir_all(&root); + } + #[test] fn local_rename_markdown_page_renames_nested_bundle() { let root = temp_root("mnote-local-rename-nested-bundle"); diff --git a/rust/crates/mnote-web/src/routes/local_markdown_parser.rs b/rust/crates/mnote-web/src/routes/local_markdown_parser.rs index 7d50b83b..2982890c 100644 --- a/rust/crates/mnote-web/src/routes/local_markdown_parser.rs +++ b/rust/crates/mnote-web/src/routes/local_markdown_parser.rs @@ -915,10 +915,7 @@ fn link_mindmap<'a>(node: &'a AstNode<'a>) -> Option<(String, String)> { .and_then(|value| value.to_str()) .unwrap_or(target) .trim(); - let lower = file_name.to_ascii_lowercase(); - let is_mindmap = lower.ends_with(".mindmap.json") - || (file_name.starts_with("思维导图") && lower.ends_with(".json")); - if !is_mindmap { + if !is_local_mindmap_file_name(file_name) { return None; } let name = collect_plain_text(node).trim().to_string(); @@ -932,6 +929,18 @@ fn link_mindmap<'a>(node: &'a AstNode<'a>) -> Option<(String, String)> { )) } +fn is_local_mindmap_file_name(file_name: &str) -> bool { + let trimmed = file_name.trim(); + let lower = trimmed.to_ascii_lowercase(); + if !lower.ends_with(".json") { + return false; + } + lower.ends_with(".mindmap.json") + || lower.starts_with("mindmap-") + || lower.starts_with("mindmap_") + || trimmed.starts_with("思维导图") +} + fn markdown_ast_document_to_blocks(document: &MarkdownAstDocument) -> Value { Value::Array( document @@ -1239,6 +1248,25 @@ mod tests { assert_eq!(first["props"]["alt"].as_str(), Some("示例图片")); } + #[test] + fn markdown_mindmap_link_parses_generated_mindmap_json_as_mindmap_block() { + let blocks = markdown_to_blocks("[思维导图](mindmap-123456.json)\n"); + let first = blocks + .as_array() + .and_then(|items| items.first()) + .expect("first block"); + + assert_eq!(first["type"].as_str(), Some("mindmap")); + assert_eq!( + first["props"]["sourcePath"].as_str(), + Some("mindmap-123456.json") + ); + assert_eq!( + first["props"]["mindmapId"].as_str(), + Some("mindmap-123456.json") + ); + } + #[test] fn markdown_attachment_refs_parse_standard_href_variants() { let root = std::env::temp_dir().join(format!( diff --git a/rust/crates/mnote-web/src/routes/local_ocr.rs b/rust/crates/mnote-web/src/routes/local_ocr.rs new file mode 100644 index 00000000..dca480bc --- /dev/null +++ b/rust/crates/mnote-web/src/routes/local_ocr.rs @@ -0,0 +1,1881 @@ +use crate::app::AppState; +use crate::context::RequestContext; +use crate::error::WebError; +use crate::routes::local_folder_source::{ + decode_local_id_segment, encode_local_id_segment, + ensure_local_workspace_read_access_with_state, ensure_local_workspace_write_access_with_state, +}; +use axum::extract::{Extension, Query, State}; +use axum::http::{HeaderMap, StatusCode}; +use axum::Json; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use std::collections::{BTreeMap, HashMap}; +use std::fs; +use std::hash::{Hash, Hasher}; +use std::io::{Cursor, Read}; +use std::path::{Component, Path, PathBuf}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +const OCR_INDEX_VERSION: u32 = 1; +const DEFAULT_PROVIDER: &str = "mineru"; +const DEFAULT_MODEL_VERSION: &str = "vlm"; +const DEFAULT_MINERU_API_BASE_URL: &str = "https://mineru.net"; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct OcrJobRequest { + root_uri: String, + document_id: String, + #[serde(default)] + source_path: Option, + source_root_relative_path: String, + #[serde(default)] + provider: Option, + #[serde(default)] + force: bool, + #[serde(default)] + mock_markdown: Option, + #[serde(default)] + mock_error: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct OcrStatusQuery { + root_uri: String, + source_root_relative_path: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct OcrReadQuery { + root_uri: String, + ocr_root_relative_path: String, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct OcrInsertRequest { + root_uri: String, + document_id: String, + ocr_root_relative_path: String, + #[serde(default)] + mode: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct OcrIndex { + version: u32, + #[serde(default)] + entries: BTreeMap, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct OcrIndexEntry { + pub(crate) job_id: String, + pub(crate) owner_document_id: String, + pub(crate) owner_document_path: String, + pub(crate) source_root_relative_path: String, + pub(crate) ocr_root_relative_path: String, + pub(crate) provider: String, + pub(crate) model_version: String, + pub(crate) status: String, + pub(crate) source_size: u64, + pub(crate) source_mtime_ms: u128, + pub(crate) created_at_ms: u128, + pub(crate) updated_at_ms: u128, + #[serde(default)] + pub(crate) plain_text_preview: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub(crate) error: Option, +} + +#[derive(Debug, Clone)] +struct SourceMetadata { + size: u64, + mtime_ms: u128, +} + +#[derive(Debug, Clone)] +struct MineruClientConfig { + api_base_url: String, + token: String, + model_version: String, + poll_interval: Duration, + max_polls: usize, +} + +#[derive(Debug, Clone)] +struct OcrSidecarPlan { + owner_document_path: String, + source_root_relative_path: String, + ocr_root_relative_path: String, + ocr_path: PathBuf, + provider: String, + model_version: String, + source_size: u64, + source_mtime_ms: u128, +} + +#[derive(Debug, Clone)] +pub(crate) struct OcrFrontmatter { + pub provider: String, + pub owner_document: String, + pub source_path: String, + pub source_root_relative_path: String, + pub source_size: u64, + pub source_mtime_ms: u128, + pub status: String, +} + +pub(crate) async fn create_job( + State(state): State, + Extension(context): Extension, + Json(body): Json, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + let root_uri = body.root_uri.trim(); + let root = ensure_local_workspace_write_access_with_state(&state, &context, root_uri) + .map_err(|error| error.with_context(&context))?; + let provider = body + .provider + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or(DEFAULT_PROVIDER); + let token = if provider != "mock" { + Some(mineru_token().ok_or_else(|| { + WebError::new( + StatusCode::UNAUTHORIZED, + "mineru_token_missing", + "缺少 MinerU API token", + ) + .with_context(&context) + })?) + } else { + None + }; + if provider != "mock" && token.is_none() { + return Err(WebError::new( + StatusCode::UNAUTHORIZED, + "mineru_token_missing", + "缺少 MinerU API token", + ) + .with_context(&context)); + } + let source_relative = body.source_root_relative_path.trim().replace('\\', "/"); + let _source_path_hint = body + .source_path + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or(&source_relative); + let plan = plan_ocr_sidecar_path( + &root, + &body.document_id, + &source_relative, + provider, + DEFAULT_MODEL_VERSION, + body.force, + )?; + let now = now_ms(); + if let Some(error) = body.mock_error.as_deref() { + let entry = build_index_entry(&plan, "failed", now, "", Some(redact_error(error))); + upsert_ocr_index_entry(&root, entry.clone())?; + return Ok(ok_json( + &context, + json!({ + "ok": true, + "job": ocr_job_payload(&root, &entry), + }), + )); + } + let markdown = if provider == "mock" { + body.mock_markdown + .unwrap_or_else(|| format!("OCR mock result for {}", plan.source_root_relative_path)) + } else { + match run_mineru_ocr(&root, &plan, token.unwrap_or_default()).await { + Ok(markdown) => markdown, + Err(error) => { + let failed_entry = + build_index_entry(&plan, "failed", now, "", Some(redact_error(error.message()))); + upsert_ocr_index_entry(&root, failed_entry)?; + return Err(error.with_context(&context)); + } + } + }; + write_ocr_sidecar(&plan, &markdown, now)?; + let entry = build_index_entry(&plan, "done", now, &markdown, None); + upsert_ocr_index_entry(&root, entry.clone())?; + Ok(ok_json( + &context, + json!({ + "ok": true, + "job": ocr_job_payload(&root, &entry), + }), + )) +} + +pub(crate) async fn list_jobs( + State(state): State, + Extension(context): Extension, + Query(query): Query, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + let root = + ensure_local_workspace_read_access_with_state(&state, &context, query.root_uri.trim()) + .map_err(|error| error.with_context(&context))?; + let index = read_ocr_index(&root)?; + let jobs = index + .entries + .values() + .map(|entry| ocr_job_payload(&root, entry)) + .collect::>(); + Ok(ok_json(&context, json!({ "ok": true, "jobs": jobs }))) +} + +pub(crate) async fn status( + State(state): State, + Extension(context): Extension, + Query(query): Query, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + let root = + ensure_local_workspace_read_access_with_state(&state, &context, query.root_uri.trim()) + .map_err(|error| error.with_context(&context))?; + let source = query + .source_root_relative_path + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .ok_or_else(|| { + WebError::bad_request_code("local_ocr_source_required", "OCR 状态查询缺少来源路径") + .with_context(&context) + })?; + let index = read_ocr_index(&root)?; + let job = index + .entries + .get(source) + .map(|entry| ocr_job_payload(&root, entry)); + Ok(ok_json(&context, json!({ "ok": true, "job": job }))) +} + +pub(crate) async fn read( + State(state): State, + Extension(context): Extension, + Query(query): Query, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + let root = + ensure_local_workspace_read_access_with_state(&state, &context, query.root_uri.trim()) + .map_err(|error| error.with_context(&context))?; + let relative = normalize_relative_path(&query.ocr_root_relative_path)?; + if !is_local_ocr_sidecar_relative_path(&relative) { + return Err(WebError::bad_request_code( + "local_ocr_sidecar_invalid", + "OCR 读取目标不是 OCR sidecar", + ) + .with_context(&context)); + } + let path = root.join(&relative); + ensure_target_under_root(&root, &path, "local_ocr_read_root_escape")?; + let markdown = fs::read_to_string(&path).map_err(|error| { + WebError::bad_request_code( + "local_ocr_read_failed", + format!("无法读取 OCR Markdown {}: {error}", path.display()), + ) + .with_context(&context) + })?; + let frontmatter = parse_ocr_frontmatter(&markdown); + Ok(ok_json( + &context, + json!({ + "ok": true, + "markdown": markdown, + "frontmatter": frontmatter.map(ocr_frontmatter_payload), + "ocrRootRelativePath": relative, + }), + )) +} + +pub(crate) async fn insert( + State(state): State, + Extension(context): Extension, + Json(body): Json, +) -> Result<(StatusCode, HeaderMap, Json), WebError> { + let root = + ensure_local_workspace_write_access_with_state(&state, &context, body.root_uri.trim()) + .map_err(|error| error.with_context(&context))?; + let mode = body + .mode + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("link"); + if mode != "link" { + return Err(WebError::bad_request_code( + "local_ocr_insert_mode_unsupported", + "当前仅支持插入 OCR 链接", + ) + .with_context(&context)); + } + let owner_document_path = owner_document_path_from_id(&body.document_id)?; + let owner_path = root.join(&owner_document_path); + ensure_target_under_root(&root, &owner_path, "local_ocr_owner_root_escape") + .map_err(|error| error.with_context(&context))?; + if !owner_path.is_file() { + return Err(WebError::bad_request_code( + "local_ocr_owner_missing", + "OCR owner Markdown 不存在", + ) + .with_context(&context)); + } + let ocr_root_relative_path = normalize_relative_path(&body.ocr_root_relative_path)?; + if !is_local_ocr_sidecar_relative_path(&ocr_root_relative_path) { + return Err(WebError::bad_request_code( + "local_ocr_sidecar_invalid", + "OCR 插入目标不是 OCR sidecar", + ) + .with_context(&context)); + } + let ocr_path = root.join(&ocr_root_relative_path); + ensure_target_under_root(&root, &ocr_path, "local_ocr_read_root_escape") + .map_err(|error| error.with_context(&context))?; + if !ocr_path.is_file() { + return Err( + WebError::bad_request_code("local_ocr_read_failed", "OCR Markdown 不存在") + .with_context(&context), + ); + } + let current = fs::read_to_string(&owner_path).map_err(|error| { + WebError::bad_request_code( + "local_ocr_owner_read_failed", + format!( + "无法读取 OCR owner Markdown {}: {error}", + owner_path.display() + ), + ) + .with_context(&context) + })?; + let link_target = relative_from_owner_dir(&owner_document_path, &ocr_root_relative_path); + let label = ocr_link_label(&ocr_root_relative_path); + let inserted_markdown = format!("[OCR:{}]({})", label, link_target); + let mut next = current.trim_end_matches('\n').to_string(); + if next.is_empty() { + next.push_str(&inserted_markdown); + next.push('\n'); + } else { + next.push_str("\n\n"); + next.push_str(&inserted_markdown); + next.push('\n'); + } + fs::write(&owner_path, next).map_err(|error| { + WebError::bad_request_code( + "local_ocr_owner_write_failed", + format!( + "无法写入 OCR owner Markdown {}: {error}", + owner_path.display() + ), + ) + .with_context(&context) + })?; + Ok(ok_json( + &context, + json!({ + "ok": true, + "documentId": body.document_id, + "ownerDocumentPath": owner_document_path, + "ocrRootRelativePath": ocr_root_relative_path, + "insertedMarkdown": inserted_markdown, + }), + )) +} + +pub(crate) fn is_local_ocr_sidecar_relative_path(relative_path: &str) -> bool { + let normalized = relative_path.trim().replace('\\', "/"); + let path = Path::new(&normalized); + let Some(file_name) = path.file_name().and_then(|value| value.to_str()) else { + return false; + }; + let Some(parent_name) = path + .parent() + .and_then(|value| value.file_name()) + .and_then(|value| value.to_str()) + else { + return false; + }; + parent_name.ends_with(".ocr") && file_name.ends_with(".ocr.md") +} + +pub(crate) fn parse_ocr_frontmatter(markdown: &str) -> Option { + let trimmed = markdown.strip_prefix("---\n")?; + let end = trimmed.find("\n---")?; + let frontmatter = &trimmed[..end]; + let mut fields = HashMap::::new(); + for line in frontmatter.lines() { + let Some((key, value)) = line.split_once(':') else { + continue; + }; + fields.insert( + key.trim().to_string(), + value.trim().trim_matches('"').to_string(), + ); + } + if fields.get("mnote_ocr_version").map(String::as_str) != Some("1") { + return None; + } + Some(OcrFrontmatter { + provider: fields.get("provider")?.to_string(), + owner_document: fields.get("owner_document")?.to_string(), + source_path: fields.get("source_path")?.to_string(), + source_root_relative_path: fields.get("source_root_relative_path")?.to_string(), + source_size: fields.get("source_size")?.parse().ok()?, + source_mtime_ms: fields.get("source_mtime_ms")?.parse().ok()?, + status: fields.get("status")?.to_string(), + }) +} + +#[cfg(test)] +fn read_ocr_index_entry( + root: &Path, + source_root_relative_path: &str, +) -> Result, WebError> { + let source = normalize_relative_path(source_root_relative_path)?; + Ok(read_ocr_index(root)?.entries.remove(&source)) +} + +pub(crate) fn ocr_index_entries(root: &Path) -> Result, WebError> { + Ok(read_ocr_index(root)?.entries.into_values().collect()) +} + +pub(crate) fn strip_ocr_frontmatter(markdown: &str) -> &str { + let Some(trimmed) = markdown.strip_prefix("---\n") else { + return markdown; + }; + let Some(end) = trimmed.find("\n---") else { + return markdown; + }; + trimmed[end + 4..].trim_start_matches('\n') +} + +async fn run_mineru_ocr(root: &Path, plan: &OcrSidecarPlan, token: String) -> Result { + let config = MineruClientConfig { + api_base_url: mineru_api_base_url(), + token, + model_version: plan.model_version.clone(), + poll_interval: mineru_poll_interval(), + max_polls: mineru_max_polls(), + }; + let source_path = root.join(&plan.source_root_relative_path); + let bytes = fs::read(&source_path).map_err(|error| { + WebError::bad_request_code( + "mineru_source_read_failed", + format!( + "无法读取 MinerU OCR 来源文件 {}: {error}", + source_path.display() + ), + ) + })?; + let file_name = Path::new(&plan.source_root_relative_path) + .file_name() + .and_then(|value| value.to_str()) + .unwrap_or("source.pdf"); + let client = reqwest::Client::new(); + let upload = create_mineru_upload_task(&client, &config, file_name).await?; + upload_mineru_source(&client, &upload.upload_url, bytes).await?; + let zip_url = poll_mineru_result_zip_url(&client, &config, &upload.batch_id).await?; + let zip_bytes = download_mineru_result_zip(&client, &zip_url).await?; + extract_mineru_markdown_from_zip(&zip_bytes) +} + +#[derive(Debug)] +struct MineruUploadTask { + batch_id: String, + upload_url: String, +} + +async fn create_mineru_upload_task( + client: &reqwest::Client, + config: &MineruClientConfig, + file_name: &str, +) -> Result { + let url = format!( + "{}/api/v4/file-urls/batch", + config.api_base_url.trim_end_matches('/') + ); + let payload = json!({ + "files": [{ "name": file_name, "data_id": short_hash(file_name) }], + "model_version": config.model_version, + }); + let response = client + .post(&url) + .bearer_auth(&config.token) + .json(&payload) + .send() + .await + .map_err(|error| { + WebError::bad_gateway_code( + "mineru_upload_task_failed", + format!("MinerU 上传任务创建失败: {}", redact_error(&error.to_string())), + ) + })?; + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + if !status.is_success() { + return Err(WebError::bad_gateway_code( + "mineru_upload_task_http_failed", + format!("MinerU 上传任务创建失败: HTTP {}", status.as_u16()), + )); + } + let value = parse_mineru_json(&body, "mineru_upload_task_json_invalid")?; + let batch_id = find_json_string_by_keys(&value, &["batch_id", "batchId", "id"]) + .ok_or_else(|| { + WebError::bad_gateway_code( + "mineru_upload_task_batch_missing", + "MinerU 上传任务响应缺少 batch_id", + ) + })?; + let upload_url = find_upload_url(&value).ok_or_else(|| { + WebError::bad_gateway_code( + "mineru_upload_url_missing", + "MinerU 上传任务响应缺少 upload_url", + ) + })?; + Ok(MineruUploadTask { + batch_id, + upload_url, + }) +} + +async fn upload_mineru_source( + client: &reqwest::Client, + upload_url: &str, + bytes: Vec, +) -> Result<(), WebError> { + let response = client + .put(upload_url) + .body(bytes) + .send() + .await + .map_err(|error| { + WebError::bad_gateway_code( + "mineru_source_upload_failed", + format!("MinerU 源文件上传失败: {}", redact_error(&error.to_string())), + ) + })?; + if !response.status().is_success() { + return Err(WebError::bad_gateway_code( + "mineru_source_upload_http_failed", + format!("MinerU 源文件上传失败: HTTP {}", response.status().as_u16()), + )); + } + Ok(()) +} + +async fn poll_mineru_result_zip_url( + client: &reqwest::Client, + config: &MineruClientConfig, + batch_id: &str, +) -> Result { + let url = format!( + "{}/api/v4/extract-results/batch/{}", + config.api_base_url.trim_end_matches('/'), + batch_id + ); + for _ in 0..config.max_polls.max(1) { + let response = client + .get(&url) + .bearer_auth(&config.token) + .send() + .await + .map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_poll_failed", + format!("MinerU 结果轮询失败: {}", redact_error(&error.to_string())), + ) + })?; + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + if !status.is_success() { + return Err(WebError::bad_gateway_code( + "mineru_result_poll_http_failed", + format!("MinerU 结果轮询失败: HTTP {}", status.as_u16()), + )); + } + let value = parse_mineru_json(&body, "mineru_result_poll_json_invalid")?; + if let Some(error_message) = mineru_result_error(&value) { + return Err(WebError::bad_gateway_code( + "mineru_result_failed", + format!("MinerU 识别失败: {}", redact_error(&error_message)), + )); + } + if let Some(zip_url) = find_json_string_by_keys( + &value, + &["full_zip_url", "fullZipUrl", "zip_url", "zipUrl", "result_url", "resultUrl"], + ) { + return Ok(zip_url); + } + tokio::time::sleep(config.poll_interval).await; + } + Err(WebError::gateway_timeout_code( + "mineru_result_poll_timeout", + "MinerU 识别结果轮询超时", + )) +} + +async fn download_mineru_result_zip( + client: &reqwest::Client, + zip_url: &str, +) -> Result, WebError> { + let response = client.get(zip_url).send().await.map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_download_failed", + format!("MinerU 结果包下载失败: {}", redact_error(&error.to_string())), + ) + })?; + if !response.status().is_success() { + return Err(WebError::bad_gateway_code( + "mineru_result_download_http_failed", + format!("MinerU 结果包下载失败: HTTP {}", response.status().as_u16()), + )); + } + response.bytes().await.map(|bytes| bytes.to_vec()).map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_download_failed", + format!("MinerU 结果包读取失败: {}", redact_error(&error.to_string())), + ) + }) +} + +fn extract_mineru_markdown_from_zip(bytes: &[u8]) -> Result { + let cursor = Cursor::new(bytes); + let mut archive = zip::ZipArchive::new(cursor).map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_zip_invalid", + format!("MinerU 结果包不是合法 zip: {error}"), + ) + })?; + let mut candidates = Vec::<(String, String)>::new(); + for index in 0..archive.len() { + let mut file = archive.by_index(index).map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_zip_read_failed", + format!("MinerU 结果包读取失败: {error}"), + ) + })?; + let name = file.name().replace('\\', "/"); + if !name.to_ascii_lowercase().ends_with(".md") || name.contains("/.") { + continue; + } + let mut markdown = String::new(); + file.read_to_string(&mut markdown).map_err(|error| { + WebError::bad_gateway_code( + "mineru_result_markdown_read_failed", + format!("MinerU Markdown 读取失败: {error}"), + ) + })?; + candidates.push((name, markdown)); + } + candidates + .into_iter() + .max_by_key(|(name, markdown)| { + let preferred = name.ends_with("/full.md") || name == "full.md" || name.ends_with("/result.md"); + (preferred, markdown.len()) + }) + .map(|(_, markdown)| markdown) + .filter(|markdown| !markdown.trim().is_empty()) + .ok_or_else(|| { + WebError::bad_gateway_code( + "mineru_result_markdown_missing", + "MinerU 结果包中缺少 Markdown 文件", + ) + }) +} + +fn parse_mineru_json(body: &str, code: &'static str) -> Result { + serde_json::from_str::(body).map_err(|error| { + WebError::bad_gateway_code(code, format!("MinerU 响应 JSON 解析失败: {error}")) + }) +} + +fn find_upload_url(value: &Value) -> Option { + if let Some(url) = find_json_string_by_keys(value, &["upload_url", "uploadUrl"]) { + return Some(url); + } + None +} + +fn find_json_string_by_keys(value: &Value, keys: &[&str]) -> Option { + match value { + Value::Object(map) => { + for key in keys { + if let Some(text) = map.get(*key).and_then(Value::as_str) { + let trimmed = text.trim(); + if !trimmed.is_empty() { + return Some(trimmed.to_string()); + } + } + } + for nested in map.values() { + if let Some(found) = find_json_string_by_keys(nested, keys) { + return Some(found); + } + } + None + } + Value::Array(items) => items + .iter() + .find_map(|item| find_json_string_by_keys(item, keys)), + _ => None, + } +} + +fn mineru_result_error(value: &Value) -> Option { + let status = find_json_string_by_keys(value, &["state", "status"]) + .unwrap_or_default() + .to_ascii_lowercase(); + if matches!( + status.as_str(), + "failed" | "fail" | "error" | "interrupted" | "canceled" | "cancelled" + ) { + return find_json_string_by_keys(value, &["error", "message", "msg", "err_msg", "errMsg"]) + .or_else(|| Some(status)); + } + None +} + +fn ok_json(context: &RequestContext, result: Value) -> (StatusCode, HeaderMap, Json) { + let mut headers = HeaderMap::new(); + if let Ok(value) = axum::http::HeaderValue::from_str(&context.trace.request_id) { + headers.insert("x-request-id", value); + } + (StatusCode::OK, headers, Json(result)) +} + +fn plan_ocr_sidecar_path( + root: &Path, + document_id: &str, + source_root_relative_path: &str, + provider: &str, + model_version: &str, + force: bool, +) -> Result { + let owner_document_path = owner_document_path_from_id(document_id)?; + let source_root_relative_path = normalize_relative_path(source_root_relative_path)?; + let source_path = root.join(&source_root_relative_path); + ensure_target_under_root(root, &source_path, "local_ocr_source_root_escape")?; + if !source_path.is_file() { + return Err(WebError::bad_request_code( + "local_ocr_source_missing", + "OCR 来源文件不存在", + )); + } + if !is_supported_ocr_source(&source_path) { + return Err(WebError::bad_request_code( + "local_ocr_source_type_unsupported", + "OCR 仅支持图片和 PDF", + )); + } + let owner_path = root.join(&owner_document_path); + ensure_target_under_root(root, &owner_path, "local_ocr_owner_root_escape")?; + if !owner_path.is_file() { + return Err(WebError::bad_request_code( + "local_ocr_owner_missing", + "OCR owner Markdown 不存在", + )); + } + let metadata = fs::metadata(&source_path).map_err(|error| { + WebError::bad_request_code( + "local_ocr_source_stat_failed", + format!( + "无法读取 OCR 来源文件状态 {}: {error}", + source_path.display() + ), + ) + })?; + let source_metadata = SourceMetadata { + size: metadata.len(), + mtime_ms: metadata + .modified() + .ok() + .and_then(|value| value.duration_since(UNIX_EPOCH).ok()) + .map(|value| value.as_millis()) + .unwrap_or_default(), + }; + let owner_parent = Path::new(&owner_document_path) + .parent() + .map(Path::to_path_buf) + .unwrap_or_default(); + let owner_stem = Path::new(&owner_document_path) + .file_stem() + .and_then(|value| value.to_str()) + .unwrap_or("Page"); + let ocr_dir = owner_parent.join(format!("{owner_stem}.ocr")); + let source_leaf = Path::new(&source_root_relative_path) + .file_name() + .and_then(|value| value.to_str()) + .unwrap_or("source"); + let base_file_name = format!("{source_leaf}.ocr.md"); + let mut ocr_relative = ocr_dir.join(&base_file_name); + let default_path = root.join(&ocr_relative); + if !force && default_path.exists() { + let suffix = short_hash(&format!( + "{}:{}:{}", + source_root_relative_path, source_metadata.size, source_metadata.mtime_ms + )); + ocr_relative = ocr_dir.join(format!("{source_leaf}-{suffix}.ocr.md")); + } + let ocr_root_relative_path = ocr_relative.to_string_lossy().replace('\\', "/"); + let ocr_path = root.join(&ocr_root_relative_path); + ensure_target_under_root(root, &ocr_path, "local_ocr_sidecar_root_escape")?; + Ok(OcrSidecarPlan { + owner_document_path, + source_root_relative_path, + ocr_root_relative_path, + ocr_path, + provider: provider.to_string(), + model_version: model_version.to_string(), + source_size: source_metadata.size, + source_mtime_ms: source_metadata.mtime_ms, + }) +} + +fn write_ocr_sidecar( + plan: &OcrSidecarPlan, + markdown_body: &str, + now: u128, +) -> Result<(), WebError> { + if let Some(parent) = plan.ocr_path.parent() { + fs::create_dir_all(parent).map_err(|error| { + WebError::bad_request_code( + "local_ocr_sidecar_create_failed", + format!("无法创建 OCR sidecar 目录 {}: {error}", parent.display()), + ) + })?; + } + let content = build_ocr_markdown(plan, markdown_body, "done", now); + fs::write(&plan.ocr_path, content).map_err(|error| { + WebError::bad_request_code( + "local_ocr_sidecar_write_failed", + format!("无法写入 OCR Markdown {}: {error}", plan.ocr_path.display()), + ) + }) +} + +fn build_ocr_markdown( + plan: &OcrSidecarPlan, + markdown_body: &str, + status: &str, + timestamp_ms: u128, +) -> String { + let owner_document = + relative_from_sidecar_dir(&plan.ocr_root_relative_path, &plan.owner_document_path); + let source_path = + relative_from_owner_dir(&plan.owner_document_path, &plan.source_root_relative_path); + let timestamp = timestamp_ms.to_string(); + format!( + "---\nmnote_ocr_version: 1\nprovider: {}\nmodel_version: {}\nowner_document: {}\nsource_path: {}\nsource_root_relative_path: {}\nsource_size: {}\nsource_mtime_ms: {}\nstatus: {}\ncreated_at: {}\nupdated_at: {}\n---\n\n{}\n", + plan.provider, + plan.model_version, + owner_document, + source_path, + plan.source_root_relative_path, + plan.source_size, + plan.source_mtime_ms, + status, + timestamp, + timestamp, + markdown_body.trim_end() + ) +} + +fn build_index_entry( + plan: &OcrSidecarPlan, + status: &str, + now: u128, + markdown: &str, + error: Option, +) -> OcrIndexEntry { + OcrIndexEntry { + job_id: format!( + "ocr_{}_{}", + now, + short_hash(&plan.source_root_relative_path) + ), + owner_document_id: format!( + "local-md:{}", + encode_local_id_segment(&plan.owner_document_path) + ), + owner_document_path: plan.owner_document_path.clone(), + source_root_relative_path: plan.source_root_relative_path.clone(), + ocr_root_relative_path: plan.ocr_root_relative_path.clone(), + provider: plan.provider.clone(), + model_version: plan.model_version.clone(), + status: status.to_string(), + source_size: plan.source_size, + source_mtime_ms: plan.source_mtime_ms, + created_at_ms: now, + updated_at_ms: now, + plain_text_preview: markdown.chars().take(240).collect(), + error, + } +} + +fn read_ocr_index(root: &Path) -> Result { + let path = ocr_index_path(root); + if !path.exists() { + return Ok(OcrIndex { + version: OCR_INDEX_VERSION, + entries: BTreeMap::new(), + }); + } + let content = fs::read_to_string(&path).map_err(|error| { + WebError::bad_request_code( + "local_ocr_index_read_failed", + format!("无法读取 OCR 索引 {}: {error}", path.display()), + ) + })?; + serde_json::from_str::(&content).map_err(|error| { + WebError::bad_request_code( + "local_ocr_index_invalid", + format!("OCR 索引格式非法 {}: {error}", path.display()), + ) + }) +} + +fn write_ocr_index(root: &Path, index: &OcrIndex) -> Result<(), WebError> { + let path = ocr_index_path(root); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent).map_err(|error| { + WebError::bad_request_code( + "local_ocr_index_create_failed", + format!("无法创建 OCR 索引目录 {}: {error}", parent.display()), + ) + })?; + } + let content = serde_json::to_vec_pretty(index) + .map_err(|error| WebError::internal(format!("OCR 索引序列化失败: {error}")))?; + let tmp = path.with_extension("json.tmp"); + fs::write(&tmp, [&content[..], b"\n"].concat()).map_err(|error| { + WebError::bad_request_code( + "local_ocr_index_write_failed", + format!("无法写入 OCR 临时索引 {}: {error}", tmp.display()), + ) + })?; + fs::rename(&tmp, &path).map_err(|error| { + WebError::bad_request_code( + "local_ocr_index_write_failed", + format!("无法替换 OCR 索引 {}: {error}", path.display()), + ) + }) +} + +fn upsert_ocr_index_entry(root: &Path, entry: OcrIndexEntry) -> Result<(), WebError> { + let mut index = read_ocr_index(root)?; + index.version = OCR_INDEX_VERSION; + index + .entries + .insert(entry.source_root_relative_path.clone(), entry); + write_ocr_index(root, &index) +} + +fn ocr_job_payload(root: &Path, entry: &OcrIndexEntry) -> Value { + let stale = source_is_stale(root, entry); + json!({ + "jobId": entry.job_id, + "ownerDocumentId": entry.owner_document_id, + "ownerDocumentPath": entry.owner_document_path, + "sourceRootRelativePath": entry.source_root_relative_path, + "ocrRootRelativePath": entry.ocr_root_relative_path, + "provider": entry.provider, + "modelVersion": entry.model_version, + "status": if stale && entry.status == "done" { "stale" } else { entry.status.as_str() }, + "stageLabel": stage_label(if stale && entry.status == "done" { "stale" } else { entry.status.as_str() }), + "stale": stale, + "updatedAtMs": entry.updated_at_ms, + "finishedAtMs": if matches!(entry.status.as_str(), "done" | "failed") { Some(entry.updated_at_ms) } else { None }, + "plainTextPreview": entry.plain_text_preview, + "error": entry.error, + }) +} + +fn source_is_stale(root: &Path, entry: &OcrIndexEntry) -> bool { + let source = root.join(&entry.source_root_relative_path); + let Ok(metadata) = fs::metadata(source) else { + return true; + }; + let mtime_ms = metadata + .modified() + .ok() + .and_then(|value| value.duration_since(UNIX_EPOCH).ok()) + .map(|value| value.as_millis()) + .unwrap_or_default(); + metadata.len() != entry.source_size || mtime_ms != entry.source_mtime_ms +} + +fn stage_label(status: &str) -> &'static str { + match status { + "queued" => "排队中", + "uploading" => "上传中", + "mineru_processing" => "识别中", + "downloading" => "下载中", + "writing_sidecar" => "写入中", + "done" => "已识别", + "failed" => "识别失败", + "interrupted" => "已中断", + "stale" => "来源已变化", + _ => "未知状态", + } +} + +fn ocr_frontmatter_payload(frontmatter: OcrFrontmatter) -> Value { + json!({ + "provider": frontmatter.provider, + "ownerDocument": frontmatter.owner_document, + "sourcePath": frontmatter.source_path, + "sourceRootRelativePath": frontmatter.source_root_relative_path, + "sourceSize": frontmatter.source_size, + "sourceMtimeMs": frontmatter.source_mtime_ms, + "status": frontmatter.status, + }) +} + +fn ocr_index_path(root: &Path) -> PathBuf { + root.join(".mnote").join("ocr-index.json") +} + +fn owner_document_path_from_id(document_id: &str) -> Result { + let encoded = document_id + .trim() + .strip_prefix("local-md:") + .ok_or_else(|| { + WebError::bad_request_code( + "local_ocr_owner_document_invalid", + "OCR owner documentId 必须是 local-md 路径型 ID", + ) + })?; + let decoded = decode_local_id_segment(encoded)?; + normalize_relative_path(&decoded) +} + +fn normalize_relative_path(value: &str) -> Result { + let normalized = value.trim().trim_start_matches('/').replace('\\', "/"); + if normalized.is_empty() { + return Err(WebError::bad_request_code( + "local_ocr_path_required", + "OCR 路径不能为空", + )); + } + let path = Path::new(&normalized); + if path.is_absolute() + || path.components().any(|component| { + matches!( + component, + Component::ParentDir | Component::RootDir | Component::Prefix(_) + ) + }) + { + return Err(WebError::bad_request_code( + "local_ocr_path_escape", + "OCR 相对路径不能越过 root", + )); + } + Ok(normalized) +} + +fn ensure_target_under_root( + root: &Path, + target: &Path, + code: &'static str, +) -> Result<(), WebError> { + let parent = target.parent().unwrap_or(root); + let canonical_parent = parent + .canonicalize() + .unwrap_or_else(|_| parent.to_path_buf()); + let canonical_root = root.canonicalize().unwrap_or_else(|_| root.to_path_buf()); + if !canonical_parent.starts_with(&canonical_root) { + return Err(WebError::bad_request_code(code, "OCR 路径不能越过 root")); + } + Ok(()) +} + +fn is_supported_ocr_source(path: &Path) -> bool { + let ext = path + .extension() + .and_then(|value| value.to_str()) + .unwrap_or_default() + .to_ascii_lowercase(); + matches!( + ext.as_str(), + "pdf" | "png" | "jpg" | "jpeg" | "webp" | "bmp" | "tif" | "tiff" + ) +} + +fn relative_from_owner_dir(owner_document_path: &str, source_root_relative_path: &str) -> String { + let owner_parent = Path::new(owner_document_path) + .parent() + .unwrap_or(Path::new("")); + Path::new(source_root_relative_path) + .strip_prefix(owner_parent) + .map(|value| format!("./{}", value.to_string_lossy().replace('\\', "/"))) + .unwrap_or_else(|_| source_root_relative_path.to_string()) +} + +fn relative_from_sidecar_dir(ocr_root_relative_path: &str, owner_document_path: &str) -> String { + let sidecar_parent = Path::new(ocr_root_relative_path) + .parent() + .unwrap_or_else(|| Path::new("")); + let owner = Path::new(owner_document_path); + let sidecar_components = sidecar_parent + .components() + .map(|component| component.as_os_str().to_string_lossy().to_string()) + .collect::>(); + let owner_components = owner + .components() + .map(|component| component.as_os_str().to_string_lossy().to_string()) + .collect::>(); + let common = sidecar_components + .iter() + .zip(owner_components.iter()) + .take_while(|(left, right)| left == right) + .count(); + let mut parts = Vec::::new(); + for _ in common..sidecar_components.len() { + parts.push("..".to_string()); + } + parts.extend(owner_components.into_iter().skip(common)); + if parts.is_empty() { + ".".to_string() + } else { + parts.join("/") + } +} + +fn short_hash(value: &str) -> String { + let mut hasher = std::collections::hash_map::DefaultHasher::new(); + value.hash(&mut hasher); + format!("{:x}", hasher.finish()).chars().take(6).collect() +} + +fn now_ms() -> u128 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|value| value.as_millis()) + .unwrap_or_default() +} + +fn redact_error(error: &str) -> String { + let text = error.trim().replace('\n', " "); + let lower = text.to_ascii_lowercase(); + if lower.contains("token") || lower.contains("signature") || lower.contains("x-oss-") { + return "provider_error_redacted".to_string(); + } + text.chars().take(160).collect() +} + +fn ocr_link_label(ocr_root_relative_path: &str) -> String { + Path::new(ocr_root_relative_path) + .file_name() + .and_then(|value| value.to_str()) + .unwrap_or("OCR") + .trim_end_matches(".ocr.md") + .replace(['[', ']'], "") +} + +fn mineru_token() -> Option { + std::env::var("MNOTE_MINERU_API_TOKEN") + .ok() + .or_else(|| std::env::var("MINERU_API_TOKEN").ok()) + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) +} + +fn mineru_api_base_url() -> String { + std::env::var("MNOTE_MINERU_API_BASE_URL") + .ok() + .or_else(|| std::env::var("MINERU_API_BASE_URL").ok()) + .map(|value| value.trim().trim_end_matches('/').to_string()) + .filter(|value| !value.is_empty()) + .unwrap_or_else(|| DEFAULT_MINERU_API_BASE_URL.to_string()) +} + +fn mineru_poll_interval() -> Duration { + std::env::var("MNOTE_MINERU_POLL_INTERVAL_MS") + .ok() + .and_then(|value| value.trim().parse::().ok()) + .filter(|value| *value > 0) + .map(Duration::from_millis) + .unwrap_or_else(|| Duration::from_secs(2)) +} + +fn mineru_max_polls() -> usize { + std::env::var("MNOTE_MINERU_MAX_POLLS") + .ok() + .and_then(|value| value.trim().parse::().ok()) + .filter(|value| *value > 0) + .unwrap_or(90) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::app::{build_app, AppConfig, AppState}; + use axum::body::{to_bytes, Body}; + use axum::http::Request; + use std::io::Write as _; + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::sync::Arc; + use tower::util::ServiceExt; + + fn temp_root(name: &str) -> PathBuf { + let root = std::env::temp_dir().join(format!("{name}-{}", std::process::id())); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("docs").join("Page.assets")).expect("create assets"); + fs::create_dir_all(root.join(".mnote")).expect("create metadata"); + root + } + + fn app() -> axum::Router { + build_app(AppState::new(AppConfig { + service_name: "mnote-web".into(), + service_version: "0.1.0".into(), + bind_addr: "127.0.0.1:0".into(), + public_bind_addr: "127.0.0.1:3000".into(), + legacy_next_base_url: Some("http://127.0.0.1:3100".into()), + enable_legacy_next_compat: true, + enable_debug_shell_routes: false, + enable_editor_actor: true, + hermes_base_path: "/api/hermes".into(), + compat_next_base_path: "/api/compat/next".into(), + convex_url: None, + convex_admin_key: None, + allow_dev_fixtures: true, + query_fixtures_json: None, + mutation_fixtures_json: None, + dev_user_id: "dev-user".into(), + dev_user_name: "开发用户".into(), + dev_user_email: "dev@mnote.local".into(), + })) + } + + fn write_workspace_manifest(root: &Path) { + fs::write( + root.join(".mnote").join("workspace.json"), + r#"{"workspaceId":"local-ws-ocr","ownerId":"user_test","createdAt":"2026-06-01T00:00:00Z","capabilities":["local_files"]}"#, + ) + .expect("manifest"); + } + + async fn post_ocr_job(root: &Path, body: Value) -> (StatusCode, Value) { + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/jobs") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from(body.to_string())) + .expect("request"), + ) + .await + .expect("response"); + let status = response.status(); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("response body"); + let payload = serde_json::from_slice(&body).expect("response json"); + let _ = fs::remove_dir_all(root); + (status, payload) + } + + fn query_escape(value: &str) -> String { + value + .bytes() + .map(|byte| match byte { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => { + (byte as char).to_string() + } + _ => format!("%{byte:02X}"), + }) + .collect() + } + + fn build_test_mineru_zip(markdown: &str) -> Vec { + let mut bytes = Cursor::new(Vec::::new()); + { + let mut writer = zip::ZipWriter::new(&mut bytes); + writer + .start_file("full.md", zip::write::SimpleFileOptions::default()) + .expect("zip start file"); + writer + .write_all(markdown.as_bytes()) + .expect("zip markdown"); + writer.finish().expect("zip finish"); + } + bytes.into_inner() + } + + #[test] + fn local_ocr_sidecar_path_and_frontmatter_contract() { + let root = temp_root("mnote-local-ocr-sidecar"); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + let plan = plan_ocr_sidecar_path( + &root, + "local-md:docs~2FPage.md", + "docs/Page.assets/photo.png", + "mineru", + "vlm", + false, + ) + .expect("plan"); + assert_eq!( + plan.ocr_root_relative_path, + "docs/Page.ocr/photo.png.ocr.md" + ); + let markdown = build_ocr_markdown(&plan, "识别文本", "done", 1780000000000); + assert!(markdown.contains("mnote_ocr_version: 1")); + assert!(markdown.contains("provider: mineru")); + assert!(markdown.contains("model_version: vlm")); + assert!(markdown.contains("owner_document: ../Page.md")); + assert!(markdown.contains("source_path: ./Page.assets/photo.png")); + assert!(markdown.contains("source_root_relative_path: docs/Page.assets/photo.png")); + assert!(markdown.contains("status: done")); + let parsed = parse_ocr_frontmatter(&markdown).expect("frontmatter"); + assert_eq!( + parsed.source_root_relative_path, + "docs/Page.assets/photo.png" + ); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn local_ocr_index_marks_stale_and_redacts_error() { + let root = temp_root("mnote-local-ocr-index"); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + let source = root.join("docs").join("Page.assets").join("scan.pdf"); + fs::write(&source, b"pdf").expect("pdf"); + let plan = plan_ocr_sidecar_path( + &root, + "local-md:docs~2FPage.md", + "docs/Page.assets/scan.pdf", + "mock", + "vlm", + false, + ) + .expect("plan"); + let entry = build_index_entry( + &plan, + "failed", + 1780000000000, + "", + Some(redact_error("token=secret upload_url=https://example.test")), + ); + upsert_ocr_index_entry(&root, entry.clone()).expect("write index"); + let stored = read_ocr_index_entry(&root, "docs/Page.assets/scan.pdf") + .expect("read index") + .expect("entry"); + assert_eq!(stored.error.as_deref(), Some("provider_error_redacted")); + fs::write(&source, b"pdf changed").expect("change source"); + assert!(source_is_stale(&root, &stored)); + let _ = fs::remove_dir_all(root); + } + + #[tokio::test] + async fn local_ocr_jobs_route_writes_mock_sidecar_and_reads_status() { + let root = temp_root("mnote-local-ocr-route"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + let root_uri = format!("file://{}", root.display()); + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/jobs") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mock", + "mockMarkdown": "Route OCR Token" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + assert_eq!(response.status(), StatusCode::OK); + assert!(root + .join("docs") + .join("Page.ocr") + .join("photo.png.ocr.md") + .is_file()); + + let escaped_root = query_escape(&root_uri); + let status_response = app() + .oneshot( + Request::builder() + .uri(format!( + "/api/local-folder/ocr/status?rootUri={escaped_root}&sourceRootRelativePath=docs%2FPage.assets%2Fphoto.png" + )) + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("status response"); + assert_eq!(status_response.status(), StatusCode::OK); + let status_body = to_bytes(status_response.into_body(), usize::MAX) + .await + .expect("status body"); + let status_payload: Value = serde_json::from_slice(&status_body).expect("status json"); + assert_eq!(status_payload["job"]["status"].as_str(), Some("done")); + + let read_response = app() + .oneshot( + Request::builder() + .uri(format!( + "/api/local-folder/ocr/read?rootUri={escaped_root}&ocrRootRelativePath=docs%2FPage.ocr%2Fphoto.png.ocr.md" + )) + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::empty()) + .expect("request"), + ) + .await + .expect("read response"); + assert_eq!(read_response.status(), StatusCode::OK); + let read_body = to_bytes(read_response.into_body(), usize::MAX) + .await + .expect("read body"); + let read_payload: Value = serde_json::from_slice(&read_body).expect("read json"); + assert!(read_payload["markdown"] + .as_str() + .is_some_and(|markdown| markdown.contains("Route OCR Token"))); + let _ = fs::remove_dir_all(root); + } + + #[tokio::test] + async fn local_ocr_jobs_route_rejects_missing_mineru_token() { + let old_mnote_token = std::env::var("MNOTE_MINERU_API_TOKEN").ok(); + let old_mineru_token = std::env::var("MINERU_API_TOKEN").ok(); + std::env::remove_var("MNOTE_MINERU_API_TOKEN"); + std::env::remove_var("MINERU_API_TOKEN"); + + let root = temp_root("mnote-local-ocr-token"); + write_workspace_manifest(&root); + let root_uri = format!("file://{}", root.display()); + let (status, payload) = post_ocr_job( + &root, + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mineru" + }), + ) + .await; + if let Some(value) = old_mnote_token { + std::env::set_var("MNOTE_MINERU_API_TOKEN", value); + } + if let Some(value) = old_mineru_token { + std::env::set_var("MINERU_API_TOKEN", value); + } + assert_eq!(status, StatusCode::UNAUTHORIZED); + assert_eq!(payload["code"].as_str(), Some("mineru_token_missing")); + } + + #[tokio::test] + async fn local_ocr_jobs_route_runs_mineru_runtime_against_http_mock() { + let listener = tokio::net::TcpListener::bind("127.0.0.1:0") + .await + .expect("mock mineru bind"); + let base_url = format!("http://{}", listener.local_addr().expect("mock addr")); + let upload_count = Arc::new(AtomicUsize::new(0)); + let poll_count = Arc::new(AtomicUsize::new(0)); + let zip_bytes = Arc::new(build_test_mineru_zip("# MinerU Result\n\n识别文本")); + + let mock_mineru = axum::Router::new() + .route( + "/api/v4/file-urls/batch", + axum::routing::post({ + let base_url = base_url.clone(); + || async move { + Json(json!({ + "batch_id": "batch_1", + "file_urls": [{ "upload_url": format!("{base_url}/upload/source") }] + })) + } + }), + ) + .route( + "/upload/source", + axum::routing::put({ + let upload_count = upload_count.clone(); + move |body: axum::body::Bytes| { + let upload_count = upload_count.clone(); + async move { + assert!(!body.is_empty()); + upload_count.fetch_add(1, Ordering::SeqCst); + StatusCode::OK + } + } + }), + ) + .route( + "/api/v4/extract-results/batch/batch_1", + axum::routing::get({ + let base_url = base_url.clone(); + let poll_count = poll_count.clone(); + move || { + let poll_count = poll_count.clone(); + async move { + poll_count.fetch_add(1, Ordering::SeqCst); + Json(json!({ + "status": "done", + "full_zip_url": format!("{base_url}/result.zip") + })) + } + } + }), + ) + .route( + "/result.zip", + axum::routing::get({ + let zip_bytes = zip_bytes.clone(); + move || { + let zip_bytes = zip_bytes.clone(); + async move { + ( + [(axum::http::header::CONTENT_TYPE, "application/zip")], + (*zip_bytes).clone(), + ) + } + } + }), + ); + let mock_handle = tokio::spawn(async move { + axum::serve(listener, mock_mineru).await.expect("mock mineru server"); + }); + + let old_token = std::env::var("MNOTE_MINERU_API_TOKEN").ok(); + let old_base = std::env::var("MNOTE_MINERU_API_BASE_URL").ok(); + let old_interval = std::env::var("MNOTE_MINERU_POLL_INTERVAL_MS").ok(); + let old_max_polls = std::env::var("MNOTE_MINERU_MAX_POLLS").ok(); + std::env::set_var("MNOTE_MINERU_API_TOKEN", "test-mineru-token"); + std::env::set_var("MNOTE_MINERU_API_BASE_URL", &base_url); + std::env::set_var("MNOTE_MINERU_POLL_INTERVAL_MS", "1"); + std::env::set_var("MNOTE_MINERU_MAX_POLLS", "2"); + + let root = temp_root("mnote-local-ocr-mineru-runtime"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + let root_uri = format!("file://{}", root.display()); + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/jobs") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mineru" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + + if let Some(value) = old_token { + std::env::set_var("MNOTE_MINERU_API_TOKEN", value); + } else { + std::env::remove_var("MNOTE_MINERU_API_TOKEN"); + } + if let Some(value) = old_base { + std::env::set_var("MNOTE_MINERU_API_BASE_URL", value); + } else { + std::env::remove_var("MNOTE_MINERU_API_BASE_URL"); + } + if let Some(value) = old_interval { + std::env::set_var("MNOTE_MINERU_POLL_INTERVAL_MS", value); + } else { + std::env::remove_var("MNOTE_MINERU_POLL_INTERVAL_MS"); + } + if let Some(value) = old_max_polls { + std::env::set_var("MNOTE_MINERU_MAX_POLLS", value); + } else { + std::env::remove_var("MNOTE_MINERU_MAX_POLLS"); + } + + assert_eq!(response.status(), StatusCode::OK); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("response body"); + let payload: Value = serde_json::from_slice(&body).expect("response json"); + assert_eq!(payload["job"]["status"].as_str(), Some("done")); + assert_eq!(payload["job"]["provider"].as_str(), Some("mineru")); + assert_eq!(upload_count.load(Ordering::SeqCst), 1); + assert_eq!(poll_count.load(Ordering::SeqCst), 1); + let sidecar = fs::read_to_string( + root.join("docs") + .join("Page.ocr") + .join("photo.png.ocr.md"), + ) + .expect("sidecar"); + assert!(sidecar.contains("provider: mineru")); + assert!(sidecar.contains("识别文本")); + + mock_handle.abort(); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn local_ocr_mineru_runtime_config_uses_safe_defaults_and_env_overrides() { + let old_base = std::env::var("MNOTE_MINERU_API_BASE_URL").ok(); + let old_legacy_base = std::env::var("MINERU_API_BASE_URL").ok(); + let old_interval = std::env::var("MNOTE_MINERU_POLL_INTERVAL_MS").ok(); + let old_max_polls = std::env::var("MNOTE_MINERU_MAX_POLLS").ok(); + std::env::remove_var("MNOTE_MINERU_API_BASE_URL"); + std::env::remove_var("MINERU_API_BASE_URL"); + std::env::remove_var("MNOTE_MINERU_POLL_INTERVAL_MS"); + std::env::remove_var("MNOTE_MINERU_MAX_POLLS"); + + assert_eq!(mineru_api_base_url(), DEFAULT_MINERU_API_BASE_URL); + assert_eq!(mineru_poll_interval(), Duration::from_secs(2)); + assert_eq!(mineru_max_polls(), 90); + + std::env::set_var("MNOTE_MINERU_API_BASE_URL", "https://mineru.example.test/"); + std::env::set_var("MNOTE_MINERU_POLL_INTERVAL_MS", "25"); + std::env::set_var("MNOTE_MINERU_MAX_POLLS", "3"); + assert_eq!(mineru_api_base_url(), "https://mineru.example.test"); + assert_eq!(mineru_poll_interval(), Duration::from_millis(25)); + assert_eq!(mineru_max_polls(), 3); + + if let Some(value) = old_base { + std::env::set_var("MNOTE_MINERU_API_BASE_URL", value); + } else { + std::env::remove_var("MNOTE_MINERU_API_BASE_URL"); + } + if let Some(value) = old_legacy_base { + std::env::set_var("MINERU_API_BASE_URL", value); + } else { + std::env::remove_var("MINERU_API_BASE_URL"); + } + if let Some(value) = old_interval { + std::env::set_var("MNOTE_MINERU_POLL_INTERVAL_MS", value); + } else { + std::env::remove_var("MNOTE_MINERU_POLL_INTERVAL_MS"); + } + if let Some(value) = old_max_polls { + std::env::set_var("MNOTE_MINERU_MAX_POLLS", value); + } else { + std::env::remove_var("MNOTE_MINERU_MAX_POLLS"); + } + } + + #[tokio::test] + async fn local_ocr_jobs_route_rejects_root_escape_source() { + let root = temp_root("mnote-local-ocr-escape"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + let root_uri = format!("file://{}", root.display()); + let (status, payload) = post_ocr_job( + &root, + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "../outside.png", + "provider": "mock", + "mockMarkdown": "should not write" + }), + ) + .await; + assert_eq!(status, StatusCode::BAD_REQUEST); + assert_eq!(payload["code"].as_str(), Some("local_ocr_path_escape")); + } + + #[tokio::test] + async fn local_ocr_jobs_route_rejects_non_image_pdf_source() { + let root = temp_root("mnote-local-ocr-unsupported"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("notes.txt"), + b"text", + ) + .expect("text"); + let root_uri = format!("file://{}", root.display()); + let (status, payload) = post_ocr_job( + &root, + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/notes.txt", + "provider": "mock", + "mockMarkdown": "should not write" + }), + ) + .await; + assert_eq!(status, StatusCode::BAD_REQUEST); + assert_eq!( + payload["code"].as_str(), + Some("local_ocr_source_type_unsupported") + ); + } + + #[tokio::test] + async fn local_ocr_jobs_route_writes_failed_mock_entry_with_redacted_error() { + let root = temp_root("mnote-local-ocr-failed"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + let root_uri = format!("file://{}", root.display()); + let response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/jobs") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mock", + "mockError": "token=secret https://signed.example.test/full.zip?X-Oss-Signature=abc" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("response"); + assert_eq!(response.status(), StatusCode::OK); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("response body"); + let payload: Value = serde_json::from_slice(&body).expect("response json"); + assert_eq!(payload["job"]["status"].as_str(), Some("failed")); + assert_eq!( + payload["job"]["error"].as_str(), + Some("provider_error_redacted") + ); + let stored = read_ocr_index_entry(&root, "docs/Page.assets/photo.png") + .expect("read index") + .expect("entry"); + assert_eq!(stored.status, "failed"); + assert_eq!(stored.error.as_deref(), Some("provider_error_redacted")); + assert!(!root + .join("docs") + .join("Page.ocr") + .join("photo.png.ocr.md") + .exists()); + let _ = fs::remove_dir_all(root); + } + + #[tokio::test] + async fn local_ocr_insert_route_appends_explicit_ocr_link() { + let root = temp_root("mnote-local-ocr-insert"); + write_workspace_manifest(&root); + fs::write(root.join("docs").join("Page.md"), "# Page\n\n正文\n").expect("page"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + let root_uri = format!("file://{}", root.display()); + let create_response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/jobs") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "provider": "mock", + "mockMarkdown": "识别文本" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("create response"); + assert_eq!(create_response.status(), StatusCode::OK); + + let insert_response = app() + .oneshot( + Request::builder() + .method("POST") + .uri("/api/local-folder/ocr/insert") + .header("content-type", "application/json") + .header("x-mnote-actor-id", "user_test") + .header("x-mnote-actor-type", "user") + .body(Body::from( + json!({ + "rootUri": root_uri, + "documentId": "local-md:docs~2FPage.md", + "ocrRootRelativePath": "docs/Page.ocr/photo.png.ocr.md", + "mode": "link" + }) + .to_string(), + )) + .expect("request"), + ) + .await + .expect("insert response"); + assert_eq!(insert_response.status(), StatusCode::OK); + let body = to_bytes(insert_response.into_body(), usize::MAX) + .await + .expect("insert body"); + let payload: Value = serde_json::from_slice(&body).expect("insert json"); + assert_eq!( + payload["insertedMarkdown"].as_str(), + Some("[OCR:photo.png](./Page.ocr/photo.png.ocr.md)") + ); + let owner = fs::read_to_string(root.join("docs").join("Page.md")).expect("owner"); + assert_eq!( + owner, + "# Page\n\n正文\n\n[OCR:photo.png](./Page.ocr/photo.png.ocr.md)\n" + ); + let _ = fs::remove_dir_all(root); + } +} diff --git a/rust/crates/mnote-web/src/routes/local_search_index.rs b/rust/crates/mnote-web/src/routes/local_search_index.rs index 8428cfb6..29be5f97 100644 --- a/rust/crates/mnote-web/src/routes/local_search_index.rs +++ b/rust/crates/mnote-web/src/routes/local_search_index.rs @@ -3,6 +3,7 @@ use crate::routes::local_folder_source::encode_local_id_segment; use crate::routes::local_markdown_parser::{ parse_markdown_attachment_link, parse_markdown_page, split_frontmatter, }; +use crate::routes::local_ocr; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use std::fs; @@ -55,6 +56,7 @@ pub(crate) fn query_local_search_index( limit: u32, title_only: bool, exact: bool, + include_ocr: bool, ) -> Result { let index = load_or_rebuild_local_search_index(root_path, root_uri, workspace_id)?; let normalized_query = normalize_search_text(query); @@ -90,6 +92,39 @@ pub(crate) fn query_local_search_index( } } } + if include_ocr && results.len() < limit.max(1) as usize { + for entry in local_ocr::ocr_index_entries(root_path)? { + if let Some(page_id) = page_id { + if entry.owner_document_id != page_id { + continue; + } + } + if entry.status != "done" { + continue; + } + let ocr_path = root_path.join(&entry.ocr_root_relative_path); + let markdown = match fs::read_to_string(&ocr_path) { + Ok(markdown) => markdown, + Err(_) => continue, + }; + if local_ocr::parse_ocr_frontmatter(&markdown).is_none() { + continue; + } + let body = local_ocr::strip_ocr_frontmatter(&markdown); + if !local_search_ocr_matches(&entry, body, &normalized_query, title_only, exact) { + continue; + } + results.push(local_search_ocr_projection( + &entry, + body, + root_uri, + &normalized_query, + )); + if results.len() >= limit.max(1) as usize { + break; + } + } + } Ok(json!({ "enqueueAssetIds": [], "projectionOwner": "rust-kernel", @@ -100,7 +135,8 @@ pub(crate) fn query_local_search_index( "workspaceId": index.workspace_id, "builtAt": index.built_at, "documentCount": index.documents.len(), - "resourceCount": index.resources.len() + "resourceCount": index.resources.len(), + "includeOcr": include_ocr }, "recentChanges": recent_changes, "results": results @@ -404,6 +440,14 @@ fn collect_markdown_documents( continue; } if is_markdown_path(&path) { + let relative_path = path + .strip_prefix(root_path) + .unwrap_or(&path) + .to_string_lossy() + .replace('\\', "/"); + if local_ocr::is_local_ocr_sidecar_relative_path(&relative_path) { + continue; + } documents.push(index_markdown_file(root_path, &path)?); } else if resource_type_from_path(&path).is_some() { resources.push(index_resource_file(root_path, &path)?); @@ -565,6 +609,34 @@ fn local_search_resource_matches( } } +fn local_search_ocr_matches( + entry: &local_ocr::OcrIndexEntry, + body: &str, + query: &str, + title_only: bool, + exact: bool, +) -> bool { + if query.is_empty() { + return false; + } + let haystack = if title_only { + normalize_search_text(&format!( + "{}\n{}", + entry.source_root_relative_path, entry.ocr_root_relative_path + )) + } else { + normalize_search_text(&format!( + "{}\n{}\n{}", + entry.source_root_relative_path, entry.ocr_root_relative_path, body + )) + }; + if exact { + haystack == query + } else { + haystack.contains(query) + } +} + fn local_search_document_projection( document: &LocalSearchDocument, root_uri: &str, @@ -608,6 +680,42 @@ fn local_search_resource_projection(resource: &LocalSearchResource, root_uri: &s }) } +fn local_search_ocr_projection( + entry: &local_ocr::OcrIndexEntry, + body: &str, + root_uri: &str, + query: &str, +) -> Value { + let title = Path::new(&entry.owner_document_path) + .file_stem() + .and_then(|value| value.to_str()) + .unwrap_or("OCR") + .to_string(); + json!({ + "id": format!("{}#ocr:{}", entry.owner_document_id, entry.source_root_relative_path), + "documentId": entry.owner_document_id, + "title": title, + "path": entry.owner_document_path, + "resourceType": "markdown", + "sourceKind": "local_folder", + "rootUri": root_uri, + "hasOcr": true, + "snippet": ocr_search_snippet(body, query), + "ocrEvidence": { + "sourceRootRelativePath": entry.source_root_relative_path, + "ocrRootRelativePath": entry.ocr_root_relative_path, + "provider": entry.provider, + "status": entry.status, + }, + "updatedAt": entry.updated_at_ms, + "publicPath": format!( + "/documents/{}?sourceKind=local_folder&rootUri={}", + entry.owner_document_id, + encode_query_component(root_uri), + ) + }) +} + fn encode_query_component(value: &str) -> String { let mut encoded = String::with_capacity(value.len()); for byte in value.as_bytes() { @@ -764,6 +872,27 @@ fn search_snippet(document: &LocalSearchDocument, query: &str) -> String { document.raw_text.chars().take(180).collect() } +fn ocr_search_snippet(body: &str, query: &str) -> String { + let normalized_body = body.replace('\n', " "); + let normalized_query = query.trim(); + if normalized_query.is_empty() { + return normalized_body.chars().take(160).collect(); + } + let lower = normalized_body.to_ascii_lowercase(); + let lower_query = normalized_query.to_ascii_lowercase(); + if let Some(byte_index) = lower.find(&lower_query) { + let start = normalized_body[..byte_index] + .char_indices() + .rev() + .nth(40) + .map(|(idx, _)| idx) + .unwrap_or(0); + normalized_body[start..].chars().take(160).collect() + } else { + normalized_body.chars().take(160).collect() + } +} + fn is_markdown_path(path: &Path) -> bool { path.extension() .and_then(|value| value.to_str()) @@ -845,6 +974,7 @@ mod tests { 10, false, false, + false, ) .expect("projection"); let results = projection["results"].as_array().expect("results"); @@ -898,6 +1028,7 @@ mod tests { 10, false, false, + false, ) .expect("child search"); let child_result = child_search["results"] @@ -929,6 +1060,7 @@ mod tests { 10, false, false, + false, ) .expect("mindmap projection"); assert!(mindmap_projection["results"] @@ -953,6 +1085,7 @@ mod tests { 10, false, false, + false, ) .expect("office projection"); assert!(office_projection["results"] @@ -1017,6 +1150,104 @@ mod tests { let _ = fs::remove_dir_all(&root); } + #[test] + fn local_search_ocr_sidecar_requires_include_ocr_and_returns_owner_page() { + let root = temp_root("mnote-local-search-ocr"); + let root_uri = format!("file://{}", root.display()); + let workspace_id = "local-ws-ocr"; + fs::write(root.join("docs").join("Page.md"), "# Page\n正文\n").expect("page"); + fs::create_dir_all(root.join("docs").join("Page.assets")).expect("assets"); + fs::write( + root.join("docs").join("Page.assets").join("photo.png"), + b"png", + ) + .expect("photo"); + fs::create_dir_all(root.join("docs").join("Page.ocr")).expect("ocr dir"); + fs::write( + root.join("docs").join("Page.ocr").join("photo.png.ocr.md"), + "---\nmnote_ocr_version: 1\nprovider: mock\nmodel_version: vlm\nowner_document: ../Page.md\nsource_path: ./Page.assets/photo.png\nsource_root_relative_path: docs/Page.assets/photo.png\nsource_size: 3\nsource_mtime_ms: 1\nstatus: done\ncreated_at: 1\nupdated_at: 1\n---\n\nOCR-only-token 识别正文\n", + ) + .expect("ocr markdown"); + fs::create_dir_all(root.join(".mnote")).expect("mnote dir"); + fs::write( + root.join(".mnote").join("ocr-index.json"), + serde_json::to_string_pretty(&json!({ + "version": 1, + "entries": { + "docs/Page.assets/photo.png": { + "jobId": "ocr_test", + "ownerDocumentId": "local-md:docs~2FPage.md", + "ownerDocumentPath": "docs/Page.md", + "sourceRootRelativePath": "docs/Page.assets/photo.png", + "ocrRootRelativePath": "docs/Page.ocr/photo.png.ocr.md", + "provider": "mock", + "modelVersion": "vlm", + "status": "done", + "sourceSize": 3, + "sourceMtimeMs": 1, + "createdAtMs": 1, + "updatedAtMs": 1, + "plainTextPreview": "OCR-only-token 识别正文" + } + } + })) + .expect("serialize index"), + ) + .expect("ocr index"); + + let without_ocr = query_local_search_index( + &root, + &root_uri, + workspace_id, + "OCR-only-token", + None, + 10, + false, + false, + false, + ) + .expect("without ocr"); + assert_eq!(without_ocr["results"].as_array().map(Vec::len), Some(0)); + + let with_ocr = query_local_search_index( + &root, + &root_uri, + workspace_id, + "OCR-only-token", + None, + 10, + false, + false, + true, + ) + .expect("with ocr"); + let result = with_ocr["results"] + .as_array() + .and_then(|items| items.first()) + .expect("ocr result"); + assert_eq!( + result["documentId"].as_str(), + Some("local-md:docs~2FPage.md") + ); + assert_eq!(result["hasOcr"].as_bool(), Some(true)); + assert_eq!( + result["ocrEvidence"]["sourceRootRelativePath"].as_str(), + Some("docs/Page.assets/photo.png") + ); + assert_eq!( + result["ocrEvidence"]["ocrRootRelativePath"].as_str(), + Some("docs/Page.ocr/photo.png.ocr.md") + ); + let index = read_local_search_index(&root) + .expect("read search index") + .expect("search index"); + assert!(!index + .documents + .iter() + .any(|document| document.path == "docs/Page.ocr/photo.png.ocr.md")); + let _ = fs::remove_dir_all(&root); + } + #[test] fn local_search_query_reads_existing_index_without_rebuilding() { let root = temp_root("mnote-local-search-query-cache"); @@ -1038,6 +1269,7 @@ mod tests { 10, false, false, + false, ) .expect("first query"); assert_eq!( @@ -1060,6 +1292,7 @@ mod tests { 10, false, false, + false, ) .expect("query existing index"); assert_eq!( @@ -1078,6 +1311,7 @@ mod tests { 10, false, false, + false, ) .expect("query refreshed index"); assert_eq!( diff --git a/rust/crates/mnote-web/src/routes/mod.rs b/rust/crates/mnote-web/src/routes/mod.rs index 6317291a..3de1b8d2 100644 --- a/rust/crates/mnote-web/src/routes/mod.rs +++ b/rust/crates/mnote-web/src/routes/mod.rs @@ -13,12 +13,14 @@ mod kernel; mod local_folder_events; mod local_folder_source; mod local_markdown_parser; +mod local_ocr; mod local_search_index; mod media; mod mindmap_api; mod mindmap_shell; pub(crate) mod navigation_recent; mod onlyoffice; +pub(crate) mod onlyoffice_bridge; mod page_ai_workflow; mod query_support; mod resource_trash; @@ -35,7 +37,7 @@ pub(crate) mod web_shell; mod ws; pub(crate) use local_folder_source::{ - ensure_local_path_read_access, ensure_local_workspace_access, + decode_local_id_segment, ensure_local_path_read_access, ensure_local_workspace_access, local_markdown_conflict_detection_key, local_workspace_id_from_root_uri, update_local_markdown_title, write_local_markdown_page_body, }; @@ -183,6 +185,34 @@ pub fn build_router(state: AppState) -> Router { "/api/mnote-browser-runtime/sidebar-page-ai-runtime.js", get(web_shell::sidebar_page_ai_runtime_asset), ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-markdown-runtime.js", + get(web_shell::sidebar_page_ai_markdown_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-render-runtime.js", + get(web_shell::sidebar_page_ai_render_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-permission-runtime.js", + get(web_shell::sidebar_page_ai_permission_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-profile-runtime.js", + get(web_shell::sidebar_page_ai_profile_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-session-runtime.js", + get(web_shell::sidebar_page_ai_session_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-skill-runtime.js", + get(web_shell::sidebar_page_ai_skill_runtime_asset), + ) + .route( + "/api/mnote-browser-runtime/sidebar-page-ai-target-runtime.js", + get(web_shell::sidebar_page_ai_target_runtime_asset), + ) .route( "/api/mnote-browser-runtime/sidebar-page-settings-runtime.js", get(web_shell::sidebar_page_settings_runtime_asset), @@ -288,6 +318,10 @@ pub fn build_router(state: AppState) -> Router { .route("/api/auth/whoami", get(session::session)) .route("/api/auth/mnote-web-token", get(session::session)) .route("/api/auth/session/refresh", post(session::refresh_session)) + .route( + "/api/ai/agent-profiles", + get(hermes_client::list_agent_profiles), + ) .route( "/api/sidebar/shortcuts", get(sidebar_shortcuts::list_shortcuts).post(sidebar_shortcuts::upsert_shortcut), @@ -382,6 +416,54 @@ pub fn build_router(state: AppState) -> Router { .route("/api/onlyoffice/proxy", get(onlyoffice::proxy)) .route("/api/onlyoffice/callback", post(onlyoffice::callback)) .route("/api/onlyoffice/forcesave", post(onlyoffice::forcesave)) + .route( + "/api/onlyoffice/bridge/plugin/config", + get(onlyoffice_bridge::plugin_config), + ) + .route( + "/api/onlyoffice/bridge/plugin/index", + get(onlyoffice_bridge::plugin_index), + ) + .route( + "/api/onlyoffice/bridge/plugin/index/config.json", + get(onlyoffice_bridge::plugin_config), + ) + .route( + "/api/onlyoffice/bridge/plugin/index/{state}", + get(onlyoffice_bridge::plugin_index_with_state), + ) + .route( + "/api/onlyoffice/bridge/session", + post(onlyoffice_bridge::register_session), + ) + .route( + "/api/onlyoffice/bridge/session/current", + get(onlyoffice_bridge::current_session), + ) + .route( + "/api/onlyoffice/bridge/session/close", + post(onlyoffice_bridge::close_session), + ) + .route( + "/api/onlyoffice/bridge/sessions", + get(onlyoffice_bridge::list_sessions), + ) + .route( + "/api/onlyoffice/bridge/capabilities", + get(onlyoffice_bridge::capabilities), + ) + .route( + "/api/onlyoffice/bridge/commands", + post(onlyoffice_bridge::enqueue_command), + ) + .route( + "/api/onlyoffice/bridge/commands/next", + get(onlyoffice_bridge::next_command), + ) + .route( + "/api/onlyoffice/bridge/results", + get(onlyoffice_bridge::get_result).post(onlyoffice_bridge::post_result), + ) .route("/api/media/upload", post(media::upload)) .route("/api/media/sign", get(media::sign)) .route("/api/media/batch", post(resource_trash::media_batch)) @@ -452,6 +534,13 @@ pub fn build_router(state: AppState) -> Router { "/api/local-folder/events", get(local_folder_events::local_folder_events), ) + .route( + "/api/local-folder/ocr/jobs", + get(local_ocr::list_jobs).post(local_ocr::create_job), + ) + .route("/api/local-folder/ocr/status", get(local_ocr::status)) + .route("/api/local-folder/ocr/read", get(local_ocr::read)) + .route("/api/local-folder/ocr/insert", post(local_ocr::insert)) .route( "/api/local-folder/workspaces/default", post(local_folder_source::create_default_local_workspace), @@ -1027,6 +1116,13 @@ mod tests { "/api/mnote-browser-runtime/sidebar-filetree-upload-runtime.js", "/api/mnote-browser-runtime/sidebar-attachment-open-runtime.js", "/api/mnote-browser-runtime/sidebar-page-ai-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-markdown-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-render-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-permission-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-profile-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-session-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-skill-runtime.js", + "/api/mnote-browser-runtime/sidebar-page-ai-target-runtime.js", "/api/mnote-browser-runtime/sidebar-page-settings-runtime.js", "/api/mnote-browser-runtime/sidebar-tree-runtime.js", "/api/mnote-browser-runtime/tree-live-controller.js", diff --git a/rust/crates/mnote-web/src/routes/onlyoffice.rs b/rust/crates/mnote-web/src/routes/onlyoffice.rs index c327a00f..28e52146 100644 --- a/rust/crates/mnote-web/src/routes/onlyoffice.rs +++ b/rust/crates/mnote-web/src/routes/onlyoffice.rs @@ -1,3 +1,4 @@ +use super::onlyoffice_bridge; use crate::app::AppConfig; use crate::app::AppState; use crate::error::WebError; @@ -147,6 +148,9 @@ pub struct OnlyOfficeCallbackQuery { asset_id: Option, #[serde(rename = "userId")] user_id: Option, + #[serde(rename = "sessionId")] + session_id: Option, + token: Option, #[serde(rename = "rootUri")] root_uri: Option, path: Option, @@ -506,10 +510,12 @@ pub async fn page(Query(query): Query) -> Result) -> Result) -> Result) -> Result) -> Result {{ window.__MNOTE_ONLYOFFICE_READY__ = true; }}, onAppReady: () => {{ window.__MNOTE_ONLYOFFICE_READY__ = true; }}, + onRequestEditRights: () => {{ + const editHref = editModeLocationHref(); + window.__MNOTE_ONLYOFFICE_REQUEST_EDIT_RIGHTS__ = {{ + requested: true, + targetUrl: editHref + }}; + window.location.replace(editHref); + }}, onError: (event) => showError(JSON.stringify(event)) }} }}; @@ -690,7 +725,52 @@ pub async fn page(Query(query): Query) -> Result null); + if (!enqueue.ok) throw new Error(enqueued && enqueued.message || "ONLYOFFICE bridge command enqueue failed"); + const commandId = enqueued && enqueued.command && enqueued.command.id; + if (!commandId) throw new Error("ONLYOFFICE bridge command id missing"); + const resultUrl = new URL("/api/onlyoffice/bridge/results", location.origin); + resultUrl.searchParams.set("sessionId", bridgeSessionId); + resultUrl.searchParams.set("token", bridgeToken); + resultUrl.searchParams.set("commandId", commandId); + resultUrl.searchParams.set("timeoutMs", String(timeoutMs || 25000)); + const resultResponse = await fetch(resultUrl.toString()); + if (resultResponse.status === 204) throw new Error("ONLYOFFICE bridge command timed out"); + const result = await resultResponse.json().catch(() => null); + if (!resultResponse.ok || !result || result.ok === false) {{ + throw new Error(result && result.error || result && result.message || "ONLYOFFICE bridge command failed"); + }} + return result.result; + }} }}; const readyDeadline = Date.now() + 120000; const timer = window.setInterval(() => {{ @@ -1070,12 +1150,15 @@ fn onlyoffice_callback_success(extra: Value) -> Response { } fn onlyoffice_callback_failure(error: WebError) -> Response { - Json(json!({ + ( + error.status(), + Json(json!({ "error": 1, "code": error.code(), "message": error.message(), - })) - .into_response() + })), + ) + .into_response() } async fn download_onlyoffice_callback_body(download_url: &str) -> Result { @@ -1135,6 +1218,53 @@ async fn local_folder_onlyoffice_callback( ) })?; let target = resolve_onlyoffice_local_file_path(root_uri, relative_path)?; + let session_id = query + .session_id + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .ok_or_else(|| { + WebError::new( + StatusCode::UNAUTHORIZED, + "onlyoffice_local_callback_session_required", + "OnlyOffice 本地保存缺少 bridge sessionId", + ) + })?; + let token = query + .token + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .ok_or_else(|| { + WebError::new( + StatusCode::UNAUTHORIZED, + "onlyoffice_local_callback_token_required", + "OnlyOffice 本地保存缺少 bridge token", + ) + })?; + if !onlyoffice_bridge::session_token_matches(session_id, token) { + return Err(WebError::new( + StatusCode::UNAUTHORIZED, + "onlyoffice_local_callback_token_invalid", + "OnlyOffice 本地保存 bridge token 无效", + )); + } + let session = onlyoffice_bridge::session_info(session_id).ok_or_else(|| { + WebError::new( + StatusCode::UNAUTHORIZED, + "onlyoffice_local_callback_session_unregistered", + "OnlyOffice 本地保存 bridge session 未注册", + ) + })?; + if let Some(session_asset_id) = session.asset_id.as_deref() { + if !session_asset_id.trim().is_empty() && session_asset_id.trim() != asset_id { + return Err(WebError::new( + StatusCode::FORBIDDEN, + "onlyoffice_local_callback_asset_mismatch", + "OnlyOffice 本地保存 session 与资源不匹配", + )); + } + } let onlyoffice_internal_url = resolve_onlyoffice_internal_url().await; let prepared = prepare_callback(OnlyOfficeCallbackPreparationInput { asset_id: asset_id.to_string(), @@ -1840,6 +1970,22 @@ mod tests { )); assert!(html.contains("if (proxyOrigin && isLocalFolderFileOpen)")); assert!(html.contains("if (proxyOrigin && (isLocal || url.searchParams.has(\"token\")))")); + assert!(html.contains( + "const MNOTE_AGENT_PLUGIN_GUID = \"asc.{05F87DDF-7B42-4C6F-9F2B-9C77A8D5F4E2}\";" + )); + assert!(html.contains( + "const bridgePluginConfigUrl = new URL(\"/api/onlyoffice/bridge/plugin/config\", location.origin);" + )); + assert!( + html.contains("bridgePluginConfigUrl.searchParams.set(\"apiBase\", location.origin);") + ); + assert!(html.contains("const bridgeSessionSalt =")); + assert!(html.contains( + "const bridgeSessionId = \"mnote-oo-\" + fileState.docKey + \"-\" + bridgeSessionSalt;" + )); + assert!(html.contains("/api/onlyoffice/bridge/plugin/config")); + assert!(html.contains("pluginsData: [bridgePluginConfigUrl.toString()]")); + assert!(html.contains("window.__MNOTE_ONLYOFFICE_BRIDGE__")); } fn test_state(legacy_next_base_url: Option) -> AppState { @@ -1897,6 +2043,8 @@ mod tests { Query(OnlyOfficeCallbackQuery { asset_id: Some("asset_1".into()), user_id: None, + session_id: None, + token: None, root_uri: None, path: None, }), @@ -1917,9 +2065,9 @@ mod tests { } #[tokio::test] - async fn onlyoffice_local_callback_writes_status_two_body_to_original_file() { + async fn onlyoffice_local_callback_rejects_unauthenticated_local_write() { let root = std::env::temp_dir().join(format!( - "mnote-onlyoffice-local-callback-{}", + "mnote-onlyoffice-local-callback-unauth-{}", std::process::id() )); let _ = fs::remove_dir_all(&root); @@ -1938,6 +2086,74 @@ mod tests { Query(OnlyOfficeCallbackQuery { asset_id: Some("local:asset:Page/report.docx".into()), user_id: None, + session_id: None, + token: None, + root_uri: Some(format!("file://{}", root.display())), + path: Some("Page/report.docx".into()), + }), + Json(json!({ + "status": 2, + "key": "doc_key", + "url": download_url + })), + ) + .await; + + assert_eq!(response.status(), StatusCode::UNAUTHORIZED); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(payload["error"], 1); + assert_eq!( + payload["code"], + "onlyoffice_local_callback_session_required" + ); + assert_eq!(fs::read(&target).expect("read target"), b"old"); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn onlyoffice_local_callback_writes_status_two_body_to_original_file() { + let root = std::env::temp_dir().join(format!( + "mnote-onlyoffice-local-callback-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("Page")).expect("create page"); + let target = root.join("Page").join("report.docx"); + fs::write(&target, b"old").expect("write old docx"); + let (download_url, _captured) = spawn_legacy_json_server("new docx bytes").await; + let session_id = format!("mnote-oo-local-callback-{}", std::process::id()); + let token = format!("token-{session_id}"); + let registered = + onlyoffice_bridge::register_session(Json(onlyoffice_bridge::BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token.clone()), + editor_type: Some("word".into()), + document_id: Some("local-md:Page".into()), + asset_id: Some("local:asset:Page/report.docx".into()), + file_type: Some("docx".into()), + doc_key: None, + page_origin: None, + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); + let response = callback( + State(test_state(None)), + format!( + "/api/onlyoffice/callback?assetId=local%3Aasset%3APage%2Freport.docx&sessionId={}&token={}&rootUri=file%3A%2F%2F{}&path=Page%2Freport.docx", + session_id, + token, + root.display(), + ) + .parse::() + .expect("uri"), + Query(OnlyOfficeCallbackQuery { + asset_id: Some("local:asset:Page/report.docx".into()), + user_id: None, + session_id: Some(session_id), + token: Some(token), root_uri: Some(format!("file://{}", root.display())), path: Some("Page/report.docx".into()), }), @@ -1958,6 +2174,147 @@ mod tests { let _ = fs::remove_dir_all(&root); } + #[tokio::test] + async fn onlyoffice_local_callback_writes_status_six_body_to_original_file() { + let root = std::env::temp_dir().join(format!( + "mnote-onlyoffice-local-callback-status-six-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + fs::create_dir_all(root.join("Page")).expect("create page"); + let target = root.join("Page").join("report.docx"); + fs::write(&target, b"old").expect("write old docx"); + let (download_url, _captured) = spawn_legacy_json_server("status six bytes").await; + let session_id = format!("mnote-oo-local-callback-six-{}", std::process::id()); + let token = format!("token-{session_id}"); + let registered = + onlyoffice_bridge::register_session(Json(onlyoffice_bridge::BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token.clone()), + editor_type: Some("word".into()), + document_id: Some("local-md:Page".into()), + asset_id: Some("local:asset:Page/report.docx".into()), + file_type: Some("docx".into()), + doc_key: None, + page_origin: None, + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); + let response = callback( + State(test_state(None)), + format!( + "/api/onlyoffice/callback?assetId=local%3Aasset%3APage%2Freport.docx&sessionId={}&token={}&rootUri=file%3A%2F%2F{}&path=Page%2Freport.docx", + session_id, + token, + root.display(), + ) + .parse::() + .expect("uri"), + Query(OnlyOfficeCallbackQuery { + asset_id: Some("local:asset:Page/report.docx".into()), + user_id: None, + session_id: Some(session_id), + token: Some(token), + root_uri: Some(format!("file://{}", root.display())), + path: Some("Page/report.docx".into()), + }), + Json(json!({ + "status": 6, + "key": "doc_key", + "url": download_url + })), + ) + .await; + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + + assert_eq!(payload["error"], 0); + assert_eq!(fs::read(&target).expect("read target"), b"status six bytes"); + let _ = fs::remove_dir_all(&root); + } + + #[tokio::test] + async fn onlyoffice_local_callback_rejects_root_escape_path() { + let root = std::env::temp_dir().join(format!( + "mnote-onlyoffice-local-callback-root-{}", + std::process::id() + )); + let outside = std::env::temp_dir().join(format!( + "mnote-onlyoffice-local-callback-outside-{}", + std::process::id() + )); + let _ = fs::remove_dir_all(&root); + let _ = fs::remove_dir_all(&outside); + fs::create_dir_all(root.join("Page")).expect("create page"); + fs::create_dir_all(&outside).expect("create outside"); + fs::write(outside.join("report.docx"), b"outside").expect("write outside"); + let (download_url, _captured) = spawn_legacy_json_server("should not write").await; + let session_id = format!("mnote-oo-local-callback-escape-{}", std::process::id()); + let token = format!("token-{session_id}"); + let registered = + onlyoffice_bridge::register_session(Json(onlyoffice_bridge::BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token.clone()), + editor_type: Some("word".into()), + document_id: Some("local-md:Page".into()), + asset_id: Some("local:asset:Page/report.docx".into()), + file_type: Some("docx".into()), + doc_key: None, + page_origin: None, + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); + let response = callback( + State(test_state(None)), + format!( + "/api/onlyoffice/callback?assetId=local%3Aasset%3APage%2Freport.docx&sessionId={}&token={}&rootUri=file%3A%2F%2F{}&path=..%2F{}%2Freport.docx", + session_id, + token, + root.display(), + outside.file_name().and_then(|value| value.to_str()).unwrap_or_default(), + ) + .parse::() + .expect("uri"), + Query(OnlyOfficeCallbackQuery { + asset_id: Some("local:asset:Page/report.docx".into()), + user_id: None, + session_id: Some(session_id), + token: Some(token), + root_uri: Some(format!("file://{}", root.display())), + path: Some(format!( + "../{}/report.docx", + outside + .file_name() + .and_then(|value| value.to_str()) + .unwrap_or_default() + )), + }), + Json(json!({ + "status": 2, + "key": "doc_key", + "url": download_url + })), + ) + .await; + let status = response.status(); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + + assert_eq!(status, StatusCode::BAD_REQUEST); + assert_eq!(payload["error"], 1); + assert_eq!(payload["code"], "onlyoffice_local_file_root_escape"); + assert_eq!( + fs::read(outside.join("report.docx")).expect("read outside"), + b"outside" + ); + let _ = fs::remove_dir_all(&root); + let _ = fs::remove_dir_all(&outside); + } + #[tokio::test] async fn onlyoffice_local_callback_ignores_non_write_status() { let root = std::env::temp_dir().join(format!( @@ -1968,17 +2325,36 @@ mod tests { fs::create_dir_all(root.join("Page")).expect("create page"); let target = root.join("Page").join("report.docx"); fs::write(&target, b"old").expect("write old docx"); + let session_id = format!("mnote-oo-local-callback-ignore-{}", std::process::id()); + let token = format!("token-{session_id}"); + let registered = + onlyoffice_bridge::register_session(Json(onlyoffice_bridge::BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token.clone()), + editor_type: Some("word".into()), + document_id: Some("local-md:Page".into()), + asset_id: Some("local:asset:Page/report.docx".into()), + file_type: Some("docx".into()), + doc_key: None, + page_origin: None, + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); let response = callback( State(test_state(None)), format!( - "/api/onlyoffice/callback?assetId=local%3Aasset%3APage%2Freport.docx&rootUri=file%3A%2F%2F{}&path=Page%2Freport.docx", - root.display() + "/api/onlyoffice/callback?assetId=local%3Aasset%3APage%2Freport.docx&sessionId={}&token={}&rootUri=file%3A%2F%2F{}&path=Page%2Freport.docx", + session_id, + token, + root.display(), ) .parse::() .expect("uri"), Query(OnlyOfficeCallbackQuery { asset_id: Some("local:asset:Page/report.docx".into()), user_id: None, + session_id: Some(session_id), + token: Some(token), root_uri: Some(format!("file://{}", root.display())), path: Some("Page/report.docx".into()), }), @@ -2006,6 +2382,8 @@ mod tests { Query(OnlyOfficeCallbackQuery { asset_id: Some("asset_1".into()), user_id: Some("user_1".into()), + session_id: None, + token: None, root_uri: None, path: None, }), @@ -2128,4 +2506,32 @@ mod tests { assert!(html.contains("anonymous: { request: false, label: \"Guest\" }")); assert!(html.contains("features: { featuresTips: false }")); } + + #[tokio::test] + async fn onlyoffice_page_reinitializes_edit_url_on_request_edit_rights() { + let response = page(Query(OnlyOfficePageQuery { + file_url: Some( + "http://localhost:3000/api/local-folder/files/open?rootUri=file:///tmp&path=Page/report.docx" + .into(), + ), + file_name: Some("report.docx".into()), + file_type: Some("docx".into()), + asset_id: Some("local-file:Page/report.docx".into()), + document_id: Some("local-md:Page".into()), + user_id: None, + mode: Some("view".into()), + })) + .await + .expect("onlyoffice page"); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let html = String::from_utf8(body.to_vec()).expect("html"); + + assert!(html.contains("function editModeLocationHref()")); + assert!(html.contains("next.searchParams.set(\"mode\", \"edit\");")); + assert!(html.contains("onRequestEditRights: () =>")); + assert!(html.contains("window.__MNOTE_ONLYOFFICE_REQUEST_EDIT_RIGHTS__")); + assert!(html.contains("window.location.replace(editHref);")); + } } diff --git a/rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs b/rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs new file mode 100644 index 00000000..4c2405d1 --- /dev/null +++ b/rust/crates/mnote-web/src/routes/onlyoffice_bridge.rs @@ -0,0 +1,2226 @@ +use axum::extract::{Path, Query}; +use axum::http::{header, HeaderMap, HeaderValue, StatusCode}; +use axum::response::{Html, IntoResponse, Response}; +use axum::Json; +use base64::engine::general_purpose::URL_SAFE_NO_PAD; +use base64::Engine; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use std::collections::{HashMap, VecDeque}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::{Mutex, OnceLock}; +use std::time::{SystemTime, UNIX_EPOCH}; +use tokio::time::{sleep, Duration, Instant}; +use uuid::Uuid; + +pub const MNOTE_ONLYOFFICE_BRIDGE_GUID: &str = "asc.{05F87DDF-7B42-4C6F-9F2B-9C77A8D5F4E2}"; +const MAX_LONG_POLL_MS: u64 = 25_000; +const LONG_POLL_INTERVAL_MS: u64 = 250; + +static BRIDGE_COMMAND_COUNTER: AtomicU64 = AtomicU64::new(1); +static BRIDGE_STATE: OnceLock>> = OnceLock::new(); + +#[derive(Debug, Default)] +struct BridgeSessionState { + queue: VecDeque, + results: HashMap, + token: Option, + editor_type: Option, + document_id: Option, + asset_id: Option, + file_type: Option, + doc_key: Option, + page_origin: Option, + last_seen_millis: u128, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeCommandWire { + pub id: String, + pub action: String, + #[serde(default)] + pub payload: Value, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeResultWire { + pub id: String, + pub ok: bool, + #[serde(default)] + pub result: Value, + #[serde(default)] + pub error: Option, +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeSessionInfo { + pub session_id: String, + pub editor_type: Option, + pub document_id: Option, + pub asset_id: Option, + pub file_type: Option, + pub doc_key: Option, + pub page_origin: Option, + pub last_seen_millis: u128, + pub pending_commands: usize, + pub pending_results: usize, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgePluginConfigQuery { + session_id: Option, + api_base: Option, + token: Option, + document_id: Option, + asset_id: Option, + file_type: Option, + doc_key: Option, + page_origin: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgePluginIndexQuery { + session_id: Option, + api_base: Option, + token: Option, + document_id: Option, + asset_id: Option, + file_type: Option, + doc_key: Option, + page_origin: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct BridgePluginIndexState { + session_id: String, + api_base: String, + token: String, + #[serde(default)] + document_id: Option, + #[serde(default)] + asset_id: Option, + #[serde(default)] + file_type: Option, + #[serde(default)] + doc_key: Option, + #[serde(default)] + page_origin: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeSessionPayload { + pub session_id: String, + #[serde(default)] + pub token: Option, + #[serde(default)] + pub editor_type: Option, + #[serde(default)] + pub document_id: Option, + #[serde(default)] + pub asset_id: Option, + #[serde(default)] + pub file_type: Option, + #[serde(default)] + pub doc_key: Option, + #[serde(default)] + pub page_origin: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeCloseSessionPayload { + pub session_id: String, + #[serde(default)] + pub token: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeEnqueuePayload { + session_id: String, + #[serde(default)] + token: Option, + action: String, + #[serde(default)] + payload: Value, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeNextQuery { + session_id: String, + token: Option, + timeout_ms: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BridgeResultQuery { + session_id: String, + token: Option, + command_id: String, + timeout_ms: Option, +} + +pub async fn plugin_config(Query(query): Query) -> Response { + let session_id = non_empty(query.session_id).unwrap_or_else(|| "mnote-onlyoffice".into()); + let api_base = normalize_api_base(query.api_base.as_deref()); + let token = non_empty(query.token).unwrap_or_else(new_bridge_token); + let index_state = encode_index_state( + &session_id, + &api_base, + &token, + query.document_id.as_deref(), + query.asset_id.as_deref(), + query.file_type.as_deref(), + query.doc_key.as_deref(), + query.page_origin.as_deref(), + ); + let index_url = format!("{api_base}/api/onlyoffice/bridge/plugin/index/{index_state}"); + let payload = json!({ + "name": "MNote Bridge", + "guid": MNOTE_ONLYOFFICE_BRIDGE_GUID, + "mnoteBridgeToken": token, + "version": "0.1.0", + "variations": [{ + "description": "MNote agent bridge for ONLYOFFICE documents, spreadsheets, and presentations.", + "url": index_url, + "EditorsSupport": ["word", "cell", "slide"], + "isViewer": false, + "isVisual": false, + "isModal": false, + "isInsideMode": false, + "initDataType": "none", + "initData": "", + "buttons": [] + }] + }); + json_response(payload) +} + +pub async fn plugin_index(Query(query): Query) -> impl IntoResponse { + let session_id = non_empty(query.session_id).unwrap_or_else(|| "mnote-onlyoffice".into()); + let api_base = normalize_api_base(query.api_base.as_deref()); + let token = non_empty(query.token).unwrap_or_else(new_bridge_token); + render_plugin_index( + &session_id, + &api_base, + &token, + query.document_id.as_deref(), + query.asset_id.as_deref(), + query.file_type.as_deref(), + query.doc_key.as_deref(), + query.page_origin.as_deref(), + ) +} + +pub async fn plugin_index_with_state( + Path(encoded_state): Path, + Query(query): Query, +) -> impl IntoResponse { + let state = decode_index_state(&encoded_state); + let session_id = non_empty(query.session_id) + .or_else(|| state.as_ref().map(|value| value.session_id.clone())) + .unwrap_or_else(|| "mnote-onlyoffice".into()); + let api_base = normalize_api_base(query.api_base.as_deref().or_else(|| { + state + .as_ref() + .map(|value| value.api_base.as_str()) + .filter(|value| !value.is_empty()) + })); + let document_id = query.document_id.as_deref().or_else(|| { + state + .as_ref() + .and_then(|value| value.document_id.as_deref()) + }); + let asset_id = query + .asset_id + .as_deref() + .or_else(|| state.as_ref().and_then(|value| value.asset_id.as_deref())); + let file_type = query + .file_type + .as_deref() + .or_else(|| state.as_ref().and_then(|value| value.file_type.as_deref())); + let doc_key = query + .doc_key + .as_deref() + .or_else(|| state.as_ref().and_then(|value| value.doc_key.as_deref())); + let page_origin = query.page_origin.as_deref().or_else(|| { + state + .as_ref() + .and_then(|value| value.page_origin.as_deref()) + }); + let token = non_empty(query.token) + .or_else(|| { + state + .as_ref() + .map(|value| value.token.as_str()) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned) + }) + .unwrap_or_else(new_bridge_token); + render_plugin_index( + &session_id, + &api_base, + &token, + document_id, + asset_id, + file_type, + doc_key, + page_origin, + ) +} + +fn render_plugin_index( + session_id: &str, + api_base: &str, + token: &str, + document_id: Option<&str>, + asset_id: Option<&str>, + file_type: Option<&str>, + doc_key: Option<&str>, + page_origin: Option<&str>, +) -> Html { + let html = format!( + r#" + + + + + + + + +"#, + session_id = json_string(session_id), + api_base = json_string(api_base), + token = json_string(token), + document_id = json_string(document_id.unwrap_or("")), + asset_id = json_string(asset_id.unwrap_or("")), + file_type = json_string(file_type.unwrap_or("")), + doc_key = json_string(doc_key.unwrap_or("")), + page_origin = json_string(page_origin.unwrap_or("")), + ); + Html(html) +} + +pub async fn register_session(Json(payload): Json) -> Response { + let Some(session_id) = non_empty(Some(payload.session_id)) else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + let Some(token) = non_empty(payload.token) else { + return unauthorized("onlyoffice_bridge_token_required", "缺少 bridge token"); + }; + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + let session = state.entry(session_id.clone()).or_default(); + session.token = Some(token); + session.last_seen_millis = now_millis(); + session.editor_type = payload + .editor_type + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + session.document_id = payload + .document_id + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + session.asset_id = payload + .asset_id + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + session.file_type = payload + .file_type + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + session.doc_key = payload + .doc_key + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + session.page_origin = payload + .page_origin + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned); + json_response(json!({ + "ok": true, + "sessionId": session_id, + "editorType": session.editor_type.clone().unwrap_or_default(), + "documentId": session.document_id.clone().unwrap_or_default(), + "assetId": session.asset_id.clone().unwrap_or_default(), + "fileType": session.file_type.clone().unwrap_or_default(), + "docKey": session.doc_key.clone().unwrap_or_default(), + "pageOrigin": session.page_origin.clone().unwrap_or_default() + })) +} + +pub async fn list_sessions() -> Response { + json_response(json!({ + "ok": true, + "sessions": session_infos() + })) +} + +pub async fn current_session() -> Response { + let current = session_infos().into_iter().next(); + json_response(json!({ + "ok": true, + "session": current + })) +} + +pub async fn close_session(Json(payload): Json) -> Response { + let Some(session_id) = non_empty(Some(payload.session_id)) else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + if let Err(response) = ensure_session_token(&session_id, payload.token.as_deref()) { + return response; + } + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + let closed = state.remove(&session_id).is_some(); + json_response(json!({ + "ok": true, + "sessionId": session_id, + "closed": closed + })) +} + +pub async fn capabilities() -> Response { + json_response(capability_payload()) +} + +pub fn capability_payload() -> Value { + json!({ + "ok": true, + "schema": "mnote.onlyoffice.bridge_capabilities.v1", + "guid": MNOTE_ONLYOFFICE_BRIDGE_GUID, + "actions": [ + "selection.get", + "document.insert_text", + "document.replace_selection", + "document.insert_html", + "document.export", + "document.search_replace", + "document.insert_table", + "document.get_comments", + "document.add_comment", + "sheet.get_sheets", + "sheet.add_sheet", + "sheet.rename_sheet", + "sheet.get_range", + "sheet.get_range_values", + "sheet.get_values", + "sheet.set_value", + "sheet.set_formula", + "sheet.batch_set_values", + "sheet.set_range_values", + "sheet.format_range", + "sheet.set_dimensions", + "sheet.sort_range", + "sheet.add_chart", + "presentation.get_slides", + "presentation.get_slide_texts", + "presentation.get_shapes", + "presentation.add_text_slide", + "presentation.replace_text", + "presentation.set_shape_text", + "presentation.delete_slide", + "presentation.add_table", + "presentation.clear_slide", + "presentation.add_shape" + ], + "editors": { + "word": ["selection.get", "document.insert_text", "document.replace_selection", "document.insert_html", "document.export", "document.search_replace", "document.insert_table", "document.get_comments", "document.add_comment"], + "cell": ["selection.get", "sheet.get_sheets", "sheet.add_sheet", "sheet.rename_sheet", "sheet.get_range", "sheet.get_range_values", "sheet.get_values", "sheet.set_value", "sheet.set_formula", "sheet.batch_set_values", "sheet.set_range_values", "sheet.format_range", "sheet.set_dimensions", "sheet.sort_range", "sheet.add_chart"], + "slide": ["selection.get", "presentation.get_slides", "presentation.get_slide_texts", "presentation.get_shapes", "presentation.add_text_slide", "presentation.replace_text", "presentation.set_shape_text", "presentation.delete_slide", "presentation.add_table", "presentation.clear_slide", "presentation.add_shape"] + } + }) +} + +pub async fn enqueue_command(Json(payload): Json) -> Response { + let Some(session_id) = non_empty(Some(payload.session_id)) else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + if let Err(response) = ensure_session_token(&session_id, payload.token.as_deref()) { + return response; + } + let Some(action) = non_empty(Some(payload.action)) else { + return bad_request("onlyoffice_bridge_action_required", "缺少 action"); + }; + let command = push_command(&session_id, action, payload.payload); + json_response(json!({ + "ok": true, + "sessionId": session_id, + "command": command + })) +} + +pub async fn next_command(Query(query): Query) -> Response { + let Some(session_id) = non_empty(Some(query.session_id)) else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + if let Err(response) = ensure_session_token(&session_id, query.token.as_deref()) { + return response; + } + let timeout = query + .timeout_ms + .unwrap_or(MAX_LONG_POLL_MS) + .min(MAX_LONG_POLL_MS); + let deadline = Instant::now() + Duration::from_millis(timeout); + loop { + if let Some(command) = pop_command(&session_id) { + return json_response(json!(command)); + } + if Instant::now() >= deadline { + return StatusCode::NO_CONTENT.into_response(); + } + sleep(Duration::from_millis(LONG_POLL_INTERVAL_MS)).await; + } +} + +pub async fn post_result(Json(payload): Json) -> Response { + let Some(session_id) = payload + .get("sessionId") + .and_then(Value::as_str) + .map(str::to_string) + .and_then(|value| non_empty(Some(value))) + else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + if let Err(response) = + ensure_session_token(&session_id, payload.get("token").and_then(Value::as_str)) + { + return response; + } + let Ok(result) = serde_json::from_value::(payload) else { + return bad_request("onlyoffice_bridge_result_invalid", "bridge result 格式无效"); + }; + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + let session = state.entry(session_id.clone()).or_default(); + session.results.insert(result.id.clone(), result.clone()); + json_response(json!({ + "ok": true, + "sessionId": session_id, + "result": result + })) +} + +pub async fn get_result(Query(query): Query) -> Response { + let Some(session_id) = non_empty(Some(query.session_id)) else { + return bad_request("onlyoffice_bridge_session_required", "缺少 sessionId"); + }; + let Some(command_id) = non_empty(Some(query.command_id)) else { + return bad_request("onlyoffice_bridge_command_required", "缺少 commandId"); + }; + if let Err(response) = ensure_session_token(&session_id, query.token.as_deref()) { + return response; + } + let timeout = query + .timeout_ms + .unwrap_or(MAX_LONG_POLL_MS) + .min(MAX_LONG_POLL_MS); + let deadline = Instant::now() + Duration::from_millis(timeout); + loop { + if let Some(result) = take_result(&session_id, &command_id) { + return json_response(json!(result)); + } + if Instant::now() >= deadline { + return StatusCode::NO_CONTENT.into_response(); + } + sleep(Duration::from_millis(LONG_POLL_INTERVAL_MS)).await; + } +} + +pub fn session_info(session_id: &str) -> Option { + let session_id = session_id.trim(); + if session_id.is_empty() { + return None; + } + session_infos() + .into_iter() + .find(|session| session.session_id == session_id) +} + +pub fn session_token_matches(session_id: &str, token: &str) -> bool { + let session_id = session_id.trim(); + let token = token.trim(); + if session_id.is_empty() || token.is_empty() { + return false; + } + let state = bridge_state().lock().expect("bridge state lock poisoned"); + state + .get(session_id) + .and_then(|session| session.token.as_deref()) + .is_some_and(|expected| expected == token) +} + +pub fn session_infos() -> Vec { + let state = bridge_state().lock().expect("bridge state lock poisoned"); + let mut sessions = state + .iter() + .map(|(session_id, session)| (session_id.clone(), session.last_seen_millis)) + .collect::>(); + sessions.sort_by(|(_, left), (_, right)| right.cmp(left)); + sessions + .into_iter() + .filter_map(|(session_id, _)| { + let session = state.get(&session_id)?; + Some(BridgeSessionInfo { + session_id: session_id.clone(), + editor_type: session.editor_type.clone(), + document_id: session.document_id.clone(), + asset_id: session.asset_id.clone(), + file_type: session.file_type.clone(), + doc_key: session.doc_key.clone(), + page_origin: session.page_origin.clone(), + last_seen_millis: session.last_seen_millis, + pending_commands: session.queue.len(), + pending_results: session.results.len(), + }) + }) + .collect() +} + +pub async fn run_bridge_command( + session_id: &str, + action: &str, + payload: Value, + timeout_ms: u64, +) -> Result { + let session_id = session_id.trim(); + if session_id.is_empty() { + return Err(BridgeRunError::BadRequest( + "缺少 ONLYOFFICE bridge sessionId".into(), + )); + } + let action = action.trim(); + if action.is_empty() { + return Err(BridgeRunError::BadRequest( + "缺少 ONLYOFFICE bridge action".into(), + )); + } + let token = { + let state = bridge_state().lock().expect("bridge state lock poisoned"); + state + .get(session_id) + .and_then(|session| session.token.clone()) + .ok_or_else(|| { + BridgeRunError::BadRequest("ONLYOFFICE bridge session 未注册或缺少 token".into()) + })? + }; + let command = push_command(session_id, action.to_string(), payload); + let timeout = timeout_ms.min(MAX_LONG_POLL_MS); + let deadline = Instant::now() + Duration::from_millis(timeout); + loop { + if ensure_session_token(session_id, Some(&token)).is_err() { + return Err(BridgeRunError::BadRequest( + "ONLYOFFICE bridge session token 已失效".into(), + )); + } + if let Some(result) = take_result(session_id, &command.id) { + return Ok(result); + } + if Instant::now() >= deadline { + return Err(BridgeRunError::Timeout { + session_id: session_id.to_string(), + command_id: command.id, + }); + } + sleep(Duration::from_millis(LONG_POLL_INTERVAL_MS)).await; + } +} + +#[derive(Debug, Clone)] +pub enum BridgeRunError { + BadRequest(String), + Timeout { + session_id: String, + command_id: String, + }, +} + +fn bridge_state() -> &'static Mutex> { + BRIDGE_STATE.get_or_init(|| Mutex::new(HashMap::new())) +} + +fn push_command(session_id: &str, action: String, payload: Value) -> BridgeCommandWire { + let command = BridgeCommandWire { + id: format!( + "oo_cmd_{}_{}", + now_millis(), + BRIDGE_COMMAND_COUNTER.fetch_add(1, Ordering::Relaxed) + ), + action, + payload, + }; + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + state + .entry(session_id.to_string()) + .or_default() + .queue + .push_back(command.clone()); + command +} + +fn pop_command(session_id: &str) -> Option { + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + let session = state.entry(session_id.to_string()).or_default(); + session.last_seen_millis = now_millis(); + session.queue.pop_front() +} + +fn take_result(session_id: &str, command_id: &str) -> Option { + let mut state = bridge_state().lock().expect("bridge state lock poisoned"); + state + .get_mut(session_id) + .and_then(|session| session.results.remove(command_id)) +} + +fn non_empty(value: Option) -> Option { + value + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) +} + +fn normalize_api_base(value: Option<&str>) -> String { + value + .map(str::trim) + .filter(|value| !value.is_empty()) + .unwrap_or("http://127.0.0.1:3000") + .trim_end_matches('/') + .to_string() +} + +fn encode_index_state( + session_id: &str, + api_base: &str, + token: &str, + document_id: Option<&str>, + asset_id: Option<&str>, + file_type: Option<&str>, + doc_key: Option<&str>, + page_origin: Option<&str>, +) -> String { + let payload = json!(BridgePluginIndexState { + session_id: session_id.to_string(), + api_base: api_base.to_string(), + token: token.to_string(), + document_id: document_id + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), + asset_id: asset_id + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), + file_type: file_type + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), + doc_key: doc_key + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), + page_origin: page_origin + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(ToOwned::to_owned), + }); + URL_SAFE_NO_PAD.encode(payload.to_string()) +} + +fn decode_index_state(encoded_state: &str) -> Option { + let bytes = URL_SAFE_NO_PAD.decode(encoded_state.as_bytes()).ok()?; + serde_json::from_slice(&bytes).ok() +} + +fn json_response(payload: Value) -> Response { + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_TYPE, + HeaderValue::from_static("application/json; charset=utf-8"), + ); + (StatusCode::OK, headers, payload.to_string()).into_response() +} + +fn unauthorized(code: &'static str, message: &'static str) -> Response { + ( + StatusCode::UNAUTHORIZED, + Json(json!({ + "ok": false, + "code": code, + "message": message + })), + ) + .into_response() +} + +fn bad_request(code: &'static str, message: &'static str) -> Response { + ( + StatusCode::BAD_REQUEST, + Json(json!({ + "ok": false, + "code": code, + "message": message + })), + ) + .into_response() +} + +fn new_bridge_token() -> String { + Uuid::new_v4().to_string() +} + +fn ensure_session_token(session_id: &str, token: Option<&str>) -> Result<(), Response> { + let Some(token) = token.map(str::trim).filter(|value| !value.is_empty()) else { + return Err(unauthorized( + "onlyoffice_bridge_token_required", + "缺少 bridge token", + )); + }; + let state = bridge_state().lock().expect("bridge state lock poisoned"); + match state + .get(session_id) + .and_then(|session| session.token.as_deref()) + { + Some(expected) if expected == token => Ok(()), + Some(_) => Err(unauthorized( + "onlyoffice_bridge_token_invalid", + "bridge token 无效", + )), + None => Err(unauthorized( + "onlyoffice_bridge_session_unregistered", + "bridge session 未注册", + )), + } +} + +fn json_string(input: &str) -> String { + serde_json::to_string(input).unwrap_or_else(|_| "\"\"".into()) +} + +fn now_millis() -> u128 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_millis() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn bridge_plugin_config_exposes_dynamic_index_and_guid() { + let response = plugin_config(Query(BridgePluginConfigQuery { + session_id: Some("session-a".into()), + api_base: Some("http://127.0.0.1:3000/".into()), + token: Some("token-a".into()), + document_id: Some("doc-a".into()), + asset_id: Some("asset-a".into()), + file_type: Some("xlsx".into()), + doc_key: Some("doc-key-a".into()), + page_origin: Some("http://127.0.0.1:3000".into()), + })) + .await; + assert_eq!(response.status(), StatusCode::OK); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + assert_eq!(payload["guid"], MNOTE_ONLYOFFICE_BRIDGE_GUID); + assert_eq!(payload["version"], "0.1.0"); + let url = payload["variations"][0]["url"].as_str().unwrap_or_default(); + assert!(url.contains("/api/onlyoffice/bridge/plugin/index")); + assert!(!url.contains('?')); + let encoded_state = url.rsplit('/').next().unwrap_or_default(); + let state = decode_index_state(encoded_state).expect("encoded state"); + assert_eq!(state.session_id, "session-a"); + assert_eq!(state.api_base, "http://127.0.0.1:3000"); + assert_eq!(state.token, "token-a"); + assert_eq!(state.document_id.as_deref(), Some("doc-a")); + assert_eq!(state.asset_id.as_deref(), Some("asset-a")); + assert_eq!(state.file_type.as_deref(), Some("xlsx")); + assert_eq!(state.doc_key.as_deref(), Some("doc-key-a")); + assert_eq!(state.page_origin.as_deref(), Some("http://127.0.0.1:3000")); + } + + #[tokio::test] + async fn bridge_plugin_index_accepts_path_state_with_onlyoffice_query_params() { + let encoded_state = encode_index_state( + "session-b", + "http://127.0.0.1:3000", + "token-b", + Some("doc-b"), + Some("asset-b"), + Some("pptx"), + Some("doc-key-b"), + Some("http://127.0.0.1:3001"), + ); + let response = plugin_index_with_state( + Path(encoded_state), + Query(BridgePluginIndexQuery { + session_id: None, + api_base: None, + token: None, + document_id: None, + asset_id: None, + file_type: None, + doc_key: None, + page_origin: None, + }), + ) + .await + .into_response(); + assert_eq!(response.status(), StatusCode::OK); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let html = String::from_utf8(body.to_vec()).expect("html"); + assert!(html.contains(r#"var sessionId = "session-b";"#)); + assert!(html.contains(r#"var apiBase = "http://127.0.0.1:3000";"#)); + assert!(html.contains(r#"documentId: "doc-b""#)); + assert!(html.contains(r#"assetId: "asset-b""#)); + assert!(html.contains(r#"fileType: "pptx""#)); + assert!(html.contains(r#"docKey: "doc-key-b""#)); + assert!(html.contains(r#"pageOrigin: "http://127.0.0.1:3001""#)); + } + + #[tokio::test] + async fn bridge_plugin_index_exposes_second_batch_recipe_actions() { + let response = plugin_index(Query(BridgePluginIndexQuery { + session_id: Some("session-recipes".into()), + api_base: Some("http://127.0.0.1:3000".into()), + token: Some("token-recipes".into()), + document_id: None, + asset_id: None, + file_type: None, + doc_key: None, + page_origin: None, + })) + .await + .into_response(); + assert_eq!(response.status(), StatusCode::OK); + let body = axum::body::to_bytes(response.into_body(), usize::MAX) + .await + .expect("body"); + let html = String::from_utf8(body.to_vec()).expect("html"); + assert!(html.contains(r#"case "document.search_replace":"#)); + assert!(html.contains(r#"case "document.insert_table":"#)); + assert!(html.contains(r#"case "document.get_comments":"#)); + assert!(html.contains(r#"case "document.add_comment":"#)); + assert!(html.contains(r#"case "sheet.get_sheets":"#)); + assert!(html.contains(r#"case "sheet.add_sheet":"#)); + assert!(html.contains(r#"case "sheet.rename_sheet":"#)); + assert!(html.contains(r#"case "sheet.get_range_values":"#)); + assert!(html.contains(r#"case "sheet.set_range_values":"#)); + assert!(html.contains(r#"case "sheet.format_range":"#)); + assert!(html.contains(r#"case "sheet.set_dimensions":"#)); + assert!(html.contains(r#"case "sheet.sort_range":"#)); + assert!(html.contains(r#"case "sheet.add_chart":"#)); + assert!(html.contains("range.SetSort")); + assert!(html.contains("worksheet.AddChart")); + assert!(html.contains(r#"case "presentation.get_slide_texts":"#)); + assert!(html.contains(r#"case "presentation.get_shapes":"#)); + assert!(html.contains(r#"case "presentation.replace_text":"#)); + assert!(html.contains(r#"case "presentation.set_shape_text":"#)); + assert!(html.contains(r#"case "presentation.delete_slide":"#)); + assert!(html.contains(r#"case "presentation.add_table":"#)); + assert!(html.contains(r#"case "presentation.clear_slide":"#)); + assert!(html.contains(r#"case "presentation.add_shape":"#)); + assert!(html.contains("slide.AddObject(table)")); + assert!(html.contains("slide.RemoveAllObjects()")); + assert!(html.contains("Api.CreateShape")); + assert!(html.contains("function expectedEditorTypeForAction(action)")); + assert!(html.contains(r#"if (name.indexOf("document.") === 0) return "word";"#)); + assert!(html.contains(r#"if (name.indexOf("sheet.") === 0) return "cell";"#)); + assert!(html.contains(r#"if (name.indexOf("presentation.") === 0) return "slide";"#)); + assert!(html.contains("onlyoffice_editor_type_mismatch")); + } + + #[tokio::test] + async fn bridge_session_registration_lists_metadata_and_capabilities() { + let session_id = format!("test-session-meta-{}", now_millis()); + let token = format!("token-{session_id}"); + let registered = register_session(Json(BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token), + editor_type: Some("slide".into()), + document_id: Some("doc-meta".into()), + asset_id: Some("asset-meta".into()), + file_type: Some("pptx".into()), + doc_key: Some("doc-key-meta".into()), + page_origin: Some("http://127.0.0.1:3000".into()), + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); + + let listed = list_sessions().await; + assert_eq!(listed.status(), StatusCode::OK); + let body = axum::body::to_bytes(listed.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + let session = payload["sessions"] + .as_array() + .expect("sessions") + .iter() + .find(|value| value["sessionId"] == session_id) + .expect("registered session"); + assert_eq!(session["editorType"], "slide"); + assert_eq!(session["documentId"], "doc-meta"); + assert_eq!(session["assetId"], "asset-meta"); + assert_eq!(session["fileType"], "pptx"); + assert_eq!(session["docKey"], "doc-key-meta"); + assert_eq!(session["pageOrigin"], "http://127.0.0.1:3000"); + + let current = current_session().await; + assert_eq!(current.status(), StatusCode::OK); + let body = axum::body::to_bytes(current.into_body(), usize::MAX) + .await + .expect("current body"); + let payload: Value = serde_json::from_slice(&body).expect("current json"); + assert!(payload["session"].is_object() || payload["session"].is_null()); + + let closed = close_session(Json(BridgeCloseSessionPayload { + session_id: session_id.clone(), + token: Some(format!("token-{session_id}")), + })) + .await; + assert_eq!(closed.status(), StatusCode::OK); + assert!(session_info(&session_id).is_none()); + + let capabilities = capabilities().await; + let body = axum::body::to_bytes(capabilities.into_body(), usize::MAX) + .await + .expect("capabilities body"); + let payload: Value = serde_json::from_slice(&body).expect("capabilities json"); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "presentation.set_shape_text")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "sheet.format_range")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "presentation.delete_slide")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "document.insert_table")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "document.get_comments")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "document.add_comment")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "sheet.sort_range")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "sheet.add_chart")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "presentation.add_table")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "presentation.clear_slide")); + assert!(payload["actions"] + .as_array() + .expect("actions") + .iter() + .any(|action| action == "presentation.add_shape")); + } + + #[tokio::test] + async fn bridge_queue_round_trips_command_and_result() { + let session_id = format!("test-session-{}", now_millis()); + let token = format!("token-{session_id}"); + let registered = register_session(Json(BridgeSessionPayload { + session_id: session_id.clone(), + token: Some(token.clone()), + editor_type: Some("word".into()), + document_id: None, + asset_id: None, + file_type: None, + doc_key: None, + page_origin: None, + })) + .await; + assert_eq!(registered.status(), StatusCode::OK); + + let denied = enqueue_command(Json(BridgeEnqueuePayload { + session_id: session_id.clone(), + token: None, + action: "selection.get".into(), + payload: json!({"sample": true}), + })) + .await; + assert_eq!(denied.status(), StatusCode::UNAUTHORIZED); + + let enqueue = enqueue_command(Json(BridgeEnqueuePayload { + session_id: session_id.clone(), + token: Some(token.clone()), + action: "selection.get".into(), + payload: json!({"sample": true}), + })) + .await; + assert_eq!(enqueue.status(), StatusCode::OK); + let body = axum::body::to_bytes(enqueue.into_body(), usize::MAX) + .await + .expect("body"); + let payload: Value = serde_json::from_slice(&body).expect("json"); + let command_id = payload["command"]["id"].as_str().unwrap().to_string(); + + let next = next_command(Query(BridgeNextQuery { + session_id: session_id.clone(), + token: Some(token.clone()), + timeout_ms: Some(1), + })) + .await; + assert_eq!(next.status(), StatusCode::OK); + let body = axum::body::to_bytes(next.into_body(), usize::MAX) + .await + .expect("body"); + let command: BridgeCommandWire = serde_json::from_slice(&body).expect("command"); + assert_eq!(command.id, command_id); + assert_eq!(command.action, "selection.get"); + + let posted = post_result(Json(json!({ + "sessionId": session_id, + "token": token, + "id": command_id, + "ok": true, + "result": {"text": "hello"} + }))) + .await; + assert_eq!(posted.status(), StatusCode::OK); + } +} diff --git a/rust/crates/mnote-web/src/routes/resource_trash.rs b/rust/crates/mnote-web/src/routes/resource_trash.rs index 6fd50138..e57c5544 100644 --- a/rust/crates/mnote-web/src/routes/resource_trash.rs +++ b/rust/crates/mnote-web/src/routes/resource_trash.rs @@ -1215,10 +1215,11 @@ mod tests { ) .await .expect("response"); - assert_eq!(response.status(), StatusCode::OK); + let status = response.status(); let body = to_bytes(response.into_body(), usize::MAX) .await .expect("body"); + assert_eq!(status, StatusCode::OK, "{}", String::from_utf8_lossy(&body)); serde_json::from_slice(&body).expect("json") } @@ -1236,10 +1237,11 @@ mod tests { ) .await .expect("response"); - assert_eq!(response.status(), StatusCode::OK); + let status = response.status(); let body = to_bytes(response.into_body(), usize::MAX) .await .expect("body"); + assert_eq!(status, StatusCode::OK, "{}", String::from_utf8_lossy(&body)); serde_json::from_slice(&body).expect("json") } @@ -1256,10 +1258,11 @@ mod tests { ) .await .expect("response"); - assert_eq!(response.status(), StatusCode::OK); + let status = response.status(); let body = to_bytes(response.into_body(), usize::MAX) .await .expect("body"); + assert_eq!(status, StatusCode::OK, "{}", String::from_utf8_lossy(&body)); serde_json::from_slice(&body).expect("json") } diff --git a/rust/crates/mnote-web/src/routes/search.rs b/rust/crates/mnote-web/src/routes/search.rs index 319bc525..58f2be06 100644 --- a/rust/crates/mnote-web/src/routes/search.rs +++ b/rust/crates/mnote-web/src/routes/search.rs @@ -192,6 +192,7 @@ pub async fn documents( body.limit.unwrap_or(30), filters.title_only.unwrap_or(false), filters.exact.unwrap_or(false), + filters.include_ocr.unwrap_or(false), )? } else { load_search_results_with_filters( diff --git a/rust/crates/mnote-web/src/routes/web_shell.rs b/rust/crates/mnote-web/src/routes/web_shell.rs index 5acb3bcf..6dbffa49 100644 --- a/rust/crates/mnote-web/src/routes/web_shell.rs +++ b/rust/crates/mnote-web/src/routes/web_shell.rs @@ -1623,6 +1623,104 @@ pub async fn sidebar_page_ai_runtime_asset() -> Response { .unwrap_or_else(|_| Response::new(Body::empty())) } +pub async fn sidebar_page_ai_markdown_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-markdown-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_render_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-render-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_permission_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-permission-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_profile_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-profile-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_session_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-session-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_skill_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-skill-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + +pub async fn sidebar_page_ai_target_runtime_asset() -> Response { + const JS: &str = include_str!("../../browser/sidebar-page-ai-target-runtime.js"); + Response::builder() + .status(StatusCode::OK) + .header( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + ) + .header(header::CACHE_CONTROL, runtime_asset_cache_control()) + .header(HEADER_MNOTE_WEB_OWNER, "mnote-web") + .body(browser_runtime_js_body(JS)) + .unwrap_or_else(|_| Response::new(Body::empty())) +} + pub async fn sidebar_page_settings_runtime_asset() -> Response { const JS: &str = include_str!("../../browser/sidebar-page-settings-runtime.js"); Response::builder() @@ -3151,8 +3249,18 @@ mod tests { "const pageBodyTiptapDocument = (body, fallbackText = '', context = null) => {" )); assert!(conversion_runtime.contains("body?.blockDocument || body?.block_document")); + let block_document_source_index = conversion_runtime + .find("if (blockDocument) return 'page_aggregate.block_document';") + .expect("blockDocument source should be explicit"); + let local_markdown_source_index = conversion_runtime + .find("return 'local_markdown.content';") + .expect("local markdown legacy fallback should remain explicit"); assert!( - conversion_runtime.contains("localizeTiptapAssetUrls(toTiptapDocument(body.content") + block_document_source_index < local_markdown_source_index, + "local-first 浏览器转换应优先消费 blockDocument,再降级到 body.content" + ); + assert!( + conversion_runtime.contains("localizeTiptapAssetUrls(toTiptapDocument(body?.content") ); assert!(conversion_runtime.contains("localAttachmentClassForTiptapHref")); assert!(conversion_runtime.contains("mnote-uploaded-attachment-code")); @@ -4428,4 +4536,15 @@ mod tests { "block.contentNodes.map((node) => typeof node?.text === 'string' ? node.text : '').join('')" )); } + + #[test] + fn mindmap_resize_runtime_contract_includes_dimension_attrs() { + let runtime = DOCUMENT_TIPTAP_CONVERSION_RUNTIME_JS; + assert!(runtime.contains("mindmapWidth")); + assert!(runtime.contains("mindmapHeight")); + assert!(runtime.contains("data?.mindmap_width")); + assert!(runtime.contains("dataset.mnoteMindmapWidth")); + assert!(SIDEBAR_PAGE_SETTINGS_RUNTIME_JS.contains("--mnote-mindmap-block-max-width")); + assert!(SIDEBAR_PAGE_SETTINGS_RUNTIME_JS.contains("currentPageWidthPreferences().mindmap")); + } } diff --git a/rust/crates/mnote-web/src/ssr/pages/layout.rs b/rust/crates/mnote-web/src/ssr/pages/layout.rs index 1f0cc2a8..a9d62d9f 100644 --- a/rust/crates/mnote-web/src/ssr/pages/layout.rs +++ b/rust/crates/mnote-web/src/ssr/pages/layout.rs @@ -230,6 +230,18 @@ mod tests { include_str!("../../../browser/sidebar-page-tree-runtime.js"); const SIDEBAR_PAGE_AI_RUNTIME_JS: &str = include_str!("../../../browser/sidebar-page-ai-runtime.js"); + const SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-render-runtime.js"); + const SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-permission-runtime.js"); + const SIDEBAR_PAGE_AI_PROFILE_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-profile-runtime.js"); + const SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-session-runtime.js"); + const SIDEBAR_PAGE_AI_SKILL_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-skill-runtime.js"); + const SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS: &str = + include_str!("../../../browser/sidebar-page-ai-target-runtime.js"); const SIDEBAR_PAGE_SETTINGS_RUNTIME_JS: &str = include_str!("../../../browser/sidebar-page-settings-runtime.js"); const FILETREE_CONTEXT_MENU_RUNTIME_JS: &str = @@ -504,25 +516,62 @@ mod tests { ); } + #[test] + fn page_ai_agent_target_picker_contract_is_visible_and_serialized() { + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiRenderRuntime")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS + .contains("export function createSidebarPageAiRenderRuntime")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-target-button")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-target-popover")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-target-option")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-target-chip")); + assert!(SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS.contains("primaryTargetId")); + assert!(SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS.contains("targets: [")); + assert!(SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS.contains("policy: {")); + } + #[test] fn page_ai_uses_backend_acp_session_runtime_store() { - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiLoadBackendSessions")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("/api/hermes/client/sessions?")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("params.set('source', 'acp')")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiLoadBackendSessionDetail")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiSearchBackendSessions")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-session-rename")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-session-delete")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-session-resume")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-session-search")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiSessionRuntime")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiSkillRuntime")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiTargetRuntime")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("function renderPageAiControls")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("function ensurePageAiDrawer")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("function renderPageAiConversation")); + assert!(SIDEBAR_PAGE_AI_SKILL_RUNTIME_JS + .contains("export function createSidebarPageAiSkillRuntime")); + assert!(SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS + .contains("export function createSidebarPageAiTargetRuntime")); + assert!( + SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS.contains("function currentPageAiOpenEditorsSnapshot") + ); + assert!(SIDEBAR_PAGE_AI_TARGET_RUNTIME_JS.contains("mnote.agent_target_package.v1")); + assert!(SIDEBAR_PAGE_AI_SKILL_RUNTIME_JS.contains("function pageAiSkillSourceOptions")); + assert!(SIDEBAR_PAGE_AI_SKILL_RUNTIME_JS.contains("function pageAiSkillPreferenceTable")); + assert!(SIDEBAR_PAGE_AI_SKILL_RUNTIME_JS.contains("ai.agent.reasonix.memory_enabled")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("function pageAiLoadBackendSessions")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("/api/hermes/client/sessions?")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("params.set('source', 'acp')")); + assert!( + SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("function pageAiLoadBackendSessionDetail") + ); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("function pageAiSearchBackendSessions")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-session-rename")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-session-delete")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-session-resume")); + assert!(SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-session-search")); assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("pageAiUsageSummary")); assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("usage.updated")); assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("thought.delta")); assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("permission.requested")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-permission-action=\"allow\"")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-permission-action=\"deny\"")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiHidePermissionDialog")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("if (!message.resolved)")); + assert!(SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS + .contains("data-page-ai-permission-action=\"allow\"")); + assert!(SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS + .contains("data-page-ai-permission-action=\"deny\"")); + assert!( + SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS.contains("function pageAiHidePermissionDialog") + ); + assert!(SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS.contains("if (!message.resolved)")); assert!( !SIDEBAR_PAGE_AI_RUNTIME_JS.contains("(item.resolved ? ' disabled' : '')"), "已决 ACP permission 事件不能继续展示假审批按钮" @@ -536,38 +585,50 @@ mod tests { "ACP PlanUpdate 事件应通过 plan.updated SSE 转发到前端" ); assert!( - SIDEBAR_PAGE_AI_RUNTIME_JS.contains("data-page-ai-plan"), + SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("data-page-ai-plan"), "plan 消息应渲染为 data-page-ai-plan 标记的轻量系统状态面板" ); assert!( - SIDEBAR_PAGE_AI_RUNTIME_JS.contains("执行计划 · "), + SIDEBAR_PAGE_AI_RENDER_RUNTIME_JS.contains("执行计划 · "), "plan 面板标题应显示执行计划和步数" ); } #[test] fn page_ai_session_ui_labels_local_shared_and_cloud_storage() { - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiSessionStorageLabel")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("local_private")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("local_shared")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("convex_acp_runtime_store")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("本地私有")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("共享会话")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("云端会话")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("sessionStorage:")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("permissionLevel:")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("shareId:")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("function pageAiSessionStorageLabel")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("local_private")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("local_shared")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("convex_acp_runtime_store")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("本地私有")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("共享会话")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("云端会话")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("sessionStorage:")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("permissionLevel:")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS.contains("shareId:")); } #[test] fn page_ai_acp_runtime_defaults_to_reasonix_and_keeps_hermes_switch() { assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("var PAGE_AI_SESSION_STORAGE_VERSION = 3")); - assert!(SIDEBAR_TREE_RUNTIME_JS.contains("pageAiAcpRuntime: 'reasonix'")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function pageAiNormalizeAcpRuntimes")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("return ['reasonix', 'hermes']")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function ensurePageAiStateFacade")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("pageAiAcpRuntime: 'reasonix'")); + assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("pageAiAcpRuntime: 'reasonix'")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiPermissionRuntime")); + assert!(SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS.contains("function pageAiResolvePermission")); + assert!(SIDEBAR_PAGE_AI_PERMISSION_RUNTIME_JS.contains("resolve-permission")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("createSidebarPageAiProfileRuntime")); + assert!(SIDEBAR_PAGE_AI_PROFILE_RUNTIME_JS.contains("function pageAiNormalizeAcpRuntimes")); + assert!(SIDEBAR_PAGE_AI_PROFILE_RUNTIME_JS.contains("return ['reasonix', 'hermes']")); assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("pageAiNormalizeAcpRuntimes(acpRuntimes)")); - assert!(SIDEBAR_TREE_RUNTIME_JS.contains("pageAiAcpRuntimeSelect.value || 'reasonix'")); - assert!(SIDEBAR_PAGE_AI_RUNTIME_JS + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("pageAiAcpRuntimeSelect.value || 'reasonix'")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function handlePageAiClick")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function handlePageAiChange")); + assert!(SIDEBAR_PAGE_AI_RUNTIME_JS.contains("function installPageAiDelegates")); + assert!(SIDEBAR_TREE_RUNTIME_JS.contains("sidebarPageAi.installPageAiDelegates()")); + assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("sidebarPageAi.handlePageAi")); + assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("closestAction(e.target, '[data-page-ai-action")); + assert!(SIDEBAR_PAGE_AI_SESSION_RUNTIME_JS .contains("activeAcpRuntime: pageUiState.pageAiAcpRuntime || 'reasonix'")); assert!(!SIDEBAR_PAGE_AI_RUNTIME_JS.contains("默认 (Hermes HTTP)")); } @@ -1009,7 +1070,8 @@ mod tests { assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS .contains("data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell'")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("buildLocalOnlyOfficeOpenUrl")); - assert!(SIDEBAR_TREE_RUNTIME_JS.contains("isLocalAsset ? onlyOfficeUrl")); + assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS + .contains("var localOfficeUrl = buildLocalOnlyOfficeOpenUrl")); } #[test] @@ -1072,6 +1134,9 @@ mod tests { assert!(SIDEBAR_TREE_RUNTIME_JS.contains("installMnoteDevHotReload")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/dev/hot-reload")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-dev-hot-reload")); + assert!(SIDEBAR_TREE_RUNTIME_JS.contains("import.meta.url")); + assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnoteDevHotReloadEnabled()")); + assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("\n installMnoteDevHotReload();\n")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("window.clearInterval(timer)")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote:primary-document-activated")); assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote:page-aggregate-synced")); @@ -1591,6 +1656,11 @@ mod tests { .contains("openLocalOfficeFileInActiveTab(detail, 'edit')")); assert!(SIDEBAR_FILETREE_COMMAND_RUNTIME_JS .contains("openEditorAttachmentNewWindow(detail, 'edit')")); + assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS + .contains("var requestedOfficeMode = forceEditMode ? 'edit' : 'view';")); + assert!(!SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains( + "var requestedOfficeMode = forceNewWindow || forceEditMode ? 'edit' : 'view';" + )); assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("forceEditMode ? 'edit' : 'view'")); assert!(SIDEBAR_ATTACHMENT_OPEN_RUNTIME_JS .contains("url.searchParams.set('mode', requestedMode);")); diff --git a/rust/crates/mnote-web/src/ssr/styles.rs b/rust/crates/mnote-web/src/ssr/styles.rs index 21b61915..cc3d3d74 100644 --- a/rust/crates/mnote-web/src/ssr/styles.rs +++ b/rust/crates/mnote-web/src/ssr/styles.rs @@ -3898,6 +3898,7 @@ body { .wolai-page-ai-profile-select select, .wolai-page-ai-context-select select, .wolai-page-ai-skill-search input, +.wolai-page-ai-skill-search select, .wolai-page-ai-agent-profile select { width: 100%; min-width: 0; @@ -4499,25 +4500,48 @@ button.wolai-page-ai-message-text { } .wolai-page-ai-agent-picker, -.wolai-page-ai-context-picker { +.wolai-page-ai-context-picker, +.wolai-page-ai-target-picker { position: relative; flex: 0 0 auto; } .wolai-page-ai-agent-button, -.wolai-page-ai-context-button { +.wolai-page-ai-context-button, +.wolai-page-ai-target-button { font-size: 17px; line-height: 1; } .wolai-page-ai-agent-button[aria-expanded="true"], -.wolai-page-ai-context-button[aria-expanded="true"] { +.wolai-page-ai-context-button[aria-expanded="true"], +.wolai-page-ai-target-button[aria-expanded="true"] { border-color: rgba(27, 28, 28, 0.32); background: #F7F6F4; } +.wolai-page-ai-agent-chip, +.wolai-page-ai-target-chip { + display: inline-flex; + align-items: center; + min-width: 0; + max-width: 180px; + height: 26px; + padding: 0 8px; + border: 1px solid rgba(27, 28, 28, 0.1); + border-radius: 999px; + background: #F7F6F4; + color: #5A5A5A; + font-size: 12px; + line-height: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + .wolai-page-ai-agent-popover, -.wolai-page-ai-context-popover { +.wolai-page-ai-context-popover, +.wolai-page-ai-target-popover { position: absolute; left: 0; width: min(320px, calc(100vw - 44px)); @@ -4533,7 +4557,8 @@ button.wolai-page-ai-message-text { } .wolai-page-ai-agent-popover[hidden], -.wolai-page-ai-context-popover[hidden] { +.wolai-page-ai-context-popover[hidden], +.wolai-page-ai-target-popover[hidden] { display: none !important; } @@ -4552,12 +4577,26 @@ button.wolai-page-ai-message-text { gap: 8px; } -.wolai-page-ai-agent-option-list { +.wolai-page-ai-agent-option-list, +.wolai-page-ai-target-option-list { display: grid; gap: 6px; } -.wolai-page-ai-agent-option { +.wolai-page-ai-agent-popover-section { + display: grid; + gap: 6px; +} + +.wolai-page-ai-agent-popover-title { + color: #8B8782; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; +} + +.wolai-page-ai-agent-option, +.wolai-page-ai-target-option { display: grid; gap: 2px; width: 100%; @@ -4570,17 +4609,20 @@ button.wolai-page-ai-message-text { cursor: pointer; } -.wolai-page-ai-agent-option.is-active { +.wolai-page-ai-agent-option.is-active, +.wolai-page-ai-target-option.is-active { border-color: rgba(27, 28, 28, 0.2); background: #F7F6F4; } -.wolai-page-ai-agent-option-label { +.wolai-page-ai-agent-option-label, +.wolai-page-ai-target-option-label { font-size: 12px; font-weight: 600; } -.wolai-page-ai-agent-option-detail { +.wolai-page-ai-agent-option-detail, +.wolai-page-ai-target-option-detail { color: #8B8782; font-size: 11px; } diff --git a/rust/crates/mnote-web/src/transport/convex.rs b/rust/crates/mnote-web/src/transport/convex.rs index 7d566e52..207a4d79 100644 --- a/rust/crates/mnote-web/src/transport/convex.rs +++ b/rust/crates/mnote-web/src/transport/convex.rs @@ -2,9 +2,11 @@ use crate::app::AppConfig; use crate::context::RequestContext; use crate::error::WebError; use bridge_runtime::{ - RuntimeCommandArtifactPlan, RuntimeCommandExecutionPlan, RuntimeQueryExecutionPlan, + build_runtime_command_artifact_plan, RuntimeCommandArtifactPlan, RuntimeCommandExecutionPlan, + RuntimeQueryExecutionPlan, }; use serde_json::Value; +use time::{format_description::well_known::Rfc3339, OffsetDateTime}; #[derive(Debug)] pub struct RetiredCloudCommandExecution { @@ -184,23 +186,38 @@ pub async fn execute_retired_mutation_by_name( pub async fn persist_runtime_command_artifacts( _config: &AppConfig, - context: &RequestContext, + _context: &RequestContext, _artifacts: &RuntimeCommandArtifactPlan, ) -> Result<(), WebError> { - Err(retired_error(context, "convex_artifacts_retired")) + // Convex 已退役。Rust 侧仍会把 artifact plan 返回给调用方和 realtime + // consumer;这里保持 no-op,避免兼容路径因为历史持久化层退役而失败。 + Ok(()) } pub async fn execute_retired_command_plan_with_artifacts( config: &AppConfig, context: &RequestContext, - _runtime_context: &bridge_runtime::RuntimeBridgeContextWire, - _command: &bridge_runtime::RuntimeCommandEnvelopeWire, + runtime_context: &bridge_runtime::RuntimeBridgeContextWire, + command: &bridge_runtime::RuntimeCommandEnvelopeWire, plan: &RuntimeCommandExecutionPlan, ) -> Result { let result = execute_retired_command_plan(config, context, plan).await?; + let now = OffsetDateTime::now_utc() + .format(&Rfc3339) + .unwrap_or_else(|_| "1970-01-01T00:00:00Z".into()); + let artifacts = + build_runtime_command_artifact_plan(runtime_context, command, plan, &result, &now); + let artifact_error = if let Some(artifacts) = artifacts.as_ref() { + persist_runtime_command_artifacts(config, context, artifacts) + .await + .err() + .map(|error| error.message().to_string()) + } else { + None + }; Ok(RetiredCloudCommandExecution { result, - artifacts: None, - artifact_error: None, + artifacts, + artifact_error, }) } diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.d.ts b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.d.ts index d0dfa278..0d695e61 100644 --- a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.d.ts +++ b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.d.ts @@ -48,33 +48,33 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl export interface InitOutput { readonly memory: WebAssembly.Memory; - readonly mount_mindmap_shell: (a: any, b: any) => [number, number, number]; - readonly unmount_mindmap_shell: (a: number) => [number, number]; readonly mount: (a: any, b: any) => [number, number, number]; + readonly mount_mindmap_shell: (a: any, b: any) => [number, number, number]; readonly unmount: (a: number) => [number, number]; - readonly __wbg_intounderlyingsink_free: (a: number, b: number) => void; - readonly intounderlyingsink_write: (a: number, b: any) => any; - readonly intounderlyingsink_close: (a: number) => any; - readonly intounderlyingsink_abort: (a: number, b: any) => any; + readonly unmount_mindmap_shell: (a: number) => [number, number]; readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void; - readonly intounderlyingbytesource_type: (a: number) => number; readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number; - readonly intounderlyingbytesource_start: (a: number, b: any) => void; - readonly intounderlyingbytesource_pull: (a: number, b: any) => any; readonly intounderlyingbytesource_cancel: (a: number) => void; + readonly intounderlyingbytesource_pull: (a: number, b: any) => any; + readonly intounderlyingbytesource_start: (a: number, b: any) => void; + readonly intounderlyingbytesource_type: (a: number) => number; + readonly __wbg_intounderlyingsink_free: (a: number, b: number) => void; + readonly intounderlyingsink_abort: (a: number, b: any) => any; + readonly intounderlyingsink_close: (a: number) => any; + readonly intounderlyingsink_write: (a: number, b: any) => any; readonly __wbg_intounderlyingsource_free: (a: number, b: number) => void; - readonly intounderlyingsource_pull: (a: number, b: any) => any; readonly intounderlyingsource_cancel: (a: number) => void; - readonly wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12: (a: number, b: number, c: any) => [number, number]; - readonly wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a: (a: number, b: number, c: any, d: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5: (a: number, b: number, c: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__had771ddc65647798: (a: number, b: number, c: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a: (a: number, b: number, c: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4: (a: number, b: number, c: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf: (a: number, b: number, c: any) => void; - readonly wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f: (a: number, b: number) => void; - readonly wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5: (a: number, b: number) => void; - readonly wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c: (a: number, b: number) => void; + readonly intounderlyingsource_pull: (a: number, b: any) => any; + readonly wasm_bindgen__convert__closures_____invoke__h854f4676fa692669: (a: number, b: number, c: any) => [number, number]; + readonly wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350: (a: number, b: number, c: any, d: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__h9213ab6f3ef747a1: (a: number, b: number, c: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f: (a: number, b: number, c: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__h10d35e1548938147: (a: number, b: number, c: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4: (a: number, b: number, c: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__hdc2c23cc0c047a34: (a: number, b: number, c: any) => void; + readonly wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097: (a: number, b: number) => void; + readonly wasm_bindgen__convert__closures_____invoke__had164c21c04063ef: (a: number, b: number) => void; + readonly wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1: (a: number, b: number) => void; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; readonly __externref_table_alloc: () => number; diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js index e408e341..dc01c722 100644 --- a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js +++ b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js @@ -812,7 +812,7 @@ function __wbg_get_imports() { const a = state0.a; state0.a = 0; try { - return wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(a, state0.b, arg0, arg1); + return wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(a, state0.b, arg0, arg1); } finally { state0.a = a; } @@ -1232,48 +1232,48 @@ function __wbg_get_imports() { } }, arguments); }, __wbindgen_cast_0000000000000001: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1140, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1003, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`. + const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h9213ab6f3ef747a1); return ret; }, __wbindgen_cast_0000000000000002: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1192, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1132, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f); return ret; }, __wbindgen_cast_0000000000000003: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 969, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`. - const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__had771ddc65647798); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1194, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h854f4676fa692669); return ret; }, __wbindgen_cast_0000000000000004: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1090, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1100, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h10d35e1548938147); return ret; }, __wbindgen_cast_0000000000000005: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1140, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 1132, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4); return ret; }, __wbindgen_cast_0000000000000006: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("KeyboardEvent")], shim_idx: 637, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("KeyboardEvent")], shim_idx: 333, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__hdc2c23cc0c047a34); return ret; }, __wbindgen_cast_0000000000000007: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1092, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1102, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097); return ret; }, __wbindgen_cast_0000000000000008: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1107, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`. - const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1117, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`. + const ret = makeClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__had164c21c04063ef); return ret; }, __wbindgen_cast_0000000000000009: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1143, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. - const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c); + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 1134, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1); return ret; }, __wbindgen_cast_000000000000000a: function(arg0) { @@ -1316,47 +1316,47 @@ function __wbg_get_imports() { }; } -function wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f(arg0, arg1) { - wasm.wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f(arg0, arg1); +function wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097(arg0, arg1) { + wasm.wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097(arg0, arg1); } -function wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5(arg0, arg1) { - wasm.wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5(arg0, arg1); +function wasm_bindgen__convert__closures_____invoke__had164c21c04063ef(arg0, arg1) { + wasm.wasm_bindgen__convert__closures_____invoke__had164c21c04063ef(arg0, arg1); } -function wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c(arg0, arg1) { - wasm.wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c(arg0, arg1); +function wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1(arg0, arg1) { + wasm.wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1(arg0, arg1); } -function wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5(arg0, arg1, arg2) { - wasm.wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h9213ab6f3ef747a1(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__h9213ab6f3ef747a1(arg0, arg1, arg2); } -function wasm_bindgen__convert__closures_____invoke__had771ddc65647798(arg0, arg1, arg2) { - wasm.wasm_bindgen__convert__closures_____invoke__had771ddc65647798(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f(arg0, arg1, arg2); } -function wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a(arg0, arg1, arg2) { - wasm.wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h10d35e1548938147(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__h10d35e1548938147(arg0, arg1, arg2); } -function wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4(arg0, arg1, arg2) { - wasm.wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4(arg0, arg1, arg2); } -function wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf(arg0, arg1, arg2) { - wasm.wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__hdc2c23cc0c047a34(arg0, arg1, arg2) { + wasm.wasm_bindgen__convert__closures_____invoke__hdc2c23cc0c047a34(arg0, arg1, arg2); } -function wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12(arg0, arg1, arg2) { - const ret = wasm.wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12(arg0, arg1, arg2); +function wasm_bindgen__convert__closures_____invoke__h854f4676fa692669(arg0, arg1, arg2) { + const ret = wasm.wasm_bindgen__convert__closures_____invoke__h854f4676fa692669(arg0, arg1, arg2); if (ret[1]) { throw takeFromExternrefTable0(ret[0]); } } -function wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(arg0, arg1, arg2, arg3) { - wasm.wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a(arg0, arg1, arg2, arg3); +function wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(arg0, arg1, arg2, arg3) { + wasm.wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350(arg0, arg1, arg2, arg3); } diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm index 4cf5c48c88a66405ed38fcd1d3c1d8154463c9e9..d094e0b134fec297065b6d228379965a3ff91d8b 100644 GIT binary patch literal 1953483 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 z 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�`)vLRh3G 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�pL@|5ipj|}>b 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 }P?l76B2F;|0JUF+B&Nr9%}0yRbrP=Y!~q z{W$1&qDKi3r+|O}j)_eS761!L9icu`H?dSMUN9-69|yd{)G^=5sd|6|vra>4HVEdy znVMq*92%1_6%O>v7aL&En3$&*{FSlb2mkFPE%;B<((`Mncf{eE?;J*nl8w$4If+e= zltqh!r4CWKWu`qC^TYwom=C}Z|Knl=@n=-20g;1agWS)L}W5(Q%t1o>v?uvbw= zOgS6BuTHQ*oMg)(ObP@IqH65ybCj+wk5ZGN=Pa@ZlZ2!=hBTt??^TC-ysr5pE{YRY zbxDZ0CpO}0u(JGs9K4zlW8Dz-l`dTso{YJwT)LJ`MY!ArPGMViyWATLa&YM@LL&Db zY{yuq8P~27C&BNQrU|qn;!7t+(K`_n2Hub?0Hmm4yd#KdAfdU2?dO3rSg|t^Y-ou} zwWG$6ALA|*`(7H)Y_<`&ki~^BBfEJXQY7Xv!20p%XZ?8OtRD|~?&UGt#mPOa7QgWL zsfXMx^N_n`9`qM>KKsNK#&NJ#Hw-}di9}c~)_`+lLC)kNi`a>FC`cn4>BD9&B3Ij8*jhzb7Bl|ZvdL%fK@&yb zHdKY$dl8%QlolIWpRg6@MGx-6?JDAyB6@Z7tzB01NRT-0Xb#W6>eXLP*-K?h+r7ajDc}?9B21Lc#!$b~4(a1_=XOYQR=d@k1ui4Dz zcDKdc?pEy2V=PIrfbkOz?Xc4Kei7xgFP#N{MD@P!JhSU*31=2xJS7-xe2V3qch{mB zN$fL^y*tZ*Sk3(5XnK)=O3qCnc2gu2zgm85Z0-eVbXw;U<5}U1J*APt`t7bIZE?iN z81`&gTOgz)leYs?8I3`E$7yA&u)?lyC3}e`vAedJlmhTMXbdy}l^In~>ny-|B3~mk z2|KBs9b+8%)L2?ltJA{rMG|4Uk@dncqnAAd_KK`aeVFrVkF*69AG6jd->Df>-!5Y9 zPv>I`Hd$%wzDuBeWj*?yq?aZjY&Fl%Fu3uFL8~p=gV}wMSLmB)Qy~%0bA#DzFPAAw z5^5sheV-w2+h1jONGd#bZ#}*HvwNcKekuLlR;E51Y`QT3Xwm6aU(lPUV|_q%*Q7LQ zVb<5Kh}^AgNWVS1`a1G91yXCx+u73CW^*^v)l}2jc|k-JwPN||zHSSac1F>G?`J-s z^v;T*rq%HqB6f7%) z4une=!`58(b&}x!=J6x(W!FtHes(=K7gEA62X`xth8wn#ZT$=|p*G8k!S1YGDH)6w zj`tiy-_7XdXt59rVCdLhymhsfY=#1rcPLOf`!(;V0+q8bs6jeMS~p}e*ea~H)535y zQBNpXddSq*p==#F&9m=?d9aU&mVS+zD1Ku(ae2)`@;`b79a8*N{bAGP?aFu9^5GS= z{3@+qT$hl`KVPB+OA1@CMAO=ueN2pdwh+jl@y2ZmQ^6K{9cMq5@QANHC97Inhu_G@ zI7Y>_TueII zBRRK2j?Ws_ID2rY!EpgIsA1400F~g!yI)mEZVz0=wYaS?$$DWrH}452kVv|R~jTl?++;rnxOQU(snJ)iw-EQI$x_`myi$E z)J=2fc9XrUriph=-OX`-!Uzi$)>Wz9qNU{l60N1QL;9T{6dH?4`{(D83XO9;XtZ^) z5EZ%}4UUlzj26MI0;gG%A4Eb2WD#JJkx_%ynoM>=t(W07h=dFWn?fW+8!i$mgV(Zb zA$YBcgEUFUBo0#WTE4aSN{D2;igPPF1=JB0yjJDxn+uo(AGkn0tKmorUVHosN>Pvn zubm_cnxyh*16J_bX+=Tc`HEbd7GptQsvXZo4U(XSXtfOjAE0L17|6Ea)6c@9ie9y2 zt8*YV9%e#*l^_|uqDzVcH6%=!l&KagWG3&H^pTHaBNC#N2qIH-HjjBYNVK-lqIH5$ z+sO|as&O@hSNvfop&18dVj9N_J%tM6kf)&kmU;>mMl6Vx56yuUo+8Gg4%5PL?;9XgzSB70s~lh@)EUM*Pzo4 zZO9E6a-~5>exR>3=$I!MR??v3ohdv}}@{o2=BQRH~(+6adWh9I$*hbq;M4I-qbPR^T5Mi=?eyAQvU_4)7C!GRw-< z<5@QJSeBK&2iS5xIalaJ?qqpb= zWP78_)eN3@zx?3&$cLcb{uIG;qolrs(6wUg9|WOK(z4!$A~Y)v`t!2gx~G@5;o?1E zY-%jrssWoK2Bq_k?X+I*hjqn-vuehbFYlu6Q1JOv=d6zD-YoTMP8gda++&Lyp=_C6 zOHTFxu}1?#OYRQi3-!CeF9&;{LM3e#FR>K~R27^j=q6qrf*n7VHZbo|^(uWsfIlsV za&c|orKG^?ub8S8(>PYyO7X2yHLPXGNtqdWj8KINg=UG zvJ_?v$PV;wzFC$iHQ-hyq(IRmGa!YWQDOs9@Ohm~cI`93qMLSZG2OUNRmP~pQyZfq zYA{Xf+rCy=o{m^jXy`d^)BMy!`o|m9Z=`GF^-j0^GWt~mdZ(Seq29wh- zJ)kavxjX75asd8^Dfh4R6uNnfJQZm^%?$Ty9vV25-~GWd3hWWon$4Y{ve=c&Di(;JK$7j(_!Dni*Lfd0q{^ysUqVY zRB@~wc#$1IKG$1Ige?o>2C)48g}$wc)O1 z48a93eOrnndOs~QuyPWO-38xLZuRn9ckfg*(83_BS8iJmI8|V$)s)oADhCsZb zEG544IV07~=Mi{tii?dWY{~HMhk{;wR;-bw_u1f_jhJL_M@_X(GBlDmK6z8qQW8)UBkF^e%PAcM5u$2T43T6@@mqb) z_#DV3QAl$_bV%0XsyVDka!DB`^6bW$I^qj_`A3UL==fZ)p4r}|pM;)GB zZ#8M?Fl$PO13P;#6kmxPi#$S@Kr-buQIxuc{@ z%l|#3w}d?VNN)@21EhC^^cd-#A$^GSXh?6vzU&Y!sjV%f$3l7&=>s9Xk@UWh9wEIa zq=!k5hV)U@AJXG$m$ar>^UW2H&5@x(O}`Bz*q#Iwz;2qR@5JY7_{}+{LYA>^v$R)O z*N&Pt!94+5yEMYGBCWc|?Vq`>An^eoY%$lJ&<%zypZiAhuRaHjkO91}nc&iq3Ei{008)aGW_vY#nvd>Svn0Ru*>Ns@-mbQEK%?$4^~;<9~M3mPv|DahwXRbbKB>JkpZ*1Ep^Z!{FIlBWICf|F?# zjWhjdJ+97JjrnjHvDXoqYwq1FUM_VC>%ONC*PVSHihE-a%Q*X**y&)kf;tk50jbUO zlA;G$4PB}v55<;i4eS$QynAiqTC9eK{q6P%Z*u|$Vo7qaBkT<-TSGZvUh8Esnn)rX zT3K5zi&wRNs`{@k3x`Fq?hUJZ4PH%0CU-(u{o7{&1dAi2K9+eCtD2iYMc^(FVex?P z0W~i6;O6^dN^Ay}{jiI~7zulGuVSBOpXS{_axY7uAH|@`8o>a-o41N`AnZide7!GR|9|wPNOhDQWmp@4)aZB zzv>MauNb^kO!OQUS-AaNmfo(|h=c`-i2Xa*013dizV^XQ&LfYmL*k9vo4xFG?GW;X z+RL#9EGQ8}<>TgzWITl5u_kl13e;v*1tu94|4;%fj=Fi75cy0B5>DhZsR&J{GbH&e{t9@6BoK)ZXHJ5S(Tz(l zj-c-)$K1JbspOuP-k~%ztoPfL<{&G*Md{4bo0Ntc)%%S~%NuyH$eGzvAmRx8l?yDu zst3?`7y-U+G#^3fVh{~1HWx#(BAYS2u2Ir5r$5Ayb-4hi9K8pqrN!=zsF~a+IB3on zIEBhX;D$4OXs`F7(Jp6KU3&X1bZLR7Hzn>IMnzX zwBV@!)@312AtV26+3hEgWmEMtkwK~WWyLnV`*C9R1NxTK;V03qR({*}1Ad21+`4V6{=uR~=Oc$gQf3&q%p#pJ7OC13V3T;~Vj zLIUKz*l8~=BZUIdavtxzK{>)?7kH!oAhVaenOOuOvx(Ha(nTC9T_0<_3Cly)- zuFC@mjm2vEwW)~+f&o-G^+xc-cK!`ELGJXmpj9qnfqTrM8&FC&AxBMr8%o=FEirtNynT*0X(|-JxGx%Lg*jDe^&uc zqt0&!l4rD1mNS1~_kICQk8_IFpm4LOH?hTp4qGTUPep7zYvu;ny@&@~rG>z3upiTS zp*iL`u(@$S#y+6v{E~MM_5m)}T0EpyOrHd%i8NdWLV36wTo$3ctW+pH;H6uOZ>W@M zxP($t(^3JmO6Uot`n^vFOu!IIK>}M_xf<*b zZS{Ct=-`OG(OQhD)QpCI}NvY9pN7rwA@m}2p#_#$n4%`esY1=+}_un3R0}KnQR(08qbD*P#jy#$ATS?22eEetRF?n_VPDtU_7aU z_^AzNmsbOQEer`oAfaF8ok`Rs7dYFQt(n`kUSDoXz`9qLSq>W!+4|9HFP{E9jaGU| z+7LRsiTI@~Z?)c(D?P!fxcm;^`lWIWqz4sx0pgL}@;|v&p9V!uoW+mK;mHW&?7b2i z?jED$dG;#%rf~?(Q=JZ4i%v}<)nYN;(UM2$>7AV9R&z>bA58kJVKQ&(DU6DvXKQFU z!MDCk?$WHF+N1+a)`^_9=C-U4QtAwxL)RP@^2;JV84f1W8Wyo}S(?-G$-ln47N-#| z`2{%zu8<(F^%N51Ri4VlfVZzmkXLvL3G#AJ0qT}|3Q#v>0C?yPGeurlP!9QZ&3=&< zX>aU+s#c_zur=&t0#42HPdrxR8c7%n9`{i>QV|}Ae)3J|YIdhdOec%|JAy%kfb=3+ zT*TSOA!*PvPR0mQ09q`1kfhM$OJ-_6HP3S#T*v7MSR}Z1tA*^yf%;CoHq(F(+*}${ zoy{w&gJ`{Ne$9;GCuu#yl~g8gfeyWy!4(%3yEVogqDS}N!;6997!QBZXeZK;-Y=_b zyG!dj8Iy!M!^|)n(TNrK?tm_H=hYr0hLXh*Grz>XI`fUL(|{C{8Y?L2}*j z_-J#a5#-fwAjm^Ogm^53&g8KOX&jHd*TA!a2=Qy6w?mJ?UJjbI55SXj0G;R{@T1)|Yk>SZ zWF`Y;iJA38V3G{shQpUDKjeanhYU3hYIf++u65AsTz~p2x33&Yp;R-IA^(@BcG+~B z5Ce{byA>S7*Pz+h;>vn%-ko;~RA!EoxXb_+OcGNheTb9*IWdfXHE{?lWC zlgmRoaXh5s%|oF#cto6298JbHkaJlK?WoZ-^Q%{CU&!9N`BfoRmdW}_}Ip_`iH zF6Mw6E68b*RPT)B@{p@$jD*8E|5jFJ`N5RHg2l3G(tr};hudX!;9D?!e=C+gmq17MRXBKt#Y5)EK*M%Vt5Hrf1aq0k_Fjb~p?RNV z#16!~1sxP_Df`S;w`8_vWYhqBgDbB_`>nQyonZtR?0Z0#2rHvkFH~OJFA!+p;MOzN z7U+gm3fhJOh@`+3-F3a?0)G(wNZ6*B0hm#(^m6;!vLBjXy(t~V(X8DFZP|#0=eFHp z;|Q+e+QJor=8n;-%13i-O~F^~G8pt=uiu=S8huh^Q}@e7jV=-?`U8W&T;)Du_y4Z^oe&ZeO;-abmzNJ zzLB0rG%vbc>D<%rQ5xo--oHa>aSch|pme*ZpM59kM#UYMf)%fsq@T3qMd~N*cvq>o zV+5^pV&Dyd!&W*J8vdiw`;-O~ zS9*`q;POh3Dm}$mM~$rn&0JT;8ip^PqkeT_%2+7MR?1ingQeb@MR}X7pfnn}@={#9 z#u7iT1gm2hZ>8{-P1FWaDW$ZXA0>v3I0C8M8zD3$A-7&T<6`GWABqZn*ohg^{_jDP zj+}+&um9sUZ24VttR$(=dWx)Uf^A=Y0QH*UUOn(q4<$R0jK-1(K_#X;v6Wk#5Ubbd z)fiP4@!$!`A`yzB*F(js6VmDQ#=BORcG|??f#od9+bCagVl8)=n&lJ-$tCrq#EI9{ zUKigh`a68SoFvL^xpQD(xum7@oQ}MbcX5vJWxx;^rS< z|J9p)?>rl1ldOhp$Xz$VNuj5Sqz!p1(kK(nX=?3zvCZw!)k95poZXm8c+pS==&Ltu!$I8Un!O-3jVIRXb4J-|tK z|Em421Nox-tHNconuF$wSR%%h>I^)FiC$I3FoMSbhj&4m!_qtOsMO5FDQ0Nm6vJ0} z9!@b_XUz$m;sH`{;2K!Ofrn8v@`(FQ0daSl%y8Df-012Ii%w_P@(`nthZu#n-X>V- zVafQFxnQNs1uJ6cn+Q&yd^4~x7TZFOHKcTIm&C-c->tE9w=YAIL9t zi#}8}agtS&@uN&zKH~ZJdgTPi3Cte8OrWh z6SGQcGFV_R|2)<*Lp;{8cX+JS=~u8QUF5K#APc&W)S6nUfvwCSW$w7^Sx6aOm#4QV zEz8-r^L>!#%{)1u#XETR^L!^ytvroO&4xn{hZ{FUF4JiY#l6p+(A-;Hy4b&(=7h?s z|56aAth|{v>NYXWJ*Eku3CC#}(?TfZzSg@eRu8LH8A7ybqR>{7Zc{1v(g`!jRqA{h z75NZe< z35GyLG?>F(=V2O5y17k*i5GZ`Gz})~F@pwE{qhVNOyt5^m0>ZNVO<9)Wg1LjFq4D= zHVWx0GDrPQYKjxAX_T?lVA57L(ObI(5HSs=q#=F?ky1*djUUJtYKwHb%T?3W{r%uU zSgn@wN~L@HKsmKh8yrto#UFYOw)+lZpO!_U% z!RU=xj&)?;cjt{ZR?tBHbJ2|;8ZQS3p2A}ge)_lUFn8%7s3|T25C{y2w1P;E&|^1L zA2vFQxW(az-v80Iiz3cXuP_RA_HF0enP-oXLI$jNH=fU}5r)FWVRO$rj*MiVy6phw zy1m#Hy7Z94e>PxQzex}8FZ~4UHYp>fdvT@7kaQxQt z=4FG+Ph&Ea^1p7t)$^jL4r1xOs zDeRe@r$C-|ABT{hBQss@N~yfs#*XuKeAROs$Ugc zHIvm`_lY+6Q9E^m_H&SPmwkc5%(PkwZWR5f3Bl=S;hMehs)qjZ+ybik$=Tr;b20|Q zeqS`ytDT-mD$;Q7uW(>sFD-ODSAo~|CCS`)ACBOlrI7Ge2aKb`uNip02Bjt>`$PEX@W>uEYmGGb_|IGjT61HUHf$F9d|GS`7qwSpRU_U=vH z#$1F+3)pK5)5V0leX$OQ8sR!|nVvb)?bpl?l2gc}Jmv|pz&4j`3nfr2%Up<>tl8(< z9o2M&$<1!_l}6Y(;Duy_&*FDk7-S3Zmp_YEXHU%bPLysTP)h}-&>TVRbb5t|3iWjJ zUwV~f;L$g8|*tk~=Y8on5Es7#0>tT}8X2f(#N027VRdL&0K#B}k%*(9o|B<2p zv|EL+chG}7lQPXM0_~{})Pfm$3}oHLY}9lG5qm^iHqK#SCawIS_hQaZS-`hH@qNL|Ksp8%#hEni_f=uAN?2J{YE(XczT2?TUGnN^J8 z*-q9ub|)MGYnBFuA2eX8lruL)s9`euk@Qf*vI8Nn6`&W}=u|zvupu9@u7UHT*_|xWeub@la4n8SgGVJ%9)A{C8-Mqs9UR zY1WT%HmXw~<7nW2g)q$8y{xX5!EutHaLaePHQHiWw-VD+AUirV63kY`Qksx0g3W0!7kf4yro4OqER1*YuW~8qYeAC zB0uQYLC+P5ycph8CqIt9FOVPKXS)Ex_5G0EflDbpuC&OHAMkyU=Oa7^c>a*5$d7;H znfppNk{{iZ$&Z6ITk>B8cspMC^q`poPqVnruTAzTEgq((Qa9#w%Y4w7RC}C5l|spJ zHtU4uzaJh&8@pf&X7_hVi+a26F{m+Dj#Od7MPfDou%=Y5K(O({tlk`j;C+Ih$HGt1 zJcrLdFynB6*iw5 zwDVAK$I^g>@Qk)0e-_qxVEG0s3<=56o&dCb7&}F(pIN$jL2MYdyZ|Y~#}S&%7B2ecmao~%)>AES*FpetYz9~ z#NX4cdC5{&gC{lQYVf20`OE1!DU_j>dTL-nGUO?gex)GF6~Bs#IUulYzZ{&1mkMU= z(~BdtlLgnAP61u6j>?>w3x#305sjfGV!rW?GyEGj^%VULQe*@p_UdWG#ZH^X>||C; zA}OL%yu`1!Fj7)Dt4fD>322RE*Tg6Q584i(#3Cp44Vc*QIcxmP$Jwjj06$P$aqu@n4}#&V`l2jlZhm82X?pr8m}=Q?qrNgJfu$nT?~tjd zO14na7TK^7_PXyQmeLRvGmD+)0o&~z`qyGjVnTu3W45re+~$LOyj>~FYj3<4=9fz=De4g2Bemph zm69N*Vm7$7kN_vTwFSVRcf;YKSU`Y{*NOy$sY7#*!Geojrk^%!1RhGEVt$3E81@=Z zu`3aJ=qo$*YEQ9yH$V<+ByitvCaETklbLM;RA^chch|Nv*Bwc~o!+jm*r01GcIm2$ zUAnSjm#(m*t`f_^8AUo!oJP19gsNhYsvX*5n^PMr32K93!^WCf8Q+-Vs8-Ju$%ERU zZ9m)CAzv`cWo|4VvMf^@M1I5(yl>j&TRX+_t$Qh!?{jb=7~(0pe1OxFw|=A3uHUwJ ziUr&rzZ5I@&Qo{=w;@_RX(w>{6~w#hWC*(XC0W4{X!}$33~oA^EBHsc0>5dz)l(CO zp3E!ok9GjJrKb?GcR)8n8krdYnqUy9}1 zKI7C~J`^NgDHzP=sW6x=F9`2G6fn(^C zcLt}w0^6rpKw>EV;aA{iPGK4X>&=r!1l}6F%AHc42aXA%_%+zq3q5wi7gwk+dRS^EP75u3clmmSV!W*ZpX7OrO zkQQ?*!youmA3vwwHG;m=HT^DfL?P5P&{w+vMTxY@<8|sDuOBsU)@5e$#Z%{da$>$@ z>U;+)@7UCpVoW`Sm+fbwOHlXmi43|^>Lp_}-Y$$Wm)i#oW0TwGF*+D=P3F(635-qM zH1&T9^NSs+YmX0z(f*TvMRTcJQIRbg8c_wrl4UC1AonivFx1b(M7>fMV@*PdxOhZ9 z@@v_9tYF=~@hVi7Qf6B$&DP>qs(*svD(qciVLAibS;C0JP0{J8{p7B^JGpYg^L3LB zPv|E5r0OOrzm46L2t~|kHRv4Dsk@2L1ZJga16Q}}^n?&H>Q6hTUGJ^1{__udX-!>Sz_S@@2m9eBORZ3o~GnprkYE;NYiB_b>3<`E2pVpteiJO#+ZP$^U)y1l~ln6dIs!9 z?vsycyK{6F#iGw#sN1vobn64wceO7Yv{Ypv{ zrb;C+L#}dnQnqqgF(b5KBDay)rK`x{hC}l51t~%|NfItY5GOf#a8Vpd^)PbV7xT!3 z#$YAVLdsHk=;c6Y&$5H(r9pl`D##Q_m4XKPH$qOt4?1#`*QDIn&LQXMNHbQ#0Ta%X zD)%m5oBIUJmwYWhp{{v@o4i5ap4gX2JyS=;R3kX;0$U|yH7P?b!R;iE!Y|<(%NF7E z8ovV9_^BjrxrS}YK>`?j{ki{_UB~_}GD2rZS1MAAe#b@U>SFy>dcJ9nf^%b4bxY#X z*%;MJ7x|J^8mhTG{N+in$<1QaL4&hhRlrB2*Lig1Rg?k}=`?XZuT*;+6;gfim4@fE z7O5#mB55}e&t>%HB6)KVzN;Dh>Vp2*8?*(afTkPEGf@*QHD}^Y_A__zM^@ofy6trp zDK95G+$=TvHcNX7%2E#AG7gp=nXP^X4ymK^=fY_$^sFcmYk@_&Y85yVXP^nn040dtP~@qzr(MKbq?z+ z{@@S(U=3MaK(j38EGj`03^ibE5u-#65+rKS&{B*wt%C*#A=aRXK|y1Qn*I!$%3IK& z=kvX;dp|Gpl7LL4l1{y|6m1Ngp8U=pS6~!)HZm0%L?1^4BnMsUY zIk{rAu3X+&xo677#TGZL+?`rXObD`ZaRw(NJcY~$8!^3&EhTFukeIDpfqt^Krp>6m(R zj4Q^e3>1g#^{NbX27hw0TCV8i>4=KGZ82Ga{uOQ$0-4NY1!xj1rb4+fCM$89$;unI zba$Vu8rPG5=^mP1y0M00ukF-rmk(JPq#l+$8P-1$0!aEe;?UZpYogCZlvS_9M~};@ zq4PW7(B*u`-*?UJ?3j+9~4D*$kr(E7VxY zUQ#q`^q;iUFw#^>3zTn8!+3(yW3%}0#nT4foUoLQ>a46;T?fX$ zSf684tPw#}sy{FYW(e5}5e;1rW5MURt@IT9wn!F@2{FlmBmr_;vi^H$R^$#?dW&?v zRRb2g!8eM$+VhXi`|>h)50`bC%MD!yEE55;HIpj(bR!;b@?+ee0jVh2kgdNlBoTJ1 zWhBca(CyiG7(EpoN0`OkZ{8K8X6;>(lV|LWOdzp?Hf;!=7PWus^({8sBU+X51X@*D zHo9Tmogg-XvbMY~zmOEPWF+W1@-e>f>g)^O?o^TTDU+;?G44w*FCn7YA|pHUoL(lW zDQq^RC{I)~*Q7CRIg_09d{_?ip_U-M*Txnft#aNXDSV?m3l)#vWOWlt>nQp`?9{b6 z{WW%WOec~#3G8Tg_2TY&^t0z=N3$dLJaLyj#}yitez_xHg3Ig z_6FLNeUM`;?b%G~NcDUrkd1_)PSMktBtI$c(M`2y6lswC&(ku|HH6%A!aWb+_FrVv zvbRPqfX7|=Pr3w_t#}U>>yhFXNg%*HY?ZuyZV?p^w+h}B&zg#fXAOX8y}s9NtZ%Rw z?iI8XfLaLzJ0&!)(i>J=f)jOF3tlT8Qm;=@uuk0wU_I7geYcq*wu9X4R#QyK7fcfW z);ozqJJw9uK&^OE72Aartrepx5Kv_Fn$F%(tF97|GJuPikYBd-o>~ENz(aMrRy?g* zld`+K)SNOd9Vox@*Y0ta5-0CyyVk*AZ0f*}*upVldf!*9EK+7fD9oIs*D4(;>@Ok#16A+g%sX6Q#D^bpctuGRD_QtlG%6 ztZJ$5^D5xe#f0EIvh=wJZ@hQkKmPDPu34ksbC&+=XTNs;4`2DoHy?=BtiDK>Rax`E zS6ft}Lz-s%cKcHaA%!}$i;0B5ZI^7E##dIHsfT}+4}f=~QQE`v>Ls4$%&58yI==n_ zohC2LxK*{5gaUqbw|qpkRkJOpt0yRtaSTOVA+hDD3F_gBP&H!eh z*4gwU*7kpJ?}hZSJyE}B`1s@1q^OQtIwaxyBF zSh!O2?wv8DuBu`jQ4_;F3nRa?*C40^S&*Q8qCW=Sk;56lXFLJ?N@1qCGMSU)Z!K;3 zN=(=)Fvi`C7g%`UX7?|ow<*Zlflk1^>MdXcT+c-tuEks!Ew>wn)mx-6Osa*pQR`qM zwpW1NP5e~mv|u)zi|qqtaprB~P~U>_&1!A4e>FF23JkR4S%<$kbJhOLF9JaoaonQj zMiR+Oy63ZLJfmG$xd^!u?F^Mb-q6}0`$>(vurhaHrDFDzImd;Sef_q|ih@ICFOhC| z)cR-Y5$O-7t|9dnex0JOA*~<{FA{7L-GcA6vJ7xED%WY!W;6llSP3Q0;e0_6sbWKCgv*0WMT|;HZvi5fwHz56;(221F#Vd+<{gz_y4jx_ECL>dEU!i3-J-#i4 zuA^oxjYiWMv-lozc0d$d4n7t2-%9qw3Q6Y(KK4o&r1JrNNrG3G<9i^h+ZMf<2ODw zXtr9DEgT%zKX+?B+PO74YGkZ09C)~kJ5!nq2NP)D_`*@g9Zjx{PbXP8;`DhXjfES} zz_l+NGt*eO76uO0ixkH&a4ie>sIzSe2c`Vyw-i;Qj*d9#FvNv>sPnJDx68GAgo~Kn z{#X$2Vz`aKe^gL#bAvs&h5S|VcvQ#-g)AUGk_nkp=+?1?*yFJsms_ov68eu@nX+)FN&m4wJN>fm%poJ^Df!OF61r5uZ z095|22N&fzE-{TdMKUcU^sp)1H0CV7_6@|>NVdg%+fgeWIcCIR!*BEp{Hb}5=_*_SMIEcZL)>B6X2 zxL)4OXc-l-z;zv7lWspELJ7I9?y$<3`h(<`k?*2@E;VB`a=~V+=X33DFDZ0Z@QcS4 zJi5+{KKSrL2^BdBtKh*uY0BjeW4VE%h-dY*dJojwZ@Qq-ec0iw#TAe6d$0A)7Ryy zd0g_f)Ll+nbV(RTC@&99+2wRcmm(}OW!a~pO7pJy3cd-HP>O(@0^FnsX_@g|7piHw z-jkZI8>z3dRC3|D=^TH1vFvSlYi34W*{3_sEEm3f3c^P-JEAyAD^&nom*S>eBCN&s zhfzE?y~0ymyMCFch|YD1f*2jU06P0B_SLyj&l6K;5B82}Qz1i)C&(Nua4xUX25e^#$AqxG$uOc7 zq0re?6oMuD0$W?+U+APp1Bv6-;?O9!S3k_{)u0k!ai&8?O0NGLJWFv#Otj&9nTk0B ztrw3&B5*gO*qrP?wbOyhgi}KRZefizQ-L)>!3opik_g49TJ=@h{^l8qVK_*5j2|HH zGj_q`GK#c?%who*v*Q(bQFTJRgF*N?NR+eF^+QIqE_mbz@ydsatq(jB6@N$>Zb90p z^sQ>=E2n6Tj1ZzJkae*{$ABkQ+aP%uWf@t^uj90N0jt5uXq!V1*3@#QAu#R0I!#U)r^&5=?Ku@_r^&@K zjO*n^%^s-QOC~CFX|s$iBjqkH%OPbq-l3eCE6TE}?W(erX%fQRtt?BFBX$nTyEeAE z)f`C&Og_`=;)$wU-zcS4aq^#Fpc@-yrdQX(zm_X@vaRloL8;`dp>MMCZw{6-Lsg#d zHYJIYwJF*O)HIKBpB` zEWxSjr%u4FlwZ<8pBriimS~d-U4X`GFs=*B2*5+2 zAbnuG-sdE7X&BDZQxmOc8+t4xR5<*xCUj;Bh0f4cZ$U`anMc`?UX@9Ve3w5IDNs2% zjUu9qCoUxjiIhuU5R_LvGsOb15TQJ59>hcTtJw%|lJ*7-u*Sk_GzhGqL3ILP%cuQJ z4E6O_*cj2D_QSlibf%)7SgYmdMj=>#58us@D)w=EsZ^smEt$Xqxeqq|Ih=KGJf3K-SwjU-XDmEws zp?#U*b7>nF6hr(_XdhcAmMgxxXNM3Ti?yG)sufr|-w1GN#)agXMpEVvf;3pnlZZf1 z8DVI7FjTph8xTur-x8z~@<@bFvGE4SZ8k zuxg(ND4;`T_N>PeVPx|Ad<&OVPza=L++0PR+hQF<31FNfznykOll3Q&ljU1*w<|I@lUE@4yQ|^7{=$=ol{ig8Y^vw-M**J!{4cnMq)N?k=8w^yyFhzbowJ-6O># z4;*;~k@}rK`_e}6$gIDJripmza#q0_$O zg8sxZNyJ`o;~f_SotpDT*E2&`n~H~l#YDMfy5j$Hq>YW+i5Qy(X}zMbbt8{81%t`!8LD}V zP|eOexmId7++EATtoT}%c+arY^uc`79n9TnGVA(^qNA41lrBe)vmK^!*pv9S+?7D5 zu|0Pt0&?71l?a3lCOZ`9f#>!FaW&8T5?4xWOI$0lHR-qAy(Q`I)%(qfD<(E2u9?`F zxN2fUf^Nb@&lFm3q{OXA=g|_#e3A!n)wBbim7%+^@TJllWM9TbGk=Suh$4qz;CsTC zH7kbWt#k=itXNIhU5wlO8wk=+GC~WIAn*n~;WA|vo+2dxq!*!8>!%3+Tl%7UpQr*; zJYFVRz;YGwahWG&e!0YxcxNthkc8xSP^tMyev{l&i#_%udBl{=$fLm;k3JEdk;b#Y z3KGxNtC^pyP}K(GRtiB!`RsGk<@DR5HEwUSUJ|?=TiTsy-=IeLfdgtvM{`UV~vwCUt7ji}q5YM}mz^71Wy)v_sM4$|TbTvXh+y;gI zz!r#98vo+I`9*2tUo3|{&@J5<0?Nh_GcB(S*66>vwT<3tUwdOM@41>>QW;58K%4WN zBLbbL+Wp4Jgh=PooI#9Gy;+_idC^B&PK19@Z6*|SAgu`&kmgC9W`uixLyxoycRsl^ zGwPg^XWO2%>E`By8_E>%p1e#X0C&QBD%8FoFI^*soL^?cpHE^{%+j zLp7s0**6u6BkB!Ridowkzc$5D=uD|N+QXb4TXRHn?V6*_pLlJWql2u|kd|wHx_?5= z(W=zd4Xv7^ogQ1d3<9wUgLZdBho@MpSn&d8q*p1;K`AVpH>}$6!-*epJsw->I@X!T zwXAbmtkOg_gNuLY*->~)=ne}m4qx~ba0uX6=sGD^cRoe%aNR?t&2Wf8ZbJtuXm)^6 zDv)?_pLOam>vhQ6Omtx$FSei)x3JIzsqu2z_p}%NE%kb==cFJ>_U4K*es&s3lVnqj zZiFb|>RMZraLnbjsMgumDB*isqJ-}%qlB+Rd&eQtRBl&Zuct@LDB(Br9w=Gd!V>^n ze30h=&-FY7W@)`8F#M*fujB+#!jBI-gRSQ@>;!bd1^t(SogWRC$GJmuiAVGlRSrOw zwn#Rb{>q_AgLG$$a5@biB*S`#%F>`@wYLlUnWG1KJRfZXcnx|x9hS^oY$7-lF^7F? z@4$Ybg!AXx9$39mRakk*p-HTR0MDVJn0}e5Zs>^k zXW0?qvWP|kNZROcS*lejAyGz45y;80Jsy~($AjZa4oy`lBBF*}B74ckZ2O9yY-MQ07Z3Zlkhoh7FB6rM7j;lr~LTx zz+mX6=s&|_!DPf-Be#UAfyj%gl>rTvEuho?=MMIOgtslukNVBsnwpogVo4e4-~2Rp zLncxLPqMHo_+p0MK7G2^g^hy1f`vutmAONon$I?$C92GNFyM~`{+Oepzz|J!1w#Y= z5Ef)>u=~a~XiVQ0jp>`AA9{pol~^oNm|KC^7zT1`gD3!ta19$ow5UKRUIlp4EL(HM z`u{*ky}tt#-yAiSiC=@g^h!wBb!`>5bm$=xUq?^^RarhFUcf}%qr*A}e617g2lrst znGg>?9-ZVm-2{?KZ;U}7`%a6iEG*RccBI}_eEYNC{sWAg^dQVlcV4@)h!yw+i?es} zkRKj`3rbfoO3)Qn-`U&{Sz#>bsOSfaVj4A4L8Hb2*A{^& z(&k5_WYd|8I~RzHIL%RZIV9rvAh~Q2n=N*bUeN2Pzybu4$%?wMns#6baUkl z2dCqjHmFNj(bT;6RQ1(y8-d)!kbv6UCfKP7KY>=pGwgd4s0XqTNd)3-G?dJ1KLQGS z=L$+ujirLp%4lk2v0@it89Ajbh9eY=kVFI66N#LXL6V&w?gxJO5fMY+*{?v7nv;Wb zR{)6v<{v1S#_DNLIeDfGMcx~0-eWb2aiA3 zjT(E(qd{UowP~s&b0DS&ci%Yl9$!QNGlZbak5LMOjrvk1Rn91@db;}Bt+y??e&h>(yS62yS4Qyi{W*PTXfpPF^7foZS9 zf++bV#V`T?oeg*Ep;5b}xWsH;fe1T}6#JYBOtO1tsZlz3NuaU)#_F(Uc8GeW7iH=e zWydQ!r)E*^N!<-qciKCZU=Y%X1)!+nWql1GBFJiYMv|JJprV!nn>+|jL#(p?+}eJRB*!TAyp~%enMAO;kdr0{-L{|^ zW*x%4ZP!QQrPwew5LJL!R`8kwPG>oRNX$pF$G9U)XW!?7fg8<_JX^ru9(}e{1*VBI zZSlfIbawQ^+s=PS1d>Du7Cm{}`R7K$fFR&y-jM3&mu_s8=>c<-tv-bxIdVWCK7Y8G z-ri*|0O|u`tS-d;wZ$$^m`^Q%YPpisEZNQ)INi@^(*W$2BUDH&n9MGoZT zMM`m5J30zO#+nC+5Lx&LjQ+aE2WiullWC$0YeJ%n<-ph%ZyeQNRr+H_iMY7g(dTsB ze9piNXl_0)KP&&e{H=MO_viKe_w#}Lf64#X{C~>_^ZEH7a*3;6m0V(l ziRQdI`{Gr}N+8g_kP$s5Nv^L-eLRZuj0L^OK8FVx_EaKpQnzcR@suKNng_}%%BlHy z=g{%2mB{pzMFJZ3Y!2i_aH{|%#l@BzF-++#M)ioZr(l-Va2&9OXe1{^DJ#%uIG^Cc z6wf{!^pD1K84pso&k-Nm2+B|#F?1_BQ|8S120?F2LkK^4W*s9b)Hr${Z{*C~xNdYK#OvMZcQ{5q*u!Yo;5uL_2nSH1iUx-~M%Zl`Zs{Uv(ShIGbNgOU%wi90Jhjh1zU( z7M3ezXJ?qtKhQQXFKFh3adt??9{^GQ!bu^**o~smtTKWf#(eI{lq(M&G=Nf@NYh@b zJuN@uNQC4}MX3U?!FGo&)5vt0!cgKxtT5PHO5u>kep4#<<4bCe#m^FbzzauFJ@<*D zwI!O2QqP-|`k+alM7bhS3zYf-QR>jw?2O}5>Vd-M&fv-D^E7YJ=c3e|K1bq4swD02 zgl!OP78fC;CK_FL3$s5>{0gDX`Ov&b9MDjUz0u_Q&I!nM%lmD}^#=k8I0XWAHqS7- zfqRMZ+Y(VVBFjb>*8DES=tvU)?k8dN_@)?LmYn0n=&eiWk+u-(j@OBROIt1gFkFoc z8?mFXHOAfG<>F7YgdhMdA@oAa5~ijJ0hY@I0SFxB@907P%NCS<}TyvvFEWH=d?W!dKA8UUw4pizJ1x}9(;`FLq3ECE_vewV&e zlkv{0Lvb^+1v&=f-xzf4pt527n|dFQXZ)*`kcll%Tru=OaNQWCR>p)CCLd`ZpoRz1 z(D3@{S}~~&Fy(CUbWn2=29M2r82n^|Ja9L3iA)MMNrfLADUfX>!&GA3GU*1A3t`#i zJV1;s0*NzRAaP*bgGSp{3pi=m>EZ{LF+}Q2G0fHCLCY8ntkZ^BrQkuU^GM3q_20(<)?@^=D_l^Z=9xY zdzo$?NM#HrKVg+fTDUZj~83M(AN=!c{8sF#) zwtb*8D#eq)CmjTQv84TGuSrMF*^{tcw4%9>mHtweAwt7M@PW{vnLubzaY<-c8%}6g z(g+Ppy>3DSP9YE)q|D@k8E6t3bm5pc4e{P2NeCcBXn=xTzdH4VM&($92I^rmxfm*g zvcmVmz$t3#jH24Skj)SZICwAwWsO}v!9odA7%!O`&=UhYs6Pv`zqi<@1N{k0%cr?( zV^eXW)#By7Wk^z@j?QKLNQRh;?3GTHB@C<{T-~QVQ!SoVhdLF&)JlW3mr$ZwJg@v3 z`5~HXGS@2uEvDjXkLo>Ky}~toXNLDfI8msI`Uwhb;}GvpFNIpvC}7;B!>Qv%GUw?{ z9)_e_|Mt;NsOim&MZAQZobcn!wvWs*jQ_M9!*Z^Ez%wY~8!??ER z-6G)AtFHvJQxeo8RyL2A_yp>dG*dF0sYw{O#z^rx#2zM&R3zaK!VR?Y$NsQcWp7)R znc3TUV-_H^(U=)3hHjW~V&hGYX<;s{6qXxMu9|ZQR*`}x#$i5nUa|&4W+1MlFoOXx z>rA4^_|>1195G^r8KXjK^T2uZk2(&s7O|F05tJ*l;J}Y^cato8Kxp4pdA;i zDLO^(d3~}cQOnfHVeYMW&7LVuHVf=wM^$QJ)LpESLPNROZ5(|bAL}?*QEX74J_QGQ zAz9%)7%ZREidR&I06{I)CE7N`brexMi^tIy9${R42%my!fu|5!%pui@H@5_mqy$RA zZ-sQ9dO&|l1Dr;m!!V2Iyl5C_OSe+*7Idb3Nt(lW9i6RuXG3+z z>a6BHDsEsVn9ye5#5{BYlfX<#&*##l!-Y}XLM*bRIEa}*0kzYR7b4&?xgYxl((UD$ z+CHX0y+SD|RnyBngVgApzZgB z+0OPMq2y)O-{Gpxpp))o%alr0780T?<3VqRB#p8Z5;;6&OWPQB?^QGaMc-Mhz5PL* zW)NmJihNQU2M$FcpRYuULm8I6tT=LP7=2`78H+F(WotBkJR)G7(;-h@Ya(N1UghFN zhPRB*-~|#%%v_2{iB)N)mIC6BEdy zC@_LM#A$BJfNHk8;Q(-hGgx6FUn$XdiIN12g8z62$JqRyGujmL}=ggVR`N^cFM7FgxTB4=q* zpr&3K7aESqy$*=WagFL_d^#u$T`9(K6Y#P?bnOm4>l+R}OeuHNO6e;1IrdF24>(Ot zJR*M0I>VnJG#t8H33x5sY68%5$$P7V&tVS@_gQ(OHzd3;!0?FdzFr=HT~yM+7QDH z83yQ=-%?v|%ZiZob!&(ih6l-NhZ38^$Z_b0s8gGWdwVLCI^^n&> ztTTVeI8_5ZZ8O8@YiF(QZAjz6T`m=57b2@O$+pB}m9Xm*1|4VjozYKk2a^MLUC@t> zDz4Hb5Ie{mnPf6db0W@CmW;D;*ID(dHe~isXArtvS%IeUi-D`Q?S*@E&xlc8_E7Bp z4?DF5Wu!yi$+x`6EL{&>=D~Tv<4SjdkfFm{;VuxcgJhMq@+^+FHwAeql+BtRum9>j zbwgA{t#_Mn;Vt#lTSd3fBkLlewa{ zaAaV2Lxsp(nUO&E*!i?Ar&~|;$q0W~nPjd7Ji%Bpk2wXV7g9D5vL5q}!K?PTtQd<^ zlS1(nR8voK>()GIsAAKncSk6k=z|D&W`=%Ah-7jE)B$dcZQWtlAgEUt?PbQxKmi#= zg@vlBpnXlB9i5uwlG>BoKXXArAPflGzecaXFAN#&RAB7wbk8pLf^PvGXV6g+!Tn5aP!(nFmt#(aLnCwOse9%8`xUJgZm!o1B6R| z#Hdrp3=~>i8eWoK@;Za6FVbwOPMWfYkzXl`UoDl>JkW2Fpz4cF;ZBkAi`NiT-J+{W zMjA_yiT^ko)|et`7_UPB8`xLoSI*fya9Gxk)IXbb1l;(QG5PvM4-HP>U~ShuXy<_# z2YCPh26)g)&Qx*;Qem7&EEcdG4OXz94Go6LzB^MJ+pPQ9bauieE)+v7CO3O=o`kKc zhblgFmVvf*R!Rt~O$Iw7?s?ygQ*-uWkK&Xh;Rk*x^bLd9Rw zIp%e{P*i>{)(1dQ=#5M!;26zhA}&oPY}JFwgz=_# z2c`(aWg!-QUv86HV-W&z#7n#WTv(42l09hi#-g!KOePe(cynd~d9z^Dygl1^7Knv}$$^-Rw!o5_5AxbNn!<0SSomXb2Nla_S z; zj)hT8uv?rpo;5Cd>I#Ev-(onJ2tOMCL@HBieiDiD0#|`di=z)eLQR5(x79d4c06eV z$^hD#d7+OG2RcL&TR?Q_ASrB}&Z+HHzxc8OGOYUM(%}}!Beb+!0KnN0eZH@PtEKox zjGF;@)Ukw{!>n7hb8?r*6(-0V<+C@vi>8S2*l-+b%n^mziMD>e# zaaVw-ScPk_A13;u(MqPkTGoo(XzbOJ&1wB3z)P>3VLz))$vB3Ec7m;1q!NnHB?kx- z_&UkPYAbYsc9xwT&I|j-2qwgM{*G}Xz}y`CP4Zy6CbA<+Z9~GN^1XE0>V?(AymPej zsw}C!ZUUBsJhjxkdZ!;?(Mr+M_#DMEvu;QxQg(xCc(=gm3Q~h=UhP_=j$Le}#@XUY z*bs)IPST?0!DWkH>p-JL*_1&+mXpGo3vmN^HGP^-TZ=&EH0qV3Q|V5vb?|NN^fb0; zaO6Mi_O4bM*1!HcZ!hhc5Qyzn7BFZF&_7loDjG3@4pXncc9ZePB{z zO))=&3~aA?=|$~Ld*;BnO7YeiQ|Ul!rGxF2UOZ8y%iA;6mkaAQ(Gw0*t~$X92utEI zV_Y__JBwSp!`06|Mz`EEN2k(q&n#fa3wK~XVvbrsIsj218Rup~;ZCm$cTBqFhliCa zB|8=4_fL~{9rlATMPh!gs9C#CU{9WyzG$!JP;_Gw=qSF(eVrQ=Q)BLR#qWh}>( z?37K(P7ty$DmHB_L$|y-$SWRt5RJvv@8BgH>He1z*IYzW=`2#H$TD-^WkK{wi9Byn>gd~de^&ts*T8q^*4X!0Z zU->Kz*$%$R*(AdYE*ghmBJhFPKklFIN1?iFjnQg!sk=)3_NO7J1dSvE6 z#GP*ZZ|r}qSsmC2Ma&+$AMl;*z7(NP>X(Aw13Wm0YA1V03X=g7r2@lfGW+gn2pgc) zJBp{p?&}*2x%md_yQQ>YmWr2_Xu?{fEm06Am1s7f46_3?v}Bl-DF@TZU>MQqh*t_G zdS&tVt5#Jk5d8R_o9d{O4hi4J1r9M91LF9$F1e+zcd4b{l8m&K3o>I3RHG9EgnHqt z!4RlvHHkWAgNHXtp!AdVN~?KA6*^X&BUy!@XIN##vV{B?|1$yexd#IKe@k%~uJ9CR z;WAHg6r_-#94Fx-PjL{IgJ(w_^FqIV5V45n6Ey^TFhQKTbGGR)neKMA1rP>j0Ry?F zCm^|&P*U4w(fOUT&q>zlFM1lcYZ6=-CDgG& zG(oYt-2}ywW`bg=*KL9VVhkoIq=E?wsnXV!E*#SYh4=6ZCe(l;%@ZTg0KYn?Q)}xQ zAIk*A)()&0ct?S#FBI=b@%knm^rJjFPr@q z-Tc9hSQrt@ITj=^OI2mPEvo3`vf&z8Z;!`i{W0SDF{NNX$7T(cbzv(FbExY7sI04* zwWzGCnboMPne_)r<;#C!O|lC^Wq+8~#%8f-&I&QGP)e1FoKVo|GON@!v}Bc~2!%4X zRGC$DhIa)wds(4EmvI0(dxZIb>HOlV?F6$FdAP~PBS`-UnqV}zlZjHlveWQkrdy*r zM{GO&VaK^o4Sa>fb6^S7+wz^^xrkL?X1~A) zT^xSS1F)}qqA3oVM}p)PUD#I9h4!gec1NKM9r{B%GD=D5g zlG)4!jE>*L??A}+iWr6<>lK|`Ml-Zw1VSDjDfpOuOoOH35Wkk|yI z*cd^+Ge0?qp@FCl$(Rn4#z)c8M@ZwO$S)Bg48SM`n`&lO?Kdg<1iKj{98PfknmQJ$g;KgM%BT{t>H@XG@p z#`NhV>BY){odr?*?p!8uY?yRdNQx6DF;*T+CClSVSJ}{~h{(+m|L`V|x;pImYCemN z51V6(3FOx+rHZsp`2f4p_qe z5k|Kg=qx2EZS7riiRVKgB9d3;U2}`KzFRhYI8{pOr;k-ry}PZhI-Ie{uU@^Xa$-o& zP#TsuuXv3!mAo>aIak-E#5&8O+G_IkM`R&r9C2wSFjQwtg6QU0H6Hj$vn=fSLPN0a z`lDoc!pO`L|8I6%1YJKyQuA+Xpb$@~M8&j;>t1eRm2hjiOmaaz39MsK7y+hbF(V=; zb3w5&>lJ}yeT`i~q{i;M>jH$qBna?aXMG`0*Z}HA1zFB2dWO~mPL_0v@NO@1FMBE^0a4lGCdLVuTmNq7u{NO&y4 zmWjt=4|~4Iqn;0W(DMcT#%mAyeXIk1A8YRSvCiv9^dNn^-N)MJ_pxSvA8T*F@$xn9 zWA#Z>Nx+#C8xRj?PexW5-M20SCYrlL|w1R`;mdjTsA|r5>X7Ni(;>>fC zl>jnU?J8fq6=Bt6F%p|5;@V?~aWVdD3acgPHH8QJgd^ZGT8WRYIz|mLCu~HPiZ#6x z%8T=sc6wXd5knPpD>5FKyn-c-W|keJR9pCo!IpLww6=5EF=}8P%JE!rjA92{C+@cRiC}QC7LDEyC>YpZy{@vNB$>OeR&E0POyoQn`4`i$)M-Wyh zepPskDA}z5`OSjIMqhaNb>lJB@kZjY#|fEgcx)dD!(;Cc(JJ=_CaFaR8fOpoDpnj2 zQJkwiWVXUD%(L|{6E7tU#fVsj2DS(hAQ+DY0r4yiy~To%!L?-00FA>XDZNJIIiv&R zI<0||_lP_`3V9y$+yim`b1wZBIzR-A@YO;+*e~8eV3&~|kXs$*3sLS!B@QY{Wk*y= zP27^cr+uZe7lf{?4%o7ilTzQwCV-NHKqSM)uDO9+Tx^V2Fn-X_3bEYA^I3UFAqBNp z0jYH=#ew$(n@Fm9-Wsi_LIlH++lSMcFm}iZw}#zo3=+=H7B+NKxZOcr2{!TbFm$8s zIsFw=?I**LJuybCmMCH46{3aSfx~*&OAb<|rR;j`FFt zQ8L6`A8#2Voxv2^G-kFG>r(p1RIXKzHiZiv2&88`F3ty@SQjFRwn%zfq%_RNB0m~K zCh37(A`2}v1_LGS1;J$GPK%r;+@+#;NHpFe=V9}hoQKVtjurDr*vrnv8P!AjBLi^PFBl<3t-?WA@k+_KROPEeXGF(-I zj9V!pz0^E~_}jQb6X(c0pSOs3a!(=l8T1q)p5>lG#B-6S5b+Ra$&I{w{xS9XWSUYIpx zTx|UeVH^)9oWvcZBz#b8Umo-7wd`gc%i$dfQibn)f z`IA@Y!a!9E{8#3Nu(D=as=!wqTH{t^g2aNzrtvA@i8W{3f0$=)RHi)=Dg zt+~jFjlm-7>Dl@WyK+f;fR-9P=AW=h;-bxrsG6;{NTh5e6O1>?mCR(|A!C)JJ8lOQ z5hfG^pdbUaP(;p43Y>Gke`;E{#CcUU>y23#um_Tm(fqy>wt4nB!QXb{GK2-qkNfJW znO3R)Tydkq%($ZKrpD5mK!_>a2J%WB?ft4REo5_wS@iEQw)7ErsPw3%tQ)Jeht zffq8Y!trP`b~G>{kqr}AuSjPuqb*170O53)ZIl{yjEcFlID`8W+3d&}gOZsK$mL=u z&X=qMm=gF~b%!Z|hcuJ|4tN<|wE&V0CM(dPOD?~P|1ivmm^yLYepi#e)kcudvz#4~ zjU$TnnVjWHry)O)XG^5%Z z=5k^lWIm33!n_J>3A10HmD{+fztPKNqF#nlZsx|1vJ4c_XMx2shzimf>rIf(#7*f; z;rqFi+qArSBUjY^qnG(aV!`6`nj15b58hdKDVIJV{q!>xnoEd!~978ofM8SK(79VimqM z)vM6xP?O8ofM8SK+Y}0g=8w)vM6xNxBLR*}zm%s^6LFRcQ3`1g^q;GJ8Y+*7UwZtv}v#3(L#U%RoOt2C>IN=vgWbem|y)SmDlds{iuf$w$)seypk2 z?e~NB{wmiQlL~%6q)NXZx^qmwA5(!?FcVU!%}X`g)cgG;$MXA`!c}{wTs7C3O|M#> zzmA&;epjn@V0zW0Sw(dil%XeX)v(#_c0VmwhYP})SG`P}A*cprk427xY`V@FU8r7E z8sQd9W3EVu01er~@zC{U_PLosHN!2K5mnS*lS)_r8sQdnw=-5gnCjybI}bZ)IWE+@ zgB3=XO!a3_oJ$^Mm~K&6G1bTFdd6SOFgKA96SYfI*5&%+u4afxtgb8!V=pz+J;E@e zG*@fgYOPz|M$Jf?-D<738A+3fuWG9iZehd6%Wws#SuwZbIky1b-Saw zjO4&76FMfxJET%)z8Md*$}f)_Lzl2C_&NrPyzghNXx!W^v}aUW70U467s-r&_(i31 zR#DB#uvWiP?^fxW;^38aTVM1AManPOC83<+*-ZMSCS8r1M?)+)<#mF zW2Q$`J#6Wkf%b^3Lzb^l&$CJUYPjBi)%{pf90qx7LbbE7AK@`CdrX#AnCIvhSG${O zj_vqru*z{0i(u6!;~Y$gf;mOZXJ*DIbJ409RD{YXqmVZ|u4W3W#jm+crSs~3HoS#s zB$k9MQ*u=OoePQV&|Q3mAVa!y^2~S5&AYF`F%uINOiEhHbhef0v@$p+%D+f4Hu3k7 zT{EUHR9&&EE2_HE_E|-r1v{KR4??8L4YvGdqouX8Ma$M}TEh4=Xx*{rlgueI!&t&! zeK2K_ZNi+0rOjf9NSLfo`sbYSYLUDn4n?e3`hXm!EH10NtzeYGT{G#`^%O%L%17^r z6@M0+5}ARrOjn8~AmS8O?urNJ?{XgO5#23I1DJ+}?_?IL8Q(^rYnil=k4K+ub29A0 zF>}q6KcB&vsa63>mBxaKh#N9rVwAF_sup*@tgp+;1@jusP@=CR{w2psTbSaJ=}HUjrb3v(220IibUWLWJ;~% z#D>;uc}H^v&ariY-VK;)Zy*|mcR^;>n}WBan^|K8Y?jk3BN?P`mbW72saDJW;P$8u zAupwEvc~P%o5UUO$pzr~UtI{o4cH>KXL2PbbR)$TBY&KDJO!DURaVz4YnDE@`>{vw zUiaib;NeiOF3oOYq=h9PelDXE>XTSfU=Wg5c z)EDs{p^1*AFYNyM`@XaFd-AHdj_>lDuB&&hsn=AQov)=cZpu3-N-exx`kPqARDk+$ z#LX*fXf$0q`z9+>u?nm`Dv-l%N(I)^b#;Hq$DuQNY2W45@@4Z&eMjZ$WBIaUjT+TA z_Cf_P6TXfzs)jTrQ#wF$&GBXwH@;%!^o+ii8Qs)w1S@C_=+c>Wi%n8^IVdADqe~$U z;9HRqE2Yqbq{u~tuW-A4u(uq;qWaoP4@Xyts%Z4+HWH$nPF+C zQv2L-wv1!*4O}61{sX>@`#bQ0rHgIWwj5wH(d6=GPUQ_vYfZCo^yrBAS12|ppg3w+ zUm9VnPF1q^8a=Qu$_o6bL>$sJz>;XLMt#P8V~bs~-UeWZaz%FpYIL6_7Po<%#oJj_ zWQ(08P~IxGKmomK!h!;b+$4p?I1z8u>@vI+gmw2S)>qFxQx_!Vr^dQX$3-z$@}(H{ zLz@2Q_+7lq5PrYfclSe2tV9mNLf>~+XRepjpYe@w3yuo4J!;#O-4LE!__pl~Y0 zSHG*nwPgBmy@?Lj_oolno9S?!H+{I?M2AZ^;!TrB4VJFV~xC zxqdLcTqk_Frck1RMt2%@y=hR_Q`3j*gdeUcL|u&>)W4^1!En`ybeJ-u8fe7UBOF#P>#!thN*7=Ca1aGmhO zHHC!X{^{j&Mf}b;6hH@EHbGIz)C!+q3n`QU!wk?iBO`mCjAtX+D;dsnYrziD(;{2ssfCc|fC*4_1vtL3#P zi+FRas`)iKmHuwL!7yLpEEkBHpMq@hI~xw zGcj=ImHB4oGwBlXecyX3cZ~GV()HKnvs5o`dc-fDozGqx-`LhBZ*;>S7l4e^d(>Qi zXRnIlajALXwkWr8cNZq@LH?TBgMnzYM!oQ^_|@8u)8nn z`E_vOW8xK#8>g88cbd%IX>y)BP0n$rNxRAc?*ZnQlD*6?j~dq$$=ODK*+3U3QLX$A#0>&%;Rx@M{XA}mwuLM!_RWi{UOYsc0s*Llk&6VSy7N> zJWEw8JqR9i_$tXWf*S?REyC>jaf?V$f6|~n;5jI7EKS*svk&OhF+KL3N| z{HtRFlg$5umiZrgo%25!=6^vs{|j2?zft)y=YK)V{M#3=Vg48R{4-k3|4=#q>(V53 zZ*NXOJP^^o_Oge-whc|}X>Bim!42XX1~24s*79Po@j^@6@?uHj#c=sTpI?hlB%5@C zAlKZO!R;fvYoW#K{QFQk1n$NW$6S%4;wWX`Z;|+^^fLFckwYxbYgcKa<!8oaiKi=VWM}hIu&mnANq=VQmn4&dc6df9$*peHO6*% zIW{l5Hg3GJ>#tkpV`KBxrnvlywGnXYd0%5Sh8!N@s7U8a&`oiA`PAv^gI;8MK_*_? z+vh6Ny&(Ddv(x<*?m>9l#azTB2cf)lZ!(Xlvqy^i?sexT?mnvCZO+N<0rCM5<_K%8 zDXP4ASpvg8ahe*Y_E5LgUhl~6I#Uj?+8YExSMlt=Gp*is&nb8Nw&~Ow;UQJAD+#!F z$6TIykLOge>C0Rw7jFHokjOTk#i>=wb{Mnf3!)lWkfjOt@#XGsuj`!TW+Tdpo51ic~lfkh*j$^7^F z)@{T-n32y6u@CzE<{SLr6Oa(sEM`26q<|CW-OQy9=4y61@aUN}3GlKI?TFHAs9%M4#(wEQ=Je$EyRos`$ zF{^Q73F^_61z|M!!C06VA2zRR{S41Ct!Z*#!A6Ro{f~Q}={SeMsXlPs1j8#?w7jYt zt7bP)a0*`rB5k>Di(gB?v^*9&!@I~C-XUjr7x=xggCJ3g3=p}8M+39Y)UP>yZ){&+ zpZ(t0UcWcC#=Ws{;w`wI^|?)Xu;JYC$}ev3vpcTr-q*J4VYy{~%+;@>1cM_Q4ip4TyP4W>J-8OELKlR*X z1s#W0ydq~7&q*%l!DVA$W@U;yR{Rehto%Gj(5YQVHpmEdflSXQLzs_}BGoP0`(9{X zNxoNU>b8&-+1F0j^y&^Fwhs8+x0`qd8jz>Hb{IT0j|xl3LsuiE+^<}L%Ya7vpoqs` z92(WGf@lr5D-Jq6<&!pO*C!f@spFIAw!9s>LAS?lP|SADb_R2SNKlKR!Oeme4In3j zVNGKA0{#8MDM5s%SdMUulPC0K#((yr7JkYN{sXQS1+ zg+(Gfj?H*>^V~XQnsFdxz(CN8&7lVyINf6eW$&%Nzoli zBJz>!rBjNnR8X8%>?rGbAwlX9OW<0DQe#(T&k;bW{HI|Wmuj#O-F3FF z?s-L$;0LIx3Dgo=yepjqml`oXlZx4yFyKOt9ZMh`^Kr}#z%Heoyl!`y%@KXU^>>^; z_+0Ymag@@PBlW1*ut68?368TjtbW7!xk}agb<%mQW6tK%SGvGVTSvX*7yBpD@hy2g zLZ>DL7ZSJ+e+94VsSP$~EI1;ZQGUWRBFFp1jTyrDzXWf*P1o;$k zniQ+j5%{*G*p`e)`dKU<>4zGD#6cv=N6@V^An=ZO&^w4qk|Ux`VE`m#)B}n(g3Id7 zzEDNp2@+E{zQN>ZoPC+F-1&_8DU!!6V00y+dp3n6@lrR0B!T1w8NfL67JHwfS8iORiQhYF0d`5!T8p$BS z6SV19*IJspke@uWK0{?lZkY$sW9rTpRt+xbN=>N{dz^h1N=@Mlp+rBDCb6^4hocr| z0Ia=l3xfWa6FLd5mJ-1`B*JNnrVY~BW0Q->xl9GlNiL;hFiw~7AoB_`lLF4#Naf4D$O^Is z#Ty<#dGuYyC5E)SL`*Cxv^qvG6=#YGONv))Xu9thF}iruFK*VTr3`tCi1Kn8dYKv& zLtMOSq2P@os?kl;H2htfR9opy7#p;*?f*m>DvGMbl>4g!CY}(na|tatvl1t1g?+$g z)?K};pJgro?R1E{$P3$g8uuV($(S(KSi*PivuD*J#WJw@#U8XwJn*`y*wV)H@m+bs6QWK2ewWHd1QL2Aqw~ zq+Ir*-IDCr;fjm0HF*iKsQ}g}M+FfROCo-=YLjD=CDpd3NHysi^bX1JqH))tOHzcG zuW=JPyxlzAgw7NpI$+=F_&o;G{!0jNc%7mXssc!(XRokjhPR-L(nzIEz-rF0-O!emjPW*Pe|h|rLse&V0DWFD0}pLena{^9Y3a9GZYch*!2{|w$+MvgqzPf`DS*( zK$!QQsAt0j0;OFqHU&zfN>l6aRG@@>uT7vN5nu8~NRsw`6zR}n2gSRT{vAq^KGGC@ zw@Q+bE?f%`N~0uZ`PdZT1$M|)o*F#YWQ*hxlkzgpLu_`5r#KB4c?z-Fa!(;P8xAl- z$B+BW*&3TG2wY^UIkRS?LNj~=9 zWs(oYS0pK5alYUk+t@Y5sf(nF_tpLk&9;CAGUVT`3RNiJ8DvVTh~wO%kOp?d)e2kvqt z>0=iypik*8E*hzKYxY=yMvV5M6(+AY4B_g26B`qqzeyO-M{ZX!*iUVSbAO?I>{7Q1 zd*6^WEi$z-u0ojw3MsC=nsD?BqguUoUNlEaHAn^8hL8{{lNleG$gjc3m0fPnY|L5O4KeJNJ!c6r>ddhnjvTa3>70^`_@}j#XOdY$DIB|8$kNE ziNDFd)2DJG4tUi1fhSZ6iJ;35L@AW=wUP+R{@pB$D3tNmfr1I8tt*p%M-Q?WPStEP zfQW}NJP1r}dJE0UoRQ)~heo5~(VHKNiU*?N5YOxgGSgQQXUs+whu&3bV$8N1V|Fk) zK4W$t44E-zY+r%xeLS6LYvateH#xKI6LV(V&5?aXdW9_sdv`F|!loNcwitMKg@qLxZH*0iRSU*e1$)NV zUKRSzq*&5k)u2~Ji>hjYcJ2IRo&`Qu3iTs6OsQTcI7tl{&7-^p3T$m}7l~kS8cdz1 zzZxo0@X_W`0L`w!8rLZS?v2$H@M6}VOXArAG_DiNLCz~c7d)WfhWlsgu>>tLkHu(_c`QPU%wq^GGLJ$1 zk0|a*t#>wHAl`iQP7`AhX;W!+%xVqTZ%G}ZW8Xp};iOE@4I!+%?pA}NN`{kRbr7c35TSrXxXLv!6IdW-~-ki~3l5Xfcu- z=tU)m>{c~Pf@!byOfcLDzQekg>54CXl?A6ryJsGwmu&!jmL%P zvW1ai;{z}}0Yk;-&lOof;+E9G8!0Vr?7C-Zeq*tH*CWwA ztKssBr#FrY13>FMPo5h-yt-mPO_EBhH;1r4E*6eBV4ee_O@jEuc?vNjlNO#D zevDFJFXK-n1ev@p2pd@!*oATl>p`VU+RO}CcXg5Vcli#KW$^A0dNIZy;Utuf`E@|? zVGZL33gwqzRg530J5&+NX370JkYmfQiYO}ktQSoXgbi#{Hm1w*BJuae5sG{AqY>rcG@)_WriL&{?X;33J z;mfNE| z`J~@QYB}tszQ)H0EyBlv);tm<32t;n-#Kt%j^OIGe!ns~zUGZ?uy-=LI5UZ(q^G#= zt_N9_xLA8P{ylC~B+h@;S$u7b5kG!PRZOq%Lfg;1^)!3s%oBDU1A;B6f_|(k`fU zX(lh-zeXY_Ap10oIX;Zp@d{IIzGGT%?7<93{T49h%W2Z-0DXPqmOU3-A^YI)JsyWk zSGiP=Gd`GbsUA`;3Byd>ngLvFTk~qaeQ_YpzBXIuWq!H|x2J8fr?-&a9@5)LkB0Pi z(k61D{3vOfwQqNk-bdP{Up#b!XCj?EyXAhmpw6u4P_ANA(pYjUJkx4R4<;MQ*VTQ> zhnGs}8HWsJDm^zn7}9G=A12L)=FfgaJR3~Fgt#>s=66v4N+!cE7s`0?Vpl1N0{cG2 zpe2-~uSjIiVZwL<=rw&p%X{=hO2HVT;=A+UBPhp@zOt;|W!#;V z4Un}~JCaFj^M+*oll46yXLm*+dw!vP0AzgE02qa|1ws-~T_K;?r zsj``8st)Kk&;6RtY^2y9g%!xY(QP?iG5Hd?`FgBvTaUGk^}xtLQf4L|BYe#}9d|R0 zSgzcXFBokU?r)^E!!F2+iWkCSycibarE!aK->N^Y&$Q{+Vr=EtEN8rVXfb%F#W-wi z*-dGZG*s|%DPaG}1%tUav@dG`Ol+4*{XU8y5($U|Eot_5C~N(n4sl;SX`u9E7%GxU z=D%x2kzzOxPEUqajtl1Ws7XyFQZ9SIEjO8lf*S+t(1hwF2gO<^S5go z6b+OoN3OZ=t8s0q>(s}$Eeua?%_$^On(W?EG0;*27{py>Q;-xG8`XL4{p;b=}CZ4oUdJB4CIwV*t^d&YZYrMS^LRMe>ATS;}c)0!(LP z!dV&c#;l)n4=_!D64rDAW7`uw%j<7h-k9YLO8-wV%a7lLqBdd^?IV%BjCSP%>Dav- z*}ekIoJXGBswM9zB)75hI35P{wTGhgVi0G1_`uR!+t>FU(5jAJ zS};dv!r+MPZql$b)%bbQIvN++murC_k7k8F3C#05lN*WBWYx-^887znvp68G`EvIQ zXBTxAe9rQSLCE+cd!kPQYTxO_rk$AZ&&xiAL0qx!fl_2}Xf%invdz30zvX=~Bur=p zEWIUQF*Zxa{7h`64X{{Np92;VQH&X5xJTY)Qe36?Dh;@LQv#Oe9@TOk6R_-ign8HE zK1IT|Jo6P6L zt&(Lr^w#p}p;Qvm2)RbWlmp}qHdJDHLnSt+p%Tl4hdIu!)-p}HqNSMre2j)An?S=N zvBK-suw*ZBb`z$Lsh*ZIufSS2l9^tCpk0|{1-4AI0$ZnK z1#SVePM-k@s$IV|$qMY6Xa)96$qM{!$Mg!U#nY}_fl08yB@+OlOQ!+`ZS9(#|5q{p zLleyZqN$kwZ*)%2|Erk)+6438I~DW)Pt!QKO}#z|{JCm^`CmB|^Z&(Z4BR&VlVIS( z$pj1VJV6j%KNb4P=@n>Ofk{rl3Bv$8rzxPe`Jdzj5LWlCRspNJAW0F%U>1`gQ$^Gc0f|@)wlWC7o0WC%r zW-6d`$Wz#r;8s{Do@6sR(>Mcm8H7tsi+E3es6~c5@}QF_jlYBPA#D6wB7xa%g=9hq zw%q!w)G)SBY86{``P4Ln=b%aBeTt9_hf1XolA$S63L%+Hl}VY}%A~Z1Z*6+e9aMS< zQRBQr|=kMv7w7Zllf;!e4y)Rj#=n&pOyw^IC( z!mFWhHa`~`2TFM=9e70oWz6kgIfW$lV`YXks+H_BPJ3Z4xva2I2_{p#^qk~c(RK5a zi)GAisS9PyZYhAkWjaGk+#QV$az>Wo3XWaVQk2_3h=vMPg7$-`v(#6{C8aVBA@gOh zo_p#F$*wIA!*&4%`f{xS3$!#$;lY2!Yx`g23s<06kWmqK2byJE8)I|=inU90rzK{j zajPs^%Fs)!MVQhA>{`t6?wXfbRobLlUR`DDpos1|!w%WYPR0>e`af#Fq)Lfd&IxGyN~WAE5Xm~yFp_p62t)Ii`zj5!SG0E48U z5eVvWbpcU!0a$srtOZanOL=2%cR)AaaA>Qwh?OFEhv6G$GtUxuKwT_m_C{q^W{E9n z95?-Cv>0RmNktab^=D>Rq<{p~j?NlZ2?Tuj6;YaJXPeIKk9rk53aDAZmO+*d&)X}u z6?%~aq_eFk3VVr**;;7LQNAauy%4e2S_`dLAw{}qs|gFX)8 zHCoV=>9_QtdDQbv(i&}!PdTv~4Y4WZz@BX-GPnK-5f2m=9h6j#!DbW{5B~V(4-h90 zzu=Lx`FVJEtRQ;o0S8BxxUo_>1%k1s*E7#8w#(oP>Wx`S(p#lzK!ld`ytZ$%?#A9^=VwpWD_W z?ebvQVr8?(PxtqwWhQFfdKA>nkr_(1nK)9o&1IWP%*OFoNz&1RfEunSCmU;VMq1^j3iAoZWTeWmCkSj$h*!gaIeQm#`H)xO!JaQ0>S+(orm>dNX!J4lw#Xi~fWVunzck#UZ; zQoe@Jl5Lhb{l!x0W1H3Jp0{J~sxrNAwo_F*7{ZTf1sEjo7!~WE+6jadP@ETz z(*mi~DOcy4URS|wioNSG!+l8R|0Q_3^VPwkv0!NH2XTCz7!2*TS2iQXDCr5o&<|Be zTbrZZEHnlT9a5nHhMI-OfT3SbSko9Vv}Qdu1u)dCX$%J{~(8`W?U!5|Gk{OTkmj2*n-x%RQ`sAePN$4DUO1_ET+m zJ49y7Sj!%B@v02SWRuoXmJ@){fV={YL1Eiz7mJ_ATuwN(3&S^dyqTCQ#%_p;LJ0y0 z*m(o38h|KIsr(JgURiH+iYs+M4X3W9E0ucE=t_lxbVcM5U2$7pN9|^8>s_I_l&%;p zXwj#f7EJnCcRTu6e+5{@F>oBt@e&T_fV3PJ@VkzS;qbIPE{xd7DCh*Ir(WG5nK$;3 z?D;X+rTvg7;F3_@VSDBKe?RHALsAyH;U`V()GQPZNm*!}3WY<`EEEn&S?FUE))Wp& zS?Dem3WuawQ#d3GLdW;0(5&Kndgzc~>b^tik3Ykoa7gUq)G91cm@z323C zI3$hkwH%V4wYuX3Hz@Xqfo%j;0fA^6hPX(nt}8Kv*a?9y-v+QN3~s<3LmBRTU|ZOU zB0!OX4k(0zVQ9haDt-%!T+~OH1QC@qW$`5}W$`6cLiUKEaY*C|AU-;%X5$DGgjsAO z3&eNgHNtyCXstsDh`>n4GCUABvv80p9pVI~0Z);`VC12*?eiGdx%Is9I*^?K#|5+= zXE&HS)Nx6%?HN&7g#CctF_qb3_N-E zq2H6I(J-I7a0F4w9drE`0OB^as*VG#VYJ+cF?^QB5I@1)!@NCg+XdefyBft}tQ?y>3QHze6e6SqrxCM{!Z_x5v;XrG zKl@Kj$?U76C(rEXzV~mr<%IA3A5O{atD{AJvh4jZ`=3AYv%h~zW?vmWd1n9jeeeI< ziJ$!+Ov&u4qs8yP$@cz#ByJB(D0TVO2;(`fl0~&pRzLSVh(3YJG|O-b5dA1bdIDS3 z>Rl3w!CZT!r!J55By({DX`&B!hfz9SNmvF`g#tb$%@9u|O(cw{Tdct4C<^qM!e|&} zq(3kZT-zZDp>Y#P2%Q12lCecqffewQpRkg6f|w_a*oiLT-cB_y7NYc|4vrvQ&A?8P zm=b6!RmDJLQV&k%C(f)v5aI5Wfy8GdBKXr%S|?!%9O%TcoW2|Ee?6>ClheYLwzh-v##(B6ORwj3&a3(^pw$1*-rGm{RaW_)=jHdS_ap}h zP$6MFzhBqfTdYY|SI^BruASA^$x3UW=__*=GmAg?gPFywVFi{$km0gssT4>sX!NEv zNPuV;5CjG7bQ|PVEs;RLfDr*vkS--EO3+dPL9v<7ckk!?UaBfZ63Rxj$fC~kJ1@`k zoPGAQpZ&f!PkYyvNq3D-d)KzcT}V0GJJx3RRek8u?&*f!M)A>7;v7u2aF2b*mbbdS zbJAOF=`P>uUlGdnR<}&s_4c-|cU32K-3q8(Rqry&J`rYn`?Ou&-RM$b9A%a`>E4K! zshI8!hFerZDnTugm+ygC9>W{%Jw{}P1X|8>Gde%1duU9shyoI%Fj-7H5r&nu#mB$S zqZO*1z{nPtDAX@rw>bM4T)1vW86YN|CoH1PsgLvM3>#SVfBX?$h;2v9R&wZQ=d=Q# zN6w*}hRr4{dPOLI$)EQJ{(Q+K{(Q2YRPWu4`{u>kLc;m&41LLo8zB@C5PQx7v22(2 zF+AX=jN`T_yvLH#5Cb)-4oH6Edt0cG7AeY^8|z)`>fNdn+*S{`Z&gG+$pY&J(M2Q( z^elno>F#04cITbbK0^&*ize#G`@D*9H>6y5E{&o(+7%^!V!>niXdTOL<)&p31`!s# zww50M$~m^Bb@g5Wk}`+9EMu=F6D?C}b)bm1P;Iu3nsFD>0z-23kx&vLwW?jI_n7D^ zgHXQZcIxnMDd6qx59VXD5Q#JbhK8*GYrX!b)!U7?Byo`)WwfD>QQvSIR{&d zFsxV5Xw3aRhSgv+sVKv}#R%C&VJ9XbWxc26ar6~TspZ7_ zS`P~^?*Vn=^NBrP$KoQ1H=ni&K3ekoklNJ4Ld8%(l2n+9S(KNkP;I4VyUk`%%|3Ok zF4~uGzoMy!SI7DR^@|{mXn2rkI4CTtg35^ zMf9UJB~p-ARXmW+Eikb6qp53GAQz^~QXu2q1Tv=Vcg40F9>k=0BrAC^+2%=jwJp;$ zE`{yiFiSr`snQ_I5JD9``Czi+hLfP2G`7>IkXx5`Ahj!LB5ycJD&(6q!mh)WLJpNM zJCj8}DwZ0ur$yaSY`AGxWCo=wiFDMf*6vynaysW14LZkMXHziqL+Gf(gR-p$Fj-Fm z0DDfRSz)QEqR{1>r)8x?KvXfZiQleZPAG|vbf>q+NG$abO;CZSW${(gBKkG%Ztv%I zX?AJxEDeI{Jhz=~J@8DLz@@wj*U|F*rY~o3TV4h$&Pwmq`+P_&IT3OT5OKFPvwf0< z{5ak=$~t1?g`AQB_{DB*dnnE=mp3S>7sEePy?2OCkg9yaT2x7vOp{n?*Osy4b`-B( zwNtwoS!BkH8Yy9=5iMxfq@0$}gr!UxGir}E&!uF}!!qcU=MGuXpg}r~8_;7Z3w{*d zQ74Nr&)mSANI#%Q*fafA6wbzIRMwRVpwHier5@){A~RjNfyoFG6Dy}~@3ie7Tc*xS z$Xh6#5J~6F_vr{Ap4E7kD*(5J3Xm!-f&0}E1UD67x2&A82(CV1wpR6n)mrFTflVmufuv2%3fu_(2X%$?X7rPOn8}KU z18t!YqDfm;;2#_qzqflQ99R7y`Mrf}i|h4V*BfH?ez%t{2AKL=mDzhPfH*h{Cd1A~ zm{^WATM~;cK;MY8rXW2^8_So35Q?lAU$HF0PW*0u@O{_VBm9vDIw`(MkqyY-=4~f| zfseBUbXflgKTMD*2d}2Or77TttyFpU1bR9*% z_7lxqbdgSQ8IpKwBm<0gB4nHoU}65e2JoX}WrS0pFqHYhHhd23D*cNKG1=QdT1kgJ z-7u-kPL@^CHY)=NTQRA5mB>yTWaV9A9-y`z;x&Q{%~C=*(L`}H6I%=wwl5@xi`j9d8jq1tSxXZmq z`E5Z{rO`@h@ugTq7r~H6smHHRC#J+(RstKq7Lv3G3GJScrA4B)#qz%~ z-JLA7`_bK*>@it)2mUK(ItR}h1x<;xOx$MALTJ_Fi5FOiZQr~FTs_C@;d=B4d6w0O zC9k7pnWaNMUAw(qrFZ8ML5at1Csn0UebWI(I@!D+3BWWyI z`}s@j9U^{JII6GxbW9(bwfuM$+G5E&kUpg6LtscDJ!OBzT^b}Q2eBU1yHU3Ge#)nd zh#6FnW)y8f7CBMAD{LMjoeZEfmWaks%hWPj+H}3c??2m|7@l)7<%egd-rM>T=4DrG z)?DWo+c;#~wo$NCaK zHz1wBf}HeQD>=a3!jBg}m8iw>XB_3s{v1c8H(Q_uW?h}4WE0la8mrbKQT)=^R@d>r z9pnLiy^3Idn2G5*C&l9NON+#05}XswjTCZ%MhQ$rfI#+<+=9iw{AX#FKq8cF?od-f zGKy>3&3SW4-`Qo|?sCZPr@2-ONAs$ox%-*DblDgqFs>X0*?(|SG@%XJLfKW7yoywz zi=Dmr#g_Y!#-yJx{VY%b@gzsYHiy!e8`XwHU(@-x_l^y(f)TvHLJmwO3sdx=U+a9M z^TcMJv`!ah+qqd4Mfg zvWoTD?H9i1cB8l_`3v(0cy2J3A}_80S{F*^&L9Yr4#7|Aq#$V7Bkd6e`llYzK#xAqx+2d4pPhtQq*fU%8HkxG>U6*}b-XMCs91$d)ZbXR1biK*rT<1sd8A_0`9I<>MN-sCRVno`Y0yxn7xy1`ws zAHGNAl*dR?kUJ;-Qrm7Kl_s3hNzy}cx&koj37m7iV+_;Lu&FwWx2-e#Q@G>(%{#iv zI~MpIJpVqwT6C_X#tizHcdR>4CaDhn>TLT}wO>`%5d&9?|F*WMo(M{VIb!i~$cs&} z;#k7(t_%29YuCZ*Shj)fZ6DVFxE-iJ*Vc~kn8w{s3aANHkxSTr*d*;^nMa%JgDsyVN(t>eVqG|}d(_B`H>qUOt5l(Bt(jz2 zK?yc!io^3Pd8sZhTwA0;6Ot5LS#$V%njKOv3(AG0pQL6>^%G^1=L-cGPnmiN!bY{E zZhmt|b}xwGmx@)cR`N2Y1aFHQ9V0G0gDo0nHvceOP#&o1pRi_=g zO{!B*Lx~`#-iU$u#l5aNt(2-$wqzK*Qgup0s?!urCH#!5#LBL!raZ;uOdkNN01Lqi zSDu==fD<}p%2U9}cqC3QZ0ge}PwAkkJY`(=Hc)`PhY^rxy7~_E!pAT)M_Z>RmbvYB zh=}nC%f8DYDr1X)bzPxf-yG&2^(BHY9q1r6mvd|;S7(G zgSGMKq{ZwDdHAs%Sx-WBmW6I;4sTVuNkon_iNe-}Lc%C}HryAaPp0RZ zln~xNW(uU&rySe<=ltX>InUo{s^{h1WdQJq?h9QYWyhXkTla1HG)IpxG zY|->{TdzBbMaji2G*o9WN2<^#*SSrcOYI!27pF#Iv|~xFy66ANtFJDI*}hS)!Ap8q zquk9dDtdN&!Ve)K{1Qn1u6Y%qQBw9PE=pAs?WPbrRre?7Kh9RB|GIEAquo zm6sGy2+op#`K4{01GFgIo>$I0UXLv>W;z*m%`9RHnvZojHW~DTq!1O0G@A>~=I`6y zx%hn3ut;5U>;*-Ia)#1s*AW*)vtq91i7Ou(T}g)`#?&Sz{zp>*R2(!v6QgamT_~+3 z^p-Ec{y6CcdLLuKLrAqE}#WP!Tc&aDs0{xWS55C@W^H~QlTAJ>Y2fN`eSn1iW>ZOjPM(I2xdd)NlJ z9M$Jw3d|bCY7PxgCl`{KgXtTG>8n=|ae5GV`s2hCt&EnA79e+1d2iHJTM8-#H0@rm z@>J*s<{g$mqH>SL_D?e8J=rliNgk*(qZ*TJX7rvrWQy=Y^Z>`=irwUymV z1`S=@8n4Z^Ts1>!%xqx?RfGprYhHRse@<#4?bGORf4@NHS>Cb&VRq$3D8H@E z3l2s;8m7L-{{z+9xPq?B%n&9{px8moXZB_A6Z%E?9mELz$?CW`Ddm2vCpnIOa`SAj z8El^9^74d3N|+jZSf_a_Pxd6QvdY+a^2+?+Bm5p;D7afVM`k!gyAmkXmvYdW3KU)2RvuiJp)aM?yOfns(hhY(YwG z$^Wzn_7;wcy`mv(+t@;Ku74KJ#J;|%5CNfXYfTd`;V%1%${z_6cnA0=$I;St+hli^ zr4aJ7M;dlY$1gUNcQrh0z60|FcX@N`ck6ucH@jXz>U+P0zt%e}`8?N*Blua8R4?lO zz+Xf~@CV|;3j5CI=wqK7j7?{XLHDw=9EL$)4ysgvN5KlYb;?DDQ^DVJCw^PnG=Q4P zx+SWcJqiP-mILZ^^WH=EuI%XkNL~}Xanz!(A^llyzN2_SV4vcpFnLE7_>5>_X(1lSP)-S<<14~^p6_piWInytl zenN6OEef-o%7IKK!yNE1lKvKdBPnmu;bN4^S#_4)#A~;>JX~5lz*{UH$?%MtH2K~& zJr9kJRn7a5v?rzCAzD81)VM2{`dJ*m+z(A;llx)fI_bZA}fU&aVcbsP?8^x={)C{2qeL00KcosKtkXo!9L*P*pIAo7x~ zL&GGYy@ihS=0S%hgO8=MlHRPTL#sA*Xm1hVZz>g-Zvgn}V-ENdzz-7hM`r=^)yEw0 z4*~ciKY!z7M}5oz{}6ybItye+ear#>5P&~E3&2+&bHG0Y;E&7#@YTm0@DBm_du9Rn z>SGT0hXDNXS=eyZ#~knv0r=Zz0r=`;4)})v{7tg}eDyI0{6hf#p6A{;pRYdVfPV5P-jZ7FbR7F$erZ0RE;~AUo<~4)})v{IOXeJL+Q& z_=f=eJ+lCO^)UzhLjeBveQ%uAR3CG|KNR540?pq(NAnNOhC4b7WJi6>Vg4at{@5&# z9rZB>{6hf#$iy3``RZd1_=f=eJ+pxM>SGT0hXDNXS=eyZ#~knv0r(TMpw(0#bHG0Y z;BT4*vZFrcfPV8+b4o_cXZ*+oj3f zA*UdI=)4@>^n~ybxlmkO<{L^a4wszfHyo?P0yJ)2RI@Zbey^fC+vALgw^zuL$MoPq zuK*?`Q~KJ`9#ujN06zAX%7-};Jz{eu3tNa*s#x-6VgDw`@e8CwI@}x$-+aY%cnZx6X0X|C^AkDDUu0 z*osn7u!oYK_0EC*z(D^mvk&@Tg=ng>sC2AsNCckOL8cvJ@A6Qe%{1bWeOX9dCSTSE z7s8R*v#eSO(kqyoJfDg9`i zn7n#)>|yqCOZDiuQ9arMVOT?r>e1FZOS$8$b*=(^Xoc$07LCZ$t<|Ghp~T=>_2}5D zM|;^r@)&sa=obUb$2|vgNoZ7E#p0}%XzeLhO(psW+hbX?oGp==U*X&2mXjcd6mXfG zd&|{2E}=U1Qg4wsR@nqouVm}?1bbrCaT!6 z6G-7_Ez+2*fqpxlB##ouiGwOPOBm)EXq`?X!a8ok`zcJ0BoUr*>)V}$4Q zt1+|nd-(M?fMbIlY!a7Ha5i+KtS)2H#+Tk^cJS?DV%z*Uq#A|IM^uaO8g z9o99zn+TmTScET_o*^)h>m4yV~<@q$>A%8=$ zmKph3z3`-7p~Qg)RT4CANVGxRVSSQkF8ju!X3e4OuEnZnL?0eGUo~FTBB%j?&r(Uy zxTP&KU|@kel%6vx65ZGly6A9rmS5!U@lDCD`}6F)p6If@dQkWVy_7!)!TBMDJQvnK zKNb~0fkXs5$>pvMSKBLS%VEIzpFz(NxRg+5g;X=a#glV=Fli zV`)Saco?7?OTcG`tC^uEPhzLLhG)17;575U4NNy6OkH!p*H1#H0neOaz`d;lu9wWYhP$vYTMH#*QAj?FpzHMCVMsi>SdLyTsGPOJKY95S&=zN2s;C!T(l>_YZSstb_& z#Z*utoxipk087L`Yfm914UCU^&>>2O;VnH`DOB0Zx|q&oK6XB$WL?g?c%>wH*o{WsxTw(=*hEJp6B7M*GY@rCa$h@fr)ZmJ?d%QigT zUueKovZut&YFuXwD3%E48d6ztQ}(OFHMBuim6hvpNP*j5)|0cEgGz!g{x)P%k3(u( z=O`kQ2A6e5178M83gGOK->FGAuRI}tQvPx!5Xwp(_t>~GR58qb%1BwQeVnu%ACpqH~j1i zN(R8+exbi{L99p169bJ4gY6fF8W)zgUs&0=z-)sIK|*<$sn19%W)^E2cbv=}6On^V z$j8Og9q(zKR*US-gcpv2K^20`Ycu3w%GE)blsBvz^bkCFYNP+tbW5m)1bmb<*K)h| z_V&Jz%u4?DX0=OJ>h$TRsCJp?-K0>MA>9-Sn%dG$O|d1i;`WOioi!Zx&OiE=aZWoh8ujX=R@q0bJP-P@9>7q(Zo~U5BcmjXaBZUI3y_jB+C%8ki= zXtY#jkQRb0DKXVTHy1%ydAZRm-(^Yu)ZU^tnf{7zxZfSFF6y4eR-a;p5xYkN3x{ghk=ow*N8h4K zM1PS6r0#1XHFaT}r)wZJ7`!YJJ7Tzvt#w%x!Ig+~fuz4zPeRh-VmJX6Af}3Zzz%q_ zb&H{a$vcH6_6fDk^V^s(aZ?`wTI|2-k1JLfC3K`=7E8Ze>r&-}Dwr-b=gH1u!y^nj zudyJ6{$ShUo+(DagD24H!;OG%4uPIpkKm6T>YHW(>gr<->IcOF z&H~gY=AeF%jQ8j)KwW*j)o{JVV*Q7u>rx${T`2SB(!i=M;YcR!Nm9_Rhad3rGw$fdsoLM$f%a5TbQ96s>=8*zGi?X`3r^8R}$MHrv|m(joe z=ET2_#7BL=j33ejobC6tTutc?zO!@HYq$Kc^1lapxocJTY2wpidf zt1(72eSgvC;b3gn?>L1nx=xWpX6Ois+&W@*%cAk$oJb8|xNTnfqW`Ukkq^Tw7O2V2 z&c3EXH;Hl7dD^>2KugNp+c5%*;02o&yY>UFMOv+@R5&W&k?lOX1+5zx^dlG5o#6=2Cb{_8xt5EC8Cg8ahu$Oe>(mHdM0C(d3x zijN4x*Cn={BWjgkh4-ZS?T)Ik_$;}`F=NcCVLmI%`Ru=}iHdYBZ~%wGCL6akiW|gC zSMtQCl-}RH2*lb+#2E`b^Iqni-FI}Tbg}mraKp&pRX-M| z#Hqa(UW{4$9Q^{m58*PnD?~%4rN&)@^#qDSi8Ij|o&vcbbQPTWDu%t%1E_MaXc{If zZiJvw0Yv2RqLb%QI*?R;0VQeHR=V z72vyy?{6K`E$oP6oXZ|PD(d}Vg0oYD+Y$K6e>u>L=2zsgN^dv<@(K(gUBN=u$L|(P zXD@3-G#G8!d*bobd7*t=v}x~&Cq&qW)ZU;rQ!8-Vz)!=gsM#;Jo#J<$pI?<XB^17QWC<5yyQGiT6V(JLXNsf&LqTeV zXTR7)QE`+#&QS_yRPFn1|8G5dZ;m#yT0GlHacEr^niUwJTT4xA-O-W+Lqw$l4> zUq}n_@wppiU(3AP8A{BN?=9X&!N5Xa)LydaY2hiQ)PkoROX4me=0rOOv>`bM7U+os zXMr+tK+gKe#dbpr>m!Vm=O@$H0_)SA-9A5${Rbl$ixksvP6zguj07K9mn3aj%3tWI}eb&BuA0AK8m?Ch{HVt7I@fipkdP3EV2 z2IdE-_}fev^HV}_PtwLiZfEF&Vj^K4TOqjJAv2kIyd65&ojt^&1%mvT$}4V1hAeqS zhv0TT<0J@PqmRU$uM0sjiwy`~IZF_1u#bC^V8TrU-*YmXeM`Y_uo~IpUfG>R9-4M% zRnw#t?H5%fnJa;viJcJ&f&-UQmtd0Y7OGEiAJvQfmbN-cTJ#IoW|tdp&0SrpS;w|WJT;g?X|rW= z1MQvj5__-%i|czfm~fG;t58CU5NqURk-R85RBfTq1CH^_qMl+zI(FS<1-gn~zwiL` zfIpx}ysqB4xJU|wR{4^6jZc_A>UF8#Es#RBA4s%&fP&p0re`QQrx26 zWB_u9ZvC{Y!B1PJs2#CNPMJ&hEi_N230HvuEj+vF(TQ2Qy`D!HfjqqH}N z_HNo6L;GIZmxlJ;wBP5qYsmAxsUgo{EM8OZ%)CA-la<+_o~349aQTlflVsO+C>C*k8pC_`7CUa(85I|^Xl_K> z7ZXNje08<}rj`8;^Ae~aevlPCKS?6Wbx-$*%^E-S=ir^74S}M78B)z;-<@A}1BSpY z3IO6}fHs|jCNd35@lafbFB1VY&uNot54Gii5U`7D*f`(|ZtqId{C32y$95g=Nwty{a{<4uLA3;1stEF}LKQ(V*4YDx3rNGY zhRu~10ZfV_;6<#(%dPMhFBdGbn0tdo7B8jTui~W?EV7t;`&`DQy-Dq})TfpRYhotzx31IsxK*gMhA}P-YbNdW z&yPjTcoaarJEl*I+SG&iGqBiyAwTgwMk(MLoN)M0uC@@4Ct`t7Se5Ld3Dc&9)-Q2n zT)PYM2pdw&hqsj-<`mgGeWGdf-k`RO-s?dGmr|0KKi)KBkLWsKBE@A~U&`@A90xgW z;5fkXa*nw`+hPm{MMVoH8NJ6N@%TA@yPnsw@&-MLxaQ7#sbikk* z`v5z5@pU?wVe*q7{Z^73;h+jG0wDUyzQ)(M%2SmZIXMh_$YEs-*-xPi7N@Wr9Vfqr zYETa1bZf}kcxMo&z+r$oiX3vPCURI(Gug7ghVzMZSBLA6)k1uUMNM_pj?~96UP7xa z@jwPPjw5qz8ILF?rQ(4M_~smz3pbC*5BDdO&R+Uk&f2Z0eYLIb(UOtNE^eS*HMVEwrr;|GbAFVSbChla z|2ZMesjNox4!F0?ZPp$N9;m!qmwfQhf0TTW-dFCOFe)OYY$?*aCx|#jv_{m5D^1r~ z_?$inIolWB#X=b>jcTH!4+ZyG9&9V%%GQ&MI6_pV7eG{O#3%_A=LT0XWP&`yz9N+yX2gQ5BiVhBJ;(S06ba6s))eAQFB^hj`u5*=w zL@E^!mhX=^3-jbMbsW4Srz@-wHa%AV^pCUXAj8^Nv-_cbq7tsabOBECt4~0E5RDv` z972>h&x#cewmcf*ZitqJ2N#uE>QfoyV7qG~3YK#Vk!`!axGTzTTU65%(1a@}uWiOMLZCxmxsN0K*bZ2=kZr&i!s{*c+U(U* z82?v*9^1BRUqsSq_91-{?Uec=94n}wTjJj*e-VB&!OXW+S|~*L0un)l;bL!FW@rls zz=&X!doS0CE3s~ah2KGLB#t@$uYBaE#xPxs9BEpS*2ysS0MRW#+N|hfZHjltm4Gp} z{qvR0sBCu7$DKV;g`HMnPZGB@qeco#ejvYx`>jKwePQ0EKCpu5u-Dx%&0bf%-wL85?tl%U z6nf^R&|&gD=$~leB?|iII0&P!_vibSh1t7c`q==X24A<@?h)KSxP6>541m6x${Ix& zTUGQk{Surih^k9)ssjDtUOxRWFQ3lCr0hAF^VCyU1@-wRV&*tt5Aut$>g=s5tIkV# zY|sPJ&Ly^5q_JpIEF0a^SfsU&z=i+#_fHA97SMyzN{lkv%g8j|g((+V*>iysTVg zb4`ZzuNZ8oTX@a`L@~LlA4^BZWL8~5QUzew>RHaGW0D$(9kAH(VRWB+7O_dk20-zv zqGa+2vi&>wqw^Dn)}9h-2%^Oo(B%?l@A5`zVC(yk4_#bAL-HjIhK+O67s$&@H<#!JUVY|Y|J%E^P(+|^>ZV+&}VY482bZHi#m)=SgAnT8me;U$JzHlVCf z^1HR&ZZDS*9S$Rb;^D;jj{n?eb&-`+Z3XRylpeq*0y8td&7 zcyDqayJ=hhLJA4KvV6#TE4!yzTF7c!*ge z*zC?G%O6W*1vr|nF${=yYO}|L7&g8fjDo>RFHo{24Ne6I9UcJqdOIyWyF=FET9giR z5@-j-i)VZbzG9M{G?Fqom>la05ygWUUcm0d%(GEppQ2&*n~q?=>A-$tx!X{+!nB(3 z1XkFrC8C>02~!9P15JiEXoO6|H$?SFyA&_44+<1938)2R*||(eDzr!4yN%>{k6}^g zXto3PBMUk$S^e-h*diV&ksR^tw}AM+CPGdBCq_lI%%~&l7lFvwI%Bl7ar9n}O7e9nOJ0#D9m^W?qdp^&k3NC5EU$*OEU$*Ouvp6g zC@W)jaYtC_m1Plh#q_yC$!cOWvA>zjx1!zdCH&p0#mEQNx!(#85ihHy9D0EQXXuBY zd+oK?I>k)Mx0Erp>tg4DSjpVUO$ge`xvacxdJ@WM6z09fku;+q!kh5C#W69=#&Bke0VIlc8=zSZ{mZ_P2%SbD&Ii zc$2NbbEkl^_=&NLH)K!3#7$OqrK=1H(sje>NXx^4oody^LGt7b3imYimv{A^)O~1( zrQl!69IOa>%Dzo1IjMlhD@>>u@~Hq+I#M!ja)Yk|e_1%q zIWWT8qop7mA6%4A-<<=S0NNniJ)ry&C_yQ`1$yk`l9wMiQBuCOM;@e|8<`FH|N4W5 zV6qyozx3`V%6hu0T~x2NJII4(}lCa2U)5quunU; za9M03NX}l(!E#Tk(I-;}xF_pXpG`tg%P#JA4i4{sx5kt%=L>@iM^e0W*_fsP!Mqxz zm85~^FayvhOIE}uDULLRE_Qz6K2Tfg7^8q-kWoxl-yMAn-8KVztL(CF*TCDnv_cMK zeB)HZ__l80u}Y@SZR}bp(8Hk6XVn)`@xnv!gE)f$|2FxML32^aIZy&MvAk~_lwS@Z zfqUE`KKrM`T9Rp@wA%LZ2P%JW47dgViElKwAGw-$$e&t!P|bH!`P-J*nX}cFIP9p5 zw@0nJsMLDELy@{lO+<5C4%bffdR(k@>~47;+NWgF7p^T*{QKoL-eVdG)4`HKJ$R1G za}opr`L{DGTKuN_;Bb#C731mdweZ9p#Z5%G%GBZ$?$gSEEtz0JN;4+o z8!LAJALecYAN;t1Zwu_kRPg;ku4XfVk54i!`1ZI4V+!~l``lwa(}C}aSpwhq8wTGK zCHR04Km+@(3)qKaYH$~frSf*{3*ftHTJT*?HoF>I;PY6FDc~EudRNDE;8T>t zeiyGS&c-Jjp)c3)w2OD^bc?tBc^L2gEMA3nC_2|LEI4q=S97PskL<=<%f-7jEZ!|) z@jlzOcrz_tHppkh`pkrV7JkvPc)uniPb_hoJ-Ip%l>&t{IT-$vVL5#iF#*GgQ7nZF zq%OvrE(KYhXl1~a>K)7?3qvQeV7oQ~1l&0ryU3!fk5YLUTWMY{aAVVXc%EJVFchJHKulH?Y;}#*s#zzz@2Xb2m`~S zkO#nuy77&J@#QTg81FoAFn$L$E#G)Hzz8N*S}{@h!xyt%UK%|xs6!ak4T_?_6Bfx2 zgG&L6$Z~0X{+f9)&neD5Ce>6L(3TJ|M_UpVxGxK89OO7d+eE&W++m1oLQ#o}hUBb9 z;bN!bBKHXwF_Q}+>{r0W&SGN&7jF$f1Z9Maa!6&W2xkpM3%HnMpCVF8ET95ibxZIn z;U$7QiB)6}E*fVc27?(iaS>U>G4aL3eb7fkTv}p6kCfTA?2bz&)Q(sM@}Kmf(^t$qC7YT6*}r(>&Lk8)%;8%@LYsc=Kh#Mr7aR z-U*tgc=K7BYrHv5b6B)tgh{u#qK`Obgkl|+jLXj)b(q>us4YMA5o8AxUplwt8qUGc zs6DDSZUe=|TwluZ5{`(F#RoZ}xF{~=nCC#L%@2K4ach(O&_`k;0H2X|*U^=4Mm z;(hDt$Q7a^DNLK`X{>;o)SY}Bh)G^Sky_z?X+uSI`6?(xYACX6U6K;>j*7l;?K-E{kq#Flw0Ky#1;M4fE?7Z{5b;SrzUKkF_5hzU$)2p&&TDTkYG~1EQjY(*3dPxS*>@=gC#BPcZ=2lJ8 z0;uJ_(TWVtVq{6Tw|uYghe8r5V%;@?S#c(Km>VQ1BZda-<5`P`p}aO2_b|~@gfQF z`D6zI8U4}#S;>P@$SFr$D^%vdC0DWiX< z;^Fm_V<;o+dvvCF_4@lPAplWH#rltpX{N9xSF2`)o(5yJX-(>f<(7n=a<1uD8Ih6{ zQ~SN7wclV_DeAtr#oF|Wx@}`jp>70Fv*u&!7a%F3zl?r+{X73U%GEwD`qlOCJRwr@ zAlg4uTewI2hiZcuYJX2{$%(F<{c+f4g2cjUmgdVZvbDe|t39E%p0!XXWXc&5eHJeu zG^E9&Wu()iZ9C1R5*xh9E@6%t&GcYGcIdU)(~yVk-oru|6wyt7o*1WnM04o<*@R@d z6B%Kr-A&VSf$q~_lj589`Ane6>|dLk`^pBjwXa;o{t)(+mlf00$2smD(RJ-BS95(S z$7?uhU)joWfa9k)<~g6BZC?rUOj}aVeIDPmH^8}czj8P$jI4yS+6M?{Y36fxrb1hf zl|p+hEvyu4yag8y5pi8UwxzTfXx;P0Ys*HKeQ>_E^~Y`+!OS&v~UfSUe#K; zw5`^fId|&FC!1h?`HBGM+W?oqd^<;h^A3&z=ban{&bv4YoUrBXxl^B258^^lgyH-;C$K&OrP;C8$DfGmq@7a_K@Mt+bKK;0c z7^0OqmH)a;VvtA7t&qQic+wlPLuIKfWK4UR5X?vt-u&4X&M%9yg4A7h2Tmg}LPfVW zBwPFyOQ%wFzCA)}=cSKJiFakkP>XfR*HDXf>48~Amu+ROK0-{z@VWQaNj@23ICy7m zg^2_tR)_51ytIDF6QgwVbWaSJ4y;#t3Lz!9W6;X#=6gX4Svno&F}kr+Z~$(S3jWDaOe;V;+%lYfpdmMzNg@C2DQW(+F(Y7w}zzySEh)tk(m~W*Ec5@*!xz~ zVlrIhzRS9CQKmd-#VWB?W3=IiRw3kx?SW~t_ye$bPY)vBk5W9#lkir$jD4(c*W4_3kM$)2ul0rcd% z&K{)xHuDoqwE4Ar&>E!D;;F}pjll0#yg5d4NTW!NRkGP?!mlEJearNgLxO$ zEUX|Sn3r4nh??clRXdu+E5{emM1KHUcDFoQ@Xfa9-u&qNsO-)oSjgPf4DJ2Kd~=CA}+vyGy{DfunS!^()FVRVjLqPyXFh(=HSNWmLDVAag;BT?KsNe zLAYr8JIvrHn=0>X7{WmZ*wl}i2pWii-Y1B3_KI2&WT@v(JeoHhyE+R0{a+Fj?c_hS zoRrr@oPCc}5eAH~+1LUyM|Sy|OGM0GS|WT@rWd-s3`c3j*Ijn(wW0t2GMv5GuaBzB zA3E051U9}tt#0L@4EIsrx`Pu5zoPI)yu3{JxvxV z+Yj#$c}wmQ){+n)X9n3(LyAo^M?Re-vE$@u!xM8i40@dXJ_LWqJjt7)?a?}y!#-O% znF@3hM|nzpGl*o`SO*>UwuP=14?^p>WTm@P(!zBTE?DPqr|i_|DVC{0D)-<0V3Cm2&>S4H^Do93iOIOtK zUx3=FJ*0R6Nq^)%-9W#2<%D#Tj_C>MmY7}=+l z{GxX)83*gh+4_=ei*ABErR(8wZVB2XT3Ibhht;Qs!0I543Fu*rSYV!lCP}P`Zjydo zN_L7i6mlI?PLfLSX|3SXYGL|d73ypEX(ch62wkaK@)?kq*9a9eV7is_O}4Yy`5a#%`AHjCzt)^*ZWEm_sA=7 zySo!4;cF{+nU7A1UQ-hSY_BN;*ll~pr+`&|j>=s_2uLriI>Gy}_Mx;elf9=KMg?Qp ze-rJ8X|XA2!L7Nr-YZoPS>h618){fzNyBGK5%xGsKehh(v6lQXuqj(f!iA?Rl2?i* zR*7Rs^NW|Ol@C_au6WWI=7EbnG>&?sYL3zr4%5xEvfJ5Uyown$J4DHNCA?c?HSYy& zuowXWtQovH8<$bg>`Fbi-LmVAChk>1H!mReMa3dH|O>XE=G1q>||Ik~sk#ha;;bRVCKt1^7i;t45j5v8FB z8@|H6_6i0G12OX6aH;szb0~_|$l=&p!}2*+OZlkI@)jcO8QwyKJ9hp z)Jb0;c2GpgUg`E<@Jf#yfgsoRN|GLV*8IPdKmu4xZmS-BYtc%P*Y_(qmuRAhxSRX1ms7@a}KB%IheAmMbH z{M};f%ckkJMZ4Yml2>75eTgZo(XlS3!A5JZ(8}Gxj2hFX*K6IG^bo|8+0$QKwmQ(6Xr-blK(kh2BFfrpc?6Dvc5SHXm;vhmKtl8eZ-crZ6Yiw z6*4o%LEqZ=hrrzj^KWM}hM%h%T<^vU1h-rvNO@ZJGCz&B7(uNUjiQ;h$17zRqO>5{ z7phL$#NYQf<}M;L-sM?NFrWy>*q-1A#jqN3SJD`h&TA00TAbRa(A7RMC+3XK%M@MQkzH-MfHFe61Uz*| zr;T~(rL9{+XZyY zg!y1&$8ftX^G^+@_x%XfSYI}JjPO_(Xv#0uMRByM<0*t{QJk~o|HB8oBN$b4ZqYAK z^M|8eGjDmw{3l7OXj)kx*Fx537CtB$z0g8Lqk333tC7XnQC1#?30w92ouB{GL+c-X z@tJ5nJXYGj>g7wW`tlV&zi;Oq7p=ckj`Y?Qd>&8hhHTXp_x|d0J3sT-2Tu(Te0$>7 zk8b(!tKa%>>n~jusrm|GjKG>S)5kDBDdKS*Ppf~>r@RxBZF+9?^p{I~3!1y9+zTxKXRU7j8WG4u4WA4Z)B zj=Q<*0Np-78AidoqOlqpvCtw^jrEOd$kaQenJbsNg(hKhDFfoW8Uz6}NVTv+e5&|Z zU<}HEGR)sPu*(Zgqz{+PL!|BUQor1sM!0imN=JEXM*~wXuh>sVE2rE^+@kQhNh;h% zWKoEdXODer`g3+1cu=HqzzYL8*Z!6|`2ZKPtWCV^BZkp;3K4-^jCJ~#-MZ5uXy zG?8p#)k=A+jzz7jjtLD_ngV~i4AHvX*Tpo$2@9IAD0nFz%(S-Hm2no-LEd+Xl#XoL zVPBBOm7QF|p`}<{2wt0Z+z5$e1f;}Al)r}OZI_{?U53vI!RZSTSU|1R5iu{(Q!^|4 zP?d^&o3ZaF64iiB8hE&Z9vP+hhkaud3jOGPQSr5?*vBz@nZ(7#Q`<;oJXmbLfpiz! zai<0Cl-MR2E+%f|3OjH1GAJ!Pi-Y;@3_m=HU#f*wDj9@z@4NAW}sJL?vHOTP``?Og-jBwU=n zf8ZhwLodE6algiu`_D2!B2s{Hp*@;Os<*m2f zwB_~}?ACOx&b@Nk`VZd!h40<=^YQ`JJY_?$dHrHM44+fq=q~t~+%G3w$hHokzAQ^|_F2R^-i#1RvB6*- zSCsb%Y(t@za8Zj*HO1+1W8xO&sMwf5&g4xQ=(FR7%=gj!YD!e7^ChsPSN94mqE;G# zc{8y*vgb_iFSd0P0p8&Tr*GWQU;6MhCK{&c=*hkc^Ed~)LxX3&SLv+$@is? z4tLXjQm0ndV||2(D<$z}U5jW&;%gcnpsS}ox@Lw)3EFQyt6VZu<}!`^;FBDj?(U@x z<^n5JiJ_YRY17?(dgJah+V3{Gkf$o`Pw}qi{Dx}(QN=G*6avzov{PiKxn%22oHNQt*mt#1K1xuc`;_j1DYIw{z-QI($peU~ z%zo3`><#N2N=omKTwX>*#Glta%cL>$b;K^#J;}Tn5N^U}zzst@$h8$>xM7l5)Spef z%1%S5Hg9Eo4(^q3#s?v1ilBo&3YeAz(^AFuqeCDW$7}CE$DqTBi(TrV`sLYmr4Qhs zh&ojE6zMoyY0XJ#LV+U&M`$yyULNBlFVFU1(l)XbFr0Cn?T0DSyBlm2$ewmrb2Nzur z-&ZMi;1E3JdEQED7{aptr*z`BH8sUo^0Y#kx_C?*Wwn?uthFE`Chcsg;dAz7_$4lo zlUo{n{priTcT@l(JzQ7syedp>;-dePUdz7p_(P<|3vS3Ae0|5;&7KWifkD zn;Dbm`VZcW2^$Zw*PCcUVs~Z0d@->ducYtIBU^&YWZiLhHR7ggL?M0DRX%o#}y62y7?tHKD`YscfLYhlo&pds{^*8?fnlC*XL@LTE z(A^7rzx>R7pZoOfK?*~rMy$cyWJ1-%-YdRHk1_FI5~^N$r)P z|C468C*Hr11_iWyMPtEkEVd9-;80?x@g?|x$kM?-uCv{`X&oa?v(OKCrf(`G3UU}q z6jWXO!LUl9A29Yf3QL%|m=;PsnTu&POw>|es|(J7w0d0Xa@=c*-T#IWYzLNe0Et0Z zf0k$80Baebfv$brGI1?=_kYoTFQcVg15oKJ++-Gj4O z{E=DR%_Qv@ia#4MeIIblRJ!m@BwSa~s3<`IjtYccodH6ZZac}O&SY4>Hu6hK8MQ}f zCoD%8E*QyZ)kW)9Dco+urqQvHi#{kXnPfPxO2-?)%%n`-?=41Ec{H!+nU)9Y)s|o6 z>xM;XIkCP59#&Uf^gcOBu#Dgk{=XZG^n$Y`_EPCm3}>7FA9~y>lK||cjxOhm%fb2x z`9RdohspT=@Gb-{@)^vj2>_slGXQv)%$gJQwwy+>yJa)KHu$gOlUJ`l3G@2sW-{Xa z9$F&=MRtnBXAHWNu?)quo_QL)9w zR(5M5-X+|KQ#L;ZPg4YQ?~PmJ$=Z_KUg(b6MLUC(x}}7hgasiHRkvjOzeR#kxQi@R z`|C))a1ScPQwqI=SD{lBF49K^xcFLx_J^T~aZ{mPZq?j$BT4CVedSOFzK^%H*_U9l zr1e7Q047tedRl$#@k&|0dEZ!>vff_UI}k>jdPsK8B>QKn5Pf^TBXJ*fw9vAGplX{w z@nUN(SlDhBFmf!Ul0*NWOX5Yz7hoKyYr@>0H=>RHm~>2D8{vQu?av!pcmMw2poKer zUxSF*!VFxj1sQnl0_-rpKjgj+n}u?;jAg6j&!AFk+OA=d4;2J^el7LLhan;#_;{6? zX>y~QLO|J8#^4JS1Ue6TQsI}ySP+9Cy#)v8FUd3W9>s>uQ%0nv9B?ff;K1gSb6_`E z!hvmMAqSWm+{wGtg3gM1&&%=49OPgIC%c1SwB>#W0ctCuqTgYkfO_HSsm`L}yBw9o zbDlc2ef5RkudY-7V9K~%Z}M)h^1NpCcgDMI+G(WpFUs6WFw?I zm#Q;H4F07-Faw|2uuYc)tyhzRtTUS=x0NPI@?Lb9-#j)NF=%Y2BeC>_xM`qH^b^t; zBY5dVLG+;R8ByvB`6hV&3)}NyE~U}bmds|)EOAAF7l0Qub_E36)j*ydlajpdKc`=nGn%D!9uXWPg?~LdRWr` z=CDjl69NZYO@@)doJ{k$I?W8`iuTqkXFO`Eq#rs4-%s{v_kcZo{ z#lh~PROT_gUDeix260(DozOQ$I8CCY}-hWLz)sHi>dPDuoZcZr) zhI`onE2zwC5ETQOCh#*|jDFEZsEh9Y=sS;(auy4_%v$o7jwWu9OX*?90( zoFGi-Sv86rN8uC;plWuDHRARo(DZXJ(DZjR^_SkuKAw-HiAL^9!z)7qfbxLxvc=T(wl1t*aBW=L`&-;os- z!v8=dYNPcBswk`yONmwkTU6ZwTFP!9yTB_Mb~fAIoJxdx2r8K zeKhOJRT0QTxpXRrRCB=OU8TgL%yv2$=b zFjnLr=kV!(@M#WC2Zm2u@Es5vFvr^FGl~Fna5^x2y5>&@pGrx5#A9d0%$dIgVHGLN z&3l3jm=>cuzwknW#0WpE@GY^$Vu0blDF~>@7|djyoRt%W*db+>m+=CQNR|NDJlE5R zn+s+r>EmH26%E8;Vco)gm_SyO=LN1XwHOfrw#I^MLtbMAZuq(43uqmR!;3K;Z~}of zCgVtUDK-smAiQIPhj)-dfY1pSALv!Dg>R=x0-6;pRGEqUm))>bW}7f809GpL3B*~A zgcRJolku}}Ww6~Zc>T|B3fM40g@{Cz50kx~k7Y@iu;;4Z-@yXpwnEY5Q&tV1f1VxGH1b-++ZPrkDHga{Lc+K;QvM|FHb zL1EgU3pv14pU(jW1gFtP+>rzo0zj-ma~h3FZp&;C_?UgbF6BH>^%Cwt=TLW>nKY@G<``8JfsbRhpDwQIilVo%kD47haXYe}=aR=P zBSyw1M%qxlUkc9AvbzVflSJ`E&dYMC%WgSJ#49oSvsCsa!-qktszp(;^T!|k2%c{! z&s4Chn2@iyld$0M4CX0H2PE^+y`Ol$GCFPr|p{49t7$>wHVM$ZO zs9F{!sI7-fwiihq$o-9?PS&2SqE0)4K`1!H1EMJzQ`oPTMMIDXre;nI5M$UmehspR zb68qqx@-b!6Y+xehHikz70QRU)XJ>e2}nqX+zw?~&|P>5BE6NjN0XzP zBl(BrwOR*#wf1#KuH!pR32f_Vi`pxC@yh|FwGJs6o9fHcf}0dJ(1Hb&g_;&@VeTzh z#X)buF%NkQmJ&rX)f@CIcqAScW11T;r}3VGA#z_RkbMmg!UwPB5OA&G2!$t^vLV7; znei4#29H}oObbMup;nNsO3S>Fy{c?^Vw($`!Lm#7Rn&cn@95(6y2W}KGXc#cAR<9x zwA#*gi@TmR2v$M}g3KSrxgsDce7`sELhO@;*6}-mQo7J4_eqJOp~?v)7+y;b1rkAF z@>!xX(ZHc;mGjZ{;=DHN>#0v6BQZ{Pk3It2H($8n8^(D(+>jB0u1KaCMpAQo!vBeZ zfL3eSk~ZRN-2^&B$wQ@%)V*%CS#&p zN5!jh+RWaa)M(*p3wL+3cg1ZowxQ(RhO2sGDgo+^*%nWhw;uJ}h}k1fF#0pe)bjQ+ir*pgke7cuxi~ z^AHp8*gCe~eZP>Dh#MN&D+Dp$EB>9hvWDEF{raXCENOY7_NdxgKk|~;PhoDextZ7! zY;GX8p_dG9yvwvjxshkX<_Pf#n|E+=UH@e4IL?oyh)g=z1NdDV{)(xC_f4i#eDGnv{3-dVXX%4kbyBN zuD6+qlft8lFIRm1X-!Z}EG(!x<`n)9Ch5^@(j3mBI~ikd0sYcVV!km4#)@Q8qw&5*6F@7}OfjuM&S9uk8>1L%#Z9^xc*-kbcPE#4vCHh*iRJ$yZXnu-(#<3e3)G>Ie|xf8^<|4NNJ6 z7iz82X+O#=`rx!2lsPDUk3g;g1PQhIYWivJV#cx%Fe->?YbI;E;KdpJ^7_T8R;!+D z4;etyVsl|~Hhurh4l;kC={|gHAKspYFnP`&lK!OfF5Yu1?Cf7<*TKjYJH7-Bh@j$2)a~o=7cI3SFnqaNARUo4+Bl-qbf-U5?m`pxVa22`KyGk|)|& za#zpBlUb{cfwg*}g|(VM6T+USQZq5c_qP+z>kAI>6Q31JB06x;vwJlrk9uE4_$Vj)4+6orC05OEsJYubGW^IXJf zF#ikj9)o$E&6zJT2sz6Kvuit4Jq)^QwWmavk(F{~kL}5O^FG|5=jRLZjC}Bi=SSoV z$rOJSdE)!?MfoxL;(SSdZ2mvwZ_D$%me=#Y$OrQOG5-(wf6N|pJuGx_UA+eV8WaN` z7n?7E`J`?#vmkr~{%(c0;O~aKg%CREE%>{f=dj=n!mkzE^yu@|V?q~sp{;7|${Pw#{Ng&@CbzthFgEKrz{7>Ui=*8p-FQ4Jj<@RXrgIb2ZI~G7^+qRRW z4IfNKi5-)uWG5;2V2x24NiwW+TSI9G@sDg+K_E4bM1n4xFx&iLJ@758OaHkP@l*cI z%c3pnr(m47tC=UZZL8M}*D6|%d<(CU^ME0BiOrbP#l~wNB!7($zLDF&WcK=EE2oPm zZe#;1C;d*$LeN)pZf0gR#^I} zjGjGsbkuuW&?gNAJ7)2b=f|P~10!6{PLg+MU23ssj~}KjdLhyZhpZV~m$_2OSb;Jk zPHS8l-{AexE=V|+&egUK4@qWucNWindZ(xd0?%E@t+02zHV0G%0s*Rxh9s;vWu8a;y*??Hc@;i1qh{INM2LCE2zm%*m|XgD&eX zDa?DVqLZXY!Z-bt5@_pwEjwF%QevS%<1wUgzXv=%i>E=Db2xD8X(n9igq9-W=PC7G zR}9czQxBO6X`f!7=jsI7XA+FV=3;1gAqS#x&gC#qWlmYbvY#hscnbykX|$N`DI73q zAP0Ny>E8PiSCOEDs|-X=48_&=NtOWpvmJ|6J#;YHd&5aJmh)gTPJ=Zgg)hxym<42% z#au;FG5Xo9i>TNs=|QBWPh4R&kngIAL=XXOfsJfD zy4RAYcPPb=R9OJk_>oSYWtt`;a#XaqZ(JSLk;UcOoU}Muj52#5?_|Hl$w5>o=6MZ{U_f^`U+`BH7}{~#M1R!?7*3hd1pA{o$h#dnxoyR zj&-Lv(w*!$w+57B>Z?I74#PE5cCPe#I4is!&T_AZGgL$Vl3~X}%m%$4&Vbj$$-N%V z60e8T@AYsNQV)j*GV0oJ=%b1a2i2^xZ)<;~wKIzlgs&g2CxPc#By*7BYT<>1=11j6 z`WX;CgHuZ2lMeGULu=umwCT;y@h{O+D{V1wMytfmXvu*4oYLaB@`&E;NwT03Z5MRr zD;-`d9A3*EUPBHqS+bb;pu=mx;gvhQmN>ln9bO9^UYWzI&*9YtyreHsAMNjqZ->mHU0(oowAI_wDv|0G)p-}jT+>CBTQ{jN0=y|;xC-HER#*H#H%1zp%lQN`_ z0fi*nNw6N;bH17OX({Sq)AJ)vNKWQS@M?{t*J=)j%fjXSaWCO?AzJ-)b>;qsud6H1 z4@6UL>$agSXEyuQmfP0;6=YgoZ<3DOxLIBVu|jr=Yzx(<^(FSNHqRRQE4wD~b*U{j zF;WJZ{pid8A<(qIi$Jsf09huI;T$%@Ri9>mX|y3Sp`Ah`(eJ9x67$6cZ`UpG=|Af@ zMw)+2v1R&`;Fe;3K+vDSsvDnW#7k63+>%N}*nTFs=!*P+;@}4qm-!^5dMeEe&W1$2 zKaetIx_{s)2~YZ>?lkVMknyB@nlzMgBMoIs%9CYLNO%JIuf>*=@;LH;?0fo-yYBn! zmVYKgiGA+B(m787snnG5bg3z0Qd5EwbZGf1J%tI3EGK^c$t%90Bqk_vc~)Ub8f0Sc z4ZkCa$(>3|qD+)=BfZHl_FeIbpKN^cw%^$BRm()V@9FQ~we9Cm-Z|0CL>VhI$3}eS ziN{Di$!cVvXkl?vh{-{@chJuxl<4cwpGFKtb6sCO*Z{YeiWrF!%MW5wzKoE+LMCRR}Ra0cMd~rmK+pv&S8+vlEVO-C5N2Nk^^QLd4t3d)9hCZYy*#F zAHrS)AFGXJJCp?5Q<7=3lIV`fM9?!6>twv0RwLLq z-5m-MbV`@l#?U*aRFY<@8f_%P$JYLYRAdE}jJ#y^@H#}B(3ISanc9jR#o7I0@2PjB0&;@PY5H@zGy1g7KR($Z)(5-Z zIVU8y&@66GHJg_sJrWY`!(oI@tZI>?)%GOdmBV*;F)2EiCimL}+2HH(1EzYOl;W#3Dcuyg_7|JqT|QkW~v?j!-OYEWG8CtsofM z_xTrLU`gJBaXxVzH_-y+Df5MtNjbzZD^TU2Z-G6kS8%0bEt`R!0ZhVi#RK_1BYNq$ zQ3^p=sq?Z=9m{V~^GQjS#I17C6(H@#6Di@{er3aIsUiAcqiLn7ycw92vGCEo*i7A{ z8A2sUYOT6M3B#K=0B5Lk#YD`UBRbAe`9`4t%n15)rzs@O zO4*;8J*RV5))=wT3tAew&vfxNTwGW;7Y$l6?M_5x@?=in<$>Am@8+ej8h-PVx~Z@h z8gnN5#^+ROMUPhXs4^~SUPT$GA?k95Qv#6oOtsiz&6}Plw8bt_N^+m(q?GTC3H-f< zj+kt#+G|>|_XNJfcL|5dWC@<_(It3r%O!YZ`lbZW@V@^uMX{BV%0bC88Ez@Tr;^~S z!azyzCKmg>29bb8Zq!tsdtRkIX)dUV_xz+Jz3kw&p$M}9$YgxBJ=5l-uch?{v*0Ow zU3y23%Icx$w!K7S+CUNn3er3Jkap>v^^5c#_Kjq8Dz<8K=+*^Y^eV z8`g}=UbKiVEL_1Ko0J|=OVB6={n0SdU`mxn9Gv(9@;qV{YmM0^AhKziRs$G|93JF_ z*Knr!eN^lifv{=SZVB}}U~gk*Z=I23Qp{0bPxzivk_gga6&Ot_sur6*%xbTJ;!wDb z>_cMdg!timQ^ur?{E#&muOY9{$JfEwUrm83k9!KacKuG(>7cXKp&!@$C~dAWfbs#5 zGcbKHRkuhpRkAIHB1Jk)=C}W!z4s5Yt19z;_m6Y>cfv**j3msQ?&@3Bxf5P8bs54a z^-k{;qsTb7xVQ9{fA|M~c&n&DS>RB1l)>r1AifDNve-kcpM2SDM@7>u(j{MeN2SNP@FMh?&+v6(k; zJ2f4)(ihlTaIEDUR>_4!PBWT4EjI%fW+&4=iJ4_u`xtG@%cjfJwu3v?jxjei&uRuI zuB>Lw{59T-)6@k%a0W=w`ENgams@Af7>S1I+i(vIg` zQEZ^?jMz~DX)i#F%A!(9{ivLe#$y|O5HSF)7#g?Kk2X}br9rb42^z7+Kof^%Od!%2 zdzXzD@p+?`g%plZZHuy{3o~|^A!03u7j%{)-35LE4dFlfs(bxKz4&>XgIX)@E_W2e z*iYVb8vt9mOnP3rOac{+HzYl0{sapfmlkpBX2WSOAbi7eZdo-PYo6j?I^571a76Ra zVahK$UneMR~W%&2`^a( z9WRyGdQ0NDN2be@p5@l}G_HJS(ha%wseBqMPo`{hf}SHchMqGedz=?n0k*rD*5c2* zCsFO?%%1F65R@IU4Opwr+UD;LB#YhbGf@j|H)?%QBIphw@*)jNcx{J&CsIGB*U8P9 zp;O+j@^Z?*_L1w}lPl@a)pu2cXJ)$`WV*+5aZ*L0|Mci4(B*m zb71UnR&_&gT%L|XRG5A84}ea7Y7WS) zdmDX+c@vBEZ0u+FNgdEohN)ykZ;6HreLB(8Yw6h>syfh-j!;2*i$SG(I!C@rT-^l< z6-OXtjIWWrdvSK&;e)Y?r#IroN&=6FF_0u9@U=9lkcpTk6lEbDp896^)elNZcq9`i zb$EP>C7n_!Zy+*q_Ld77=Fa=?lp+GaGdLgx!ACh|rzGByl z^cyMw;S-=JQb3fl(GG3|PS8riHU&aw37jt9FuvyI9>}_2McZKI2yn|nyM52Q48_aX zy5n)m?0L|>R*o)c2E_nbRGpX?19k#z#2Yj^LOWn&Yllw>F^6^xFNub<*V68-R^-TP zmX8AQL~VdNsxrps36l&93HFSe2+TkX`Ib|39Zg-FJ!3MnBu{3GDHXe_#gy;;0SO5o zVOBMR@_!EKkR=4?Xq#ooWHTNP+X+fmwKg1y=s&l5A2E4d#N_6S&hcL#=Ju}pZ@Row zEu5RfCi_oiHWLDc0kmPSC6zB)y!0R4DbFaJvD4yU@~1AsL@{ykJX<(lCoV#Lz+$dB>)98c--(Dp5sZ}EsYkMc|l5x zg>ej>!G~N~n&yu_zIh1=(R}!fjYCm29;(7@3#lqEFI^R0g(YL)nh%Q|BGVPP1Y*Sh z1{5<-@Ufj$U2Am9+27VfoIQJ(wu7WaO4>POjsBhDK{#;2$l5aD8%j%)A?XjSv_v`u zD{%%FM=t28#fEib{*_@$m$=cxS{>}Mg=3%)2{ZkI{c1vl2K)fkyOX5H^#wYv8-1u? zt6fINw9C4LWIFP-#CCRbon(dfaAl~yY=T~N$3HU&S%P>IN7E<3hjX0W1l=v;0re+#A8>S&-~*?=tw z$EiNQLH&(6S{JDeYzsu;N^6jGUrF?emX{(10;DjpD;a| zX|_@+)Yus~YWYSimzF6eI>KSyUrTU!avf=n6$RFC?FFl`Piv_4AG-uku!S8_oTRln zC{FCaNR9cf%G5a)+?~F*Mkd%k-q4KiGVNYqdSOSWjyC&gK(#nLW8gPtyE} z<`XcjJ-J9vlKi||>^q0sKJzE%=}DYl?N4xEsca|)#D;3&j%<`V1hf0rm5mFz_OH5i zjVw)MeZO#02$Us#4QGl-r4b2j31gdrre?gSVtGx?2km#XGdpFQMvuXE)4HWN*ue%% z0jY3xhk~Q%i!oG|KHYhmMiv@Ev$l) z>9B0nB_}Ojcz8$Uzqljm=tw(kvuXUAd%cHuyWwp=z?g%O7$V+bc5P_i%ddSfauTdl zu;I7z`q{>sYkN8@|8W6ZgT{DS!nG2Z8;t*P0S(M@KYPl)W37~x+i#-X@m}_YB!R8H zq<8Xg_JbwMFS1GKM$Nl;Nbeg2V1JwqU~M-K0<2hhVI|L4VZOX8H(wTj9YkAgYRgHE zEs)xB^h-f)c}38$xN6SPun33n3k0C`lfYo1O`TRD5bcb~1C z&0Fttf;SOX4zkKo#+LU8)PLoS*oXb1#lh`b19t;k2ShyoI*wAgf3Qb- znWMy&9EF2%_9!Z1TaG-$7fURURqPx5D~TUR$*c4zn6><>hmp|+v-6HnGed)aEngDz zPU$gSERJ@VgTyM?>%)T$6dd}#Ec(|k)>^mXz9qelM$q0iWI&?MUxnX)6@Gh*49N^k ze=XA_ZzGWowmvz^3hto{K>Dl(pNlNrQ<@1G8Ra9xAo-OfZi`BN$e7@!m?{Fw7or&uL&lp zgwgBE?y=KXd8(y+t z9J_~^M}E{bCazJxc`!vmB+CHko91O+|8Y0efMy#~_i&q?$B4DZQAS7$ae`|g!1GeQ z7$7a-h4NmY`%!io*_f3IL)_`Ei~T4c_*7ppSh>=CoknrD&VD3x2=soPNtct-IW|&^ zaJBpdb1J~Oc!q-M#VxBV>5-jo`ofmhou+|#`Ipv4)BMi0wD#<3F0C1z-{123cR{+Ds!|GihQ5;vmbC`CSk?ZPj3R z@IWEu1sN?&52#Ym-=c1E@zy;Im99PJy$?vVZFJ$pCV>{kr?!pOou$#BB&R-VNa5S) z@zUA2TCWAn_Eu+*@^3!%54KG&6wP`|4`~ zJlyDN9y&*hW_q!cIST&)l>S&{)Is)(t%5F{S=UWpcoag>d1UroW9cxSoNvY{B>u$p z5n}0!W9o2-MQ>cVLIJMRLFeWlfL)+S?}>d^91=QX+(@-6Ov=!rm1`vm>xqrn2cE%B z;;w&E#CH(O2gUJ(v0Cf~*3OE~zGHF2yZ{-w*jZeqWXK7DYDOFBil~qUS}PAH+H5nP zzlc;fQo=Jj?NUpMDP*AC)J3+@Ae2Nt^Y%ntM=+w>{KQ@uI8EmS(!em~U_SH7eF2af z$69d^Qm*lydrfWo@hDn*8ZKm^v`V7ev!qEv4{xTPn1bn15H3hk2OHHqqJ-k{;ouUABUqEb8LDs+ z#-va@1^ZDbz8|wvD3WezEEF5zWD{OP1~|tXz%qrqh~Z>E*@UOCcBew?rsWZmZICe$ zA4`xPEV=)j4DJ-A??YZXR@@w*h`zvt8fS=*)v}E}#_hO7VVXY$f=}FZvW11@<2Mn; z9c91lJrZ;&|IG25P6lCyNN^qjc=Qi`+2H~fF zMT+nPx@Dwkb`A2A8J~>};v0n~iVuh>RYf~glUhT;8_KJ?8x%Z2v!cW#j?>KPpmo_A zqmK<^8Ds;7CaKL}1HSztI0uD_-J#C|p&U zN?cXB%w}XwX-7} zV5~CVVQ3gpOsz_XPzk7uwwUM;1^7{FQ9$>?s}x{Vx3AYJzrVZ3b$A=M1RdUGT58bB zLI4u%B3ozi(P%^$$vH)ftYH^ceMZ^_PofO4V5xjf=A*Grd_#LmW@Jl@jHcrwAs3XN z_{R2nd$fRE#tDu(xQ%3cw1ZFuAU*<@S1aCyFXLV~_08T|sJHy(dTyt__2sF*Y|j;N z%X3w$hgQ5c+5Y|Hw?3RA%x#VppijqScy7dCFH|&9wzjUH&cQdL-cKi3%(XU7oU!ca zSh4Ud+K22Ks`lPFs#S91d~l9xJ3*hJwX^4__GGi#ns|(+AMvvpD1tfp3o;#7p{7rZq7vZ_!jB zRvrGyT*;4*xl){o=nGj#6)Ix=^b~ZoW!ktCxyy0})4-Nu6PR zNueh*!nb?zcuCAT#R9UIh4Af}QQG+C@optbTOVPka`QHYZZF7+SZ|9(QDAp7fZI|$ zlmXm_&KAIJ2|`oXF<@{xq#72aalFzY@9h8s9kj>06Pt`54*-*Uj{$6`8t-m*(78Ia zs)6qKd^)sdfUq^zy^Ayj5YiGIt)47=)2o)!RxvJ0cS zirEAVb0l}0!map!YIIfYfqmP)V?0vX>jo;F|6YXqgwRIUCnmrbO!f6LG|yRd2c4Q@ z7)cA*@b`AGb>u~ulz1C7ovN-ds16%CVNiCKW-BoC%)FlJ*&Th28jDc;9E3sKnX+g% zcV@Qs2wDL4S32yqgjito$89IZSLzK~F_Q#C;aQY@o5gI*yuT?!By-_rBXq^XgPkh~ z?~$=1ZLGk!LXVb4T`M9q$qgPMlIcdaBI;J_E#DXOPZ#90rX||@RE&O+KGgCZ1Ox~K zDzV2y2^C_4Lwj+RHf5gK4WdDvEh9Hz)x~kOQFm`=onTWxz0tWC{LX8qOOuxVi@82) zP2&974G@I7!V7>xFGPzQR&BA^rAYDoh0#UGC^Ztqe0-}%>g7JSIGT3*`K7s9RhpA~ zbGtMrj8aN-e88kR^AIy>juP8M(wwjbqevvpQIAy0S_h>Q023A5094VWIcg2L922U} zkmgiz4rvbLDrt_*EGW#B=Jp4s$%9}*A}NL5{ekJ52f;KSFn#+VnC1hfXF-Vvanti| zx}RbrIS8f_Or#*}3h_NbNR9?#sPN09VH!iv*{WgUPBJ16YYmD{>5o(%ge&>(p#hE<&Xcn`vul*<&SqZnwcA;QNpLi3?< z`;bX2T?1?d|4;-Viq9ZN_-7L0Cn(SOkls-*m}D+}H1A1MUDSt^38YG6({^TuJ(=}1 zkE?^9hTO&iaBS-jBKe}(wqsahS2-z5L*R9h{H29w{t@kQud(m)up`@c1iiyG0ri}6 z*)t3i?zQ}e0b9OVR>9w*YLG5Y_p+xG+oDouG{skB5V`rJ%Xys=CM1*vMQ+%gbnV~1*gO_~Z0A7^u5!OmGj zQZe0|=>l-7&{}KLhb$`fA%!-?Q)4nCt_|Te(}pnH{pjnsNZIMS5eI>`5mK2u=YcU4 zCI=>Fo7kMtlCDU<3Pt+SThzo7hzgfQ1D(D$P1`ohJJ~~a7>&~SQr*&_f%}D&ObB6K z!J^^d7d5{h)ydpjX;<7kb_Ql|MhdPCw3(Q=Y7K;@NKF>D1Rcl?1Yx!84rCp5qH9W+J zgg3xQ>I2_^@X5(ieazRXhnJNBp@S?5iN3SA)ce<3zvZ>PXHsQJ>j)|u!!Vg2nXi|9 z@T_Iw7eRc1UvCTCToLrQgY}-IGzC!U9;b4Wlk}Z8~;) z(#}BLcg1c|+O2etGAXP7+d&c7lJ$M4s--lBY|E3+Y-wotWZaMylwRz?tHbKui^*1& zJQx+FfRyb=lq(+>23JEQ?6rJ32-cn>GLkt!c{*TTmo-c}80G>Kp(*C3bY;j6QsGKb zm))cunAXODK z6=wL;qyU=dh6o*cY@W$k@>~csSeu1~}Z;3m8buVx|f0 z0VPLX;_@9OiNeX*dG9LDiX2Q%7YOC3>u5PKjMpD9o;FpKj&ReOVV;C*jWKBp&MuS^ zOuNY!9Er%p@qZFA!=KoJ>@^ZG+X-M;ILFUCYXG z_J(~Qn1Aen)@-lk)JjIcm+JYUbr=>;&cQE3=Gm7l0lY~UVxY3m9tOYjeY|77gCkZL zF@xm`#$SuwF&W1ny>6n_jRCbt2uhN%gz{|AF5SV!ZP2KcaFRgvLK>%5l>nCi z$-h9kU*FbuG-vXEo6%nlFF%j(&}GWjj#YOUt)BTrX?5y`Od1_JC9^mNCt(-ppECqW z6Wy~!@gXZ7Y1RL$@*65@Bpr^T{L%mX+WDl>#w55(Klgm=lb^Fp+6t9I0+$ziN>YqC z?+iJZmy%igiRlYIbJb%%z4HlW)>cjIq+SzvvQw|d-mTm6DpLbW1Aya|;ARw4JHif| zg=07-y5ivz-w}z}M8nbe!zUgWv4?#C@3O3&XqcKGToIWJZk5-nGO~?cyx3l3!-}po zKVt+Pi*^uO42f%Fv+m-Y)3fR5#ep#4Y8E3>X-1HnB1uV+!L1Odx|m+g5j0lR1?rWk z60T;h1>j~s@OA5Y%@k>%U@1{zspdqvsiN45Lc{{D;>az#{+0b^T_y;_Yt15v!53Vt zJfmvFIwhp0-uN4yj*>ou)&i%mMkV^qXtX3{)?Oh`MMU_yKe0|PH`A&1ENYKstaD2E zM+|w1^t{UE$31*y6q7)S4PvT6+vPgCUBE-p!Fpf~7zga4XCq#@8qOFuUWP8^8dyOv zqC^{(d)wM2(Y5aJtsyV*{bgRFPsgf+tCEuXrung}vL_GGk`spIb0E$_(bcGh&#|Xj zW#(*!dPAiX^f@b?r~y$Tt(hfd)4CBq2!|n-!91o|GhK|w9Jui08ZILI4zw5~?GB$W z;|2`Y<{bv{l}8$Scm@|w=i!Z*+mr)qm$x>d>DFA+CvLDL!u z_p-H$gkv#z&Z?~-BhnH{n1HmS?y&dhESe=>Mr5%q(sN6TJWoVTi(>zYX*k|XCrI0C z_l}je*GkLen_;CPamrR&B2L*#cy55Wl|ESL9yBgYg**`fr`pXfn;HJbACf|DHOqHGE=`C8t6u&Mztb zm8z-{er09is;{m2j!>i}t}@wCpD|$I;nMmU>a~3)Rjd9D5u(|@@u%~f-;gwA?oHP< z`9&jEbOAX1Y8&~F-jb);&Lf4+mpEIjBBA=mC7L4_R8uN&+>A_0G$u}zWo0!bm{buQiiU}ye}K9gjVI(y<0{Es9dn>c$yc7=UdmJHs4Gtyg~`JeSd zPxA#WqwJD!u!mjX0ln%4KcH%7QB~UvxY7x^mMJk8dAI~E@T`V`7sJ&Go}C)PO9szpo2y3%7V$)TTiAv_bND=J zMbwg!;-5CnB2<QXa48w?ljP5G^qqx$?e)O(?VV^l~&F?+@{;=3cIjia{o0i&_ zJZ!Z+|09CJW&HjyjEr%$u>D&fX5dM-BV)2zo~BJ_(dY~t=H4tU+DWFzvQq^F1XKF-=?ORmut|p{ zUR3^hrb=q+umTNoU&lCG>pCROtjG;51e--YXg6_x`+{&>ANpBwuWr8prOsfSYe7ZI znw&!m8cykUC8-4s1^DO_%2fzfE>)lEO^7)V3fvx!5+E%YNmDG?F8DZuO||EMNstp5 zi4bU0^a2=+EciK#%N3f)ChKg=Xg>DpR zSJ~GB1Mta^6m*-bfwS8VZIv{?x9#7%|C#nt*t00Rdivpt47$82!VA= z=BR~1ri_FOG!j$-k_6?&km-_4f*o)qmmYF9fAT7sELF->1)(;Lg-#~JV<(g0vC+X+ zGU+%i5K48)>XdjhSIiq~HnP{KH6; zk=`mA8OyiYugX}+>)%oVY+o5HpCVpyzMtZZfy$?#AFVB6riD9dhQ&Huno}h@(dn5* zdwZXYTTEa!lW=3;{vfMSjBs7>)P)YMSxsO~xkcPZ>q#2)0AkTR-ZJN;aUEW%lkLT( z@q1VJEs~C7USa&|avMzR_nkOsdW|?RK}@90w=*7k^1O#x7RIlMga}p#(R2*g;;K?h zE#h|{m~mGy*v`HEZX*teYwnPS9i-?jY16ft-)$ILmtKdFw0B|Kj4pW9duH5K$EN1$ z*pzon^%{90rK*CFMeuOBg4dc=Zwz%c22j;NZ)3{2=Yifb zz=+?L1i-t}xyYN?69c9aL*x9(#}L_mc$mrd@=%cW!DKU*iOC{BqBg_ZRE7b<%>EOh zRLPVvXMt4kfEYwKum~h6Yn5qA_@Eg1^N$eK=m(2&k&eS9NNGp%o%dpx`Wx!w0I@;k ziSJ;m`^I5J;M*7YmcGE;+ZRyS=?l_?=nHE7ersJZSF|o&$Xu;&Dq3eQgc<-UDh{3a z>dG{<0s4)My?ZiPLYpPNDbO^M-hFXW$y3yKEjyPjoKK*#$j_- zDv2G}pR5_+h2dnI${8!jBm>g$OJRiNPowP0AGZ|lgtB!pU}>$6=NZ3LT+Youc#8Kf zAmJLWuKbDOR#0>0>#m-pJM^1F=#{E_wq|LoXm*(AZEgJgs@66x)Zs7QuOALMmJ-QlzsTsKGz5;^j1oNtI^D?~gu&wvNjgrz3i?_|HOe`Vi?uB#L@!tt;F0T|9}O4rq#ht$rs57|d@n!K zHEWaJfFU)Bfk+&@jU>X`ETyxLj;5b}H;N1iq%4)wZJVf$cr6`!W>J7_k)Yq1d6q}@ zY$Rkms7z{P1Uy8AJCQItS$suJrr|M4-Oi295gI#i4LHs zi(b+n5|cucp%w|$V;cSSSLh*4bbhQ9B1or8P-M- zVze9x_&)2`68z1$CWBGG&hull-RBH+yPxiYb7|%2;rv^O1KC%(>9D-_1N7?Qp8tnD*D0fPh z&48J(6P28N+z<#UCT|F7GNL%xyNI0;pOUXvVxkKU2asqmll4UU0NnS8sPIv#9k|7I z5tRfK9IvNpn{GN88tb?9d*e+fLkj!w;uPLj#fY}0kc41pni&BvvreSbur!0;c=(b( z|M_?S`SE|fK)<_I{{DNnKKj7*tIxme+zZxNvO&$I*l(YoQr`h*stwOmtX4D|+Hbil z6amtg4hQrN&u!E+r^7Zv)0i+U=#1Meb+UvrVy`O@eQNKf&)@dv?|=C#=LQ&Eu=mj& zcmHAR!W&-`7`-l+(S5tO-M{ zfgSfuP5k1a*JK&JF0s*rcmLa$@4xf%3-2$M(XAUE{LhCsPJi+5UJGpWx&+Z>n}4?M zH@DsLamc*$Mt9yj^_fjy`0Cfv*8)VZOJsE2UoPG7s~_Dwy{}kB-~RqXUw!b||Fz|} z2X|V5jJDqTwLd+1$7K({FRY@6*8cLTr=MJV?-vf@>jFe~{N=$*Kk>`oUNsy*^!fX@ z-?#7KM}M;S;3_IWbn9<#{>C-8T{ZR7VyEr7;LbZA`S?$6`QKj)WHj-5l+$ki?fq-N z`d^nk@vg9nK7Rf!mv6iG_upRlT0rP^Nzrb);GXODUOs*Q#{z^NUjMBP5C7;d7j8I+ zii&;q*xFBg;pxk++wp^9pMCw)f4uPzcir>Q|M6O^A`@CyVTZk^x6lKcAvkt5n@4v@ zYhD;)r+TGaGksUZrKmlcji96u&1PS;k7xI3A|?T4n(sutYPv-far8UiRu?c(@6qqc zc+e9XY7#s(40=vHj);lq6%4Lznsi5IGp9CMZ)&j&&7pQ4s+e<^wZFQ2j#mkIEqx`9 zZ+%s(mGSWHhzFzmcTRDXYoXbmk7>ASFepR1l~l%@DAYV*jKQL8iFA~*xf0T5YS4j> z&>K^Oc6t^}>0M)V%XO`rj{Mi(#?kX_G>Z>2`tT)sM}vK*dw5B=(rV=}JGaxV={bXXIFrb$D~=1MER%N*}wx>uC0cIXjfG!y1E38B&! zMUIL!#z+VFWGCc;5kaBNa-@y3JC7JNb6wEu2Jbed$7B@rw=^HfqvjBe0Hr%&X^mJ$ zKadcR$gVqz`!g1@zC?ghEm8Dtau=sOWL(z$U6$H-GDB5JbQygL0lI z`e@}vTYmQQAKdZ1t9}SEQds@U_1m}X{M@D+zWD!Mu;vt^C~285qemwNCkPwEJU=aq zy7rt6L4j|ssmG7k>whJCuq@aN>EVMhC1k1@H@rCWHi7>HZ*9ku#i7spj2u;y5f$0dD@DJfN;XfG5^pf z@IbW%(EOTu;1(uaj{vA#Z^@-%p>yU!o~|SrIix&6(u zPw15iW85ARHM1Z1@z_gs3Sz;)5LwlDabf=n9qi2o!F7>pKmg7E^Ad%*lq_7cNJ_-Y4yD3~Qaj%;<4Ybbh zds(1$kZwWooY|8bM=#=K;Td|$Y!vmi5hKL#xA~|xy5L14h!F5PagN zsq6eG#bOn56%4YAJx-oIeiV1{yVyC&-HemW_%jl@cVSl1gdsckTmeD$(mV2((fBmq;Uj;2U?^;o-*V znS`N+M6Qe>(?@-|dG-jy%EG{m!E&e=8vx&>=H01FItmLu`f^f6r^Q2&&#x%anj25f z6$dU}d+bINU&NpuFGD3p`J8&0LOb@}pfZF;ec3}-Q@Vrsu`JKX7p&KB9=qRTS(Y}~nB5eaH?3A`Tyif&iBpuQ z19V%llHU~fT|tMc2llej@?-{Ijx|QQZ3J7@kEq($os!8+%-G29?1|r*VPl z`(VT4B`u-A{<6QZ{wztLAEme_5_gP$Z7kq4&w__L#GP1YnJASCYFCSRwG!Dx>`W8# zYze{Wd=i%63qA{8xT5-$!%0bUUz4~M-Qrb}E9Pb9xG zTasVF%%x<@WR-`#C+=)7(Gq%B9`??pY0>H9I(4IZ=z9X9Dh_>rOl?s@59ms-=+*oawrNhH#(gT>0Fye}4M+ zk9^~~kA3v~%E8p<4|bliAhMTe1#;DC=TY;1BRT7IQmBb1Wx9Q~k+=N%4p zjZr|*{zn^~YKQ?KvUWGRSH>5%e1s=b^mv@FT88>lHCJ9hg8&-}VKWdT9aqP=l);&c zFolh>lm49maP0Gd0^Dzo#|or@L1ABm2%My_UzEm!8sAY61*KRivXhMTnGlmj0JDXd z7|<17M->uiQYC}h89gC%K%0(m0(*L2phi7SYQy37AE0ZHnfC*DF7M?+&P`?X;}^PC zF-ppwgNWHqf=nxXUeJ8H#H}$(^Qob_=F=uv`SK)%CnNS`kN^(;>r{}B=FXIi{>*&P zwT?4FPk;84BZz_`4Sh%cEdJf_a&dlyzr#|gRbO!4$Y1b`B{okeJUp36 zoFDElvPN58v`jKf>_s&%rjQsPG~^a12aFH^96sVq;pGj?Er)`^>HDEzoDL?mk3yg2 zQAEd!7>ad(d;!SvRI-=rEHwbvVCwn6rf+VENW3y;ieA!l(g)TLfd@_Tr1^QKggs-) zniwyPsb}V5sSeqW5`E=dNbM#{{kEa(4Q@!6Beq(w(rH+JMl?)JtpHU3Sj0kESc{{2 zqNyV@gm_taX8R(0Oxq65LWGlBO7Zk}0_9E=RB1a*^KKhcfGhh*so82Q^nCm8u^TO< ze8Q^iGYgXuP>J)Aeg++;9pju(9;yU4Q^!=oE!`jL*xN~WW-68X4v zHiV8+)42wd;!>c>ztp!M1Sm$Z@~J(9)O~9)`)!<3{&?}=yf+=<`2sZD5YGfu-4M@j zVr=|u$dnl(ZB%3-P+EK;Uj!w%RyfcanX*lSUW-K^;2#rTmV$8l&KT&-&mHJWMp95# zqm#YZL1qtDRRZaNkO&haHg)D_TlNkx00c;6iN+MaBJ*FPhgHXZ>E;66rr?Le^{9Ay zqi6A8cOIQgx{v52V$kBV_$gBz47CuRx!7TCq&zHsL_UosOjJeWAS z0#Wsyksr27iGx#xrIof;Hu>o+S~rpHjU6F2jjPc>R8SCBxZ~r@bA8c=2C99QC7WuJ&CBE?LnJSh%2>*(m_Clr$iB9bkXdo_+)6bK+N`A@FSXA$;6&%Q$CanU=_6YPr#*xX{3_ zTnzB4iYcuXd(+<~7*kx4z1wGT#sVkbWqWG=>?ETYJRp&55!2w=0YMy6&zGuN7jDw?*0JBmA4D5tWsChCcxa zD}|1uO`W0W^`9%9D-%&G9W(rQqg6}bH&F%8REVHBF$QEdg$OC~N|Q6&uw3EZSk^KU z>x0OinVaYk43sZ@uYGL$r-#~_T;A5?P_;?)XWnEl>9}>;ftj86+kHYp%kB$yu@2=C zsETIvW4_~ujSZ+L1MCAaTPe;@@`NUajZiE8{T^aVDbV$}8n%(7a_Zww}b`ZZ>C72$OsmsG4ODwvxt04!qWtu8(fe3Ga%_jYzg@yc zw(9f&b|F_|Ve;)iMfv_y{xs?<&wbxuv^amne}u+5&p&0bws;`T5nec3J%=H;lhqN< zEk&-F3Rz1Y@KmN^bUee2^hH{f@b9}O^~K>;*^lck+o1mXA)l>f6G!Tlc2`azlk5x9 zn3GoRGpUGE`;Qgny>c!~o z7$>%N2b16spidgokoL{p0jS|f1Klz23uy>Dn1h>;1Bz3nPo-~0oTbTBGAIB1EE!a3 z&(O(Lfw8FI(CmP6*K`*|mgx&|(rf@a@aqyTEG1SuOVe1<@}z(R5H2DbVhY{D@uFNa zpC2yl7E5ZxdND>+So+LT&2h#clq{c6xJ?at3RK22;{;g(K$KsNA0&{eQ-KspMQBT; zWQbN#nPYUEm;KmErWt;s`PWOyNHU^NVJkOfjD-*=IggI9wTIHXE51O!CiE0-*V`MK=>Q|+R2s6JugY%G zp>ha{pTaLlUD&@@7^x?zEd~89Y*`X>@tLcfsFugFkje8?bHSzVE>PC$U`O?sB+Z;> zVv|dC{)C@aMA=;a7t#kQYeIvnN`qGOIX_#eSyL`Me3uEsdO{Yw^2j6-;RWYzD`D^h zMf2PbPoku4qKGK1FyZ1J&PZ}SR5&~d@jo1%gw9ra5YaTRIRMiIQ}^}=4+s?PIMRoX4HUE1=E2@YZTy^&}QbAS=4*K?+NNXWc~q#!$j;MXx=J1t)m{=m3y_7 zwJ}_JbqG?ceorqc(`JiuZ;obLReSSpwqQLO_gFArKt^FP=r$f)NSGqig0PedyY5Gn zcqB1E07xmc3dWGZ8f_)@6;R?Kr|5_aRT}%jG=FaOzRt7qu5$qMqI3M$hq?Xa)+-f%t9(AsfZH`K>$8FAIn@&u$BPoR8lNrqo#J9;-`+ z#=-AxKWd!JRGn`mNZda5QXp}KoGYqWLBi_mkJ0j#Xz>Z+A24r-Hn1zUdQMg>C2}R3 zUnI<_EEm=s9vNCZ?>9uy%4A)AfJ0@Mhl;!)sO*g$EKlkRT=vAX0OmknE<0buayiH0 za<+rz%vqpvpf8sVFJifD4$I~Cuv|9Hwpxo^@T(su2`=))V}DsxINz0H3m7j!#gTV`FT&9H<%cMzP-+q~)>_)@&hUpp{7 zS&lg3;7C*d64g?|rV57d1~*5&(w3843AK!?fccD^5MesRr&D{`ne0C-gE-7IqVBjxC>BgENkonR65ps0mH5){3jG zXBT&vRFFy`S(D2Jj4mj}gRZL<-(GxMw`F6dOXlE*T7)q) z;#K+E<-LH-KYKip04LFp@z#2Or*y>b_ZkZTdI2pRZ_Caqmo6NGB$uERl;2|=zej!{ ztI|)oI_B@=?5!yFQ?L?pRNH%qBKD4|H>j!h%)gOF`Udf4wO3DBWx*#(QSCxdgZeRo zAHwF03i3^|URf)3^O8hNmgKiU{gmaF(S2SydNImr67;7}u8X)>#xA0!W$cpcaOhZ- z6*Z3rb5NzEv*NiRA_PUGDNx;c0&jN@(MJAMh<2@XWXEI9L$vLQLbQpD^$=|?iUFw} zh*}BJ=IPR;5~23P$cOBX*nO+C$`&|y&HXNv=6?j^? z{~{lu+qH=|e|h}QHY|w_Fo=-8pP>XZkwb(bznLK-$@Z0o$m2~cQ5V`U#F)oWNM$C` zMnfZ{+gRnZA8=APlJbBY%qa8^;u{Fg;FoQ!nmiSI^kfO|cd&0=U#bm^x4XOf8-gj* zrhp}BTB@*wNG|!;-*6-~g_(qT<<8iHSEC;$#$IoxLFpn>3VYBJuFzfj&=qWXJi$W= z4@qH5w~!Vmk4u|{E-UV~2%F0BYBo@(4=o{%7=#Rib)roPXQ?r;9h{>kWg#fT&Qas= z3eHjM=1KcGYW0C0&|bnYW}KsTJ7|oZt#j0N6z8aMzRo~wRprmwZReT#{Ete$mRgEP%U2lPtWR#_>h%o8f7I#A|N>Rfgp zZ=O9BkeoSBkc@_fGKau*K<}Qa+G4|ech9`^76&v~LTWve%^B_dkjhk8EB6GXGC3Pk zIiSH3(&rdhM&}C_kh0<0wE-++vw`K$K~624$4$1;A5xl$>ypvL&N9W+h*0|WXc24% zHahWOa7ZRq!Y>)Sh4`ftfOuD@e{@JViINd2O2`f}gj^ggQa3nKD0a~#Nj{ccc$fsE zCGa3z7MXk`nN{rttHHmiOa8a*E_M02;qL5%+XP|#AKvvv{qwUZA^5-t7_4)vMp>v8jaz>jun2= zn!IB%STpHMqplSZs{@-`^j5!-t%$nSftC-_>JZ_*x$ZStfj{M3US&d1 z0uI&nSZQs-mXJEVq7KQDs*Ry?VRS6~(=$G&Mykh6+6vK>`3D>BXh7e^dG$UKyiYth z7ojFCR{>q=T9}}PLD4}`T~nAm-_@Kd846iFeoed%!!s8umB?a+f!gC2v1=s)n|z|V zXA|F*|Ll7|yZ&F#$Pf7+hz9?zj4K9ZHxJWslnsc0MFJIVa=@fj7?P#xA%ciQxIi9~ zh#1lH99o$a>KgQO=5n)*_(?OZ&qzxPZ;F9dN>h)tmO5t>NyG$){^OG4RkGw<%NgJw zc2A;V1J_taTht*ZaC1^VH=ev!#e^tH&s}SvImxWN0@8?Olwk7lQjys^`wd!2=~U!F zC4p1;%MXdN8dcz+(Si7o#9ILr9M6WTwvj9Z1vgI78p z<&_6EDdCaU&N3-43y;_3%&B=X;ChsF9AFk?7qbY+G=F|GC%)H0i^*sWFO}Gy-sVPRBQS21ykxcoQ_qpaQZ}6QA#s zf9}?x<8m0;bM9FlNuakh*>r`{jtY`XlMN~_r+htwhED0;I^9D(rSgQzGCF*g=gYWG za2@7)16Ocpek0dL!!`(rR2|m_8LhbvYy2sktSr2|Mi)%GeRY7%=HQSy~8J` zRo2WI4#&l4F2L;S7GSn_+vrqi0SxRES!}vVGM)%9JGxm5DE~^p;0CtCU$wz*s{m%I z0L`yJU@Y*l_H?oYp^1wfHbjuN!KSwYo2x6ZQCYBgkTDjp z(Y*pTDhoD0=DA?=5LdxwJ6FNxVXp14*|TUC*z~rb;XNU%v4LZkmP&z!Rh};z9!mt6 z;DM$>3t((RQ6>9fk2cgkpxpu((D1$reVY7q6EK@q7GU-=zyO#Hx)%VmNo4`%8J-I; zf8r{@{F$o&vyba6fKf(cv>a7rv#*stO;-W4;h832CRCm;V8#tF+kA8!5-|&4sFHop zFwGiB`Aop9ahh+KW={n$y9&TO%K!slwpRc%T>$1UJQrY|<0`<6qV5r3R !%=9dP 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͍Zn;{|8$>#b2>8oRx`1D>=9e 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%0AUF_4l|) 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

    rkAE-tx; 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�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�#;IktNm&w(%a3~ht+?LQkzHKQ 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 z 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�}+d=E1PwN;? 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 EA51|YtpET3 diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm.d.ts b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm.d.ts index d15b5a0d..ff0b71e1 100644 --- a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm.d.ts +++ b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm.d.ts @@ -1,33 +1,33 @@ /* tslint:disable */ /* eslint-disable */ export const memory: WebAssembly.Memory; -export const mount_mindmap_shell: (a: any, b: any) => [number, number, number]; -export const unmount_mindmap_shell: (a: number) => [number, number]; export const mount: (a: any, b: any) => [number, number, number]; +export const mount_mindmap_shell: (a: any, b: any) => [number, number, number]; export const unmount: (a: number) => [number, number]; -export const __wbg_intounderlyingsink_free: (a: number, b: number) => void; -export const intounderlyingsink_write: (a: number, b: any) => any; -export const intounderlyingsink_close: (a: number) => any; -export const intounderlyingsink_abort: (a: number, b: any) => any; +export const unmount_mindmap_shell: (a: number) => [number, number]; export const __wbg_intounderlyingbytesource_free: (a: number, b: number) => void; -export const intounderlyingbytesource_type: (a: number) => number; export const intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number; -export const intounderlyingbytesource_start: (a: number, b: any) => void; -export const intounderlyingbytesource_pull: (a: number, b: any) => any; export const intounderlyingbytesource_cancel: (a: number) => void; +export const intounderlyingbytesource_pull: (a: number, b: any) => any; +export const intounderlyingbytesource_start: (a: number, b: any) => void; +export const intounderlyingbytesource_type: (a: number) => number; +export const __wbg_intounderlyingsink_free: (a: number, b: number) => void; +export const intounderlyingsink_abort: (a: number, b: any) => any; +export const intounderlyingsink_close: (a: number) => any; +export const intounderlyingsink_write: (a: number, b: any) => any; export const __wbg_intounderlyingsource_free: (a: number, b: number) => void; -export const intounderlyingsource_pull: (a: number, b: any) => any; export const intounderlyingsource_cancel: (a: number) => void; -export const wasm_bindgen__convert__closures_____invoke__h3a3182d847094e12: (a: number, b: number, c: any) => [number, number]; -export const wasm_bindgen__convert__closures_____invoke__h0accad0f5d87788a: (a: number, b: number, c: any, d: any) => void; -export const wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5: (a: number, b: number, c: any) => void; -export const wasm_bindgen__convert__closures_____invoke__had771ddc65647798: (a: number, b: number, c: any) => void; -export const wasm_bindgen__convert__closures_____invoke__h0abd2b2fe4652e2a: (a: number, b: number, c: any) => void; -export const wasm_bindgen__convert__closures_____invoke__h396914cf76a9e7a5_4: (a: number, b: number, c: any) => void; -export const wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf: (a: number, b: number, c: any) => void; -export const wasm_bindgen__convert__closures_____invoke__h794babeffd4f821f: (a: number, b: number) => void; -export const wasm_bindgen__convert__closures_____invoke__h2b648e7ac8ec1fb5: (a: number, b: number) => void; -export const wasm_bindgen__convert__closures_____invoke__h0b7fb40a8610550c: (a: number, b: number) => void; +export const intounderlyingsource_pull: (a: number, b: any) => any; +export const wasm_bindgen__convert__closures_____invoke__h854f4676fa692669: (a: number, b: number, c: any) => [number, number]; +export const wasm_bindgen__convert__closures_____invoke__h1a94ffe1b1ed8350: (a: number, b: number, c: any, d: any) => void; +export const wasm_bindgen__convert__closures_____invoke__h9213ab6f3ef747a1: (a: number, b: number, c: any) => void; +export const wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f: (a: number, b: number, c: any) => void; +export const wasm_bindgen__convert__closures_____invoke__h10d35e1548938147: (a: number, b: number, c: any) => void; +export const wasm_bindgen__convert__closures_____invoke__h280638b828d42e1f_4: (a: number, b: number, c: any) => void; +export const wasm_bindgen__convert__closures_____invoke__hdc2c23cc0c047a34: (a: number, b: number, c: any) => void; +export const wasm_bindgen__convert__closures_____invoke__h68fbbcff54846097: (a: number, b: number) => void; +export const wasm_bindgen__convert__closures_____invoke__had164c21c04063ef: (a: number, b: number) => void; +export const wasm_bindgen__convert__closures_____invoke__h5921057d3102c7f1: (a: number, b: number) => void; export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; export const __externref_table_alloc: () => number; diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/snippets/leptos-tiptap-c355e6ec24c3df4c/src/js/generated/tiptap_paragraph.js b/rust/spikes/leptos-tiptap-spike/generated/island/snippets/leptos-tiptap-c355e6ec24c3df4c/src/js/generated/tiptap_paragraph.js index fd222c47..a010cd50 100644 --- a/rust/spikes/leptos-tiptap-spike/generated/island/snippets/leptos-tiptap-c355e6ec24c3df4c/src/js/generated/tiptap_paragraph.js +++ b/rust/spikes/leptos-tiptap-spike/generated/island/snippets/leptos-tiptap-c355e6ec24c3df4c/src/js/generated/tiptap_paragraph.js @@ -1,4 +1,4 @@ -var Zb=Object.create;var T0=Object.defineProperty;var Qb=Object.getOwnPropertyDescriptor;var Jb=Object.getOwnPropertyNames;var ew=Object.getPrototypeOf,tw=Object.prototype.hasOwnProperty;var iw=(i,e,t)=>e in i?T0(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var T=(i,e)=>()=>(i&&(e=i(i=0)),e);var rr=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),tt=(i,e)=>{for(var t in e)T0(i,t,{get:e[t],enumerable:!0})},rw=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Jb(e))!tw.call(i,n)&&n!==t&&T0(i,n,{get:()=>e[n],enumerable:!(r=Qb(e,n))||r.enumerable});return i};var pt=(i,e,t)=>(t=i!=null?Zb(ew(i)):{},rw(e||!i||!i.__esModule?T0(t,"default",{value:i,enumerable:!0}):t,i));var U=(i,e,t)=>iw(i,typeof e!="symbol"?e+"":e,t);function Fc(){if(!k0&&(k0=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!k0))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return k0(fw)}var k0,fw,N3=T(()=>{fw=new Uint8Array(16)});function E3(i,e=0){return xt[i[e+0]]+xt[i[e+1]]+xt[i[e+2]]+xt[i[e+3]]+"-"+xt[i[e+4]]+xt[i[e+5]]+"-"+xt[i[e+6]]+xt[i[e+7]]+"-"+xt[i[e+8]]+xt[i[e+9]]+"-"+xt[i[e+10]]+xt[i[e+11]]+xt[i[e+12]]+xt[i[e+13]]+xt[i[e+14]]+xt[i[e+15]]}var xt,S3=T(()=>{xt=[];for(let i=0;i<256;++i)xt.push((i+256).toString(16).slice(1))});var mw,qc,A3=T(()=>{mw=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),qc={randomUUID:mw}});function pw(i,e,t){if(qc.randomUUID&&!e&&!i)return qc.randomUUID();i=i||{};let r=i.random||(i.rng||Fc)();if(r[6]=r[6]&15|64,r[8]=r[8]&63|128,e){t=t||0;for(let n=0;n<16;++n)e[t+n]=r[n];return e}return E3(r)}var fo,k3=T(()=>{A3();N3();S3();fo=pw});var Hc=T(()=>{k3()});var k,Uc,eU,$c,$s,Mi,C3,_3,js,L3,$e=T(()=>{k={CHANGE_THEME:"changeTheme",CHANGE_LAYOUT:"changeLayout",MODE:{READONLY:"readonly",EDIT:"edit"},LAYOUT:{LOGICAL_STRUCTURE:"logicalStructure",LOGICAL_STRUCTURE_LEFT:"logicalStructureLeft",MIND_MAP:"mindMap",ORGANIZATION_STRUCTURE:"organizationStructure",CATALOG_ORGANIZATION:"catalogOrganization",TIMELINE:"timeline",TIMELINE2:"timeline2",FISHBONE:"fishbone",FISHBONE2:"fishbone2",RIGHT_FISHBONE:"rightFishbone",RIGHT_FISHBONE2:"rightFishbone2",VERTICAL_TIMELINE:"verticalTimeline",VERTICAL_TIMELINE2:"verticalTimeline2",VERTICAL_TIMELINE3:"verticalTimeline3"},DIR:{UP:"up",LEFT:"left",DOWN:"down",RIGHT:"right"},KEY_DIR:{LEFT:"Left",UP:"Up",RIGHT:"Right",DOWN:"Down"},SHAPE:{RECTANGLE:"rectangle",DIAMOND:"diamond",PARALLELOGRAM:"parallelogram",ROUNDED_RECTANGLE:"roundedRectangle",OCTAGONAL_RECTANGLE:"octagonalRectangle",OUTER_TRIANGULAR_RECTANGLE:"outerTriangularRectangle",INNER_TRIANGULAR_RECTANGLE:"innerTriangularRectangle",ELLIPSE:"ellipse",CIRCLE:"circle"},MOUSE_WHEEL_ACTION:{ZOOM:"zoom",MOVE:"move"},INIT_ROOT_NODE_POSITION:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom",CENTER:"center"},LAYOUT_GROW_DIR:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom"},PASTE_TYPE:{CLIP_BOARD:"clipBoard",CANVAS:"canvas"},SCROLL_BAR_DIR:{VERTICAL:"vertical",HORIZONTAL:"horizontal"},CREATE_NEW_NODE_BEHAVIOR:{DEFAULT:"default",NOT_ACTIVE:"notActive",ACTIVE_ONLY:"activeOnly"},TAG_PLACEMENT:{RIGHT:"right",BOTTOM:"bottom"},IMG_PLACEMENT:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom"}},Uc={[k.INIT_ROOT_NODE_POSITION.LEFT]:0,[k.INIT_ROOT_NODE_POSITION.TOP]:0,[k.INIT_ROOT_NODE_POSITION.RIGHT]:1,[k.INIT_ROOT_NODE_POSITION.BOTTOM]:1,[k.INIT_ROOT_NODE_POSITION.CENTER]:.5},eU=[{name:"\u903B\u8F91\u7ED3\u6784\u56FE",value:k.LAYOUT.LOGICAL_STRUCTURE},{name:"\u5411\u5DE6\u903B\u8F91\u7ED3\u6784\u56FE",value:k.LAYOUT.LOGICAL_STRUCTURE_LEFT},{name:"\u601D\u7EF4\u5BFC\u56FE",value:k.LAYOUT.MIND_MAP},{name:"\u7EC4\u7EC7\u7ED3\u6784\u56FE",value:k.LAYOUT.ORGANIZATION_STRUCTURE},{name:"\u76EE\u5F55\u7EC4\u7EC7\u56FE",value:k.LAYOUT.CATALOG_ORGANIZATION},{name:"\u65F6\u95F4\u8F74",value:k.LAYOUT.TIMELINE},{name:"\u65F6\u95F4\u8F742",value:k.LAYOUT.TIMELINE2},{name:"\u7AD6\u5411\u65F6\u95F4\u8F74",value:k.LAYOUT.VERTICAL_TIMELINE},{name:"\u7AD6\u5411\u65F6\u95F4\u8F742",value:k.LAYOUT.VERTICAL_TIMELINE2},{name:"\u7AD6\u5411\u65F6\u95F4\u8F743",value:k.LAYOUT.VERTICAL_TIMELINE3},{name:"\u9C7C\u9AA8\u56FE",value:k.LAYOUT.FISHBONE},{name:"\u9C7C\u9AA8\u56FE2",value:k.LAYOUT.FISHBONE2},{name:"\u5411\u53F3\u9C7C\u9AA8\u56FE",value:k.LAYOUT.RIGHT_FISHBONE},{name:"\u5411\u53F3\u9C7C\u9AA8\u56FE2",value:k.LAYOUT.RIGHT_FISHBONE2}],$c=[k.LAYOUT.LOGICAL_STRUCTURE,k.LAYOUT.LOGICAL_STRUCTURE_LEFT,k.LAYOUT.MIND_MAP,k.LAYOUT.CATALOG_ORGANIZATION,k.LAYOUT.ORGANIZATION_STRUCTURE,k.LAYOUT.TIMELINE,k.LAYOUT.TIMELINE2,k.LAYOUT.VERTICAL_TIMELINE,k.LAYOUT.VERTICAL_TIMELINE2,k.LAYOUT.VERTICAL_TIMELINE3,k.LAYOUT.FISHBONE,k.LAYOUT.FISHBONE2,k.LAYOUT.RIGHT_FISHBONE,k.LAYOUT.RIGHT_FISHBONE2],$s=["text","image","imageTitle","imageSize","icon","tag","hyperlink","hyperlinkTitle","note","expand","isActive","generalization","richText","resetRichText","uid","activeStyle","associativeLineTargets","associativeLineTargetControlOffsets","associativeLinePoint","associativeLineText","attachmentUrl","attachmentName","notation","outerFrame","number","range","customLeft","customTop","customTextWidth","checkbox","dir","needUpdate","imgMap","nodeLink"],Mi={READ_CLIPBOARD_ERROR:"read_clipboard_error",PARSE_PASTE_DATA_ERROR:"parse_paste_data_error",CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR:"custom_handle_clipboard_text_error",LOAD_CLIPBOARD_IMAGE_ERROR:"load_clipboard_image_error",BEFORE_TEXT_EDIT_ERROR:"before_text_edit_error",EXPORT_ERROR:"export_error",EXPORT_LOAD_IMAGE_ERROR:"export_load_image_error",DATA_CHANGE_DETAIL_EVENT_ERROR:"data_change_detail_event_error"},C3=` +var ww=Object.create;var L0=Object.defineProperty;var Mw=Object.getOwnPropertyDescriptor;var Tw=Object.getOwnPropertyNames;var Nw=Object.getPrototypeOf,Ew=Object.prototype.hasOwnProperty;var Sw=(i,e,t)=>e in i?L0(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var T=(i,e)=>()=>(i&&(e=i(i=0)),e);var tr=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),tt=(i,e)=>{for(var t in e)L0(i,t,{get:e[t],enumerable:!0})},Aw=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Tw(e))!Ew.call(i,n)&&n!==t&&L0(i,n,{get:()=>e[n],enumerable:!(r=Mw(e,n))||r.enumerable});return i};var yt=(i,e,t)=>(t=i!=null?ww(Nw(i)):{},Aw(e||!i||!i.__esModule?L0(t,"default",{value:i,enumerable:!0}):t,i));var U=(i,e,t)=>Sw(i,typeof e!="symbol"?e+"":e,t);function Kc(){if(!O0&&(O0=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!O0))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return O0(Bw)}var O0,Bw,P3=T(()=>{Bw=new Uint8Array(16)});function F3(i,e=0){return bt[i[e+0]]+bt[i[e+1]]+bt[i[e+2]]+bt[i[e+3]]+"-"+bt[i[e+4]]+bt[i[e+5]]+"-"+bt[i[e+6]]+bt[i[e+7]]+"-"+bt[i[e+8]]+bt[i[e+9]]+"-"+bt[i[e+10]]+bt[i[e+11]]+bt[i[e+12]]+bt[i[e+13]]+bt[i[e+14]]+bt[i[e+15]]}var bt,q3=T(()=>{bt=[];for(let i=0;i<256;++i)bt.push((i+256).toString(16).slice(1))});var Pw,Zc,H3=T(()=>{Pw=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),Zc={randomUUID:Pw}});function Fw(i,e,t){if(Zc.randomUUID&&!e&&!i)return Zc.randomUUID();i=i||{};let r=i.random||(i.rng||Kc)();if(r[6]=r[6]&15|64,r[8]=r[8]&63|128,e){t=t||0;for(let n=0;n<16;++n)e[t+n]=r[n];return e}return F3(r)}var vo,U3=T(()=>{H3();P3();q3();vo=Fw});var Qc=T(()=>{U3()});var C,Jc,SU,eu,js,Ti,$3,j3,Gs,G3,Ge=T(()=>{C={CHANGE_THEME:"changeTheme",CHANGE_LAYOUT:"changeLayout",MODE:{READONLY:"readonly",EDIT:"edit"},LAYOUT:{LOGICAL_STRUCTURE:"logicalStructure",LOGICAL_STRUCTURE_LEFT:"logicalStructureLeft",MIND_MAP:"mindMap",ORGANIZATION_STRUCTURE:"organizationStructure",CATALOG_ORGANIZATION:"catalogOrganization",TIMELINE:"timeline",TIMELINE2:"timeline2",FISHBONE:"fishbone",FISHBONE2:"fishbone2",RIGHT_FISHBONE:"rightFishbone",RIGHT_FISHBONE2:"rightFishbone2",VERTICAL_TIMELINE:"verticalTimeline",VERTICAL_TIMELINE2:"verticalTimeline2",VERTICAL_TIMELINE3:"verticalTimeline3"},DIR:{UP:"up",LEFT:"left",DOWN:"down",RIGHT:"right"},KEY_DIR:{LEFT:"Left",UP:"Up",RIGHT:"Right",DOWN:"Down"},SHAPE:{RECTANGLE:"rectangle",DIAMOND:"diamond",PARALLELOGRAM:"parallelogram",ROUNDED_RECTANGLE:"roundedRectangle",OCTAGONAL_RECTANGLE:"octagonalRectangle",OUTER_TRIANGULAR_RECTANGLE:"outerTriangularRectangle",INNER_TRIANGULAR_RECTANGLE:"innerTriangularRectangle",ELLIPSE:"ellipse",CIRCLE:"circle"},MOUSE_WHEEL_ACTION:{ZOOM:"zoom",MOVE:"move"},INIT_ROOT_NODE_POSITION:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom",CENTER:"center"},LAYOUT_GROW_DIR:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom"},PASTE_TYPE:{CLIP_BOARD:"clipBoard",CANVAS:"canvas"},SCROLL_BAR_DIR:{VERTICAL:"vertical",HORIZONTAL:"horizontal"},CREATE_NEW_NODE_BEHAVIOR:{DEFAULT:"default",NOT_ACTIVE:"notActive",ACTIVE_ONLY:"activeOnly"},TAG_PLACEMENT:{RIGHT:"right",BOTTOM:"bottom"},IMG_PLACEMENT:{LEFT:"left",TOP:"top",RIGHT:"right",BOTTOM:"bottom"}},Jc={[C.INIT_ROOT_NODE_POSITION.LEFT]:0,[C.INIT_ROOT_NODE_POSITION.TOP]:0,[C.INIT_ROOT_NODE_POSITION.RIGHT]:1,[C.INIT_ROOT_NODE_POSITION.BOTTOM]:1,[C.INIT_ROOT_NODE_POSITION.CENTER]:.5},SU=[{name:"\u903B\u8F91\u7ED3\u6784\u56FE",value:C.LAYOUT.LOGICAL_STRUCTURE},{name:"\u5411\u5DE6\u903B\u8F91\u7ED3\u6784\u56FE",value:C.LAYOUT.LOGICAL_STRUCTURE_LEFT},{name:"\u601D\u7EF4\u5BFC\u56FE",value:C.LAYOUT.MIND_MAP},{name:"\u7EC4\u7EC7\u7ED3\u6784\u56FE",value:C.LAYOUT.ORGANIZATION_STRUCTURE},{name:"\u76EE\u5F55\u7EC4\u7EC7\u56FE",value:C.LAYOUT.CATALOG_ORGANIZATION},{name:"\u65F6\u95F4\u8F74",value:C.LAYOUT.TIMELINE},{name:"\u65F6\u95F4\u8F742",value:C.LAYOUT.TIMELINE2},{name:"\u7AD6\u5411\u65F6\u95F4\u8F74",value:C.LAYOUT.VERTICAL_TIMELINE},{name:"\u7AD6\u5411\u65F6\u95F4\u8F742",value:C.LAYOUT.VERTICAL_TIMELINE2},{name:"\u7AD6\u5411\u65F6\u95F4\u8F743",value:C.LAYOUT.VERTICAL_TIMELINE3},{name:"\u9C7C\u9AA8\u56FE",value:C.LAYOUT.FISHBONE},{name:"\u9C7C\u9AA8\u56FE2",value:C.LAYOUT.FISHBONE2},{name:"\u5411\u53F3\u9C7C\u9AA8\u56FE",value:C.LAYOUT.RIGHT_FISHBONE},{name:"\u5411\u53F3\u9C7C\u9AA8\u56FE2",value:C.LAYOUT.RIGHT_FISHBONE2}],eu=[C.LAYOUT.LOGICAL_STRUCTURE,C.LAYOUT.LOGICAL_STRUCTURE_LEFT,C.LAYOUT.MIND_MAP,C.LAYOUT.CATALOG_ORGANIZATION,C.LAYOUT.ORGANIZATION_STRUCTURE,C.LAYOUT.TIMELINE,C.LAYOUT.TIMELINE2,C.LAYOUT.VERTICAL_TIMELINE,C.LAYOUT.VERTICAL_TIMELINE2,C.LAYOUT.VERTICAL_TIMELINE3,C.LAYOUT.FISHBONE,C.LAYOUT.FISHBONE2,C.LAYOUT.RIGHT_FISHBONE,C.LAYOUT.RIGHT_FISHBONE2],js=["text","image","imageTitle","imageSize","icon","tag","hyperlink","hyperlinkTitle","note","expand","isActive","generalization","richText","resetRichText","uid","activeStyle","associativeLineTargets","associativeLineTargetControlOffsets","associativeLinePoint","associativeLineText","attachmentUrl","attachmentName","notation","outerFrame","number","range","customLeft","customTop","customTextWidth","checkbox","dir","needUpdate","imgMap","nodeLink"],Ti={READ_CLIPBOARD_ERROR:"read_clipboard_error",PARSE_PASTE_DATA_ERROR:"parse_paste_data_error",CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR:"custom_handle_clipboard_text_error",LOAD_CLIPBOARD_IMAGE_ERROR:"load_clipboard_image_error",BEFORE_TEXT_EDIT_ERROR:"before_text_edit_error",EXPORT_ERROR:"export_error",EXPORT_LOAD_IMAGE_ERROR:"export_load_image_error",DATA_CHANGE_DETAIL_EVENT_ERROR:"data_change_detail_event_error"},$3=` /* \u9F20\u6807hover\u548C\u6FC0\u6D3B\u65F6\u6E32\u67D3\u7684\u77E9\u5F62 */ .smm-hover-node{ display: none; @@ -19,13 +19,13 @@ var Zb=Object.create;var T0=Object.defineProperty;var Qb=Object.getOwnPropertyDe .smm-text-node-wrap, .smm-expand-btn-text { user-select: none; } -`,_3=["img","br","hr","input","link","meta","area"],js=1.2,L3=["fontFamily","fontSize","fontWeight","fontStyle","textDecoration","color","textAlign"]});function mo(i){this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(i)}var I3=T(()=>{mo.prototype.init_genrand=function(i){for(this.mt[0]=i>>>0,this.mti=1;this.mti>>30,this.mt[this.mti]=(((i&4294901760)>>>16)*1812433253<<16)+(i&65535)*1812433253+this.mti,this.mt[this.mti]>>>=0};mo.prototype.genrand_int32=function(){var i,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var t;for(this.mti==this.N+1&&this.init_genrand(5489),t=0;t>>1^e[i&1];for(;t>>1^e[i&1];i=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^i>>>1^e[i&1],this.mti=0}return i=this.mt[this.mti++],i^=i>>>11,i^=i<<7&2636928640,i^=i<<15&4022730752,i^=i>>>18,i>>>0}});function fe(i,e){if(Array.isArray(i)){for(let t of i)fe(t,e);return}if(typeof i=="object"){for(let t in i)fe(t,i[t]);return}q3(Object.getOwnPropertyNames(e)),Yc[i]=Object.assign(Yc[i]||{},e)}function Wt(i){return Yc[i]||{}}function gw(){return[...new Set(F3)]}function q3(i){F3.push(...i)}function ru(i,e){let t,r=i.length,n=[];for(t=0;t=0;e--)$3(i.children[e]);return i.id&&(i.id=U3(i.nodeName)),i}function ge(i,e){let t,r;for(i=Array.isArray(i)?i:[i],r=i.length-1;r>=0;r--)for(t in e)i[r].prototype[t]=e[t]}function Fe(i){return function(...e){let t=e[e.length-1];return t&&t.constructor===Object&&!(t instanceof Array)?i.apply(this,e.slice(0,-1)).attr(t):i.apply(this,e)}}function Tw(){return this.parent().children()}function Nw(){return this.parent().index(this)}function Ew(){return this.siblings()[this.position()+1]}function Sw(){return this.siblings()[this.position()-1]}function Aw(){let i=this.position();return this.parent().add(this.remove(),i+1),this}function kw(){let i=this.position();return this.parent().add(this.remove(),i?i-1:0),this}function Cw(){return this.parent().add(this.remove()),this}function _w(){return this.parent().add(this.remove(),0),this}function Lw(i){i=Rt(i),i.remove();let e=this.position();return this.parent().add(i,e),this}function Iw(i){i=Rt(i),i.remove();let e=this.position();return this.parent().add(i,e+1),this}function zw(i){return i=Rt(i),i.before(this),this}function Rw(i){return i=Rt(i),i.after(this),this}function Hw(){let i=this.attr("class");return i==null?[]:i.trim().split(Sr)}function Uw(i){return this.classes().indexOf(i)!==-1}function $w(i){if(!this.hasClass(i)){let e=this.classes();e.push(i),this.attr("class",e.join(" "))}return this}function jw(i){return this.hasClass(i)&&this.attr("class",this.classes().filter(function(e){return e!==i}).join(" ")),this}function Gw(i){return this.hasClass(i)?this.removeClass(i):this.addClass(i)}function Vw(i,e){let t={};if(arguments.length===0)return this.node.style.cssText.split(/\s*;\s*/).filter(function(r){return!!r.length}).forEach(function(r){let n=r.split(/\s*:\s*/);t[n[0]]=n[1]}),t;if(arguments.length<2){if(Array.isArray(i)){for(let r of i){let n=C0(r);t[r]=this.node.style[n]}return t}if(typeof i=="string")return this.node.style[C0(i)];if(typeof i=="object")for(let r in i)this.node.style[C0(r)]=i[r]==null||D3.test(i[r])?"":i[r]}return arguments.length===2&&(this.node.style[C0(i)]=e==null||D3.test(e)?"":e),this}function Ww(){return this.css("display","")}function Yw(){return this.css("display","none")}function Xw(){return this.css("display")!=="none"}function Kw(i,e,t){if(i==null)return this.data(ru(xw(this.node.attributes,r=>r.nodeName.indexOf("data-")===0),r=>r.nodeName.slice(5)));if(i instanceof Array){let r={};for(let n of i)r[n]=this.data(n);return r}else if(typeof i=="object")for(e in i)this.data(e,i[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+i))}catch{return this.attr("data-"+i)}else this.attr("data-"+i,e===null?null:t===!0||typeof e=="string"||typeof e=="number"?e:JSON.stringify(e));return this}function Zw(i,e){if(typeof arguments[0]=="object")for(let t in i)this.remember(t,i[t]);else{if(arguments.length===1)return this.memory()[i];this.memory()[i]=e}return this}function Qw(){if(arguments.length===0)this._memory={};else for(let i=arguments.length-1;i>=0;i--)delete this.memory()[arguments[i]];return this}function Jw(){return this._memory=this._memory||{}}function eM(i){return i.length===4?["#",i.substring(1,2),i.substring(1,2),i.substring(2,3),i.substring(2,3),i.substring(3,4),i.substring(3,4)].join(""):i}function tM(i){let e=Math.round(i),r=Math.max(0,Math.min(255,e)).toString(16);return r.length===1?"0"+r:r}function Gs(i,e){for(let t=e.length;t--;)if(i[e[t]]==null)return!1;return!0}function iM(i,e){let t=Gs(i,"rgb")?{_a:i.r,_b:i.g,_c:i.b,_d:0,space:"rgb"}:Gs(i,"xyz")?{_a:i.x,_b:i.y,_c:i.z,_d:0,space:"xyz"}:Gs(i,"hsl")?{_a:i.h,_b:i.s,_c:i.l,_d:0,space:"hsl"}:Gs(i,"lab")?{_a:i.l,_b:i.a,_c:i.b,_d:0,space:"lab"}:Gs(i,"lch")?{_a:i.l,_b:i.c,_c:i.h,_d:0,space:"lch"}:Gs(i,"cmyk")?{_a:i.c,_b:i.m,_c:i.y,_d:i.k,space:"cmyk"}:{_a:0,_b:0,_c:0,space:"rgb"};return t.space=e||t.space,t}function rM(i){return i==="lab"||i==="xyz"||i==="lch"}function Vc(i,e,t){return t<0&&(t+=1),t>1&&(t-=1),t<1/6?i+(e-i)*6*t:t<1/2?e:t<2/3?i+(e-i)*(2/3-t)*6:i}function nM(i,e){return new it(i,e).transformO(this.screenCTM().inverseO())}function Vs(i,e,t){return Math.abs(e-i)<(t||1e-6)}function sM(){return new xe(this.node.getCTM())}function aM(){if(typeof this.isRoot=="function"&&!this.isRoot()){let i=this.rect(1,1),e=i.node.getScreenCTM();return i.remove(),new xe(e)}return new xe(this.node.getScreenCTM())}function ln(){if(!ln.nodes){let i=Rt().size(2,0);i.node.style.cssText=["opacity: 0","position: absolute","left: -100%","top: -100%","overflow: hidden"].join(";"),i.attr("focusable","false"),i.attr("aria-hidden","true");let e=i.path().node;ln.nodes={svg:i,path:e}}if(!ln.nodes.svg.node.parentNode){let i=Te.document.body||Te.document.documentElement;ln.nodes.svg.addTo(i)}return ln.nodes}function G3(i){return!i.width&&!i.height&&!i.x&&!i.y}function oM(i){return i===Te.document||(Te.document.documentElement.contains||function(e){for(;e.parentNode;)e=e.parentNode;return e===Te.document}).call(Te.document.documentElement,i)}function V3(i,e,t){let r;try{if(r=e(i.node),G3(r)&&!oM(i.node))throw new Error("Element not in the dom")}catch{r=t(i)}return r}function lM(){let t=V3(this,n=>n.getBBox(),n=>{try{let s=n.clone().addTo(ln().svg).show(),a=s.node.getBBox();return s.remove(),a}catch(s){throw new Error(`Getting bbox of element "${n.node.nodeName}" is not possible: ${s.toString()}`)}});return new Gt(t)}function hM(i){let r=V3(this,s=>s.getBoundingClientRect(),s=>{throw new Error(`Getting rbox of element "${s.node.nodeName}" is not possible`)}),n=new Gt(r);return i?n.transform(i.screenCTM().inverseO()):n.addOffset()}function dM(i,e){let t=this.bbox();return i>t.x&&e>t.y&&i(r[n]=this.attr(n),r),{});if(typeof i=="object"&&i.constructor===Object)for(e in i)this.attr(e,i[e]);else if(e===null)this.node.removeAttribute(i);else{if(e==null)return e=this.node.getAttribute(i),e==null?xM[i]:O3.test(e)?parseFloat(e):e;e=X3.reduce((r,n)=>n(i,r,this),e),typeof e=="number"?e=new ye(e):Ni.isColor(e)?e=new Ni(e):e.constructor===Array&&(e=new hn(e)),i==="leading"?this.leading&&this.leading(e):typeof t=="string"?this.node.setAttributeNS(t,i,e.toString()):this.node.setAttribute(i,e.toString()),this.rebuild&&(i==="font-size"||i==="x")&&this.rebuild()}}return this}function wM(){return this.attr("transform",null)}function MM(){return(this.attr("transform")||"").split(Pw).slice(0,-1).map(function(e){let t=e.trim().split("(");return[t[0],t[1].split(Sr).map(function(r){return parseFloat(r)})]}).reverse().reduce(function(e,t){return t[0]==="matrix"?e.lmultiply(xe.fromArray(t[1])):e[t[0]].apply(e,t[1])},new xe)}function TM(i,e){if(this===i)return this;let t=this.screenCTM(),r=i.screenCTM().inverse();return this.addTo(i,e).untransform().transform(r.multiply(t)),this}function NM(i){return this.toParent(this.root(),i)}function EM(i,e){if(i==null||typeof i=="string"){let n=new xe(this).decompose();return i==null?n:n[i]}xe.isMatrixLike(i)||(i={...i,origin:Xc(i,this)});let t=e===!0?this:e||!1,r=new xe(t).transform(i);return this.attr("transform",r)}function lu(i){return this.attr("rx",i)}function hu(i){return this.attr("ry",i)}function K3(i){return i==null?this.cx()-this.rx():this.cx(i+this.rx())}function Z3(i){return i==null?this.cy()-this.ry():this.cy(i+this.ry())}function Q3(i){return this.attr("cx",i)}function J3(i){return this.attr("cy",i)}function e2(i){return i==null?this.rx()*2:this.rx(new ye(i).divide(2))}function t2(i){return i==null?this.ry()*2:this.ry(new ye(i).divide(2))}function i2(i,e){return(this._element||this).type==="radialGradient"?this.attr({fx:new ye(i),fy:new ye(e)}):this.attr({x1:new ye(i),y1:new ye(e)})}function r2(i,e){return(this._element||this).type==="radialGradient"?this.attr({cx:new ye(i),cy:new ye(e)}):this.attr({x2:new ye(i),y2:new ye(e)})}function CM(i){return i==null?this.bbox().x:this.move(i,this.bbox().y)}function _M(i){return i==null?this.bbox().y:this.move(this.bbox().x,i)}function LM(i){let e=this.bbox();return i==null?e.width:this.size(i,e.height)}function IM(i){let e=this.bbox();return i==null?e.height:this.size(e.width,i)}function Ys(i,e){return function(t){return t==null?this[i]:(this[i]=t,e&&e.call(this),this)}}function P3(){let i=(this._duration||500)/1e3,e=this._overshoot||0,t=1e-10,r=Math.PI,n=Math.log(e/100+t),s=-n/Math.sqrt(r*r+n*n),a=3.9/(s*i);this.d=2*s*a,this.k=a*a}function DM(i){let e=i.segment[0];return Jc[e](i.segment.slice(1),i.p,i.p0)}function eu(i){return i.segment.length&&i.segment.length-1===RM[i.segment[0].toUpperCase()]}function OM(i,e){i.inNumber&&Jn(i,!1);let t=au.test(e);if(t)i.segment=[e];else{let r=i.lastCommand,n=r.toLowerCase(),s=r===n;i.segment=[n==="m"?s?"l":"L":r]}return i.inSegment=!0,i.lastCommand=i.segment[0],t}function Jn(i,e){if(!i.inNumber)throw new Error("Parser Error");i.number&&i.segment.push(parseFloat(i.number)),i.inNumber=e,i.number="",i.pointSeen=!1,i.hasExponent=!1,eu(i)&&tu(i)}function tu(i){i.inSegment=!1,i.absolute&&(i.segment=DM(i)),i.segments.push(i.segment)}function BM(i){if(!i.segment.length)return!1;let e=i.segment[0].toUpperCase()==="A",t=i.segment.length;return e&&(t===4||t===5)}function PM(i){return i.lastToken.toUpperCase()==="E"}function FM(i,e=!0){let t=0,r="",n={segment:[],inNumber:!1,number:"",lastToken:"",inSegment:!1,segments:[],pointSeen:!1,hasExponent:!1,absolute:e,p0:new it,p:new it};for(;n.lastToken=r,r=i.charAt(t++);)if(!(!n.inSegment&&OM(n,r))){if(r==="."){if(n.pointSeen||n.hasExponent){Jn(n,!1),--t;continue}n.inNumber=!0,n.pointSeen=!0,n.number+=r;continue}if(!isNaN(parseInt(r))){if(n.number==="0"||BM(n)){n.inNumber=!0,n.number=r,Jn(n,!0);continue}n.inNumber=!0,n.number+=r;continue}if(r===" "||r===","){n.inNumber&&Jn(n,!1);continue}if(r==="-"){if(n.inNumber&&!PM(n)){Jn(n,!1),--t;continue}n.number+=r,n.inNumber=!0;continue}if(r.toUpperCase()==="E"){n.number+=r,n.hasExponent=!0;continue}if(au.test(r)){if(n.inNumber)Jn(n,!1);else if(eu(n))tu(n);else throw new Error("parser Error");--t}}return n.inNumber&&Jn(n,!1),n.inSegment&&eu(n)&&tu(n),n.segments}function qM(i){let e="";for(let t=0,r=i.length;t{let n;try{n=t.bbox()}catch{return}let s=new xe(t),a=s.translate(i,e).transform(s.inverse()),o=new it(n.x,n.y).transform(a);t.move(o.x,o.y)}),this}function uT(i){return this.dmove(i,0)}function fT(i){return this.dmove(0,i)}function mT(i,e=this.bbox()){return i==null?e.height:this.size(e.width,i,e)}function pT(i=0,e=0,t=this.bbox()){let r=i-t.x,n=e-t.y;return this.dmove(r,n)}function gT(i,e,t=this.bbox()){let r=ta(this,i,e,t),n=r.width/t.width,s=r.height/t.height;return this.children().forEach((a,o)=>{let l=new it(t).transform(new xe(a).inverse());a.scale(n,s,l.x,l.y)}),this}function xT(i,e=this.bbox()){return i==null?e.width:this.size(i,e.height,e)}function yT(i,e=this.bbox()){return i==null?e.x:this.move(i,e.y,e)}function vT(i,e=this.bbox()){return i==null?e.y:this.move(e.x,i,e)}function bT(i,e){if(!i)return"";if(!e)return i;let t=i+"{";for(let r in e)t+=yw(r)+":"+e[r]+";";return t+="}",t}var Yc,F3,nu,vw,_0,Lo,bw,Te,yo,es,su,Gc,Mw,j3,Dw,Ow,Bw,Pw,Fw,z3,R3,D3,O3,qw,Sr,au,Ni,it,xe,Gt,Nr,cM,mM,W3,ts,go,xM,hn,ye,X3,dn,Ei,po,bM,Vt,bo,Dt,SM,Xs,L0,AM,is,rs,ji,sr,kM,du,ns,Ks,zM,wo,Mo,Zs,Zc,Qc,RM,Jc,Wc,Er,n2,Tr,To,No,HM,ss,cu,ar,s2,Gi,as,Ve,xo,Se,XM,KM,I0,Vi,Qs,a2,o2,iu,QM,Eo,So,l2,Ce,Js,Wi,Ao,ea,h2,_e,cn,ko,z0,Co,_o,R0,Ae,yt=T(()=>{Yc={},F3=[];nu="http://www.w3.org/2000/svg",vw="http://www.w3.org/1999/xhtml",_0="http://www.w3.org/2000/xmlns/",Lo="http://www.w3.org/1999/xlink",bw="http://svgjs.dev/svgjs",Te={window:typeof window>"u"?null:window,document:typeof document>"u"?null:document},yo=class{},es={},su="___SYMBOL___ROOT___";Gc=Ti;Mw=1e3;fe("Dom",{siblings:Tw,position:Nw,next:Ew,prev:Sw,forward:Aw,backward:kw,front:Cw,back:_w,before:Lw,after:Iw,insertBefore:zw,insertAfter:Rw});j3=/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,Dw=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,Ow=/rgb\((\d+),(\d+),(\d+)\)/,Bw=/(#[a-z_][a-z0-9\-_]*)/i,Pw=/\)\s*,?\s*/,Fw=/\s/g,z3=/^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i,R3=/^rgb\(/,D3=/^(\s+)?$/,O3=/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,qw=/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,Sr=/[\s,]+/,au=/[MLHVCSQTAZ]/i;fe("Dom",{classes:Hw,hasClass:Uw,addClass:$w,removeClass:jw,toggleClass:Gw});fe("Dom",{css:Vw,show:Ww,hide:Yw,visible:Xw});fe("Dom",{data:Kw});fe("Dom",{remember:Zw,forget:Qw,memory:Jw});Ni=class i{constructor(...e){this.init(...e)}static isColor(e){return e&&(e instanceof i||this.isRgb(e)||this.test(e))}static isRgb(e){return e&&typeof e.r=="number"&&typeof e.g=="number"&&typeof e.b=="number"}static random(e="vibrant",t,r){let{random:n,round:s,sin:a,PI:o}=Math;if(e==="vibrant"){let l=24*n()+57,h=38*n()+45,d=360*n();return new i(l,h,d,"lch")}else if(e==="sine"){t=t??n();let l=s(80*a(2*o*t/.5+.01)+150),h=s(50*a(2*o*t/.5+4.6)+200),d=s(100*a(2*o*t/.5+2.3)+150);return new i(l,h,d)}else if(e==="pastel"){let l=8*n()+86,h=17*n()+9,d=360*n();return new i(l,h,d,"lch")}else if(e==="dark"){let l=10+10*n(),h=50*n()+86,d=360*n();return new i(l,h,d,"lch")}else if(e==="rgb"){let l=255*n(),h=255*n(),d=255*n();return new i(l,h,d)}else if(e==="lab"){let l=100*n(),h=256*n()-128,d=256*n()-128;return new i(l,h,d,"lab")}else if(e==="grey"){let l=255*n();return new i(l,l,l)}else throw new Error("Unsupported random color mode")}static test(e){return typeof e=="string"&&(z3.test(e)||R3.test(e))}cmyk(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(f=>f/255),o=Math.min(1-n,1-s,1-a);if(o===1)return new i(0,0,0,1,"cmyk");let l=(1-n-o)/(1-o),h=(1-s-o)/(1-o),d=(1-a-o)/(1-o);return new i(l,h,d,o,"cmyk")}hsl(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(x=>x/255),o=Math.max(n,s,a),l=Math.min(n,s,a),h=(o+l)/2,d=o===l,c=o-l,f=d?0:h>.5?c/(2-o-l):c/(o+l),m=d?0:o===n?((s-a)/c+(sparseInt(x));Object.assign(this,{_a:f,_b:m,_c:g,_d:0,space:"rgb"})}else if(z3.test(e)){let c=x=>parseInt(x,16),[,f,m,g]=Dw.exec(eM(e)).map(c);Object.assign(this,{_a:f,_b:m,_c:g,_d:0,space:"rgb"})}else throw Error("Unsupported string format, can't construct Color");let{_a:a,_b:o,_c:l,_d:h}=this,d=this.space==="rgb"?{r:a,g:o,b:l}:this.space==="xyz"?{x:a,y:o,z:l}:this.space==="hsl"?{h:a,s:o,l}:this.space==="lab"?{l:a,a:o,b:l}:this.space==="lch"?{l:a,c:o,h:l}:this.space==="cmyk"?{c:a,m:o,y:l,k:h}:{};Object.assign(this,d)}lab(){let{x:e,y:t,z:r}=this.xyz(),n=116*t-16,s=500*(e-t),a=200*(t-r);return new i(n,s,a,"lab")}lch(){let{l:e,a:t,b:r}=this.lab(),n=Math.sqrt(t**2+r**2),s=180*Math.atan2(r,t)/Math.PI;return s<0&&(s*=-1,s=360-s),new i(e,n,s,"lch")}rgb(){if(this.space==="rgb")return this;if(rM(this.space)){let{x:e,y:t,z:r}=this;if(this.space==="lab"||this.space==="lch"){let{l:m,a:g,b:x}=this;if(this.space==="lch"){let{c:O,h:q}=this,P=Math.PI/180;g=O*Math.cos(P*q),x=O*Math.sin(P*q)}let y=(m+16)/116,b=g/500+y,S=y-x/200,A=16/116,C=.008856,I=7.787;e=.95047*(b**3>C?b**3:(b-A)/I),t=1*(y**3>C?y**3:(y-A)/I),r=1.08883*(S**3>C?S**3:(S-A)/I)}let n=e*3.2406+t*-1.5372+r*-.4986,s=e*-.9689+t*1.8758+r*.0415,a=e*.0557+t*-.204+r*1.057,o=Math.pow,l=.0031308,h=n>l?1.055*o(n,1/2.4)-.055:12.92*n,d=s>l?1.055*o(s,1/2.4)-.055:12.92*s,c=a>l?1.055*o(a,1/2.4)-.055:12.92*a;return new i(255*h,255*d,255*c)}else if(this.space==="hsl"){let{h:e,s:t,l:r}=this;if(e/=360,t/=100,r/=100,t===0)return r*=255,new i(r,r,r);let n=r<.5?r*(1+t):r+t-r*t,s=2*r-n,a=255*Vc(s,n,e+1/3),o=255*Vc(s,n,e),l=255*Vc(s,n,e-1/3);return new i(a,o,l)}else if(this.space==="cmyk"){let{c:e,m:t,y:r,k:n}=this,s=255*(1-Math.min(1,e*(1-n)+n)),a=255*(1-Math.min(1,t*(1-n)+n)),o=255*(1-Math.min(1,r*(1-n)+n));return new i(s,a,o)}else return this}toArray(){let{_a:e,_b:t,_c:r,_d:n,space:s}=this;return[e,t,r,n,s]}toHex(){let[e,t,r]=this._clamped().map(tM);return`#${e}${t}${r}`}toRgb(){let[e,t,r]=this._clamped();return`rgb(${e},${t},${r})`}toString(){return this.toHex()}xyz(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(b=>b/255),o=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,l=s>.04045?Math.pow((s+.055)/1.055,2.4):s/12.92,h=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,d=(o*.4124+l*.3576+h*.1805)/.95047,c=(o*.2126+l*.7152+h*.0722)/1,f=(o*.0193+l*.1192+h*.9505)/1.08883,m=d>.008856?Math.pow(d,1/3):7.787*d+16/116,g=c>.008856?Math.pow(c,1/3):7.787*c+16/116,x=f>.008856?Math.pow(f,1/3):7.787*f+16/116;return new i(m,g,x,"xyz")}_clamped(){let{_a:e,_b:t,_c:r}=this.rgb(),{max:n,min:s,round:a}=Math,o=l=>n(0,s(a(l),255));return[e,t,r].map(o)}},it=class i{constructor(...e){this.init(...e)}clone(){return new i(this)}init(e,t){let r={x:0,y:0},n=Array.isArray(e)?{x:e[0],y:e[1]}:typeof e=="object"?{x:e.x,y:e.y}:{x:e,y:t};return this.x=n.x==null?r.x:n.x,this.y=n.y==null?r.y:n.y,this}toArray(){return[this.x,this.y]}transform(e){return this.clone().transformO(e)}transformO(e){xe.isMatrixLike(e)||(e=new xe(e));let{x:t,y:r}=this;return this.x=e.a*t+e.c*r+e.e,this.y=e.b*t+e.d*r+e.f,this}};xe=class i{constructor(...e){this.init(...e)}static formatTransforms(e){let t=e.flip==="both"||e.flip===!0,r=e.flip&&(t||e.flip==="x")?-1:1,n=e.flip&&(t||e.flip==="y")?-1:1,s=e.skew&&e.skew.length?e.skew[0]:isFinite(e.skew)?e.skew:isFinite(e.skewX)?e.skewX:0,a=e.skew&&e.skew.length?e.skew[1]:isFinite(e.skew)?e.skew:isFinite(e.skewY)?e.skewY:0,o=e.scale&&e.scale.length?e.scale[0]*r:isFinite(e.scale)?e.scale*r:isFinite(e.scaleX)?e.scaleX*r:r,l=e.scale&&e.scale.length?e.scale[1]*n:isFinite(e.scale)?e.scale*n:isFinite(e.scaleY)?e.scaleY*n:n,h=e.shear||0,d=e.rotate||e.theta||0,c=new it(e.origin||e.around||e.ox||e.originX,e.oy||e.originY),f=c.x,m=c.y,g=new it(e.position||e.px||e.positionX||NaN,e.py||e.positionY||NaN),x=g.x,y=g.y,b=new it(e.translate||e.tx||e.translateX,e.ty||e.translateY),S=b.x,A=b.y,C=new it(e.relative||e.rx||e.relativeX,e.ry||e.relativeY),I=C.x,O=C.y;return{scaleX:o,scaleY:l,skewX:s,skewY:a,shear:h,theta:d,rx:I,ry:O,tx:S,ty:A,ox:f,oy:m,px:x,py:y}}static fromArray(e){return{a:e[0],b:e[1],c:e[2],d:e[3],e:e[4],f:e[5]}}static isMatrixLike(e){return e.a!=null||e.b!=null||e.c!=null||e.d!=null||e.e!=null||e.f!=null}static matrixMultiply(e,t,r){let n=e.a*t.a+e.c*t.b,s=e.b*t.a+e.d*t.b,a=e.a*t.c+e.c*t.d,o=e.b*t.c+e.d*t.d,l=e.e+e.a*t.e+e.c*t.f,h=e.f+e.b*t.e+e.d*t.f;return r.a=n,r.b=s,r.c=a,r.d=o,r.e=l,r.f=h,r}around(e,t,r){return this.clone().aroundO(e,t,r)}aroundO(e,t,r){let n=e||0,s=t||0;return this.translateO(-n,-s).lmultiplyO(r).translateO(n,s)}clone(){return new i(this)}decompose(e=0,t=0){let r=this.a,n=this.b,s=this.c,a=this.d,o=this.e,l=this.f,h=r*a-n*s,d=h>0?1:-1,c=d*Math.sqrt(r*r+n*n),f=Math.atan2(d*n,d*r),m=180/Math.PI*f,g=Math.cos(f),x=Math.sin(f),y=(r*s+n*a)/h,b=s*c/(y*r-n)||a*c/(y*n+r),S=o-e+e*g*c+t*(y*g*c-x*b),A=l-t+e*x*c+t*(y*x*c+g*b);return{scaleX:c,scaleY:b,shear:y,rotate:m,translateX:S,translateY:A,originX:e,originY:t,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}}equals(e){if(e===this)return!0;let t=new i(e);return Vs(this.a,t.a)&&Vs(this.b,t.b)&&Vs(this.c,t.c)&&Vs(this.d,t.d)&&Vs(this.e,t.e)&&Vs(this.f,t.f)}flip(e,t){return this.clone().flipO(e,t)}flipO(e,t){return e==="x"?this.scaleO(-1,1,t,0):e==="y"?this.scaleO(1,-1,0,t):this.scaleO(-1,-1,e,t||e)}init(e){let t=i.fromArray([1,0,0,1,0,0]);return e=e instanceof Ei?e.matrixify():typeof e=="string"?i.fromArray(e.split(Sr).map(parseFloat)):Array.isArray(e)?i.fromArray(e):typeof e=="object"&&i.isMatrixLike(e)?e:typeof e=="object"?new i().transform(e):arguments.length===6?i.fromArray([].slice.call(arguments)):t,this.a=e.a!=null?e.a:t.a,this.b=e.b!=null?e.b:t.b,this.c=e.c!=null?e.c:t.c,this.d=e.d!=null?e.d:t.d,this.e=e.e!=null?e.e:t.e,this.f=e.f!=null?e.f:t.f,this}inverse(){return this.clone().inverseO()}inverseO(){let e=this.a,t=this.b,r=this.c,n=this.d,s=this.e,a=this.f,o=e*n-t*r;if(!o)throw new Error("Cannot invert "+this);let l=n/o,h=-t/o,d=-r/o,c=e/o,f=-(l*s+d*a),m=-(h*s+c*a);return this.a=l,this.b=h,this.c=d,this.d=c,this.e=f,this.f=m,this}lmultiply(e){return this.clone().lmultiplyO(e)}lmultiplyO(e){let t=this,r=e instanceof i?e:new i(e);return i.matrixMultiply(r,t,this)}multiply(e){return this.clone().multiplyO(e)}multiplyO(e){let t=this,r=e instanceof i?e:new i(e);return i.matrixMultiply(t,r,this)}rotate(e,t,r){return this.clone().rotateO(e,t,r)}rotateO(e,t=0,r=0){e=jc(e);let n=Math.cos(e),s=Math.sin(e),{a,b:o,c:l,d:h,e:d,f:c}=this;return this.a=a*n-o*s,this.b=o*n+a*s,this.c=l*n-h*s,this.d=h*n+l*s,this.e=d*n-c*s+r*s-t*n+t,this.f=c*n+d*s-t*s-r*n+r,this}scale(e,t,r,n){return this.clone().scaleO(...arguments)}scaleO(e,t=e,r=0,n=0){arguments.length===3&&(n=r,r=t,t=e);let{a:s,b:a,c:o,d:l,e:h,f:d}=this;return this.a=s*e,this.b=a*t,this.c=o*e,this.d=l*t,this.e=h*e-r*e+r,this.f=d*t-n*t+n,this}shear(e,t,r){return this.clone().shearO(e,t,r)}shearO(e,t=0,r=0){let{a:n,b:s,c:a,d:o,e:l,f:h}=this;return this.a=n+s*e,this.c=a+o*e,this.e=l+h*e-r*e,this}skew(e,t,r,n){return this.clone().skewO(...arguments)}skewO(e,t=e,r=0,n=0){arguments.length===3&&(n=r,r=t,t=e),e=jc(e),t=jc(t);let s=Math.tan(e),a=Math.tan(t),{a:o,b:l,c:h,d,e:c,f}=this;return this.a=o+l*s,this.b=l+o*a,this.c=h+d*s,this.d=d+h*a,this.e=c+f*s-n*s,this.f=f+c*a-r*a,this}skewX(e,t,r){return this.skew(e,0,t,r)}skewY(e,t,r){return this.skew(0,e,t,r)}toArray(){return[this.a,this.b,this.c,this.d,this.e,this.f]}toString(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}transform(e){if(i.isMatrixLike(e))return new i(e).multiplyO(this);let t=i.formatTransforms(e),r=this,{x:n,y:s}=new it(t.ox,t.oy).transform(r),a=new i().translateO(t.rx,t.ry).lmultiplyO(r).translateO(-n,-s).scaleO(t.scaleX,t.scaleY).skewO(t.skewX,t.skewY).shearO(t.shear).rotateO(t.theta).translateO(n,s);if(isFinite(t.px)||isFinite(t.py)){let o=new it(n,s).transform(a),l=isFinite(t.px)?t.px-o.x:0,h=isFinite(t.py)?t.py-o.y:0;a.translateO(l,h)}return a.translateO(t.tx,t.ty),a}translate(e,t){return this.clone().translateO(e,t)}translateO(e,t){return this.e+=e||0,this.f+=t||0,this}valueOf(){return{a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}}};be(xe,"Matrix");Gt=class i{constructor(...e){this.init(...e)}addOffset(){return this.x+=Te.window.pageXOffset,this.y+=Te.window.pageYOffset,new i(this)}init(e){let t=[0,0,0,0];return e=typeof e=="string"?e.split(Sr).map(parseFloat):Array.isArray(e)?e:typeof e=="object"?[e.left!=null?e.left:e.x,e.top!=null?e.top:e.y,e.width,e.height]:arguments.length===4?[].slice.call(arguments):t,this.x=e[0]||0,this.y=e[1]||0,this.width=this.w=e[2]||0,this.height=this.h=e[3]||0,this.x2=this.x+this.w,this.y2=this.y+this.h,this.cx=this.x+this.w/2,this.cy=this.y+this.h/2,this}isNulled(){return G3(this)}merge(e){let t=Math.min(this.x,e.x),r=Math.min(this.y,e.y),n=Math.max(this.x+this.width,e.x+e.width)-t,s=Math.max(this.y+this.height,e.y+e.height)-r;return new i(t,r,n,s)}toArray(){return[this.x,this.y,this.width,this.height]}toString(){return this.x+" "+this.y+" "+this.width+" "+this.height}transform(e){e instanceof xe||(e=new xe(e));let t=1/0,r=-1/0,n=1/0,s=-1/0;return[new it(this.x,this.y),new it(this.x2,this.y),new it(this.x,this.y2),new it(this.x2,this.y2)].forEach(function(o){o=o.transform(e),t=Math.min(t,o.x),r=Math.max(r,o.x),n=Math.min(n,o.y),s=Math.max(s,o.y)}),new i(t,n,r-t,s-n)}};fe({viewbox:{viewbox(i,e,t,r){return i==null?new Gt(this.attr("viewBox")):this.attr("viewBox",new Gt(i,e,t,r))},zoom(i,e){let{width:t,height:r}=this.attr(["width","height"]);if((!t&&!r||typeof t=="string"||typeof r=="string")&&(t=this.node.clientWidth,r=this.node.clientHeight),!t||!r)throw new Error("Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element");let n=this.viewbox(),s=t/n.width,a=r/n.height,o=Math.min(s,a);if(i==null)return o;let l=o/i;l===1/0&&(l=Number.MAX_SAFE_INTEGER/100),e=e||new it(t/2/s+n.x,r/2/a+n.y);let h=new Gt(n).transform(new xe({scale:l,origin:e}));return this.viewbox(h)}}});be(Gt,"Box");Nr=class extends Array{constructor(e=[],...t){if(super(e,...t),typeof e=="number")return this;this.length=0,this.push(...e)}};ge([Nr],{each(i,...e){return typeof i=="function"?this.map((t,r,n)=>i.call(t,t,r,n)):this.map(t=>t[i](...e))},toArray(){return Array.prototype.concat.apply([],this)}});cM=["toArray","constructor","each"];Nr.extend=function(i){i=i.reduce((e,t)=>(cM.includes(t)||t[0]==="_"||(e[t]=function(...r){return this.each(t,...r)}),e),{}),ge([Nr],i)};mM=0,W3={};ts=class extends yo{addEventListener(){}dispatch(e,t,r){return gM(this,e,t,r)}dispatchEvent(e){let t=this.getEventHolder().events;if(!t)return!0;let r=t[e.type];for(let n in r)for(let s in r[n])r[n][s](e);return!e.defaultPrevented}fire(e,t,r){return this.dispatch(e,t,r),this}getEventHolder(){return this}getEventTarget(){return this}off(e,t,r){return Ws(this,e,t,r),this}on(e,t,r,n){return Kc(this,e,t,r,n),this}removeEventListener(){}};be(ts,"EventTarget");go={duration:400,ease:">",delay:0},xM={"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","text-anchor":"start"},hn=class extends Array{constructor(...e){super(...e),this.init(...e)}clone(){return new this.constructor(this)}init(e){return typeof e=="number"?this:(this.length=0,this.push(...this.parse(e)),this)}parse(e=[]){return e instanceof Array?e:e.trim().split(Sr).map(parseFloat)}toArray(){return Array.prototype.concat.apply([],this)}toSet(){return new Set(this)}toString(){return this.join(" ")}valueOf(){let e=[];return e.push(...this),e}},ye=class i{constructor(...e){this.init(...e)}convert(e){return new i(this.value,e)}divide(e){return e=new i(e),new i(this/e,this.unit||e.unit)}init(e,t){return t=Array.isArray(e)?e[1]:t,e=Array.isArray(e)?e[0]:e,this.value=0,this.unit=t||"",typeof e=="number"?this.value=isNaN(e)?0:isFinite(e)?e:e<0?-34e37:34e37:typeof e=="string"?(t=e.match(j3),t&&(this.value=parseFloat(t[1]),t[5]==="%"?this.value/=100:t[5]==="s"&&(this.value*=1e3),this.unit=t[5])):e instanceof i&&(this.value=e.valueOf(),this.unit=e.unit),this}minus(e){return e=new i(e),new i(this-e,this.unit||e.unit)}plus(e){return e=new i(e),new i(this+e,this.unit||e.unit)}times(e){return e=new i(e),new i(this*e,this.unit||e.unit)}toArray(){return[this.value,this.unit]}toJSON(){return this.toString()}toString(){return(this.unit==="%"?~~(this.value*1e8)/1e6:this.unit==="s"?this.value/1e3:this.value)+this.unit}valueOf(){return this.value}},X3=[];dn=class i extends ts{constructor(e,t){super(),this.node=e,this.type=e.nodeName,t&&e!==t&&this.attr(t)}add(e,t){return e=Rt(e),e.removeNamespace&&this.node instanceof Te.window.SVGElement&&e.removeNamespace(),t==null?this.node.appendChild(e.node):e.node!==this.node.childNodes[t]&&this.node.insertBefore(e.node,this.node.childNodes[t]),this}addTo(e,t){return Rt(e).put(this,t)}children(){return new Nr(ru(this.node.children,function(e){return Ti(e)}))}clear(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this}clone(e=!0,t=!0){this.writeDataToDom();let r=this.node.cloneNode(e);return t&&(r=$3(r)),new this.constructor(r)}each(e,t){let r=this.children(),n,s;for(n=0,s=r.length;n=0}html(e,t){return this.xml(e,t,vw)}id(e){return typeof e>"u"&&!this.node.id&&(this.node.id=U3(this.type)),this.attr("id",e)}index(e){return[].slice.call(this.node.childNodes).indexOf(e.node)}last(){return Ti(this.node.lastChild)}matches(e){let t=this.node,r=t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector||null;return r&&r.call(t,e)}parent(e){let t=this;if(!t.node.parentNode)return null;if(t=Ti(t.node.parentNode),!e)return t;do if(typeof e=="string"?t.matches(e):t instanceof e)return t;while(t=Ti(t.node.parentNode));return t}put(e,t){return e=Rt(e),this.add(e,t),e}putIn(e,t){return Rt(e).add(this,t)}remove(){return this.parent()&&this.parent().removeElement(this),this}removeElement(e){return this.node.removeChild(e.node),this}replace(e){return e=Rt(e),this.node.parentNode&&this.node.parentNode.replaceChild(e.node,this.node),e}round(e=2,t=null){let r=10**e,n=this.attr(t);for(let s in n)typeof n[s]=="number"&&(n[s]=Math.round(n[s]*r)/r);return this.attr(n),this}svg(e,t){return this.xml(e,t,nu)}toString(){return this.id()}words(e){return this.node.textContent=e,this}wrap(e){let t=this.parent();if(!t)return this.addTo(e);let r=t.index(this);return t.put(e,r).put(this)}writeDataToDom(){return this.each(function(){this.writeDataToDom()}),this}xml(e,t,r){if(typeof e=="boolean"&&(r=t,t=e,e=null),e==null||typeof e=="function"){t=t??!0,this.writeDataToDom();let o=this;if(e!=null){if(o=Ti(o.node.cloneNode(!0)),t){let l=e(o);if(o=l||o,l===!1)return""}o.each(function(){let l=e(this),h=l||this;l===!1?this.remove():l&&this!==h&&this.replace(h)},!0)}return t?o.node.outerHTML:o.node.innerHTML}t=t??!1;let n=vo("wrapper",r),s=Te.document.createDocumentFragment();n.innerHTML=e;for(let o=n.children.length;o--;)s.appendChild(n.firstElementChild);let a=this.parent();return t?this.replace(s)&&a:this.add(s)}};ge(dn,{attr:vM,find:uM,findOne:fM});be(dn,"Dom");Ei=class extends dn{constructor(e,t){super(e,t),this.dom={},this.node.instance=this,e.hasAttribute("svgjs:data")&&this.setData(JSON.parse(e.getAttribute("svgjs:data"))||{})}center(e,t){return this.cx(e).cy(t)}cx(e){return e==null?this.x()+this.width()/2:this.x(e-this.width()/2)}cy(e){return e==null?this.y()+this.height()/2:this.y(e-this.height()/2)}defs(){let e=this.root();return e&&e.defs()}dmove(e,t){return this.dx(e).dy(t)}dx(e=0){return this.x(new ye(e).plus(this.x()))}dy(e=0){return this.y(new ye(e).plus(this.y()))}getEventHolder(){return this}height(e){return this.attr("height",e)}move(e,t){return this.x(e).y(t)}parents(e=this.root()){let t=typeof e=="string";t||(e=Rt(e));let r=new Nr,n=this;for(;(n=n.parent())&&n.node!==Te.document&&n.nodeName!=="#document-fragment"&&(r.push(n),!(!t&&n.node===e.node||t&&n.matches(e)));)if(n.node===this.root().node)return null;return r}reference(e){if(e=this.attr(e),!e)return null;let t=(e+"").match(Bw);return t?Rt(t[1]):null}root(){let e=this.parent(ww(su));return e&&e.root()}setData(e){return this.dom=e,this}size(e,t){let r=ta(this,e,t);return this.width(new ye(r.width)).height(new ye(r.height))}width(e){return this.attr("width",e)}writeDataToDom(){return this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),super.writeDataToDom()}x(e){return this.attr("x",e)}y(e){return this.attr("y",e)}};ge(Ei,{bbox:lM,rbox:hM,inside:dM,point:nM,ctm:sM,screenCTM:aM});be(Ei,"Element");po={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(i,e){return e==="color"?i:i+"-"+e}};["fill","stroke"].forEach(function(i){let e={},t;e[i]=function(r){if(typeof r>"u")return this.attr(i);if(typeof r=="string"||r instanceof Ni||Ni.isRgb(r)||r instanceof Ei)this.attr(i,r);else for(t=po[i].length-1;t>=0;t--)r[po[i][t]]!=null&&this.attr(po.prefix(i,po[i][t]),r[po[i][t]]);return this},fe(["Element","Runner"],e)});fe(["Element","Runner"],{matrix:function(i,e,t,r,n,s){return i==null?new xe(this):this.attr("transform",new xe(i,e,t,r,n,s))},rotate:function(i,e,t){return this.transform({rotate:i,ox:e,oy:t},!0)},skew:function(i,e,t,r){return arguments.length===1||arguments.length===3?this.transform({skew:i,ox:e,oy:t},!0):this.transform({skew:[i,e],ox:t,oy:r},!0)},shear:function(i,e,t){return this.transform({shear:i,ox:e,oy:t},!0)},scale:function(i,e,t,r){return arguments.length===1||arguments.length===3?this.transform({scale:i,ox:e,oy:t},!0):this.transform({scale:[i,e],ox:t,oy:r},!0)},translate:function(i,e){return this.transform({translate:[i,e]},!0)},relative:function(i,e){return this.transform({relative:[i,e]},!0)},flip:function(i="both",e="center"){return"xybothtrue".indexOf(i)===-1&&(e=i,i="both"),this.transform({flip:i,origin:e},!0)},opacity:function(i){return this.attr("opacity",i)}});fe("radius",{radius:function(i,e=i){return(this._element||this).type==="radialGradient"?this.attr("r",new ye(i)):this.rx(i).ry(e)}});fe("Path",{length:function(){return this.node.getTotalLength()},pointAt:function(i){return new it(this.node.getPointAtLength(i))}});fe(["Element","Runner"],{font:function(i,e){if(typeof i=="object"){for(e in i)this.font(e,i[e]);return this}return i==="leading"?this.leading(e):i==="anchor"?this.attr("text-anchor",e):i==="size"||i==="family"||i==="weight"||i==="stretch"||i==="variant"||i==="style"?this.attr("font-"+i,e):this.attr(i,e)}});bM=["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].reduce(function(i,e){let t=function(r){return r===null?this.off(e):this.on(e,r),this};return i[e]=t,i},{});fe("Element",bM);fe("Element",{untransform:wM,matrixify:MM,toParent:TM,toRoot:NM,transform:EM});Vt=class i extends Ei{flatten(e=this,t){return this.each(function(){if(this instanceof i)return this.flatten().ungroup()}),this}ungroup(e=this.parent(),t=e.index(this)){return t=t===-1?e.children().length:t,this.each(function(r,n){return n[n.length-r-1].toParent(e,t)}),this.remove()}};be(Vt,"Container");bo=class extends Vt{constructor(e,t=e){super(qe("defs",e),t)}flatten(){return this}ungroup(){return this}};be(bo,"Defs");Dt=class extends Ei{};be(Dt,"Shape");SM={__proto__:null,rx:lu,ry:hu,x:K3,y:Z3,cx:Q3,cy:J3,width:e2,height:t2},Xs=class extends Dt{constructor(e,t=e){super(qe("ellipse",e),t)}size(e,t){let r=ta(this,e,t);return this.rx(new ye(r.width).divide(2)).ry(new ye(r.height).divide(2))}};ge(Xs,SM);fe("Container",{ellipse:Fe(function(i=0,e=i){return this.put(new Xs).size(i,e).move(0,0)})});be(Xs,"Ellipse");L0=class extends dn{constructor(e=Te.document.createDocumentFragment()){super(e)}xml(e,t,r){if(typeof e=="boolean"&&(r=t,t=e,e=null),e==null||typeof e=="function"){let n=new dn(vo("wrapper",r));return n.add(this.node.cloneNode(!0)),n.xml(!1,r)}return super.xml(e,!1,r)}};be(L0,"Fragment");AM={__proto__:null,from:i2,to:r2},is=class extends Vt{constructor(e,t){super(qe(e+"Gradient",typeof e=="string"?null:e),t)}attr(e,t,r){return e==="transform"&&(e="gradientTransform"),super.attr(e,t,r)}bbox(){return new Gt}targets(){return ia("svg [fill*="+this.id()+"]")}toString(){return this.url()}update(e){return this.clear(),typeof e=="function"&&e.call(this,this),this}url(){return"url(#"+this.id()+")"}};ge(is,AM);fe({Container:{gradient(...i){return this.defs().gradient(...i)}},Defs:{gradient:Fe(function(i,e){return this.put(new is(i)).update(e)})}});be(is,"Gradient");rs=class extends Vt{constructor(e,t=e){super(qe("pattern",e),t)}attr(e,t,r){return e==="transform"&&(e="patternTransform"),super.attr(e,t,r)}bbox(){return new Gt}targets(){return ia("svg [fill*="+this.id()+"]")}toString(){return this.url()}update(e){return this.clear(),typeof e=="function"&&e.call(this,this),this}url(){return"url(#"+this.id()+")"}};fe({Container:{pattern(...i){return this.defs().pattern(...i)}},Defs:{pattern:Fe(function(i,e,t){return this.put(new rs).update(t).attr({x:0,y:0,width:i,height:e,patternUnits:"userSpaceOnUse"})})}});be(rs,"Pattern");ji=class extends Dt{constructor(e,t=e){super(qe("image",e),t)}load(e,t){if(!e)return this;let r=new Te.window.Image;return Kc(r,"load",function(n){let s=this.parent(rs);this.width()===0&&this.height()===0&&this.size(r.width,r.height),s instanceof rs&&s.width()===0&&s.height()===0&&s.size(this.width(),this.height()),typeof t=="function"&&t.call(this,n)},this),Kc(r,"load error",function(){Ws(r)}),this.attr("href",r.src=e,Lo)}};yM(function(i,e,t){return(i==="fill"||i==="stroke")&&qw.test(e)&&(e=t.root().defs().image(e)),e instanceof ji&&(e=t.root().defs().pattern(0,0,r=>{r.add(e)})),e});fe({Container:{image:Fe(function(i,e){return this.put(new ji).size(0,0).load(i,e)})}});be(ji,"Image");sr=class extends hn{bbox(){let e=-1/0,t=-1/0,r=1/0,n=1/0;return this.forEach(function(s){e=Math.max(s[0],e),t=Math.max(s[1],t),r=Math.min(s[0],r),n=Math.min(s[1],n)}),new Gt(r,n,e-r,t-n)}move(e,t){let r=this.bbox();if(e-=r.x,t-=r.y,!isNaN(e)&&!isNaN(t))for(let n=this.length-1;n>=0;n--)this[n]=[this[n][0]+e,this[n][1]+t];return this}parse(e=[0,0]){let t=[];e instanceof Array?e=Array.prototype.concat.apply([],e):e=e.trim().split(Sr).map(parseFloat),e.length%2!==0&&e.pop();for(let r=0,n=e.length;r=0;r--)n.width&&(this[r][0]=(this[r][0]-n.x)*e/n.width+n.x),n.height&&(this[r][1]=(this[r][1]-n.y)*t/n.height+n.y);return this}toLine(){return{x1:this[0][0],y1:this[0][1],x2:this[1][0],y2:this[1][1]}}toString(){let e=[];for(let t=0,r=this.length;t":function(i){return-Math.cos(i*Math.PI)/2+.5},">":function(i){return Math.sin(i*Math.PI/2)},"<":function(i){return-Math.cos(i*Math.PI/2)+1},bezier:function(i,e,t,r){return function(n){return n<0?i>0?e/i*n:t>0?r/t*n:0:n>1?t<1?(1-r)/(1-t)*n+(r-t)/(1-t):i<1?(1-e)/(1-i)*n+(e-i)/(1-i):1:3*n*(1-n)**2*e+3*n**2*(1-n)*r+n**3}},steps:function(i,e="end"){e=e.split("-").reverse()[0];let t=i;return e==="none"?--t:e==="both"&&++t,(r,n=!1)=>{let s=Math.floor(r*i),a=r*s%1===0;return(e==="start"||e==="both")&&++s,n&&a&&--s,r>=0&&s<0&&(s=0),r<=1&&s>t&&(s=t),s/t}}},wo=class{done(){return!1}},Mo=class extends wo{constructor(e=go.ease){super(),this.ease=zM[e]||e}step(e,t,r){return typeof e!="number"?r<1?e:t:e+(t-e)*this.ease(r)}},Zs=class extends wo{constructor(e){super(),this.stepper=e}done(e){return e.done}step(e,t,r,n){return this.stepper(e,t,r,n)}};Zc=class extends Zs{constructor(e=500,t=0){super(),this.duration(e).overshoot(t)}step(e,t,r,n){if(typeof e=="string")return e;if(n.done=r===1/0,r===1/0)return t;if(r===0)return e;r>100&&(r=16),r/=1e3;let s=n.velocity||0,a=-this.d*s-this.k*(e-t),o=e+s*r+a*r*r/2;return n.velocity=s+a*r,n.done=Math.abs(t-o)+Math.abs(s)<.002,n.done?t:o}};ge(Zc,{duration:Ys("_duration",P3),overshoot:Ys("_overshoot",P3)});Qc=class extends Zs{constructor(e=.1,t=.01,r=0,n=1e3){super(),this.p(e).i(t).d(r).windup(n)}step(e,t,r,n){if(typeof e=="string")return e;if(n.done=r===1/0,r===1/0)return t;if(r===0)return e;let s=t-e,a=(n.integral||0)+s*r,o=(s-(n.error||0))/r,l=this._windup;return l!==!1&&(a=Math.max(-l,Math.min(a,l))),n.error=s,n.integral=a,n.done=Math.abs(s)<.001,n.done?t:e+(this.P*s+this.I*a+this.D*o)}};ge(Qc,{windup:Ys("_windup"),p:Ys("P"),i:Ys("I"),d:Ys("D")});RM={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0},Jc={M:function(i,e,t){return e.x=t.x=i[0],e.y=t.y=i[1],["M",e.x,e.y]},L:function(i,e){return e.x=i[0],e.y=i[1],["L",i[0],i[1]]},H:function(i,e){return e.x=i[0],["H",i[0]]},V:function(i,e){return e.y=i[0],["V",i[0]]},C:function(i,e){return e.x=i[4],e.y=i[5],["C",i[0],i[1],i[2],i[3],i[4],i[5]]},S:function(i,e){return e.x=i[2],e.y=i[3],["S",i[0],i[1],i[2],i[3]]},Q:function(i,e){return e.x=i[2],e.y=i[3],["Q",i[0],i[1],i[2],i[3]]},T:function(i,e){return e.x=i[0],e.y=i[1],["T",i[0],i[1]]},Z:function(i,e,t){return e.x=t.x,e.y=t.y,["Z"]},A:function(i,e){return e.x=i[5],e.y=i[6],["A",i[0],i[1],i[2],i[3],i[4],i[5],i[6]]}},Wc="mlhvqtcsaz".split("");for(let i=0,e=Wc.length;i=0;s--)n=this[s][0],n==="M"||n==="L"||n==="T"?(this[s][1]+=e,this[s][2]+=t):n==="H"?this[s][1]+=e:n==="V"?this[s][1]+=t:n==="C"||n==="S"||n==="Q"?(this[s][1]+=e,this[s][2]+=t,this[s][3]+=e,this[s][4]+=t,n==="C"&&(this[s][5]+=e,this[s][6]+=t)):n==="A"&&(this[s][6]+=e,this[s][7]+=t);return this}parse(e="M0 0"){return Array.isArray(e)&&(e=Array.prototype.concat.apply([],e).toString()),FM(e)}size(e,t){let r=this.bbox(),n,s;for(r.width=r.width===0?1:r.width,r.height=r.height===0?1:r.height,n=this.length-1;n>=0;n--)s=this[n][0],s==="M"||s==="L"||s==="T"?(this[n][1]=(this[n][1]-r.x)*e/r.width+r.x,this[n][2]=(this[n][2]-r.y)*t/r.height+r.y):s==="H"?this[n][1]=(this[n][1]-r.x)*e/r.width+r.x:s==="V"?this[n][1]=(this[n][1]-r.y)*t/r.height+r.y:s==="C"||s==="S"||s==="Q"?(this[n][1]=(this[n][1]-r.x)*e/r.width+r.x,this[n][2]=(this[n][2]-r.y)*t/r.height+r.y,this[n][3]=(this[n][3]-r.x)*e/r.width+r.x,this[n][4]=(this[n][4]-r.y)*t/r.height+r.y,s==="C"&&(this[n][5]=(this[n][5]-r.x)*e/r.width+r.x,this[n][6]=(this[n][6]-r.y)*t/r.height+r.y)):s==="A"&&(this[n][1]=this[n][1]*e/r.width,this[n][2]=this[n][2]*t/r.height,this[n][6]=(this[n][6]-r.x)*e/r.width+r.x,this[n][7]=(this[n][7]-r.y)*t/r.height+r.y);return this}toString(){return qM(this)}},n2=i=>{let e=typeof i;return e==="number"?ye:e==="string"?Ni.isColor(i)?Ni:Sr.test(i)?au.test(i)?Er:hn:j3.test(i)?ye:To:cu.indexOf(i.constructor)>-1?i.constructor:Array.isArray(i)?hn:e==="object"?ss:To},Tr=class{constructor(e){this._stepper=e||new Mo("-"),this._from=null,this._to=null,this._type=null,this._context=null,this._morphObj=null}at(e){return this._morphObj.morph(this._from,this._to,e,this._stepper,this._context)}done(){return this._context.map(this._stepper.done).reduce(function(t,r){return t&&r},!0)}from(e){return e==null?this._from:(this._from=this._set(e),this)}stepper(e){return e==null?this._stepper:(this._stepper=e,this)}to(e){return e==null?this._to:(this._to=this._set(e),this)}type(e){return e==null?this._type:(this._type=e,this)}_set(e){this._type||this.type(n2(e));let t=new this._type(e);return this._type===Ni&&(t=this._to?t[this._to[4]]():this._from?t[this._from[4]]():t),this._type===ss&&(t=this._to?t.align(this._to):this._from?t.align(this._from):t),t=t.toConsumable(),this._morphObj=this._morphObj||new this._type,this._context=this._context||Array.apply(null,Array(t.length)).map(Object).map(function(r){return r.done=!0,r}),t}},To=class{constructor(...e){this.init(...e)}init(e){return e=Array.isArray(e)?e[0]:e,this.value=e,this}toArray(){return[this.value]}valueOf(){return this.value}},No=class i{constructor(...e){this.init(...e)}init(e){return Array.isArray(e)&&(e={scaleX:e[0],scaleY:e[1],shear:e[2],rotate:e[3],translateX:e[4],translateY:e[5],originX:e[6],originY:e[7]}),Object.assign(this,i.defaults,e),this}toArray(){let e=this;return[e.scaleX,e.scaleY,e.shear,e.rotate,e.translateX,e.translateY,e.originX,e.originY]}};No.defaults={scaleX:1,scaleY:1,shear:0,rotate:0,translateX:0,translateY:0,originX:0,originY:0};HM=(i,e)=>i[0]e[0]?1:0,ss=class{constructor(...e){this.init(...e)}align(e){let t=this.values;for(let r=0,n=t.length;rr.concat(n),[]),this}toArray(){return this.values}valueOf(){let e={},t=this.values;for(;t.length;){let r=t.shift(),n=t.shift(),s=t.shift(),a=t.splice(0,s);e[r]=new n(a)}return e}},cu=[To,No,ss];ar=class extends Dt{constructor(e,t=e){super(qe("path",e),t)}array(){return this._array||(this._array=new Er(this.attr("d")))}clear(){return delete this._array,this}height(e){return e==null?this.bbox().height:this.size(this.bbox().width,e)}move(e,t){return this.attr("d",this.array().move(e,t))}plot(e){return e==null?this.array():this.clear().attr("d",typeof e=="string"?e:this._array=new Er(e))}size(e,t){let r=ta(this,e,t);return this.attr("d",this.array().size(r.width,r.height))}width(e){return e==null?this.bbox().width:this.size(e,this.bbox().height)}x(e){return e==null?this.bbox().x:this.move(e,this.bbox().y)}y(e){return e==null?this.bbox().y:this.move(this.bbox().x,e)}};ar.prototype.MorphArray=Er;fe({Container:{path:Fe(function(i){return this.put(new ar).plot(i||new Er)})}});be(ar,"Path");s2={__proto__:null,array:jM,clear:GM,move:VM,plot:WM,size:YM},Gi=class extends Dt{constructor(e,t=e){super(qe("polygon",e),t)}};fe({Container:{polygon:Fe(function(i){return this.put(new Gi).plot(i||new sr)})}});ge(Gi,du);ge(Gi,s2);be(Gi,"Polygon");as=class extends Dt{constructor(e,t=e){super(qe("polyline",e),t)}};fe({Container:{polyline:Fe(function(i){return this.put(new as).plot(i||new sr)})}});ge(as,du);ge(as,s2);be(as,"Polyline");Ve=class extends Dt{constructor(e,t=e){super(qe("rect",e),t)}};ge(Ve,{rx:lu,ry:hu});fe({Container:{rect:Fe(function(i,e){return this.put(new Ve).size(i,e)})}});be(Ve,"Rect");xo=class{constructor(){this._first=null,this._last=null}first(){return this._first&&this._first.value}last(){return this._last&&this._last.value}push(e){let t=typeof e.next<"u"?e:{value:e,next:null,prev:null};return this._last?(t.prev=this._last,this._last.next=t,this._last=t):(this._last=t,this._first=t),t}remove(e){e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e===this._last&&(this._last=e.prev),e===this._first&&(this._first=e.next),e.prev=null,e.next=null}shift(){let e=this._first;return e?(this._first=e.next,this._first&&(this._first.prev=null),this._last=this._first?this._last:null,e.value):null}},Se={nextDraw:null,frames:new xo,timeouts:new xo,immediates:new xo,timer:()=>Te.window.performance||Te.window.Date,transforms:[],frame(i){let e=Se.frames.push({run:i});return Se.nextDraw===null&&(Se.nextDraw=Te.window.requestAnimationFrame(Se._draw)),e},timeout(i,e){e=e||0;let t=Se.timer().now()+e,r=Se.timeouts.push({run:i,time:t});return Se.nextDraw===null&&(Se.nextDraw=Te.window.requestAnimationFrame(Se._draw)),r},immediate(i){let e=Se.immediates.push(i);return Se.nextDraw===null&&(Se.nextDraw=Te.window.requestAnimationFrame(Se._draw)),e},cancelFrame(i){i!=null&&Se.frames.remove(i)},clearTimeout(i){i!=null&&Se.timeouts.remove(i)},cancelImmediate(i){i!=null&&Se.immediates.remove(i)},_draw(i){let e=null,t=Se.timeouts.last();for(;(e=Se.timeouts.shift())&&(i>=e.time?e.run():Se.timeouts.push(e),e!==t););let r=null,n=Se.frames.last();for(;r!==n&&(r=Se.frames.shift());)r.run(i);let s=null;for(;s=Se.immediates.shift();)s();Se.nextDraw=Se.timeouts.first()||Se.frames.first()?Te.window.requestAnimationFrame(Se._draw):null}},XM=function(i){let e=i.start,t=i.runner.duration(),r=e+t;return{start:e,duration:t,end:r,runner:i.runner}},KM=function(){let i=Te.window;return(i.performance||i.Date).now()},I0=class extends ts{constructor(e=KM){super(),this._timeSource=e,this._startTime=0,this._speed=1,this._persist=0,this._nextFrame=null,this._paused=!0,this._runners=[],this._runnerIds=[],this._lastRunnerId=-1,this._time=0,this._lastSourceTime=0,this._lastStepTime=0,this._step=this._stepFn.bind(this,!1),this._stepImmediate=this._stepFn.bind(this,!0)}active(){return!!this._nextFrame}finish(){return this.time(this.getEndTimeOfTimeline()+1),this.pause()}getEndTime(){let e=this.getLastRunnerInfo(),t=e?e.runner.duration():0;return(e?e.start:this._time)+t}getEndTimeOfTimeline(){let e=this._runners.map(t=>t.start+t.runner.duration());return Math.max(0,...e)}getLastRunnerInfo(){return this.getRunnerInfoById(this._lastRunnerId)}getRunnerInfoById(e){return this._runners[this._runnerIds.indexOf(e)]||null}pause(){return this._paused=!0,this._continue()}persist(e){return e==null?this._persist:(this._persist=e,this)}play(){return this._paused=!1,this.updateTime()._continue()}reverse(e){let t=this.speed();if(e==null)return this.speed(-t);let r=Math.abs(t);return this.speed(e?-r:r)}schedule(e,t,r){if(e==null)return this._runners.map(XM);let n=0,s=this.getEndTime();if(t=t||0,r==null||r==="last"||r==="after")n=s;else if(r==="absolute"||r==="start")n=t,t=0;else if(r==="now")n=this._time;else if(r==="relative"){let l=this.getRunnerInfoById(e.id);l&&(n=l.start+t,t=0)}else if(r==="with-last"){let l=this.getLastRunnerInfo();n=l?l.start:this._time}else throw new Error('Invalid value for the "when" parameter');e.unschedule(),e.timeline(this);let a=e.persist(),o={persist:a===null?this._persist:a,start:n+t,runner:e};return this._lastRunnerId=e.id,this._runners.push(o),this._runners.sort((l,h)=>l.start-h.start),this._runnerIds=this._runners.map(l=>l.runner.id),this.updateTime()._continue(),this}seek(e){return this.time(this._time+e)}source(e){return e==null?this._timeSource:(this._timeSource=e,this)}speed(e){return e==null?this._speed:(this._speed=e,this)}stop(){return this.time(0),this.pause()}time(e){return e==null?this._time:(this._time=e,this._continue(!0))}unschedule(e){let t=this._runnerIds.indexOf(e.id);return t<0?this:(this._runners.splice(t,1),this._runnerIds.splice(t,1),e.timeline(null),this)}updateTime(){return this.active()||(this._lastSourceTime=this._timeSource()),this}_continue(e=!1){return Se.cancelFrame(this._nextFrame),this._nextFrame=null,e?this._stepImmediate():this._paused?this:(this._nextFrame=Se.frame(this._step),this)}_stepFn(e=!1){let t=this._timeSource(),r=t-this._lastSourceTime;e&&(r=0);let n=this._speed*r+(this._time-this._lastStepTime);this._lastSourceTime=t,e||(this._time+=n,this._time=this._time<0?0:this._time),this._lastStepTime=this._time,this.fire("time",this._time);for(let a=this._runners.length;a--;){let o=this._runners[a],l=o.runner;this._time-o.start<=0&&l.reset()}let s=!1;for(let a=0,o=this._runners.length;a0?this._continue():(this.pause(),this.fire("finished")),this}};fe({Element:{timeline:function(i){return i==null?(this._timeline=this._timeline||new I0,this._timeline):(this._timeline=i,this)}}});Vi=class i extends ts{constructor(e){super(),this.id=i.id++,e=e??go.duration,e=typeof e=="function"?new Zs(e):e,this._element=null,this._timeline=null,this.done=!1,this._queue=[],this._duration=typeof e=="number"&&e,this._isDeclarative=e instanceof Zs,this._stepper=this._isDeclarative?e:new Mo,this._history={},this.enabled=!0,this._time=0,this._lastTime=0,this._reseted=!0,this.transforms=new xe,this.transformId=1,this._haveReversed=!1,this._reverse=!1,this._loopsDone=0,this._swing=!1,this._wait=0,this._times=1,this._frameId=null,this._persist=this._isDeclarative?!0:null}static sanitise(e,t,r){let n=1,s=!1,a=0;return e=e||go.duration,t=t||go.delay,r=r||"last",typeof e=="object"&&!(e instanceof wo)&&(t=e.delay||t,r=e.when||r,s=e.swing||s,n=e.times||n,a=e.wait||a,e=e.duration||go.duration),{duration:e,delay:t,swing:s,times:n,wait:a,when:r}}active(e){return e==null?this.enabled:(this.enabled=e,this)}addTransform(e,t){return this.transforms.lmultiplyO(e),this}after(e){return this.on("finished",e)}animate(e,t,r){let n=i.sanitise(e,t,r),s=new i(n.duration);return this._timeline&&s.timeline(this._timeline),this._element&&s.element(this._element),s.loop(n).schedule(n.delay,n.when)}clearTransform(){return this.transforms=new xe,this}clearTransformsFromQueue(){(!this.done||!this._timeline||!this._timeline._runnerIds.includes(this.id))&&(this._queue=this._queue.filter(e=>!e.isTransform))}delay(e){return this.animate(0,e)}duration(){return this._times*(this._wait+this._duration)-this._wait}during(e){return this.queue(null,e)}ease(e){return this._stepper=new Mo(e),this}element(e){return e==null?this._element:(this._element=e,e._prepareRunner(),this)}finish(){return this.step(1/0)}loop(e,t,r){return typeof e=="object"&&(t=e.swing,r=e.wait,e=e.times),this._times=e||1/0,this._swing=t||!1,this._wait=r||0,this._times===!0&&(this._times=1/0),this}loops(e){let t=this._duration+this._wait;if(e==null){let a=Math.floor(this._time/t),l=(this._time-a*t)/this._duration;return Math.min(a+l,this._times)}let r=Math.floor(e),n=e%1,s=t*r+this._duration*n;return this.time(s)}persist(e){return e==null?this._persist:(this._persist=e,this)}position(e){let t=this._time,r=this._duration,n=this._wait,s=this._times,a=this._swing,o=this._reverse,l;if(e==null){let f=function(g){let x=a*Math.floor(g%(2*(n+r))/(n+r)),y=x&&!o||!x&&o,b=Math.pow(-1,y)*(g%(n+r))/r+y;return Math.max(Math.min(b,1),0)},m=s*(n+r)-n;return l=t<=0?Math.round(f(1e-5)):t=0;this._lastPosition=t;let n=this.duration(),s=this._lastTime<=0&&this._time>0,a=this._lastTime=n;this._lastTime=this._time,s&&this.fire("start",this);let o=this._isDeclarative;this.done=!o&&!a&&this._time>=n,this._reseted=!1;let l=!1;return(r||o)&&(this._initialise(r),this.transforms=new xe,l=this._run(o?e:t),this.fire("step",this)),this.done=this.done||l&&o,a&&this.fire("finished",this),this}time(e){if(e==null)return this._time;let t=e-this._time;return this.step(t),this}timeline(e){return typeof e>"u"?this._timeline:(this._timeline=e,this)}unschedule(){let e=this.timeline();return e&&e.unschedule(this),this}_initialise(e){if(!(!e&&!this._isDeclarative))for(let t=0,r=this._queue.length;ti.lmultiplyO(e),o2=i=>i.transforms;iu=class{constructor(){this.runners=[],this.ids=[]}add(e){if(this.runners.includes(e))return;let t=e.id+1;return this.runners.push(e),this.ids.push(t),this}clearBefore(e){let t=this.ids.indexOf(e+1)||1;return this.ids.splice(0,t,0),this.runners.splice(0,t,new Qs).forEach(r=>r.clearTransformsFromQueue()),this}edit(e,t){let r=this.ids.indexOf(e+1);return this.ids.splice(r,1,e+1),this.runners.splice(r,1,t),this}getByID(e){return this.runners[this.ids.indexOf(e+1)]}length(){return this.ids.length}merge(){let e=null;for(let t=0;te.id<=i.id).map(o2).reduce(a2,new xe)},_addRunner(i){this._transformationRunners.add(i),Se.cancelImmediate(this._frameId),this._frameId=Se.immediate(ZM.bind(this))},_prepareRunner(){this._frameId==null&&(this._transformationRunners=new iu().add(new Qs(new xe(this))))}}});QM=(i,e)=>i.filter(t=>!e.includes(t));ge(Vi,{attr(i,e){return this.styleAttr("attr",i,e)},css(i,e){return this.styleAttr("css",i,e)},styleAttr(i,e,t){if(typeof e=="string")return this.styleAttr(i,{[e]:t});let r=e;if(this._tryRetarget(i,r))return this;let n=new Tr(this._stepper).to(r),s=Object.keys(r);return this.queue(function(){n=n.from(this.element()[i](s))},function(a){return this.element()[i](n.at(a).valueOf()),n.done()},function(a){let o=Object.keys(a),l=QM(o,s);if(l.length){let d=this.element()[i](l),c=new ss(n.from()).valueOf();Object.assign(c,d),n.from(c)}let h=new ss(n.to()).valueOf();Object.assign(h,a),n.to(h),s=o,r=a}),this._rememberMorpher(i,n),this},zoom(i,e){if(this._tryRetarget("zoom",i,e))return this;let t=new Tr(this._stepper).to(new ye(i));return this.queue(function(){t=t.from(this.element().zoom())},function(r){return this.element().zoom(t.at(r),e),t.done()},function(r,n){e=n,t.to(r)}),this._rememberMorpher("zoom",t),this},transform(i,e,t){if(e=i.relative||e,this._isDeclarative&&!e&&this._tryRetarget("transform",i))return this;let r=xe.isMatrixLike(i);t=i.affine!=null?i.affine:t??!r;let n=new Tr(this._stepper).type(t?No:xe),s,a,o,l,h;function d(){a=a||this.element(),s=s||Xc(i,a),h=new xe(e?void 0:a),a._addRunner(this),e||a._clearTransformRunnersBefore(this)}function c(m){e||this.clearTransform();let{x:g,y:x}=new it(s).transform(a._currentTransform(this)),y=new xe({...i,origin:[g,x]}),b=this._isDeclarative&&o?o:h;if(t){y=y.decompose(g,x),b=b.decompose(g,x);let A=y.rotate,C=b.rotate,I=[A-360,A,A+360],O=I.map(W=>Math.abs(W-C)),q=Math.min(...O),P=O.indexOf(q);y.rotate=I[P]}e&&(r||(y.rotate=i.rotate||0),this._isDeclarative&&l&&(b.rotate=l)),n.from(b),n.to(y);let S=n.at(m);return l=S.rotate,o=new xe(S),this.addTransform(o),a._addRunner(this),n.done()}function f(m){(m.origin||"center").toString()!==(i.origin||"center").toString()&&(s=Xc(m,a)),i={...m,origin:s}}return this.queue(d,c,f,!0),this._isDeclarative&&this._rememberMorpher("transform",n),this},x(i,e){return this._queueNumber("x",i)},y(i){return this._queueNumber("y",i)},dx(i=0){return this._queueNumberDelta("x",i)},dy(i=0){return this._queueNumberDelta("y",i)},dmove(i,e){return this.dx(i).dy(e)},_queueNumberDelta(i,e){if(e=new ye(e),this._tryRetarget(i,e))return this;let t=new Tr(this._stepper).to(e),r=null;return this.queue(function(){r=this.element()[i](),t.from(r),t.to(r+e)},function(n){return this.element()[i](t.at(n)),t.done()},function(n){t.to(r+new ye(n))}),this._rememberMorpher(i,t),this},_queueObject(i,e){if(this._tryRetarget(i,e))return this;let t=new Tr(this._stepper).to(e);return this.queue(function(){t.from(this.element()[i]())},function(r){return this.element()[i](t.at(r)),t.done()}),this._rememberMorpher(i,t),this},_queueNumber(i,e){return this._queueObject(i,new ye(e))},cx(i){return this._queueNumber("cx",i)},cy(i){return this._queueNumber("cy",i)},move(i,e){return this.x(i).y(e)},center(i,e){return this.cx(i).cy(e)},size(i,e){let t;return(!i||!e)&&(t=this._element.bbox()),i||(i=t.width/t.height*e),e||(e=t.height/t.width*i),this.width(i).height(e)},width(i){return this._queueNumber("width",i)},height(i){return this._queueNumber("height",i)},plot(i,e,t,r){if(arguments.length===4)return this.plot([i,e,t,r]);if(this._tryRetarget("plot",i))return this;let n=new Tr(this._stepper).type(this._element.MorphArray).to(i);return this.queue(function(){n.from(this._element.array())},function(s){return this._element.plot(n.at(s)),n.done()}),this._rememberMorpher("plot",n),this},leading(i){return this._queueNumber("leading",i)},viewbox(i,e,t,r){return this._queueObject("viewbox",new Gt(i,e,t,r))},update(i){return typeof i!="object"?this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]}):(i.opacity!=null&&this.attr("stop-opacity",i.opacity),i.color!=null&&this.attr("stop-color",i.color),i.offset!=null&&this.attr("offset",i.offset),this)}});ge(Vi,{rx:lu,ry:hu,from:i2,to:r2});be(Vi,"Runner");Eo=class extends Vt{constructor(e,t=e){super(qe("svg",e),t),this.namespace()}defs(){return this.isRoot()?Ti(this.node.querySelector("defs"))||this.put(new bo):this.root().defs()}isRoot(){return!this.node.parentNode||!(this.node.parentNode instanceof Te.window.SVGElement)&&this.node.parentNode.nodeName!=="#document-fragment"}namespace(){return this.isRoot()?this.attr({xmlns:nu,version:"1.1"}).attr("xmlns:xlink",Lo,_0).attr("xmlns:svgjs",bw,_0):this.root().namespace()}removeNamespace(){return this.attr({xmlns:null,version:null}).attr("xmlns:xlink",null,_0).attr("xmlns:svgjs",null,_0)}root(){return this.isRoot()?this:super.root()}};fe({Container:{nested:Fe(function(){return this.put(new Eo)})}});be(Eo,"Svg",!0);So=class extends Vt{constructor(e,t=e){super(qe("symbol",e),t)}};fe({Container:{symbol:Fe(function(){return this.put(new So)})}});be(So,"Symbol");l2={__proto__:null,plain:JM,length:eT,x:tT,y:iT,move:rT,cx:nT,cy:sT,center:aT,ax:oT,ay:lT,amove:hT,build:dT},Ce=class extends Dt{constructor(e,t=e){super(qe("text",e),t),this.dom.leading=new ye(1.3),this._rebuild=!0,this._build=!1}leading(e){return e==null?this.dom.leading:(this.dom.leading=new ye(e),this.rebuild())}rebuild(e){if(typeof e=="boolean"&&(this._rebuild=e),this._rebuild){let t=this,r=0,n=this.dom.leading;this.each(function(s){let a=Te.window.getComputedStyle(this.node).getPropertyValue("font-size"),o=n*new ye(a);this.dom.newLined&&(this.attr("x",t.attr("x")),this.text()===` -`?r+=o:(this.attr("dy",s?o+r:0),r=0))}),this.fire("rebuild")}return this}setData(e){return this.dom=e,this.dom.leading=new ye(e.leading||1.3),this}text(e){if(e===void 0){let t=this.node.childNodes,r=0;e="";for(let n=0,s=t.length;n{bo.prototype.init_genrand=function(i){for(this.mt[0]=i>>>0,this.mti=1;this.mti>>30,this.mt[this.mti]=(((i&4294901760)>>>16)*1812433253<<16)+(i&65535)*1812433253+this.mti,this.mt[this.mti]>>>=0};bo.prototype.genrand_int32=function(){var i,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var t;for(this.mti==this.N+1&&this.init_genrand(5489),t=0;t>>1^e[i&1];for(;t>>1^e[i&1];i=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^i>>>1^e[i&1],this.mti=0}return i=this.mt[this.mti++],i^=i>>>11,i^=i<<7&2636928640,i^=i<<15&4022730752,i^=i>>>18,i>>>0}});function fe(i,e){if(Array.isArray(i)){for(let t of i)fe(t,e);return}if(typeof i=="object"){for(let t in i)fe(t,i[t]);return}e2(Object.getOwnPropertyNames(e)),su[i]=Object.assign(su[i]||{},e)}function Xt(i){return su[i]||{}}function qw(){return[...new Set(J3)]}function e2(i){J3.push(...i)}function mu(i,e){let t,r=i.length,n=[];for(t=0;t=0;e--)r2(i.children[e]);return i.id&&(i.id=i2(i.nodeName)),i}function xe(i,e){let t,r;for(i=Array.isArray(i)?i:[i],r=i.length-1;r>=0;r--)for(t in e)i[r].prototype[t]=e[t]}function He(i){return function(...e){let t=e[e.length-1];return t&&t.constructor===Object&&!(t instanceof Array)?i.apply(this,e.slice(0,-1)).attr(t):i.apply(this,e)}}function Vw(){return this.parent().children()}function Yw(){return this.parent().index(this)}function Xw(){return this.siblings()[this.position()+1]}function Kw(){return this.siblings()[this.position()-1]}function Zw(){let i=this.position();return this.parent().add(this.remove(),i+1),this}function Qw(){let i=this.position();return this.parent().add(this.remove(),i?i-1:0),this}function Jw(){return this.parent().add(this.remove()),this}function eM(){return this.parent().add(this.remove(),0),this}function tM(i){i=Rt(i),i.remove();let e=this.position();return this.parent().add(i,e),this}function iM(i){i=Rt(i),i.remove();let e=this.position();return this.parent().add(i,e+1),this}function rM(i){return i=Rt(i),i.before(this),this}function nM(i){return i=Rt(i),i.after(this),this}function cM(){let i=this.attr("class");return i==null?[]:i.trim().split(Sr)}function uM(i){return this.classes().indexOf(i)!==-1}function fM(i){if(!this.hasClass(i)){let e=this.classes();e.push(i),this.attr("class",e.join(" "))}return this}function mM(i){return this.hasClass(i)&&this.attr("class",this.classes().filter(function(e){return e!==i}).join(" ")),this}function pM(i){return this.hasClass(i)?this.removeClass(i):this.addClass(i)}function gM(i,e){let t={};if(arguments.length===0)return this.node.style.cssText.split(/\s*;\s*/).filter(function(r){return!!r.length}).forEach(function(r){let n=r.split(/\s*:\s*/);t[n[0]]=n[1]}),t;if(arguments.length<2){if(Array.isArray(i)){for(let r of i){let n=B0(r);t[r]=this.node.style[n]}return t}if(typeof i=="string")return this.node.style[B0(i)];if(typeof i=="object")for(let r in i)this.node.style[B0(r)]=i[r]==null||X3.test(i[r])?"":i[r]}return arguments.length===2&&(this.node.style[B0(i)]=e==null||X3.test(e)?"":e),this}function xM(){return this.css("display","")}function yM(){return this.css("display","none")}function vM(){return this.css("display")!=="none"}function bM(i,e,t){if(i==null)return this.data(mu(Hw(this.node.attributes,r=>r.nodeName.indexOf("data-")===0),r=>r.nodeName.slice(5)));if(i instanceof Array){let r={};for(let n of i)r[n]=this.data(n);return r}else if(typeof i=="object")for(e in i)this.data(e,i[e]);else if(arguments.length<2)try{return JSON.parse(this.attr("data-"+i))}catch{return this.attr("data-"+i)}else this.attr("data-"+i,e===null?null:t===!0||typeof e=="string"||typeof e=="number"?e:JSON.stringify(e));return this}function wM(i,e){if(typeof arguments[0]=="object")for(let t in i)this.remember(t,i[t]);else{if(arguments.length===1)return this.memory()[i];this.memory()[i]=e}return this}function MM(){if(arguments.length===0)this._memory={};else for(let i=arguments.length-1;i>=0;i--)delete this.memory()[arguments[i]];return this}function TM(){return this._memory=this._memory||{}}function NM(i){return i.length===4?["#",i.substring(1,2),i.substring(1,2),i.substring(2,3),i.substring(2,3),i.substring(3,4),i.substring(3,4)].join(""):i}function EM(i){let e=Math.round(i),r=Math.max(0,Math.min(255,e)).toString(16);return r.length===1?"0"+r:r}function Ws(i,e){for(let t=e.length;t--;)if(i[e[t]]==null)return!1;return!0}function SM(i,e){let t=Ws(i,"rgb")?{_a:i.r,_b:i.g,_c:i.b,_d:0,space:"rgb"}:Ws(i,"xyz")?{_a:i.x,_b:i.y,_c:i.z,_d:0,space:"xyz"}:Ws(i,"hsl")?{_a:i.h,_b:i.s,_c:i.l,_d:0,space:"hsl"}:Ws(i,"lab")?{_a:i.l,_b:i.a,_c:i.b,_d:0,space:"lab"}:Ws(i,"lch")?{_a:i.l,_b:i.c,_c:i.h,_d:0,space:"lch"}:Ws(i,"cmyk")?{_a:i.c,_b:i.m,_c:i.y,_d:i.k,space:"cmyk"}:{_a:0,_b:0,_c:0,space:"rgb"};return t.space=e||t.space,t}function AM(i){return i==="lab"||i==="xyz"||i==="lch"}function ru(i,e,t){return t<0&&(t+=1),t>1&&(t-=1),t<1/6?i+(e-i)*6*t:t<1/2?e:t<2/3?i+(e-i)*(2/3-t)*6:i}function kM(i,e){return new it(i,e).transformO(this.screenCTM().inverseO())}function Vs(i,e,t){return Math.abs(e-i)<(t||1e-6)}function CM(){return new be(this.node.getCTM())}function _M(){if(typeof this.isRoot=="function"&&!this.isRoot()){let i=this.rect(1,1),e=i.node.getScreenCTM();return i.remove(),new be(e)}return new be(this.node.getScreenCTM())}function on(){if(!on.nodes){let i=Rt().size(2,0);i.node.style.cssText=["opacity: 0","position: absolute","left: -100%","top: -100%","overflow: hidden"].join(";"),i.attr("focusable","false"),i.attr("aria-hidden","true");let e=i.path().node;on.nodes={svg:i,path:e}}if(!on.nodes.svg.node.parentNode){let i=Ne.document.body||Ne.document.documentElement;on.nodes.svg.addTo(i)}return on.nodes}function s2(i){return!i.width&&!i.height&&!i.x&&!i.y}function LM(i){return i===Ne.document||(Ne.document.documentElement.contains||function(e){for(;e.parentNode;)e=e.parentNode;return e===Ne.document}).call(Ne.document.documentElement,i)}function a2(i,e,t){let r;try{if(r=e(i.node),s2(r)&&!LM(i.node))throw new Error("Element not in the dom")}catch{r=t(i)}return r}function IM(){let t=a2(this,n=>n.getBBox(),n=>{try{let s=n.clone().addTo(on().svg).show(),a=s.node.getBBox();return s.remove(),a}catch(s){throw new Error(`Getting bbox of element "${n.node.nodeName}" is not possible: ${s.toString()}`)}});return new Vt(t)}function zM(i){let r=a2(this,s=>s.getBoundingClientRect(),s=>{throw new Error(`Getting rbox of element "${s.node.nodeName}" is not possible`)}),n=new Vt(r);return i?n.transform(i.screenCTM().inverseO()):n.addOffset()}function RM(i,e){let t=this.bbox();return i>t.x&&e>t.y&&i(r[n]=this.attr(n),r),{});if(typeof i=="object"&&i.constructor===Object)for(e in i)this.attr(e,i[e]);else if(e===null)this.node.removeAttribute(i);else{if(e==null)return e=this.node.getAttribute(i),e==null?HM[i]:K3.test(e)?parseFloat(e):e;e=h2.reduce((r,n)=>n(i,r,this),e),typeof e=="number"?e=new we(e):Ei.isColor(e)?e=new Ei(e):e.constructor===Array&&(e=new ln(e)),i==="leading"?this.leading&&this.leading(e):typeof t=="string"?this.node.setAttributeNS(t,i,e.toString()):this.node.setAttribute(i,e.toString()),this.rebuild&&(i==="font-size"||i==="x")&&this.rebuild()}}return this}function GM(){return this.attr("transform",null)}function WM(){return(this.attr("transform")||"").split(lM).slice(0,-1).map(function(e){let t=e.trim().split("(");return[t[0],t[1].split(Sr).map(function(r){return parseFloat(r)})]}).reverse().reduce(function(e,t){return t[0]==="matrix"?e.lmultiply(be.fromArray(t[1])):e[t[0]].apply(e,t[1])},new be)}function VM(i,e){if(this===i)return this;let t=this.screenCTM(),r=i.screenCTM().inverse();return this.addTo(i,e).untransform().transform(r.multiply(t)),this}function YM(i){return this.toParent(this.root(),i)}function XM(i,e){if(i==null||typeof i=="string"){let n=new be(this).decompose();return i==null?n:n[i]}be.isMatrixLike(i)||(i={...i,origin:au(i,this)});let t=e===!0?this:e||!1,r=new be(t).transform(i);return this.attr("transform",r)}function vu(i){return this.attr("rx",i)}function bu(i){return this.attr("ry",i)}function d2(i){return i==null?this.cx()-this.rx():this.cx(i+this.rx())}function c2(i){return i==null?this.cy()-this.ry():this.cy(i+this.ry())}function u2(i){return this.attr("cx",i)}function f2(i){return this.attr("cy",i)}function m2(i){return i==null?this.rx()*2:this.rx(new we(i).divide(2))}function p2(i){return i==null?this.ry()*2:this.ry(new we(i).divide(2))}function g2(i,e){return(this._element||this).type==="radialGradient"?this.attr({fx:new we(i),fy:new we(e)}):this.attr({x1:new we(i),y1:new we(e)})}function x2(i,e){return(this._element||this).type==="radialGradient"?this.attr({cx:new we(i),cy:new we(e)}):this.attr({x2:new we(i),y2:new we(e)})}function JM(i){return i==null?this.bbox().x:this.move(i,this.bbox().y)}function eT(i){return i==null?this.bbox().y:this.move(this.bbox().x,i)}function tT(i){let e=this.bbox();return i==null?e.width:this.size(i,e.height)}function iT(i){let e=this.bbox();return i==null?e.height:this.size(e.width,i)}function Xs(i,e){return function(t){return t==null?this[i]:(this[i]=t,e&&e.call(this),this)}}function Q3(){let i=(this._duration||500)/1e3,e=this._overshoot||0,t=1e-10,r=Math.PI,n=Math.log(e/100+t),s=-n/Math.sqrt(r*r+n*n),a=3.9/(s*i);this.d=2*s*a,this.k=a*a}function sT(i){let e=i.segment[0];return du[e](i.segment.slice(1),i.p,i.p0)}function cu(i){return i.segment.length&&i.segment.length-1===nT[i.segment[0].toUpperCase()]}function aT(i,e){i.inNumber&&Jn(i,!1);let t=xu.test(e);if(t)i.segment=[e];else{let r=i.lastCommand,n=r.toLowerCase(),s=r===n;i.segment=[n==="m"?s?"l":"L":r]}return i.inSegment=!0,i.lastCommand=i.segment[0],t}function Jn(i,e){if(!i.inNumber)throw new Error("Parser Error");i.number&&i.segment.push(parseFloat(i.number)),i.inNumber=e,i.number="",i.pointSeen=!1,i.hasExponent=!1,cu(i)&&uu(i)}function uu(i){i.inSegment=!1,i.absolute&&(i.segment=sT(i)),i.segments.push(i.segment)}function oT(i){if(!i.segment.length)return!1;let e=i.segment[0].toUpperCase()==="A",t=i.segment.length;return e&&(t===4||t===5)}function lT(i){return i.lastToken.toUpperCase()==="E"}function hT(i,e=!0){let t=0,r="",n={segment:[],inNumber:!1,number:"",lastToken:"",inSegment:!1,segments:[],pointSeen:!1,hasExponent:!1,absolute:e,p0:new it,p:new it};for(;n.lastToken=r,r=i.charAt(t++);)if(!(!n.inSegment&&aT(n,r))){if(r==="."){if(n.pointSeen||n.hasExponent){Jn(n,!1),--t;continue}n.inNumber=!0,n.pointSeen=!0,n.number+=r;continue}if(!isNaN(parseInt(r))){if(n.number==="0"||oT(n)){n.inNumber=!0,n.number=r,Jn(n,!0);continue}n.inNumber=!0,n.number+=r;continue}if(r===" "||r===","){n.inNumber&&Jn(n,!1);continue}if(r==="-"){if(n.inNumber&&!lT(n)){Jn(n,!1),--t;continue}n.number+=r,n.inNumber=!0;continue}if(r.toUpperCase()==="E"){n.number+=r,n.hasExponent=!0;continue}if(xu.test(r)){if(n.inNumber)Jn(n,!1);else if(cu(n))uu(n);else throw new Error("parser Error");--t}}return n.inNumber&&Jn(n,!1),n.inSegment&&cu(n)&&uu(n),n.segments}function dT(i){let e="";for(let t=0,r=i.length;t{let n;try{n=t.bbox()}catch{return}let s=new be(t),a=s.translate(i,e).transform(s.inverse()),o=new it(n.x,n.y).transform(a);t.move(o.x,o.y)}),this}function OT(i){return this.dmove(i,0)}function BT(i){return this.dmove(0,i)}function PT(i,e=this.bbox()){return i==null?e.height:this.size(e.width,i,e)}function FT(i=0,e=0,t=this.bbox()){let r=i-t.x,n=e-t.y;return this.dmove(r,n)}function qT(i,e,t=this.bbox()){let r=ia(this,i,e,t),n=r.width/t.width,s=r.height/t.height;return this.children().forEach((a,o)=>{let l=new it(t).transform(new be(a).inverse());a.scale(n,s,l.x,l.y)}),this}function HT(i,e=this.bbox()){return i==null?e.width:this.size(i,e.height,e)}function UT(i,e=this.bbox()){return i==null?e.x:this.move(i,e.y,e)}function $T(i,e=this.bbox()){return i==null?e.y:this.move(e.x,i,e)}function jT(i,e){if(!i)return"";if(!e)return i;let t=i+"{";for(let r in e)t+=Uw(r)+":"+e[r]+";";return t+="}",t}var su,J3,pu,$w,P0,Bo,jw,Ne,No,es,gu,iu,Ww,n2,sM,aM,oM,lM,hM,V3,Y3,X3,K3,dM,Sr,xu,Ei,it,be,Vt,Nr,DM,PM,o2,ts,Mo,HM,ln,we,h2,hn,Si,wo,jM,Yt,So,Dt,KM,Ks,F0,ZM,is,rs,$i,rr,QM,wu,ns,Zs,rT,Ao,ko,Qs,lu,hu,nT,du,nu,Er,y2,Tr,Co,_o,cT,ss,Mu,nr,v2,ji,as,Ve,To,Ae,vT,bT,q0,Gi,Js,b2,w2,fu,MT,Lo,Io,M2,_e,ea,Wi,zo,ta,T2,Le,dn,Ro,H0,Do,Oo,U0,ke,wt=T(()=>{su={},J3=[];pu="http://www.w3.org/2000/svg",$w="http://www.w3.org/1999/xhtml",P0="http://www.w3.org/2000/xmlns/",Bo="http://www.w3.org/1999/xlink",jw="http://svgjs.dev/svgjs",Ne={window:typeof window>"u"?null:window,document:typeof document>"u"?null:document},No=class{},es={},gu="___SYMBOL___ROOT___";iu=Ni;Ww=1e3;fe("Dom",{siblings:Vw,position:Yw,next:Xw,prev:Kw,forward:Zw,backward:Qw,front:Jw,back:eM,before:tM,after:iM,insertBefore:rM,insertAfter:nM});n2=/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,sM=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,aM=/rgb\((\d+),(\d+),(\d+)\)/,oM=/(#[a-z_][a-z0-9\-_]*)/i,lM=/\)\s*,?\s*/,hM=/\s/g,V3=/^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i,Y3=/^rgb\(/,X3=/^(\s+)?$/,K3=/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,dM=/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,Sr=/[\s,]+/,xu=/[MLHVCSQTAZ]/i;fe("Dom",{classes:cM,hasClass:uM,addClass:fM,removeClass:mM,toggleClass:pM});fe("Dom",{css:gM,show:xM,hide:yM,visible:vM});fe("Dom",{data:bM});fe("Dom",{remember:wM,forget:MM,memory:TM});Ei=class i{constructor(...e){this.init(...e)}static isColor(e){return e&&(e instanceof i||this.isRgb(e)||this.test(e))}static isRgb(e){return e&&typeof e.r=="number"&&typeof e.g=="number"&&typeof e.b=="number"}static random(e="vibrant",t,r){let{random:n,round:s,sin:a,PI:o}=Math;if(e==="vibrant"){let l=24*n()+57,h=38*n()+45,d=360*n();return new i(l,h,d,"lch")}else if(e==="sine"){t=t??n();let l=s(80*a(2*o*t/.5+.01)+150),h=s(50*a(2*o*t/.5+4.6)+200),d=s(100*a(2*o*t/.5+2.3)+150);return new i(l,h,d)}else if(e==="pastel"){let l=8*n()+86,h=17*n()+9,d=360*n();return new i(l,h,d,"lch")}else if(e==="dark"){let l=10+10*n(),h=50*n()+86,d=360*n();return new i(l,h,d,"lch")}else if(e==="rgb"){let l=255*n(),h=255*n(),d=255*n();return new i(l,h,d)}else if(e==="lab"){let l=100*n(),h=256*n()-128,d=256*n()-128;return new i(l,h,d,"lab")}else if(e==="grey"){let l=255*n();return new i(l,l,l)}else throw new Error("Unsupported random color mode")}static test(e){return typeof e=="string"&&(V3.test(e)||Y3.test(e))}cmyk(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(f=>f/255),o=Math.min(1-n,1-s,1-a);if(o===1)return new i(0,0,0,1,"cmyk");let l=(1-n-o)/(1-o),h=(1-s-o)/(1-o),d=(1-a-o)/(1-o);return new i(l,h,d,o,"cmyk")}hsl(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(x=>x/255),o=Math.max(n,s,a),l=Math.min(n,s,a),h=(o+l)/2,d=o===l,c=o-l,f=d?0:h>.5?c/(2-o-l):c/(o+l),m=d?0:o===n?((s-a)/c+(sparseInt(x));Object.assign(this,{_a:f,_b:m,_c:g,_d:0,space:"rgb"})}else if(V3.test(e)){let c=x=>parseInt(x,16),[,f,m,g]=sM.exec(NM(e)).map(c);Object.assign(this,{_a:f,_b:m,_c:g,_d:0,space:"rgb"})}else throw Error("Unsupported string format, can't construct Color");let{_a:a,_b:o,_c:l,_d:h}=this,d=this.space==="rgb"?{r:a,g:o,b:l}:this.space==="xyz"?{x:a,y:o,z:l}:this.space==="hsl"?{h:a,s:o,l}:this.space==="lab"?{l:a,a:o,b:l}:this.space==="lch"?{l:a,c:o,h:l}:this.space==="cmyk"?{c:a,m:o,y:l,k:h}:{};Object.assign(this,d)}lab(){let{x:e,y:t,z:r}=this.xyz(),n=116*t-16,s=500*(e-t),a=200*(t-r);return new i(n,s,a,"lab")}lch(){let{l:e,a:t,b:r}=this.lab(),n=Math.sqrt(t**2+r**2),s=180*Math.atan2(r,t)/Math.PI;return s<0&&(s*=-1,s=360-s),new i(e,n,s,"lch")}rgb(){if(this.space==="rgb")return this;if(AM(this.space)){let{x:e,y:t,z:r}=this;if(this.space==="lab"||this.space==="lch"){let{l:m,a:g,b:x}=this;if(this.space==="lch"){let{c:O,h:q}=this,F=Math.PI/180;g=O*Math.cos(F*q),x=O*Math.sin(F*q)}let y=(m+16)/116,b=g/500+y,E=y-x/200,k=16/116,L=.008856,I=7.787;e=.95047*(b**3>L?b**3:(b-k)/I),t=1*(y**3>L?y**3:(y-k)/I),r=1.08883*(E**3>L?E**3:(E-k)/I)}let n=e*3.2406+t*-1.5372+r*-.4986,s=e*-.9689+t*1.8758+r*.0415,a=e*.0557+t*-.204+r*1.057,o=Math.pow,l=.0031308,h=n>l?1.055*o(n,1/2.4)-.055:12.92*n,d=s>l?1.055*o(s,1/2.4)-.055:12.92*s,c=a>l?1.055*o(a,1/2.4)-.055:12.92*a;return new i(255*h,255*d,255*c)}else if(this.space==="hsl"){let{h:e,s:t,l:r}=this;if(e/=360,t/=100,r/=100,t===0)return r*=255,new i(r,r,r);let n=r<.5?r*(1+t):r+t-r*t,s=2*r-n,a=255*ru(s,n,e+1/3),o=255*ru(s,n,e),l=255*ru(s,n,e-1/3);return new i(a,o,l)}else if(this.space==="cmyk"){let{c:e,m:t,y:r,k:n}=this,s=255*(1-Math.min(1,e*(1-n)+n)),a=255*(1-Math.min(1,t*(1-n)+n)),o=255*(1-Math.min(1,r*(1-n)+n));return new i(s,a,o)}else return this}toArray(){let{_a:e,_b:t,_c:r,_d:n,space:s}=this;return[e,t,r,n,s]}toHex(){let[e,t,r]=this._clamped().map(EM);return`#${e}${t}${r}`}toRgb(){let[e,t,r]=this._clamped();return`rgb(${e},${t},${r})`}toString(){return this.toHex()}xyz(){let{_a:e,_b:t,_c:r}=this.rgb(),[n,s,a]=[e,t,r].map(b=>b/255),o=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,l=s>.04045?Math.pow((s+.055)/1.055,2.4):s/12.92,h=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,d=(o*.4124+l*.3576+h*.1805)/.95047,c=(o*.2126+l*.7152+h*.0722)/1,f=(o*.0193+l*.1192+h*.9505)/1.08883,m=d>.008856?Math.pow(d,1/3):7.787*d+16/116,g=c>.008856?Math.pow(c,1/3):7.787*c+16/116,x=f>.008856?Math.pow(f,1/3):7.787*f+16/116;return new i(m,g,x,"xyz")}_clamped(){let{_a:e,_b:t,_c:r}=this.rgb(),{max:n,min:s,round:a}=Math,o=l=>n(0,s(a(l),255));return[e,t,r].map(o)}},it=class i{constructor(...e){this.init(...e)}clone(){return new i(this)}init(e,t){let r={x:0,y:0},n=Array.isArray(e)?{x:e[0],y:e[1]}:typeof e=="object"?{x:e.x,y:e.y}:{x:e,y:t};return this.x=n.x==null?r.x:n.x,this.y=n.y==null?r.y:n.y,this}toArray(){return[this.x,this.y]}transform(e){return this.clone().transformO(e)}transformO(e){be.isMatrixLike(e)||(e=new be(e));let{x:t,y:r}=this;return this.x=e.a*t+e.c*r+e.e,this.y=e.b*t+e.d*r+e.f,this}};be=class i{constructor(...e){this.init(...e)}static formatTransforms(e){let t=e.flip==="both"||e.flip===!0,r=e.flip&&(t||e.flip==="x")?-1:1,n=e.flip&&(t||e.flip==="y")?-1:1,s=e.skew&&e.skew.length?e.skew[0]:isFinite(e.skew)?e.skew:isFinite(e.skewX)?e.skewX:0,a=e.skew&&e.skew.length?e.skew[1]:isFinite(e.skew)?e.skew:isFinite(e.skewY)?e.skewY:0,o=e.scale&&e.scale.length?e.scale[0]*r:isFinite(e.scale)?e.scale*r:isFinite(e.scaleX)?e.scaleX*r:r,l=e.scale&&e.scale.length?e.scale[1]*n:isFinite(e.scale)?e.scale*n:isFinite(e.scaleY)?e.scaleY*n:n,h=e.shear||0,d=e.rotate||e.theta||0,c=new it(e.origin||e.around||e.ox||e.originX,e.oy||e.originY),f=c.x,m=c.y,g=new it(e.position||e.px||e.positionX||NaN,e.py||e.positionY||NaN),x=g.x,y=g.y,b=new it(e.translate||e.tx||e.translateX,e.ty||e.translateY),E=b.x,k=b.y,L=new it(e.relative||e.rx||e.relativeX,e.ry||e.relativeY),I=L.x,O=L.y;return{scaleX:o,scaleY:l,skewX:s,skewY:a,shear:h,theta:d,rx:I,ry:O,tx:E,ty:k,ox:f,oy:m,px:x,py:y}}static fromArray(e){return{a:e[0],b:e[1],c:e[2],d:e[3],e:e[4],f:e[5]}}static isMatrixLike(e){return e.a!=null||e.b!=null||e.c!=null||e.d!=null||e.e!=null||e.f!=null}static matrixMultiply(e,t,r){let n=e.a*t.a+e.c*t.b,s=e.b*t.a+e.d*t.b,a=e.a*t.c+e.c*t.d,o=e.b*t.c+e.d*t.d,l=e.e+e.a*t.e+e.c*t.f,h=e.f+e.b*t.e+e.d*t.f;return r.a=n,r.b=s,r.c=a,r.d=o,r.e=l,r.f=h,r}around(e,t,r){return this.clone().aroundO(e,t,r)}aroundO(e,t,r){let n=e||0,s=t||0;return this.translateO(-n,-s).lmultiplyO(r).translateO(n,s)}clone(){return new i(this)}decompose(e=0,t=0){let r=this.a,n=this.b,s=this.c,a=this.d,o=this.e,l=this.f,h=r*a-n*s,d=h>0?1:-1,c=d*Math.sqrt(r*r+n*n),f=Math.atan2(d*n,d*r),m=180/Math.PI*f,g=Math.cos(f),x=Math.sin(f),y=(r*s+n*a)/h,b=s*c/(y*r-n)||a*c/(y*n+r),E=o-e+e*g*c+t*(y*g*c-x*b),k=l-t+e*x*c+t*(y*x*c+g*b);return{scaleX:c,scaleY:b,shear:y,rotate:m,translateX:E,translateY:k,originX:e,originY:t,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}}equals(e){if(e===this)return!0;let t=new i(e);return Vs(this.a,t.a)&&Vs(this.b,t.b)&&Vs(this.c,t.c)&&Vs(this.d,t.d)&&Vs(this.e,t.e)&&Vs(this.f,t.f)}flip(e,t){return this.clone().flipO(e,t)}flipO(e,t){return e==="x"?this.scaleO(-1,1,t,0):e==="y"?this.scaleO(1,-1,0,t):this.scaleO(-1,-1,e,t||e)}init(e){let t=i.fromArray([1,0,0,1,0,0]);return e=e instanceof Si?e.matrixify():typeof e=="string"?i.fromArray(e.split(Sr).map(parseFloat)):Array.isArray(e)?i.fromArray(e):typeof e=="object"&&i.isMatrixLike(e)?e:typeof e=="object"?new i().transform(e):arguments.length===6?i.fromArray([].slice.call(arguments)):t,this.a=e.a!=null?e.a:t.a,this.b=e.b!=null?e.b:t.b,this.c=e.c!=null?e.c:t.c,this.d=e.d!=null?e.d:t.d,this.e=e.e!=null?e.e:t.e,this.f=e.f!=null?e.f:t.f,this}inverse(){return this.clone().inverseO()}inverseO(){let e=this.a,t=this.b,r=this.c,n=this.d,s=this.e,a=this.f,o=e*n-t*r;if(!o)throw new Error("Cannot invert "+this);let l=n/o,h=-t/o,d=-r/o,c=e/o,f=-(l*s+d*a),m=-(h*s+c*a);return this.a=l,this.b=h,this.c=d,this.d=c,this.e=f,this.f=m,this}lmultiply(e){return this.clone().lmultiplyO(e)}lmultiplyO(e){let t=this,r=e instanceof i?e:new i(e);return i.matrixMultiply(r,t,this)}multiply(e){return this.clone().multiplyO(e)}multiplyO(e){let t=this,r=e instanceof i?e:new i(e);return i.matrixMultiply(t,r,this)}rotate(e,t,r){return this.clone().rotateO(e,t,r)}rotateO(e,t=0,r=0){e=tu(e);let n=Math.cos(e),s=Math.sin(e),{a,b:o,c:l,d:h,e:d,f:c}=this;return this.a=a*n-o*s,this.b=o*n+a*s,this.c=l*n-h*s,this.d=h*n+l*s,this.e=d*n-c*s+r*s-t*n+t,this.f=c*n+d*s-t*s-r*n+r,this}scale(e,t,r,n){return this.clone().scaleO(...arguments)}scaleO(e,t=e,r=0,n=0){arguments.length===3&&(n=r,r=t,t=e);let{a:s,b:a,c:o,d:l,e:h,f:d}=this;return this.a=s*e,this.b=a*t,this.c=o*e,this.d=l*t,this.e=h*e-r*e+r,this.f=d*t-n*t+n,this}shear(e,t,r){return this.clone().shearO(e,t,r)}shearO(e,t=0,r=0){let{a:n,b:s,c:a,d:o,e:l,f:h}=this;return this.a=n+s*e,this.c=a+o*e,this.e=l+h*e-r*e,this}skew(e,t,r,n){return this.clone().skewO(...arguments)}skewO(e,t=e,r=0,n=0){arguments.length===3&&(n=r,r=t,t=e),e=tu(e),t=tu(t);let s=Math.tan(e),a=Math.tan(t),{a:o,b:l,c:h,d,e:c,f}=this;return this.a=o+l*s,this.b=l+o*a,this.c=h+d*s,this.d=d+h*a,this.e=c+f*s-n*s,this.f=f+c*a-r*a,this}skewX(e,t,r){return this.skew(e,0,t,r)}skewY(e,t,r){return this.skew(0,e,t,r)}toArray(){return[this.a,this.b,this.c,this.d,this.e,this.f]}toString(){return"matrix("+this.a+","+this.b+","+this.c+","+this.d+","+this.e+","+this.f+")"}transform(e){if(i.isMatrixLike(e))return new i(e).multiplyO(this);let t=i.formatTransforms(e),r=this,{x:n,y:s}=new it(t.ox,t.oy).transform(r),a=new i().translateO(t.rx,t.ry).lmultiplyO(r).translateO(-n,-s).scaleO(t.scaleX,t.scaleY).skewO(t.skewX,t.skewY).shearO(t.shear).rotateO(t.theta).translateO(n,s);if(isFinite(t.px)||isFinite(t.py)){let o=new it(n,s).transform(a),l=isFinite(t.px)?t.px-o.x:0,h=isFinite(t.py)?t.py-o.y:0;a.translateO(l,h)}return a.translateO(t.tx,t.ty),a}translate(e,t){return this.clone().translateO(e,t)}translateO(e,t){return this.e+=e||0,this.f+=t||0,this}valueOf(){return{a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f}}};Me(be,"Matrix");Vt=class i{constructor(...e){this.init(...e)}addOffset(){return this.x+=Ne.window.pageXOffset,this.y+=Ne.window.pageYOffset,new i(this)}init(e){let t=[0,0,0,0];return e=typeof e=="string"?e.split(Sr).map(parseFloat):Array.isArray(e)?e:typeof e=="object"?[e.left!=null?e.left:e.x,e.top!=null?e.top:e.y,e.width,e.height]:arguments.length===4?[].slice.call(arguments):t,this.x=e[0]||0,this.y=e[1]||0,this.width=this.w=e[2]||0,this.height=this.h=e[3]||0,this.x2=this.x+this.w,this.y2=this.y+this.h,this.cx=this.x+this.w/2,this.cy=this.y+this.h/2,this}isNulled(){return s2(this)}merge(e){let t=Math.min(this.x,e.x),r=Math.min(this.y,e.y),n=Math.max(this.x+this.width,e.x+e.width)-t,s=Math.max(this.y+this.height,e.y+e.height)-r;return new i(t,r,n,s)}toArray(){return[this.x,this.y,this.width,this.height]}toString(){return this.x+" "+this.y+" "+this.width+" "+this.height}transform(e){e instanceof be||(e=new be(e));let t=1/0,r=-1/0,n=1/0,s=-1/0;return[new it(this.x,this.y),new it(this.x2,this.y),new it(this.x,this.y2),new it(this.x2,this.y2)].forEach(function(o){o=o.transform(e),t=Math.min(t,o.x),r=Math.max(r,o.x),n=Math.min(n,o.y),s=Math.max(s,o.y)}),new i(t,n,r-t,s-n)}};fe({viewbox:{viewbox(i,e,t,r){return i==null?new Vt(this.attr("viewBox")):this.attr("viewBox",new Vt(i,e,t,r))},zoom(i,e){let{width:t,height:r}=this.attr(["width","height"]);if((!t&&!r||typeof t=="string"||typeof r=="string")&&(t=this.node.clientWidth,r=this.node.clientHeight),!t||!r)throw new Error("Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element");let n=this.viewbox(),s=t/n.width,a=r/n.height,o=Math.min(s,a);if(i==null)return o;let l=o/i;l===1/0&&(l=Number.MAX_SAFE_INTEGER/100),e=e||new it(t/2/s+n.x,r/2/a+n.y);let h=new Vt(n).transform(new be({scale:l,origin:e}));return this.viewbox(h)}}});Me(Vt,"Box");Nr=class extends Array{constructor(e=[],...t){if(super(e,...t),typeof e=="number")return this;this.length=0,this.push(...e)}};xe([Nr],{each(i,...e){return typeof i=="function"?this.map((t,r,n)=>i.call(t,t,r,n)):this.map(t=>t[i](...e))},toArray(){return Array.prototype.concat.apply([],this)}});DM=["toArray","constructor","each"];Nr.extend=function(i){i=i.reduce((e,t)=>(DM.includes(t)||t[0]==="_"||(e[t]=function(...r){return this.each(t,...r)}),e),{}),xe([Nr],i)};PM=0,o2={};ts=class extends No{addEventListener(){}dispatch(e,t,r){return qM(this,e,t,r)}dispatchEvent(e){let t=this.getEventHolder().events;if(!t)return!0;let r=t[e.type];for(let n in r)for(let s in r[n])r[n][s](e);return!e.defaultPrevented}fire(e,t,r){return this.dispatch(e,t,r),this}getEventHolder(){return this}getEventTarget(){return this}off(e,t,r){return Ys(this,e,t,r),this}on(e,t,r,n){return ou(this,e,t,r,n),this}removeEventListener(){}};Me(ts,"EventTarget");Mo={duration:400,ease:">",delay:0},HM={"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","text-anchor":"start"},ln=class extends Array{constructor(...e){super(...e),this.init(...e)}clone(){return new this.constructor(this)}init(e){return typeof e=="number"?this:(this.length=0,this.push(...this.parse(e)),this)}parse(e=[]){return e instanceof Array?e:e.trim().split(Sr).map(parseFloat)}toArray(){return Array.prototype.concat.apply([],this)}toSet(){return new Set(this)}toString(){return this.join(" ")}valueOf(){let e=[];return e.push(...this),e}},we=class i{constructor(...e){this.init(...e)}convert(e){return new i(this.value,e)}divide(e){return e=new i(e),new i(this/e,this.unit||e.unit)}init(e,t){return t=Array.isArray(e)?e[1]:t,e=Array.isArray(e)?e[0]:e,this.value=0,this.unit=t||"",typeof e=="number"?this.value=isNaN(e)?0:isFinite(e)?e:e<0?-34e37:34e37:typeof e=="string"?(t=e.match(n2),t&&(this.value=parseFloat(t[1]),t[5]==="%"?this.value/=100:t[5]==="s"&&(this.value*=1e3),this.unit=t[5])):e instanceof i&&(this.value=e.valueOf(),this.unit=e.unit),this}minus(e){return e=new i(e),new i(this-e,this.unit||e.unit)}plus(e){return e=new i(e),new i(this+e,this.unit||e.unit)}times(e){return e=new i(e),new i(this*e,this.unit||e.unit)}toArray(){return[this.value,this.unit]}toJSON(){return this.toString()}toString(){return(this.unit==="%"?~~(this.value*1e8)/1e6:this.unit==="s"?this.value/1e3:this.value)+this.unit}valueOf(){return this.value}},h2=[];hn=class i extends ts{constructor(e,t){super(),this.node=e,this.type=e.nodeName,t&&e!==t&&this.attr(t)}add(e,t){return e=Rt(e),e.removeNamespace&&this.node instanceof Ne.window.SVGElement&&e.removeNamespace(),t==null?this.node.appendChild(e.node):e.node!==this.node.childNodes[t]&&this.node.insertBefore(e.node,this.node.childNodes[t]),this}addTo(e,t){return Rt(e).put(this,t)}children(){return new Nr(mu(this.node.children,function(e){return Ni(e)}))}clear(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return this}clone(e=!0,t=!0){this.writeDataToDom();let r=this.node.cloneNode(e);return t&&(r=r2(r)),new this.constructor(r)}each(e,t){let r=this.children(),n,s;for(n=0,s=r.length;n=0}html(e,t){return this.xml(e,t,$w)}id(e){return typeof e>"u"&&!this.node.id&&(this.node.id=i2(this.type)),this.attr("id",e)}index(e){return[].slice.call(this.node.childNodes).indexOf(e.node)}last(){return Ni(this.node.lastChild)}matches(e){let t=this.node,r=t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector||null;return r&&r.call(t,e)}parent(e){let t=this;if(!t.node.parentNode)return null;if(t=Ni(t.node.parentNode),!e)return t;do if(typeof e=="string"?t.matches(e):t instanceof e)return t;while(t=Ni(t.node.parentNode));return t}put(e,t){return e=Rt(e),this.add(e,t),e}putIn(e,t){return Rt(e).add(this,t)}remove(){return this.parent()&&this.parent().removeElement(this),this}removeElement(e){return this.node.removeChild(e.node),this}replace(e){return e=Rt(e),this.node.parentNode&&this.node.parentNode.replaceChild(e.node,this.node),e}round(e=2,t=null){let r=10**e,n=this.attr(t);for(let s in n)typeof n[s]=="number"&&(n[s]=Math.round(n[s]*r)/r);return this.attr(n),this}svg(e,t){return this.xml(e,t,pu)}toString(){return this.id()}words(e){return this.node.textContent=e,this}wrap(e){let t=this.parent();if(!t)return this.addTo(e);let r=t.index(this);return t.put(e,r).put(this)}writeDataToDom(){return this.each(function(){this.writeDataToDom()}),this}xml(e,t,r){if(typeof e=="boolean"&&(r=t,t=e,e=null),e==null||typeof e=="function"){t=t??!0,this.writeDataToDom();let o=this;if(e!=null){if(o=Ni(o.node.cloneNode(!0)),t){let l=e(o);if(o=l||o,l===!1)return""}o.each(function(){let l=e(this),h=l||this;l===!1?this.remove():l&&this!==h&&this.replace(h)},!0)}return t?o.node.outerHTML:o.node.innerHTML}t=t??!1;let n=Eo("wrapper",r),s=Ne.document.createDocumentFragment();n.innerHTML=e;for(let o=n.children.length;o--;)s.appendChild(n.firstElementChild);let a=this.parent();return t?this.replace(s)&&a:this.add(s)}};xe(hn,{attr:$M,find:OM,findOne:BM});Me(hn,"Dom");Si=class extends hn{constructor(e,t){super(e,t),this.dom={},this.node.instance=this,e.hasAttribute("svgjs:data")&&this.setData(JSON.parse(e.getAttribute("svgjs:data"))||{})}center(e,t){return this.cx(e).cy(t)}cx(e){return e==null?this.x()+this.width()/2:this.x(e-this.width()/2)}cy(e){return e==null?this.y()+this.height()/2:this.y(e-this.height()/2)}defs(){let e=this.root();return e&&e.defs()}dmove(e,t){return this.dx(e).dy(t)}dx(e=0){return this.x(new we(e).plus(this.x()))}dy(e=0){return this.y(new we(e).plus(this.y()))}getEventHolder(){return this}height(e){return this.attr("height",e)}move(e,t){return this.x(e).y(t)}parents(e=this.root()){let t=typeof e=="string";t||(e=Rt(e));let r=new Nr,n=this;for(;(n=n.parent())&&n.node!==Ne.document&&n.nodeName!=="#document-fragment"&&(r.push(n),!(!t&&n.node===e.node||t&&n.matches(e)));)if(n.node===this.root().node)return null;return r}reference(e){if(e=this.attr(e),!e)return null;let t=(e+"").match(oM);return t?Rt(t[1]):null}root(){let e=this.parent(Gw(gu));return e&&e.root()}setData(e){return this.dom=e,this}size(e,t){let r=ia(this,e,t);return this.width(new we(r.width)).height(new we(r.height))}width(e){return this.attr("width",e)}writeDataToDom(){return this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),super.writeDataToDom()}x(e){return this.attr("x",e)}y(e){return this.attr("y",e)}};xe(Si,{bbox:IM,rbox:zM,inside:RM,point:kM,ctm:CM,screenCTM:_M});Me(Si,"Element");wo={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(i,e){return e==="color"?i:i+"-"+e}};["fill","stroke"].forEach(function(i){let e={},t;e[i]=function(r){if(typeof r>"u")return this.attr(i);if(typeof r=="string"||r instanceof Ei||Ei.isRgb(r)||r instanceof Si)this.attr(i,r);else for(t=wo[i].length-1;t>=0;t--)r[wo[i][t]]!=null&&this.attr(wo.prefix(i,wo[i][t]),r[wo[i][t]]);return this},fe(["Element","Runner"],e)});fe(["Element","Runner"],{matrix:function(i,e,t,r,n,s){return i==null?new be(this):this.attr("transform",new be(i,e,t,r,n,s))},rotate:function(i,e,t){return this.transform({rotate:i,ox:e,oy:t},!0)},skew:function(i,e,t,r){return arguments.length===1||arguments.length===3?this.transform({skew:i,ox:e,oy:t},!0):this.transform({skew:[i,e],ox:t,oy:r},!0)},shear:function(i,e,t){return this.transform({shear:i,ox:e,oy:t},!0)},scale:function(i,e,t,r){return arguments.length===1||arguments.length===3?this.transform({scale:i,ox:e,oy:t},!0):this.transform({scale:[i,e],ox:t,oy:r},!0)},translate:function(i,e){return this.transform({translate:[i,e]},!0)},relative:function(i,e){return this.transform({relative:[i,e]},!0)},flip:function(i="both",e="center"){return"xybothtrue".indexOf(i)===-1&&(e=i,i="both"),this.transform({flip:i,origin:e},!0)},opacity:function(i){return this.attr("opacity",i)}});fe("radius",{radius:function(i,e=i){return(this._element||this).type==="radialGradient"?this.attr("r",new we(i)):this.rx(i).ry(e)}});fe("Path",{length:function(){return this.node.getTotalLength()},pointAt:function(i){return new it(this.node.getPointAtLength(i))}});fe(["Element","Runner"],{font:function(i,e){if(typeof i=="object"){for(e in i)this.font(e,i[e]);return this}return i==="leading"?this.leading(e):i==="anchor"?this.attr("text-anchor",e):i==="size"||i==="family"||i==="weight"||i==="stretch"||i==="variant"||i==="style"?this.attr("font-"+i,e):this.attr(i,e)}});jM=["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","mouseenter","mouseleave","touchstart","touchmove","touchleave","touchend","touchcancel"].reduce(function(i,e){let t=function(r){return r===null?this.off(e):this.on(e,r),this};return i[e]=t,i},{});fe("Element",jM);fe("Element",{untransform:GM,matrixify:WM,toParent:VM,toRoot:YM,transform:XM});Yt=class i extends Si{flatten(e=this,t){return this.each(function(){if(this instanceof i)return this.flatten().ungroup()}),this}ungroup(e=this.parent(),t=e.index(this)){return t=t===-1?e.children().length:t,this.each(function(r,n){return n[n.length-r-1].toParent(e,t)}),this.remove()}};Me(Yt,"Container");So=class extends Yt{constructor(e,t=e){super(Ue("defs",e),t)}flatten(){return this}ungroup(){return this}};Me(So,"Defs");Dt=class extends Si{};Me(Dt,"Shape");KM={__proto__:null,rx:vu,ry:bu,x:d2,y:c2,cx:u2,cy:f2,width:m2,height:p2},Ks=class extends Dt{constructor(e,t=e){super(Ue("ellipse",e),t)}size(e,t){let r=ia(this,e,t);return this.rx(new we(r.width).divide(2)).ry(new we(r.height).divide(2))}};xe(Ks,KM);fe("Container",{ellipse:He(function(i=0,e=i){return this.put(new Ks).size(i,e).move(0,0)})});Me(Ks,"Ellipse");F0=class extends hn{constructor(e=Ne.document.createDocumentFragment()){super(e)}xml(e,t,r){if(typeof e=="boolean"&&(r=t,t=e,e=null),e==null||typeof e=="function"){let n=new hn(Eo("wrapper",r));return n.add(this.node.cloneNode(!0)),n.xml(!1,r)}return super.xml(e,!1,r)}};Me(F0,"Fragment");ZM={__proto__:null,from:g2,to:x2},is=class extends Yt{constructor(e,t){super(Ue(e+"Gradient",typeof e=="string"?null:e),t)}attr(e,t,r){return e==="transform"&&(e="gradientTransform"),super.attr(e,t,r)}bbox(){return new Vt}targets(){return ra("svg [fill*="+this.id()+"]")}toString(){return this.url()}update(e){return this.clear(),typeof e=="function"&&e.call(this,this),this}url(){return"url(#"+this.id()+")"}};xe(is,ZM);fe({Container:{gradient(...i){return this.defs().gradient(...i)}},Defs:{gradient:He(function(i,e){return this.put(new is(i)).update(e)})}});Me(is,"Gradient");rs=class extends Yt{constructor(e,t=e){super(Ue("pattern",e),t)}attr(e,t,r){return e==="transform"&&(e="patternTransform"),super.attr(e,t,r)}bbox(){return new Vt}targets(){return ra("svg [fill*="+this.id()+"]")}toString(){return this.url()}update(e){return this.clear(),typeof e=="function"&&e.call(this,this),this}url(){return"url(#"+this.id()+")"}};fe({Container:{pattern(...i){return this.defs().pattern(...i)}},Defs:{pattern:He(function(i,e,t){return this.put(new rs).update(t).attr({x:0,y:0,width:i,height:e,patternUnits:"userSpaceOnUse"})})}});Me(rs,"Pattern");$i=class extends Dt{constructor(e,t=e){super(Ue("image",e),t)}load(e,t){if(!e)return this;let r=new Ne.window.Image;return ou(r,"load",function(n){let s=this.parent(rs);this.width()===0&&this.height()===0&&this.size(r.width,r.height),s instanceof rs&&s.width()===0&&s.height()===0&&s.size(this.width(),this.height()),typeof t=="function"&&t.call(this,n)},this),ou(r,"load error",function(){Ys(r)}),this.attr("href",r.src=e,Bo)}};UM(function(i,e,t){return(i==="fill"||i==="stroke")&&dM.test(e)&&(e=t.root().defs().image(e)),e instanceof $i&&(e=t.root().defs().pattern(0,0,r=>{r.add(e)})),e});fe({Container:{image:He(function(i,e){return this.put(new $i).size(0,0).load(i,e)})}});Me($i,"Image");rr=class extends ln{bbox(){let e=-1/0,t=-1/0,r=1/0,n=1/0;return this.forEach(function(s){e=Math.max(s[0],e),t=Math.max(s[1],t),r=Math.min(s[0],r),n=Math.min(s[1],n)}),new Vt(r,n,e-r,t-n)}move(e,t){let r=this.bbox();if(e-=r.x,t-=r.y,!isNaN(e)&&!isNaN(t))for(let n=this.length-1;n>=0;n--)this[n]=[this[n][0]+e,this[n][1]+t];return this}parse(e=[0,0]){let t=[];e instanceof Array?e=Array.prototype.concat.apply([],e):e=e.trim().split(Sr).map(parseFloat),e.length%2!==0&&e.pop();for(let r=0,n=e.length;r=0;r--)n.width&&(this[r][0]=(this[r][0]-n.x)*e/n.width+n.x),n.height&&(this[r][1]=(this[r][1]-n.y)*t/n.height+n.y);return this}toLine(){return{x1:this[0][0],y1:this[0][1],x2:this[1][0],y2:this[1][1]}}toString(){let e=[];for(let t=0,r=this.length;t":function(i){return-Math.cos(i*Math.PI)/2+.5},">":function(i){return Math.sin(i*Math.PI/2)},"<":function(i){return-Math.cos(i*Math.PI/2)+1},bezier:function(i,e,t,r){return function(n){return n<0?i>0?e/i*n:t>0?r/t*n:0:n>1?t<1?(1-r)/(1-t)*n+(r-t)/(1-t):i<1?(1-e)/(1-i)*n+(e-i)/(1-i):1:3*n*(1-n)**2*e+3*n**2*(1-n)*r+n**3}},steps:function(i,e="end"){e=e.split("-").reverse()[0];let t=i;return e==="none"?--t:e==="both"&&++t,(r,n=!1)=>{let s=Math.floor(r*i),a=r*s%1===0;return(e==="start"||e==="both")&&++s,n&&a&&--s,r>=0&&s<0&&(s=0),r<=1&&s>t&&(s=t),s/t}}},Ao=class{done(){return!1}},ko=class extends Ao{constructor(e=Mo.ease){super(),this.ease=rT[e]||e}step(e,t,r){return typeof e!="number"?r<1?e:t:e+(t-e)*this.ease(r)}},Qs=class extends Ao{constructor(e){super(),this.stepper=e}done(e){return e.done}step(e,t,r,n){return this.stepper(e,t,r,n)}};lu=class extends Qs{constructor(e=500,t=0){super(),this.duration(e).overshoot(t)}step(e,t,r,n){if(typeof e=="string")return e;if(n.done=r===1/0,r===1/0)return t;if(r===0)return e;r>100&&(r=16),r/=1e3;let s=n.velocity||0,a=-this.d*s-this.k*(e-t),o=e+s*r+a*r*r/2;return n.velocity=s+a*r,n.done=Math.abs(t-o)+Math.abs(s)<.002,n.done?t:o}};xe(lu,{duration:Xs("_duration",Q3),overshoot:Xs("_overshoot",Q3)});hu=class extends Qs{constructor(e=.1,t=.01,r=0,n=1e3){super(),this.p(e).i(t).d(r).windup(n)}step(e,t,r,n){if(typeof e=="string")return e;if(n.done=r===1/0,r===1/0)return t;if(r===0)return e;let s=t-e,a=(n.integral||0)+s*r,o=(s-(n.error||0))/r,l=this._windup;return l!==!1&&(a=Math.max(-l,Math.min(a,l))),n.error=s,n.integral=a,n.done=Math.abs(s)<.001,n.done?t:e+(this.P*s+this.I*a+this.D*o)}};xe(hu,{windup:Xs("_windup"),p:Xs("P"),i:Xs("I"),d:Xs("D")});nT={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0},du={M:function(i,e,t){return e.x=t.x=i[0],e.y=t.y=i[1],["M",e.x,e.y]},L:function(i,e){return e.x=i[0],e.y=i[1],["L",i[0],i[1]]},H:function(i,e){return e.x=i[0],["H",i[0]]},V:function(i,e){return e.y=i[0],["V",i[0]]},C:function(i,e){return e.x=i[4],e.y=i[5],["C",i[0],i[1],i[2],i[3],i[4],i[5]]},S:function(i,e){return e.x=i[2],e.y=i[3],["S",i[0],i[1],i[2],i[3]]},Q:function(i,e){return e.x=i[2],e.y=i[3],["Q",i[0],i[1],i[2],i[3]]},T:function(i,e){return e.x=i[0],e.y=i[1],["T",i[0],i[1]]},Z:function(i,e,t){return e.x=t.x,e.y=t.y,["Z"]},A:function(i,e){return e.x=i[5],e.y=i[6],["A",i[0],i[1],i[2],i[3],i[4],i[5],i[6]]}},nu="mlhvqtcsaz".split("");for(let i=0,e=nu.length;i=0;s--)n=this[s][0],n==="M"||n==="L"||n==="T"?(this[s][1]+=e,this[s][2]+=t):n==="H"?this[s][1]+=e:n==="V"?this[s][1]+=t:n==="C"||n==="S"||n==="Q"?(this[s][1]+=e,this[s][2]+=t,this[s][3]+=e,this[s][4]+=t,n==="C"&&(this[s][5]+=e,this[s][6]+=t)):n==="A"&&(this[s][6]+=e,this[s][7]+=t);return this}parse(e="M0 0"){return Array.isArray(e)&&(e=Array.prototype.concat.apply([],e).toString()),hT(e)}size(e,t){let r=this.bbox(),n,s;for(r.width=r.width===0?1:r.width,r.height=r.height===0?1:r.height,n=this.length-1;n>=0;n--)s=this[n][0],s==="M"||s==="L"||s==="T"?(this[n][1]=(this[n][1]-r.x)*e/r.width+r.x,this[n][2]=(this[n][2]-r.y)*t/r.height+r.y):s==="H"?this[n][1]=(this[n][1]-r.x)*e/r.width+r.x:s==="V"?this[n][1]=(this[n][1]-r.y)*t/r.height+r.y:s==="C"||s==="S"||s==="Q"?(this[n][1]=(this[n][1]-r.x)*e/r.width+r.x,this[n][2]=(this[n][2]-r.y)*t/r.height+r.y,this[n][3]=(this[n][3]-r.x)*e/r.width+r.x,this[n][4]=(this[n][4]-r.y)*t/r.height+r.y,s==="C"&&(this[n][5]=(this[n][5]-r.x)*e/r.width+r.x,this[n][6]=(this[n][6]-r.y)*t/r.height+r.y)):s==="A"&&(this[n][1]=this[n][1]*e/r.width,this[n][2]=this[n][2]*t/r.height,this[n][6]=(this[n][6]-r.x)*e/r.width+r.x,this[n][7]=(this[n][7]-r.y)*t/r.height+r.y);return this}toString(){return dT(this)}},y2=i=>{let e=typeof i;return e==="number"?we:e==="string"?Ei.isColor(i)?Ei:Sr.test(i)?xu.test(i)?Er:ln:n2.test(i)?we:Co:Mu.indexOf(i.constructor)>-1?i.constructor:Array.isArray(i)?ln:e==="object"?ss:Co},Tr=class{constructor(e){this._stepper=e||new ko("-"),this._from=null,this._to=null,this._type=null,this._context=null,this._morphObj=null}at(e){return this._morphObj.morph(this._from,this._to,e,this._stepper,this._context)}done(){return this._context.map(this._stepper.done).reduce(function(t,r){return t&&r},!0)}from(e){return e==null?this._from:(this._from=this._set(e),this)}stepper(e){return e==null?this._stepper:(this._stepper=e,this)}to(e){return e==null?this._to:(this._to=this._set(e),this)}type(e){return e==null?this._type:(this._type=e,this)}_set(e){this._type||this.type(y2(e));let t=new this._type(e);return this._type===Ei&&(t=this._to?t[this._to[4]]():this._from?t[this._from[4]]():t),this._type===ss&&(t=this._to?t.align(this._to):this._from?t.align(this._from):t),t=t.toConsumable(),this._morphObj=this._morphObj||new this._type,this._context=this._context||Array.apply(null,Array(t.length)).map(Object).map(function(r){return r.done=!0,r}),t}},Co=class{constructor(...e){this.init(...e)}init(e){return e=Array.isArray(e)?e[0]:e,this.value=e,this}toArray(){return[this.value]}valueOf(){return this.value}},_o=class i{constructor(...e){this.init(...e)}init(e){return Array.isArray(e)&&(e={scaleX:e[0],scaleY:e[1],shear:e[2],rotate:e[3],translateX:e[4],translateY:e[5],originX:e[6],originY:e[7]}),Object.assign(this,i.defaults,e),this}toArray(){let e=this;return[e.scaleX,e.scaleY,e.shear,e.rotate,e.translateX,e.translateY,e.originX,e.originY]}};_o.defaults={scaleX:1,scaleY:1,shear:0,rotate:0,translateX:0,translateY:0,originX:0,originY:0};cT=(i,e)=>i[0]e[0]?1:0,ss=class{constructor(...e){this.init(...e)}align(e){let t=this.values;for(let r=0,n=t.length;rr.concat(n),[]),this}toArray(){return this.values}valueOf(){let e={},t=this.values;for(;t.length;){let r=t.shift(),n=t.shift(),s=t.shift(),a=t.splice(0,s);e[r]=new n(a)}return e}},Mu=[Co,_o,ss];nr=class extends Dt{constructor(e,t=e){super(Ue("path",e),t)}array(){return this._array||(this._array=new Er(this.attr("d")))}clear(){return delete this._array,this}height(e){return e==null?this.bbox().height:this.size(this.bbox().width,e)}move(e,t){return this.attr("d",this.array().move(e,t))}plot(e){return e==null?this.array():this.clear().attr("d",typeof e=="string"?e:this._array=new Er(e))}size(e,t){let r=ia(this,e,t);return this.attr("d",this.array().size(r.width,r.height))}width(e){return e==null?this.bbox().width:this.size(e,this.bbox().height)}x(e){return e==null?this.bbox().x:this.move(e,this.bbox().y)}y(e){return e==null?this.bbox().y:this.move(this.bbox().x,e)}};nr.prototype.MorphArray=Er;fe({Container:{path:He(function(i){return this.put(new nr).plot(i||new Er)})}});Me(nr,"Path");v2={__proto__:null,array:mT,clear:pT,move:gT,plot:xT,size:yT},ji=class extends Dt{constructor(e,t=e){super(Ue("polygon",e),t)}};fe({Container:{polygon:He(function(i){return this.put(new ji).plot(i||new rr)})}});xe(ji,wu);xe(ji,v2);Me(ji,"Polygon");as=class extends Dt{constructor(e,t=e){super(Ue("polyline",e),t)}};fe({Container:{polyline:He(function(i){return this.put(new as).plot(i||new rr)})}});xe(as,wu);xe(as,v2);Me(as,"Polyline");Ve=class extends Dt{constructor(e,t=e){super(Ue("rect",e),t)}};xe(Ve,{rx:vu,ry:bu});fe({Container:{rect:He(function(i,e){return this.put(new Ve).size(i,e)})}});Me(Ve,"Rect");To=class{constructor(){this._first=null,this._last=null}first(){return this._first&&this._first.value}last(){return this._last&&this._last.value}push(e){let t=typeof e.next<"u"?e:{value:e,next:null,prev:null};return this._last?(t.prev=this._last,this._last.next=t,this._last=t):(this._last=t,this._first=t),t}remove(e){e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e===this._last&&(this._last=e.prev),e===this._first&&(this._first=e.next),e.prev=null,e.next=null}shift(){let e=this._first;return e?(this._first=e.next,this._first&&(this._first.prev=null),this._last=this._first?this._last:null,e.value):null}},Ae={nextDraw:null,frames:new To,timeouts:new To,immediates:new To,timer:()=>Ne.window.performance||Ne.window.Date,transforms:[],frame(i){let e=Ae.frames.push({run:i});return Ae.nextDraw===null&&(Ae.nextDraw=Ne.window.requestAnimationFrame(Ae._draw)),e},timeout(i,e){e=e||0;let t=Ae.timer().now()+e,r=Ae.timeouts.push({run:i,time:t});return Ae.nextDraw===null&&(Ae.nextDraw=Ne.window.requestAnimationFrame(Ae._draw)),r},immediate(i){let e=Ae.immediates.push(i);return Ae.nextDraw===null&&(Ae.nextDraw=Ne.window.requestAnimationFrame(Ae._draw)),e},cancelFrame(i){i!=null&&Ae.frames.remove(i)},clearTimeout(i){i!=null&&Ae.timeouts.remove(i)},cancelImmediate(i){i!=null&&Ae.immediates.remove(i)},_draw(i){let e=null,t=Ae.timeouts.last();for(;(e=Ae.timeouts.shift())&&(i>=e.time?e.run():Ae.timeouts.push(e),e!==t););let r=null,n=Ae.frames.last();for(;r!==n&&(r=Ae.frames.shift());)r.run(i);let s=null;for(;s=Ae.immediates.shift();)s();Ae.nextDraw=Ae.timeouts.first()||Ae.frames.first()?Ne.window.requestAnimationFrame(Ae._draw):null}},vT=function(i){let e=i.start,t=i.runner.duration(),r=e+t;return{start:e,duration:t,end:r,runner:i.runner}},bT=function(){let i=Ne.window;return(i.performance||i.Date).now()},q0=class extends ts{constructor(e=bT){super(),this._timeSource=e,this._startTime=0,this._speed=1,this._persist=0,this._nextFrame=null,this._paused=!0,this._runners=[],this._runnerIds=[],this._lastRunnerId=-1,this._time=0,this._lastSourceTime=0,this._lastStepTime=0,this._step=this._stepFn.bind(this,!1),this._stepImmediate=this._stepFn.bind(this,!0)}active(){return!!this._nextFrame}finish(){return this.time(this.getEndTimeOfTimeline()+1),this.pause()}getEndTime(){let e=this.getLastRunnerInfo(),t=e?e.runner.duration():0;return(e?e.start:this._time)+t}getEndTimeOfTimeline(){let e=this._runners.map(t=>t.start+t.runner.duration());return Math.max(0,...e)}getLastRunnerInfo(){return this.getRunnerInfoById(this._lastRunnerId)}getRunnerInfoById(e){return this._runners[this._runnerIds.indexOf(e)]||null}pause(){return this._paused=!0,this._continue()}persist(e){return e==null?this._persist:(this._persist=e,this)}play(){return this._paused=!1,this.updateTime()._continue()}reverse(e){let t=this.speed();if(e==null)return this.speed(-t);let r=Math.abs(t);return this.speed(e?-r:r)}schedule(e,t,r){if(e==null)return this._runners.map(vT);let n=0,s=this.getEndTime();if(t=t||0,r==null||r==="last"||r==="after")n=s;else if(r==="absolute"||r==="start")n=t,t=0;else if(r==="now")n=this._time;else if(r==="relative"){let l=this.getRunnerInfoById(e.id);l&&(n=l.start+t,t=0)}else if(r==="with-last"){let l=this.getLastRunnerInfo();n=l?l.start:this._time}else throw new Error('Invalid value for the "when" parameter');e.unschedule(),e.timeline(this);let a=e.persist(),o={persist:a===null?this._persist:a,start:n+t,runner:e};return this._lastRunnerId=e.id,this._runners.push(o),this._runners.sort((l,h)=>l.start-h.start),this._runnerIds=this._runners.map(l=>l.runner.id),this.updateTime()._continue(),this}seek(e){return this.time(this._time+e)}source(e){return e==null?this._timeSource:(this._timeSource=e,this)}speed(e){return e==null?this._speed:(this._speed=e,this)}stop(){return this.time(0),this.pause()}time(e){return e==null?this._time:(this._time=e,this._continue(!0))}unschedule(e){let t=this._runnerIds.indexOf(e.id);return t<0?this:(this._runners.splice(t,1),this._runnerIds.splice(t,1),e.timeline(null),this)}updateTime(){return this.active()||(this._lastSourceTime=this._timeSource()),this}_continue(e=!1){return Ae.cancelFrame(this._nextFrame),this._nextFrame=null,e?this._stepImmediate():this._paused?this:(this._nextFrame=Ae.frame(this._step),this)}_stepFn(e=!1){let t=this._timeSource(),r=t-this._lastSourceTime;e&&(r=0);let n=this._speed*r+(this._time-this._lastStepTime);this._lastSourceTime=t,e||(this._time+=n,this._time=this._time<0?0:this._time),this._lastStepTime=this._time,this.fire("time",this._time);for(let a=this._runners.length;a--;){let o=this._runners[a],l=o.runner;this._time-o.start<=0&&l.reset()}let s=!1;for(let a=0,o=this._runners.length;a0?this._continue():(this.pause(),this.fire("finished")),this}};fe({Element:{timeline:function(i){return i==null?(this._timeline=this._timeline||new q0,this._timeline):(this._timeline=i,this)}}});Gi=class i extends ts{constructor(e){super(),this.id=i.id++,e=e??Mo.duration,e=typeof e=="function"?new Qs(e):e,this._element=null,this._timeline=null,this.done=!1,this._queue=[],this._duration=typeof e=="number"&&e,this._isDeclarative=e instanceof Qs,this._stepper=this._isDeclarative?e:new ko,this._history={},this.enabled=!0,this._time=0,this._lastTime=0,this._reseted=!0,this.transforms=new be,this.transformId=1,this._haveReversed=!1,this._reverse=!1,this._loopsDone=0,this._swing=!1,this._wait=0,this._times=1,this._frameId=null,this._persist=this._isDeclarative?!0:null}static sanitise(e,t,r){let n=1,s=!1,a=0;return e=e||Mo.duration,t=t||Mo.delay,r=r||"last",typeof e=="object"&&!(e instanceof Ao)&&(t=e.delay||t,r=e.when||r,s=e.swing||s,n=e.times||n,a=e.wait||a,e=e.duration||Mo.duration),{duration:e,delay:t,swing:s,times:n,wait:a,when:r}}active(e){return e==null?this.enabled:(this.enabled=e,this)}addTransform(e,t){return this.transforms.lmultiplyO(e),this}after(e){return this.on("finished",e)}animate(e,t,r){let n=i.sanitise(e,t,r),s=new i(n.duration);return this._timeline&&s.timeline(this._timeline),this._element&&s.element(this._element),s.loop(n).schedule(n.delay,n.when)}clearTransform(){return this.transforms=new be,this}clearTransformsFromQueue(){(!this.done||!this._timeline||!this._timeline._runnerIds.includes(this.id))&&(this._queue=this._queue.filter(e=>!e.isTransform))}delay(e){return this.animate(0,e)}duration(){return this._times*(this._wait+this._duration)-this._wait}during(e){return this.queue(null,e)}ease(e){return this._stepper=new ko(e),this}element(e){return e==null?this._element:(this._element=e,e._prepareRunner(),this)}finish(){return this.step(1/0)}loop(e,t,r){return typeof e=="object"&&(t=e.swing,r=e.wait,e=e.times),this._times=e||1/0,this._swing=t||!1,this._wait=r||0,this._times===!0&&(this._times=1/0),this}loops(e){let t=this._duration+this._wait;if(e==null){let a=Math.floor(this._time/t),l=(this._time-a*t)/this._duration;return Math.min(a+l,this._times)}let r=Math.floor(e),n=e%1,s=t*r+this._duration*n;return this.time(s)}persist(e){return e==null?this._persist:(this._persist=e,this)}position(e){let t=this._time,r=this._duration,n=this._wait,s=this._times,a=this._swing,o=this._reverse,l;if(e==null){let f=function(g){let x=a*Math.floor(g%(2*(n+r))/(n+r)),y=x&&!o||!x&&o,b=Math.pow(-1,y)*(g%(n+r))/r+y;return Math.max(Math.min(b,1),0)},m=s*(n+r)-n;return l=t<=0?Math.round(f(1e-5)):t=0;this._lastPosition=t;let n=this.duration(),s=this._lastTime<=0&&this._time>0,a=this._lastTime=n;this._lastTime=this._time,s&&this.fire("start",this);let o=this._isDeclarative;this.done=!o&&!a&&this._time>=n,this._reseted=!1;let l=!1;return(r||o)&&(this._initialise(r),this.transforms=new be,l=this._run(o?e:t),this.fire("step",this)),this.done=this.done||l&&o,a&&this.fire("finished",this),this}time(e){if(e==null)return this._time;let t=e-this._time;return this.step(t),this}timeline(e){return typeof e>"u"?this._timeline:(this._timeline=e,this)}unschedule(){let e=this.timeline();return e&&e.unschedule(this),this}_initialise(e){if(!(!e&&!this._isDeclarative))for(let t=0,r=this._queue.length;ti.lmultiplyO(e),w2=i=>i.transforms;fu=class{constructor(){this.runners=[],this.ids=[]}add(e){if(this.runners.includes(e))return;let t=e.id+1;return this.runners.push(e),this.ids.push(t),this}clearBefore(e){let t=this.ids.indexOf(e+1)||1;return this.ids.splice(0,t,0),this.runners.splice(0,t,new Js).forEach(r=>r.clearTransformsFromQueue()),this}edit(e,t){let r=this.ids.indexOf(e+1);return this.ids.splice(r,1,e+1),this.runners.splice(r,1,t),this}getByID(e){return this.runners[this.ids.indexOf(e+1)]}length(){return this.ids.length}merge(){let e=null;for(let t=0;te.id<=i.id).map(w2).reduce(b2,new be)},_addRunner(i){this._transformationRunners.add(i),Ae.cancelImmediate(this._frameId),this._frameId=Ae.immediate(wT.bind(this))},_prepareRunner(){this._frameId==null&&(this._transformationRunners=new fu().add(new Js(new be(this))))}}});MT=(i,e)=>i.filter(t=>!e.includes(t));xe(Gi,{attr(i,e){return this.styleAttr("attr",i,e)},css(i,e){return this.styleAttr("css",i,e)},styleAttr(i,e,t){if(typeof e=="string")return this.styleAttr(i,{[e]:t});let r=e;if(this._tryRetarget(i,r))return this;let n=new Tr(this._stepper).to(r),s=Object.keys(r);return this.queue(function(){n=n.from(this.element()[i](s))},function(a){return this.element()[i](n.at(a).valueOf()),n.done()},function(a){let o=Object.keys(a),l=MT(o,s);if(l.length){let d=this.element()[i](l),c=new ss(n.from()).valueOf();Object.assign(c,d),n.from(c)}let h=new ss(n.to()).valueOf();Object.assign(h,a),n.to(h),s=o,r=a}),this._rememberMorpher(i,n),this},zoom(i,e){if(this._tryRetarget("zoom",i,e))return this;let t=new Tr(this._stepper).to(new we(i));return this.queue(function(){t=t.from(this.element().zoom())},function(r){return this.element().zoom(t.at(r),e),t.done()},function(r,n){e=n,t.to(r)}),this._rememberMorpher("zoom",t),this},transform(i,e,t){if(e=i.relative||e,this._isDeclarative&&!e&&this._tryRetarget("transform",i))return this;let r=be.isMatrixLike(i);t=i.affine!=null?i.affine:t??!r;let n=new Tr(this._stepper).type(t?_o:be),s,a,o,l,h;function d(){a=a||this.element(),s=s||au(i,a),h=new be(e?void 0:a),a._addRunner(this),e||a._clearTransformRunnersBefore(this)}function c(m){e||this.clearTransform();let{x:g,y:x}=new it(s).transform(a._currentTransform(this)),y=new be({...i,origin:[g,x]}),b=this._isDeclarative&&o?o:h;if(t){y=y.decompose(g,x),b=b.decompose(g,x);let k=y.rotate,L=b.rotate,I=[k-360,k,k+360],O=I.map(W=>Math.abs(W-L)),q=Math.min(...O),F=O.indexOf(q);y.rotate=I[F]}e&&(r||(y.rotate=i.rotate||0),this._isDeclarative&&l&&(b.rotate=l)),n.from(b),n.to(y);let E=n.at(m);return l=E.rotate,o=new be(E),this.addTransform(o),a._addRunner(this),n.done()}function f(m){(m.origin||"center").toString()!==(i.origin||"center").toString()&&(s=au(m,a)),i={...m,origin:s}}return this.queue(d,c,f,!0),this._isDeclarative&&this._rememberMorpher("transform",n),this},x(i,e){return this._queueNumber("x",i)},y(i){return this._queueNumber("y",i)},dx(i=0){return this._queueNumberDelta("x",i)},dy(i=0){return this._queueNumberDelta("y",i)},dmove(i,e){return this.dx(i).dy(e)},_queueNumberDelta(i,e){if(e=new we(e),this._tryRetarget(i,e))return this;let t=new Tr(this._stepper).to(e),r=null;return this.queue(function(){r=this.element()[i](),t.from(r),t.to(r+e)},function(n){return this.element()[i](t.at(n)),t.done()},function(n){t.to(r+new we(n))}),this._rememberMorpher(i,t),this},_queueObject(i,e){if(this._tryRetarget(i,e))return this;let t=new Tr(this._stepper).to(e);return this.queue(function(){t.from(this.element()[i]())},function(r){return this.element()[i](t.at(r)),t.done()}),this._rememberMorpher(i,t),this},_queueNumber(i,e){return this._queueObject(i,new we(e))},cx(i){return this._queueNumber("cx",i)},cy(i){return this._queueNumber("cy",i)},move(i,e){return this.x(i).y(e)},center(i,e){return this.cx(i).cy(e)},size(i,e){let t;return(!i||!e)&&(t=this._element.bbox()),i||(i=t.width/t.height*e),e||(e=t.height/t.width*i),this.width(i).height(e)},width(i){return this._queueNumber("width",i)},height(i){return this._queueNumber("height",i)},plot(i,e,t,r){if(arguments.length===4)return this.plot([i,e,t,r]);if(this._tryRetarget("plot",i))return this;let n=new Tr(this._stepper).type(this._element.MorphArray).to(i);return this.queue(function(){n.from(this._element.array())},function(s){return this._element.plot(n.at(s)),n.done()}),this._rememberMorpher("plot",n),this},leading(i){return this._queueNumber("leading",i)},viewbox(i,e,t,r){return this._queueObject("viewbox",new Vt(i,e,t,r))},update(i){return typeof i!="object"?this.update({offset:arguments[0],color:arguments[1],opacity:arguments[2]}):(i.opacity!=null&&this.attr("stop-opacity",i.opacity),i.color!=null&&this.attr("stop-color",i.color),i.offset!=null&&this.attr("offset",i.offset),this)}});xe(Gi,{rx:vu,ry:bu,from:g2,to:x2});Me(Gi,"Runner");Lo=class extends Yt{constructor(e,t=e){super(Ue("svg",e),t),this.namespace()}defs(){return this.isRoot()?Ni(this.node.querySelector("defs"))||this.put(new So):this.root().defs()}isRoot(){return!this.node.parentNode||!(this.node.parentNode instanceof Ne.window.SVGElement)&&this.node.parentNode.nodeName!=="#document-fragment"}namespace(){return this.isRoot()?this.attr({xmlns:pu,version:"1.1"}).attr("xmlns:xlink",Bo,P0).attr("xmlns:svgjs",jw,P0):this.root().namespace()}removeNamespace(){return this.attr({xmlns:null,version:null}).attr("xmlns:xlink",null,P0).attr("xmlns:svgjs",null,P0)}root(){return this.isRoot()?this:super.root()}};fe({Container:{nested:He(function(){return this.put(new Lo)})}});Me(Lo,"Svg",!0);Io=class extends Yt{constructor(e,t=e){super(Ue("symbol",e),t)}};fe({Container:{symbol:He(function(){return this.put(new Io)})}});Me(Io,"Symbol");M2={__proto__:null,plain:TT,length:NT,x:ET,y:ST,move:AT,cx:kT,cy:CT,center:_T,ax:LT,ay:IT,amove:zT,build:RT},_e=class extends Dt{constructor(e,t=e){super(Ue("text",e),t),this.dom.leading=new we(1.3),this._rebuild=!0,this._build=!1}leading(e){return e==null?this.dom.leading:(this.dom.leading=new we(e),this.rebuild())}rebuild(e){if(typeof e=="boolean"&&(this._rebuild=e),this._rebuild){let t=this,r=0,n=this.dom.leading;this.each(function(s){let a=Ne.window.getComputedStyle(this.node).getPropertyValue("font-size"),o=n*new we(a);this.dom.newLined&&(this.attr("x",t.attr("x")),this.text()===` +`?r+=o:(this.attr("dy",s?o+r:0),r=0))}),this.fire("rebuild")}return this}setData(e){return this.dom=e,this.dom.leading=new we(e.leading||1.3),this}text(e){if(e===void 0){let t=this.node.childNodes,r=0;e="";for(let n=0,s=t.length;n(i.attr("href")||"").includes(this.id()))}}});_o.prototype.MorphArray=Er;be(_o,"TextPath");R0=class extends Dt{constructor(e,t=e){super(qe("use",e),t)}use(e,t){return this.attr("href",(t||"")+"#"+e,Lo)}};fe({Container:{use:Fe(function(i,e){return this.put(new R0).use(i,e)})}});be(R0,"Use");Ae=Rt;ge([Eo,So,ji,rs,Ks],Wt("viewbox"));ge([ns,as,Gi,ar],Wt("marker"));ge(Ce,Wt("Text"));ge(ar,Wt("Path"));ge(bo,Wt("Defs"));ge([Ce,Js],Wt("Tspan"));ge([Ve,Xs,is,Vi],Wt("radius"));ge(ts,Wt("EventTarget"));ge(dn,Wt("Dom"));ge(Ei,Wt("Element"));ge(Dt,Wt("Shape"));ge([Vt,L0],Wt("Container"));ge(is,Wt("Gradient"));ge(Vi,Wt("Runner"));Nr.extend(gw());UM([ye,Ni,Gt,xe,hn,sr,Er,it]);$M()});var O0=rr((nU,c2)=>{"use strict";var D0=function(e){return wT(e)&&!MT(e)};function wT(i){return!!i&&typeof i=="object"}function MT(i){var e=Object.prototype.toString.call(i);return e==="[object RegExp]"||e==="[object Date]"||ET(i)}var TT=typeof Symbol=="function"&&Symbol.for,NT=TT?Symbol.for("react.element"):60103;function ET(i){return i.$$typeof===NT}function ST(i){return Array.isArray(i)?[]:{}}function Io(i,e){var t=e&&e.clone===!0;return t&&D0(i)?ra(ST(i),i,e):i}function d2(i,e,t){var r=i.slice();return e.forEach(function(n,s){typeof r[s]>"u"?r[s]=Io(n,t):D0(n)?r[s]=ra(i[s],n,t):i.indexOf(n)===-1&&r.push(Io(n,t))}),r}function AT(i,e,t){var r={};return D0(i)&&Object.keys(i).forEach(function(n){r[n]=Io(i[n],t)}),Object.keys(e).forEach(function(n){!D0(e[n])||!i[n]?r[n]=Io(e[n],t):r[n]=ra(i[n],e[n],t)}),r}function ra(i,e,t){var r=Array.isArray(e),n=Array.isArray(i),s=t||{arrayMerge:d2},a=r===n;if(a)if(r){var o=s.arrayMerge||d2;return o(i,e,t)}else return AT(i,e,t);else return Io(e,t)}ra.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce(function(r,n){return ra(r,n,t)})};var kT=ra;c2.exports=kT});var B0,CT,u2,zo,Ro=T(()=>{B0={paddingX:15,paddingY:5,imgMaxWidth:200,imgMaxHeight:100,iconSize:20,lineWidth:1,lineColor:"#549688",lineDasharray:"none",lineFlow:!1,lineFlowDuration:1,lineFlowForward:!0,lineStyle:"straight",rootLineKeepSameInCurve:!0,rootLineStartPositionKeepSameInCurve:!1,lineRadius:5,showLineMarker:!1,generalizationLineWidth:1,generalizationLineColor:"#549688",generalizationLineMargin:0,generalizationNodeMargin:20,associativeLineWidth:2,associativeLineColor:"rgb(51, 51, 51)",associativeLineActiveWidth:8,associativeLineActiveColor:"rgba(2, 167, 240, 1)",associativeLineDasharray:"6,4",associativeLineTextColor:"rgb(51, 51, 51)",associativeLineTextFontSize:14,associativeLineTextLineHeight:1.2,associativeLineTextFontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",backgroundColor:"#fafafa",backgroundImage:"none",backgroundRepeat:"no-repeat",backgroundPosition:"center center",backgroundSize:"cover",nodeUseLineStyle:!1,root:{shape:"rectangle",fillColor:"#549688",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#fff",fontSize:16,fontWeight:"bold",fontStyle:"normal",borderColor:"transparent",borderWidth:0,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},second:{shape:"rectangle",marginX:100,marginY:40,fillColor:"#fff",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#565656",fontSize:16,fontWeight:"normal",fontStyle:"normal",borderColor:"#549688",borderWidth:1,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},node:{shape:"rectangle",marginX:50,marginY:0,fillColor:"transparent",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#6a6d6c",fontSize:14,fontWeight:"normal",fontStyle:"normal",borderColor:"transparent",borderWidth:0,borderRadius:5,borderDasharray:"none",textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},generalization:{shape:"rectangle",marginX:100,marginY:40,fillColor:"#fff",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#565656",fontSize:16,fontWeight:"normal",fontStyle:"normal",borderColor:"#549688",borderWidth:1,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"}},CT=["lineWidth","lineColor","lineDasharray","lineStyle","generalizationLineWidth","generalizationLineColor","associativeLineWidth","associativeLineColor","associativeLineActiveWidth","associativeLineActiveColor","associativeLineTextColor","associativeLineTextFontSize","associativeLineTextLineHeight","associativeLineTextFontFamily","backgroundColor","backgroundImage","backgroundRepeat","backgroundPosition","backgroundSize","rootLineKeepSameInCurve","rootLineStartPositionKeepSameInCurve","showLineMarker","lineRadius","hoverRectColor","hoverRectRadius","lineFlow","lineFlowDuration","lineFlowForward","textAlign"],u2=i=>{let e=Object.keys(i);for(let t=0;tr===e[t]))return!1;return!0},zo=["lineColor","lineDasharray","lineWidth","lineMarkerDir","lineFlow","lineFlowDuration","lineFlowForward"]});var f2,de,Xt,U0,na,Kt,uu,ls,fu,m2,Si,p2,Zt,fn,g2,x2,y2,P0,sa,aa,_T,wt,v2,b2,os,Yt,F0,w2,Do,M2,Oo,mu,$0,LT,q0,j0,un,T2,N2,hs,E2,S2,ds,A2,k2,oa,la,Bo,cs,Ot,ha,Ie,G0,mn,H0,pu,gu,C2,V0,_2,L2,I2,xu,Po,yu,vu,z2,R2,bu,D2,IT,cU,pn,us,or,Fo,wu,O2,pe=T(()=>{Hc();$e();I3();yt();f2=pt(O0());Ro();de=(i,e,t,r,n,s=0,a=0,o=[])=>{let l=!1;if(t&&(l=t(i,e,n,s,a,o)),!l&&i.children&&i.children.length>0){let h=s+1;i.children.forEach((d,c)=>{de(d,i,t,r,!1,h,c,[...o,i])})}r&&r(i,e,n,s,a,o)},Xt=(i,e)=>{let t=[i],r=!1;for(e(i,null)==="stop"&&(r=!0);t.length&&!r;){let n=t.shift();n.children&&n.children.length&&n.children.forEach(s=>{r||(t.push(s),e(s,n)==="stop"&&(r=!0))})}},U0=(i,e,t,r)=>{let n=i/e,s=[];if(t&&r)if(i<=t&&e<=r)s=[i,e];else{let a=t/r;n>a?s=[t,t/n]:s=[n*r,r]}else t?i<=t?s=[i,e]:s=[t,t/n]:r&&(e<=r?s=[i,e]:s=[n*r,r]);return s},na=i=>{i=i.replace(/
    /gim,` -`);let e=document.createElement("div");return e.innerHTML=i,i=e.textContent,i},Kt=i=>{try{return JSON.parse(JSON.stringify(i))}catch{return null}},uu=(i,e,t=!1)=>(i.data=Kt(e.data),t&&(i.data.isActive=!1,us(i.data).forEach(n=>{n.isActive=!1})),i.children=[],e.children&&e.children.length>0&&e.children.forEach((r,n)=>{i.children[n]=uu({},r,t)}),Object.keys(e).forEach(r=>{!["data","children"].includes(r)&&!/^_/.test(r)&&(i[r]=e[r])}),i),ls=(i,e,t=!1,r=!0)=>{let n=e.nodeData?e.nodeData:e;return i.data=Kt(n.data),r?delete i.data.uid:i.data.uid||(i.data.uid=wt()),t&&(i.data.isActive=!1),i.children=[],e.children&&e.children.length>0?e.children.forEach((s,a)=>{i.children[a]=ls({},s,t,r)}):e.nodeData&&e.nodeData.children&&e.nodeData.children.length>0&&e.nodeData.children.forEach((s,a)=>{i.children[a]=ls({},s,t,r)}),Object.keys(n).forEach(s=>{!["data","children"].includes(s)&&!/^_/.test(s)&&(i[s]=n[s])}),i},fu=(i,e=!1)=>new Promise((t,r)=>{let n=new Image;n.setAttribute("crossOrigin","anonymous"),n.onload=()=>{try{let s=document.createElement("canvas");s.width=n.width,s.height=n.height,s.getContext("2d").drawImage(n,0,0,n.width,n.height),e?s.toBlob(o=>{t(o)}):t(s.toDataURL())}catch(s){r(s)}},n.onerror=s=>{r(s)},n.src=i}),m2=(i,e)=>{let t=document.createElement("a");t.href=i,t.download=e,t.click()},Si=(i,e=300,t)=>{let r=null;return(...n)=>{r||(r=setTimeout(()=>{i.call(t,...n),r=null},e))}},p2=(i,e=300,t)=>{let r=null;return(...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{r=null,i.apply(t,n)},e)}},Zt=(i,e=()=>{})=>{let t=0,r=i.length;if(r<=0)return e();let n=()=>{if(t>=r){e();return}i[t](),setTimeout(()=>{t++,n()},0)};n()},fn=i=>i*(Math.PI/180),g2=i=>i.replace(/([a-z])([A-Z])/g,(...e)=>e[1]+"-"+e[2].toLowerCase()),x2=function(i,e){let t=!1,r=null,n=()=>{t=!1,e?i.call(e):i()};if(typeof MutationObserver<"u"){let s=1,a=new MutationObserver(n),o=document.createTextNode(s);a.observe(o,{characterData:!0}),r=function(){s=(s+1)%2,o.data=s}}else r=setTimeout;return function(){t||(t=!0,r(n,0))}},y2=(i,e,t=0,r=0)=>{let n=i.elRect,{scaleX:s,scaleY:a,translateX:o,translateY:l}=i.draw.transform(),{left:h,top:d,width:c,height:f}=e,m=(h+c)*s+o,g=(d+f)*a+l;h=h*s+o,d=d*a+l;let x=0,y=0;return h<0+t&&(x=-h+t),m>n.width-t&&(x=-(m-n.width)-t),d<0+r&&(y=-d+r),g>n.height-r&&(y=-(g-n.height)-r),{isOuter:x!==0||y!==0,offsetLeft:x,offsetTop:y}},P0=null,sa=i=>(P0||(P0=document.createElement("div")),P0.innerHTML=i,P0.textContent),aa=i=>new Promise((e,t)=>{let r=new FileReader;r.onload=n=>{e(n.target.result)},r.onerror=n=>{t(n)},r.readAsDataURL(i)}),_T=i=>new Promise(e=>{let t=new Image;t.src=i,t.onload=()=>{e({width:t.width,height:t.height})},t.onerror=()=>{e({width:0,height:0})}}),wt=()=>fo(),v2=i=>new Promise((e,t)=>{let r=new FileReader;r.readAsDataURL(i),r.onload=async n=>{let s=n.target.result,a=await _T(s);e({url:s,size:a})},r.onerror=n=>{t(n)}}),b2=i=>([[" "," "]].forEach(e=>{i=i.replace(new RegExp(e[0],"g"),e[1])}),i),os=i=>Object.prototype.toString.call(i).slice(8,-1),Yt=i=>i==null||i==="",F0=null,w2=i=>{F0||(F0=document.createElement("div")),F0.innerHTML=i;for(let e=F0.childNodes,t=e.length;t--;)if(e[t].nodeType==1)return!0;return!1},Do=null,M2=(i,e,t)=>{Do||(Do=document.createElement("div")),Do.innerHTML=i;let r=n=>{n.childNodes.forEach(a=>{a.nodeType===1?r(a):a.nodeType===3&&n.replaceChild(document.createTextNode(a.nodeValue.replace(new RegExp(e,"g"),t)),a)})};return r(Do),Do.innerHTML},Oo=i=>(i=String(i).replace(/\s+/g,""),["#fff","#ffffff","#FFF","#FFFFFF","rgb(255,255,255)"].includes(i)||/rgba\(255,255,255,[^)]+\)/.test(i)),mu=i=>(i=String(i).replace(/\s+/g,""),["","transparent"].includes(i)||/rgba\(\d+,\d+,\d+,0\)/.test(i)),$0=i=>{let{lineColor:e,root:t,second:r,node:n}=i,s=[e,t.fillColor,t.color,r.fillColor,r.color,n.fillColor,n.color,t.borderColor,r.borderColor,n.borderColor];for(let a=0;a{let e=t=>{t.childNodes.forEach(n=>{n.nodeType===1&&(n.classList.contains("ql-formula")?n.parentNode.removeChild(n):e(n))})};e(i)},q0=null,j0=i=>{q0||(q0=document.createElement("div")),q0.innerHTML=i;let e=q0.childNodes,t="";for(let r=0;r{un||(un=document.createElement("div")),un.innerHTML=i;let e=un.querySelectorAll(".ql-formula");Array.from(e).forEach(n=>{let s=document.createTextNode("$smmformula$");n.parentNode.replaceChild(s,n)});let t=un.childNodes,r=[];for(let n=0;n`

    ${mn(n)}

    `).join(""),e.length>0){i=i.replace(/\$smmformula\$/g,''),un.innerHTML=i;let n=un.querySelectorAll(".smmformula");Array.from(n).forEach((s,a)=>{s.parentNode.replaceChild(e[a],s)}),i=un.innerHTML}return i},N2=(i,e)=>{let t={};return Object.keys(e).forEach(r=>{let n=i[r],s=e[r];if(os(n)!==os(s)){t[r]=s;return}if(os(n)==="Object"){if(JSON.stringify(n)!==JSON.stringify(s)){t[r]=s;return}}else if(n!==s){t[r]=s;return}}),t},hs=i=>/^_/.test(i)?!1:!$s.includes(i),E2=i=>{let e=[...zo],t=Object.keys(i);for(let r=0;ri.reduce((e,t)=>{let r=e.find(n=>n.type===t.type);return r?t.list.forEach(n=>{let s=r.list.find(a=>a.name===n.name);s?s.icon=n.icon:r.list.push(n)}):e.push({...t}),e},[]),ds=i=>{let e=[];return i.forEach(t=>{i.find(r=>r.uid!==t.uid&&r.isAncestor(t))||e.push(t)}),e},A2=i=>{let e={},t={};i.forEach(n=>{let s=n.parent;if(s){let a=s.uid;t[a]=s;let o=n.getIndexInBrothers(),l={node:n,index:o};e[a]?e[a].find(h=>h.index===l.index)||e[a].push(l):e[a]=[l]}});let r=[];return Object.keys(e).forEach(n=>{if(e[n].length>1){let s=e[n].map(a=>a.index).sort((a,o)=>a-o);r.push({node:t[n],range:[s[0],s[s.length-1]]})}else r.push({node:e[n][0].node})}),r},k2=(i,e,t,r,n,s,a,o)=>e>n&&s>i&&r>a&&o>t,oa=i=>{let e=window.getSelection(),t=document.createRange();t.selectNodeContents(i),t.collapse(),e.removeAllRanges(),e.addRange(t)},la=i=>{let e=window.getSelection(),t=document.createRange();t.selectNodeContents(i),e.removeAllRanges(),e.addRange(t)},Bo=(i,e={})=>{e={...e},e&&e.richText&&e.resetRichText&&delete e.resetRichText;let r=n=>{n.forEach(s=>{s.data={...s.data,...e},s.children&&s.children.length>0&&r(s.children)})};return r(i),i},cs=(i,e=!1,t=null,r=!1)=>{let n=s=>{s.forEach(a=>{a.data||(a.data={}),(e||Yt(a.data.uid))&&(a.data.uid=wt()),r&&us(a.data).forEach(l=>{(e||Yt(l.uid))&&(l.uid=wt())}),t&&t(a),a.children&&a.children.length>0&&n(a.children)})};return n(i),i},Ot=i=>i?Array.isArray(i)?i:[i]:[],ha=i=>i.parent?i.parent.nodeData.children.findIndex(e=>e.data.uid===i.uid):0,Ie=(i,e)=>e.findIndex(t=>t.uid===i.uid),G0=i=>{let e=0;for(let n=0;n([["&","&"],["<","<"],[">",">"]].forEach(e=>{i=i.replace(new RegExp(e[0],"g"),e[1])}),i),H0=(i,e)=>{let t=os(i);if(t!==os(e))return!1;if(t==="Object"){let r=Object.keys(i),n=Object.keys(e);if(r.length!==n.length)return!1;for(let s=0;snavigator.clipboard&&typeof navigator.clipboard.read=="function",gu=i=>{navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(JSON.stringify(i))},C2=async()=>{let i=null,e=null;if(pu()){let t=await navigator.clipboard.read();if(t&&t.length>0)for(let r of t)for(let n of r.types)/^image\//.test(n)?e=await r.getType(n):n==="text/plain"&&(i=await(await r.getType(n)).text())}return{text:i,img:e}},V0=i=>{if(!i||!i.parent)return;let e=ha(i);e!==-1&&i.parent.nodeData.children.splice(e,1)},_2=i=>(_3.forEach(e=>{i=i.replace(new RegExp(`<${e}([^>]*)>`,"g"),`<${e} $1 />`)}),i),L2=(i,e)=>{if(i.length!==e.length)return!1;for(let t=0;tr.uid===i[t].uid))return!1;return!0},I2=()=>{let i=navigator.userAgent.match(/\s+Chrome\/(.*)\s+/);return i&&i[1]?Number.parseFloat(i[1]):""},xu=i=>({simpleMindMap:!0,data:i}),Po=i=>{let e=null;if(typeof i=="string")try{let r=JSON.parse(i);typeof r=="object"&&r.simpleMindMap&&(e=r.data)}catch{}else typeof i=="object"&&i.simpleMindMap&&(e=i.data);let t=!!e;return{isSmm:t,data:t?e:String(i)}},yu=(i,e)=>{i.preventDefault();let t=window.getSelection();if(!t.rangeCount)return;t.deleteFromDocument(),e=e||i.clipboardData.getData("text"),e=mn(e),e=sa(e);let r=e.split(/\n/g),n=document.createDocumentFragment();r.forEach((s,a)=>{let o=document.createTextNode(s);if(n.appendChild(o),a{let e={},t=(r,n)=>{let s=r.data.uid;n&&n.children.push(s),e[s]={isRoot:!n,data:{...r.data},children:[]},r.children&&r.children.length>0&&r.children.forEach(a=>{t(a,e[s])})};return t(i,null),e},z2=(i,e)=>{let t=i.x+i.width/2,r=i.y+i.height/2,n=e.x+e.width/2,s=e.y+e.height/2;return tn&&rn&&r>s?"right-bottom":ts?"left-bottom":tn&&r===s?"right":t===n&&rs?"bottom":"overlap"},R2=({addContentToHeader:i,addContentToFooter:e})=>{let t=[],r=null,n=0,s=null,a=0,o=(l,h)=>{if(typeof l=="function"){let d=l();if(!d)return;let{el:c,cssText:f,height:m}=d;if(c instanceof HTMLElement){or(c);let g=pn({el:c,height:m});h(g,m)}f&&t.push(f)}};return o(i,(l,h)=>{r=l,n=h}),o(e,(l,h)=>{s=l,a=h}),{cssTextList:t,header:r,headerHeight:n,footer:s,footerHeight:a}},bu=(i,e=0,t=0,r=0,n=0,s=!1,a=!1)=>{let o=1/0,l=-1/0,h=1/0,d=-1/0,c=(f,m)=>{if(!(m&&s)&&f.group)try{let{x:g,y:x,width:y,height:b}=f.group.findOne(".smm-node-shape").rbox();gl&&(l=g+y),xd&&(d=x+b)}catch{}!a&&f._generalizationList.length>0&&f._generalizationList.forEach(g=>{c(g.generalizationNode)}),f.children&&f.children.forEach(g=>{c(g)})};return c(i,!0),o=o-e+r,h=h-t+n,l=l-e+r,d=d-t+n,{left:o,top:h,width:l-o,height:d-h}},D2=(i,e=0,t=0,r=0,n=0)=>{let s=1/0,a=-1/0,o=1/0,l=-1/0;return i.forEach(h=>{let{left:d,top:c,width:f,height:m}=bu(h,e,t,r,n,!1,!0);da&&(a=d+f),cl&&(l=c+m)}),{left:s,top:o,width:a-s,height:l-o}},IT=()=>{if(document.documentElement.requestFullScreen)return"fullscreenchange";if(document.documentElement.webkitRequestFullScreen)return"webkitfullscreenchange";if(document.documentElement.mozRequestFullScreen)return"mozfullscreenchange";if(document.documentElement.msRequestFullscreen)return"msfullscreenchange"},cU=IT(),pn=({el:i,width:e,height:t})=>{let r=new ea;return e!==void 0&&r.width(e),t!==void 0&&r.height(t),r.add(i),r},us=i=>{let e=i.generalization;return e?Array.isArray(e)?e:[e]:[]},or=i=>{i.setAttribute("xmlns","http://www.w3.org/1999/xhtml")},Fo=i=>(i=[...i],i.sort((e,t)=>e.sortIndex-t.sortIndex),i),wu=(i,e)=>(0,f2.default)(i,e,{arrayMerge:(t,r)=>r}),O2=i=>{let e={};return L3.forEach(t=>{let r=i.style.merge(t);t==="fontSize"&&(r=r+"px"),e[t]=r}),e}});var B2,Mu,W0,qo,Y0=T(()=>{pe();B2=["backgroundColor","backgroundImage","backgroundRepeat","backgroundPosition","backgroundSize"],Mu=["gradientStyle","startColor","endColor","startDir","endDir","fillColor","borderColor","borderWidth","borderDasharray"],W0=class i{static setBackgroundStyle(e,t){if(!e)return;if(!i.cacheStyle){i.cacheStyle={};let l=window.getComputedStyle(e);B2.forEach(h=>{i.cacheStyle[h]=l[h]})}let{backgroundColor:r,backgroundImage:n,backgroundRepeat:s,backgroundPosition:a,backgroundSize:o}=t;e.style.backgroundColor=r,n&&n!=="none"?(e.style.backgroundImage=`url(${n})`,e.style.backgroundRepeat=s,e.style.backgroundPosition=a,e.style.backgroundSize=o):e.style.backgroundImage="none"}static removeBackgroundStyle(e){i.cacheStyle&&(B2.forEach(t=>{e.style[t]=i.cacheStyle[t]}),i.cacheStyle=null)}constructor(e){this.ctx=e,this._markerPath=null,this._marker=null,this._gradient=null}merge(e,t){let r=this.ctx.mindMap.themeConfig,n=null,s=!1;t?(s=!0,n=r):this.ctx.isGeneralization?n=r.generalization:this.ctx.layerIndex===0?n=r.root:this.ctx.layerIndex===1?n=r.second:n=r.node;let a="";return this.getSelfStyle(e)!==void 0?a=this.getSelfStyle(e):n[e]!==void 0?a=n[e]:a=r[e],s||this.addToEffectiveStyles({[e]:a}),a}getStyle(e,t){return this.merge(e,t)}getSelfStyle(e){return this.ctx.getData(e)}addToEffectiveStyles(e){this.ctx.mindMap.painter&&(this.ctx.effectiveStyles={...this.ctx.effectiveStyles,...e})}rect(e){this.shape(e),e.radius(this.merge("borderRadius"))}shape(e){let t={};Mu.forEach(r=>{t[r]=this.merge(r)}),t.gradientStyle?(this._gradient||(this._gradient=this.ctx.nodeDraw.gradient("linear")),this._gradient.update(r=>{r.stop(0,t.startColor),r.stop(1,t.endColor)}),this._gradient.from(...t.startDir).to(...t.endDir),e.fill(this._gradient)):e.fill({color:t.fillColor}),e.stroke({color:t.borderColor,width:t.borderWidth,dasharray:t.borderDasharray})}text(e){let t={color:this.merge("color"),fontFamily:this.merge("fontFamily"),fontSize:this.merge("fontSize"),fontWeight:this.merge("fontWeight"),fontStyle:this.merge("fontStyle"),textDecoration:this.merge("textDecoration")};e.fill({color:t.color}).css({"font-family":t.fontFamily,"font-size":t.fontSize+"px","font-weight":t.fontWeight,"font-style":t.fontStyle,"text-decoration":t.textDecoration})}domText(e,t=1){let r={color:this.merge("color"),fontFamily:this.merge("fontFamily"),fontSize:this.merge("fontSize"),fontWeight:this.merge("fontWeight"),fontStyle:this.merge("fontStyle"),textDecoration:this.merge("textDecoration"),textAlign:this.merge("textAlign")};e.style.color=r.color,e.style.textDecoration=r.textDecoration,e.style.fontFamily=r.fontFamily,e.style.fontSize=r.fontSize*t+"px",e.style.fontWeight=r.fontWeight||"normal",e.style.fontStyle=r.fontStyle,e.style.textAlign=r.textAlign}tagText(e,t){e.fill({color:"#fff"}).css({"font-size":t.fontSize+"px"})}tagRect(e,t){e.fill({color:t.fill}),t.radius&&e.radius(t.radius)}iconNode(e,t){e.attr({fill:t||this.merge("color")})}line(e,{width:t,color:r,dasharray:n}={},s,a){let{customHandleLine:o}=this.ctx.mindMap.opt;if(typeof o=="function"&&o(this.ctx,e,{width:t,color:r,dasharray:n}),e.stroke({color:r,dasharray:n,width:t}).fill({color:"none"}),s){let l=this.merge("showLineMarker",!0),h=a.style;if(l){h._marker=h._marker||h.createMarker(),h._markerPath.stroke({color:r}).fill({color:r}),e.attr("marker-start",""),e.attr("marker-end","");let d=h.merge("lineMarkerDir");e.marker(d,h._marker)}else h._marker&&(e.attr("marker-start",""),e.attr("marker-end",""),h._marker.remove(),h._marker=null)}}createMarker(){return this.ctx.lineDraw.marker(20,20,e=>{e.ref(8,5),e.size(20,20),e.attr("markerUnits","userSpaceOnUse"),e.attr("orient","auto-start-reverse"),this._markerPath=e.path("M0,0 L2,5 L0,10 L10,5 Z")})}generalizationLine(e){e.stroke({width:this.merge("generalizationLineWidth",!0),color:this.merge("generalizationLineColor",!0)}).fill({color:"none"})}iconBtn(e,t,r){let{color:n,fill:s,fontSize:a,fontColor:o}=this.ctx.mindMap.opt.expandBtnStyle||{color:"#808080",fill:"#fff",fontSize:12,strokeColor:"#333333",fontColor:"#333333"};e.fill({color:n}),t.fill({color:n}),r.fill({color:s}),this.ctx.mindMap.opt.isShowExpandNum&&e.attr({"font-size":a+"px","font-color":o})}hasCustomStyle(){let e=!1;return Object.keys(this.ctx.getData()).forEach(t=>{hs(t)&&(e=!0)}),e}getCustomStyle(){let e={};return Object.keys(this.ctx.getData()).forEach(t=>{hs(t)&&(e[t]=this.ctx.getData(t))}),e}hoverNode(e){let t=this.merge("hoverRectColor")||this.ctx.mindMap.opt.hoverRectColor,r=this.merge("hoverRectRadius");e.radius(r).fill("none").stroke({color:t})}onRemove(){this._marker&&(this._marker.remove(),this._marker=null),this._markerPath&&(this._markerPath.remove(),this._markerPath=null),this._gradient&&(this._gradient.remove(),this._gradient=null)}};W0.cacheStyle=null;qo=W0});var Ho,P2,Tu=T(()=>{yt();$e();Ho=class{constructor(e){this.node=e,this.mindMap=e.mindMap}getShapePadding(e,t,r,n){let s=this.node.getShape(),a=15,o=5,l=e+r*2,h=t+n*2,d=Math.abs(l-h);switch(s){case k.SHAPE.ROUNDED_RECTANGLE:return{paddingX:t>e?(t-e)/2:0,paddingY:0};case k.SHAPE.DIAMOND:return{paddingX:e/2,paddingY:t/2};case k.SHAPE.PARALLELOGRAM:return{paddingX:r<=0?a:0,paddingY:0};case k.SHAPE.OUTER_TRIANGULAR_RECTANGLE:return{paddingX:r<=0?a:0,paddingY:0};case k.SHAPE.INNER_TRIANGULAR_RECTANGLE:return{paddingX:r<=0?a:0,paddingY:0};case k.SHAPE.ELLIPSE:return{paddingX:r<=0?a:0,paddingY:n<=0?o:0};case k.SHAPE.CIRCLE:return{paddingX:h>l?d/2:0,paddingY:ht.name===e)}createShape(){let e=this.node.getShape(),t=null;if(e===k.SHAPE.RECTANGLE?t=this.createRect():e===k.SHAPE.DIAMOND?t=this.createDiamond():e===k.SHAPE.PARALLELOGRAM?t=this.createParallelogram():e===k.SHAPE.ROUNDED_RECTANGLE?t=this.createRoundedRectangle():e===k.SHAPE.OCTAGONAL_RECTANGLE?t=this.createOctagonalRectangle():e===k.SHAPE.OUTER_TRIANGULAR_RECTANGLE?t=this.createOuterTriangularRectangle():e===k.SHAPE.INNER_TRIANGULAR_RECTANGLE?t=this.createInnerTriangularRectangle():e===k.SHAPE.ELLIPSE?t=this.createEllipse():e===k.SHAPE.CIRCLE&&(t=this.createCircle()),!t){let r=this.getShapeFromExtendList(e);r&&(t=r.createShape(this.node))}return t||this.createRect()}getNodeSize(){let e=this.node.getBorderWidth(),{width:t,height:r}=this.node;return t-=e,r-=e,{width:t,height:r}}createPath(e){let{customCreateNodePath:t}=this.mindMap.opt;return t?Ae(t(e)):new ar().plot(e)}createPolygon(e){let{customCreateNodePolygon:t}=this.mindMap.opt;return t?Ae(t(e)):new Gi().plot(e)}createRect(){let{width:e,height:t}=this.getNodeSize(),r=this.node.style.merge("borderRadius"),n=` +`);for(let t=0,r=e.length;t(i.attr("href")||"").includes(this.id()))}}});Oo.prototype.MorphArray=Er;Me(Oo,"TextPath");U0=class extends Dt{constructor(e,t=e){super(Ue("use",e),t)}use(e,t){return this.attr("href",(t||"")+"#"+e,Bo)}};fe({Container:{use:He(function(i,e){return this.put(new U0).use(i,e)})}});Me(U0,"Use");ke=Rt;xe([Lo,Io,$i,rs,Zs],Xt("viewbox"));xe([ns,as,ji,nr],Xt("marker"));xe(_e,Xt("Text"));xe(nr,Xt("Path"));xe(So,Xt("Defs"));xe([_e,ea],Xt("Tspan"));xe([Ve,Ks,is,Gi],Xt("radius"));xe(ts,Xt("EventTarget"));xe(hn,Xt("Dom"));xe(Si,Xt("Element"));xe(Dt,Xt("Shape"));xe([Yt,F0],Xt("Container"));xe(is,Xt("Gradient"));xe(Gi,Xt("Runner"));Nr.extend(qw());uT([we,Ei,Vt,be,ln,rr,Er,it]);fT()});var j0=tr((_U,E2)=>{"use strict";var $0=function(e){return GT(e)&&!WT(e)};function GT(i){return!!i&&typeof i=="object"}function WT(i){var e=Object.prototype.toString.call(i);return e==="[object RegExp]"||e==="[object Date]"||XT(i)}var VT=typeof Symbol=="function"&&Symbol.for,YT=VT?Symbol.for("react.element"):60103;function XT(i){return i.$$typeof===YT}function KT(i){return Array.isArray(i)?[]:{}}function Po(i,e){var t=e&&e.clone===!0;return t&&$0(i)?na(KT(i),i,e):i}function N2(i,e,t){var r=i.slice();return e.forEach(function(n,s){typeof r[s]>"u"?r[s]=Po(n,t):$0(n)?r[s]=na(i[s],n,t):i.indexOf(n)===-1&&r.push(Po(n,t))}),r}function ZT(i,e,t){var r={};return $0(i)&&Object.keys(i).forEach(function(n){r[n]=Po(i[n],t)}),Object.keys(e).forEach(function(n){!$0(e[n])||!i[n]?r[n]=Po(e[n],t):r[n]=na(i[n],e[n],t)}),r}function na(i,e,t){var r=Array.isArray(e),n=Array.isArray(i),s=t||{arrayMerge:N2},a=r===n;if(a)if(r){var o=s.arrayMerge||N2;return o(i,e,t)}else return ZT(i,e,t);else return Po(e,t)}na.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce(function(r,n){return na(r,n,t)})};var QT=na;E2.exports=QT});var G0,JT,S2,Fo,qo=T(()=>{G0={paddingX:15,paddingY:5,imgMaxWidth:200,imgMaxHeight:100,iconSize:20,lineWidth:1,lineColor:"#549688",lineDasharray:"none",lineFlow:!1,lineFlowDuration:1,lineFlowForward:!0,lineStyle:"straight",rootLineKeepSameInCurve:!0,rootLineStartPositionKeepSameInCurve:!1,lineRadius:5,showLineMarker:!1,generalizationLineWidth:1,generalizationLineColor:"#549688",generalizationLineMargin:0,generalizationNodeMargin:20,associativeLineWidth:2,associativeLineColor:"rgb(51, 51, 51)",associativeLineActiveWidth:8,associativeLineActiveColor:"rgba(2, 167, 240, 1)",associativeLineDasharray:"6,4",associativeLineTextColor:"rgb(51, 51, 51)",associativeLineTextFontSize:14,associativeLineTextLineHeight:1.2,associativeLineTextFontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",backgroundColor:"#fafafa",backgroundImage:"none",backgroundRepeat:"no-repeat",backgroundPosition:"center center",backgroundSize:"cover",nodeUseLineStyle:!1,root:{shape:"rectangle",fillColor:"#549688",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#fff",fontSize:16,fontWeight:"bold",fontStyle:"normal",borderColor:"transparent",borderWidth:0,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},second:{shape:"rectangle",marginX:100,marginY:40,fillColor:"#fff",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#565656",fontSize:16,fontWeight:"normal",fontStyle:"normal",borderColor:"#549688",borderWidth:1,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},node:{shape:"rectangle",marginX:50,marginY:0,fillColor:"transparent",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#6a6d6c",fontSize:14,fontWeight:"normal",fontStyle:"normal",borderColor:"transparent",borderWidth:0,borderRadius:5,borderDasharray:"none",textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],lineMarkerDir:"end",hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"},generalization:{shape:"rectangle",marginX:100,marginY:40,fillColor:"#fff",fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",color:"#565656",fontSize:16,fontWeight:"normal",fontStyle:"normal",borderColor:"#549688",borderWidth:1,borderDasharray:"none",borderRadius:5,textDecoration:"none",gradientStyle:!1,startColor:"#549688",endColor:"#fff",startDir:[0,0],endDir:[1,0],hoverRectColor:"",hoverRectRadius:5,textAlign:"left",imgPlacement:"top",tagPlacement:"right"}},JT=["lineWidth","lineColor","lineDasharray","lineStyle","generalizationLineWidth","generalizationLineColor","associativeLineWidth","associativeLineColor","associativeLineActiveWidth","associativeLineActiveColor","associativeLineTextColor","associativeLineTextFontSize","associativeLineTextLineHeight","associativeLineTextFontFamily","backgroundColor","backgroundImage","backgroundRepeat","backgroundPosition","backgroundSize","rootLineKeepSameInCurve","rootLineStartPositionKeepSameInCurve","showLineMarker","lineRadius","hoverRectColor","hoverRectRadius","lineFlow","lineFlowDuration","lineFlowForward","textAlign"],S2=i=>{let e=Object.keys(i);for(let t=0;tr===e[t]))return!1;return!0},Fo=["lineColor","lineDasharray","lineWidth","lineMarkerDir","lineFlow","lineFlowDuration","lineFlowForward"]});var A2,ue,Zt,K0,sa,Qt,Tu,ls,Nu,k2,Ai,C2,Jt,un,_2,L2,I2,W0,aa,oa,eN,Tt,z2,R2,os,Kt,V0,D2,Ho,O2,Uo,Eu,Z0,tN,Y0,Q0,cn,B2,P2,hs,F2,q2,ds,H2,U2,la,ha,$o,cs,Ot,da,ze,J0,fn,X0,Su,Au,$2,eh,j2,G2,W2,ku,jo,Cu,_u,V2,Y2,Lu,X2,iN,BU,mn,us,sr,Go,Iu,K2,pe=T(()=>{Qc();Ge();W3();wt();A2=yt(j0());qo();ue=(i,e,t,r,n,s=0,a=0,o=[])=>{let l=!1;if(t&&(l=t(i,e,n,s,a,o)),!l&&i.children&&i.children.length>0){let h=s+1;i.children.forEach((d,c)=>{ue(d,i,t,r,!1,h,c,[...o,i])})}r&&r(i,e,n,s,a,o)},Zt=(i,e)=>{let t=[i],r=!1;for(e(i,null)==="stop"&&(r=!0);t.length&&!r;){let n=t.shift();n.children&&n.children.length&&n.children.forEach(s=>{r||(t.push(s),e(s,n)==="stop"&&(r=!0))})}},K0=(i,e,t,r)=>{let n=i/e,s=[];if(t&&r)if(i<=t&&e<=r)s=[i,e];else{let a=t/r;n>a?s=[t,t/n]:s=[n*r,r]}else t?i<=t?s=[i,e]:s=[t,t/n]:r&&(e<=r?s=[i,e]:s=[n*r,r]);return s},sa=i=>{i=i.replace(/
    /gim,` +`);let e=document.createElement("div");return e.innerHTML=i,i=e.textContent,i},Qt=i=>{try{return JSON.parse(JSON.stringify(i))}catch{return null}},Tu=(i,e,t=!1)=>(i.data=Qt(e.data),t&&(i.data.isActive=!1,us(i.data).forEach(n=>{n.isActive=!1})),i.children=[],e.children&&e.children.length>0&&e.children.forEach((r,n)=>{i.children[n]=Tu({},r,t)}),Object.keys(e).forEach(r=>{!["data","children"].includes(r)&&!/^_/.test(r)&&(i[r]=e[r])}),i),ls=(i,e,t=!1,r=!0)=>{let n=e.nodeData?e.nodeData:e;return i.data=Qt(n.data),r?delete i.data.uid:i.data.uid||(i.data.uid=Tt()),t&&(i.data.isActive=!1),i.children=[],e.children&&e.children.length>0?e.children.forEach((s,a)=>{i.children[a]=ls({},s,t,r)}):e.nodeData&&e.nodeData.children&&e.nodeData.children.length>0&&e.nodeData.children.forEach((s,a)=>{i.children[a]=ls({},s,t,r)}),Object.keys(n).forEach(s=>{!["data","children"].includes(s)&&!/^_/.test(s)&&(i[s]=n[s])}),i},Nu=(i,e=!1)=>new Promise((t,r)=>{let n=new Image;n.setAttribute("crossOrigin","anonymous"),n.onload=()=>{try{let s=document.createElement("canvas");s.width=n.width,s.height=n.height,s.getContext("2d").drawImage(n,0,0,n.width,n.height),e?s.toBlob(o=>{t(o)}):t(s.toDataURL())}catch(s){r(s)}},n.onerror=s=>{r(s)},n.src=i}),k2=(i,e)=>{let t=document.createElement("a");t.href=i,t.download=e,t.click()},Ai=(i,e=300,t)=>{let r=null;return(...n)=>{r||(r=setTimeout(()=>{i.call(t,...n),r=null},e))}},C2=(i,e=300,t)=>{let r=null;return(...n)=>{r&&clearTimeout(r),r=setTimeout(()=>{r=null,i.apply(t,n)},e)}},Jt=(i,e=()=>{})=>{let t=0,r=i.length;if(r<=0)return e();let n=()=>{if(t>=r){e();return}i[t](),setTimeout(()=>{t++,n()},0)};n()},un=i=>i*(Math.PI/180),_2=i=>i.replace(/([a-z])([A-Z])/g,(...e)=>e[1]+"-"+e[2].toLowerCase()),L2=function(i,e){let t=!1,r=null,n=()=>{t=!1,e?i.call(e):i()};if(typeof MutationObserver<"u"){let s=1,a=new MutationObserver(n),o=document.createTextNode(s);a.observe(o,{characterData:!0}),r=function(){s=(s+1)%2,o.data=s}}else r=setTimeout;return function(){t||(t=!0,r(n,0))}},I2=(i,e,t=0,r=0)=>{let n=i.elRect,{scaleX:s,scaleY:a,translateX:o,translateY:l}=i.draw.transform(),{left:h,top:d,width:c,height:f}=e,m=(h+c)*s+o,g=(d+f)*a+l;h=h*s+o,d=d*a+l;let x=0,y=0;return h<0+t&&(x=-h+t),m>n.width-t&&(x=-(m-n.width)-t),d<0+r&&(y=-d+r),g>n.height-r&&(y=-(g-n.height)-r),{isOuter:x!==0||y!==0,offsetLeft:x,offsetTop:y}},W0=null,aa=i=>(W0||(W0=document.createElement("div")),W0.innerHTML=i,W0.textContent),oa=i=>new Promise((e,t)=>{let r=new FileReader;r.onload=n=>{e(n.target.result)},r.onerror=n=>{t(n)},r.readAsDataURL(i)}),eN=i=>new Promise(e=>{let t=new Image;t.src=i,t.onload=()=>{e({width:t.width,height:t.height})},t.onerror=()=>{e({width:0,height:0})}}),Tt=()=>vo(),z2=i=>new Promise((e,t)=>{let r=new FileReader;r.readAsDataURL(i),r.onload=async n=>{let s=n.target.result,a=await eN(s);e({url:s,size:a})},r.onerror=n=>{t(n)}}),R2=i=>([[" "," "]].forEach(e=>{i=i.replace(new RegExp(e[0],"g"),e[1])}),i),os=i=>Object.prototype.toString.call(i).slice(8,-1),Kt=i=>i==null||i==="",V0=null,D2=i=>{V0||(V0=document.createElement("div")),V0.innerHTML=i;for(let e=V0.childNodes,t=e.length;t--;)if(e[t].nodeType==1)return!0;return!1},Ho=null,O2=(i,e,t)=>{Ho||(Ho=document.createElement("div")),Ho.innerHTML=i;let r=n=>{n.childNodes.forEach(a=>{a.nodeType===1?r(a):a.nodeType===3&&n.replaceChild(document.createTextNode(a.nodeValue.replace(new RegExp(e,"g"),t)),a)})};return r(Ho),Ho.innerHTML},Uo=i=>(i=String(i).replace(/\s+/g,""),["#fff","#ffffff","#FFF","#FFFFFF","rgb(255,255,255)"].includes(i)||/rgba\(255,255,255,[^)]+\)/.test(i)),Eu=i=>(i=String(i).replace(/\s+/g,""),["","transparent"].includes(i)||/rgba\(\d+,\d+,\d+,0\)/.test(i)),Z0=i=>{let{lineColor:e,root:t,second:r,node:n}=i,s=[e,t.fillColor,t.color,r.fillColor,r.color,n.fillColor,n.color,t.borderColor,r.borderColor,n.borderColor];for(let a=0;a{let e=t=>{t.childNodes.forEach(n=>{n.nodeType===1&&(n.classList.contains("ql-formula")?n.parentNode.removeChild(n):e(n))})};e(i)},Y0=null,Q0=i=>{Y0||(Y0=document.createElement("div")),Y0.innerHTML=i;let e=Y0.childNodes,t="";for(let r=0;r{cn||(cn=document.createElement("div")),cn.innerHTML=i;let e=cn.querySelectorAll(".ql-formula");Array.from(e).forEach(n=>{let s=document.createTextNode("$smmformula$");n.parentNode.replaceChild(s,n)});let t=cn.childNodes,r=[];for(let n=0;n`

    ${fn(n)}

    `).join(""),e.length>0){i=i.replace(/\$smmformula\$/g,''),cn.innerHTML=i;let n=cn.querySelectorAll(".smmformula");Array.from(n).forEach((s,a)=>{s.parentNode.replaceChild(e[a],s)}),i=cn.innerHTML}return i},P2=(i,e)=>{let t={};return Object.keys(e).forEach(r=>{let n=i[r],s=e[r];if(os(n)!==os(s)){t[r]=s;return}if(os(n)==="Object"){if(JSON.stringify(n)!==JSON.stringify(s)){t[r]=s;return}}else if(n!==s){t[r]=s;return}}),t},hs=i=>/^_/.test(i)?!1:!js.includes(i),F2=i=>{let e=[...Fo],t=Object.keys(i);for(let r=0;ri.reduce((e,t)=>{let r=e.find(n=>n.type===t.type);return r?t.list.forEach(n=>{let s=r.list.find(a=>a.name===n.name);s?s.icon=n.icon:r.list.push(n)}):e.push({...t}),e},[]),ds=i=>{let e=[];return i.forEach(t=>{i.find(r=>r.uid!==t.uid&&r.isAncestor(t))||e.push(t)}),e},H2=i=>{let e={},t={};i.forEach(n=>{let s=n.parent;if(s){let a=s.uid;t[a]=s;let o=n.getIndexInBrothers(),l={node:n,index:o};e[a]?e[a].find(h=>h.index===l.index)||e[a].push(l):e[a]=[l]}});let r=[];return Object.keys(e).forEach(n=>{if(e[n].length>1){let s=e[n].map(a=>a.index).sort((a,o)=>a-o);r.push({node:t[n],range:[s[0],s[s.length-1]]})}else r.push({node:e[n][0].node})}),r},U2=(i,e,t,r,n,s,a,o)=>e>n&&s>i&&r>a&&o>t,la=i=>{let e=window.getSelection(),t=document.createRange();t.selectNodeContents(i),t.collapse(),e.removeAllRanges(),e.addRange(t)},ha=i=>{let e=window.getSelection(),t=document.createRange();t.selectNodeContents(i),e.removeAllRanges(),e.addRange(t)},$o=(i,e={})=>{e={...e},e&&e.richText&&e.resetRichText&&delete e.resetRichText;let r=n=>{n.forEach(s=>{s.data={...s.data,...e},s.children&&s.children.length>0&&r(s.children)})};return r(i),i},cs=(i,e=!1,t=null,r=!1)=>{let n=s=>{s.forEach(a=>{a.data||(a.data={}),(e||Kt(a.data.uid))&&(a.data.uid=Tt()),r&&us(a.data).forEach(l=>{(e||Kt(l.uid))&&(l.uid=Tt())}),t&&t(a),a.children&&a.children.length>0&&n(a.children)})};return n(i),i},Ot=i=>i?Array.isArray(i)?i:[i]:[],da=i=>i.parent?i.parent.nodeData.children.findIndex(e=>e.data.uid===i.uid):0,ze=(i,e)=>e.findIndex(t=>t.uid===i.uid),J0=i=>{let e=0;for(let n=0;n([["&","&"],["<","<"],[">",">"]].forEach(e=>{i=i.replace(new RegExp(e[0],"g"),e[1])}),i),X0=(i,e)=>{let t=os(i);if(t!==os(e))return!1;if(t==="Object"){let r=Object.keys(i),n=Object.keys(e);if(r.length!==n.length)return!1;for(let s=0;snavigator.clipboard&&typeof navigator.clipboard.read=="function",Au=i=>{navigator.clipboard&&navigator.clipboard.writeText&&navigator.clipboard.writeText(JSON.stringify(i))},$2=async()=>{let i=null,e=null;if(Su()){let t=await navigator.clipboard.read();if(t&&t.length>0)for(let r of t)for(let n of r.types)/^image\//.test(n)?e=await r.getType(n):n==="text/plain"&&(i=await(await r.getType(n)).text())}return{text:i,img:e}},eh=i=>{if(!i||!i.parent)return;let e=da(i);e!==-1&&i.parent.nodeData.children.splice(e,1)},j2=i=>(j3.forEach(e=>{i=i.replace(new RegExp(`<${e}([^>]*)>`,"g"),`<${e} $1 />`)}),i),G2=(i,e)=>{if(i.length!==e.length)return!1;for(let t=0;tr.uid===i[t].uid))return!1;return!0},W2=()=>{let i=navigator.userAgent.match(/\s+Chrome\/(.*)\s+/);return i&&i[1]?Number.parseFloat(i[1]):""},ku=i=>({simpleMindMap:!0,data:i}),jo=i=>{let e=null;if(typeof i=="string")try{let r=JSON.parse(i);typeof r=="object"&&r.simpleMindMap&&(e=r.data)}catch{}else typeof i=="object"&&i.simpleMindMap&&(e=i.data);let t=!!e;return{isSmm:t,data:t?e:String(i)}},Cu=(i,e)=>{i.preventDefault();let t=window.getSelection();if(!t.rangeCount)return;t.deleteFromDocument(),e=e||i.clipboardData.getData("text"),e=fn(e),e=aa(e);let r=e.split(/\n/g),n=document.createDocumentFragment();r.forEach((s,a)=>{let o=document.createTextNode(s);if(n.appendChild(o),a{let e={},t=(r,n)=>{let s=r.data.uid;n&&n.children.push(s),e[s]={isRoot:!n,data:{...r.data},children:[]},r.children&&r.children.length>0&&r.children.forEach(a=>{t(a,e[s])})};return t(i,null),e},V2=(i,e)=>{let t=i.x+i.width/2,r=i.y+i.height/2,n=e.x+e.width/2,s=e.y+e.height/2;return tn&&rn&&r>s?"right-bottom":ts?"left-bottom":tn&&r===s?"right":t===n&&rs?"bottom":"overlap"},Y2=({addContentToHeader:i,addContentToFooter:e})=>{let t=[],r=null,n=0,s=null,a=0,o=(l,h)=>{if(typeof l=="function"){let d=l();if(!d)return;let{el:c,cssText:f,height:m}=d;if(c instanceof HTMLElement){sr(c);let g=mn({el:c,height:m});h(g,m)}f&&t.push(f)}};return o(i,(l,h)=>{r=l,n=h}),o(e,(l,h)=>{s=l,a=h}),{cssTextList:t,header:r,headerHeight:n,footer:s,footerHeight:a}},Lu=(i,e=0,t=0,r=0,n=0,s=!1,a=!1)=>{let o=1/0,l=-1/0,h=1/0,d=-1/0,c=(f,m)=>{if(!(m&&s)&&f.group)try{let{x:g,y:x,width:y,height:b}=f.group.findOne(".smm-node-shape").rbox();gl&&(l=g+y),xd&&(d=x+b)}catch{}!a&&f._generalizationList.length>0&&f._generalizationList.forEach(g=>{c(g.generalizationNode)}),f.children&&f.children.forEach(g=>{c(g)})};return c(i,!0),o=o-e+r,h=h-t+n,l=l-e+r,d=d-t+n,{left:o,top:h,width:l-o,height:d-h}},X2=(i,e=0,t=0,r=0,n=0)=>{let s=1/0,a=-1/0,o=1/0,l=-1/0;return i.forEach(h=>{let{left:d,top:c,width:f,height:m}=Lu(h,e,t,r,n,!1,!0);da&&(a=d+f),cl&&(l=c+m)}),{left:s,top:o,width:a-s,height:l-o}},iN=()=>{if(document.documentElement.requestFullScreen)return"fullscreenchange";if(document.documentElement.webkitRequestFullScreen)return"webkitfullscreenchange";if(document.documentElement.mozRequestFullScreen)return"mozfullscreenchange";if(document.documentElement.msRequestFullscreen)return"msfullscreenchange"},BU=iN(),mn=({el:i,width:e,height:t})=>{let r=new ta;return e!==void 0&&r.width(e),t!==void 0&&r.height(t),r.add(i),r},us=i=>{let e=i.generalization;return e?Array.isArray(e)?e:[e]:[]},sr=i=>{i.setAttribute("xmlns","http://www.w3.org/1999/xhtml")},Go=i=>(i=[...i],i.sort((e,t)=>e.sortIndex-t.sortIndex),i),Iu=(i,e)=>(0,A2.default)(i,e,{arrayMerge:(t,r)=>r}),K2=i=>{let e={};return G3.forEach(t=>{let r=i.style.merge(t);t==="fontSize"&&(r=r+"px"),e[t]=r}),e}});var Z2,zu,th,Wo,ih=T(()=>{pe();Z2=["backgroundColor","backgroundImage","backgroundRepeat","backgroundPosition","backgroundSize"],zu=["gradientStyle","startColor","endColor","startDir","endDir","fillColor","borderColor","borderWidth","borderDasharray"],th=class i{static setBackgroundStyle(e,t){if(!e)return;if(!i.cacheStyle){i.cacheStyle={};let l=window.getComputedStyle(e);Z2.forEach(h=>{i.cacheStyle[h]=l[h]})}let{backgroundColor:r,backgroundImage:n,backgroundRepeat:s,backgroundPosition:a,backgroundSize:o}=t;e.style.backgroundColor=r,n&&n!=="none"?(e.style.backgroundImage=`url(${n})`,e.style.backgroundRepeat=s,e.style.backgroundPosition=a,e.style.backgroundSize=o):e.style.backgroundImage="none"}static removeBackgroundStyle(e){i.cacheStyle&&(Z2.forEach(t=>{e.style[t]=i.cacheStyle[t]}),i.cacheStyle=null)}constructor(e){this.ctx=e,this._markerPath=null,this._marker=null,this._gradient=null}merge(e,t){let r=this.ctx.mindMap.themeConfig,n=null,s=!1;t?(s=!0,n=r):this.ctx.isGeneralization?n=r.generalization:this.ctx.layerIndex===0?n=r.root:this.ctx.layerIndex===1?n=r.second:n=r.node;let a="";return this.getSelfStyle(e)!==void 0?a=this.getSelfStyle(e):n[e]!==void 0?a=n[e]:a=r[e],s||this.addToEffectiveStyles({[e]:a}),a}getStyle(e,t){return this.merge(e,t)}getSelfStyle(e){return this.ctx.getData(e)}addToEffectiveStyles(e){this.ctx.mindMap.painter&&(this.ctx.effectiveStyles={...this.ctx.effectiveStyles,...e})}rect(e){this.shape(e),e.radius(this.merge("borderRadius"))}shape(e){let t={};zu.forEach(r=>{t[r]=this.merge(r)}),t.gradientStyle?(this._gradient||(this._gradient=this.ctx.nodeDraw.gradient("linear")),this._gradient.update(r=>{r.stop(0,t.startColor),r.stop(1,t.endColor)}),this._gradient.from(...t.startDir).to(...t.endDir),e.fill(this._gradient)):e.fill({color:t.fillColor}),e.stroke({color:t.borderColor,width:t.borderWidth,dasharray:t.borderDasharray})}text(e){let t={color:this.merge("color"),fontFamily:this.merge("fontFamily"),fontSize:this.merge("fontSize"),fontWeight:this.merge("fontWeight"),fontStyle:this.merge("fontStyle"),textDecoration:this.merge("textDecoration")};e.fill({color:t.color}).css({"font-family":t.fontFamily,"font-size":t.fontSize+"px","font-weight":t.fontWeight,"font-style":t.fontStyle,"text-decoration":t.textDecoration})}domText(e,t=1){let r={color:this.merge("color"),fontFamily:this.merge("fontFamily"),fontSize:this.merge("fontSize"),fontWeight:this.merge("fontWeight"),fontStyle:this.merge("fontStyle"),textDecoration:this.merge("textDecoration"),textAlign:this.merge("textAlign")};e.style.color=r.color,e.style.textDecoration=r.textDecoration,e.style.fontFamily=r.fontFamily,e.style.fontSize=r.fontSize*t+"px",e.style.fontWeight=r.fontWeight||"normal",e.style.fontStyle=r.fontStyle,e.style.textAlign=r.textAlign}tagText(e,t){e.fill({color:"#fff"}).css({"font-size":t.fontSize+"px"})}tagRect(e,t){e.fill({color:t.fill}),t.radius&&e.radius(t.radius)}iconNode(e,t){e.attr({fill:t||this.merge("color")})}line(e,{width:t,color:r,dasharray:n}={},s,a){let{customHandleLine:o}=this.ctx.mindMap.opt;if(typeof o=="function"&&o(this.ctx,e,{width:t,color:r,dasharray:n}),e.stroke({color:r,dasharray:n,width:t}).fill({color:"none"}),s){let l=this.merge("showLineMarker",!0),h=a.style;if(l){h._marker=h._marker||h.createMarker(),h._markerPath.stroke({color:r}).fill({color:r}),e.attr("marker-start",""),e.attr("marker-end","");let d=h.merge("lineMarkerDir");e.marker(d,h._marker)}else h._marker&&(e.attr("marker-start",""),e.attr("marker-end",""),h._marker.remove(),h._marker=null)}}createMarker(){return this.ctx.lineDraw.marker(20,20,e=>{e.ref(8,5),e.size(20,20),e.attr("markerUnits","userSpaceOnUse"),e.attr("orient","auto-start-reverse"),this._markerPath=e.path("M0,0 L2,5 L0,10 L10,5 Z")})}generalizationLine(e){e.stroke({width:this.merge("generalizationLineWidth",!0),color:this.merge("generalizationLineColor",!0)}).fill({color:"none"})}iconBtn(e,t,r){let{color:n,fill:s,fontSize:a,fontColor:o}=this.ctx.mindMap.opt.expandBtnStyle||{color:"#808080",fill:"#fff",fontSize:12,strokeColor:"#333333",fontColor:"#333333"};e.fill({color:n}),t.fill({color:n}),r.fill({color:s}),this.ctx.mindMap.opt.isShowExpandNum&&e.attr({"font-size":a+"px","font-color":o})}hasCustomStyle(){let e=!1;return Object.keys(this.ctx.getData()).forEach(t=>{hs(t)&&(e=!0)}),e}getCustomStyle(){let e={};return Object.keys(this.ctx.getData()).forEach(t=>{hs(t)&&(e[t]=this.ctx.getData(t))}),e}hoverNode(e){let t=this.merge("hoverRectColor")||this.ctx.mindMap.opt.hoverRectColor,r=this.merge("hoverRectRadius");e.radius(r).fill("none").stroke({color:t})}onRemove(){this._marker&&(this._marker.remove(),this._marker=null),this._markerPath&&(this._markerPath.remove(),this._markerPath=null),this._gradient&&(this._gradient.remove(),this._gradient=null)}};th.cacheStyle=null;Wo=th});var Vo,Q2,Ru=T(()=>{wt();Ge();Vo=class{constructor(e){this.node=e,this.mindMap=e.mindMap}getShapePadding(e,t,r,n){let s=this.node.getShape(),a=15,o=5,l=e+r*2,h=t+n*2,d=Math.abs(l-h);switch(s){case C.SHAPE.ROUNDED_RECTANGLE:return{paddingX:t>e?(t-e)/2:0,paddingY:0};case C.SHAPE.DIAMOND:return{paddingX:e/2,paddingY:t/2};case C.SHAPE.PARALLELOGRAM:return{paddingX:r<=0?a:0,paddingY:0};case C.SHAPE.OUTER_TRIANGULAR_RECTANGLE:return{paddingX:r<=0?a:0,paddingY:0};case C.SHAPE.INNER_TRIANGULAR_RECTANGLE:return{paddingX:r<=0?a:0,paddingY:0};case C.SHAPE.ELLIPSE:return{paddingX:r<=0?a:0,paddingY:n<=0?o:0};case C.SHAPE.CIRCLE:return{paddingX:h>l?d/2:0,paddingY:ht.name===e)}createShape(){let e=this.node.getShape(),t=null;if(e===C.SHAPE.RECTANGLE?t=this.createRect():e===C.SHAPE.DIAMOND?t=this.createDiamond():e===C.SHAPE.PARALLELOGRAM?t=this.createParallelogram():e===C.SHAPE.ROUNDED_RECTANGLE?t=this.createRoundedRectangle():e===C.SHAPE.OCTAGONAL_RECTANGLE?t=this.createOctagonalRectangle():e===C.SHAPE.OUTER_TRIANGULAR_RECTANGLE?t=this.createOuterTriangularRectangle():e===C.SHAPE.INNER_TRIANGULAR_RECTANGLE?t=this.createInnerTriangularRectangle():e===C.SHAPE.ELLIPSE?t=this.createEllipse():e===C.SHAPE.CIRCLE&&(t=this.createCircle()),!t){let r=this.getShapeFromExtendList(e);r&&(t=r.createShape(this.node))}return t||this.createRect()}getNodeSize(){let e=this.node.getBorderWidth(),{width:t,height:r}=this.node;return t-=e,r-=e,{width:t,height:r}}createPath(e){let{customCreateNodePath:t}=this.mindMap.opt;return t?ke(t(e)):new nr().plot(e)}createPolygon(e){let{customCreateNodePolygon:t}=this.mindMap.opt;return t?ke(t(e)):new ji().plot(e)}createRect(){let{width:e,height:t}=this.getNodeSize(),r=this.node.style.merge("borderRadius"),n=` M${r},0 L${e-r},0 C${e-r},0 ${e},0 ${e},${r} @@ -52,9 +52,9 @@ var Zb=Object.create;var T0=Object.defineProperty;var Qb=Object.getOwnPropertyDe A${r},${n} 0 0,1 ${r},${t} M${r},${t} A${r},${n} 0 0,1 ${r},0 - `;return this.createPath(s)}},P2=[k.SHAPE.RECTANGLE,k.SHAPE.DIAMOND,k.SHAPE.PARALLELOGRAM,k.SHAPE.ROUNDED_RECTANGLE,k.SHAPE.OCTAGONAL_RECTANGLE,k.SHAPE.OUTER_TRIANGULAR_RECTANGLE,k.SHAPE.INNER_TRIANGULAR_RECTANGLE,k.SHAPE.ELLIPSE,k.SHAPE.CIRCLE]});function zT(){let i=this.getData("generalization");return Array.isArray(i)?i:i?[i]:[]}function RT(){return this.formatGetGeneralization().length>0}function DT(){return!!this.formatGetGeneralization().find(e=>!e.range||e.range.length<=0)}function OT(i){return this._generalizationList.findIndex(e=>e.generalizationNode.uid===i.uid)}function BT(){if(this.isGeneralization||!this.checkHasGeneralization())return;let i=0,e=0;this.formatGetGeneralization().forEach((r,n)=>{let s=this._generalizationList[n];s||(s=this._generalizationList[n]={}),s.node=this,s.range=r.range,s.generalizationLine||(s.generalizationLine=this.lineDraw.path()),s.generalizationNode||(s.generalizationNode=new da({data:{inserting:r.inserting,data:r},uid:wt(),renderer:this.renderer,mindMap:this.mindMap,isGeneralization:!0})),delete r.inserting,s.generalizationNode.generalizationBelongNode=this,s.generalizationNode.width>i&&(i=s.generalizationNode.width),s.generalizationNode.height>e&&(e=s.generalizationNode.height),r.isActive&&this.renderer.addNodeToActiveList(s.generalizationNode)}),this._generalizationNodeWidth=i,this._generalizationNodeHeight=e}function PT(){this.isGeneralization||(this.removeGeneralization(),this.createGeneralizationNode())}function FT(i){if(this.isGeneralization)return;this.updateGeneralizationData();let e=this.formatGetGeneralization();if(e.length<=0||this.getData("expand")===!1){this.removeGeneralization();return}e.length!==this._generalizationList.length&&this.removeGeneralization(),this.createGeneralizationNode(),this.renderer.layout.renderGeneralization(this._generalizationList),this._generalizationList.forEach(t=>{this.style.generalizationLine(t.generalizationLine),t.generalizationNode.render(()=>{},i)})}function qT(){let i=this.getChildrenLength(),e=this.formatGetGeneralization(),t=[];e.forEach(r=>{if(!r.range){t.push(r);return}r.range.length>0&&r.range[0]<=i-1&&r.range[1]<=i-1&&t.push(r)}),t.length!==e.length&&this.setData({generalization:t})}function HT(){this.isGeneralization||(this._generalizationList.forEach(i=>{i.generalizationNode.style.onRemove(),i.generalizationLine&&(i.generalizationLine.remove(),i.generalizationLine=null),i.generalizationNode&&(this.renderer.removeNodeFromActiveList(i.generalizationNode),i.generalizationNode.remove(),i.generalizationNode=null)}),this._generalizationList=[],this.generalizationBelongNode&&this.nodeDraw.find(".generalization_"+this.generalizationBelongNode.uid).remove())}function UT(){this.isGeneralization||this._generalizationList.forEach(i=>{i.generalizationLine&&i.generalizationLine.hide(),i.generalizationNode&&i.generalizationNode.hide()})}function $T(){this.isGeneralization||this._generalizationList.forEach(i=>{i.generalizationLine&&i.generalizationLine.show(),i.generalizationNode&&i.generalizationNode.show()})}function jT(i){this._generalizationList.forEach(e=>{e.generalizationLine.opacity(i),e.generalizationNode.group.opacity(i)})}function GT(){let i=this.generalizationBelongNode,e=i.formatGetGeneralization(),t=i.getGeneralizationNodeIndex(this),r=e[t],s=this.getStyle("hoverRectColor")||this.mindMap.opt.hoverRectColor,a=s?{stroke:s}:null;Array.isArray(r.range)&&r.range.length>0?this.mindMap.renderer.highlightNode(i,r.range,a):this.mindMap.renderer.highlightNode(i,null,a)}function VT(){this.mindMap.renderer.closeHighlightNode()}var Nu,F2=T(()=>{X0();pe();Nu={formatGetGeneralization:zT,checkHasGeneralization:RT,checkHasSelfGeneralization:DT,getGeneralizationNodeIndex:OT,createGeneralizationNode:BT,updateGeneralization:PT,updateGeneralizationData:qT,renderGeneralization:FT,removeGeneralization:HT,hideGeneralization:UT,showGeneralization:$T,setGeneralizationOpacity:jT,handleGeneralizationMouseenter:GT,handleGeneralizationMouseleave:VT}});var WT,YT,XT,KT,ZT,Uo,Eu=T(()=>{WT='',YT='',XT='',KT='',ZT='',Uo={open:WT,close:YT,remove:XT,imgAdjust:KT,quickCreateChild:ZT}});function QT(){if(this._openExpandNode)return;let{expandBtnSize:i,expandBtnIcon:e,isShowExpandNum:t}=this.mindMap.opt,{close:r,open:n}=e||{};t?(this._openExpandNode=new Ce,this._openExpandNode.addClass("smm-expand-btn-text"),this._openExpandNode.attr({"text-anchor":"middle","dominant-baseline":"middle",x:i/2,y:2})):(this._openExpandNode=Ae(n||Uo.open).size(i,i),this._openExpandNode.x(0).y(-i/2)),this._closeExpandNode=Ae(r||Uo.close).size(i,i),this._closeExpandNode.x(0).y(-i/2),this._fillExpandNode=new Wi().size(i),this._fillExpandNode.x(0).y(-i/2),this.style.iconBtn(this._openExpandNode,this._closeExpandNode,this._fillExpandNode)}function JT(i=[]){return i.reduce((e,t)=>e+this.sumNode(t.children||[]),i.length)}function eN(){let{expand:i}=this.getData();if(i===this._lastExpandBtnType)return;this._expandBtn&&this._expandBtn.clear(),this.createExpandNodeContent();let e;if(i===!1?(e=this._openExpandNode,this._lastExpandBtnType=!1):(e=this._closeExpandNode,this._lastExpandBtnType=!0),this._expandBtn){let{isShowExpandNum:t,expandBtnStyle:r,expandBtnNumHandler:n}=this.mindMap.opt;if(t)if(i)this._fillExpandNode.stroke("none");else{this._fillExpandNode.stroke({color:r.strokeColor});let s=this.sumNode(this.nodeData.children||[]);if(typeof n=="function"){let a=n(s,this);Yt(a)||(s=a)}e.text(String(s))}this._expandBtn.add(this._fillExpandNode).add(e)}}function tN(){this._expandBtn&&this.renderer.layout.renderExpandBtn(this,this._expandBtn)}function iN(){this.getChildrenLength()<=0||this.isRoot||(this._expandBtn?this.group.add(this._expandBtn):(this._expandBtn=new _e,this._expandBtn.on("mouseover",i=>{i.stopPropagation(),this._expandBtn.css({cursor:"pointer"})}),this._expandBtn.on("mouseout",i=>{i.stopPropagation(),this._expandBtn.css({cursor:"auto"})}),this._expandBtn.on("click",i=>{i.stopPropagation(),this.mindMap.execCommand("SET_NODE_EXPAND",this,!this.getData("expand")),this.mindMap.emit("expand_btn_click",this)}),this._expandBtn.on("dblclick",i=>{i.stopPropagation()}),this._expandBtn.addClass("smm-expand-btn"),this.group.add(this._expandBtn)),this._showExpandBtn=!0,this.updateExpandBtnNode(),this.updateExpandBtnPos())}function rN(){this._expandBtn&&this._showExpandBtn&&(this._expandBtn.remove(),this._showExpandBtn=!1)}function nN(){let{alwaysShowExpandBtn:i,notShowExpandBtn:e}=this.mindMap.opt;i||e||setTimeout(()=>{this.renderExpandBtn()},0)}function sN(){let{alwaysShowExpandBtn:i,notShowExpandBtn:e}=this.mindMap.opt;if(i||this._isMouseenter||e)return;let{isActive:t,expand:r}=this.getData();!t&&r&&setTimeout(()=>{this.removeExpandBtn()},0)}var Su,q2=T(()=>{Eu();yt();pe();Su={createExpandNodeContent:QT,updateExpandBtnNode:eN,updateExpandBtnPos:tN,renderExpandBtn:iN,removeExpandBtn:rN,showExpandBtn:nN,hideExpandBtn:sN,sumNode:JT}});function aN(i={}){this.mindMap.execCommand("SET_NODE_DATA",this,i)}function oN(i,e,t){this.mindMap.execCommand("SET_NODE_TEXT",this,i,e,t)}function lN(i){this.mindMap.execCommand("SET_NODE_IMAGE",this,i)}function hN(i){this.mindMap.execCommand("SET_NODE_ICON",this,i)}function dN(i,e){this.mindMap.execCommand("SET_NODE_HYPERLINK",this,i,e)}function cN(i){this.mindMap.execCommand("SET_NODE_NOTE",this,i)}function uN(i,e){this.mindMap.execCommand("SET_NODE_ATTACHMENT",this,i,e)}function fN(i){this.mindMap.execCommand("SET_NODE_TAG",this,i)}function mN(i){this.mindMap.execCommand("SET_NODE_SHAPE",this,i)}function pN(i,e){this.mindMap.execCommand("SET_NODE_STYLE",this,i,e)}function gN(i){this.mindMap.execCommand("SET_NODE_STYLES",this,i)}var Au,H2=T(()=>{Au={setData:aN,setText:oN,setImage:lN,setIcon:hN,setHyperlink:dN,setNote:cN,setAttachment:uN,setTag:fN,setShape:mN,setStyle:pN,setStyles:gN}});var xN,yN,vN,U2,bN,$o,$2=T(()=>{pe();xN='',yN='',vN='',U2=[{name:"\u4F18\u5148\u7EA7\u56FE\u6807",type:"priority",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''}]},{name:"\u8FDB\u5EA6\u56FE\u6807",type:"progress",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''}]},{name:"\u8868\u60C5\u56FE\u6807",type:"expression",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''},{name:"11",icon:''},{name:"12",icon:''},{name:"13",icon:''},{name:"14",icon:''},{name:"15",icon:''},{name:"16",icon:''},{name:"17",icon:''},{name:"18",icon:''},{name:"19",icon:''},{name:"20",icon:''}]},{name:"\u6807\u8BB0\u56FE\u6807",type:"sign",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''},{name:"11",icon:''},{name:"12",icon:''},{name:"13",icon:''},{name:"14",icon:''},{name:"15",icon:''},{name:"16",icon:''},{name:"17",icon:''},{name:"18",icon:''},{name:"19",icon:''},{name:"20",icon:''},{name:"21",icon:''},{name:"22",icon:''},{name:"23",icon:''}]}],bN=(i,e=[])=>{let t=i.split("_"),n=S2([...U2,...e]).find(s=>s.type===t[0]);if(n){let s=n.list.find(a=>a.name===t[1]);return s?s.icon:""}else return""},$o={hyperlink:xN,note:yN,attachment:vN,nodeIconList:U2,getNodeIconListIcon:bN}});function MN(){let i=this.getData("image");if(!i)return;i=(this.mindMap.renderer.renderTree.data.imgMap||{})[i]||i;let e=this.getImgShowSize(),t=new ji().load(i).size(...e),{defaultNodeImage:r}=this.mindMap.opt;if(r){let n=new Image;n.onerror=()=>{t.load(r)},n.src=i}return this.getData("imageTitle")&&t.attr("title",this.getData("imageTitle")),t.on("click",n=>{this.mindMap.emit("node_img_click",this,t,n)}),t.on("dblclick",n=>{this.mindMap.emit("node_img_dblclick",this,n,t)}),t.on("mouseenter",n=>{this.mindMap.emit("node_img_mouseenter",this,t,n)}),t.on("mouseleave",n=>{this.mindMap.emit("node_img_mouseleave",this,t,n)}),t.on("mousemove",n=>{this.mindMap.emit("node_img_mousemove",this,t,n)}),{node:t,width:e[0],height:e[1]}}function TN(){let{custom:i,width:e,height:t}=this.getData("imageSize");return i?[e,t]:U0(e,t,this.mindMap.themeConfig.imgMaxWidth,this.mindMap.themeConfig.imgMaxHeight)}function NN(){let i=this.getData();if(!i.icon||i.icon.length<=0)return[];let e=this.mindMap.themeConfig.iconSize;return i.icon.map(t=>{let r=$o.getNodeIconListIcon(t,this.mindMap.opt.iconList||[]),n=null;return/^{this.mindMap.emit("node_icon_click",this,t,s,n)}),n.on("mouseenter",s=>{this.mindMap.emit("node_icon_mouseenter",this,t,s,n)}),n.on("mouseleave",s=>{this.mindMap.emit("node_icon_mouseleave",this,t,s,n)}),{node:n,width:e,height:e}})}function EN(i){let e=this.hasCustomWidth(),t=typeof i=="string"?i:this.getData("text"),{textAutoWrapWidth:r,emptyTextMeasureHeightText:n}=this.mindMap.opt;r=e?this.customTextWidth:r;let s=new _e,a=!1;this.getData("resetRichText")&&(delete this.nodeData.data.resetRichText,a=!0),a&&!Yt(t)&&(w2(t)?t=T2(t):t=`

    ${t}

    `,this.setData({text:t}));let o=[],l=O2(this);Object.keys(l).forEach(y=>{o.push([y,l[y]])}),this.mindMap.commonCaches.measureRichtextNodeTextSizeEl||(this.mindMap.commonCaches.measureRichtextNodeTextSizeEl=document.createElement("div"),this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position="fixed",this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.left="-999999px",this.mindMap.el.appendChild(this.mindMap.commonCaches.measureRichtextNodeTextSizeEl));let h=this.mindMap.commonCaches.measureRichtextNodeTextSizeEl;o.forEach(([y,b])=>{h.style[y]=b}),h.style.lineHeight=1.2;let d=`
    ${t}
    `;h.innerHTML=d;let c=h.children[0];c.classList.add("smm-richtext-node-wrap"),or(c),c.style.maxWidth=r+"px",e?c.style.width=this.customTextWidth+"px":c.style.width="";let{width:f,height:m}=c.getBoundingClientRect();if(m<=0){h.innerHTML=`

    ${n}

    `;let y=h.children[0];y.classList.add("smm-richtext-node-wrap"),m=y.getBoundingClientRect().height,h.innerHTML=d}f=Math.min(Math.ceil(f)+1,r),m=Math.ceil(m),s.attr("data-width",f),s.attr("data-height",m);let g=pn({el:h.children[0],width:f,height:m}),x={"line-height":1.2};return o.forEach(([y,b])=>{x[g2(y)]=b}),g.css(x),s.add(g),{node:s,nodeContent:g,width:f,height:m}}function SN(i){if(this.getData("needUpdate")&&delete this.nodeData.data.needUpdate,this.getData("richText"))return this.createRichTextNode(i);let e=typeof i=="string"?i:this.getData("text");this.getData("resetRichText")&&delete this.nodeData.data.resetRichText;let t=new _e,r=this.getStyle("fontSize",!1),n=this.getStyle("textAlign",!1),s=[];Yt(e)||(s=String(e).split(/\n/gim));let{textAutoWrapWidth:a,emptyTextMeasureHeightText:o}=this.mindMap.opt,l=s.length>1;s.forEach((c,f)=>{let m=c.split(""),g=[],x=[];for(;m.length;){let y=m.shift(),b=[...x,y].join("");wN(b,this.style).width<=a?x.push(y):(g.push(x.join("")),x=[y])}x.length>0&&g.push(x.join("")),g.length>1&&(l=!0),s[f]=g.join(` + `;return this.createPath(s)}},Q2=[C.SHAPE.RECTANGLE,C.SHAPE.DIAMOND,C.SHAPE.PARALLELOGRAM,C.SHAPE.ROUNDED_RECTANGLE,C.SHAPE.OCTAGONAL_RECTANGLE,C.SHAPE.OUTER_TRIANGULAR_RECTANGLE,C.SHAPE.INNER_TRIANGULAR_RECTANGLE,C.SHAPE.ELLIPSE,C.SHAPE.CIRCLE]});function rN(){let i=this.getData("generalization");return Array.isArray(i)?i:i?[i]:[]}function nN(){return this.formatGetGeneralization().length>0}function sN(){return!!this.formatGetGeneralization().find(e=>!e.range||e.range.length<=0)}function aN(i){return this._generalizationList.findIndex(e=>e.generalizationNode.uid===i.uid)}function oN(){if(this.isGeneralization||!this.checkHasGeneralization())return;let i=0,e=0;this.formatGetGeneralization().forEach((r,n)=>{let s=this._generalizationList[n];s||(s=this._generalizationList[n]={}),s.node=this,s.range=r.range,s.generalizationLine||(s.generalizationLine=this.lineDraw.path()),s.generalizationNode||(s.generalizationNode=new ca({data:{inserting:r.inserting,data:r},uid:Tt(),renderer:this.renderer,mindMap:this.mindMap,isGeneralization:!0})),delete r.inserting,s.generalizationNode.generalizationBelongNode=this,s.generalizationNode.width>i&&(i=s.generalizationNode.width),s.generalizationNode.height>e&&(e=s.generalizationNode.height),r.isActive&&this.renderer.addNodeToActiveList(s.generalizationNode)}),this._generalizationNodeWidth=i,this._generalizationNodeHeight=e}function lN(){this.isGeneralization||(this.removeGeneralization(),this.createGeneralizationNode())}function hN(i){if(this.isGeneralization)return;this.updateGeneralizationData();let e=this.formatGetGeneralization();if(e.length<=0||this.getData("expand")===!1){this.removeGeneralization();return}e.length!==this._generalizationList.length&&this.removeGeneralization(),this.createGeneralizationNode(),this.renderer.layout.renderGeneralization(this._generalizationList),this._generalizationList.forEach(t=>{this.style.generalizationLine(t.generalizationLine),t.generalizationNode.render(()=>{},i)})}function dN(){let i=this.getChildrenLength(),e=this.formatGetGeneralization(),t=[];e.forEach(r=>{if(!r.range){t.push(r);return}r.range.length>0&&r.range[0]<=i-1&&r.range[1]<=i-1&&t.push(r)}),t.length!==e.length&&this.setData({generalization:t})}function cN(){this.isGeneralization||(this._generalizationList.forEach(i=>{i.generalizationNode.style.onRemove(),i.generalizationLine&&(i.generalizationLine.remove(),i.generalizationLine=null),i.generalizationNode&&(this.renderer.removeNodeFromActiveList(i.generalizationNode),i.generalizationNode.remove(),i.generalizationNode=null)}),this._generalizationList=[],this.generalizationBelongNode&&this.nodeDraw.find(".generalization_"+this.generalizationBelongNode.uid).remove())}function uN(){this.isGeneralization||this._generalizationList.forEach(i=>{i.generalizationLine&&i.generalizationLine.hide(),i.generalizationNode&&i.generalizationNode.hide()})}function fN(){this.isGeneralization||this._generalizationList.forEach(i=>{i.generalizationLine&&i.generalizationLine.show(),i.generalizationNode&&i.generalizationNode.show()})}function mN(i){this._generalizationList.forEach(e=>{e.generalizationLine.opacity(i),e.generalizationNode.group.opacity(i)})}function pN(){let i=this.generalizationBelongNode,e=i.formatGetGeneralization(),t=i.getGeneralizationNodeIndex(this),r=e[t],s=this.getStyle("hoverRectColor")||this.mindMap.opt.hoverRectColor,a=s?{stroke:s}:null;Array.isArray(r.range)&&r.range.length>0?this.mindMap.renderer.highlightNode(i,r.range,a):this.mindMap.renderer.highlightNode(i,null,a)}function gN(){this.mindMap.renderer.closeHighlightNode()}var Du,J2=T(()=>{rh();pe();Du={formatGetGeneralization:rN,checkHasGeneralization:nN,checkHasSelfGeneralization:sN,getGeneralizationNodeIndex:aN,createGeneralizationNode:oN,updateGeneralization:lN,updateGeneralizationData:dN,renderGeneralization:hN,removeGeneralization:cN,hideGeneralization:uN,showGeneralization:fN,setGeneralizationOpacity:mN,handleGeneralizationMouseenter:pN,handleGeneralizationMouseleave:gN}});var xN,yN,vN,bN,wN,Yo,Ou=T(()=>{xN='',yN='',vN='',bN='',wN='',Yo={open:xN,close:yN,remove:vN,imgAdjust:bN,quickCreateChild:wN}});function MN(){if(this._openExpandNode)return;let{expandBtnSize:i,expandBtnIcon:e,isShowExpandNum:t}=this.mindMap.opt,{close:r,open:n}=e||{};t?(this._openExpandNode=new _e,this._openExpandNode.addClass("smm-expand-btn-text"),this._openExpandNode.attr({"text-anchor":"middle","dominant-baseline":"middle",x:i/2,y:2})):(this._openExpandNode=ke(n||Yo.open).size(i,i),this._openExpandNode.x(0).y(-i/2)),this._closeExpandNode=ke(r||Yo.close).size(i,i),this._closeExpandNode.x(0).y(-i/2),this._fillExpandNode=new Wi().size(i),this._fillExpandNode.x(0).y(-i/2),this.style.iconBtn(this._openExpandNode,this._closeExpandNode,this._fillExpandNode)}function TN(i=[]){return i.reduce((e,t)=>e+this.sumNode(t.children||[]),i.length)}function NN(){let{expand:i}=this.getData();if(i===this._lastExpandBtnType)return;this._expandBtn&&this._expandBtn.clear(),this.createExpandNodeContent();let e;if(i===!1?(e=this._openExpandNode,this._lastExpandBtnType=!1):(e=this._closeExpandNode,this._lastExpandBtnType=!0),this._expandBtn){let{isShowExpandNum:t,expandBtnStyle:r,expandBtnNumHandler:n}=this.mindMap.opt;if(t)if(i)this._fillExpandNode.stroke("none");else{this._fillExpandNode.stroke({color:r.strokeColor});let s=this.sumNode(this.nodeData.children||[]);if(typeof n=="function"){let a=n(s,this);Kt(a)||(s=a)}e.text(String(s))}this._expandBtn.add(this._fillExpandNode).add(e)}}function EN(){this._expandBtn&&this.renderer.layout.renderExpandBtn(this,this._expandBtn)}function SN(){this.getChildrenLength()<=0||this.isRoot||(this._expandBtn?this.group.add(this._expandBtn):(this._expandBtn=new Le,this._expandBtn.on("mouseover",i=>{i.stopPropagation(),this._expandBtn.css({cursor:"pointer"})}),this._expandBtn.on("mouseout",i=>{i.stopPropagation(),this._expandBtn.css({cursor:"auto"})}),this._expandBtn.on("click",i=>{i.stopPropagation(),this.mindMap.execCommand("SET_NODE_EXPAND",this,!this.getData("expand")),this.mindMap.emit("expand_btn_click",this)}),this._expandBtn.on("dblclick",i=>{i.stopPropagation()}),this._expandBtn.addClass("smm-expand-btn"),this.group.add(this._expandBtn)),this._showExpandBtn=!0,this.updateExpandBtnNode(),this.updateExpandBtnPos())}function AN(){this._expandBtn&&this._showExpandBtn&&(this._expandBtn.remove(),this._showExpandBtn=!1)}function kN(){let{alwaysShowExpandBtn:i,notShowExpandBtn:e}=this.mindMap.opt;i||e||setTimeout(()=>{this.renderExpandBtn()},0)}function CN(){let{alwaysShowExpandBtn:i,notShowExpandBtn:e}=this.mindMap.opt;if(i||this._isMouseenter||e)return;let{isActive:t,expand:r}=this.getData();!t&&r&&setTimeout(()=>{this.removeExpandBtn()},0)}var Bu,e6=T(()=>{Ou();wt();pe();Bu={createExpandNodeContent:MN,updateExpandBtnNode:NN,updateExpandBtnPos:EN,renderExpandBtn:SN,removeExpandBtn:AN,showExpandBtn:kN,hideExpandBtn:CN,sumNode:TN}});function _N(i={}){this.mindMap.execCommand("SET_NODE_DATA",this,i)}function LN(i,e,t){this.mindMap.execCommand("SET_NODE_TEXT",this,i,e,t)}function IN(i){this.mindMap.execCommand("SET_NODE_IMAGE",this,i)}function zN(i){this.mindMap.execCommand("SET_NODE_ICON",this,i)}function RN(i,e){this.mindMap.execCommand("SET_NODE_HYPERLINK",this,i,e)}function DN(i){this.mindMap.execCommand("SET_NODE_NOTE",this,i)}function ON(i,e){this.mindMap.execCommand("SET_NODE_ATTACHMENT",this,i,e)}function BN(i){this.mindMap.execCommand("SET_NODE_TAG",this,i)}function PN(i){this.mindMap.execCommand("SET_NODE_SHAPE",this,i)}function FN(i,e){this.mindMap.execCommand("SET_NODE_STYLE",this,i,e)}function qN(i){this.mindMap.execCommand("SET_NODE_STYLES",this,i)}var Pu,t6=T(()=>{Pu={setData:_N,setText:LN,setImage:IN,setIcon:zN,setHyperlink:RN,setNote:DN,setAttachment:ON,setTag:BN,setShape:PN,setStyle:FN,setStyles:qN}});var HN,UN,$N,i6,jN,Xo,r6=T(()=>{pe();HN='',UN='',$N='',i6=[{name:"\u4F18\u5148\u7EA7\u56FE\u6807",type:"priority",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''}]},{name:"\u8FDB\u5EA6\u56FE\u6807",type:"progress",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''}]},{name:"\u8868\u60C5\u56FE\u6807",type:"expression",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''},{name:"11",icon:''},{name:"12",icon:''},{name:"13",icon:''},{name:"14",icon:''},{name:"15",icon:''},{name:"16",icon:''},{name:"17",icon:''},{name:"18",icon:''},{name:"19",icon:''},{name:"20",icon:''}]},{name:"\u6807\u8BB0\u56FE\u6807",type:"sign",list:[{name:"1",icon:''},{name:"2",icon:''},{name:"3",icon:''},{name:"4",icon:''},{name:"5",icon:''},{name:"6",icon:''},{name:"7",icon:''},{name:"8",icon:''},{name:"9",icon:''},{name:"10",icon:''},{name:"11",icon:''},{name:"12",icon:''},{name:"13",icon:''},{name:"14",icon:''},{name:"15",icon:''},{name:"16",icon:''},{name:"17",icon:''},{name:"18",icon:''},{name:"19",icon:''},{name:"20",icon:''},{name:"21",icon:''},{name:"22",icon:''},{name:"23",icon:''}]}],jN=(i,e=[])=>{let t=i.split("_"),n=q2([...i6,...e]).find(s=>s.type===t[0]);if(n){let s=n.list.find(a=>a.name===t[1]);return s?s.icon:""}else return""},Xo={hyperlink:HN,note:UN,attachment:$N,nodeIconList:i6,getNodeIconListIcon:jN}});function WN(){let i=this.getData("image");if(!i)return;i=(this.mindMap.renderer.renderTree.data.imgMap||{})[i]||i;let e=this.getImgShowSize(),t=new $i().load(i).size(...e),{defaultNodeImage:r}=this.mindMap.opt;if(r){let n=new Image;n.onerror=()=>{t.load(r)},n.src=i}return this.getData("imageTitle")&&t.attr("title",this.getData("imageTitle")),t.on("click",n=>{this.mindMap.emit("node_img_click",this,t,n)}),t.on("dblclick",n=>{this.mindMap.emit("node_img_dblclick",this,n,t)}),t.on("mouseenter",n=>{this.mindMap.emit("node_img_mouseenter",this,t,n)}),t.on("mouseleave",n=>{this.mindMap.emit("node_img_mouseleave",this,t,n)}),t.on("mousemove",n=>{this.mindMap.emit("node_img_mousemove",this,t,n)}),{node:t,width:e[0],height:e[1]}}function VN(){let{custom:i,width:e,height:t}=this.getData("imageSize");return i?[e,t]:K0(e,t,this.mindMap.themeConfig.imgMaxWidth,this.mindMap.themeConfig.imgMaxHeight)}function YN(){let i=this.getData();if(!i.icon||i.icon.length<=0)return[];let e=this.mindMap.themeConfig.iconSize;return i.icon.map(t=>{let r=Xo.getNodeIconListIcon(t,this.mindMap.opt.iconList||[]),n=null;return/^{this.mindMap.emit("node_icon_click",this,t,s,n)}),n.on("mouseenter",s=>{this.mindMap.emit("node_icon_mouseenter",this,t,s,n)}),n.on("mouseleave",s=>{this.mindMap.emit("node_icon_mouseleave",this,t,s,n)}),{node:n,width:e,height:e}})}function XN(i){let e=this.hasCustomWidth(),t=typeof i=="string"?i:this.getData("text"),{textAutoWrapWidth:r,emptyTextMeasureHeightText:n}=this.mindMap.opt;r=e?this.customTextWidth:r;let s=new Le,a=!1;this.getData("resetRichText")&&(delete this.nodeData.data.resetRichText,a=!0),a&&!Kt(t)&&(D2(t)?t=B2(t):t=`

    ${t}

    `,this.setData({text:t}));let o=[],l=K2(this);Object.keys(l).forEach(y=>{o.push([y,l[y]])}),this.mindMap.commonCaches.measureRichtextNodeTextSizeEl||(this.mindMap.commonCaches.measureRichtextNodeTextSizeEl=document.createElement("div"),this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position="fixed",this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.left="-999999px",this.mindMap.el.appendChild(this.mindMap.commonCaches.measureRichtextNodeTextSizeEl));let h=this.mindMap.commonCaches.measureRichtextNodeTextSizeEl;o.forEach(([y,b])=>{h.style[y]=b}),h.style.lineHeight=1.2;let d=`
    ${t}
    `;h.innerHTML=d;let c=h.children[0];c.classList.add("smm-richtext-node-wrap"),sr(c),c.style.maxWidth=r+"px",e?c.style.width=this.customTextWidth+"px":c.style.width="";let{width:f,height:m}=c.getBoundingClientRect();if(m<=0){h.innerHTML=`

    ${n}

    `;let y=h.children[0];y.classList.add("smm-richtext-node-wrap"),m=y.getBoundingClientRect().height,h.innerHTML=d}f=Math.min(Math.ceil(f)+1,r),m=Math.ceil(m),s.attr("data-width",f),s.attr("data-height",m);let g=mn({el:h.children[0],width:f,height:m}),x={"line-height":1.2};return o.forEach(([y,b])=>{x[_2(y)]=b}),g.css(x),s.add(g),{node:s,nodeContent:g,width:f,height:m}}function KN(i){if(this.getData("needUpdate")&&delete this.nodeData.data.needUpdate,this.getData("richText"))return this.createRichTextNode(i);let e=typeof i=="string"?i:this.getData("text");this.getData("resetRichText")&&delete this.nodeData.data.resetRichText;let t=new Le,r=this.getStyle("fontSize",!1),n=this.getStyle("textAlign",!1),s=[];Kt(e)||(s=String(e).split(/\n/gim));let{textAutoWrapWidth:a,emptyTextMeasureHeightText:o}=this.mindMap.opt,l=s.length>1;s.forEach((c,f)=>{let m=c.split(""),g=[],x=[];for(;m.length;){let y=m.shift(),b=[...x,y].join("");GN(b,this.style).width<=a?x.push(y):(g.push(x.join("")),x=[y])}x.length>0&&g.push(x.join("")),g.length>1&&(l=!0),s[f]=g.join(` `)}),s=s.join(` -`).replace(/\n$/g,"").split(/\n/gim),s.forEach((c,f)=>{c===""&&(c="\uFEFF");let m=new Ce().text(c);m.addClass("smm-text-node-wrap"),m.attr("text-anchor",{left:"start",center:"middle",right:"end"}[n]||"start"),this.style.text(m),m.y(r*js*f+(js-1)*r/2),t.add(m)});let{width:h,height:d}=t.bbox();if(d<=0){let c=new Ce().text(o);this.style.text(c),d=c.bbox().height}return h=Math.min(Math.ceil(h),a),d=Math.ceil(d),t.attr("data-width",h),t.attr("data-height",d),t.attr("data-ismultiLine",l||s.length>1),{node:t,width:h,height:d}}function AN(){let{hyperlink:i,hyperlinkTitle:e}=this.getData();if(!i)return;let{customHyperlinkJump:t,hyperlinkIcon:r}=this.mindMap.opt,{icon:n,style:s}=r,a=this.getNodeIconSize("hyperlinkIcon"),o=new Ae().size(a,a),l=new cn().to(i).target("_blank");l.node.addEventListener("click",d=>{typeof t=="function"&&(d.preventDefault(),t(i,this))}),e&&o.add(Ae(`${e}`)),l.rect(a,a).fill({color:"transparent"});let h=Ae(n||$o.hyperlink).size(a,a);return this.style.iconNode(h,s.color),l.add(h),o.add(l),{node:o,width:a,height:a}}function kN(){let i=this.getData("tag");if(!i||i.length<=0)return[];let{maxTag:e,tagsColorMap:t}=this.mindMap.opt;t=t||{};let r=[];return i.slice(0,e).forEach((n,s)=>{let a="",o={...j2};typeof n=="string"?a=n:(a=n.text,o={...j2,...n.style});let l=typeof o.width<"u",h=new _e;h.on("click",()=>{this.mindMap.emit("node_tag_click",this,n,s,h)});let d=new Ce().text(a);this.style.tagText(d,o);let{width:c,height:f}=d.bbox(),m=l?o.width:c+o.paddingX*2,g=l?Math.max(m,c):m,x=Math.max(o.height,f);l?d.x((g-c)/2):d.x(l?0:o.paddingX),d.cy(-x/2);let y=new Ve().size(m,o.height).cy(-x/2);l&&y.x((g-m)/2),this.style.tagRect(y,{...o,fill:o.fill||t[d.node.textContent]||G0(d.node.textContent)}),h.add(y).add(d),r.push({node:h,width:g,height:x})}),r}function CN(){if(!this.getData("note"))return null;let{icon:i,style:e}=this.mindMap.opt.noteIcon,t=this.getNodeIconSize("noteIcon"),r=new Ae().attr("cursor","pointer").addClass("smm-node-note").size(t,t);r.add(new Ve().size(t,t).fill({color:"transparent"}));let n=Ae(i||$o.note).size(t,t);return this.style.iconNode(n,e.color),r.add(n),this.mindMap.opt.customNoteContentShow||(this.noteEl||(this.noteEl=document.createElement("div"),this.noteEl.style.cssText=` +`).replace(/\n$/g,"").split(/\n/gim),s.forEach((c,f)=>{c===""&&(c="\uFEFF");let m=new _e().text(c);m.addClass("smm-text-node-wrap"),m.attr("text-anchor",{left:"start",center:"middle",right:"end"}[n]||"start"),this.style.text(m),m.y(r*Gs*f+(Gs-1)*r/2),t.add(m)});let{width:h,height:d}=t.bbox();if(d<=0){let c=new _e().text(o);this.style.text(c),d=c.bbox().height}return h=Math.min(Math.ceil(h),a),d=Math.ceil(d),t.attr("data-width",h),t.attr("data-height",d),t.attr("data-ismultiLine",l||s.length>1),{node:t,width:h,height:d}}function ZN(){let{hyperlink:i,hyperlinkTitle:e}=this.getData();if(!i)return;let{customHyperlinkJump:t,hyperlinkIcon:r}=this.mindMap.opt,{icon:n,style:s}=r,a=this.getNodeIconSize("hyperlinkIcon"),o=new ke().size(a,a),l=new dn().to(i).target("_blank");l.node.addEventListener("click",d=>{typeof t=="function"&&(d.preventDefault(),t(i,this))}),e&&o.add(ke(`${e}`)),l.rect(a,a).fill({color:"transparent"});let h=ke(n||Xo.hyperlink).size(a,a);return this.style.iconNode(h,s.color),l.add(h),o.add(l),{node:o,width:a,height:a}}function QN(){let i=this.getData("tag");if(!i||i.length<=0)return[];let{maxTag:e,tagsColorMap:t}=this.mindMap.opt;t=t||{};let r=[];return i.slice(0,e).forEach((n,s)=>{let a="",o={...n6};typeof n=="string"?a=n:(a=n.text,o={...n6,...n.style});let l=typeof o.width<"u",h=new Le;h.on("click",()=>{this.mindMap.emit("node_tag_click",this,n,s,h)});let d=new _e().text(a);this.style.tagText(d,o);let{width:c,height:f}=d.bbox(),m=l?o.width:c+o.paddingX*2,g=l?Math.max(m,c):m,x=Math.max(o.height,f);l?d.x((g-c)/2):d.x(l?0:o.paddingX),d.cy(-x/2);let y=new Ve().size(m,o.height).cy(-x/2);l&&y.x((g-m)/2),this.style.tagRect(y,{...o,fill:o.fill||t[d.node.textContent]||J0(d.node.textContent)}),h.add(y).add(d),r.push({node:h,width:g,height:x})}),r}function JN(){if(!this.getData("note"))return null;let{icon:i,style:e}=this.mindMap.opt.noteIcon,t=this.getNodeIconSize("noteIcon"),r=new ke().attr("cursor","pointer").addClass("smm-node-note").size(t,t);r.add(new Ve().size(t,t).fill({color:"transparent"}));let n=ke(i||Xo.note).size(t,t);return this.style.iconNode(n,e.color),r.add(n),this.mindMap.opt.customNoteContentShow||(this.noteEl||(this.noteEl=document.createElement("div"),this.noteEl.style.cssText=` position: fixed; padding: 10px; border-radius: 5px; @@ -62,24 +62,24 @@ var Zb=Object.create;var T0=Object.defineProperty;var Qb=Object.getOwnPropertyDe display: none; background-color: #fff; z-index: ${this.mindMap.opt.nodeNoteTooltipZIndex} - `,(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.noteEl)),this.noteEl.innerText=this.getData("note")),r.on("mouseover",()=>{let{left:s,top:a}=this.getNoteContentPosition();this.mindMap.opt.customNoteContentShow?this.mindMap.opt.customNoteContentShow.show(this.getData("note"),s,a,this):(this.noteEl.style.left=s+"px",this.noteEl.style.top=a+"px",this.noteEl.style.display="block")}),r.on("mouseout",()=>{this.mindMap.opt.customNoteContentShow?this.mindMap.opt.customNoteContentShow.hide():this.noteEl.style.display="none"}),r.on("click",s=>{this.mindMap.emit("node_note_click",this,s,r)}),r.on("dblclick",s=>{this.mindMap.emit("node_note_dblclick",this,s,r)}),{node:r,width:t,height:t}}function _N(){let{attachmentUrl:i,attachmentName:e}=this.getData();if(!i)return;let t=this.getNodeIconSize("attachmentIcon"),{icon:r,style:n}=this.mindMap.opt.attachmentIcon,s=new Ae().attr("cursor","pointer").size(t,t);e&&s.add(Ae(`${e}`)),s.add(new Ve().size(t,t).fill({color:"transparent"}));let a=Ae(r||$o.attachment).size(t,t);return this.style.iconNode(a,n.color),s.add(a),s.on("click",o=>{this.mindMap.emit("node_attachmentClick",this,o,s)}),s.on("contextmenu",o=>{this.mindMap.emit("node_attachmentContextmenu",this,o,s)}),{node:s,width:t,height:t}}function LN(i){let{style:e}=this.mindMap.opt[i];return Yt(e.size)?this.mindMap.themeConfig.iconSize:e.size}function IN(){let i=this.getNodeIconSize("noteIcon"),{scaleY:e}=this.mindMap.view.getTransformData().transform,t=i*e,{left:r,top:n}=this._noteData.node.node.getBoundingClientRect();return n+=t,{left:r,top:n}}function zN(i){this.mindMap.commonCaches.measureCustomNodeContentSizeEl||(this.mindMap.commonCaches.measureCustomNodeContentSizeEl=document.createElement("div"),this.mindMap.commonCaches.measureCustomNodeContentSizeEl.style.cssText=` + `,(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.noteEl)),this.noteEl.innerText=this.getData("note")),r.on("mouseover",()=>{let{left:s,top:a}=this.getNoteContentPosition();this.mindMap.opt.customNoteContentShow?this.mindMap.opt.customNoteContentShow.show(this.getData("note"),s,a,this):(this.noteEl.style.left=s+"px",this.noteEl.style.top=a+"px",this.noteEl.style.display="block")}),r.on("mouseout",()=>{this.mindMap.opt.customNoteContentShow?this.mindMap.opt.customNoteContentShow.hide():this.noteEl.style.display="none"}),r.on("click",s=>{this.mindMap.emit("node_note_click",this,s,r)}),r.on("dblclick",s=>{this.mindMap.emit("node_note_dblclick",this,s,r)}),{node:r,width:t,height:t}}function eE(){let{attachmentUrl:i,attachmentName:e}=this.getData();if(!i)return;let t=this.getNodeIconSize("attachmentIcon"),{icon:r,style:n}=this.mindMap.opt.attachmentIcon,s=new ke().attr("cursor","pointer").size(t,t);e&&s.add(ke(`${e}`)),s.add(new Ve().size(t,t).fill({color:"transparent"}));let a=ke(r||Xo.attachment).size(t,t);return this.style.iconNode(a,n.color),s.add(a),s.on("click",o=>{this.mindMap.emit("node_attachmentClick",this,o,s)}),s.on("contextmenu",o=>{this.mindMap.emit("node_attachmentContextmenu",this,o,s)}),{node:s,width:t,height:t}}function tE(i){let{style:e}=this.mindMap.opt[i];return Kt(e.size)?this.mindMap.themeConfig.iconSize:e.size}function iE(){let i=this.getNodeIconSize("noteIcon"),{scaleY:e}=this.mindMap.view.getTransformData().transform,t=i*e,{left:r,top:n}=this._noteData.node.node.getBoundingClientRect();return n+=t,{left:r,top:n}}function rE(i){this.mindMap.commonCaches.measureCustomNodeContentSizeEl||(this.mindMap.commonCaches.measureCustomNodeContentSizeEl=document.createElement("div"),this.mindMap.commonCaches.measureCustomNodeContentSizeEl.style.cssText=` position: fixed; left: -99999px; top: -99999px; - `,this.mindMap.el.appendChild(this.mindMap.commonCaches.measureCustomNodeContentSizeEl)),this.mindMap.commonCaches.measureCustomNodeContentSizeEl.innerHTML="",this.mindMap.commonCaches.measureCustomNodeContentSizeEl.appendChild(i);let e=this.mindMap.commonCaches.measureCustomNodeContentSizeEl.getBoundingClientRect();return{width:e.width,height:e.height}}function RN(){return!!this._customNodeContent}var wN,j2,ku,G2=T(()=>{pe();yt();$2();$e();wN=(i,e)=>{let t=new _e,r=new Ce().text(i);return e.text(r),t.add(r),t.bbox()},j2={radius:3,fontSize:12,fill:"",height:20,paddingX:8};ku={createImgNode:MN,getImgShowSize:TN,createIconNode:NN,createRichTextNode:EN,createTextNode:SN,createHyperlinkNode:AN,createTagNode:kN,createNoteNode:CN,createAttachmentNode:_N,getNoteContentPosition:IN,getNodeIconSize:LN,measureCustomNodeContentSize:zN,isUseCustomNodeContent:RN}});function DN(){if(this.getChildrenLength()<=0||this.isRoot)return;let{alwaysShowExpandBtn:i,notShowExpandBtn:e,expandBtnSize:t}=this.mindMap.opt;if(!i&&!e){let{width:r,height:n}=this;this._unVisibleRectRegionNode||(this._unVisibleRectRegionNode=new Ve,this._unVisibleRectRegionNode.fill({color:"transparent"})),this.group.add(this._unVisibleRectRegionNode),this.renderer.layout.renderExpandBtnRect(this._unVisibleRectRegionNode,t,r,n,this)}}function ON(){this._unVisibleRectRegionNode&&(this._unVisibleRectRegionNode.remove(),this._unVisibleRectRegionNode=null)}function BN(){this.needRerenderExpandBtnPlaceholderRect&&(this.needRerenderExpandBtnPlaceholderRect=!1,this.renderExpandBtnPlaceholderRect()),this.getChildrenLength()>0?this._unVisibleRectRegionNode||this.renderExpandBtnPlaceholderRect():this._unVisibleRectRegionNode&&this.clearExpandBtnPlaceholderRect()}var Cu,V2=T(()=>{yt();Cu={renderExpandBtnPlaceholderRect:DN,clearExpandBtnPlaceholderRect:ON,updateExpandBtnPlaceholderRect:BN}});function PN(){this.checkEnableDragModifyNodeWidth()&&(this._dragHandleNodes=null,this.dragHandleWidth=4,this.dragHandleMousedownX=0,this.isDragHandleMousedown=!1,this.dragHandleIndex=0,this.dragHandleMousedownCustomTextWidth=0,this.dragHandleMousedownBodyCursor="",this.dragHandleMousedownLeft=0,this.onDragMousemoveHandle=this.onDragMousemoveHandle.bind(this),window.addEventListener("mousemove",this.onDragMousemoveHandle),this.onDragMouseupHandle=this.onDragMouseupHandle.bind(this),window.addEventListener("mouseup",this.onDragMouseupHandle),this.mindMap.on("node_mouseup",this.onDragMouseupHandle))}function FN(i){if(!this.isDragHandleMousedown)return;i.stopPropagation(),i.preventDefault();let{minNodeTextModifyWidth:e,maxNodeTextModifyWidth:t,isUseCustomNodeContent:r,customCreateNodeContent:n}=this.mindMap.opt,s=r&&n&&this._customNodeContent;document.body.style.cursor="ew-resize",this.group.css({cursor:"ew-resize"});let{scaleX:a}=this.mindMap.draw.transform(),o=i.clientX-this.dragHandleMousedownX,l=this.dragHandleMousedownCustomTextWidth+(this.dragHandleIndex===0?-o:o)/a;if(l=Math.max(l,e),t!==-1&&(l=Math.min(l,t)),!s&&this.getData("image")){let h=this.getImgShowSize();this._rectInfo.textContentWidth-this.customTextWidth+l<=h[0]&&(l=h[0]+this.customTextWidth-this._rectInfo.textContentWidth)}this.customTextWidth=l,this.dragHandleIndex===0&&(this.left=this.dragHandleMousedownLeft+o/a),this.reRender(s?[]:["text"],{ignoreUpdateCustomTextWidth:!0})}function qN(){this.isDragHandleMousedown&&(document.body.style.cursor=this.dragHandleMousedownBodyCursor,this.group.css({cursor:"default"}),this.isDragHandleMousedown=!1,this.dragHandleMousedownX=0,this.dragHandleIndex=0,this.dragHandleMousedownCustomTextWidth=0,this.setData({customTextWidth:this.customTextWidth}),this.mindMap.render(),this.mindMap.emit("dragModifyNodeWidthEnd",this))}function HN(){let i=[new Ve,new Ve];return i.forEach((e,t)=>{e.size(this.dragHandleWidth,this.height).fill({color:"transparent"}).css({cursor:"ew-resize"}),e.on("mousedown",r=>{r.stopPropagation(),r.preventDefault(),this.dragHandleMousedownX=r.clientX,this.dragHandleIndex=t,this.dragHandleMousedownCustomTextWidth=this.customTextWidth===void 0?this._textData?this._textData.width:this.width:this.customTextWidth,this.dragHandleMousedownBodyCursor=document.body.style.cursor,this.dragHandleMousedownLeft=this.left,this.isDragHandleMousedown=!0})}),i}function UN(){this.checkEnableDragModifyNodeWidth()&&(this._dragHandleNodes||(this._dragHandleNodes=this.createDragHandleNode()),this.getData("isActive")?(this._dragHandleNodes.forEach(i=>{i.height(this.height),this.group.add(i)}),this._dragHandleNodes[1].x(this.width-this.dragHandleWidth)):this._dragHandleNodes.forEach(i=>{i.remove()}))}var _u,W2=T(()=>{yt();_u={initDragHandle:PN,onDragMousemoveHandle:FN,onDragMouseupHandle:qN,createDragHandleNode:HN,updateDragHandle:UN}});function $N(){this.mindMap.cooperate&&(this._userListGroup=new _e,this.group.add(this._userListGroup))}function jN(i){let{avatarSize:e,fontSize:t}=this.mindMap.opt.cooperateStyle,r=new _e,n=i.isMore?i.name:String(i.name)[0],s=new Wi().size(e,e);s.fill({color:i.color||G0(n)});let a=new Ce().text(n).fill({color:"#fff"}).css({"font-size":t+"px"}).dx(-t/2).dy((e-t)/2);return r.add(s).add(a),r}function GN(i){let{avatarSize:e}=this.mindMap.opt.cooperateStyle;return new ji().load(i.avatar).size(e,e)}function VN(){if(!this._userListGroup)return;let{avatarSize:i}=this.mindMap.opt.cooperateStyle;this._userListGroup.clear();let e=this.userList.length,t=Math.floor(this.width/i),r=[];e>t?r.push(...this.userList.slice(0,t-1),{isMore:!0,name:"+"+(e-t+1)}):r.push(...this.userList),r.forEach((n,s)=>{let a=null;n.avatar?a=this.createImageAvatar(n):a=this.createTextAvatar(n),a.on("click",o=>{this.mindMap.emit("node_cooperate_avatar_click",n,this,a,o)}),a.on("mouseenter",o=>{this.mindMap.emit("node_cooperate_avatar_mouseenter",n,this,a,o)}),a.on("mouseleave",o=>{this.mindMap.emit("node_cooperate_avatar_mouseleave",n,this,a,o)}),a.x(s*i).cy(-i/2),this._userListGroup.add(a)})}function WN(i){this.userList.find(e=>e.id==i.id)||(this.userList.push(i),this.updateUserListNode())}function YN(i){let e=this.userList.findIndex(t=>t.id==i.id);e!==-1&&(this.userList.splice(e,1),this.updateUserListNode())}function XN(){this.userList=[],this.updateUserListNode()}var Lu,Y2=T(()=>{yt();pe();Lu={createUserListNode:$N,updateUserListNode:VN,createTextAvatar:jN,createImageAvatar:GN,addUser:WN,removeUser:YN,emptyUser:XN}});function KN(){this.isGeneralization||(this._quickCreateChildBtn=null,this._showQuickCreateChildBtn=!1)}function ZN(){if(!(this.isGeneralization||this.getChildrenLength()>0)){if(this._quickCreateChildBtn)this.group.add(this._quickCreateChildBtn);else{let{quickCreateChildBtnIcon:i,expandBtnStyle:e,expandBtnSize:t}=this.mindMap.opt,{icon:r,style:n}=i,{color:s,fill:a}=e||{color:"#808080",fill:"#fff"};s=n.color||s;let o=Ae(r||Uo.quickCreateChild).size(t,t);o.css({cursor:"pointer"}),o.x(0).y(-t/2),this.style.iconNode(o,s);let l=new Wi().size(t);l.x(0).y(-t/2),l.fill({color:a}).css({cursor:"pointer"}),this._quickCreateChildBtn=new _e,this._quickCreateChildBtn.add(l).add(o),this._quickCreateChildBtn.on("click",h=>{h.stopPropagation(),this.mindMap.emit("quick_create_btn_click",this);let{customQuickCreateChildBtnClick:d}=this.mindMap.opt;if(typeof d=="function"){d(this);return}this.mindMap.execCommand("INSERT_CHILD_NODE",!0,[this])}),this._quickCreateChildBtn.on("dblclick",h=>{h.stopPropagation()}),this._quickCreateChildBtn.addClass("smm-quick-create-child-btn"),this.group.add(this._quickCreateChildBtn)}this._showQuickCreateChildBtn=!0,this.renderer.layout.renderExpandBtn(this,this._quickCreateChildBtn)}}function QN(){this.isGeneralization||this._quickCreateChildBtn&&this._showQuickCreateChildBtn&&(this._quickCreateChildBtn.remove(),this._showQuickCreateChildBtn=!1)}function JN(){if(this.isGeneralization)return;let{isActive:i}=this.getData();i||this.removeQuickCreateChildBtn()}var Iu,X2=T(()=>{Eu();yt();Iu={initQuickCreateChildBtn:KN,showQuickCreateChildBtn:ZN,removeQuickCreateChildBtn:QN,hideQuickCreateChildBtn:JN}});function eE(i,e,t,r,n){let{imgTextMargin:s}=this.mindMap.opt;return i==="v"?r>0&&n>0?s:0:e>0&&t>0?s:0}function tE(i){let e=0,t=this._tagData.reduce((r,n)=>(e=Math.max(e,n.height),r+=n.width),0);return t+=(this._tagData.length-1)*i,{width:t,height:e}}function iE(){if(this.isUseCustomNodeContent()){let C=this.measureCustomNodeContentSize(this._customNodeContent);return{width:this.hasCustomWidth()?this.customTextWidth:C.width,height:C.height}}let{TAG_PLACEMENT:i,IMG_PLACEMENT:e}=k,{textContentMargin:t}=this.mindMap.opt,n=(this.getStyle("tagPlacement")||i.RIGHT)===i.BOTTOM,s=this.getStyle("imgPlacement")||e.TOP,a=0,o=0,l=0,h=0,d=0,c=0,f=0;if(this._imgData&&(a=this._imgData.width,o=this._imgData.height),this.mindMap.nodeInnerPrefixList.forEach(C=>{let I=this[`_${C.name}Data`];I&&(l+=I.width,h=Math.max(h,I.height),f++)}),this._prefixData&&(l+=this._prefixData.width,h=Math.max(h,this._prefixData.height),f++),this._iconData.length>0&&(l+=this._iconData.reduce((C,I)=>(h=Math.max(h,I.height),C+=I.width),0)+(this._iconData.length-1)*t,f++),this._textData&&(l+=this._textData.width,h=Math.max(h,this._textData.height),f++),this._hyperlinkData&&(l+=this._hyperlinkData.width,h=Math.max(h,this._hyperlinkData.height),f++),this._tagData.length>0){let{width:C,height:I}=this.getTagContentSize(t);n?(d=C,c=I):(l+=C,h=Math.max(h,I),f++)}this._noteData&&(l+=this._noteData.width,h=Math.max(h,this._noteData.height),f++),this._attachmentData&&(l+=this._attachmentData.width,h=Math.max(h,this._attachmentData.height),f++),this._postfixData&&(l+=this._postfixData.width,h=Math.max(h,this._postfixData.height),f++),this.mindMap.nodeInnerPostfixList.forEach(C=>{let I=this[`_${C.name}Data`];I&&(l+=I.width,h=Math.max(h,I.height),f++)}),l+=(f-1)*t,n&&l>0&&c>0&&(this._rectInfo.textContentWidthWithoutTag=l,l=Math.max(l,d),h=h+t+c),this._rectInfo.textContentWidth=l,this._rectInfo.textContentHeight=h;let m=0,g=0;[e.TOP,e.BOTTOM].includes(s)?(m=Math.max(a,l),g=o+h+this.getImgTextMarin("v",0,0,o,h)):(m=a+l+this.getImgTextMarin("h",a,l),g=Math.max(o,h));let{paddingX:x,paddingY:y}=this.getPaddingVale(),{paddingX:b,paddingY:S}=this.shapeInstance.getShapePadding(m,g,x,y);this.shapePadding.paddingX=b,this.shapePadding.paddingY=S;let A=this.getBorderWidth();return{width:m+x*2+b*2+A,height:g+y*2+S*2+A}}function rE(){if(!this.group)return;this.group.clear();let{hoverRectPadding:i,openRealtimeRenderOnNodeTextEdit:e,textContentMargin:t,addCustomContentToNode:r}=this.mindMap.opt,{width:n,height:s}=this,{paddingX:a,paddingY:o}=this.getPaddingVale(),l=this.getBorderWidth()/2;a+=this.shapePadding.paddingX+l,o+=this.shapePadding.paddingY+l,this.shapeNode=this.shapeInstance.createShape(),this.shapeNode.addClass("smm-node-shape"),this.shapeNode.translate(l,l),this.style.shape(this.shapeNode),this.group.add(this.shapeNode),this.renderExpandBtnPlaceholderRect(),this.createUserListNode&&this.createUserListNode(),this.isGeneralization&&this.generalizationBelongNode&&this.group.addClass("generalization_"+this.generalizationBelongNode.uid);let h=()=>{this.hoverNode=new Ve().size(n+i*2,s+i*2).x(-i).y(-i),this.hoverNode.addClass("smm-hover-node"),this.style.hoverNode(this.hoverNode,n,s),this.group.add(this.hoverNode)};if(this.isUseCustomNodeContent()){let le=pn({el:this._customNodeContent,width:n,height:s});this.group.add(le),h();return}let{IMG_PLACEMENT:d,TAG_PLACEMENT:c}=k,f=this.getStyle("imgPlacement")||d.TOP,g=(this.getStyle("tagPlacement")||c.RIGHT)===c.BOTTOM,{textContentWidth:x,textContentHeight:y,textContentWidthWithoutTag:b}=this._rectInfo,S=y,A=0,C=0,I=this._tagData&&this._tagData.length>0;if(I){let le=this.getTagContentSize(t);A=le.width,C=le.height,g&&(y-=C+t)}let O=0,q=0;if(this._imgData)switch(O=this._imgData.width,q=this._imgData.height,this.group.add(this._imgData.node),f){case d.TOP:this._imgData.node.cx(n/2).y(o);break;case d.BOTTOM:this._imgData.node.cx(n/2).y(s-o-q);break;case d.LEFT:this._imgData.node.x(a).cy(s/2);break;case d.RIGHT:this._imgData.node.x(n-a-O).cy(s/2);break;default:break}let P=new _e,W=0;if(I&&g&&(W=b{let ce=this[`_${le.name}Data`];ce&&(ce.node.x(W).y((y-ce.height)/2),P.add(ce.node),W+=ce.width+t)}),this._prefixData){let le=pn({el:this._prefixData.el,width:this._prefixData.width,height:this._prefixData.height});le.x(W).y((y-this._prefixData.height)/2),P.add(le),W+=this._prefixData.width+t}let ne=new _e;if(this._iconData&&this._iconData.length>0){let le=0;this._iconData.forEach(ce=>{ce.node.x(W+le).y((y-ce.height)/2),ne.add(ce.node),le+=ce.width+t}),P.add(ne),W+=le}if(this._textData){let le=this._textData.node.attr("data-offsetx")||0;this._textData.node.attr("data-offsetx",W),(this._textData.nodeContent||this._textData.node).x(-le).x(W).y((y-this._textData.height)/2),e&&this._textData.node.opacity(this.mindMap.renderer.textEdit.getCurrentEditNode()===this?0:1),P.add(this._textData.node),W+=this._textData.width+t}this._hyperlinkData&&(this._hyperlinkData.node.x(W).y((y-this._hyperlinkData.height)/2),P.add(this._hyperlinkData.node),W+=this._hyperlinkData.width+t);let re=new _e;if(I)if(g){let le=0;this._tagData.forEach(ce=>{ce.node.x(le).y((C-ce.height)/2),re.add(ce.node),le+=ce.width+t}),re.x((x-A)/2).y(S-C),P.add(re)}else{let le=0;this._tagData.forEach(ce=>{ce.node.x(W+le).y((y-ce.height)/2),re.add(ce.node),le+=ce.width+t}),P.add(re),W+=le}if(this._noteData&&(this._noteData.node.x(W).y((y-this._noteData.height)/2),P.add(this._noteData.node),W+=this._noteData.width+t),this._attachmentData&&(this._attachmentData.node.x(W).y((y-this._attachmentData.height)/2),P.add(this._attachmentData.node),W+=this._attachmentData.width+t),this._postfixData){let le=pn({el:this._postfixData.el,width:this._postfixData.width,height:this._postfixData.height});le.x(W).y((y-this._postfixData.height)/2),P.add(le),W+=this._postfixData.width+t}this.mindMap.nodeInnerPostfixList.forEach(le=>{let ce=this[`_${le.name}Data`];ce&&(ce.node.x(W).y((y-ce.height)/2),P.add(ce.node),W+=ce.width+t)}),this.group.add(P);let{width:oe,height:ke}=P.bbox(),Q=0,Y=0;switch(f){case d.TOP:Q=n/2-oe/2,Y=o+q+this.getImgTextMarin("v",0,0,q,S);break;case d.BOTTOM:Q=n/2-oe/2,Y=o;break;case d.LEFT:Q=O+a+this.getImgTextMarin("h",O,x),Y=s/2-ke/2;break;case d.RIGHT:Q=a,Y=s/2-ke/2;break}if(P.translate(Q,Y),h(),this._customContentAddToNodeAdd&&this._customContentAddToNodeAdd.el){let le=pn(this._customContentAddToNodeAdd);this.group.add(le),r&&typeof r.handle=="function"&&r.handle({content:this._customContentAddToNodeAdd,element:le,node:this})}this.mindMap.emit("node_layout_end",this)}var zu,K2=T(()=>{$e();yt();pe();zu={getImgTextMarin:eE,getTagContentSize:tE,getNodeRect:iE,layout:rE}});var Ru,da,X0=T(()=>{Y0();Tu();yt();F2();q2();H2();G2();V2();W2();Y2();X2();K2();$e();pe();Ru=class i{constructor(e={}){this.opt=e,this.nodeData=this.handleData(e.data||{}),this.nodeDataSnapshot="",this.uid=e.uid,this.mindMap=e.mindMap,this.renderer=e.renderer,this.draw=this.mindMap.draw,this.nodeDraw=this.mindMap.nodeDraw,this.lineDraw=this.mindMap.lineDraw,this.style=new qo(this),this.effectiveStyles={},this.shapeInstance=new Ho(this),this.shapePadding={paddingX:0,paddingY:0},this.isRoot=e.isRoot===void 0?!1:e.isRoot,this.isGeneralization=e.isGeneralization===void 0?!1:e.isGeneralization,this.generalizationBelongNode=null,this.layerIndex=e.layerIndex===void 0?0:e.layerIndex,this.width=e.width||0,this.height=e.height||0,this.customTextWidth=e.data.data.customTextWidth||void 0,this._left=e.left||0,this._top=e.top||0,this.customLeft=e.data.data.customLeft||void 0,this.customTop=e.data.data.customTop||void 0,this.isDrag=!1,this.parent=e.parent||null,this.children=e.children||[],this.userList=[],this.group=null,this.shapeNode=null,this.hoverNode=null,this._customNodeContent=null,this._imgData=null,this._iconData=null,this._textData=null,this._hyperlinkData=null,this._tagData=null,this._noteData=null,this.noteEl=null,this.noteContentIsShow=!1,this._attachmentData=null,this._prefixData=null,this._postfixData=null,this._expandBtn=null,this._lastExpandBtnType=null,this._showExpandBtn=!1,this._openExpandNode=null,this._closeExpandNode=null,this._fillExpandNode=null,this._userListGroup=null,this._lines=[],this._generalizationList=[],this._unVisibleRectRegionNode=null,this._isMouseenter=!1,this._customContentAddToNodeAdd=null,this._rectInfo={textContentWidth:0,textContentHeight:0,textContentWidthWithoutTag:0},this._generalizationNodeWidth=0,this._generalizationNodeHeight=0,this.expandBtnSize=this.mindMap.opt.expandBtnSize,this.isMultipleChoice=!1,this.needLayout=!1,this.isHide=!1;let t=Object.getPrototypeOf(this);t.bindEvent||(Object.keys(zu).forEach(r=>{t[r]=zu[r]}),Object.keys(Nu).forEach(r=>{t[r]=Nu[r]}),Object.keys(Su).forEach(r=>{t[r]=Su[r]}),Object.keys(Cu).forEach(r=>{t[r]=Cu[r]}),Object.keys(Au).forEach(r=>{t[r]=Au[r]}),Object.keys(ku).forEach(r=>{t[r]=ku[r]}),this.mindMap.cooperate&&Object.keys(Lu).forEach(r=>{t[r]=Lu[r]}),Object.keys(_u).forEach(r=>{t[r]=_u[r]}),this.mindMap.opt.isShowCreateChildBtnIcon&&(Object.keys(Iu).forEach(r=>{t[r]=Iu[r]}),this.initQuickCreateChildBtn()),t.bindEvent=!0),this.getSize(),this.updateGeneralization(),this.initDragHandle()}get left(){return this.customLeft||this._left}set left(e){this._left=e}get top(){return this.customTop||this._top}set top(e){this._top=e}reset(){this.children=[],this.parent=null,this.isRoot=!1,this.layerIndex=0,this.left=0,this.top=0}resetWhenDelete(){this._isMouseenter=!1}handleData(e){return e.data.expand=e.data.expand!==!1,e.data.isActive=e.data.isActive===!0,e.children=e.children||[],e}createNodeData(e){let{isUseCustomNodeContent:t,customCreateNodeContent:r,createNodePrefixContent:n,createNodePostfixContent:s,addCustomContentToNode:a}=this.mindMap.opt,o=["custom","image","icon","text","hyperlink","tag","note","attachment","prefix","postfix",...this.mindMap.nodeInnerPrefixList.map(h=>h.name),...this.mindMap.nodeInnerPostfixList.map(h=>h.name)],l={};if(Array.isArray(e)?o.forEach(h=>{e.includes(h)&&(l[h]=!0)}):o.forEach(h=>{l[h]=!0}),t&&r&&l.custom&&(this._customNodeContent=r(this)),this._customNodeContent){or(this._customNodeContent);return}l.image&&(this._imgData=this.createImgNode()),l.icon&&(this._iconData=this.createIconNode()),l.text&&(this._textData=this.createTextNode()),l.hyperlink&&(this._hyperlinkData=this.createHyperlinkNode()),l.tag&&(this._tagData=this.createTagNode()),l.note&&(this._noteData=this.createNoteNode()),l.attachment&&(this._attachmentData=this.createAttachmentNode()),this.mindMap.nodeInnerPrefixList.forEach(h=>{l[h.name]&&(this[`_${h.name}Data`]=h.createContent(this))}),l.prefix&&(this._prefixData=n?n(this):null,this._prefixData&&this._prefixData.el&&or(this._prefixData.el)),l.postfix&&(this._postfixData=s?s(this):null,this._postfixData&&this._postfixData.el&&or(this._postfixData.el)),this.mindMap.nodeInnerPostfixList.forEach(h=>{l[h.name]&&(this[`_${h.name}Data`]=h.createContent(this))}),a&&typeof a.create=="function"&&(this._customContentAddToNodeAdd=a.create(this),this._customContentAddToNodeAdd&&this._customContentAddToNodeAdd.el&&or(this._customContentAddToNodeAdd.el))}getSize(e,t={}){t.ignoreUpdateCustomTextWidth||(this.customTextWidth=this.getData("customTextWidth")||void 0),this.customLeft=this.getData("customLeft")||void 0,this.customTop=this.getData("customTop")||void 0,this.createNodeData(e);let{width:n,height:s}=this.getNodeRect(),a=this.width!==n||this.height!==s;return this.width=n,this.height=s,a}bindGroupEvent(){this.group.on("click",e=>{if(this.mindMap.emit("node_click",this,e),this.isMultipleChoice){e.stopPropagation(),this.isMultipleChoice=!1;return}this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate&&this.userList.length>0||this.active(e)}),this.group.on("mousedown",e=>{let{readonly:t,enableCtrlKeyNodeSelection:r,useLeftKeySelectionRightKeyDrag:n,mousedownEventPreventDefault:s}=this.mindMap.opt;if(s&&e.preventDefault(),t||(this.isRoot?e.which===3&&!n&&e.stopPropagation():e.which!==2&&e.stopPropagation()),!t&&(e.ctrlKey||e.metaKey)&&r){this.isMultipleChoice=!0;let a=this.getData("isActive");a||this.mindMap.emit("before_node_active",this,this.renderer.activeNodeList),this.mindMap.renderer[a?"removeNodeFromActiveList":"addNodeToActiveList"](this,!0),this.renderer.emitNodeActiveEvent(a?null:this)}this.mindMap.emit("node_mousedown",this,e)}),this.group.on("mouseup",e=>{!this.isRoot&&e.which!==2&&!this.mindMap.opt.readonly&&e.stopPropagation(),this.mindMap.emit("node_mouseup",this,e)}),this.group.on("mouseenter",e=>{this.isDrag||(this._isMouseenter=!0,this.showExpandBtn(),this.isGeneralization&&this.handleGeneralizationMouseenter(),this.mindMap.emit("node_mouseenter",this,e))}),this.group.on("mouseleave",e=>{this._isMouseenter&&(this._isMouseenter=!1,this.hideExpandBtn(),this.isGeneralization&&this.handleGeneralizationMouseleave(),this.mindMap.emit("node_mouseleave",this,e))}),this.group.on("dblclick",e=>{let{readonly:t,onlyOneEnableActiveNodeOnCooperate:r}=this.mindMap.opt;t||e.ctrlKey||e.metaKey||(e.stopPropagation(),!(r&&this.userList.length>0)&&this.mindMap.emit("node_dblclick",this,e))}),this.group.on("contextmenu",e=>{let{readonly:t,useLeftKeySelectionRightKeyDrag:r}=this.mindMap.opt;t||e.ctrlKey||(e.stopPropagation(),e.preventDefault(),!(this.mindMap.select&&!r&&this.mindMap.select.hasSelectRange())&&(this.getData("isActive")&&this.renderer.activeNodeList.length===1||(this.renderer.clearActiveNodeList(),this.active(e)),this.mindMap.emit("node_contextmenu",e,this)))})}active(e){this.mindMap.opt.readonly||(e&&e.stopPropagation(),!this.getData("isActive")&&(this.mindMap.emit("before_node_active",this,this.renderer.activeNodeList),this.renderer.clearActiveNodeList(),this.renderer.addNodeToActiveList(this,!0),this.renderer.emitNodeActiveEvent(this)))}deactivate(){this.mindMap.renderer.removeNodeFromActiveList(this),this.mindMap.renderer.emitNodeActiveEvent()}update(e){if(!this.group)return;this.updateNodeActiveClass();let{alwaysShowExpandBtn:t,notShowExpandBtn:r,isShowCreateChildBtnIcon:n,readonly:s}=this.mindMap.opt,a=this.getChildrenLength();if(!r)if(t)this._expandBtn&&a<=0?this.removeExpandBtn():this.renderExpandBtn();else{let{isActive:l,expand:h}=this.getData();a<=0?this.removeExpandBtn():h&&!l&&!this._isMouseenter?this.hideExpandBtn():this.showExpandBtn()}if(n)if(a>0)this.removeQuickCreateChildBtn();else{let{isActive:l}=this.getData();l?this.showQuickCreateChildBtn():this.hideQuickCreateChildBtn()}this.updateDragHandle(),this.renderGeneralization(e),this.updateUserListNode&&this.updateUserListNode();let o=this.group.transform();this.nodeDataSnapshot=s?"":JSON.stringify(this.getData()),(this.left!==o.translateX||this.top!==o.translateY)&&this.group.translate(this.left-o.translateX,this.top-o.translateY)}getNodePosInClient(e,t){let r=this.mindMap.draw.transform(),{scaleX:n,scaleY:s,translateX:a,translateY:o}=r,l=e*n+a,h=t*s+o;return{left:l,top:h}}checkIsInClient(e=0){let{left:t,top:r}=this.getNodePosInClient(this.left,this.top);return t+this.width>0-e&&r+this.height>0-e&&t{},t=!1,r=!1){this.renderLine();let{openPerformance:n,performanceConfig:s}=this.mindMap.opt;if(t||!n||this.checkIsInClient(s.padding)||this.isRoot?this.group?(this.nodeDraw.has(this.group)||this.nodeDraw.add(this.group),this.needLayout&&(this.needLayout=!1,this.layout()),this.updateExpandBtnPlaceholderRect(),this.update(t)):(this.group=new _e,this.group.addClass("smm-node"),this.group.css({cursor:"default"}),this.bindGroupEvent(),this.nodeDraw.add(this.group),this.layout(),this.update(t)):n&&s.removeNodeWhenOutCanvas&&this.removeSelf(),this.children&&this.children.length&&this.getData("expand")!==!1){let a=0;this.children.forEach(o=>{let l=()=>{o.render(()=>{a++,a>=this.children.length&&e()},t,r)};r?setTimeout(l,0):l()})}else e();this.nodeData.inserting&&(delete this.nodeData.inserting,this.active(),this.mindMap.emit("node_dblclick",this,null,!0))}removeSelf(){this.group&&(this.group.remove(),this.removeGeneralization())}remove(){this.group&&(this.group.remove(),this.removeGeneralization(),this.removeLine(),this.children&&this.children.length&&this.children.forEach(e=>{e.remove()}))}destroy(){this.removeLine(),this.parent&&this.parent.removeLine(),this.group&&(this.emptyUser&&this.emptyUser(),this.resetWhenDelete(),this.group.remove(),this.removeGeneralization(),this.group=null,this.style.onRemove())}hide(){if(this.group&&this.group.hide(),this.hideGeneralization(),this.parent){let e=this.parent.children.indexOf(this);this.parent._lines[e]&&this.parent._lines[e].hide(),this._lines.forEach(t=>{t.hide()})}this.children&&this.children.length&&this.children.forEach(e=>{e.hide()})}show(){if(this.group){if(this.group.show(),this.showGeneralization(),this.parent){let e=this.parent.children.indexOf(this);this.parent._lines[e]&&this.parent._lines[e].show(),this._lines.forEach(t=>{t.show()})}this.children&&this.children.length&&this.children.forEach(e=>{e.show()})}}setOpacity(e){this.group&&this.group.opacity(e),this._lines.forEach(t=>{t.opacity(e)}),this.children.forEach(t=>{t.setOpacity(e)}),this.setGeneralizationOpacity(e)}hideChildren(){this._lines.forEach(e=>{e.hide()}),this.children&&this.children.length&&this.children.forEach(e=>{e.hide()})}showChildren(){this._lines.forEach(e=>{e.show()}),this.children&&this.children.length&&this.children.forEach(e=>{e.show()})}startDrag(){this.isDrag=!0,this.group&&this.group.addClass("smm-node-dragging")}endDrag(){this.isDrag=!1,this.group&&this.group.removeClass("smm-node-dragging")}renderLine(e=!1){if(this.getData("expand")===!1)return;let t=this.getChildrenLength();this.mindMap.renderer.layout.nodeIsRemoveAllLines&&this.mindMap.renderer.layout.nodeIsRemoveAllLines(this)&&(t=0),t>this._lines.length?new Array(t-this._lines.length).fill(0).forEach(()=>{this._lines.push(this.lineDraw.path())}):t{r.remove()}),this._lines=this._lines.slice(0,t)),this.renderer.layout.renderLine(this,this._lines,(...r)=>{this.styleLine(...r)},this.style.getStyle("lineStyle",!0)),e&&this.children&&this.children.length>0&&this.children.forEach(r=>{r.renderLine(e)})}getShape(){return this.mindMap.themeConfig.nodeUseLineStyle?k.SHAPE.RECTANGLE:this.style.getStyle("shape",!1,!1)}hasCustomPosition(){return this.customLeft!==void 0&&this.customTop!==void 0}ancestorHasCustomPosition(){let e=this;for(;e;){if(e.hasCustomPosition())return!0;e=e.parent}return!1}ancestorHasGeneralization(){let e=this.parent;for(;e;){if(e.checkHasGeneralization())return!0;e=e.parent}return!1}addChildren(e){this.children.push(e)}styleLine(e,t,r){let{enableInheritAncestorLineStyle:n}=this.mindMap.opt,s=n?"getSelfInhertStyle":"getSelfStyle",a=t[s]("lineWidth")||t.getStyle("lineWidth",!0),o=t[s]("lineColor")||this.getRainbowLineColor(t)||t.getStyle("lineColor",!0),l=t[s]("lineDasharray")||t.getStyle("lineDasharray",!0);this.style.line(e,{width:a,color:o,dasharray:l},r,t)}getRainbowLineColor(e){return this.mindMap.rainbowLines?this.mindMap.rainbowLines.getNodeColor(e):""}removeLine(){this._lines.forEach(e=>{e.remove()}),this._lines=[]}isAncestor(e){if(this.uid===e.uid)return!1;let t=e.parent;for(;t;){if(this.uid===t.uid)return!0;t=t.parent}return!1}isParent(e){if(this.uid===e.uid)return!1;let t=e.parent;return!!(t&&this.uid===t.uid)}isBrother(e){return!this.parent||this.uid===e.uid?!1:this.parent.children.find(t=>t.uid===e.uid)}getIndexInBrothers(){return this.parent&&this.parent.children?this.parent.children.findIndex(e=>e.uid===this.uid):-1}getPaddingVale(){return{paddingX:this.getStyle("paddingX"),paddingY:this.getStyle("paddingY")}}getStyle(e,t){let r=this.style.merge(e,t);return r===void 0?"":r}getSelfStyle(e){return this.style.getSelfStyle(e)}getParentSelfStyle(e){return this.parent?this.parent.getSelfStyle(e)||this.parent.getParentSelfStyle(e):null}getSelfInhertStyle(e){return this.getSelfStyle(e)||this.getParentSelfStyle(e)}getBorderWidth(){return this.style.merge("borderWidth",!1)||0}getData(e){return e?this.nodeData.data[e]:this.nodeData.data}getPureData(e=!0,t=!1){return ls({},this,e,t)}getAncestorNodes(){let e=[],t=this.parent;for(;t;)e.unshift(t),t=t.parent;return e}hasCustomStyle(){return this.style.hasCustomStyle()}getRect(){return this.group?this.group.rbox():null}getRectInSvg(){let{scaleX:e,scaleY:t,translateX:r,translateY:n}=this.mindMap.draw.transform(),{left:s,top:a,width:o,height:l}=this,h=(s+o)*e+r,d=(a+l)*t+n;return s=s*e+r,a=a*t+n,{left:s,right:h,top:a,bottom:d,width:o*e,height:l*t}}highlight(){this.group&&this.group.addClass("smm-node-highlight")}closeHighlight(){this.group&&this.group.removeClass("smm-node-highlight")}fakeClone(){let e=new i({...this.opt,uid:wt()});return Object.keys(this).forEach(t=>{e[t]=this[t]}),e}createSvgTextNode(e=""){return new Ce().text(e)}getSvgObjects(){return{SVG:Ae,G:_e,Rect:Ve}}checkEnableDragModifyNodeWidth(){let{enableDragModifyNodeWidth:e,isUseCustomNodeContent:t,customCreateNodeContent:r}=this.mindMap.opt;return e&&(this.mindMap.richText||t&&r)}hasCustomWidth(){return this.checkEnableDragModifyNodeWidth()&&this.customTextWidth!==void 0}getChildrenLength(){return this.nodeData.children?this.nodeData.children.length:0}},da=Ru});var jo,Z2=T(()=>{jo=class{constructor(e){this.max=e||1e3,this.size=0,this.pool=new Map}add(e,t){return!this.has(e)&&this.size>=this.max?!1:(this.delete(e),this.pool.set(e,t),this.size++,!0)}delete(e){this.pool.has(e)&&(this.pool.delete(e),this.size--)}has(e){return this.pool.has(e)}get(e){if(this.pool.has(e))return this.pool.get(e)}clear(){this.size=0,this.pool=new Map}}});var Du,Mt,Ar=T(()=>{X0();$e();Z2();pe();Du=class{constructor(e){this.renderer=e,this.mindMap=e.mindMap,this.draw=this.mindMap.draw,this.lineDraw=this.mindMap.lineDraw,this.root=null,this.lru=new jo(this.mindMap.opt.maxNodeCacheCount),this.rootNodeCenterOffset=null}doLayout(){throw new Error("\u3010computed\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderLine(){throw new Error("\u3010renderLine\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderExpandBtn(){throw new Error("\u3010renderExpandBtn\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderGeneralization(){}cacheNode(e,t){this.renderer.nodeCache[e]=t,this.lru.add(e,t)}checkIsNeedResizeSources(){return this.renderer.checkHasRenderSource(k.CHANGE_THEME)}checkIsLayerTypeChange(e,t){if(e>=2&&t>=2)return!1;if(e>=2&&t<2||e<2&&t>=2)return!0}checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(e){this.renderer.checkHasRenderSource(k.CHANGE_LAYOUT)&&(e.needRerenderExpandBtnPlaceholderRect=!0)}checkIsNodeDataChange(e,t){if(e)e=typeof e=="string"?JSON.parse(e):e,e.isActive=t.isActive,e.expand=t.expand,e=JSON.stringify(e);else return!1;return e!==JSON.stringify(t)}checkNodeFixChange(e,t,r){let n=!1;this.mindMap.nodeInnerPrefixList.forEach(a=>{if(a.updateNodeData){let o=a.updateNodeData(e,t);o&&(n=o)}});let s=!1;return this.mindMap.nodeInnerPostfixList.forEach(a=>{if(a.updateNodeData){let o=a.updateNodeData(e,r);o&&(s=o)}}),n||s}createNode(e,t,r,n,s,a){let o={};this.mindMap.nodeInnerPrefixList.forEach(c=>{if(c.createNodeData){let[f,m]=c.createNodeData({data:e,parent:t,ancestors:a,layerIndex:n,index:s});o[f]=m}});let l={};this.mindMap.nodeInnerPostfixList.forEach(c=>{if(c.createNodeData){let[f,m]=c.createNodeData({data:e,parent:t,ancestors:a,layerIndex:n,index:s});l[f]=m}});let h=e.data.uid,d=null;if(e&&e._node&&!this.renderer.reRender){d=e._node;let c=this.checkIsLayerTypeChange(d.layerIndex,n);d.reset(),d.layerIndex=n,r?d.isRoot=!0:d.parent=t._node,this.cacheNode(e._node.uid,d),this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(d);let f=this.checkNodeFixChange(d,o,l),m=this.checkIsNeedResizeSources(),g=this.checkIsNodeDataChange(e._node.nodeDataSnapshot,e.data);(m||g||c||d.getData("resetRichText")||d.getData("needUpdate")||f)&&(d.getSize(),d.needLayout=!0),this.checkGetGeneralizationChange(d,m)}else if((this.lru.has(h)||this.renderer.lastNodeCache[h])&&!this.renderer.reRender){d=this.lru.get(h)||this.renderer.lastNodeCache[h];let c=JSON.stringify(d.getData()),f=this.checkIsLayerTypeChange(d.layerIndex,n);d.reset(),d.nodeData=d.handleData(e||{}),d.layerIndex=n,r?d.isRoot=!0:d.parent=t._node,this.cacheNode(h,d),this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(d),e._node=d;let m=this.checkIsNeedResizeSources(),g=this.checkIsNodeDataChange(c,e.data),x=this.checkNodeFixChange(d,o,l);(m||g||f||d.getData("resetRichText")||d.getData("needUpdate")||x)&&(d.getSize(),d.needLayout=!0),this.checkGetGeneralizationChange(d,m)}else{let c=h||wt();d=new da({data:e,uid:c,renderer:this.renderer,mindMap:this.mindMap,draw:this.draw,layerIndex:n,isRoot:r,parent:r?null:t._node,...o}),e.data.uid=c,this.cacheNode(c,d),e._node=d}return e.data.isActive&&this.renderer.addNodeToActiveList(d),this.mindMap.renderer.findActiveNodeIndex(d)!==-1&&d.setData({isActive:!0}),r?this.root=d:t._node.addChildren(d),d}checkGetGeneralizationChange(e,t){let r=e.getData("generalization");r&&e._generalizationList&&e._generalizationList.length>0&&e._generalizationList.forEach((n,s)=>{let a=n.generalizationNode,o=a.getData(),l=r[s];(t||l&&JSON.stringify(o)!==JSON.stringify(l))&&(l&&(a.nodeData.data=l),a.getSize(),a.needLayout=!0)})}formatPosition(e,t,r){return typeof e=="number"?e:Uc[e]!==void 0?t*Uc[e]:/^\d\d*%$/.test(e)?Number.parseFloat(e)/100*t:(t-r)/2}formatInitRootNodePosition(e){let{CENTER:t}=k.INIT_ROOT_NODE_POSITION;return(!e||!Array.isArray(e)||e.length<2)&&(e=[t,t]),e}setNodeCenter(e,t){let{initRootNodePosition:r}=this.mindMap.opt;r=this.formatInitRootNodePosition(t||r),e.left=this.formatPosition(r[0],this.mindMap.width,e.width),e.top=this.formatPosition(r[1],this.mindMap.height,e.height)}getRootCenterOffset(e,t){if(this.rootNodeCenterOffset)return this.rootNodeCenterOffset;let{initRootNodePosition:r}=this.mindMap.opt,{CENTER:n}=k.INIT_ROOT_NODE_POSITION;if(r=this.formatInitRootNodePosition(r),r[0]===n&&r[1]===n)this.rootNodeCenterOffset={x:0,y:0};else{let s={width:e,height:t},a={width:e,height:t};this.setNodeCenter(s,[n,n]),this.setNodeCenter(a),this.rootNodeCenterOffset={x:a.left-s.left,y:a.top-s.top}}return this.rootNodeCenterOffset}updateChildren(e,t,r){e.forEach(n=>{n[t]+=r,n.children&&n.children.length&&!n.hasCustomPosition()&&this.updateChildren(n.children,t,r)})}updateChildrenPro(e,t){e.forEach(r=>{Object.keys(t).forEach(n=>{r[n]+=t[n]}),r.children&&r.children.length&&!r.hasCustomPosition()&&this.updateChildrenPro(r.children,t)})}getNodeAreaWidth(e,t=!1){let r=[],n=0,s=(a,o)=>{t&&a.checkHasGeneralization()&&(n+=a._generalizationNodeWidth),a.children.length?(o+=a.width/2,a.children.forEach(l=>{s(l,o)})):(o+=a.width,r.push(o))};return s(e,0),Math.max(...r)+n}quadraticCurvePath(e,t,r,n,s=!1){let a,o;return s?(a=e+(r-e)*.8,o=t+(n-t)*.2):(a=e+(r-e)*.2,o=t+(n-t)*.8),`M ${e},${t} Q ${a},${o} ${r},${n}`}cubicBezierPath(e,t,r,n,s=!1){let a,o,l,h;return s?(a=e,o=t+(n-t)/2,l=r,h=o):(a=e+(r-e)/2,o=t,l=a,h=n),`M ${e},${t} C ${a},${o} ${l},${h} ${r},${n}`}computeNewPoint(e,t,r=0){if(e[0]===t[0])return t[1]>e[1]?[t[0],t[1]-r]:[t[0],t[1]+r];if(e[1]===t[1])return t[0]>e[0]?[t[0]-r,t[1]]:[t[0]+r,t[1]]}createFoldLine(e){let{lineRadius:t}=this.mindMap.themeConfig,r=e.length,n="",s="";if(r>=3&&t>0){let a=e[r-3],o=e[r-2],l=e[r-1];if(!(a[0].toFixed(0)===o[0].toFixed(0)&&o[0].toFixed(0)===l[0].toFixed(0)||a[1].toFixed(0)===o[1].toFixed(0)&&o[1].toFixed(0)===l[1].toFixed(0))){let d=this.computeNewPoint(a,o,t),c=this.computeNewPoint(l,o,t);s=`Q ${o[0]},${o[1]} ${c[0]},${c[1]}`,e.splice(r-2,1,d,s)}}return e.forEach((a,o)=>{if(typeof a=="string")n+=a;else{let[l,h]=a;o===0?n+=`M ${l},${h}`:n+=`L ${l},${h}`}}),n}getMarginX(e){let{themeConfig:t,opt:r}=this.mindMap,{second:n,node:s}=t,a=r.hoverRectPadding*2;return e===1?n.marginX+a:s.marginX+a}getMarginY(e){let{themeConfig:t,opt:r}=this.mindMap,{second:n,node:s}=t,a=r.hoverRectPadding*2;return e===1?n.marginY+a:s.marginY+a}getNodeWidthWithGeneralization(e){return Math.max(e.width,e.checkHasGeneralization()?e._generalizationNodeWidth:0)}getNodeHeightWithGeneralization(e){return Math.max(e.height,e.checkHasGeneralization()?e._generalizationNodeHeight:0)}getNodeBoundaries(e,t){let{generalizationLineMargin:r,generalizationNodeMargin:n}=this.mindMap.themeConfig,s=d=>{let c=1/0,f=-1/0,m=1/0,g=-1/0;d.children&&d.children.length>0&&d.children.forEach(y=>{let{left:b,right:S,top:A,bottom:C}=s(y),I=y.checkHasGeneralization()&&y.getData("expand")?y._generalizationNodeWidth+n:0,O=y.checkHasGeneralization()&&y.getData("expand")?y._generalizationNodeHeight+n:0;b-(t==="h"?I:0)f&&(f=S+(t==="h"?I:0)),Ag&&(g=C+(t==="v"?O:0))});let x={left:d.left,right:d.left+d.width,top:d.top,bottom:d.top+d.height};return{left:x.leftf?x.right:f,top:x.topg?x.bottom:g}},{left:a,right:o,top:l,bottom:h}=s(e);return{left:a,right:o,top:l,bottom:h,generalizationLineMargin:r,generalizationNodeMargin:n}}getChildrenBoundaries(e,t,r=0,n){let{generalizationLineMargin:s,generalizationNodeMargin:a}=this.mindMap.themeConfig,o=e.children.slice(r,n+1),l=1/0,h=-1/0,d=1/0,c=-1/0;return o.forEach(f=>{let m=this.getNodeBoundaries(f,t);l=m.lefth?m.right:h,d=m.topc?m.bottom:c}),{left:l,right:h,top:d,bottom:c,generalizationLineMargin:s,generalizationNodeMargin:a}}getNodeGeneralizationRenderBoundaries(e,t){let r=null;return e.range?r=this.getChildrenBoundaries(e.node,t,e.range[0],e.range[1]):r=this.getNodeBoundaries(e.node,t),r}getNodeActChildrenLength(e){return e.nodeData.children&&e.nodeData.children.length}setLineStyle(e,t,r,n){t.plot(this.transformPath(r)),e&&e(t,n,!0)}transformPath(e){let{customTransformNodeLinePath:t}=this.mindMap.opt;return t?t(e):e}},Mt=Du});var Ou,K0,Bu=T(()=>{Ou=class{constructor(e){this.mindMap=e,this.autoMoveTimer=null}onMove(e,t,r=()=>{},n=()=>{}){r();let s=this.mindMap.opt.selectTranslateStep,a=this.mindMap.opt.selectTranslateLimit,o=0;e<=this.mindMap.elRect.left+a&&(n("left",s),this.mindMap.view.translateX(s),o++),e>=this.mindMap.elRect.right-a&&(n("right",s),this.mindMap.view.translateX(-s),o++),t<=this.mindMap.elRect.top+a&&(n("top",s),this.mindMap.view.translateY(s),o++),t>=this.mindMap.elRect.bottom-a&&(n("bottom",s),this.mindMap.view.translateY(-s),o++),o>0&&this.startAutoMove(e,t,r,n)}startAutoMove(e,t,r,n){this.autoMoveTimer=setTimeout(()=>{this.onMove(e,t,r,n)},20)}clearAutoMoveTimer(){clearTimeout(this.autoMoveTimer)}},K0=Ou});var Q2={};tt(Q2,{default:()=>nE});var Z0,nE,J2=T(()=>{pe();Ar();$e();Bu();Z0=class extends Mt{constructor({mindMap:e}){super(e.renderer),this.mindMap=e,this.autoMove=new K0(e),this.reset(),this.bindEvent()}reset(){this.isDragging=!1,this.mousedownNode=null,this.beingDragNodeList=[],this.nodeList=[],this.overlapNode=null,this.prevNode=null,this.nextNode=null,this.drawTransform=null,this.clone=null,this.placeholder=null,this.placeholderWidth=50,this.placeholderHeight=10,this.placeHolderLine=null,this.placeHolderExtraLines=[],this.offsetX=0,this.offsetY=0,this.isMousedown=!1,this.mouseDownX=0,this.mouseDownY=0,this.mouseMoveX=0,this.mouseMoveY=0,this.checkDragOffset=10,this.minOffset=10}bindEvent(){this.onNodeMousedown=this.onNodeMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.checkOverlapNode=Si(this.checkOverlapNode,300,this),this.mindMap.on("node_mousedown",this.onNodeMousedown),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("node_mouseup",this.onMouseup),this.mindMap.on("mouseup",this.onMouseup)}unBindEvent(){this.mindMap.off("node_mousedown",this.onNodeMousedown),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("node_mouseup",this.onMouseup),this.mindMap.off("mouseup",this.onMouseup)}onNodeMousedown(e,t){if(this.mindMap.opt.readonly||t.which!==1||e.isGeneralization||e.isRoot)return;this.isMousedown=!0,this.mousedownNode=e;let{x:r,y:n}=this.mindMap.toPos(t.clientX,t.clientY);this.mouseDownX=r,this.mouseDownY=n}onMousemove(e){if(this.mindMap.opt.readonly||!this.isMousedown)return;e.preventDefault();let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseMoveX=t,this.mouseMoveY=r,!(!this.isDragging&&Math.abs(t-this.mouseDownX)<=this.checkDragOffset&&Math.abs(r-this.mouseDownY)<=this.checkDragOffset)&&(this.mindMap.emit("node_dragging",this.mousedownNode),this.handleStartMove(),this.onMove(t,r,e))}async onMouseup(e){if(!this.isMousedown)return;let{autoMoveWhenMouseInEdgeOnDrag:t,enableFreeDrag:r,beforeDragEnd:n}=this.mindMap.opt;t&&this.mindMap.select&&this.autoMove.clearAutoMoveTimer(),this.isMousedown=!1,this.beingDragNodeList.forEach(l=>{l.setOpacity(1),l.showChildren(),l.endDrag()}),this.removeCloneNode();let s=this.overlapNode?this.overlapNode.getData("uid"):"",a=this.prevNode?this.prevNode.getData("uid"):"",o=this.nextNode?this.nextNode.getData("uid"):"";if(this.isDragging&&typeof n=="function"&&await n({overlapNodeUid:s,prevNodeUid:a,nextNodeUid:o,beingDragNodeList:[...this.beingDragNodeList]})){this.reset();return}if(this.overlapNode)this.removeNodeActive(this.overlapNode),this.mindMap.execCommand("MOVE_NODE_TO",this.beingDragNodeList,this.overlapNode);else if(this.prevNode)this.removeNodeActive(this.prevNode),this.mindMap.execCommand("INSERT_AFTER",this.beingDragNodeList,this.prevNode);else if(this.nextNode)this.removeNodeActive(this.nextNode),this.mindMap.execCommand("INSERT_BEFORE",this.beingDragNodeList,this.nextNode);else if(this.clone&&r&&this.beingDragNodeList.length===1){let{x:l,y:h}=this.mindMap.toPos(e.clientX-this.offsetX,e.clientY-this.offsetY),{scaleX:d,scaleY:c,translateX:f,translateY:m}=this.drawTransform;l=(l-f)/d,h=(h-m)/c,this.mousedownNode.left=l,this.mousedownNode.top=h,this.mousedownNode.customLeft=l,this.mousedownNode.customTop=h,this.mindMap.execCommand("SET_NODE_CUSTOM_POSITION",this.mousedownNode,l,h),this.mindMap.render()}this.isDragging&&this.mindMap.emit("node_dragend",{overlapNodeUid:s,prevNodeUid:a,nextNodeUid:o}),this.reset()}removeNodeActive(e){e.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1)}onMove(e,t,r){if(!this.isMousedown||!this.isDragging)return;let{scaleX:n,scaleY:s,translateX:a,translateY:o}=this.drawTransform,l=e-this.offsetX,h=t-this.offsetY;e=(l-a)/n,t=(h-o)/s;let d=this.clone.transform();this.clone.translate(e-d.translateX,t-d.translateY),this.checkOverlapNode(),this.drawTransform=this.mindMap.draw.transform(),this.autoMove.clearAutoMoveTimer(),this.autoMove.onMove(r.clientX,r.clientY)}async handleStartMove(){if(!this.isDragging){let e=this.mousedownNode;this.drawTransform=this.mindMap.draw.transform();let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.drawTransform;this.offsetX=this.mouseDownX-(e.left*t+n),this.offsetY=this.mouseDownY-(e.top*r+s),e.getData("isActive")?this.beingDragNodeList=Fo(ds(this.mindMap.renderer.activeNodeList.filter(o=>!o.isRoot&&!o.isGeneralization))):this.beingDragNodeList=[e];let{beforeDragStart:a}=this.mindMap.opt;if(typeof a=="function"&&await a([...this.beingDragNodeList]))return;this.nodeTreeToList(),this.createCloneNode(),this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.isDragging=!0}}nodeTreeToList(){let e=[];Xt(this.mindMap.renderer.root,t=>{this.checkIsInBeingDragNodeList(t)||(e[t.layerIndex]||(e[t.layerIndex]=[]),e[t.layerIndex].push(t))}),this.nodeList=e.reduceRight((t,r)=>[...t,...r],[])}createCloneNode(){if(!this.clone){let{dragMultiNodeRectConfig:e,dragPlaceholderRectFill:t,dragPlaceholderLineConfig:r,dragOpacityConfig:n,handleDragCloneNode:s}=this.mindMap.opt,{width:a,height:o,fill:l}=e,h=this.beingDragNodeList[0],d=h.style.merge("lineColor",!0);if(this.beingDragNodeList.length>1)this.clone=this.mindMap.otherDraw.rect().size(a,o).radius(o/2).fill({color:l||d}),this.offsetX=a/2,this.offsetY=o/2;else{this.clone=h.group.clone();let c=this.clone.findOne(".smm-expand-btn");c&&c.remove(),this.mindMap.otherDraw.add(this.clone),typeof s=="function"&&s(this.clone)}this.clone.opacity(n.cloneNodeOpacity),this.clone.css("z-index",99999),this.placeholder=this.mindMap.otherDraw.rect().fill({color:t||d}).radius(5),this.placeHolderLine=this.mindMap.otherDraw.path().stroke({color:r.color||d,width:r.width}).fill({color:"none"}),this.beingDragNodeList.forEach(c=>{c.setOpacity(n.beingDragNodeOpacity),c.hideChildren(),c.startDrag()})}}removeCloneNode(){this.clone&&(this.clone.remove(),this.placeholder.remove(),this.placeHolderLine.remove(),this.removeExtraLines())}removeExtraLines(){this.placeHolderExtraLines.forEach(e=>{e.remove()}),this.placeHolderExtraLines=[]}checkOverlapNode(){if(!this.drawTransform||!this.placeholder)return;let{LOGICAL_STRUCTURE:e,LOGICAL_STRUCTURE_LEFT:t,MIND_MAP:r,ORGANIZATION_STRUCTURE:n,CATALOG_ORGANIZATION:s,TIMELINE:a,TIMELINE2:o,VERTICAL_TIMELINE:l,VERTICAL_TIMELINE2:h,VERTICAL_TIMELINE3:d,FISHBONE:c,FISHBONE2:f,RIGHT_FISHBONE:m,RIGHT_FISHBONE2:g}=k.LAYOUT;this.overlapNode=null,this.prevNode=null,this.nextNode=null,this.placeholder.size(0,0),this.placeHolderLine.hide(),this.removeExtraLines(),this.nodeList.forEach(x=>{if(x.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",x,!1),!(this.overlapNode||this.prevNode&&this.nextNode))switch(this.mindMap.opt.layout){case e:case t:this.handleLogicalStructure(x);break;case r:this.handleMindMap(x);break;case n:this.handleOrganizationStructure(x);break;case s:this.handleCatalogOrganization(x);break;case a:this.handleTimeLine(x);break;case o:this.handleTimeLine2(x);break;case l:case h:case d:this.handleLogicalStructure(x);break;case c:case f:case m:case g:this.handleFishbone(x);break;default:this.handleLogicalStructure(x)}}),this.overlapNode&&this.handleOverlapNode()}handleOverlapNode(){let{LOGICAL_STRUCTURE:e,LOGICAL_STRUCTURE_LEFT:t,MIND_MAP:r,ORGANIZATION_STRUCTURE:n,CATALOG_ORGANIZATION:s,TIMELINE:a,TIMELINE2:o,VERTICAL_TIMELINE:l,VERTICAL_TIMELINE2:h,VERTICAL_TIMELINE3:d,FISHBONE:c,FISHBONE2:f,RIGHT_FISHBONE:m,RIGHT_FISHBONE2:g}=k.LAYOUT,{LEFT:x,TOP:y,RIGHT:b,BOTTOM:S}=k.LAYOUT_GROW_DIR,A=this.overlapNode.layerIndex,C=this.overlapNode.children,I=this.mindMap.renderer.layout.getMarginX(A+1),O=this.mindMap.renderer.layout.getMarginY(A+1),q=this.placeholderWidth/2,P=this.placeholderHeight/2,W="",ne="",re="",oe=!1,ke=!1;if(C.length>0){let Q=C[C.length-1],Y=this.getNodeRect(Q);switch(W=this.getNewChildNodeDir(Q),this.mindMap.opt.layout){case e:case r:ne=W===x?Y.originRight-this.placeholderWidth:Y.originLeft,re=Y.originBottom+this.minOffset-P;break;case t:ne=Y.originRight-this.placeholderWidth,re=Y.originBottom+this.minOffset-P;break;case n:oe=!0,ne=Y.originRight+this.minOffset-P,re=Y.originTop;break;case s:A===0?(oe=!0,ne=Y.originRight+this.minOffset-P,re=Y.originTop):(ne=Y.originLeft,re=Y.originBottom+this.minOffset-P);break;case a:A===0?(oe=!0,ne=Y.originRight+this.minOffset-P,re=Y.originTop+Y.originHeight/2-q):(ne=Y.originLeft,re=Y.originBottom+this.minOffset-P);break;case o:A===0?(oe=!0,ne=Y.originRight+this.minOffset-P,re=Y.originTop+Y.originHeight/2-q):(ne=Y.originLeft,A===1?re=W===y?Y.originTop-this.placeholderHeight-this.minOffset+P:Y.originBottom+this.minOffset-P:re=Y.originBottom+this.minOffset-P);break;case l:case h:case d:A===0?(ne=Y.originLeft+Y.originWidth/2-q,re=Y.originBottom+this.minOffset-P):(ne=W===b?Y.originLeft:Y.originRight-this.placeholderWidth,re=Y.originBottom+this.minOffset-P);break;case c:case f:case m:case g:A<=1?(ke=!0,this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)):(ne=Y.originLeft,re=W===y?Y.originBottom+this.minOffset-P:Y.originTop-this.placeholderHeight-this.minOffset+P);break;default:}}else{let Q=this.getNodeRect(this.overlapNode);switch(W=this.getNewChildNodeDir(this.overlapNode),this.mindMap.opt.layout){case e:case r:ne=W===b?Q.originRight+I:Q.originLeft-this.placeholderWidth-I,re=Q.originTop+(Q.originHeight-this.placeholderHeight)/2;break;case t:ne=Q.originLeft-this.placeholderWidth-I,re=Q.originTop+(Q.originHeight-this.placeholderHeight)/2;break;case n:oe=!0,ne=Q.originLeft+(Q.originWidth-this.placeholderHeight)/2,re=Q.originBottom+I;break;case s:A===0&&(oe=!0),ne=Q.originLeft+Q.originWidth*.5,re=Q.originBottom+I;break;case a:A===0&&(oe=!0),ne=Q.originLeft+Q.originWidth*.5,re=Q.originBottom+O;break;case o:A===0&&(oe=!0),ne=Q.originLeft+Q.originWidth*.5,A===1?re=W===y?Q.originTop-this.placeholderHeight-I:Q.originBottom+I:re=Q.originBottom+I;break;case l:case h:case d:A===0&&(oe=!0),ne=W===b?Q.originRight+I:Q.originLeft-this.placeholderWidth-I,re=Q.originTop+Q.originHeight/2-P;break;case c:case f:case m:case g:A<=1?(ke=!0,this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)):(ne=Q.originLeft+Q.originWidth*.5,re=W===S?Q.originTop-this.placeholderHeight-this.minOffset+P:Q.originBottom+this.minOffset-P);break;default:}}ke||this.setPlaceholderRect({x:ne,y:re,dir:W,rotate:oe})}getNewChildNodeDir(e){let{LOGICAL_STRUCTURE:t,LOGICAL_STRUCTURE_LEFT:r,MIND_MAP:n,TIMELINE2:s,VERTICAL_TIMELINE:a,VERTICAL_TIMELINE2:o,VERTICAL_TIMELINE3:l,FISHBONE:h,FISHBONE2:d,RIGHT_FISHBONE:c,RIGHT_FISHBONE2:f}=k.LAYOUT;switch(this.mindMap.opt.layout){case t:return k.LAYOUT_GROW_DIR.RIGHT;case r:return k.LAYOUT_GROW_DIR.LEFT;case n:case s:case a:case o:case l:case h:case d:case c:case f:return e.dir;default:return""}}handleVerticalCheck(e,t,r=!1){let{layout:n}=this.mindMap.opt,{LAYOUT:s,LAYOUT_GROW_DIR:a}=k,{VERTICAL_TIMELINE:o,VERTICAL_TIMELINE2:l,VERTICAL_TIMELINE3:h,FISHBONE:d,FISHBONE2:c,RIGHT_FISHBONE:f,RIGHT_FISHBONE2:m}=s,{LEFT:g}=a,x=this.mouseMoveX,y=this.mouseMoveY,b=this.getNodeRect(e),S=this.getNewChildNodeDir(e),A=e.layerIndex;r&&(t=t.reverse());let C=b.originHeight/4,{prevBrotherOffset:I,nextBrotherOffset:O}=this.getNodeDistanceToSiblingNode(t,e,b,"v");if(b.left<=x&&b.right>=x){if(!this.overlapNode&&!this.prevNode&&!this.nextNode&&!e.isRoot){let q=O>0?y>b.bottom&&y<=b.bottom+O:y>=b.bottom-C&&y<=b.bottom,P=I>0?y=b.top-I:y>=b.top&&y<=b.top+C,{scaleY:W}=this.drawTransform,ne=S===g?b.originRight-this.placeholderWidth:b.originLeft,re=!1;switch(n){case o:case l:case h:A===1&&(ne=b.originLeft+b.originWidth/2-this.placeholderWidth/2);break;case f:case m:ne=b.originLeft+b.originWidth-this.placeholderWidth;break;default:}if(q){r?this.nextNode=e:this.prevNode=e;let oe=b.originBottom+O/W-this.placeholderHeight/2;switch(n){case d:case c:case f:case m:A===2&&(re=!0,oe=b.originBottom+this.minOffset-this.placeholderHeight/2);break;default:}this.setPlaceholderRect({x:ne,y:oe,dir:S,notRenderLine:re})}else if(P){r?this.prevNode=e:this.nextNode=e;let oe=b.originTop-this.placeholderHeight-I/W+this.placeholderHeight/2;switch(n){case d:case c:case f:case m:A===2&&(re=!0,oe=b.originTop-this.placeholderHeight-this.minOffset+this.placeholderHeight/2);break;default:}this.setPlaceholderRect({x:ne,y:oe,dir:S,notRenderLine:re})}}this.checkIsOverlap({node:e,dir:"v",prevBrotherOffset:I,nextBrotherOffset:O,size:C,pos:y,nodeRect:b})}}handleHorizontalCheck(e,t){let{layout:r}=this.mindMap.opt,{LAYOUT:n}=k,{FISHBONE:s,FISHBONE2:a,RIGHT_FISHBONE:o,RIGHT_FISHBONE2:l,TIMELINE:h,TIMELINE2:d}=n,c=this.mouseMoveX,f=this.mouseMoveY,m=this.getNodeRect(e),g=m.originWidth/4,{prevBrotherOffset:x,nextBrotherOffset:y}=this.getNodeDistanceToSiblingNode(t,e,m,"h");if(m.top<=f&&m.bottom>=f){if(!this.overlapNode&&!this.prevNode&&!this.nextNode&&!e.isRoot){let b=y>0?c=m.right:c<=m.right&&c>=m.right-g,S=x>0?c>m.left-x&&c<=m.left:c<=m.left+g&&c>=m.left,{scaleX:A}=this.drawTransform,C=e.layerIndex,I=m.originTop,O=!1;switch(r){case h:case d:I=m.originTop+m.originHeight/2-this.placeholderWidth/2;break;case s:case a:case o:case l:C===1&&(O=!0,I=m.originTop+m.originHeight/2-this.placeholderWidth/2);break;default:}b?([o,l].includes(r)?this.nextNode=e:this.prevNode=e,this.setPlaceholderRect({x:m.originRight+y/A-this.placeholderHeight/2,y:I,rotate:!0,notRenderLine:O})):S&&([o,l].includes(r)?this.prevNode=e:this.nextNode=e,this.setPlaceholderRect({x:m.originLeft-this.placeholderHeight-x/A+this.placeholderHeight/2,y:I,rotate:!0,notRenderLine:O}))}this.checkIsOverlap({node:e,dir:"h",prevBrotherOffset:x,nextBrotherOffset:y,size:g,pos:c,nodeRect:m})}}getNodeDistanceToSiblingNode(e,t,r,n){let{TOP:s,LEFT:a,BOTTOM:o,RIGHT:l}=k.LAYOUT_GROW_DIR,{scaleX:h,scaleY:d}=this.drawTransform,c=n==="v"?s:a,f=n==="v"?o:l,m=n==="v"?d:h,g=this.minOffset*m,x=Ie(t,e),y=null,b=null;x!==-1&&(x-1>=0&&(y=e[x-1]),x+1<=e.length-1&&(b=e[x+1]));let S=0;if(y){let C=this.getNodeRect(y);S=r[c]-C[f],S=S>=g?S/2:0}else S=g;let A=0;return b?(A=this.getNodeRect(b)[c]-r[f],A=A>=g?A/2:0):A=g,{prevBrother:y,prevBrotherOffset:S,nextBrother:b,nextBrotherOffset:A}}setPlaceholderRect({x:e,y:t,dir:r,rotate:n,notRenderLine:s}){let a=this.placeholderWidth,o=this.placeholderHeight;if(n){let f=a;a=o,o=f}if(this.placeholder.size(a,o).move(e,t),s)return;let{dragPlaceholderLineConfig:l}=this.mindMap.opt,h=null,d=null;this.overlapNode?(h=this.overlapNode,d=this.overlapNode):(h=this.prevNode||this.nextNode,d=h.parent),d=d.fakeClone(),h=h.fakeClone();let c=this.beingDragNodeList[0].fakeClone();c.dir=r,c.left=e,c.top=t,c.width=a,c.height=o,d.children=[c],d._lines=[],this.placeHolderLine.show(),this.mindMap.renderer.layout.renderLine(d,[this.placeHolderLine],(...f)=>{},h.style.getStyle("lineStyle",!0)),this.placeHolderExtraLines=[...d._lines],this.placeHolderExtraLines.forEach(f=>{this.mindMap.otherDraw.add(f),f.stroke({color:l.color,width:l.width}).fill({color:"none"})})}checkIsOverlap({node:e,dir:t,prevBrotherOffset:r,nextBrotherOffset:n,size:s,pos:a,nodeRect:o}){let{TOP:l,LEFT:h,BOTTOM:d,RIGHT:c}=k.LAYOUT_GROW_DIR,f=t==="v"?l:h,m=t==="v"?d:c;!this.overlapNode&&!this.prevNode&&!this.nextNode&&o[f]+(r>0?0:s)<=a&&o[m]-(n>0?0:s)>=a&&(this.overlapNode=e)}handleLogicalStructure(e){let t=this.commonGetNodeCheckList(e);this.handleVerticalCheck(e,t)}handleMindMap(e){let t=e.parent?e.parent.children.filter(r=>{let n=!0;return e.layerIndex===1&&(n=r.dir===e.dir),n&&!this.checkIsInBeingDragNodeList(r)}):[];this.handleVerticalCheck(e,t)}handleOrganizationStructure(e){let t=this.commonGetNodeCheckList(e);this.handleHorizontalCheck(e,t)}handleCatalogOrganization(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):this.handleVerticalCheck(e,t)}handleTimeLine(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):this.handleVerticalCheck(e,t)}handleTimeLine2(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):e.dir===k.LAYOUT_GROW_DIR.TOP&&e.layerIndex===2?this.handleVerticalCheck(e,t,!0):this.handleVerticalCheck(e,t)}handleFishbone(e){let t=e.parent?e.parent.children.filter(r=>r.layerIndex>1&&!this.checkIsInBeingDragNodeList(r)):[];if(e.layerIndex===1)this.handleHorizontalCheck(e,t);else{let r=e.dir===k.LAYOUT_GROW_DIR.TOP&&e.layerIndex===2,n=e.dir===k.LAYOUT_GROW_DIR.BOTTOM&&e.layerIndex>=3;r||n?this.handleVerticalCheck(e,t,!0):this.handleVerticalCheck(e,t)}}commonGetNodeCheckList(e){return e.parent?[...e.parent.children].filter(t=>!this.checkIsInBeingDragNodeList(t)):[]}getNodeRect(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.drawTransform,{left:a,top:o,width:l,height:h}=e,d=l,c=h,f=a,m=o,g=o+h,x=a+l,y=(a+l)*t+n,b=(o+h)*r+s;return a=a*t+n,o=o*r+s,{left:a,top:o,right:y,bottom:b,originWidth:d,originHeight:c,originLeft:f,originTop:m,originBottom:g,originRight:x}}checkIsInBeingDragNodeList(e){return!!this.beingDragNodeList.find(t=>t.uid===e.uid||t.isAncestor(e))}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};Z0.instanceName="drag";nE=Z0});var e6={};tt(e6,{default:()=>sE});var Q0,sE,t6=T(()=>{pe();$e();Q0=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,this.addShortcut()}addShortcut(){this.onLeftKeyUp=this.onLeftKeyUp.bind(this),this.onUpKeyUp=this.onUpKeyUp.bind(this),this.onRightKeyUp=this.onRightKeyUp.bind(this),this.onDownKeyUp=this.onDownKeyUp.bind(this),this.mindMap.keyCommand.addShortcut(k.KEY_DIR.LEFT,this.onLeftKeyUp),this.mindMap.keyCommand.addShortcut(k.KEY_DIR.UP,this.onUpKeyUp),this.mindMap.keyCommand.addShortcut(k.KEY_DIR.RIGHT,this.onRightKeyUp),this.mindMap.keyCommand.addShortcut(k.KEY_DIR.DOWN,this.onDownKeyUp)}removeShortcut(){this.mindMap.keyCommand.removeShortcut(k.KEY_DIR.LEFT,this.onLeftKeyUp),this.mindMap.keyCommand.removeShortcut(k.KEY_DIR.UP,this.onUpKeyUp),this.mindMap.keyCommand.removeShortcut(k.KEY_DIR.RIGHT,this.onRightKeyUp),this.mindMap.keyCommand.removeShortcut(k.KEY_DIR.DOWN,this.onDownKeyUp)}onLeftKeyUp(){this.onKeyup(k.KEY_DIR.LEFT)}onUpKeyUp(){this.onKeyup(k.KEY_DIR.UP)}onRightKeyUp(){this.onKeyup(k.KEY_DIR.RIGHT)}onDownKeyUp(){this.onKeyup(k.KEY_DIR.DOWN)}onKeyup(e){if(this.mindMap.renderer.activeNodeList.length>0)this.focus(e);else{let t=this.mindMap.renderer.root;this.mindMap.execCommand("GO_TARGET_NODE",t)}}focus(e){let t=this.mindMap.renderer.activeNodeList[0],r=this.getNodeRect(t),n=null,s=1/0,a=(o,l)=>{let h=this.getDistance(r,o);h{if(s.uid===e.uid)return;let a=this.getNodeRect(s),{left:o,top:l,right:h,bottom:d}=a,c=!1;r===k.KEY_DIR.LEFT?c=h<=t.left:r===k.KEY_DIR.RIGHT?c=o>=t.right:r===k.KEY_DIR.UP?c=d<=t.top:r===k.KEY_DIR.DOWN&&(c=l>=t.bottom),c&&n(a,s)})}getFocusNodeByShadowAlgorithm({currentActiveNode:e,currentActiveNodeRect:t,dir:r,checkNodeDis:n}){Xt(this.mindMap.renderer.root,s=>{if(s.uid===e.uid)return;let a=this.getNodeRect(s),{left:o,top:l,right:h,bottom:d}=a,c=!1;r===k.KEY_DIR.LEFT?c=ot.top:r===k.KEY_DIR.RIGHT?c=h>t.right&&lt.top:r===k.KEY_DIR.UP?c=lt.left:r===k.KEY_DIR.DOWN&&(c=d>t.bottom&&ot.left),c&&n(a,s)})}getFocusNodeByAreaAlgorithm({currentActiveNode:e,currentActiveNodeRect:t,dir:r,checkNodeDis:n}){let s=(t.right+t.left)/2,a=(t.bottom+t.top)/2;Xt(this.mindMap.renderer.root,o=>{if(o.uid===e.uid)return;let l=this.getNodeRect(o),{left:h,top:d,right:c,bottom:f}=l,m=(c+h)/2,g=(f+d)/2,x=m-s,y=g-a;if(x===0&&y===0)return;let b=!1;r===k.KEY_DIR.LEFT?b=x<=0&&x<=y&&x<=-y:r===k.KEY_DIR.RIGHT?b=x>0&&x>=-y&&x>=y:r===k.KEY_DIR.UP?b=y<=0&&y0&&-yx),b&&n(l,o)})}getNodeRect(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.mindMap.draw.transform(),{left:a,top:o,width:l,height:h}=e;return{right:(a+l)*t+n,bottom:(o+h)*r+s,left:a*t+n,top:o*r+s}}getDistance(e,t){let r=this.getCenter(e),n=this.getCenter(t);return Math.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2))}getCenter({left:e,right:t,top:r,bottom:n}){return{x:(e+t)/2,y:(r+n)/2}}beforePluginRemove(){this.removeShortcut()}beforePluginDestroy(){this.removeShortcut()}};Q0.instanceName="keyboardNavigation";sE=Q0});var Fu,J0,Pu,i6,aE,oE,lE,eh,hE,r6,n6=T(()=>{Fu=i=>String(i).split(/\s+/).map(t=>{if(/^[\d.]+/.test(t)){let r=/^([\d.]+)(.*)$/.exec(t);return[Number(r[1]),r[2]]}else return t}),J0=(i,e)=>i*e,Pu=(i,e)=>e/i,i6={left:0,top:0,center:50,bottom:100,right:100},aE=({backgroundSize:i,drawOpt:e,imageRatio:t,canvasWidth:r,canvasHeight:n,canvasRatio:s})=>{if(i){let a=Fu(i);if(a[0]==="auto"&&a[1]==="auto")return;if(a[0]==="cover"){t>s?(e.height=n,e.width=J0(t,n)):(e.width=r,e.height=Pu(t,r));return}if(a[0]==="contain"){t>s?(e.width=r,e.height=Pu(t,r)):(e.height=n,e.width=J0(t,n));return}let o=-1;a[0]&&(Array.isArray(a[0])?a[0][1]==="%"?(e.width=a[0][0]/100*r,o=e.width):(e.width=a[0][0],o=a[0][0]):a[0]==="auto"&&a[1]&&(a[1][1]==="%"?e.width=J0(t,a[1][0]/100*n):e.width=J0(t,a[1][0]))),a[1]&&Array.isArray(a[1])?a[1][1]==="%"?e.height=a[1][0]/100*n:e.height=a[1][0]:o!==-1&&(e.height=Pu(t,o))}},oE=({backgroundPosition:i,drawOpt:e,imgWidth:t,imgHeight:r,canvasWidth:n,canvasHeight:s})=>{if(i){let a=Fu(i);if(a=a.map(o=>typeof o=="string"&&i6[o]!==void 0?[i6[o],"%"]:o),Array.isArray(a[0])){if(a.length===1&&a.push([50,"%"]),a[0][1]==="%"){let o=a[0][0]/100*n,l=a[0][0]/100*t;e.x=o-l}else e.x=a[0][0];if(a[1][1]==="%"){let o=a[1][0]/100*s,l=a[1][0]/100*r;e.y=o-l}else e.y=a[1][0]}}},lE=({ctx:i,image:e,backgroundRepeat:t,drawOpt:r,imgWidth:n,imgHeight:s,canvasWidth:a,canvasHeight:o})=>{if(t){let l=r.x,h=r.y,d=Math.ceil(l/n),c=Math.ceil(h/s),f=l-d*n,m=h-c*s,g=Fu(t);if(g[0]==="no-repeat"||n>=a&&s>=o)return;if(g[0]==="repeat-x"&&a>n){let x=f;for(;xs){let x=m;for(;xs){let y=m;for(;y{i.drawImage(e,t.sx,t.sy,t.swidth,t.sheight,t.x,t.y,t.width,t.height)},hE=(i,e,t,r,{backgroundSize:n,backgroundPosition:s,backgroundRepeat:a},o=()=>{})=>{let l=e/t,h=new Image;h.src=r,h.onload=()=>{let d=h.width,c=h.height,f=d/c,m={sx:0,sy:0,swidth:d,sheight:c,x:0,y:0,width:d,height:c};aE({backgroundSize:n,drawOpt:m,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l}),oE({backgroundPosition:s,drawOpt:m,imgWidth:m.width,imgHeight:m.height,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l}),lE({ctx:i,image:h,backgroundRepeat:a,drawOpt:m,imgWidth:m.width,imgHeight:m.height,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l})||eh(i,h,m),o()},h.onerror=d=>{o(d)}},r6=hE});var qu,dE,cE,s6,a6=T(()=>{pe();qu=i=>i.richText?j0(i.text):i.text,dE=i=>new Array(i).fill("#").join(""),cE=i=>new Array(i-6).fill(" ").join("")+"*",s6=i=>{let e="";return de(i,null,(t,r,n,s)=>{let a=s+1;a<=6?e+=dE(a):e+=cE(a),e+=" "+qu(t.data);let o=t.data.generalization;if(Array.isArray(o))e+=o.map(l=>` [${qu(l)}]`);else if(o&&o.text){let l=qu(o);e+=` [${l}]`}e+=` + `,this.mindMap.el.appendChild(this.mindMap.commonCaches.measureCustomNodeContentSizeEl)),this.mindMap.commonCaches.measureCustomNodeContentSizeEl.innerHTML="",this.mindMap.commonCaches.measureCustomNodeContentSizeEl.appendChild(i);let e=this.mindMap.commonCaches.measureCustomNodeContentSizeEl.getBoundingClientRect();return{width:e.width,height:e.height}}function nE(){return!!this._customNodeContent}var GN,n6,Fu,s6=T(()=>{pe();wt();r6();Ge();GN=(i,e)=>{let t=new Le,r=new _e().text(i);return e.text(r),t.add(r),t.bbox()},n6={radius:3,fontSize:12,fill:"",height:20,paddingX:8};Fu={createImgNode:WN,getImgShowSize:VN,createIconNode:YN,createRichTextNode:XN,createTextNode:KN,createHyperlinkNode:ZN,createTagNode:QN,createNoteNode:JN,createAttachmentNode:eE,getNoteContentPosition:iE,getNodeIconSize:tE,measureCustomNodeContentSize:rE,isUseCustomNodeContent:nE}});function sE(){if(this.getChildrenLength()<=0||this.isRoot)return;let{alwaysShowExpandBtn:i,notShowExpandBtn:e,expandBtnSize:t}=this.mindMap.opt;if(!i&&!e){let{width:r,height:n}=this;this._unVisibleRectRegionNode||(this._unVisibleRectRegionNode=new Ve,this._unVisibleRectRegionNode.fill({color:"transparent"})),this.group.add(this._unVisibleRectRegionNode),this.renderer.layout.renderExpandBtnRect(this._unVisibleRectRegionNode,t,r,n,this)}}function aE(){this._unVisibleRectRegionNode&&(this._unVisibleRectRegionNode.remove(),this._unVisibleRectRegionNode=null)}function oE(){this.needRerenderExpandBtnPlaceholderRect&&(this.needRerenderExpandBtnPlaceholderRect=!1,this.renderExpandBtnPlaceholderRect()),this.getChildrenLength()>0?this._unVisibleRectRegionNode||this.renderExpandBtnPlaceholderRect():this._unVisibleRectRegionNode&&this.clearExpandBtnPlaceholderRect()}var qu,a6=T(()=>{wt();qu={renderExpandBtnPlaceholderRect:sE,clearExpandBtnPlaceholderRect:aE,updateExpandBtnPlaceholderRect:oE}});function lE(){this.checkEnableDragModifyNodeWidth()&&(this._dragHandleNodes=null,this.dragHandleWidth=4,this.dragHandleMousedownX=0,this.isDragHandleMousedown=!1,this.dragHandleIndex=0,this.dragHandleMousedownCustomTextWidth=0,this.dragHandleMousedownBodyCursor="",this.dragHandleMousedownLeft=0,this.onDragMousemoveHandle=this.onDragMousemoveHandle.bind(this),window.addEventListener("mousemove",this.onDragMousemoveHandle),this.onDragMouseupHandle=this.onDragMouseupHandle.bind(this),window.addEventListener("mouseup",this.onDragMouseupHandle),this.mindMap.on("node_mouseup",this.onDragMouseupHandle))}function hE(i){if(!this.isDragHandleMousedown)return;i.stopPropagation(),i.preventDefault();let{minNodeTextModifyWidth:e,maxNodeTextModifyWidth:t,isUseCustomNodeContent:r,customCreateNodeContent:n}=this.mindMap.opt,s=r&&n&&this._customNodeContent;document.body.style.cursor="ew-resize",this.group.css({cursor:"ew-resize"});let{scaleX:a}=this.mindMap.draw.transform(),o=i.clientX-this.dragHandleMousedownX,l=this.dragHandleMousedownCustomTextWidth+(this.dragHandleIndex===0?-o:o)/a;if(l=Math.max(l,e),t!==-1&&(l=Math.min(l,t)),!s&&this.getData("image")){let h=this.getImgShowSize();this._rectInfo.textContentWidth-this.customTextWidth+l<=h[0]&&(l=h[0]+this.customTextWidth-this._rectInfo.textContentWidth)}this.customTextWidth=l,this.dragHandleIndex===0&&(this.left=this.dragHandleMousedownLeft+o/a),this.reRender(s?[]:["text"],{ignoreUpdateCustomTextWidth:!0})}function dE(){this.isDragHandleMousedown&&(document.body.style.cursor=this.dragHandleMousedownBodyCursor,this.group.css({cursor:"default"}),this.isDragHandleMousedown=!1,this.dragHandleMousedownX=0,this.dragHandleIndex=0,this.dragHandleMousedownCustomTextWidth=0,this.setData({customTextWidth:this.customTextWidth}),this.mindMap.render(),this.mindMap.emit("dragModifyNodeWidthEnd",this))}function cE(){let i=[new Ve,new Ve];return i.forEach((e,t)=>{e.size(this.dragHandleWidth,this.height).fill({color:"transparent"}).css({cursor:"ew-resize"}),e.on("mousedown",r=>{r.stopPropagation(),r.preventDefault(),this.dragHandleMousedownX=r.clientX,this.dragHandleIndex=t,this.dragHandleMousedownCustomTextWidth=this.customTextWidth===void 0?this._textData?this._textData.width:this.width:this.customTextWidth,this.dragHandleMousedownBodyCursor=document.body.style.cursor,this.dragHandleMousedownLeft=this.left,this.isDragHandleMousedown=!0})}),i}function uE(){this.checkEnableDragModifyNodeWidth()&&(this._dragHandleNodes||(this._dragHandleNodes=this.createDragHandleNode()),this.getData("isActive")?(this._dragHandleNodes.forEach(i=>{i.height(this.height),this.group.add(i)}),this._dragHandleNodes[1].x(this.width-this.dragHandleWidth)):this._dragHandleNodes.forEach(i=>{i.remove()}))}var Hu,o6=T(()=>{wt();Hu={initDragHandle:lE,onDragMousemoveHandle:hE,onDragMouseupHandle:dE,createDragHandleNode:cE,updateDragHandle:uE}});function fE(){this.mindMap.cooperate&&(this._userListGroup=new Le,this.group.add(this._userListGroup))}function mE(i){let{avatarSize:e,fontSize:t}=this.mindMap.opt.cooperateStyle,r=new Le,n=i.isMore?i.name:String(i.name)[0],s=new Wi().size(e,e);s.fill({color:i.color||J0(n)});let a=new _e().text(n).fill({color:"#fff"}).css({"font-size":t+"px"}).dx(-t/2).dy((e-t)/2);return r.add(s).add(a),r}function pE(i){let{avatarSize:e}=this.mindMap.opt.cooperateStyle;return new $i().load(i.avatar).size(e,e)}function gE(){if(!this._userListGroup)return;let{avatarSize:i}=this.mindMap.opt.cooperateStyle;this._userListGroup.clear();let e=this.userList.length,t=Math.floor(this.width/i),r=[];e>t?r.push(...this.userList.slice(0,t-1),{isMore:!0,name:"+"+(e-t+1)}):r.push(...this.userList),r.forEach((n,s)=>{let a=null;n.avatar?a=this.createImageAvatar(n):a=this.createTextAvatar(n),a.on("click",o=>{this.mindMap.emit("node_cooperate_avatar_click",n,this,a,o)}),a.on("mouseenter",o=>{this.mindMap.emit("node_cooperate_avatar_mouseenter",n,this,a,o)}),a.on("mouseleave",o=>{this.mindMap.emit("node_cooperate_avatar_mouseleave",n,this,a,o)}),a.x(s*i).cy(-i/2),this._userListGroup.add(a)})}function xE(i){this.userList.find(e=>e.id==i.id)||(this.userList.push(i),this.updateUserListNode())}function yE(i){let e=this.userList.findIndex(t=>t.id==i.id);e!==-1&&(this.userList.splice(e,1),this.updateUserListNode())}function vE(){this.userList=[],this.updateUserListNode()}var Uu,l6=T(()=>{wt();pe();Uu={createUserListNode:fE,updateUserListNode:gE,createTextAvatar:mE,createImageAvatar:pE,addUser:xE,removeUser:yE,emptyUser:vE}});function bE(){this.isGeneralization||(this._quickCreateChildBtn=null,this._showQuickCreateChildBtn=!1)}function wE(){if(!(this.isGeneralization||this.getChildrenLength()>0)){if(this._quickCreateChildBtn)this.group.add(this._quickCreateChildBtn);else{let{quickCreateChildBtnIcon:i,expandBtnStyle:e,expandBtnSize:t}=this.mindMap.opt,{icon:r,style:n}=i,{color:s,fill:a}=e||{color:"#808080",fill:"#fff"};s=n.color||s;let o=ke(r||Yo.quickCreateChild).size(t,t);o.css({cursor:"pointer"}),o.x(0).y(-t/2),this.style.iconNode(o,s);let l=new Wi().size(t);l.x(0).y(-t/2),l.fill({color:a}).css({cursor:"pointer"}),this._quickCreateChildBtn=new Le,this._quickCreateChildBtn.add(l).add(o),this._quickCreateChildBtn.on("click",h=>{h.stopPropagation(),this.mindMap.emit("quick_create_btn_click",this);let{customQuickCreateChildBtnClick:d}=this.mindMap.opt;if(typeof d=="function"){d(this);return}this.mindMap.execCommand("INSERT_CHILD_NODE",!0,[this])}),this._quickCreateChildBtn.on("dblclick",h=>{h.stopPropagation()}),this._quickCreateChildBtn.addClass("smm-quick-create-child-btn"),this.group.add(this._quickCreateChildBtn)}this._showQuickCreateChildBtn=!0,this.renderer.layout.renderExpandBtn(this,this._quickCreateChildBtn)}}function ME(){this.isGeneralization||this._quickCreateChildBtn&&this._showQuickCreateChildBtn&&(this._quickCreateChildBtn.remove(),this._showQuickCreateChildBtn=!1)}function TE(){if(this.isGeneralization)return;let{isActive:i}=this.getData();i||this.removeQuickCreateChildBtn()}var $u,h6=T(()=>{Ou();wt();$u={initQuickCreateChildBtn:bE,showQuickCreateChildBtn:wE,removeQuickCreateChildBtn:ME,hideQuickCreateChildBtn:TE}});function NE(i,e,t,r,n){let{imgTextMargin:s}=this.mindMap.opt;return i==="v"?r>0&&n>0?s:0:e>0&&t>0?s:0}function EE(i){let e=0,t=this._tagData.reduce((r,n)=>(e=Math.max(e,n.height),r+=n.width),0);return t+=(this._tagData.length-1)*i,{width:t,height:e}}function SE(){if(this.isUseCustomNodeContent()){let L=this.measureCustomNodeContentSize(this._customNodeContent);return{width:this.hasCustomWidth()?this.customTextWidth:L.width,height:L.height}}let{TAG_PLACEMENT:i,IMG_PLACEMENT:e}=C,{textContentMargin:t}=this.mindMap.opt,n=(this.getStyle("tagPlacement")||i.RIGHT)===i.BOTTOM,s=this.getStyle("imgPlacement")||e.TOP,a=0,o=0,l=0,h=0,d=0,c=0,f=0;if(this._imgData&&(a=this._imgData.width,o=this._imgData.height),this.mindMap.nodeInnerPrefixList.forEach(L=>{let I=this[`_${L.name}Data`];I&&(l+=I.width,h=Math.max(h,I.height),f++)}),this._prefixData&&(l+=this._prefixData.width,h=Math.max(h,this._prefixData.height),f++),this._iconData.length>0&&(l+=this._iconData.reduce((L,I)=>(h=Math.max(h,I.height),L+=I.width),0)+(this._iconData.length-1)*t,f++),this._textData&&(l+=this._textData.width,h=Math.max(h,this._textData.height),f++),this._hyperlinkData&&(l+=this._hyperlinkData.width,h=Math.max(h,this._hyperlinkData.height),f++),this._tagData.length>0){let{width:L,height:I}=this.getTagContentSize(t);n?(d=L,c=I):(l+=L,h=Math.max(h,I),f++)}this._noteData&&(l+=this._noteData.width,h=Math.max(h,this._noteData.height),f++),this._attachmentData&&(l+=this._attachmentData.width,h=Math.max(h,this._attachmentData.height),f++),this._postfixData&&(l+=this._postfixData.width,h=Math.max(h,this._postfixData.height),f++),this.mindMap.nodeInnerPostfixList.forEach(L=>{let I=this[`_${L.name}Data`];I&&(l+=I.width,h=Math.max(h,I.height),f++)}),l+=(f-1)*t,n&&l>0&&c>0&&(this._rectInfo.textContentWidthWithoutTag=l,l=Math.max(l,d),h=h+t+c),this._rectInfo.textContentWidth=l,this._rectInfo.textContentHeight=h;let m=0,g=0;[e.TOP,e.BOTTOM].includes(s)?(m=Math.max(a,l),g=o+h+this.getImgTextMarin("v",0,0,o,h)):(m=a+l+this.getImgTextMarin("h",a,l),g=Math.max(o,h));let{paddingX:x,paddingY:y}=this.getPaddingVale(),{paddingX:b,paddingY:E}=this.shapeInstance.getShapePadding(m,g,x,y);this.shapePadding.paddingX=b,this.shapePadding.paddingY=E;let k=this.getBorderWidth();return{width:m+x*2+b*2+k,height:g+y*2+E*2+k}}function AE(){if(!this.group)return;this.group.clear();let{hoverRectPadding:i,openRealtimeRenderOnNodeTextEdit:e,textContentMargin:t,addCustomContentToNode:r}=this.mindMap.opt,{width:n,height:s}=this,{paddingX:a,paddingY:o}=this.getPaddingVale(),l=this.getBorderWidth()/2;a+=this.shapePadding.paddingX+l,o+=this.shapePadding.paddingY+l,this.shapeNode=this.shapeInstance.createShape(),this.shapeNode.addClass("smm-node-shape"),this.shapeNode.translate(l,l),this.style.shape(this.shapeNode),this.group.add(this.shapeNode),this.renderExpandBtnPlaceholderRect(),this.createUserListNode&&this.createUserListNode(),this.isGeneralization&&this.generalizationBelongNode&&this.group.addClass("generalization_"+this.generalizationBelongNode.uid);let h=()=>{this.hoverNode=new Ve().size(n+i*2,s+i*2).x(-i).y(-i),this.hoverNode.addClass("smm-hover-node"),this.style.hoverNode(this.hoverNode,n,s),this.group.add(this.hoverNode)};if(this.isUseCustomNodeContent()){let oe=mn({el:this._customNodeContent,width:n,height:s});this.group.add(oe),h();return}let{IMG_PLACEMENT:d,TAG_PLACEMENT:c}=C,f=this.getStyle("imgPlacement")||d.TOP,g=(this.getStyle("tagPlacement")||c.RIGHT)===c.BOTTOM,{textContentWidth:x,textContentHeight:y,textContentWidthWithoutTag:b}=this._rectInfo,E=y,k=0,L=0,I=this._tagData&&this._tagData.length>0;if(I){let oe=this.getTagContentSize(t);k=oe.width,L=oe.height,g&&(y-=L+t)}let O=0,q=0;if(this._imgData)switch(O=this._imgData.width,q=this._imgData.height,this.group.add(this._imgData.node),f){case d.TOP:this._imgData.node.cx(n/2).y(o);break;case d.BOTTOM:this._imgData.node.cx(n/2).y(s-o-q);break;case d.LEFT:this._imgData.node.x(a).cy(s/2);break;case d.RIGHT:this._imgData.node.x(n-a-O).cy(s/2);break;default:break}let F=new Le,W=0;if(I&&g&&(W=b{let he=this[`_${oe.name}Data`];he&&(he.node.x(W).y((y-he.height)/2),F.add(he.node),W+=he.width+t)}),this._prefixData){let oe=mn({el:this._prefixData.el,width:this._prefixData.width,height:this._prefixData.height});oe.x(W).y((y-this._prefixData.height)/2),F.add(oe),W+=this._prefixData.width+t}let ne=new Le;if(this._iconData&&this._iconData.length>0){let oe=0;this._iconData.forEach(he=>{he.node.x(W+oe).y((y-he.height)/2),ne.add(he.node),oe+=he.width+t}),F.add(ne),W+=oe}if(this._textData){let oe=this._textData.node.attr("data-offsetx")||0;this._textData.node.attr("data-offsetx",W),(this._textData.nodeContent||this._textData.node).x(-oe).x(W).y((y-this._textData.height)/2),e&&this._textData.node.opacity(this.mindMap.renderer.textEdit.getCurrentEditNode()===this?0:1),F.add(this._textData.node),W+=this._textData.width+t}this._hyperlinkData&&(this._hyperlinkData.node.x(W).y((y-this._hyperlinkData.height)/2),F.add(this._hyperlinkData.node),W+=this._hyperlinkData.width+t);let re=new Le;if(I)if(g){let oe=0;this._tagData.forEach(he=>{he.node.x(oe).y((L-he.height)/2),re.add(he.node),oe+=he.width+t}),re.x((x-k)/2).y(E-L),F.add(re)}else{let oe=0;this._tagData.forEach(he=>{he.node.x(W+oe).y((y-he.height)/2),re.add(he.node),oe+=he.width+t}),F.add(re),W+=oe}if(this._noteData&&(this._noteData.node.x(W).y((y-this._noteData.height)/2),F.add(this._noteData.node),W+=this._noteData.width+t),this._attachmentData&&(this._attachmentData.node.x(W).y((y-this._attachmentData.height)/2),F.add(this._attachmentData.node),W+=this._attachmentData.width+t),this._postfixData){let oe=mn({el:this._postfixData.el,width:this._postfixData.width,height:this._postfixData.height});oe.x(W).y((y-this._postfixData.height)/2),F.add(oe),W+=this._postfixData.width+t}this.mindMap.nodeInnerPostfixList.forEach(oe=>{let he=this[`_${oe.name}Data`];he&&(he.node.x(W).y((y-he.height)/2),F.add(he.node),W+=he.width+t)}),this.group.add(F);let{width:le,height:Ce}=F.bbox(),te=0,Q=0;switch(f){case d.TOP:te=n/2-le/2,Q=o+q+this.getImgTextMarin("v",0,0,q,E);break;case d.BOTTOM:te=n/2-le/2,Q=o;break;case d.LEFT:te=O+a+this.getImgTextMarin("h",O,x),Q=s/2-Ce/2;break;case d.RIGHT:te=a,Q=s/2-Ce/2;break}if(F.translate(te,Q),h(),this._customContentAddToNodeAdd&&this._customContentAddToNodeAdd.el){let oe=mn(this._customContentAddToNodeAdd);this.group.add(oe),r&&typeof r.handle=="function"&&r.handle({content:this._customContentAddToNodeAdd,element:oe,node:this})}this.mindMap.emit("node_layout_end",this)}var ju,d6=T(()=>{Ge();wt();pe();ju={getImgTextMarin:NE,getTagContentSize:EE,getNodeRect:SE,layout:AE}});var Gu,ca,rh=T(()=>{ih();Ru();wt();J2();e6();t6();s6();a6();o6();l6();h6();d6();Ge();pe();Gu=class i{constructor(e={}){this.opt=e,this.nodeData=this.handleData(e.data||{}),this.nodeDataSnapshot="",this.uid=e.uid,this.mindMap=e.mindMap,this.renderer=e.renderer,this.draw=this.mindMap.draw,this.nodeDraw=this.mindMap.nodeDraw,this.lineDraw=this.mindMap.lineDraw,this.style=new Wo(this),this.effectiveStyles={},this.shapeInstance=new Vo(this),this.shapePadding={paddingX:0,paddingY:0},this.isRoot=e.isRoot===void 0?!1:e.isRoot,this.isGeneralization=e.isGeneralization===void 0?!1:e.isGeneralization,this.generalizationBelongNode=null,this.layerIndex=e.layerIndex===void 0?0:e.layerIndex,this.width=e.width||0,this.height=e.height||0,this.customTextWidth=e.data.data.customTextWidth||void 0,this._left=e.left||0,this._top=e.top||0,this.customLeft=e.data.data.customLeft||void 0,this.customTop=e.data.data.customTop||void 0,this.isDrag=!1,this.parent=e.parent||null,this.children=e.children||[],this.userList=[],this.group=null,this.shapeNode=null,this.hoverNode=null,this._customNodeContent=null,this._imgData=null,this._iconData=null,this._textData=null,this._hyperlinkData=null,this._tagData=null,this._noteData=null,this.noteEl=null,this.noteContentIsShow=!1,this._attachmentData=null,this._prefixData=null,this._postfixData=null,this._expandBtn=null,this._lastExpandBtnType=null,this._showExpandBtn=!1,this._openExpandNode=null,this._closeExpandNode=null,this._fillExpandNode=null,this._userListGroup=null,this._lines=[],this._generalizationList=[],this._unVisibleRectRegionNode=null,this._isMouseenter=!1,this._customContentAddToNodeAdd=null,this._rectInfo={textContentWidth:0,textContentHeight:0,textContentWidthWithoutTag:0},this._generalizationNodeWidth=0,this._generalizationNodeHeight=0,this.expandBtnSize=this.mindMap.opt.expandBtnSize,this.isMultipleChoice=!1,this.needLayout=!1,this.isHide=!1;let t=Object.getPrototypeOf(this);t.bindEvent||(Object.keys(ju).forEach(r=>{t[r]=ju[r]}),Object.keys(Du).forEach(r=>{t[r]=Du[r]}),Object.keys(Bu).forEach(r=>{t[r]=Bu[r]}),Object.keys(qu).forEach(r=>{t[r]=qu[r]}),Object.keys(Pu).forEach(r=>{t[r]=Pu[r]}),Object.keys(Fu).forEach(r=>{t[r]=Fu[r]}),this.mindMap.cooperate&&Object.keys(Uu).forEach(r=>{t[r]=Uu[r]}),Object.keys(Hu).forEach(r=>{t[r]=Hu[r]}),this.mindMap.opt.isShowCreateChildBtnIcon&&(Object.keys($u).forEach(r=>{t[r]=$u[r]}),this.initQuickCreateChildBtn()),t.bindEvent=!0),this.getSize(),this.updateGeneralization(),this.initDragHandle()}get left(){return this.customLeft||this._left}set left(e){this._left=e}get top(){return this.customTop||this._top}set top(e){this._top=e}reset(){this.children=[],this.parent=null,this.isRoot=!1,this.layerIndex=0,this.left=0,this.top=0}resetWhenDelete(){this._isMouseenter=!1}handleData(e){return e.data.expand=e.data.expand!==!1,e.data.isActive=e.data.isActive===!0,e.children=e.children||[],e}createNodeData(e){let{isUseCustomNodeContent:t,customCreateNodeContent:r,createNodePrefixContent:n,createNodePostfixContent:s,addCustomContentToNode:a}=this.mindMap.opt,o=["custom","image","icon","text","hyperlink","tag","note","attachment","prefix","postfix",...this.mindMap.nodeInnerPrefixList.map(h=>h.name),...this.mindMap.nodeInnerPostfixList.map(h=>h.name)],l={};if(Array.isArray(e)?o.forEach(h=>{e.includes(h)&&(l[h]=!0)}):o.forEach(h=>{l[h]=!0}),t&&r&&l.custom&&(this._customNodeContent=r(this)),this._customNodeContent){sr(this._customNodeContent);return}l.image&&(this._imgData=this.createImgNode()),l.icon&&(this._iconData=this.createIconNode()),l.text&&(this._textData=this.createTextNode()),l.hyperlink&&(this._hyperlinkData=this.createHyperlinkNode()),l.tag&&(this._tagData=this.createTagNode()),l.note&&(this._noteData=this.createNoteNode()),l.attachment&&(this._attachmentData=this.createAttachmentNode()),this.mindMap.nodeInnerPrefixList.forEach(h=>{l[h.name]&&(this[`_${h.name}Data`]=h.createContent(this))}),l.prefix&&(this._prefixData=n?n(this):null,this._prefixData&&this._prefixData.el&&sr(this._prefixData.el)),l.postfix&&(this._postfixData=s?s(this):null,this._postfixData&&this._postfixData.el&&sr(this._postfixData.el)),this.mindMap.nodeInnerPostfixList.forEach(h=>{l[h.name]&&(this[`_${h.name}Data`]=h.createContent(this))}),a&&typeof a.create=="function"&&(this._customContentAddToNodeAdd=a.create(this),this._customContentAddToNodeAdd&&this._customContentAddToNodeAdd.el&&sr(this._customContentAddToNodeAdd.el))}getSize(e,t={}){t.ignoreUpdateCustomTextWidth||(this.customTextWidth=this.getData("customTextWidth")||void 0),this.customLeft=this.getData("customLeft")||void 0,this.customTop=this.getData("customTop")||void 0,this.createNodeData(e);let{width:n,height:s}=this.getNodeRect(),a=this.width!==n||this.height!==s;return this.width=n,this.height=s,a}bindGroupEvent(){this.group.on("click",e=>{if(this.mindMap.emit("node_click",this,e),this.isMultipleChoice){e.stopPropagation(),this.isMultipleChoice=!1;return}this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate&&this.userList.length>0||this.active(e)}),this.group.on("mousedown",e=>{let{readonly:t,enableCtrlKeyNodeSelection:r,useLeftKeySelectionRightKeyDrag:n,mousedownEventPreventDefault:s}=this.mindMap.opt;if(s&&e.preventDefault(),t||(this.isRoot?e.which===3&&!n&&e.stopPropagation():e.which!==2&&e.stopPropagation()),!t&&(e.ctrlKey||e.metaKey)&&r){this.isMultipleChoice=!0;let a=this.getData("isActive");a||this.mindMap.emit("before_node_active",this,this.renderer.activeNodeList),this.mindMap.renderer[a?"removeNodeFromActiveList":"addNodeToActiveList"](this,!0),this.renderer.emitNodeActiveEvent(a?null:this)}this.mindMap.emit("node_mousedown",this,e)}),this.group.on("mouseup",e=>{!this.isRoot&&e.which!==2&&!this.mindMap.opt.readonly&&e.stopPropagation(),this.mindMap.emit("node_mouseup",this,e)}),this.group.on("mouseenter",e=>{this.isDrag||(this._isMouseenter=!0,this.showExpandBtn(),this.isGeneralization&&this.handleGeneralizationMouseenter(),this.mindMap.emit("node_mouseenter",this,e))}),this.group.on("mouseleave",e=>{this._isMouseenter&&(this._isMouseenter=!1,this.hideExpandBtn(),this.isGeneralization&&this.handleGeneralizationMouseleave(),this.mindMap.emit("node_mouseleave",this,e))}),this.group.on("dblclick",e=>{let{readonly:t,onlyOneEnableActiveNodeOnCooperate:r}=this.mindMap.opt;t||e.ctrlKey||e.metaKey||(e.stopPropagation(),!(r&&this.userList.length>0)&&this.mindMap.emit("node_dblclick",this,e))}),this.group.on("contextmenu",e=>{let{readonly:t,useLeftKeySelectionRightKeyDrag:r}=this.mindMap.opt;t||e.ctrlKey||(e.stopPropagation(),e.preventDefault(),!(this.mindMap.select&&!r&&this.mindMap.select.hasSelectRange())&&(this.getData("isActive")&&this.renderer.activeNodeList.length===1||(this.renderer.clearActiveNodeList(),this.active(e)),this.mindMap.emit("node_contextmenu",e,this)))})}active(e){this.mindMap.opt.readonly||(e&&e.stopPropagation(),!this.getData("isActive")&&(this.mindMap.emit("before_node_active",this,this.renderer.activeNodeList),this.renderer.clearActiveNodeList(),this.renderer.addNodeToActiveList(this,!0),this.renderer.emitNodeActiveEvent(this)))}deactivate(){this.mindMap.renderer.removeNodeFromActiveList(this),this.mindMap.renderer.emitNodeActiveEvent()}update(e){if(!this.group)return;this.updateNodeActiveClass();let{alwaysShowExpandBtn:t,notShowExpandBtn:r,isShowCreateChildBtnIcon:n,readonly:s}=this.mindMap.opt,a=this.getChildrenLength();if(!r)if(t)this._expandBtn&&a<=0?this.removeExpandBtn():this.renderExpandBtn();else{let{isActive:l,expand:h}=this.getData();a<=0?this.removeExpandBtn():h&&!l&&!this._isMouseenter?this.hideExpandBtn():this.showExpandBtn()}if(n)if(a>0)this.removeQuickCreateChildBtn();else{let{isActive:l}=this.getData();l?this.showQuickCreateChildBtn():this.hideQuickCreateChildBtn()}this.updateDragHandle(),this.renderGeneralization(e),this.updateUserListNode&&this.updateUserListNode();let o=this.group.transform();this.nodeDataSnapshot=s?"":JSON.stringify(this.getData()),(this.left!==o.translateX||this.top!==o.translateY)&&this.group.translate(this.left-o.translateX,this.top-o.translateY)}getNodePosInClient(e,t){let r=this.mindMap.draw.transform(),{scaleX:n,scaleY:s,translateX:a,translateY:o}=r,l=e*n+a,h=t*s+o;return{left:l,top:h}}checkIsInClient(e=0){let{left:t,top:r}=this.getNodePosInClient(this.left,this.top);return t+this.width>0-e&&r+this.height>0-e&&t{},t=!1,r=!1){this.renderLine();let{openPerformance:n,performanceConfig:s}=this.mindMap.opt;if(t||!n||this.checkIsInClient(s.padding)||this.isRoot?this.group?(this.nodeDraw.has(this.group)||this.nodeDraw.add(this.group),this.needLayout&&(this.needLayout=!1,this.layout()),this.updateExpandBtnPlaceholderRect(),this.update(t)):(this.group=new Le,this.group.addClass("smm-node"),this.group.css({cursor:"default"}),this.bindGroupEvent(),this.nodeDraw.add(this.group),this.layout(),this.update(t)):n&&s.removeNodeWhenOutCanvas&&this.removeSelf(),this.children&&this.children.length&&this.getData("expand")!==!1){let a=0;this.children.forEach(o=>{let l=()=>{o.render(()=>{a++,a>=this.children.length&&e()},t,r)};r?setTimeout(l,0):l()})}else e();this.nodeData.inserting&&(delete this.nodeData.inserting,this.active(),this.mindMap.emit("node_dblclick",this,null,!0))}removeSelf(){this.group&&(this.group.remove(),this.removeGeneralization())}remove(){this.group&&(this.group.remove(),this.removeGeneralization(),this.removeLine(),this.children&&this.children.length&&this.children.forEach(e=>{e.remove()}))}destroy(){this.removeLine(),this.parent&&this.parent.removeLine(),this.group&&(this.emptyUser&&this.emptyUser(),this.resetWhenDelete(),this.group.remove(),this.removeGeneralization(),this.group=null,this.style.onRemove())}hide(){if(this.group&&this.group.hide(),this.hideGeneralization(),this.parent){let e=this.parent.children.indexOf(this);this.parent._lines[e]&&this.parent._lines[e].hide(),this._lines.forEach(t=>{t.hide()})}this.children&&this.children.length&&this.children.forEach(e=>{e.hide()})}show(){if(this.group){if(this.group.show(),this.showGeneralization(),this.parent){let e=this.parent.children.indexOf(this);this.parent._lines[e]&&this.parent._lines[e].show(),this._lines.forEach(t=>{t.show()})}this.children&&this.children.length&&this.children.forEach(e=>{e.show()})}}setOpacity(e){this.group&&this.group.opacity(e),this._lines.forEach(t=>{t.opacity(e)}),this.children.forEach(t=>{t.setOpacity(e)}),this.setGeneralizationOpacity(e)}hideChildren(){this._lines.forEach(e=>{e.hide()}),this.children&&this.children.length&&this.children.forEach(e=>{e.hide()})}showChildren(){this._lines.forEach(e=>{e.show()}),this.children&&this.children.length&&this.children.forEach(e=>{e.show()})}startDrag(){this.isDrag=!0,this.group&&this.group.addClass("smm-node-dragging")}endDrag(){this.isDrag=!1,this.group&&this.group.removeClass("smm-node-dragging")}renderLine(e=!1){if(this.getData("expand")===!1)return;let t=this.getChildrenLength();this.mindMap.renderer.layout.nodeIsRemoveAllLines&&this.mindMap.renderer.layout.nodeIsRemoveAllLines(this)&&(t=0),t>this._lines.length?new Array(t-this._lines.length).fill(0).forEach(()=>{this._lines.push(this.lineDraw.path())}):t{r.remove()}),this._lines=this._lines.slice(0,t)),this.renderer.layout.renderLine(this,this._lines,(...r)=>{this.styleLine(...r)},this.style.getStyle("lineStyle",!0)),e&&this.children&&this.children.length>0&&this.children.forEach(r=>{r.renderLine(e)})}getShape(){return this.mindMap.themeConfig.nodeUseLineStyle?C.SHAPE.RECTANGLE:this.style.getStyle("shape",!1,!1)}hasCustomPosition(){return this.customLeft!==void 0&&this.customTop!==void 0}ancestorHasCustomPosition(){let e=this;for(;e;){if(e.hasCustomPosition())return!0;e=e.parent}return!1}ancestorHasGeneralization(){let e=this.parent;for(;e;){if(e.checkHasGeneralization())return!0;e=e.parent}return!1}addChildren(e){this.children.push(e)}styleLine(e,t,r){let{enableInheritAncestorLineStyle:n}=this.mindMap.opt,s=n?"getSelfInhertStyle":"getSelfStyle",a=t[s]("lineWidth")||t.getStyle("lineWidth",!0),o=t[s]("lineColor")||this.getRainbowLineColor(t)||t.getStyle("lineColor",!0),l=t[s]("lineDasharray")||t.getStyle("lineDasharray",!0);this.style.line(e,{width:a,color:o,dasharray:l},r,t)}getRainbowLineColor(e){return this.mindMap.rainbowLines?this.mindMap.rainbowLines.getNodeColor(e):""}removeLine(){this._lines.forEach(e=>{e.remove()}),this._lines=[]}isAncestor(e){if(this.uid===e.uid)return!1;let t=e.parent;for(;t;){if(this.uid===t.uid)return!0;t=t.parent}return!1}isParent(e){if(this.uid===e.uid)return!1;let t=e.parent;return!!(t&&this.uid===t.uid)}isBrother(e){return!this.parent||this.uid===e.uid?!1:this.parent.children.find(t=>t.uid===e.uid)}getIndexInBrothers(){return this.parent&&this.parent.children?this.parent.children.findIndex(e=>e.uid===this.uid):-1}getPaddingVale(){return{paddingX:this.getStyle("paddingX"),paddingY:this.getStyle("paddingY")}}getStyle(e,t){let r=this.style.merge(e,t);return r===void 0?"":r}getSelfStyle(e){return this.style.getSelfStyle(e)}getParentSelfStyle(e){return this.parent?this.parent.getSelfStyle(e)||this.parent.getParentSelfStyle(e):null}getSelfInhertStyle(e){return this.getSelfStyle(e)||this.getParentSelfStyle(e)}getBorderWidth(){return this.style.merge("borderWidth",!1)||0}getData(e){return e?this.nodeData.data[e]:this.nodeData.data}getPureData(e=!0,t=!1){return ls({},this,e,t)}getAncestorNodes(){let e=[],t=this.parent;for(;t;)e.unshift(t),t=t.parent;return e}hasCustomStyle(){return this.style.hasCustomStyle()}getRect(){return this.group?this.group.rbox():null}getRectInSvg(){let{scaleX:e,scaleY:t,translateX:r,translateY:n}=this.mindMap.draw.transform(),{left:s,top:a,width:o,height:l}=this,h=(s+o)*e+r,d=(a+l)*t+n;return s=s*e+r,a=a*t+n,{left:s,right:h,top:a,bottom:d,width:o*e,height:l*t}}highlight(){this.group&&this.group.addClass("smm-node-highlight")}closeHighlight(){this.group&&this.group.removeClass("smm-node-highlight")}fakeClone(){let e=new i({...this.opt,uid:Tt()});return Object.keys(this).forEach(t=>{e[t]=this[t]}),e}createSvgTextNode(e=""){return new _e().text(e)}getSvgObjects(){return{SVG:ke,G:Le,Rect:Ve}}checkEnableDragModifyNodeWidth(){let{enableDragModifyNodeWidth:e,isUseCustomNodeContent:t,customCreateNodeContent:r}=this.mindMap.opt;return e&&(this.mindMap.richText||t&&r)}hasCustomWidth(){return this.checkEnableDragModifyNodeWidth()&&this.customTextWidth!==void 0}getChildrenLength(){return this.nodeData.children?this.nodeData.children.length:0}},ca=Gu});var Ko,c6=T(()=>{Ko=class{constructor(e){this.max=e||1e3,this.size=0,this.pool=new Map}add(e,t){return!this.has(e)&&this.size>=this.max?!1:(this.delete(e),this.pool.set(e,t),this.size++,!0)}delete(e){this.pool.has(e)&&(this.pool.delete(e),this.size--)}has(e){return this.pool.has(e)}get(e){if(this.pool.has(e))return this.pool.get(e)}clear(){this.size=0,this.pool=new Map}}});var Wu,Nt,Ar=T(()=>{rh();Ge();c6();pe();Wu=class{constructor(e){this.renderer=e,this.mindMap=e.mindMap,this.draw=this.mindMap.draw,this.lineDraw=this.mindMap.lineDraw,this.root=null,this.lru=new Ko(this.mindMap.opt.maxNodeCacheCount),this.rootNodeCenterOffset=null}doLayout(){throw new Error("\u3010computed\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderLine(){throw new Error("\u3010renderLine\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderExpandBtn(){throw new Error("\u3010renderExpandBtn\u3011\u65B9\u6CD5\u4E3A\u5FC5\u8981\u65B9\u6CD5\uFF0C\u9700\u8981\u5B50\u7C7B\u8FDB\u884C\u91CD\u5199\uFF01")}renderGeneralization(){}cacheNode(e,t){this.renderer.nodeCache[e]=t,this.lru.add(e,t)}checkIsNeedResizeSources(){return this.renderer.checkHasRenderSource(C.CHANGE_THEME)}checkIsLayerTypeChange(e,t){if(e>=2&&t>=2)return!1;if(e>=2&&t<2||e<2&&t>=2)return!0}checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(e){this.renderer.checkHasRenderSource(C.CHANGE_LAYOUT)&&(e.needRerenderExpandBtnPlaceholderRect=!0)}checkIsNodeDataChange(e,t){if(e)e=typeof e=="string"?JSON.parse(e):e,e.isActive=t.isActive,e.expand=t.expand,e=JSON.stringify(e);else return!1;return e!==JSON.stringify(t)}checkNodeFixChange(e,t,r){let n=!1;this.mindMap.nodeInnerPrefixList.forEach(a=>{if(a.updateNodeData){let o=a.updateNodeData(e,t);o&&(n=o)}});let s=!1;return this.mindMap.nodeInnerPostfixList.forEach(a=>{if(a.updateNodeData){let o=a.updateNodeData(e,r);o&&(s=o)}}),n||s}createNode(e,t,r,n,s,a){let o={};this.mindMap.nodeInnerPrefixList.forEach(c=>{if(c.createNodeData){let[f,m]=c.createNodeData({data:e,parent:t,ancestors:a,layerIndex:n,index:s});o[f]=m}});let l={};this.mindMap.nodeInnerPostfixList.forEach(c=>{if(c.createNodeData){let[f,m]=c.createNodeData({data:e,parent:t,ancestors:a,layerIndex:n,index:s});l[f]=m}});let h=e.data.uid,d=null;if(e&&e._node&&!this.renderer.reRender){d=e._node;let c=this.checkIsLayerTypeChange(d.layerIndex,n);d.reset(),d.layerIndex=n,r?d.isRoot=!0:d.parent=t._node,this.cacheNode(e._node.uid,d),this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(d);let f=this.checkNodeFixChange(d,o,l),m=this.checkIsNeedResizeSources(),g=this.checkIsNodeDataChange(e._node.nodeDataSnapshot,e.data);(m||g||c||d.getData("resetRichText")||d.getData("needUpdate")||f)&&(d.getSize(),d.needLayout=!0),this.checkGetGeneralizationChange(d,m)}else if((this.lru.has(h)||this.renderer.lastNodeCache[h])&&!this.renderer.reRender){d=this.lru.get(h)||this.renderer.lastNodeCache[h];let c=JSON.stringify(d.getData()),f=this.checkIsLayerTypeChange(d.layerIndex,n);d.reset(),d.nodeData=d.handleData(e||{}),d.layerIndex=n,r?d.isRoot=!0:d.parent=t._node,this.cacheNode(h,d),this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(d),e._node=d;let m=this.checkIsNeedResizeSources(),g=this.checkIsNodeDataChange(c,e.data),x=this.checkNodeFixChange(d,o,l);(m||g||f||d.getData("resetRichText")||d.getData("needUpdate")||x)&&(d.getSize(),d.needLayout=!0),this.checkGetGeneralizationChange(d,m)}else{let c=h||Tt();d=new ca({data:e,uid:c,renderer:this.renderer,mindMap:this.mindMap,draw:this.draw,layerIndex:n,isRoot:r,parent:r?null:t._node,...o}),e.data.uid=c,this.cacheNode(c,d),e._node=d}return e.data.isActive&&this.renderer.addNodeToActiveList(d),this.mindMap.renderer.findActiveNodeIndex(d)!==-1&&d.setData({isActive:!0}),r?this.root=d:t._node.addChildren(d),d}checkGetGeneralizationChange(e,t){let r=e.getData("generalization");r&&e._generalizationList&&e._generalizationList.length>0&&e._generalizationList.forEach((n,s)=>{let a=n.generalizationNode,o=a.getData(),l=r[s];(t||l&&JSON.stringify(o)!==JSON.stringify(l))&&(l&&(a.nodeData.data=l),a.getSize(),a.needLayout=!0)})}formatPosition(e,t,r){return typeof e=="number"?e:Jc[e]!==void 0?t*Jc[e]:/^\d\d*%$/.test(e)?Number.parseFloat(e)/100*t:(t-r)/2}formatInitRootNodePosition(e){let{CENTER:t}=C.INIT_ROOT_NODE_POSITION;return(!e||!Array.isArray(e)||e.length<2)&&(e=[t,t]),e}setNodeCenter(e,t){let{initRootNodePosition:r}=this.mindMap.opt;r=this.formatInitRootNodePosition(t||r),e.left=this.formatPosition(r[0],this.mindMap.width,e.width),e.top=this.formatPosition(r[1],this.mindMap.height,e.height)}getRootCenterOffset(e,t){if(this.rootNodeCenterOffset)return this.rootNodeCenterOffset;let{initRootNodePosition:r}=this.mindMap.opt,{CENTER:n}=C.INIT_ROOT_NODE_POSITION;if(r=this.formatInitRootNodePosition(r),r[0]===n&&r[1]===n)this.rootNodeCenterOffset={x:0,y:0};else{let s={width:e,height:t},a={width:e,height:t};this.setNodeCenter(s,[n,n]),this.setNodeCenter(a),this.rootNodeCenterOffset={x:a.left-s.left,y:a.top-s.top}}return this.rootNodeCenterOffset}updateChildren(e,t,r){e.forEach(n=>{n[t]+=r,n.children&&n.children.length&&!n.hasCustomPosition()&&this.updateChildren(n.children,t,r)})}updateChildrenPro(e,t){e.forEach(r=>{Object.keys(t).forEach(n=>{r[n]+=t[n]}),r.children&&r.children.length&&!r.hasCustomPosition()&&this.updateChildrenPro(r.children,t)})}getNodeAreaWidth(e,t=!1){let r=[],n=0,s=(a,o)=>{t&&a.checkHasGeneralization()&&(n+=a._generalizationNodeWidth),a.children.length?(o+=a.width/2,a.children.forEach(l=>{s(l,o)})):(o+=a.width,r.push(o))};return s(e,0),Math.max(...r)+n}quadraticCurvePath(e,t,r,n,s=!1){let a,o;return s?(a=e+(r-e)*.8,o=t+(n-t)*.2):(a=e+(r-e)*.2,o=t+(n-t)*.8),`M ${e},${t} Q ${a},${o} ${r},${n}`}cubicBezierPath(e,t,r,n,s=!1){let a,o,l,h;return s?(a=e,o=t+(n-t)/2,l=r,h=o):(a=e+(r-e)/2,o=t,l=a,h=n),`M ${e},${t} C ${a},${o} ${l},${h} ${r},${n}`}computeNewPoint(e,t,r=0){if(e[0]===t[0])return t[1]>e[1]?[t[0],t[1]-r]:[t[0],t[1]+r];if(e[1]===t[1])return t[0]>e[0]?[t[0]-r,t[1]]:[t[0]+r,t[1]]}createFoldLine(e){let{lineRadius:t}=this.mindMap.themeConfig,r=e.length,n="",s="";if(r>=3&&t>0){let a=e[r-3],o=e[r-2],l=e[r-1];if(!(a[0].toFixed(0)===o[0].toFixed(0)&&o[0].toFixed(0)===l[0].toFixed(0)||a[1].toFixed(0)===o[1].toFixed(0)&&o[1].toFixed(0)===l[1].toFixed(0))){let d=this.computeNewPoint(a,o,t),c=this.computeNewPoint(l,o,t);s=`Q ${o[0]},${o[1]} ${c[0]},${c[1]}`,e.splice(r-2,1,d,s)}}return e.forEach((a,o)=>{if(typeof a=="string")n+=a;else{let[l,h]=a;o===0?n+=`M ${l},${h}`:n+=`L ${l},${h}`}}),n}getMarginX(e){let{themeConfig:t,opt:r}=this.mindMap,{second:n,node:s}=t,a=r.hoverRectPadding*2;return e===1?n.marginX+a:s.marginX+a}getMarginY(e){let{themeConfig:t,opt:r}=this.mindMap,{second:n,node:s}=t,a=r.hoverRectPadding*2;return e===1?n.marginY+a:s.marginY+a}getNodeWidthWithGeneralization(e){return Math.max(e.width,e.checkHasGeneralization()?e._generalizationNodeWidth:0)}getNodeHeightWithGeneralization(e){return Math.max(e.height,e.checkHasGeneralization()?e._generalizationNodeHeight:0)}getNodeBoundaries(e,t){let{generalizationLineMargin:r,generalizationNodeMargin:n}=this.mindMap.themeConfig,s=d=>{let c=1/0,f=-1/0,m=1/0,g=-1/0;d.children&&d.children.length>0&&d.children.forEach(y=>{let{left:b,right:E,top:k,bottom:L}=s(y),I=y.checkHasGeneralization()&&y.getData("expand")?y._generalizationNodeWidth+n:0,O=y.checkHasGeneralization()&&y.getData("expand")?y._generalizationNodeHeight+n:0;b-(t==="h"?I:0)f&&(f=E+(t==="h"?I:0)),kg&&(g=L+(t==="v"?O:0))});let x={left:d.left,right:d.left+d.width,top:d.top,bottom:d.top+d.height};return{left:x.leftf?x.right:f,top:x.topg?x.bottom:g}},{left:a,right:o,top:l,bottom:h}=s(e);return{left:a,right:o,top:l,bottom:h,generalizationLineMargin:r,generalizationNodeMargin:n}}getChildrenBoundaries(e,t,r=0,n){let{generalizationLineMargin:s,generalizationNodeMargin:a}=this.mindMap.themeConfig,o=e.children.slice(r,n+1),l=1/0,h=-1/0,d=1/0,c=-1/0;return o.forEach(f=>{let m=this.getNodeBoundaries(f,t);l=m.lefth?m.right:h,d=m.topc?m.bottom:c}),{left:l,right:h,top:d,bottom:c,generalizationLineMargin:s,generalizationNodeMargin:a}}getNodeGeneralizationRenderBoundaries(e,t){let r=null;return e.range?r=this.getChildrenBoundaries(e.node,t,e.range[0],e.range[1]):r=this.getNodeBoundaries(e.node,t),r}getNodeActChildrenLength(e){return e.nodeData.children&&e.nodeData.children.length}setLineStyle(e,t,r,n){t.plot(this.transformPath(r)),e&&e(t,n,!0)}transformPath(e){let{customTransformNodeLinePath:t}=this.mindMap.opt;return t?t(e):e}},Nt=Wu});var Vu,nh,Yu=T(()=>{Vu=class{constructor(e){this.mindMap=e,this.autoMoveTimer=null}onMove(e,t,r=()=>{},n=()=>{}){r();let s=this.mindMap.opt.selectTranslateStep,a=this.mindMap.opt.selectTranslateLimit,o=0;e<=this.mindMap.elRect.left+a&&(n("left",s),this.mindMap.view.translateX(s),o++),e>=this.mindMap.elRect.right-a&&(n("right",s),this.mindMap.view.translateX(-s),o++),t<=this.mindMap.elRect.top+a&&(n("top",s),this.mindMap.view.translateY(s),o++),t>=this.mindMap.elRect.bottom-a&&(n("bottom",s),this.mindMap.view.translateY(-s),o++),o>0&&this.startAutoMove(e,t,r,n)}startAutoMove(e,t,r,n){this.autoMoveTimer=setTimeout(()=>{this.onMove(e,t,r,n)},20)}clearAutoMoveTimer(){clearTimeout(this.autoMoveTimer)}},nh=Vu});var u6={};tt(u6,{default:()=>kE});var sh,kE,f6=T(()=>{pe();Ar();Ge();Yu();sh=class extends Nt{constructor({mindMap:e}){super(e.renderer),this.mindMap=e,this.autoMove=new nh(e),this.reset(),this.bindEvent()}reset(){this.isDragging=!1,this.mousedownNode=null,this.beingDragNodeList=[],this.nodeList=[],this.overlapNode=null,this.prevNode=null,this.nextNode=null,this.drawTransform=null,this.clone=null,this.placeholder=null,this.placeholderWidth=50,this.placeholderHeight=10,this.placeHolderLine=null,this.placeHolderExtraLines=[],this.offsetX=0,this.offsetY=0,this.isMousedown=!1,this.mouseDownX=0,this.mouseDownY=0,this.mouseMoveX=0,this.mouseMoveY=0,this.checkDragOffset=10,this.minOffset=10}bindEvent(){this.onNodeMousedown=this.onNodeMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.checkOverlapNode=Ai(this.checkOverlapNode,300,this),this.mindMap.on("node_mousedown",this.onNodeMousedown),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("node_mouseup",this.onMouseup),this.mindMap.on("mouseup",this.onMouseup)}unBindEvent(){this.mindMap.off("node_mousedown",this.onNodeMousedown),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("node_mouseup",this.onMouseup),this.mindMap.off("mouseup",this.onMouseup)}onNodeMousedown(e,t){if(this.mindMap.opt.readonly||t.which!==1||e.isGeneralization||e.isRoot)return;this.isMousedown=!0,this.mousedownNode=e;let{x:r,y:n}=this.mindMap.toPos(t.clientX,t.clientY);this.mouseDownX=r,this.mouseDownY=n}onMousemove(e){if(this.mindMap.opt.readonly||!this.isMousedown)return;e.preventDefault();let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseMoveX=t,this.mouseMoveY=r,!(!this.isDragging&&Math.abs(t-this.mouseDownX)<=this.checkDragOffset&&Math.abs(r-this.mouseDownY)<=this.checkDragOffset)&&(this.mindMap.emit("node_dragging",this.mousedownNode),this.handleStartMove(),this.onMove(t,r,e))}async onMouseup(e){if(!this.isMousedown)return;let{autoMoveWhenMouseInEdgeOnDrag:t,enableFreeDrag:r,beforeDragEnd:n}=this.mindMap.opt;t&&this.mindMap.select&&this.autoMove.clearAutoMoveTimer(),this.isMousedown=!1,this.beingDragNodeList.forEach(l=>{l.setOpacity(1),l.showChildren(),l.endDrag()}),this.removeCloneNode();let s=this.overlapNode?this.overlapNode.getData("uid"):"",a=this.prevNode?this.prevNode.getData("uid"):"",o=this.nextNode?this.nextNode.getData("uid"):"";if(this.isDragging&&typeof n=="function"&&await n({overlapNodeUid:s,prevNodeUid:a,nextNodeUid:o,beingDragNodeList:[...this.beingDragNodeList]})){this.reset();return}if(this.overlapNode)this.removeNodeActive(this.overlapNode),this.mindMap.execCommand("MOVE_NODE_TO",this.beingDragNodeList,this.overlapNode);else if(this.prevNode)this.removeNodeActive(this.prevNode),this.mindMap.execCommand("INSERT_AFTER",this.beingDragNodeList,this.prevNode);else if(this.nextNode)this.removeNodeActive(this.nextNode),this.mindMap.execCommand("INSERT_BEFORE",this.beingDragNodeList,this.nextNode);else if(this.clone&&r&&this.beingDragNodeList.length===1){let{x:l,y:h}=this.mindMap.toPos(e.clientX-this.offsetX,e.clientY-this.offsetY),{scaleX:d,scaleY:c,translateX:f,translateY:m}=this.drawTransform;l=(l-f)/d,h=(h-m)/c,this.mousedownNode.left=l,this.mousedownNode.top=h,this.mousedownNode.customLeft=l,this.mousedownNode.customTop=h,this.mindMap.execCommand("SET_NODE_CUSTOM_POSITION",this.mousedownNode,l,h),this.mindMap.render()}this.isDragging&&this.mindMap.emit("node_dragend",{overlapNodeUid:s,prevNodeUid:a,nextNodeUid:o}),this.reset()}removeNodeActive(e){e.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1)}onMove(e,t,r){if(!this.isMousedown||!this.isDragging)return;let{scaleX:n,scaleY:s,translateX:a,translateY:o}=this.drawTransform,l=e-this.offsetX,h=t-this.offsetY;e=(l-a)/n,t=(h-o)/s;let d=this.clone.transform();this.clone.translate(e-d.translateX,t-d.translateY),this.checkOverlapNode(),this.drawTransform=this.mindMap.draw.transform(),this.autoMove.clearAutoMoveTimer(),this.autoMove.onMove(r.clientX,r.clientY)}async handleStartMove(){if(!this.isDragging){let e=this.mousedownNode;this.drawTransform=this.mindMap.draw.transform();let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.drawTransform;this.offsetX=this.mouseDownX-(e.left*t+n),this.offsetY=this.mouseDownY-(e.top*r+s),e.getData("isActive")?this.beingDragNodeList=Go(ds(this.mindMap.renderer.activeNodeList.filter(o=>!o.isRoot&&!o.isGeneralization))):this.beingDragNodeList=[e];let{beforeDragStart:a}=this.mindMap.opt;if(typeof a=="function"&&await a([...this.beingDragNodeList]))return;this.nodeTreeToList(),this.createCloneNode(),this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.isDragging=!0}}nodeTreeToList(){let e=[];Zt(this.mindMap.renderer.root,t=>{this.checkIsInBeingDragNodeList(t)||(e[t.layerIndex]||(e[t.layerIndex]=[]),e[t.layerIndex].push(t))}),this.nodeList=e.reduceRight((t,r)=>[...t,...r],[])}createCloneNode(){if(!this.clone){let{dragMultiNodeRectConfig:e,dragPlaceholderRectFill:t,dragPlaceholderLineConfig:r,dragOpacityConfig:n,handleDragCloneNode:s}=this.mindMap.opt,{width:a,height:o,fill:l}=e,h=this.beingDragNodeList[0],d=h.style.merge("lineColor",!0);if(this.beingDragNodeList.length>1)this.clone=this.mindMap.otherDraw.rect().size(a,o).radius(o/2).fill({color:l||d}),this.offsetX=a/2,this.offsetY=o/2;else{this.clone=h.group.clone();let c=this.clone.findOne(".smm-expand-btn");c&&c.remove(),this.mindMap.otherDraw.add(this.clone),typeof s=="function"&&s(this.clone)}this.clone.opacity(n.cloneNodeOpacity),this.clone.css("z-index",99999),this.placeholder=this.mindMap.otherDraw.rect().fill({color:t||d}).radius(5),this.placeHolderLine=this.mindMap.otherDraw.path().stroke({color:r.color||d,width:r.width}).fill({color:"none"}),this.beingDragNodeList.forEach(c=>{c.setOpacity(n.beingDragNodeOpacity),c.hideChildren(),c.startDrag()})}}removeCloneNode(){this.clone&&(this.clone.remove(),this.placeholder.remove(),this.placeHolderLine.remove(),this.removeExtraLines())}removeExtraLines(){this.placeHolderExtraLines.forEach(e=>{e.remove()}),this.placeHolderExtraLines=[]}checkOverlapNode(){if(!this.drawTransform||!this.placeholder)return;let{LOGICAL_STRUCTURE:e,LOGICAL_STRUCTURE_LEFT:t,MIND_MAP:r,ORGANIZATION_STRUCTURE:n,CATALOG_ORGANIZATION:s,TIMELINE:a,TIMELINE2:o,VERTICAL_TIMELINE:l,VERTICAL_TIMELINE2:h,VERTICAL_TIMELINE3:d,FISHBONE:c,FISHBONE2:f,RIGHT_FISHBONE:m,RIGHT_FISHBONE2:g}=C.LAYOUT;this.overlapNode=null,this.prevNode=null,this.nextNode=null,this.placeholder.size(0,0),this.placeHolderLine.hide(),this.removeExtraLines(),this.nodeList.forEach(x=>{if(x.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",x,!1),!(this.overlapNode||this.prevNode&&this.nextNode))switch(this.mindMap.opt.layout){case e:case t:this.handleLogicalStructure(x);break;case r:this.handleMindMap(x);break;case n:this.handleOrganizationStructure(x);break;case s:this.handleCatalogOrganization(x);break;case a:this.handleTimeLine(x);break;case o:this.handleTimeLine2(x);break;case l:case h:case d:this.handleLogicalStructure(x);break;case c:case f:case m:case g:this.handleFishbone(x);break;default:this.handleLogicalStructure(x)}}),this.overlapNode&&this.handleOverlapNode()}handleOverlapNode(){let{LOGICAL_STRUCTURE:e,LOGICAL_STRUCTURE_LEFT:t,MIND_MAP:r,ORGANIZATION_STRUCTURE:n,CATALOG_ORGANIZATION:s,TIMELINE:a,TIMELINE2:o,VERTICAL_TIMELINE:l,VERTICAL_TIMELINE2:h,VERTICAL_TIMELINE3:d,FISHBONE:c,FISHBONE2:f,RIGHT_FISHBONE:m,RIGHT_FISHBONE2:g}=C.LAYOUT,{LEFT:x,TOP:y,RIGHT:b,BOTTOM:E}=C.LAYOUT_GROW_DIR,k=this.overlapNode.layerIndex,L=this.overlapNode.children,I=this.mindMap.renderer.layout.getMarginX(k+1),O=this.mindMap.renderer.layout.getMarginY(k+1),q=this.placeholderWidth/2,F=this.placeholderHeight/2,W="",ne="",re="",le=!1,Ce=!1;if(L.length>0){let te=L[L.length-1],Q=this.getNodeRect(te);switch(W=this.getNewChildNodeDir(te),this.mindMap.opt.layout){case e:case r:ne=W===x?Q.originRight-this.placeholderWidth:Q.originLeft,re=Q.originBottom+this.minOffset-F;break;case t:ne=Q.originRight-this.placeholderWidth,re=Q.originBottom+this.minOffset-F;break;case n:le=!0,ne=Q.originRight+this.minOffset-F,re=Q.originTop;break;case s:k===0?(le=!0,ne=Q.originRight+this.minOffset-F,re=Q.originTop):(ne=Q.originLeft,re=Q.originBottom+this.minOffset-F);break;case a:k===0?(le=!0,ne=Q.originRight+this.minOffset-F,re=Q.originTop+Q.originHeight/2-q):(ne=Q.originLeft,re=Q.originBottom+this.minOffset-F);break;case o:k===0?(le=!0,ne=Q.originRight+this.minOffset-F,re=Q.originTop+Q.originHeight/2-q):(ne=Q.originLeft,k===1?re=W===y?Q.originTop-this.placeholderHeight-this.minOffset+F:Q.originBottom+this.minOffset-F:re=Q.originBottom+this.minOffset-F);break;case l:case h:case d:k===0?(ne=Q.originLeft+Q.originWidth/2-q,re=Q.originBottom+this.minOffset-F):(ne=W===b?Q.originLeft:Q.originRight-this.placeholderWidth,re=Q.originBottom+this.minOffset-F);break;case c:case f:case m:case g:k<=1?(Ce=!0,this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)):(ne=Q.originLeft,re=W===y?Q.originBottom+this.minOffset-F:Q.originTop-this.placeholderHeight-this.minOffset+F);break;default:}}else{let te=this.getNodeRect(this.overlapNode);switch(W=this.getNewChildNodeDir(this.overlapNode),this.mindMap.opt.layout){case e:case r:ne=W===b?te.originRight+I:te.originLeft-this.placeholderWidth-I,re=te.originTop+(te.originHeight-this.placeholderHeight)/2;break;case t:ne=te.originLeft-this.placeholderWidth-I,re=te.originTop+(te.originHeight-this.placeholderHeight)/2;break;case n:le=!0,ne=te.originLeft+(te.originWidth-this.placeholderHeight)/2,re=te.originBottom+I;break;case s:k===0&&(le=!0),ne=te.originLeft+te.originWidth*.5,re=te.originBottom+I;break;case a:k===0&&(le=!0),ne=te.originLeft+te.originWidth*.5,re=te.originBottom+O;break;case o:k===0&&(le=!0),ne=te.originLeft+te.originWidth*.5,k===1?re=W===y?te.originTop-this.placeholderHeight-I:te.originBottom+I:re=te.originBottom+I;break;case l:case h:case d:k===0&&(le=!0),ne=W===b?te.originRight+I:te.originLeft-this.placeholderWidth-I,re=te.originTop+te.originHeight/2-F;break;case c:case f:case m:case g:k<=1?(Ce=!0,this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)):(ne=te.originLeft+te.originWidth*.5,re=W===E?te.originTop-this.placeholderHeight-this.minOffset+F:te.originBottom+this.minOffset-F);break;default:}}Ce||this.setPlaceholderRect({x:ne,y:re,dir:W,rotate:le})}getNewChildNodeDir(e){let{LOGICAL_STRUCTURE:t,LOGICAL_STRUCTURE_LEFT:r,MIND_MAP:n,TIMELINE2:s,VERTICAL_TIMELINE:a,VERTICAL_TIMELINE2:o,VERTICAL_TIMELINE3:l,FISHBONE:h,FISHBONE2:d,RIGHT_FISHBONE:c,RIGHT_FISHBONE2:f}=C.LAYOUT;switch(this.mindMap.opt.layout){case t:return C.LAYOUT_GROW_DIR.RIGHT;case r:return C.LAYOUT_GROW_DIR.LEFT;case n:case s:case a:case o:case l:case h:case d:case c:case f:return e.dir;default:return""}}handleVerticalCheck(e,t,r=!1){let{layout:n}=this.mindMap.opt,{LAYOUT:s,LAYOUT_GROW_DIR:a}=C,{VERTICAL_TIMELINE:o,VERTICAL_TIMELINE2:l,VERTICAL_TIMELINE3:h,FISHBONE:d,FISHBONE2:c,RIGHT_FISHBONE:f,RIGHT_FISHBONE2:m}=s,{LEFT:g}=a,x=this.mouseMoveX,y=this.mouseMoveY,b=this.getNodeRect(e),E=this.getNewChildNodeDir(e),k=e.layerIndex;r&&(t=t.reverse());let L=b.originHeight/4,{prevBrotherOffset:I,nextBrotherOffset:O}=this.getNodeDistanceToSiblingNode(t,e,b,"v");if(b.left<=x&&b.right>=x){if(!this.overlapNode&&!this.prevNode&&!this.nextNode&&!e.isRoot){let q=O>0?y>b.bottom&&y<=b.bottom+O:y>=b.bottom-L&&y<=b.bottom,F=I>0?y=b.top-I:y>=b.top&&y<=b.top+L,{scaleY:W}=this.drawTransform,ne=E===g?b.originRight-this.placeholderWidth:b.originLeft,re=!1;switch(n){case o:case l:case h:k===1&&(ne=b.originLeft+b.originWidth/2-this.placeholderWidth/2);break;case f:case m:ne=b.originLeft+b.originWidth-this.placeholderWidth;break;default:}if(q){r?this.nextNode=e:this.prevNode=e;let le=b.originBottom+O/W-this.placeholderHeight/2;switch(n){case d:case c:case f:case m:k===2&&(re=!0,le=b.originBottom+this.minOffset-this.placeholderHeight/2);break;default:}this.setPlaceholderRect({x:ne,y:le,dir:E,notRenderLine:re})}else if(F){r?this.prevNode=e:this.nextNode=e;let le=b.originTop-this.placeholderHeight-I/W+this.placeholderHeight/2;switch(n){case d:case c:case f:case m:k===2&&(re=!0,le=b.originTop-this.placeholderHeight-this.minOffset+this.placeholderHeight/2);break;default:}this.setPlaceholderRect({x:ne,y:le,dir:E,notRenderLine:re})}}this.checkIsOverlap({node:e,dir:"v",prevBrotherOffset:I,nextBrotherOffset:O,size:L,pos:y,nodeRect:b})}}handleHorizontalCheck(e,t){let{layout:r}=this.mindMap.opt,{LAYOUT:n}=C,{FISHBONE:s,FISHBONE2:a,RIGHT_FISHBONE:o,RIGHT_FISHBONE2:l,TIMELINE:h,TIMELINE2:d}=n,c=this.mouseMoveX,f=this.mouseMoveY,m=this.getNodeRect(e),g=m.originWidth/4,{prevBrotherOffset:x,nextBrotherOffset:y}=this.getNodeDistanceToSiblingNode(t,e,m,"h");if(m.top<=f&&m.bottom>=f){if(!this.overlapNode&&!this.prevNode&&!this.nextNode&&!e.isRoot){let b=y>0?c=m.right:c<=m.right&&c>=m.right-g,E=x>0?c>m.left-x&&c<=m.left:c<=m.left+g&&c>=m.left,{scaleX:k}=this.drawTransform,L=e.layerIndex,I=m.originTop,O=!1;switch(r){case h:case d:I=m.originTop+m.originHeight/2-this.placeholderWidth/2;break;case s:case a:case o:case l:L===1&&(O=!0,I=m.originTop+m.originHeight/2-this.placeholderWidth/2);break;default:}b?([o,l].includes(r)?this.nextNode=e:this.prevNode=e,this.setPlaceholderRect({x:m.originRight+y/k-this.placeholderHeight/2,y:I,rotate:!0,notRenderLine:O})):E&&([o,l].includes(r)?this.prevNode=e:this.nextNode=e,this.setPlaceholderRect({x:m.originLeft-this.placeholderHeight-x/k+this.placeholderHeight/2,y:I,rotate:!0,notRenderLine:O}))}this.checkIsOverlap({node:e,dir:"h",prevBrotherOffset:x,nextBrotherOffset:y,size:g,pos:c,nodeRect:m})}}getNodeDistanceToSiblingNode(e,t,r,n){let{TOP:s,LEFT:a,BOTTOM:o,RIGHT:l}=C.LAYOUT_GROW_DIR,{scaleX:h,scaleY:d}=this.drawTransform,c=n==="v"?s:a,f=n==="v"?o:l,m=n==="v"?d:h,g=this.minOffset*m,x=ze(t,e),y=null,b=null;x!==-1&&(x-1>=0&&(y=e[x-1]),x+1<=e.length-1&&(b=e[x+1]));let E=0;if(y){let L=this.getNodeRect(y);E=r[c]-L[f],E=E>=g?E/2:0}else E=g;let k=0;return b?(k=this.getNodeRect(b)[c]-r[f],k=k>=g?k/2:0):k=g,{prevBrother:y,prevBrotherOffset:E,nextBrother:b,nextBrotherOffset:k}}setPlaceholderRect({x:e,y:t,dir:r,rotate:n,notRenderLine:s}){let a=this.placeholderWidth,o=this.placeholderHeight;if(n){let f=a;a=o,o=f}if(this.placeholder.size(a,o).move(e,t),s)return;let{dragPlaceholderLineConfig:l}=this.mindMap.opt,h=null,d=null;this.overlapNode?(h=this.overlapNode,d=this.overlapNode):(h=this.prevNode||this.nextNode,d=h.parent),d=d.fakeClone(),h=h.fakeClone();let c=this.beingDragNodeList[0].fakeClone();c.dir=r,c.left=e,c.top=t,c.width=a,c.height=o,d.children=[c],d._lines=[],this.placeHolderLine.show(),this.mindMap.renderer.layout.renderLine(d,[this.placeHolderLine],(...f)=>{},h.style.getStyle("lineStyle",!0)),this.placeHolderExtraLines=[...d._lines],this.placeHolderExtraLines.forEach(f=>{this.mindMap.otherDraw.add(f),f.stroke({color:l.color,width:l.width}).fill({color:"none"})})}checkIsOverlap({node:e,dir:t,prevBrotherOffset:r,nextBrotherOffset:n,size:s,pos:a,nodeRect:o}){let{TOP:l,LEFT:h,BOTTOM:d,RIGHT:c}=C.LAYOUT_GROW_DIR,f=t==="v"?l:h,m=t==="v"?d:c;!this.overlapNode&&!this.prevNode&&!this.nextNode&&o[f]+(r>0?0:s)<=a&&o[m]-(n>0?0:s)>=a&&(this.overlapNode=e)}handleLogicalStructure(e){let t=this.commonGetNodeCheckList(e);this.handleVerticalCheck(e,t)}handleMindMap(e){let t=e.parent?e.parent.children.filter(r=>{let n=!0;return e.layerIndex===1&&(n=r.dir===e.dir),n&&!this.checkIsInBeingDragNodeList(r)}):[];this.handleVerticalCheck(e,t)}handleOrganizationStructure(e){let t=this.commonGetNodeCheckList(e);this.handleHorizontalCheck(e,t)}handleCatalogOrganization(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):this.handleVerticalCheck(e,t)}handleTimeLine(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):this.handleVerticalCheck(e,t)}handleTimeLine2(e){let t=this.commonGetNodeCheckList(e);e.layerIndex===1?this.handleHorizontalCheck(e,t):e.dir===C.LAYOUT_GROW_DIR.TOP&&e.layerIndex===2?this.handleVerticalCheck(e,t,!0):this.handleVerticalCheck(e,t)}handleFishbone(e){let t=e.parent?e.parent.children.filter(r=>r.layerIndex>1&&!this.checkIsInBeingDragNodeList(r)):[];if(e.layerIndex===1)this.handleHorizontalCheck(e,t);else{let r=e.dir===C.LAYOUT_GROW_DIR.TOP&&e.layerIndex===2,n=e.dir===C.LAYOUT_GROW_DIR.BOTTOM&&e.layerIndex>=3;r||n?this.handleVerticalCheck(e,t,!0):this.handleVerticalCheck(e,t)}}commonGetNodeCheckList(e){return e.parent?[...e.parent.children].filter(t=>!this.checkIsInBeingDragNodeList(t)):[]}getNodeRect(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.drawTransform,{left:a,top:o,width:l,height:h}=e,d=l,c=h,f=a,m=o,g=o+h,x=a+l,y=(a+l)*t+n,b=(o+h)*r+s;return a=a*t+n,o=o*r+s,{left:a,top:o,right:y,bottom:b,originWidth:d,originHeight:c,originLeft:f,originTop:m,originBottom:g,originRight:x}}checkIsInBeingDragNodeList(e){return!!this.beingDragNodeList.find(t=>t.uid===e.uid||t.isAncestor(e))}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};sh.instanceName="drag";kE=sh});var m6={};tt(m6,{default:()=>CE});var ah,CE,p6=T(()=>{pe();Ge();ah=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,this.addShortcut()}addShortcut(){this.onLeftKeyUp=this.onLeftKeyUp.bind(this),this.onUpKeyUp=this.onUpKeyUp.bind(this),this.onRightKeyUp=this.onRightKeyUp.bind(this),this.onDownKeyUp=this.onDownKeyUp.bind(this),this.mindMap.keyCommand.addShortcut(C.KEY_DIR.LEFT,this.onLeftKeyUp),this.mindMap.keyCommand.addShortcut(C.KEY_DIR.UP,this.onUpKeyUp),this.mindMap.keyCommand.addShortcut(C.KEY_DIR.RIGHT,this.onRightKeyUp),this.mindMap.keyCommand.addShortcut(C.KEY_DIR.DOWN,this.onDownKeyUp)}removeShortcut(){this.mindMap.keyCommand.removeShortcut(C.KEY_DIR.LEFT,this.onLeftKeyUp),this.mindMap.keyCommand.removeShortcut(C.KEY_DIR.UP,this.onUpKeyUp),this.mindMap.keyCommand.removeShortcut(C.KEY_DIR.RIGHT,this.onRightKeyUp),this.mindMap.keyCommand.removeShortcut(C.KEY_DIR.DOWN,this.onDownKeyUp)}onLeftKeyUp(){this.onKeyup(C.KEY_DIR.LEFT)}onUpKeyUp(){this.onKeyup(C.KEY_DIR.UP)}onRightKeyUp(){this.onKeyup(C.KEY_DIR.RIGHT)}onDownKeyUp(){this.onKeyup(C.KEY_DIR.DOWN)}onKeyup(e){if(this.mindMap.renderer.activeNodeList.length>0)this.focus(e);else{let t=this.mindMap.renderer.root;this.mindMap.execCommand("GO_TARGET_NODE",t)}}focus(e){let t=this.mindMap.renderer.activeNodeList[0],r=this.getNodeRect(t),n=null,s=1/0,a=(o,l)=>{let h=this.getDistance(r,o);h{if(s.uid===e.uid)return;let a=this.getNodeRect(s),{left:o,top:l,right:h,bottom:d}=a,c=!1;r===C.KEY_DIR.LEFT?c=h<=t.left:r===C.KEY_DIR.RIGHT?c=o>=t.right:r===C.KEY_DIR.UP?c=d<=t.top:r===C.KEY_DIR.DOWN&&(c=l>=t.bottom),c&&n(a,s)})}getFocusNodeByShadowAlgorithm({currentActiveNode:e,currentActiveNodeRect:t,dir:r,checkNodeDis:n}){Zt(this.mindMap.renderer.root,s=>{if(s.uid===e.uid)return;let a=this.getNodeRect(s),{left:o,top:l,right:h,bottom:d}=a,c=!1;r===C.KEY_DIR.LEFT?c=ot.top:r===C.KEY_DIR.RIGHT?c=h>t.right&&lt.top:r===C.KEY_DIR.UP?c=lt.left:r===C.KEY_DIR.DOWN&&(c=d>t.bottom&&ot.left),c&&n(a,s)})}getFocusNodeByAreaAlgorithm({currentActiveNode:e,currentActiveNodeRect:t,dir:r,checkNodeDis:n}){let s=(t.right+t.left)/2,a=(t.bottom+t.top)/2;Zt(this.mindMap.renderer.root,o=>{if(o.uid===e.uid)return;let l=this.getNodeRect(o),{left:h,top:d,right:c,bottom:f}=l,m=(c+h)/2,g=(f+d)/2,x=m-s,y=g-a;if(x===0&&y===0)return;let b=!1;r===C.KEY_DIR.LEFT?b=x<=0&&x<=y&&x<=-y:r===C.KEY_DIR.RIGHT?b=x>0&&x>=-y&&x>=y:r===C.KEY_DIR.UP?b=y<=0&&y0&&-yx),b&&n(l,o)})}getNodeRect(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.mindMap.draw.transform(),{left:a,top:o,width:l,height:h}=e;return{right:(a+l)*t+n,bottom:(o+h)*r+s,left:a*t+n,top:o*r+s}}getDistance(e,t){let r=this.getCenter(e),n=this.getCenter(t);return Math.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2))}getCenter({left:e,right:t,top:r,bottom:n}){return{x:(e+t)/2,y:(r+n)/2}}beforePluginRemove(){this.removeShortcut()}beforePluginDestroy(){this.removeShortcut()}};ah.instanceName="keyboardNavigation";CE=ah});var Ku,oh,Xu,g6,_E,LE,IE,lh,zE,x6,y6=T(()=>{Ku=i=>String(i).split(/\s+/).map(t=>{if(/^[\d.]+/.test(t)){let r=/^([\d.]+)(.*)$/.exec(t);return[Number(r[1]),r[2]]}else return t}),oh=(i,e)=>i*e,Xu=(i,e)=>e/i,g6={left:0,top:0,center:50,bottom:100,right:100},_E=({backgroundSize:i,drawOpt:e,imageRatio:t,canvasWidth:r,canvasHeight:n,canvasRatio:s})=>{if(i){let a=Ku(i);if(a[0]==="auto"&&a[1]==="auto")return;if(a[0]==="cover"){t>s?(e.height=n,e.width=oh(t,n)):(e.width=r,e.height=Xu(t,r));return}if(a[0]==="contain"){t>s?(e.width=r,e.height=Xu(t,r)):(e.height=n,e.width=oh(t,n));return}let o=-1;a[0]&&(Array.isArray(a[0])?a[0][1]==="%"?(e.width=a[0][0]/100*r,o=e.width):(e.width=a[0][0],o=a[0][0]):a[0]==="auto"&&a[1]&&(a[1][1]==="%"?e.width=oh(t,a[1][0]/100*n):e.width=oh(t,a[1][0]))),a[1]&&Array.isArray(a[1])?a[1][1]==="%"?e.height=a[1][0]/100*n:e.height=a[1][0]:o!==-1&&(e.height=Xu(t,o))}},LE=({backgroundPosition:i,drawOpt:e,imgWidth:t,imgHeight:r,canvasWidth:n,canvasHeight:s})=>{if(i){let a=Ku(i);if(a=a.map(o=>typeof o=="string"&&g6[o]!==void 0?[g6[o],"%"]:o),Array.isArray(a[0])){if(a.length===1&&a.push([50,"%"]),a[0][1]==="%"){let o=a[0][0]/100*n,l=a[0][0]/100*t;e.x=o-l}else e.x=a[0][0];if(a[1][1]==="%"){let o=a[1][0]/100*s,l=a[1][0]/100*r;e.y=o-l}else e.y=a[1][0]}}},IE=({ctx:i,image:e,backgroundRepeat:t,drawOpt:r,imgWidth:n,imgHeight:s,canvasWidth:a,canvasHeight:o})=>{if(t){let l=r.x,h=r.y,d=Math.ceil(l/n),c=Math.ceil(h/s),f=l-d*n,m=h-c*s,g=Ku(t);if(g[0]==="no-repeat"||n>=a&&s>=o)return;if(g[0]==="repeat-x"&&a>n){let x=f;for(;xs){let x=m;for(;xs){let y=m;for(;y{i.drawImage(e,t.sx,t.sy,t.swidth,t.sheight,t.x,t.y,t.width,t.height)},zE=(i,e,t,r,{backgroundSize:n,backgroundPosition:s,backgroundRepeat:a},o=()=>{})=>{let l=e/t,h=new Image;h.src=r,h.onload=()=>{let d=h.width,c=h.height,f=d/c,m={sx:0,sy:0,swidth:d,sheight:c,x:0,y:0,width:d,height:c};_E({backgroundSize:n,drawOpt:m,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l}),LE({backgroundPosition:s,drawOpt:m,imgWidth:m.width,imgHeight:m.height,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l}),IE({ctx:i,image:h,backgroundRepeat:a,drawOpt:m,imgWidth:m.width,imgHeight:m.height,imageRatio:f,canvasWidth:e,canvasHeight:t,canvasRatio:l})||lh(i,h,m),o()},h.onerror=d=>{o(d)}},x6=zE});var Zu,RE,DE,v6,b6=T(()=>{pe();Zu=i=>i.richText?Q0(i.text):i.text,RE=i=>new Array(i).fill("#").join(""),DE=i=>new Array(i-6).fill(" ").join("")+"*",v6=i=>{let e="";return ue(i,null,(t,r,n,s)=>{let a=s+1;a<=6?e+=RE(a):e+=DE(a),e+=" "+Zu(t.data);let o=t.data.generalization;if(Array.isArray(o))e+=o.map(l=>` [${Zu(l)}]`);else if(o&&o.text){let l=Zu(o);e+=` [${l}]`}e+=` `,t.data.note&&(e+=t.data.note+` -`)},()=>{},!0),e}});var Hu,uE,o6,l6=T(()=>{pe();Hu=i=>i.richText?j0(i.text):i.text,uE=i=>new Array(i).fill(" ").join(""),o6=i=>{let e="";return de(i,null,(t,r,n,s)=>{e+=uE(s),e+=" "+Hu(t.data);let a=t.data.generalization;Array.isArray(a)?e+=a.map(o=>` [${Hu(o)}]`):a&&a.text&&(e+=` [${Hu(a)}]`),e+=` +`)},()=>{},!0),e}});var Qu,OE,w6,M6=T(()=>{pe();Qu=i=>i.richText?Q0(i.text):i.text,OE=i=>new Array(i).fill(" ").join(""),w6=i=>{let e="";return ue(i,null,(t,r,n,s)=>{e+=OE(s),e+=" "+Qu(t.data);let a=t.data.generalization;Array.isArray(a)?e+=a.map(o=>` [${Qu(o)}]`):a&&a.text&&(e+=` [${Qu(a)}]`),e+=` -`},()=>{},!0),e}});var h6={};tt(h6,{default:()=>fE});var th,fE,d6=T(()=>{pe();yt();n6();a6();$e();l6();th=class{constructor(e){this.mindMap=e.mindMap}async export(e,t=!0,r="\u601D\u7EF4\u5BFC\u56FE",...n){if(this[e]){let s=await this[e](r,...n);return t&&m2(s,r+"."+e),s}else return null}createTransformImgTaskList(e,t,r,n){return e.find(t).map(async a=>{let o=n(a);if(/^data:/.test(o)||o==="none")return;let l=await fu(o);a.attr(r,l)})}async getSvgData(e){let{exportPaddingX:t,exportPaddingY:r,errorHandler:n,resetCss:s,addContentToHeader:a,addContentToFooter:o,handleBeingExportSvg:l}=this.mindMap.opt,{svg:h,svgHTML:d,clipData:c}=this.mindMap.getSvgData({paddingX:t,paddingY:r,addContentToHeader:a,addContentToFooter:o,node:e});c&&(c.paddingX=t,c.paddingY=r);let f=!1,m=this.createTransformImgTaskList(h,"image","href",y=>y.attr("href")||y.attr("xlink:href")),g=this.createTransformImgTaskList(h,"img","src",y=>y.attr("src")),x=[...m,...g];try{await Promise.all(x)}catch(y){n(Mi.EXPORT_LOAD_IMAGE_ERROR,y)}if(this.mindMap.richText){let y=h.find("foreignObject");if(y.length>0&&(y[0].add(Ae(``)),f=!0),this.mindMap.formula&&h.find(".ql-formula").length>0){let S=this.mindMap.formula.getStyleText();if(S){let A=document.createElement("style");A.innerHTML=S,or(A),y[0].add(A),f=!0}}}return typeof l=="function"&&(f=!0,h=l(h)),(x.length>0||f)&&(d=h.svg()),{node:h,str:d,clipData:c}}svgToPng(e,t,r=null,n=!1,s="image/png"){let{maxCanvasSize:a,minExportImgCanvasScale:o}=this.mindMap.opt;return new Promise((l,h)=>{let d=new Image;d.setAttribute("crossOrigin","anonymous"),d.onload=async()=>{try{let c=document.createElement("canvas"),f=Math.max(window.devicePixelRatio,o),m=d.width,g=d.height,x=0,y=0;r&&(x=r.paddingX,y=r.paddingY,m=r.width+x*2,g=r.height+y*2);let b=0,S=0,{backgroundImage:A}=this.mindMap.themeConfig;if(n&&A&&!t){let ke=await new Promise(Q=>{let Y=new Image;Y.onload=()=>{Q([Y.width,Y.height])},Y.onerror=()=>{Q(null)},Y.src=A});if(ke){let Q=m/g,Y=ke[0]/ke[1];Q>Y?(b=m,S=m/Y):(S=g,b=g*Y)}}let C=1,I=1,O=(b||m)*f,q=(S||g)*f;if(O>a||q>a){let ke=null,Q=null;O>a?ke=a:q>a&&(Q=a);let Y=U0(O,q,ke,Q);C=Y[0]/O,I=Y[1]/q,O=Y[0],q=Y[1]}c.width=O,c.height=q;let P=O/f,W=q/f;c.style.width=P+"px",c.style.height=W+"px";let ne=c.getContext("2d");ne.scale(f,f),t||await this.drawBackgroundToCanvas(ne,P,W);let re=(b>0?(b-m)/2:0)*C,oe=(S>0?(S-g)/2:0)*I;r?ne.drawImage(d,r.left,r.top,r.width,r.height,x*C+re,y*I+oe,r.width*C,r.height*I):ne.drawImage(d,re,oe,m*C,g*I),l(c.toDataURL(s))}catch(c){h(c)}},d.onerror=c=>{h(c)},d.src=e})}drawBackgroundToCanvas(e,t,r){return new Promise((n,s)=>{let{backgroundColor:a="#fff",backgroundImage:o,backgroundRepeat:l="no-repeat",backgroundPosition:h="center center",backgroundSize:d="cover"}=this.mindMap.themeConfig;e.save(),e.rect(0,0,t,r),e.fillStyle=a,e.fill(),e.restore(),o&&o!=="none"?(e.save(),r6(e,t,r,o,{backgroundRepeat:l,backgroundPosition:h,backgroundSize:d},c=>{c?s(c):n(),e.restore()})):n()})}drawBackgroundToSvg(e){return new Promise(async t=>{let{backgroundColor:r="#fff",backgroundImage:n,backgroundRepeat:s="repeat"}=this.mindMap.themeConfig;if(e.css("background-color",r),n&&n!=="none"){let a=await fu(n);e.css("background-image",`url(${a})`),e.css("background-repeat",s),t()}else t()})}async _image(e,t,r=!1,n=null,s=!1){this.mindMap.renderer.textEdit.hideEditTextBox(),this.handleNodeExport(n);let{str:a,clipData:o}=await this.getSvgData(n),l=await this.fixSvgStrAndToBlob(a);return await this.svgToPng(l,r,o,s,e)}async png(...e){return await this._image("image/png",...e)}async jpg(...e){return await this._image("image/jpg",...e)}handleNodeExport(e){if(e&&e.getData("isActive")){e.deactivate();let{alwaysShowExpandBtn:t,notShowExpandBtn:r}=this.mindMap.opt;!t&&!r&&e.getData("expand")&&e.removeExpandBtn()}}async pdf(e,t=!1,r=!1){if(!this.mindMap.doExportPDF)throw new Error("\u8BF7\u6CE8\u518CExportPDF\u63D2\u4EF6");let n=await this.png(e,t,null,r);return await this.mindMap.doExportPDF.pdf(n)}async xmind(e){if(!this.mindMap.doExportXMind)throw new Error("\u8BF7\u6CE8\u518CExportXMind\u63D2\u4EF6");let t=this.mindMap.getData(),r=await this.mindMap.doExportXMind.xmind(t,e);return await aa(r)}async svg(e){this.mindMap.renderer.textEdit.hideEditTextBox();let{node:t}=await this.getSvgData();t.first().before(Ae(`${e}`)),await this.drawBackgroundToSvg(t);let r=t.svg();return await this.fixSvgStrAndToBlob(r)}async fixSvgStrAndToBlob(e){e=b2(e),e=_2(e);let t=new Blob([e],{type:"image/svg+xml"});return await aa(t)}async json(e,t=!0){let r=this.mindMap.getData(t),n=JSON.stringify(r),s=new Blob([n]);return await aa(s)}async smm(e,t){return await this.json(e,t)}async md(){let e=this.mindMap.getData(),t=s6(e),r=new Blob([t]);return await aa(r)}async txt(){let e=this.mindMap.getData(),t=o6(e),r=new Blob([t]);return await aa(r)}};th.instanceName="doExport";fE=th});var c6={};tt(c6,{default:()=>mE});var ih,mE,u6=T(()=>{pe();Bu();ih=class{constructor({mindMap:e}){this.mindMap=e,this.rect=null,this.isMousedown=!1,this.mouseDownX=0,this.mouseDownY=0,this.mouseMoveX=0,this.mouseMoveY=0,this.isSelecting=!1,this.cacheActiveList=[],this.autoMove=new K0(e),this.bindEvent()}bindEvent(){this.onMousedown=this.onMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.checkInNodes=Si(this.checkInNodes,300,this),this.mindMap.on("mousedown",this.onMousedown),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("mouseup",this.onMouseup),this.mindMap.on("node_mouseup",this.onMouseup)}unBindEvent(){this.mindMap.off("mousedown",this.onMousedown),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("mouseup",this.onMouseup),this.mindMap.off("node_mouseup",this.onMouseup)}onMousedown(e){let{readonly:t,mousedownEventPreventDefault:r}=this.mindMap.opt;if(t)return;let{useLeftKeySelectionRightKeyDrag:n}=this.mindMap.opt;if(!(e.ctrlKey||e.metaKey)&&(n?e.which!==1:e.which!==3))return;r&&e.preventDefault(),this.isMousedown=!0,this.cacheActiveList=[...this.mindMap.renderer.activeNodeList];let{x:s,y:a}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseDownX=s,this.mouseDownY=a,this.createRect(s,a)}onMousemove(e){if(this.mindMap.opt.readonly||!this.isMousedown)return;let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseMoveX=t,this.mouseMoveY=r,!(Math.abs(t-this.mouseDownX)<=10&&Math.abs(r-this.mouseDownY)<=10)&&(this.autoMove.clearAutoMoveTimer(),this.autoMove.onMove(e.clientX,e.clientY,()=>{this.isSelecting=!0,this.rect&&this.rect.plot([[this.mouseDownX,this.mouseDownY],[this.mouseMoveX,this.mouseDownY],[this.mouseMoveX,this.mouseMoveY],[this.mouseDownX,this.mouseMoveY]]),this.checkInNodes()},(n,s)=>{switch(n){case"left":this.mouseDownX+=s;break;case"top":this.mouseDownY+=s;break;case"right":this.mouseDownX-=s;break;case"bottom":this.mouseDownY-=s;break;default:break}}))}onMouseup(){this.mindMap.opt.readonly||this.isMousedown&&(this.checkTriggerNodeActiveEvent(),this.autoMove.clearAutoMoveTimer(),this.isMousedown=!1,this.cacheActiveList=[],this.rect&&this.rect.remove(),this.rect=null,setTimeout(()=>{this.isSelecting=!1},0))}checkTriggerNodeActiveEvent(){let e=this.cacheActiveList.length!==this.mindMap.renderer.activeNodeList.length,t=!1;if(!e)for(let r=0;rs.getData("uid")===n.getData("uid"))){t=!0;break}}(e||t)&&this.mindMap.renderer.emitNodeActiveEvent()}createRect(e,t){this.rect&&this.rect.remove(),this.rect=this.mindMap.svg.polygon().stroke({color:"#0984e3"}).fill({color:"rgba(9,132,227,0.3)"}).plot([[e,t]])}checkInNodes(){let{scaleX:e,scaleY:t,translateX:r,translateY:n}=this.mindMap.draw.transform(),s=Math.min(this.mouseDownX,this.mouseMoveX),a=Math.min(this.mouseDownY,this.mouseMoveY),o=Math.max(this.mouseDownX,this.mouseMoveX),l=Math.max(this.mouseDownY,this.mouseMoveY),h=d=>{let{left:c,top:f,width:m,height:g}=d,x=(c+m)*e+r,y=(f+g)*t+n;if(c=c*e+r,f=f*t+n,k2(s,o,a,l,c,x,f,y)){if(d.getData("isActive"))return;this.mindMap.renderer.addNodeToActiveList(d),this.mindMap.renderer.emitNodeActiveEvent()}else if(d.getData("isActive")){if(!d.getData("isActive"))return;this.mindMap.renderer.removeNodeFromActiveList(d),this.mindMap.renderer.emitNodeActiveEvent()}};Xt(this.mindMap.renderer.root,d=>{h(d),d._generalizationList&&d._generalizationList.length>0&&d._generalizationList.forEach(c=>{h(c.generalizationNode)})})}hasSelectRange(){return this.isSelecting}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};ih.instanceName="select";mE=ih});var Go,Vo,rh,f6,m6,pE,kr,Uu,p6,$u,ju=T(()=>{pe();Go=(i,e)=>i.getData("associativeLineTargets").findIndex(t=>t===e.getData("uid")),Vo=(i,e,t,r)=>{let s=i+(t-i)/2,a=e,o=s,l=r;return Math.abs(i-t)<=5&&(s=i+(r-e)/2,o=s),Math.abs(e-r)<=5&&(s=i,a=e-(t-i)/2,o=t,l=a),[{x:s,y:a},{x:o,y:l}]},rh=(i,e,t,r)=>`M ${i.x},${i.y} C ${t.x},${t.y} ${r.x},${r.y} ${e.x},${e.y}`,f6=i=>{let{left:e,top:t,width:r,height:n}=i;return{right:e+r,bottom:t+n,left:e,top:t,width:r,height:n}},m6=(i,e,t,r)=>{let n=Vo(i,e,t,r);return rh({x:i,y:e},{x:t,y:r},n[0],n[1])},pE=(i,e)=>{let{left:t,top:r,translateLeft:n,translateTop:s,width:a,height:o}=i,l=e.clientX,h=e.clientY,d=n+a/2,c=s+o/2,f=t+a/2,m=r+o/2,g=Math.atan(o/a),x=l-d,y=c-h,b=Math.atan2(y,x),S=t+a,A=r+o;if(b=-g){let O=b*(a/2);return(b=0||b>=-g&&b<0)&&(A=m-O),{x:S,y:A,dir:"right",range:O}}else if(b>=g&&b=g){let q=o/2/b;O=-q,S=f+q}else if(b>=Math.PI/2-g&&b=g-Math.PI){let O=0;if(b>=g-Math.PI/2&&b<-g){let q=o/2/b;O=q,S=f-q}else if(b=g-Math.PI){let q=(d-l)/(c-h),P=o/2*q;O=-P,S=f+P}return{x:S,y:A,dir:"bottom",range:O}}S=t;let I=(c-h)/(d-l)*(a/2);return(b>=-Math.PI&&b=Math.PI-g)&&(A=m-I),{x:S,y:A,dir:"left",range:I}},kr=(i,e="right",t=0,r=null)=>{let{left:n,top:s,width:a,height:o}=i;if(r)return pE(i,r);switch(e){case"left":return{x:n,y:s+o/2-t,dir:e};case"right":return{x:n+a,y:s+o/2-t,dir:e};case"top":return{x:n+a/2-t,y:s,dir:e};case"bottom":return{x:n+a/2-t,y:s+o,dir:e};default:break}},Uu=(i,e)=>{let t=f6(i),r=f6(e),n="",s="";switch(z2({x:t.left,y:t.top,width:t.width,height:t.height},{x:r.left,y:r.top,width:r.width,height:r.height})){case"left-top":n="right",s="top";break;case"right-top":n="left",s="top";break;case"right-bottom":n="left",s="bottom";break;case"left-bottom":n="right",s="bottom";break;case"left":n="right",s="left";break;case"right":n="left",s="right";break;case"top":n="right",s="right";break;case"bottom":n="left",s="left";break;case"overlap":n="right",s="right";break;default:break}return[kr(i,n),kr(e,s)]},p6=(i,e,t,r)=>{let n=Go(t,r),s=[],a=t.getData("associativeLineTargetControlOffsets");if(a&&a[n]){let o=a[n];s=[{x:i.x+o[0].x,y:i.y+o[0].y},{x:e.x+o[1].x,y:e.y+o[1].y}]}else s=Vo(i.x,i.y,e.x,e.y);return{path:rh(i,e,s[0],s[1]),controlPoints:s}},$u=(i,e)=>{let t=Vo(i.x,i.y,e.x,e.y);return[{x:t[0].x-i.x,y:t[0].y-i.y},{x:t[1].x-e.x,y:t[1].y-e.y}]}});function gE(i,e){let{associativeLineActiveColor:t}=this.getStyleConfig(i,e);this.controlLine1=this.associativeLineDraw.line().stroke({color:t,width:2}),this.controlLine2=this.associativeLineDraw.line().stroke({color:t,width:2}),this.controlPoint1=this.createOneControlNode("controlPoint1",i,e),this.controlPoint2=this.createOneControlNode("controlPoint2",i,e)}function xE(i,e,t){let{associativeLineActiveColor:r}=this.getStyleConfig(e,t);return this.associativeLineDraw.circle(this.controlPointDiameter).stroke({color:r}).fill({color:"#fff"}).click(n=>{n.stopPropagation()}).mousedown(n=>{this.onControlPointMousedown(n,i)})}function yE(i,e){i.stopPropagation(),i.preventDefault(),this.isControlPointMousedown=!0,this.mousedownControlPointKey=e}function vE(i){if(!this.isControlPointMousedown||!this.mousedownControlPointKey||!this[this.mousedownControlPointKey])return;i.stopPropagation(),i.preventDefault();let e=this.controlPointDiameter/2,{x:t,y:r}=this.getTransformedEventPos(i);this.controlPointMousemoveState.pos={x:t,y:r},this[this.mousedownControlPointKey].x(t-e).y(r-e);let[,,,n,s]=this.activeLine,a=Go(n,s),{associativeLinePoint:o,associativeLineTargetControlOffsets:l}=n.getData();o=o||[];let h=this.getNodePos(n),d=this.getNodePos(s),[c,f]=this.updateAllLinesPos(n,s,o[a]);this.controlPointMousemoveState.startPoint=c,this.controlPointMousemoveState.endPoint=f,this.controlPointMousemoveState.targetIndex=a;let m=[];l?m=l[a]:m=$u(c,f);let g=null,x=null,{x:y,y:b}=this.mindMap.toPos(i.clientX,i.clientY),S={clientX:y,clientY:b};this.mousedownControlPointKey==="controlPoint1"?(c=kr(h,"",0,S),g={x:t,y:r},x={x:f.x+m[1].x,y:f.y+m[1].y},c&&(this.controlPointMousemoveState.startPoint=c,this.controlLine1.plot(c.x,c.y,g.x,g.y))):(f=kr(d,"",0,S),g={x:c.x+m[0].x,y:c.y+m[0].y},x={x:t,y:r},f&&(this.controlPointMousemoveState.endPoint=f,this.controlLine2.plot(f.x,f.y,x.x,x.y))),this.updataAassociativeLine(c,f,g,x,this.activeLine)}function bE(i,e,t,r,n){let[s,a,o]=n,l=rh(i,e,t,r);s.plot(l),a.plot(l),this.updateTextPos(s,o),this.updateTextEditBoxPos(o)}function wE(i){if(!this.isControlPointMousedown)return;i.stopPropagation(),i.preventDefault();let{pos:e,startPoint:t,endPoint:r,targetIndex:n}=this.controlPointMousemoveState,[,,,s]=this.activeLine,a=[],{associativeLinePoint:o,associativeLineTargetControlOffsets:l}=s.getData();o||(o=[]),o[n]=o[n]||{startPoint:t,endPoint:r},l?a=l:a[n]=$u(t,r);let h=null,d=null;this.mousedownControlPointKey==="controlPoint1"?(h={x:e.x-t.x,y:e.y-t.y},d=a[n][1],o[n].startPoint=t):(h=a[n][0],d={x:e.x-r.x,y:e.y-r.y},o[n].endPoint=r),a[n]=[h,d],this.mindMap.execCommand("SET_NODE_DATA",s,{associativeLineTargetControlOffsets:a,associativeLinePoint:o}),this.isNotRenderAllLines=!0,setTimeout(()=>{this.resetControlPoint()},0)}function ME(){this.isControlPointMousedown=!1,this.mousedownControlPointKey="",this.controlPointMousemoveState={pos:null,startPoint:null,endPoint:null,targetIndex:""}}function TE(i,e,t,r,n,s){if(!this.mindMap.opt.enableAdjustAssociativeLinePoints)return;this.controlLine1||this.createControlNodes(n,s);let a=this.controlPointDiameter/2;this.controlLine1.plot(i.x,i.y,t.x,t.y),this.controlLine2.plot(e.x,e.y,r.x,r.y),this.controlPoint1.x(t.x-a).y(t.y-a),this.controlPoint2.x(r.x-a).y(r.y-a)}function NE(){this.controlLine1&&([this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.remove()}),this.controlLine1=null,this.controlLine2=null,this.controlPoint1=null,this.controlPoint2=null)}function EE(){this.controlLine1&&[this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.hide()})}function SE(){this.controlLine1&&[this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.show()})}var Gu,g6=T(()=>{ju();Gu={createControlNodes:gE,createOneControlNode:xE,onControlPointMousedown:yE,onControlPointMousemove:vE,onControlPointMouseup:wE,resetControlPoint:ME,renderControls:TE,removeControls:NE,hideControls:EE,showControls:SE,updataAassociativeLine:bE}});function kE(i){let e=this.associativeLineDraw.group(),t=()=>{(!this.activeLine||this.activeLine[3]!==i.node||this.activeLine[4]!==i.toNode)&&this.setActiveLine({...i,text:e})};return e.click(r=>{r.stopPropagation(),t()}),e.on("dblclick",r=>{r.stopPropagation(),t(),this.activeLine&&this.showEditTextBox(e)}),e}function CE(i){this.mindMap.emit("before_show_text_edit"),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.className=AE,this.textEditNode.style.cssText="position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);padding: 3px 5px;margin-left: -5px;margin-top: -3px;outline: none; word-break: break-all;",this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",f=>{f.stopPropagation()}),this.textEditNode.addEventListener("click",f=>{f.stopPropagation()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let[,,,e,t]=this.activeLine,{associativeLineTextFontSize:r,associativeLineTextFontFamily:n,associativeLineTextLineHeight:s}=this.getStyleConfig(e,t),{defaultAssociativeLineText:a,nodeTextEditZIndex:o}=this.mindMap.opt,l=this.mindMap.view.scale,h=this.getText(e,t),d=(h||a).split(/\n/gim);this.textEditNode.style.fontFamily=n,this.textEditNode.style.fontSize=r*l+"px",this.textEditNode.style.lineHeight=d.length>1?s:"normal",this.textEditNode.style.zIndex=o,this.textEditNode.innerHTML=d.join("
    "),this.textEditNode.style.display="block",this.updateTextEditBoxPos(i),this.setIsShowTextEdit(!0),h===""||h===a?la(this.textEditNode):oa(this.textEditNode)}function _E(i){this.showTextEdit=i,i?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}function LE(){if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}function IE(){this.hideEditTextBox()}function zE(i){let e=i.node.getBoundingClientRect();this.textEditNode&&(this.textEditNode.style.minWidth=`${e.width+10}px`,this.textEditNode.style.minHeight=`${e.height+6}px`,this.textEditNode.style.left=`${e.left}px`,this.textEditNode.style.top=`${e.top}px`)}function RE(){if(!this.showTextEdit)return;let[i,,e,t,r]=this.activeLine,n=na(this.textEditNode.innerHTML);n=n===this.mindMap.opt.defaultAssociativeLineText?"":n,this.mindMap.execCommand("SET_NODE_DATA",t,{associativeLineText:{...t.getData("associativeLineText")||{},[r.getData("uid")]:n}}),this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.setIsShowTextEdit(!1),this.renderText(n,i,e,t,r),this.mindMap.emit("hide_text_edit")}function DE(i,e){let t=i.getData("associativeLineText");return t&&t[e.getData("uid")]||""}function OE(i,e,t,r,n){if(!i)return;let{associativeLineTextFontSize:s,associativeLineTextLineHeight:a}=this.getStyleConfig(r,n);t.clear(),i.replace(/\n$/g,"").split(/\n/gim).forEach((l,h)=>{l===""&&(l="\uFEFF");let d=new Ce().text(l);d.y(s*a*h),this.styleText(d,r,n),t.add(d)}),x6(e,t)}function BE(i,e,t){let{associativeLineTextColor:r,associativeLineTextFontSize:n,associativeLineTextFontFamily:s}=this.getStyleConfig(e,t);i.fill({color:r}).css({"font-family":s,"font-size":n+"px"})}function x6(i,e){let t=i.length(),r=i.pointAt(t/2),{width:n,height:s}=e.bbox();e.x(r.x-n/2),e.y(r.y-s/2)}var AE,Vu,y6=T(()=>{yt();pe();AE="associative-line-text-edit-warp";Vu={getText:DE,createText:kE,styleText:BE,onScale:IE,showEditTextBox:CE,setIsShowTextEdit:_E,removeTextEditEl:LE,hideEditTextBox:RE,updateTextEditBoxPos:zE,renderText:OE,updateTextPos:x6}});var v6={};tt(v6,{default:()=>FE});var PE,Wu,nh,FE,b6=T(()=>{pe();Hc();ju();g6();y6();PE=["associativeLineWidth","associativeLineColor","associativeLineActiveWidth","associativeLineActiveColor","associativeLineDasharray","associativeLineTextColor","associativeLineTextFontSize","associativeLineTextLineHeight","associativeLineTextFontFamily"],Wu="associative-line-text-edit-warp",nh=class{constructor(e={}){this.mindMap=e.mindMap,this.associativeLineDraw=this.mindMap.associativeLineDraw,this.isNotRenderAllLines=!1,this.lineList=[],this.activeLine=null,this.isCreatingLine=!1,this.creatingStartNode=null,this.creatingLine=null,this.overlapNode=null,this.isNodeDragging=!1,this.controlLine1=null,this.controlLine2=null,this.controlPoint1=null,this.controlPoint2=null,this.controlPointDiameter=10,this.isControlPointMousedown=!1,this.mousedownControlPointKey="",this.controlPointMousemoveState={pos:null,startPoint:null,endPoint:null,targetIndex:""},this.checkOverlapNode=Si(this.checkOverlapNode,100,this),Object.keys(Gu).forEach(t=>{this[t]=Gu[t].bind(this)}),this.showTextEdit=!1,Object.keys(Vu).forEach(t=>{this[t]=Vu[t].bind(this)}),this.mindMap.addEditNodeClass(Wu),this.bindEvent()}bindEvent(){this.renderAllLines=this.renderAllLines.bind(this),this.onDrawClick=this.onDrawClick.bind(this),this.onNodeClick=this.onNodeClick.bind(this),this.removeLine=this.removeLine.bind(this),this.addLine=this.addLine.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onNodeDragging=this.onNodeDragging.bind(this),this.onNodeDragend=this.onNodeDragend.bind(this),this.onControlPointMouseup=this.onControlPointMouseup.bind(this),this.onBeforeDestroy=this.onBeforeDestroy.bind(this),this.mindMap.on("node_tree_render_end",this.renderAllLines),this.mindMap.on("data_change",this.renderAllLines),this.mindMap.on("draw_click",this.onDrawClick),this.mindMap.on("node_click",this.onNodeClick),this.mindMap.on("contextmenu",this.onDrawClick),this.mindMap.keyCommand.addShortcut("Del|Backspace",this.removeLine),this.mindMap.command.add("ADD_ASSOCIATIVE_LINE",this.addLine),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("node_dragging",this.onNodeDragging),this.mindMap.on("node_dragend",this.onNodeDragend),this.mindMap.on("mouseup",this.onControlPointMouseup),this.mindMap.on("scale",this.onScale),this.mindMap.on("beforeDestroy",this.onBeforeDestroy)}unBindEvent(){this.mindMap.off("node_tree_render_end",this.renderAllLines),this.mindMap.off("data_change",this.renderAllLines),this.mindMap.off("draw_click",this.onDrawClick),this.mindMap.off("node_click",this.onNodeClick),this.mindMap.off("contextmenu",this.onDrawClick),this.mindMap.keyCommand.removeShortcut("Del|Backspace",this.removeLine),this.mindMap.command.remove("ADD_ASSOCIATIVE_LINE",this.addLine),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("node_dragging",this.onNodeDragging),this.mindMap.off("node_dragend",this.onNodeDragend),this.mindMap.off("mouseup",this.onControlPointMouseup),this.mindMap.off("scale",this.onScale),this.mindMap.off("beforeDestroy",this.onBeforeDestroy)}getStyleConfig(e,t){let r={};t&&(r=(e.getData("associativeLineStyle")||{})[t.getData("uid")]||{});let n={};return PE.forEach(s=>{typeof r[s]<"u"?n[s]=r[s]:n[s]=e.getStyle(s)}),n}onBeforeDestroy(){this.hideEditTextBox(),this.removeTextEditEl()}onDrawClick(){this.isCreatingLine&&this.cancelCreateLine(),this.isControlPointMousedown||(this.clearActiveLine(),this.renderAllLines())}onNodeClick(e){this.isCreatingLine?this.completeCreateLine(e):(this.clearActiveLine(),this.renderAllLines())}createMarker(e=()=>{}){return this.associativeLineDraw.marker(20,20,t=>{t.ref(12,5),t.size(10,10),t.attr("orient","auto-start-reverse"),e(t.path("M0,0 L2,5 L0,10 L10,5 Z"))})}updateAllLinesPos(e,t,r){r=r||{};let[n,s]=Uu(e,t),a=0,o="",l=0,h="";return r.startPoint&&(a=r.startPoint.range||0,o=r.startPoint.dir||"right",n=kr(e,o,a)),r.endPoint&&(l=r.endPoint.range||0,h=r.endPoint.dir||"right",s=kr(t,h,l)),[n,s]}renderAllLines(){if(this.isNotRenderAllLines){this.isNotRenderAllLines=!1;return}this.removeAllLines(),this.removeControls(),this.clearActiveLine();let e=this.mindMap.renderer.root;if(!e)return;let t=new Map,r=new Map;de(e,null,n=>{if(!n)return;let s=n.getData();s.associativeLineTargets&&s.associativeLineTargets.length>0&&r.set(n,s.associativeLineTargets),s.uid&&t.set(s.uid,n)},()=>{},!0,0),r.forEach((n,s)=>{n.forEach((a,o)=>{let l=t.get(a);if(!s||!l)return;let h=(s.getData("associativeLinePoint")||[])[o],[d,c]=this.updateAllLinesPos(s,l,h);this.drawLine(d,c,s,l)})})}drawLine(e,t,r,n){let{associativeLineWidth:s,associativeLineColor:a,associativeLineActiveWidth:o,associativeLineDasharray:l}=this.getStyleConfig(r,n),h=null,d=this.createMarker(y=>{h=y});h.stroke({color:a}).fill({color:a});let{path:c,controlPoints:f}=p6(e,t,r,n),m=this.associativeLineDraw.path();m.stroke({width:s,color:a,dasharray:l||"6,4"}).fill({color:"none"}),m.plot(c),m.marker("end",d);let g=this.associativeLineDraw.path();g.stroke({width:o,color:"transparent"}).fill({color:"none"}),g.plot(c);let x=this.createText({path:m,clickPath:g,markerPath:h,node:r,toNode:n,startPoint:e,endPoint:t,controlPoints:f});g.click(y=>{y.stopPropagation(),this.setActiveLine({path:m,clickPath:g,markerPath:h,text:x,node:r,toNode:n,startPoint:e,endPoint:t,controlPoints:f})}),g.dblclick(()=>{this.activeLine&&this.showEditTextBox(x)}),this.renderText(this.getText(r,n),m,x,r,n),this.lineList.push([m,g,x,r,n])}updateActiveLineStyle(){if(!this.activeLine)return;this.isNotRenderAllLines=!0;let[e,t,r,n,s,a]=this.activeLine,{associativeLineWidth:o,associativeLineColor:l,associativeLineDasharray:h,associativeLineActiveWidth:d,associativeLineActiveColor:c,associativeLineTextColor:f,associativeLineTextFontFamily:m,associativeLineTextFontSize:g}=this.getStyleConfig(n,s);e.stroke({width:o,color:l,dasharray:h||"6,4"}).fill({color:"none"}),t.stroke({width:d,color:c}).fill({color:"none"}),a.stroke({color:l}).fill({color:l}),r.find("text").forEach(x=>{x.fill({color:f}).css({"font-family":m,"font-size":g+"px"})}),this.controlLine1&&this.controlLine1.stroke({color:c}),this.controlLine2&&this.controlLine2.stroke({color:c}),this.controlPoint1&&this.controlPoint1.stroke({color:c}),this.controlPoint2&&this.controlPoint2.stroke({color:c}),this.updateTextPos(e,r)}setActiveLine({path:e,clickPath:t,markerPath:r,text:n,node:s,toNode:a,startPoint:o,endPoint:l,controlPoints:h}){let{associativeLineActiveColor:d}=this.getStyleConfig(s,a);this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.clearActiveLine(),this.activeLine=[e,t,n,s,a,r],t.stroke({color:d}),this.getText(s,a)||this.renderText(this.mindMap.opt.defaultAssociativeLineText,e,n,s,a),this.renderControls(o,l,h[0],h[1],s,a),this.mindMap.emit("associative_line_click",e,t,s,a),this.front()}removeAllLines(){this.lineList.forEach(e=>{e[0].remove(),e[1].remove(),e[2].remove()}),this.lineList=[]}createLineFromActiveNode(){if(this.mindMap.renderer.activeNodeList.length<=0)return;let e=this.mindMap.renderer.activeNodeList[0];this.createLine(e)}createLine(e){let{associativeLineWidth:t,associativeLineColor:r,associativeLineDasharray:n}=this.getStyleConfig(e);if(this.isCreatingLine||!e)return;this.front(),this.isCreatingLine=!0,this.creatingStartNode=e,this.creatingLine=this.associativeLineDraw.path(),this.creatingLine.stroke({width:t,color:r,dasharray:n||"6,4"}).fill({color:"none"});let s=null,a=this.createMarker(o=>{s=o});s.stroke({color:r}).fill({color:r}),this.creatingLine.marker("end",a)}cancelCreateLine(){this.isCreatingLine=!1,this.creatingStartNode=null,this.creatingLine.remove(),this.creatingLine=null,this.overlapNode=null,this.back()}onMousemove(e){this.onControlPointMousemove(e),this.updateCreatingLine(e)}updateCreatingLine(e){if(!this.isCreatingLine)return;let{x:t,y:r}=this.getTransformedEventPos(e),n=kr(this.creatingStartNode),s=t>n.x?-10:10,a=m6(n.x,n.y,t+s,r);this.creatingLine.plot(a),this.checkOverlapNode(t,r)}getTransformedEventPos(e){let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY),{scaleX:n,scaleY:s,translateX:a,translateY:o}=this.mindMap.draw.transform();return{x:(t-a)/n,y:(r-o)/s}}getNodePos(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.mindMap.draw.transform(),{left:a,top:o,width:l,height:h}=e,d=a*t+n,c=o*r+s;return{left:a,top:o,translateLeft:d,translateTop:c,width:l,height:h}}checkOverlapNode(e,t){this.overlapNode=null,Xt(this.mindMap.renderer.root,r=>{if(r.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",r,!1),r.uid===this.creatingStartNode.uid||this.overlapNode)return;let{left:n,top:s,width:a,height:o}=r,l=n+a,h=s+o;e>=n&&e<=l&&t>=s&&t<=h&&(this.overlapNode=r)}),this.overlapNode&&!this.overlapNode.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)}completeCreateLine(e){if(this.creatingStartNode.uid===e.uid)return;let{beforeAssociativeLineConnection:t}=this.mindMap.opt,r=!1;typeof t=="function"&&(r=t(e)),!r&&(this.addLine(this.creatingStartNode,e),this.overlapNode&&this.overlapNode.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!1),this.cancelCreateLine())}addLine(e,t){if(!e||!t)return;let r=t.getData("uid");r||(r=fo(),this.mindMap.execCommand("SET_NODE_DATA",t,{uid:r}));let n=e.getData("associativeLineTargets")||[];if(n.some(f=>f===r))return;n.push(r);let[a,o]=Uu(e,t),l=Vo(a.x,a.y,o.x,o.y),{associativeLineInitPointsPosition:h}=this.mindMap.opt;if(h){let{from:f,to:m}=h;f&&(a.dir=f),m&&(o.dir=m)}let d=e.getData("associativeLineTargetControlOffsets")||[];d[n.length-1]=[{x:l[0].x-a.x,y:l[0].y-a.y},{x:l[1].x-o.x,y:l[1].y-o.y}];let c=e.getData("associativeLinePoint")||[];c[n.length-1]={startPoint:a,endPoint:o},this.mindMap.execCommand("SET_NODE_DATA",e,{associativeLineTargets:n,associativeLineTargetControlOffsets:d,associativeLinePoint:c})}removeLine(){if(!this.activeLine)return;let[,,,e,t]=this.activeLine;this.removeControls();let{associativeLineTargets:r,associativeLinePoint:n,associativeLineTargetControlOffsets:s,associativeLineText:a,associativeLineStyle:o}=e.getData();n=n||[];let l=Go(e,t),h={};a&&Object.keys(a).forEach(c=>{c!==t.getData("uid")&&(h[c]=a[c])});let d={};o&&Object.keys(o).forEach(c=>{c!==t.getData("uid")&&(d[c]=o[c])}),this.mindMap.execCommand("SET_NODE_DATA",e,{associativeLineTargets:r.filter((c,f)=>f!==l),associativeLinePoint:n.filter((c,f)=>f!==l),associativeLineTargetControlOffsets:s?s.filter((c,f)=>f!==l):[],associativeLineText:h,associativeLineStyle:d})}clearActiveLine(){if(this.activeLine){let[,e,t,r,n]=this.activeLine;e.stroke({color:"transparent"}),this.hideEditTextBox(),this.getText(r,n)||t.clear(),this.activeLine=null,this.removeControls(),this.back(),this.mindMap.emit("associative_line_deactivate")}}onNodeDragging(){this.isNodeDragging||(this.isNodeDragging=!0,this.lineList.forEach(e=>{e[0].hide(),e[1].hide(),e[2].hide()}),this.hideControls())}onNodeDragend(){this.isNodeDragging&&(this.lineList.forEach(e=>{e[0].show(),e[1].show(),e[2].show()}),this.showControls(),this.isNodeDragging=!1)}front(){this.mindMap.opt.associativeLineIsAlwaysAboveNode||this.associativeLineDraw.front()}back(){this.mindMap.opt.associativeLineIsAlwaysAboveNode||(this.associativeLineDraw.back(),this.associativeLineDraw.forward())}beforePluginRemove(){this.mindMap.deleteEditNodeClass(Wu),this.unBindEvent()}beforePluginDestroy(){this.mindMap.deleteEditNodeClass(Wu),this.unBindEvent()}};nh.instanceName="associativeLine";FE=nh});var w6={};tt(w6,{default:()=>qE});var sh,qE,M6=T(()=>{pe();X0();$e();sh=class{constructor({mindMap:e}){this.mindMap=e,this.isSearching=!1,this.searchText="",this.matchNodeList=[],this.currentIndex=-1,this.notResetSearchText=!1,this.isJumpNext=!1,this.bindEvent()}bindEvent(){this.onDataChange=this.onDataChange.bind(this),this.onModeChange=this.onModeChange.bind(this),this.mindMap.on("data_change",this.onDataChange),this.mindMap.on("mode_change",this.onModeChange)}unBindEvent(){this.mindMap.off("data_change",this.onDataChange),this.mindMap.off("mode_change",this.onModeChange)}onDataChange(){if(this.isJumpNext){this.isJumpNext=!1,this.search(this.searchText);return}if(this.notResetSearchText){this.notResetSearchText=!1;return}this.searchText=""}onModeChange(e){!(e===k.MODE.READONLY)&&this.isSearching&&this.matchNodeList[this.currentIndex]&&this.matchNodeList[this.currentIndex].closeHighlight()}search(e,t=()=>{}){if(Yt(e))return this.endSearch();e=String(e),this.isSearching=!0,this.searchText===e?this.searchNext(t):(this.searchText=e,this.doSearch(),this.searchNext(t)),this.emitEvent()}updateMatchNodeList(e){this.matchNodeList=e,this.mindMap.emit("search_match_node_list_change",e)}endSearch(){this.isSearching&&(this.mindMap.opt.readonly&&this.matchNodeList[this.currentIndex]&&this.matchNodeList[this.currentIndex].closeHighlight(),this.searchText="",this.updateMatchNodeList([]),this.currentIndex=-1,this.notResetSearchText=!1,this.isSearching=!1,this.emitEvent())}doSearch(){this.clearHighlightOnReadonly(),this.updateMatchNodeList([]),this.currentIndex=-1;let{isOnlySearchCurrentRenderNodes:e}=this.mindMap.opt,t=e?this.mindMap.renderer.root:this.mindMap.renderer.renderTree;if(!t)return;let r=[];Xt(t,n=>{let{richText:s,text:a,generalization:o}=e?n.getData():n.data;s&&(a=sa(a)),a.includes(this.searchText)&&r.push(n),us({generalization:o}).forEach(h=>{let{richText:d,text:c,uid:f}=h;e&&!this.mindMap.renderer.findNodeByUid(f)||(d&&(c=sa(c)),c.includes(this.searchText)&&r.push({data:h}))})}),this.updateMatchNodeList(r)}isNodeInstance(e){return e instanceof da}searchNext(e,t){if(!this.isSearching||this.matchNodeList.length<=0)return;t!==void 0&&Number.isInteger(t)&&t>=0&&t{this.isNodeInstance(n)||(this.matchNodeList[this.currentIndex]=o,this.updateMatchNodeList(this.matchNodeList)),e(),r&&o.highlight(),a&&(this.notResetSearchText=!1)})}clearHighlightOnReadonly(){let{readonly:e}=this.mindMap.opt;e&&this.matchNodeList.forEach(t=>{this.isNodeInstance(t)&&t.closeHighlight()})}jump(e,t=()=>{}){this.searchNext(t,e)}replace(e,t=!1){if(e==null||!this.isSearching||this.matchNodeList.length<=0)return;this.isJumpNext=t,e=String(e);let r=this.matchNodeList[this.currentIndex];if(!r)return;let n=e.includes(this.searchText),s=this.getReplacedText(r,this.searchText,e);if(this.notResetSearchText=!0,r.setText(s,r.getData("richText")),n){this.updateMatchNodeList(this.matchNodeList);return}let a=this.matchNodeList.filter(o=>r!==o);this.updateMatchNodeList(a),this.currentIndex>this.matchNodeList.length-1?this.currentIndex=-1:this.currentIndex--,this.emitEvent()}replaceAll(e){if(e==null||!this.isSearching||this.matchNodeList.length<=0)return;e=String(e);let t=e.includes(this.searchText);this.notResetSearchText=!0,this.matchNodeList.forEach(r=>{let n=this.getReplacedText(r,this.searchText,e);if(this.isNodeInstance(r)){let s={text:n};this.mindMap.renderer.setNodeDataRender(r,s,!0)}else r.data.text=n}),this.mindMap.render(),this.mindMap.command.addHistory(),t?this.updateMatchNodeList(this.matchNodeList):this.endSearch()}getReplacedText(e,t,r){let{richText:n,text:s}=this.isNodeInstance(e)?e.getData():e.data;return n?M2(s,t,r):s.replace(new RegExp(t,"g"),r)}emitEvent(){this.mindMap.emit("search_info_change",{currentIndex:this.currentIndex,total:this.matchNodeList.length})}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};sh.instanceName="search";qE=sh});var T6,N6,E6=T(()=>{pe();T6=i=>{i=ds(i);let e={},t={};i.forEach(n=>{let s=n.parent;if(s){let a=s.uid;t[a]=s;let o=n.getIndexInBrothers(),l={node:n,index:o};e[a]?e[a].find(h=>h.index===l.index)||e[a].push(l):e[a]=[l]}});let r=[];return Object.keys(e).forEach(n=>{let s=e[n],a=t[n];if(s.length>1){let o=s.map(f=>f.index).sort((f,m)=>f-m),l=o[0],h=o[o.length-1],d=-1,c=-1;for(let f=l;f<=h;f++)o.includes(f)?(d===-1&&(d=f),c=f):(d!==-1&&c!==-1&&r.push({node:a,range:[d,c]}),d=-1,c=-1);d!==-1&&c!==-1&&r.push({node:a,range:[d,c]})}else r.push({node:a,range:[s[0].index,s[0].index]})}),r},N6=i=>{let e=i.children;if(!e||e.length<=0)return;let t=[],r={};return e.forEach((n,s)=>{let a=n.getData("outerFrame");if(!a)return;let o=a.groupId;o?(r[o]||(r[o]=[]),r[o].push({node:n,index:s})):t.push({nodeList:[n],range:[s,s]})}),Object.keys(r).forEach(n=>{let s=r[n];t.push({nodeList:s.map(a=>a.node),range:[s[0].index,s[s.length-1].index]})}),t}});function UE(i,e,t){let r=this.draw.group(),n=()=>{(!this.activeOuterFrame||this.activeOuterFrame.el!==i)&&this.setActiveOuterFrame(i,e,t,r)};return r.click(s=>{s.stopPropagation(),n()}),r.on("dblclick",s=>{s.stopPropagation(),n(),this.showEditTextBox(r)}),r}function $E(i){this.mindMap.emit("before_show_text_edit"),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.className=HE,this.textEditNode.style.cssText=` +`},()=>{},!0),e}});var T6={};tt(T6,{default:()=>BE});var hh,BE,N6=T(()=>{pe();wt();y6();b6();Ge();M6();hh=class{constructor(e){this.mindMap=e.mindMap}async export(e,t=!0,r="\u601D\u7EF4\u5BFC\u56FE",...n){if(this[e]){let s=await this[e](r,...n);return t&&k2(s,r+"."+e),s}else return null}createTransformImgTaskList(e,t,r,n){return e.find(t).map(async a=>{let o=n(a);if(/^data:/.test(o)||o==="none")return;let l=await Nu(o);a.attr(r,l)})}async getSvgData(e){let{exportPaddingX:t,exportPaddingY:r,errorHandler:n,resetCss:s,addContentToHeader:a,addContentToFooter:o,handleBeingExportSvg:l}=this.mindMap.opt,{svg:h,svgHTML:d,clipData:c}=this.mindMap.getSvgData({paddingX:t,paddingY:r,addContentToHeader:a,addContentToFooter:o,node:e});c&&(c.paddingX=t,c.paddingY=r);let f=!1,m=this.createTransformImgTaskList(h,"image","href",y=>y.attr("href")||y.attr("xlink:href")),g=this.createTransformImgTaskList(h,"img","src",y=>y.attr("src")),x=[...m,...g];try{await Promise.all(x)}catch(y){n(Ti.EXPORT_LOAD_IMAGE_ERROR,y)}if(this.mindMap.richText){let y=h.find("foreignObject");if(y.length>0&&(y[0].add(ke(``)),f=!0),this.mindMap.formula&&h.find(".ql-formula").length>0){let E=this.mindMap.formula.getStyleText();if(E){let k=document.createElement("style");k.innerHTML=E,sr(k),y[0].add(k),f=!0}}}return typeof l=="function"&&(f=!0,h=l(h)),(x.length>0||f)&&(d=h.svg()),{node:h,str:d,clipData:c}}svgToPng(e,t,r=null,n=!1,s="image/png"){let{maxCanvasSize:a,minExportImgCanvasScale:o}=this.mindMap.opt;return new Promise((l,h)=>{let d=new Image;d.setAttribute("crossOrigin","anonymous"),d.onload=async()=>{try{let c=document.createElement("canvas"),f=Math.max(window.devicePixelRatio,o),m=d.width,g=d.height,x=0,y=0;r&&(x=r.paddingX,y=r.paddingY,m=r.width+x*2,g=r.height+y*2);let b=0,E=0,{backgroundImage:k}=this.mindMap.themeConfig;if(n&&k&&!t){let Ce=await new Promise(te=>{let Q=new Image;Q.onload=()=>{te([Q.width,Q.height])},Q.onerror=()=>{te(null)},Q.src=k});if(Ce){let te=m/g,Q=Ce[0]/Ce[1];te>Q?(b=m,E=m/Q):(E=g,b=g*Q)}}let L=1,I=1,O=(b||m)*f,q=(E||g)*f;if(O>a||q>a){let Ce=null,te=null;O>a?Ce=a:q>a&&(te=a);let Q=K0(O,q,Ce,te);L=Q[0]/O,I=Q[1]/q,O=Q[0],q=Q[1]}c.width=O,c.height=q;let F=O/f,W=q/f;c.style.width=F+"px",c.style.height=W+"px";let ne=c.getContext("2d");ne.scale(f,f),t||await this.drawBackgroundToCanvas(ne,F,W);let re=(b>0?(b-m)/2:0)*L,le=(E>0?(E-g)/2:0)*I;r?ne.drawImage(d,r.left,r.top,r.width,r.height,x*L+re,y*I+le,r.width*L,r.height*I):ne.drawImage(d,re,le,m*L,g*I),l(c.toDataURL(s))}catch(c){h(c)}},d.onerror=c=>{h(c)},d.src=e})}drawBackgroundToCanvas(e,t,r){return new Promise((n,s)=>{let{backgroundColor:a="#fff",backgroundImage:o,backgroundRepeat:l="no-repeat",backgroundPosition:h="center center",backgroundSize:d="cover"}=this.mindMap.themeConfig;e.save(),e.rect(0,0,t,r),e.fillStyle=a,e.fill(),e.restore(),o&&o!=="none"?(e.save(),x6(e,t,r,o,{backgroundRepeat:l,backgroundPosition:h,backgroundSize:d},c=>{c?s(c):n(),e.restore()})):n()})}drawBackgroundToSvg(e){return new Promise(async t=>{let{backgroundColor:r="#fff",backgroundImage:n,backgroundRepeat:s="repeat"}=this.mindMap.themeConfig;if(e.css("background-color",r),n&&n!=="none"){let a=await Nu(n);e.css("background-image",`url(${a})`),e.css("background-repeat",s),t()}else t()})}async _image(e,t,r=!1,n=null,s=!1){this.mindMap.renderer.textEdit.hideEditTextBox(),this.handleNodeExport(n);let{str:a,clipData:o}=await this.getSvgData(n),l=await this.fixSvgStrAndToBlob(a);return await this.svgToPng(l,r,o,s,e)}async png(...e){return await this._image("image/png",...e)}async jpg(...e){return await this._image("image/jpg",...e)}handleNodeExport(e){if(e&&e.getData("isActive")){e.deactivate();let{alwaysShowExpandBtn:t,notShowExpandBtn:r}=this.mindMap.opt;!t&&!r&&e.getData("expand")&&e.removeExpandBtn()}}async pdf(e,t=!1,r=!1){if(!this.mindMap.doExportPDF)throw new Error("\u8BF7\u6CE8\u518CExportPDF\u63D2\u4EF6");let n=await this.png(e,t,null,r);return await this.mindMap.doExportPDF.pdf(n)}async xmind(e){if(!this.mindMap.doExportXMind)throw new Error("\u8BF7\u6CE8\u518CExportXMind\u63D2\u4EF6");let t=this.mindMap.getData(),r=await this.mindMap.doExportXMind.xmind(t,e);return await oa(r)}async svg(e){this.mindMap.renderer.textEdit.hideEditTextBox();let{node:t}=await this.getSvgData();t.first().before(ke(`${e}`)),await this.drawBackgroundToSvg(t);let r=t.svg();return await this.fixSvgStrAndToBlob(r)}async fixSvgStrAndToBlob(e){e=R2(e),e=j2(e);let t=new Blob([e],{type:"image/svg+xml"});return await oa(t)}async json(e,t=!0){let r=this.mindMap.getData(t),n=JSON.stringify(r),s=new Blob([n]);return await oa(s)}async smm(e,t){return await this.json(e,t)}async md(){let e=this.mindMap.getData(),t=v6(e),r=new Blob([t]);return await oa(r)}async txt(){let e=this.mindMap.getData(),t=w6(e),r=new Blob([t]);return await oa(r)}};hh.instanceName="doExport";BE=hh});var E6={};tt(E6,{default:()=>PE});var dh,PE,S6=T(()=>{pe();Yu();dh=class{constructor({mindMap:e}){this.mindMap=e,this.rect=null,this.isMousedown=!1,this.mouseDownX=0,this.mouseDownY=0,this.mouseMoveX=0,this.mouseMoveY=0,this.isSelecting=!1,this.cacheActiveList=[],this.autoMove=new nh(e),this.bindEvent()}bindEvent(){this.onMousedown=this.onMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.checkInNodes=Ai(this.checkInNodes,300,this),this.mindMap.on("mousedown",this.onMousedown),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("mouseup",this.onMouseup),this.mindMap.on("node_mouseup",this.onMouseup)}unBindEvent(){this.mindMap.off("mousedown",this.onMousedown),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("mouseup",this.onMouseup),this.mindMap.off("node_mouseup",this.onMouseup)}onMousedown(e){let{readonly:t,mousedownEventPreventDefault:r}=this.mindMap.opt;if(t)return;let{useLeftKeySelectionRightKeyDrag:n}=this.mindMap.opt;if(!(e.ctrlKey||e.metaKey)&&(n?e.which!==1:e.which!==3))return;r&&e.preventDefault(),this.isMousedown=!0,this.cacheActiveList=[...this.mindMap.renderer.activeNodeList];let{x:s,y:a}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseDownX=s,this.mouseDownY=a,this.createRect(s,a)}onMousemove(e){if(this.mindMap.opt.readonly||!this.isMousedown)return;let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY);this.mouseMoveX=t,this.mouseMoveY=r,!(Math.abs(t-this.mouseDownX)<=10&&Math.abs(r-this.mouseDownY)<=10)&&(this.autoMove.clearAutoMoveTimer(),this.autoMove.onMove(e.clientX,e.clientY,()=>{this.isSelecting=!0,this.rect&&this.rect.plot([[this.mouseDownX,this.mouseDownY],[this.mouseMoveX,this.mouseDownY],[this.mouseMoveX,this.mouseMoveY],[this.mouseDownX,this.mouseMoveY]]),this.checkInNodes()},(n,s)=>{switch(n){case"left":this.mouseDownX+=s;break;case"top":this.mouseDownY+=s;break;case"right":this.mouseDownX-=s;break;case"bottom":this.mouseDownY-=s;break;default:break}}))}onMouseup(){this.mindMap.opt.readonly||this.isMousedown&&(this.checkTriggerNodeActiveEvent(),this.autoMove.clearAutoMoveTimer(),this.isMousedown=!1,this.cacheActiveList=[],this.rect&&this.rect.remove(),this.rect=null,setTimeout(()=>{this.isSelecting=!1},0))}checkTriggerNodeActiveEvent(){let e=this.cacheActiveList.length!==this.mindMap.renderer.activeNodeList.length,t=!1;if(!e)for(let r=0;rs.getData("uid")===n.getData("uid"))){t=!0;break}}(e||t)&&this.mindMap.renderer.emitNodeActiveEvent()}createRect(e,t){this.rect&&this.rect.remove(),this.rect=this.mindMap.svg.polygon().stroke({color:"#0984e3"}).fill({color:"rgba(9,132,227,0.3)"}).plot([[e,t]])}checkInNodes(){let{scaleX:e,scaleY:t,translateX:r,translateY:n}=this.mindMap.draw.transform(),s=Math.min(this.mouseDownX,this.mouseMoveX),a=Math.min(this.mouseDownY,this.mouseMoveY),o=Math.max(this.mouseDownX,this.mouseMoveX),l=Math.max(this.mouseDownY,this.mouseMoveY),h=d=>{let{left:c,top:f,width:m,height:g}=d,x=(c+m)*e+r,y=(f+g)*t+n;if(c=c*e+r,f=f*t+n,U2(s,o,a,l,c,x,f,y)){if(d.getData("isActive"))return;this.mindMap.renderer.addNodeToActiveList(d),this.mindMap.renderer.emitNodeActiveEvent()}else if(d.getData("isActive")){if(!d.getData("isActive"))return;this.mindMap.renderer.removeNodeFromActiveList(d),this.mindMap.renderer.emitNodeActiveEvent()}};Zt(this.mindMap.renderer.root,d=>{h(d),d._generalizationList&&d._generalizationList.length>0&&d._generalizationList.forEach(c=>{h(c.generalizationNode)})})}hasSelectRange(){return this.isSelecting}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};dh.instanceName="select";PE=dh});var Zo,Qo,ch,A6,k6,FE,kr,Ju,C6,e1,t1=T(()=>{pe();Zo=(i,e)=>i.getData("associativeLineTargets").findIndex(t=>t===e.getData("uid")),Qo=(i,e,t,r)=>{let s=i+(t-i)/2,a=e,o=s,l=r;return Math.abs(i-t)<=5&&(s=i+(r-e)/2,o=s),Math.abs(e-r)<=5&&(s=i,a=e-(t-i)/2,o=t,l=a),[{x:s,y:a},{x:o,y:l}]},ch=(i,e,t,r)=>`M ${i.x},${i.y} C ${t.x},${t.y} ${r.x},${r.y} ${e.x},${e.y}`,A6=i=>{let{left:e,top:t,width:r,height:n}=i;return{right:e+r,bottom:t+n,left:e,top:t,width:r,height:n}},k6=(i,e,t,r)=>{let n=Qo(i,e,t,r);return ch({x:i,y:e},{x:t,y:r},n[0],n[1])},FE=(i,e)=>{let{left:t,top:r,translateLeft:n,translateTop:s,width:a,height:o}=i,l=e.clientX,h=e.clientY,d=n+a/2,c=s+o/2,f=t+a/2,m=r+o/2,g=Math.atan(o/a),x=l-d,y=c-h,b=Math.atan2(y,x),E=t+a,k=r+o;if(b=-g){let O=b*(a/2);return(b=0||b>=-g&&b<0)&&(k=m-O),{x:E,y:k,dir:"right",range:O}}else if(b>=g&&b=g){let q=o/2/b;O=-q,E=f+q}else if(b>=Math.PI/2-g&&b=g-Math.PI){let O=0;if(b>=g-Math.PI/2&&b<-g){let q=o/2/b;O=q,E=f-q}else if(b=g-Math.PI){let q=(d-l)/(c-h),F=o/2*q;O=-F,E=f+F}return{x:E,y:k,dir:"bottom",range:O}}E=t;let I=(c-h)/(d-l)*(a/2);return(b>=-Math.PI&&b=Math.PI-g)&&(k=m-I),{x:E,y:k,dir:"left",range:I}},kr=(i,e="right",t=0,r=null)=>{let{left:n,top:s,width:a,height:o}=i;if(r)return FE(i,r);switch(e){case"left":return{x:n,y:s+o/2-t,dir:e};case"right":return{x:n+a,y:s+o/2-t,dir:e};case"top":return{x:n+a/2-t,y:s,dir:e};case"bottom":return{x:n+a/2-t,y:s+o,dir:e};default:break}},Ju=(i,e)=>{let t=A6(i),r=A6(e),n="",s="";switch(V2({x:t.left,y:t.top,width:t.width,height:t.height},{x:r.left,y:r.top,width:r.width,height:r.height})){case"left-top":n="right",s="top";break;case"right-top":n="left",s="top";break;case"right-bottom":n="left",s="bottom";break;case"left-bottom":n="right",s="bottom";break;case"left":n="right",s="left";break;case"right":n="left",s="right";break;case"top":n="right",s="right";break;case"bottom":n="left",s="left";break;case"overlap":n="right",s="right";break;default:break}return[kr(i,n),kr(e,s)]},C6=(i,e,t,r)=>{let n=Zo(t,r),s=[],a=t.getData("associativeLineTargetControlOffsets");if(a&&a[n]){let o=a[n];s=[{x:i.x+o[0].x,y:i.y+o[0].y},{x:e.x+o[1].x,y:e.y+o[1].y}]}else s=Qo(i.x,i.y,e.x,e.y);return{path:ch(i,e,s[0],s[1]),controlPoints:s}},e1=(i,e)=>{let t=Qo(i.x,i.y,e.x,e.y);return[{x:t[0].x-i.x,y:t[0].y-i.y},{x:t[1].x-e.x,y:t[1].y-e.y}]}});function qE(i,e){let{associativeLineActiveColor:t}=this.getStyleConfig(i,e);this.controlLine1=this.associativeLineDraw.line().stroke({color:t,width:2}),this.controlLine2=this.associativeLineDraw.line().stroke({color:t,width:2}),this.controlPoint1=this.createOneControlNode("controlPoint1",i,e),this.controlPoint2=this.createOneControlNode("controlPoint2",i,e)}function HE(i,e,t){let{associativeLineActiveColor:r}=this.getStyleConfig(e,t);return this.associativeLineDraw.circle(this.controlPointDiameter).stroke({color:r}).fill({color:"#fff"}).click(n=>{n.stopPropagation()}).mousedown(n=>{this.onControlPointMousedown(n,i)})}function UE(i,e){i.stopPropagation(),i.preventDefault(),this.isControlPointMousedown=!0,this.mousedownControlPointKey=e}function $E(i){if(!this.isControlPointMousedown||!this.mousedownControlPointKey||!this[this.mousedownControlPointKey])return;i.stopPropagation(),i.preventDefault();let e=this.controlPointDiameter/2,{x:t,y:r}=this.getTransformedEventPos(i);this.controlPointMousemoveState.pos={x:t,y:r},this[this.mousedownControlPointKey].x(t-e).y(r-e);let[,,,n,s]=this.activeLine,a=Zo(n,s),{associativeLinePoint:o,associativeLineTargetControlOffsets:l}=n.getData();o=o||[];let h=this.getNodePos(n),d=this.getNodePos(s),[c,f]=this.updateAllLinesPos(n,s,o[a]);this.controlPointMousemoveState.startPoint=c,this.controlPointMousemoveState.endPoint=f,this.controlPointMousemoveState.targetIndex=a;let m=[];l?m=l[a]:m=e1(c,f);let g=null,x=null,{x:y,y:b}=this.mindMap.toPos(i.clientX,i.clientY),E={clientX:y,clientY:b};this.mousedownControlPointKey==="controlPoint1"?(c=kr(h,"",0,E),g={x:t,y:r},x={x:f.x+m[1].x,y:f.y+m[1].y},c&&(this.controlPointMousemoveState.startPoint=c,this.controlLine1.plot(c.x,c.y,g.x,g.y))):(f=kr(d,"",0,E),g={x:c.x+m[0].x,y:c.y+m[0].y},x={x:t,y:r},f&&(this.controlPointMousemoveState.endPoint=f,this.controlLine2.plot(f.x,f.y,x.x,x.y))),this.updataAassociativeLine(c,f,g,x,this.activeLine)}function jE(i,e,t,r,n){let[s,a,o]=n,l=ch(i,e,t,r);s.plot(l),a.plot(l),this.updateTextPos(s,o),this.updateTextEditBoxPos(o)}function GE(i){if(!this.isControlPointMousedown)return;i.stopPropagation(),i.preventDefault();let{pos:e,startPoint:t,endPoint:r,targetIndex:n}=this.controlPointMousemoveState,[,,,s]=this.activeLine,a=[],{associativeLinePoint:o,associativeLineTargetControlOffsets:l}=s.getData();o||(o=[]),o[n]=o[n]||{startPoint:t,endPoint:r},l?a=l:a[n]=e1(t,r);let h=null,d=null;this.mousedownControlPointKey==="controlPoint1"?(h={x:e.x-t.x,y:e.y-t.y},d=a[n][1],o[n].startPoint=t):(h=a[n][0],d={x:e.x-r.x,y:e.y-r.y},o[n].endPoint=r),a[n]=[h,d],this.mindMap.execCommand("SET_NODE_DATA",s,{associativeLineTargetControlOffsets:a,associativeLinePoint:o}),this.isNotRenderAllLines=!0,setTimeout(()=>{this.resetControlPoint()},0)}function WE(){this.isControlPointMousedown=!1,this.mousedownControlPointKey="",this.controlPointMousemoveState={pos:null,startPoint:null,endPoint:null,targetIndex:""}}function VE(i,e,t,r,n,s){if(!this.mindMap.opt.enableAdjustAssociativeLinePoints)return;this.controlLine1||this.createControlNodes(n,s);let a=this.controlPointDiameter/2;this.controlLine1.plot(i.x,i.y,t.x,t.y),this.controlLine2.plot(e.x,e.y,r.x,r.y),this.controlPoint1.x(t.x-a).y(t.y-a),this.controlPoint2.x(r.x-a).y(r.y-a)}function YE(){this.controlLine1&&([this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.remove()}),this.controlLine1=null,this.controlLine2=null,this.controlPoint1=null,this.controlPoint2=null)}function XE(){this.controlLine1&&[this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.hide()})}function KE(){this.controlLine1&&[this.controlLine1,this.controlLine2,this.controlPoint1,this.controlPoint2].forEach(i=>{i.show()})}var i1,_6=T(()=>{t1();i1={createControlNodes:qE,createOneControlNode:HE,onControlPointMousedown:UE,onControlPointMousemove:$E,onControlPointMouseup:GE,resetControlPoint:WE,renderControls:VE,removeControls:YE,hideControls:XE,showControls:KE,updataAassociativeLine:jE}});function QE(i){let e=this.associativeLineDraw.group(),t=()=>{(!this.activeLine||this.activeLine[3]!==i.node||this.activeLine[4]!==i.toNode)&&this.setActiveLine({...i,text:e})};return e.click(r=>{r.stopPropagation(),t()}),e.on("dblclick",r=>{r.stopPropagation(),t(),this.activeLine&&this.showEditTextBox(e)}),e}function JE(i){this.mindMap.emit("before_show_text_edit"),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.className=ZE,this.textEditNode.style.cssText="position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);padding: 3px 5px;margin-left: -5px;margin-top: -3px;outline: none; word-break: break-all;",this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",f=>{f.stopPropagation()}),this.textEditNode.addEventListener("click",f=>{f.stopPropagation()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let[,,,e,t]=this.activeLine,{associativeLineTextFontSize:r,associativeLineTextFontFamily:n,associativeLineTextLineHeight:s}=this.getStyleConfig(e,t),{defaultAssociativeLineText:a,nodeTextEditZIndex:o}=this.mindMap.opt,l=this.mindMap.view.scale,h=this.getText(e,t),d=(h||a).split(/\n/gim);this.textEditNode.style.fontFamily=n,this.textEditNode.style.fontSize=r*l+"px",this.textEditNode.style.lineHeight=d.length>1?s:"normal",this.textEditNode.style.zIndex=o,this.textEditNode.innerHTML=d.join("
    "),this.textEditNode.style.display="block",this.updateTextEditBoxPos(i),this.setIsShowTextEdit(!0),h===""||h===a?ha(this.textEditNode):la(this.textEditNode)}function eS(i){this.showTextEdit=i,i?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}function tS(){if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}function iS(){this.hideEditTextBox()}function rS(i){let e=i.node.getBoundingClientRect();this.textEditNode&&(this.textEditNode.style.minWidth=`${e.width+10}px`,this.textEditNode.style.minHeight=`${e.height+6}px`,this.textEditNode.style.left=`${e.left}px`,this.textEditNode.style.top=`${e.top}px`)}function nS(){if(!this.showTextEdit)return;let[i,,e,t,r]=this.activeLine,n=sa(this.textEditNode.innerHTML);n=n===this.mindMap.opt.defaultAssociativeLineText?"":n,this.mindMap.execCommand("SET_NODE_DATA",t,{associativeLineText:{...t.getData("associativeLineText")||{},[r.getData("uid")]:n}}),this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.setIsShowTextEdit(!1),this.renderText(n,i,e,t,r),this.mindMap.emit("hide_text_edit")}function sS(i,e){let t=i.getData("associativeLineText");return t&&t[e.getData("uid")]||""}function aS(i,e,t,r,n){if(!i)return;let{associativeLineTextFontSize:s,associativeLineTextLineHeight:a}=this.getStyleConfig(r,n);t.clear(),i.replace(/\n$/g,"").split(/\n/gim).forEach((l,h)=>{l===""&&(l="\uFEFF");let d=new _e().text(l);d.y(s*a*h),this.styleText(d,r,n),t.add(d)}),L6(e,t)}function oS(i,e,t){let{associativeLineTextColor:r,associativeLineTextFontSize:n,associativeLineTextFontFamily:s}=this.getStyleConfig(e,t);i.fill({color:r}).css({"font-family":s,"font-size":n+"px"})}function L6(i,e){let t=i.length(),r=i.pointAt(t/2),{width:n,height:s}=e.bbox();e.x(r.x-n/2),e.y(r.y-s/2)}var ZE,r1,I6=T(()=>{wt();pe();ZE="associative-line-text-edit-warp";r1={getText:sS,createText:QE,styleText:oS,onScale:iS,showEditTextBox:JE,setIsShowTextEdit:eS,removeTextEditEl:tS,hideEditTextBox:nS,updateTextEditBoxPos:rS,renderText:aS,updateTextPos:L6}});var z6={};tt(z6,{default:()=>hS});var lS,n1,uh,hS,R6=T(()=>{pe();Qc();t1();_6();I6();lS=["associativeLineWidth","associativeLineColor","associativeLineActiveWidth","associativeLineActiveColor","associativeLineDasharray","associativeLineTextColor","associativeLineTextFontSize","associativeLineTextLineHeight","associativeLineTextFontFamily"],n1="associative-line-text-edit-warp",uh=class{constructor(e={}){this.mindMap=e.mindMap,this.associativeLineDraw=this.mindMap.associativeLineDraw,this.isNotRenderAllLines=!1,this.lineList=[],this.activeLine=null,this.isCreatingLine=!1,this.creatingStartNode=null,this.creatingLine=null,this.overlapNode=null,this.isNodeDragging=!1,this.controlLine1=null,this.controlLine2=null,this.controlPoint1=null,this.controlPoint2=null,this.controlPointDiameter=10,this.isControlPointMousedown=!1,this.mousedownControlPointKey="",this.controlPointMousemoveState={pos:null,startPoint:null,endPoint:null,targetIndex:""},this.checkOverlapNode=Ai(this.checkOverlapNode,100,this),Object.keys(i1).forEach(t=>{this[t]=i1[t].bind(this)}),this.showTextEdit=!1,Object.keys(r1).forEach(t=>{this[t]=r1[t].bind(this)}),this.mindMap.addEditNodeClass(n1),this.bindEvent()}bindEvent(){this.renderAllLines=this.renderAllLines.bind(this),this.onDrawClick=this.onDrawClick.bind(this),this.onNodeClick=this.onNodeClick.bind(this),this.removeLine=this.removeLine.bind(this),this.addLine=this.addLine.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onNodeDragging=this.onNodeDragging.bind(this),this.onNodeDragend=this.onNodeDragend.bind(this),this.onControlPointMouseup=this.onControlPointMouseup.bind(this),this.onBeforeDestroy=this.onBeforeDestroy.bind(this),this.mindMap.on("node_tree_render_end",this.renderAllLines),this.mindMap.on("data_change",this.renderAllLines),this.mindMap.on("draw_click",this.onDrawClick),this.mindMap.on("node_click",this.onNodeClick),this.mindMap.on("contextmenu",this.onDrawClick),this.mindMap.keyCommand.addShortcut("Del|Backspace",this.removeLine),this.mindMap.command.add("ADD_ASSOCIATIVE_LINE",this.addLine),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("node_dragging",this.onNodeDragging),this.mindMap.on("node_dragend",this.onNodeDragend),this.mindMap.on("mouseup",this.onControlPointMouseup),this.mindMap.on("scale",this.onScale),this.mindMap.on("beforeDestroy",this.onBeforeDestroy)}unBindEvent(){this.mindMap.off("node_tree_render_end",this.renderAllLines),this.mindMap.off("data_change",this.renderAllLines),this.mindMap.off("draw_click",this.onDrawClick),this.mindMap.off("node_click",this.onNodeClick),this.mindMap.off("contextmenu",this.onDrawClick),this.mindMap.keyCommand.removeShortcut("Del|Backspace",this.removeLine),this.mindMap.command.remove("ADD_ASSOCIATIVE_LINE",this.addLine),this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("node_dragging",this.onNodeDragging),this.mindMap.off("node_dragend",this.onNodeDragend),this.mindMap.off("mouseup",this.onControlPointMouseup),this.mindMap.off("scale",this.onScale),this.mindMap.off("beforeDestroy",this.onBeforeDestroy)}getStyleConfig(e,t){let r={};t&&(r=(e.getData("associativeLineStyle")||{})[t.getData("uid")]||{});let n={};return lS.forEach(s=>{typeof r[s]<"u"?n[s]=r[s]:n[s]=e.getStyle(s)}),n}onBeforeDestroy(){this.hideEditTextBox(),this.removeTextEditEl()}onDrawClick(){this.isCreatingLine&&this.cancelCreateLine(),this.isControlPointMousedown||(this.clearActiveLine(),this.renderAllLines())}onNodeClick(e){this.isCreatingLine?this.completeCreateLine(e):(this.clearActiveLine(),this.renderAllLines())}createMarker(e=()=>{}){return this.associativeLineDraw.marker(20,20,t=>{t.ref(12,5),t.size(10,10),t.attr("orient","auto-start-reverse"),e(t.path("M0,0 L2,5 L0,10 L10,5 Z"))})}updateAllLinesPos(e,t,r){r=r||{};let[n,s]=Ju(e,t),a=0,o="",l=0,h="";return r.startPoint&&(a=r.startPoint.range||0,o=r.startPoint.dir||"right",n=kr(e,o,a)),r.endPoint&&(l=r.endPoint.range||0,h=r.endPoint.dir||"right",s=kr(t,h,l)),[n,s]}renderAllLines(){if(this.isNotRenderAllLines){this.isNotRenderAllLines=!1;return}this.removeAllLines(),this.removeControls(),this.clearActiveLine();let e=this.mindMap.renderer.root;if(!e)return;let t=new Map,r=new Map;ue(e,null,n=>{if(!n)return;let s=n.getData();s.associativeLineTargets&&s.associativeLineTargets.length>0&&r.set(n,s.associativeLineTargets),s.uid&&t.set(s.uid,n)},()=>{},!0,0),r.forEach((n,s)=>{n.forEach((a,o)=>{let l=t.get(a);if(!s||!l)return;let h=(s.getData("associativeLinePoint")||[])[o],[d,c]=this.updateAllLinesPos(s,l,h);this.drawLine(d,c,s,l)})})}drawLine(e,t,r,n){let{associativeLineWidth:s,associativeLineColor:a,associativeLineActiveWidth:o,associativeLineDasharray:l}=this.getStyleConfig(r,n),h=null,d=this.createMarker(y=>{h=y});h.stroke({color:a}).fill({color:a});let{path:c,controlPoints:f}=C6(e,t,r,n),m=this.associativeLineDraw.path();m.stroke({width:s,color:a,dasharray:l||"6,4"}).fill({color:"none"}),m.plot(c),m.marker("end",d);let g=this.associativeLineDraw.path();g.stroke({width:o,color:"transparent"}).fill({color:"none"}),g.plot(c);let x=this.createText({path:m,clickPath:g,markerPath:h,node:r,toNode:n,startPoint:e,endPoint:t,controlPoints:f});g.click(y=>{y.stopPropagation(),this.setActiveLine({path:m,clickPath:g,markerPath:h,text:x,node:r,toNode:n,startPoint:e,endPoint:t,controlPoints:f})}),g.dblclick(()=>{this.activeLine&&this.showEditTextBox(x)}),this.renderText(this.getText(r,n),m,x,r,n),this.lineList.push([m,g,x,r,n])}updateActiveLineStyle(){if(!this.activeLine)return;this.isNotRenderAllLines=!0;let[e,t,r,n,s,a]=this.activeLine,{associativeLineWidth:o,associativeLineColor:l,associativeLineDasharray:h,associativeLineActiveWidth:d,associativeLineActiveColor:c,associativeLineTextColor:f,associativeLineTextFontFamily:m,associativeLineTextFontSize:g}=this.getStyleConfig(n,s);e.stroke({width:o,color:l,dasharray:h||"6,4"}).fill({color:"none"}),t.stroke({width:d,color:c}).fill({color:"none"}),a.stroke({color:l}).fill({color:l}),r.find("text").forEach(x=>{x.fill({color:f}).css({"font-family":m,"font-size":g+"px"})}),this.controlLine1&&this.controlLine1.stroke({color:c}),this.controlLine2&&this.controlLine2.stroke({color:c}),this.controlPoint1&&this.controlPoint1.stroke({color:c}),this.controlPoint2&&this.controlPoint2.stroke({color:c}),this.updateTextPos(e,r)}setActiveLine({path:e,clickPath:t,markerPath:r,text:n,node:s,toNode:a,startPoint:o,endPoint:l,controlPoints:h}){let{associativeLineActiveColor:d}=this.getStyleConfig(s,a);this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.clearActiveLine(),this.activeLine=[e,t,n,s,a,r],t.stroke({color:d}),this.getText(s,a)||this.renderText(this.mindMap.opt.defaultAssociativeLineText,e,n,s,a),this.renderControls(o,l,h[0],h[1],s,a),this.mindMap.emit("associative_line_click",e,t,s,a),this.front()}removeAllLines(){this.lineList.forEach(e=>{e[0].remove(),e[1].remove(),e[2].remove()}),this.lineList=[]}createLineFromActiveNode(){if(this.mindMap.renderer.activeNodeList.length<=0)return;let e=this.mindMap.renderer.activeNodeList[0];this.createLine(e)}createLine(e){let{associativeLineWidth:t,associativeLineColor:r,associativeLineDasharray:n}=this.getStyleConfig(e);if(this.isCreatingLine||!e)return;this.front(),this.isCreatingLine=!0,this.creatingStartNode=e,this.creatingLine=this.associativeLineDraw.path(),this.creatingLine.stroke({width:t,color:r,dasharray:n||"6,4"}).fill({color:"none"});let s=null,a=this.createMarker(o=>{s=o});s.stroke({color:r}).fill({color:r}),this.creatingLine.marker("end",a)}cancelCreateLine(){this.isCreatingLine=!1,this.creatingStartNode=null,this.creatingLine.remove(),this.creatingLine=null,this.overlapNode=null,this.back()}onMousemove(e){this.onControlPointMousemove(e),this.updateCreatingLine(e)}updateCreatingLine(e){if(!this.isCreatingLine)return;let{x:t,y:r}=this.getTransformedEventPos(e),n=kr(this.creatingStartNode),s=t>n.x?-10:10,a=k6(n.x,n.y,t+s,r);this.creatingLine.plot(a),this.checkOverlapNode(t,r)}getTransformedEventPos(e){let{x:t,y:r}=this.mindMap.toPos(e.clientX,e.clientY),{scaleX:n,scaleY:s,translateX:a,translateY:o}=this.mindMap.draw.transform();return{x:(t-a)/n,y:(r-o)/s}}getNodePos(e){let{scaleX:t,scaleY:r,translateX:n,translateY:s}=this.mindMap.draw.transform(),{left:a,top:o,width:l,height:h}=e,d=a*t+n,c=o*r+s;return{left:a,top:o,translateLeft:d,translateTop:c,width:l,height:h}}checkOverlapNode(e,t){this.overlapNode=null,Zt(this.mindMap.renderer.root,r=>{if(r.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",r,!1),r.uid===this.creatingStartNode.uid||this.overlapNode)return;let{left:n,top:s,width:a,height:o}=r,l=n+a,h=s+o;e>=n&&e<=l&&t>=s&&t<=h&&(this.overlapNode=r)}),this.overlapNode&&!this.overlapNode.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!0)}completeCreateLine(e){if(this.creatingStartNode.uid===e.uid)return;let{beforeAssociativeLineConnection:t}=this.mindMap.opt,r=!1;typeof t=="function"&&(r=t(e)),!r&&(this.addLine(this.creatingStartNode,e),this.overlapNode&&this.overlapNode.getData("isActive")&&this.mindMap.execCommand("SET_NODE_ACTIVE",this.overlapNode,!1),this.cancelCreateLine())}addLine(e,t){if(!e||!t)return;let r=t.getData("uid");r||(r=vo(),this.mindMap.execCommand("SET_NODE_DATA",t,{uid:r}));let n=e.getData("associativeLineTargets")||[];if(n.some(f=>f===r))return;n.push(r);let[a,o]=Ju(e,t),l=Qo(a.x,a.y,o.x,o.y),{associativeLineInitPointsPosition:h}=this.mindMap.opt;if(h){let{from:f,to:m}=h;f&&(a.dir=f),m&&(o.dir=m)}let d=e.getData("associativeLineTargetControlOffsets")||[];d[n.length-1]=[{x:l[0].x-a.x,y:l[0].y-a.y},{x:l[1].x-o.x,y:l[1].y-o.y}];let c=e.getData("associativeLinePoint")||[];c[n.length-1]={startPoint:a,endPoint:o},this.mindMap.execCommand("SET_NODE_DATA",e,{associativeLineTargets:n,associativeLineTargetControlOffsets:d,associativeLinePoint:c})}removeLine(){if(!this.activeLine)return;let[,,,e,t]=this.activeLine;this.removeControls();let{associativeLineTargets:r,associativeLinePoint:n,associativeLineTargetControlOffsets:s,associativeLineText:a,associativeLineStyle:o}=e.getData();n=n||[];let l=Zo(e,t),h={};a&&Object.keys(a).forEach(c=>{c!==t.getData("uid")&&(h[c]=a[c])});let d={};o&&Object.keys(o).forEach(c=>{c!==t.getData("uid")&&(d[c]=o[c])}),this.mindMap.execCommand("SET_NODE_DATA",e,{associativeLineTargets:r.filter((c,f)=>f!==l),associativeLinePoint:n.filter((c,f)=>f!==l),associativeLineTargetControlOffsets:s?s.filter((c,f)=>f!==l):[],associativeLineText:h,associativeLineStyle:d})}clearActiveLine(){if(this.activeLine){let[,e,t,r,n]=this.activeLine;e.stroke({color:"transparent"}),this.hideEditTextBox(),this.getText(r,n)||t.clear(),this.activeLine=null,this.removeControls(),this.back(),this.mindMap.emit("associative_line_deactivate")}}onNodeDragging(){this.isNodeDragging||(this.isNodeDragging=!0,this.lineList.forEach(e=>{e[0].hide(),e[1].hide(),e[2].hide()}),this.hideControls())}onNodeDragend(){this.isNodeDragging&&(this.lineList.forEach(e=>{e[0].show(),e[1].show(),e[2].show()}),this.showControls(),this.isNodeDragging=!1)}front(){this.mindMap.opt.associativeLineIsAlwaysAboveNode||this.associativeLineDraw.front()}back(){this.mindMap.opt.associativeLineIsAlwaysAboveNode||(this.associativeLineDraw.back(),this.associativeLineDraw.forward())}beforePluginRemove(){this.mindMap.deleteEditNodeClass(n1),this.unBindEvent()}beforePluginDestroy(){this.mindMap.deleteEditNodeClass(n1),this.unBindEvent()}};uh.instanceName="associativeLine";hS=uh});var D6={};tt(D6,{default:()=>dS});var fh,dS,O6=T(()=>{pe();rh();Ge();fh=class{constructor({mindMap:e}){this.mindMap=e,this.isSearching=!1,this.searchText="",this.matchNodeList=[],this.currentIndex=-1,this.notResetSearchText=!1,this.isJumpNext=!1,this.bindEvent()}bindEvent(){this.onDataChange=this.onDataChange.bind(this),this.onModeChange=this.onModeChange.bind(this),this.mindMap.on("data_change",this.onDataChange),this.mindMap.on("mode_change",this.onModeChange)}unBindEvent(){this.mindMap.off("data_change",this.onDataChange),this.mindMap.off("mode_change",this.onModeChange)}onDataChange(){if(this.isJumpNext){this.isJumpNext=!1,this.search(this.searchText);return}if(this.notResetSearchText){this.notResetSearchText=!1;return}this.searchText=""}onModeChange(e){!(e===C.MODE.READONLY)&&this.isSearching&&this.matchNodeList[this.currentIndex]&&this.matchNodeList[this.currentIndex].closeHighlight()}search(e,t=()=>{}){if(Kt(e))return this.endSearch();e=String(e),this.isSearching=!0,this.searchText===e?this.searchNext(t):(this.searchText=e,this.doSearch(),this.searchNext(t)),this.emitEvent()}updateMatchNodeList(e){this.matchNodeList=e,this.mindMap.emit("search_match_node_list_change",e)}endSearch(){this.isSearching&&(this.mindMap.opt.readonly&&this.matchNodeList[this.currentIndex]&&this.matchNodeList[this.currentIndex].closeHighlight(),this.searchText="",this.updateMatchNodeList([]),this.currentIndex=-1,this.notResetSearchText=!1,this.isSearching=!1,this.emitEvent())}doSearch(){this.clearHighlightOnReadonly(),this.updateMatchNodeList([]),this.currentIndex=-1;let{isOnlySearchCurrentRenderNodes:e}=this.mindMap.opt,t=e?this.mindMap.renderer.root:this.mindMap.renderer.renderTree;if(!t)return;let r=[];Zt(t,n=>{let{richText:s,text:a,generalization:o}=e?n.getData():n.data;s&&(a=aa(a)),a.includes(this.searchText)&&r.push(n),us({generalization:o}).forEach(h=>{let{richText:d,text:c,uid:f}=h;e&&!this.mindMap.renderer.findNodeByUid(f)||(d&&(c=aa(c)),c.includes(this.searchText)&&r.push({data:h}))})}),this.updateMatchNodeList(r)}isNodeInstance(e){return e instanceof ca}searchNext(e,t){if(!this.isSearching||this.matchNodeList.length<=0)return;t!==void 0&&Number.isInteger(t)&&t>=0&&t{this.isNodeInstance(n)||(this.matchNodeList[this.currentIndex]=o,this.updateMatchNodeList(this.matchNodeList)),e(),r&&o.highlight(),a&&(this.notResetSearchText=!1)})}clearHighlightOnReadonly(){let{readonly:e}=this.mindMap.opt;e&&this.matchNodeList.forEach(t=>{this.isNodeInstance(t)&&t.closeHighlight()})}jump(e,t=()=>{}){this.searchNext(t,e)}replace(e,t=!1){if(e==null||!this.isSearching||this.matchNodeList.length<=0)return;this.isJumpNext=t,e=String(e);let r=this.matchNodeList[this.currentIndex];if(!r)return;let n=e.includes(this.searchText),s=this.getReplacedText(r,this.searchText,e);if(this.notResetSearchText=!0,r.setText(s,r.getData("richText")),n){this.updateMatchNodeList(this.matchNodeList);return}let a=this.matchNodeList.filter(o=>r!==o);this.updateMatchNodeList(a),this.currentIndex>this.matchNodeList.length-1?this.currentIndex=-1:this.currentIndex--,this.emitEvent()}replaceAll(e){if(e==null||!this.isSearching||this.matchNodeList.length<=0)return;e=String(e);let t=e.includes(this.searchText);this.notResetSearchText=!0,this.matchNodeList.forEach(r=>{let n=this.getReplacedText(r,this.searchText,e);if(this.isNodeInstance(r)){let s={text:n};this.mindMap.renderer.setNodeDataRender(r,s,!0)}else r.data.text=n}),this.mindMap.render(),this.mindMap.command.addHistory(),t?this.updateMatchNodeList(this.matchNodeList):this.endSearch()}getReplacedText(e,t,r){let{richText:n,text:s}=this.isNodeInstance(e)?e.getData():e.data;return n?O2(s,t,r):s.replace(new RegExp(t,"g"),r)}emitEvent(){this.mindMap.emit("search_info_change",{currentIndex:this.currentIndex,total:this.matchNodeList.length})}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};fh.instanceName="search";dS=fh});var B6,P6,F6=T(()=>{pe();B6=i=>{i=ds(i);let e={},t={};i.forEach(n=>{let s=n.parent;if(s){let a=s.uid;t[a]=s;let o=n.getIndexInBrothers(),l={node:n,index:o};e[a]?e[a].find(h=>h.index===l.index)||e[a].push(l):e[a]=[l]}});let r=[];return Object.keys(e).forEach(n=>{let s=e[n],a=t[n];if(s.length>1){let o=s.map(f=>f.index).sort((f,m)=>f-m),l=o[0],h=o[o.length-1],d=-1,c=-1;for(let f=l;f<=h;f++)o.includes(f)?(d===-1&&(d=f),c=f):(d!==-1&&c!==-1&&r.push({node:a,range:[d,c]}),d=-1,c=-1);d!==-1&&c!==-1&&r.push({node:a,range:[d,c]})}else r.push({node:a,range:[s[0].index,s[0].index]})}),r},P6=i=>{let e=i.children;if(!e||e.length<=0)return;let t=[],r={};return e.forEach((n,s)=>{let a=n.getData("outerFrame");if(!a)return;let o=a.groupId;o?(r[o]||(r[o]=[]),r[o].push({node:n,index:s})):t.push({nodeList:[n],range:[s,s]})}),Object.keys(r).forEach(n=>{let s=r[n];t.push({nodeList:s.map(a=>a.node),range:[s[0].index,s[s.length-1].index]})}),t}});function uS(i,e,t){let r=this.draw.group(),n=()=>{(!this.activeOuterFrame||this.activeOuterFrame.el!==i)&&this.setActiveOuterFrame(i,e,t,r)};return r.click(s=>{s.stopPropagation(),n()}),r.on("dblclick",s=>{s.stopPropagation(),n(),this.showEditTextBox(r)}),r}function fS(i){this.mindMap.emit("before_show_text_edit"),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.className=cS,this.textEditNode.style.cssText=` position: fixed; box-sizing: border-box; background-color: #fff; box-shadow: 0 0 20px rgba(0,0,0,.5); outline: none; word-break: break-all; - `,this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",g=>{g.stopPropagation()}),this.textEditNode.addEventListener("click",g=>{g.stopPropagation()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let{node:e,range:t}=this.activeOuterFrame,r=this.getStyle(this.getNodeRangeFirstNode(e,t)),[n,s,a,o]=r.textFillPadding,{defaultOuterFrameText:l,nodeTextEditZIndex:h}=this.mindMap.opt,d=this.mindMap.view.scale,c=this.getText(this.getNodeRangeFirstNode(e,t)),f=(c||l).split(/\n/gim);this.textEditNode.style.padding=`${n}px ${s}px ${a}px ${o}px`,this.textEditNode.style.fontFamily=r.fontFamily,this.textEditNode.style.fontSize=r.fontSize*d+"px",this.textEditNode.style.fontWeight=r.fontWeight,this.textEditNode.style.fontStyle=r.fontStyle,this.textEditNode.style.lineHeight=f.length>1?r.lineHeight:"normal",this.textEditNode.style.zIndex=h,this.textEditNode.innerHTML=f.join("
    "),this.textEditNode.style.display="block",this.updateTextEditBoxPos(i),this.setIsShowTextEdit(!0),c===""||c===l?la(this.textEditNode):oa(this.textEditNode)}function jE(i){this.showTextEdit=i,i?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}function GE(){if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}function VE(){this.hideEditTextBox()}function WE(i){let e=i.node.getBoundingClientRect();this.textEditNode&&(this.textEditNode.style.minWidth=`${e.width}px`,this.textEditNode.style.minHeight=`${e.height}px`,this.textEditNode.style.left=`${e.left}px`,this.textEditNode.style.top=`${e.top}px`)}function YE(){if(!this.showTextEdit)return;let{el:i,textNode:e,node:t,range:r}=this.activeOuterFrame,n=na(this.textEditNode.innerHTML);n=n===this.mindMap.opt.defaultOuterFrameText?"":n,this.updateActiveOuterFrame({text:n}),this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.setIsShowTextEdit(!1),this.renderText(n,i,e,t,r),this.mindMap.emit("hide_text_edit")}function XE(i,e,t,r,n){if(!i)return;t.clear();let s=new Ve;t.add(s);let a=this.getStyle(this.getNodeRangeFirstNode(r,n)),[o,l,h,d]=a.textFillPadding,c=i.replace(/\n$/g,"").split(/\n/gim),f=new _e;c.forEach((A,C)=>{A===""&&(A="\uFEFF");let I=new Ce().text(A);I.y(a.fontSize*a.lineHeight*C),this.styleText(I,a),f.add(I)}),t.add(f);let{width:m,height:g}=t.bbox(),x=m+o+h,y=g+l+d;s.size(x,y).x(0).dy(0),this.styleTextShape(s,a);let b=0;switch(a.textAlign){case"left":b=e.x();break;case"center":b=e.x()+e.width()/2-x/2;break;case"right":b=e.x()+e.width()-x;break;default:break}let S=e.y()-y;s.x(b),s.y(S),f.x(b+o),f.y(S+l)}function KE(i,e){i.fill({color:e.textFill}).radius(e.textFillRadius)}function ZE(i,e){i.fill({color:e.color}).css({"font-family":e.fontFamily,"font-size":e.fontSize+"px","font-weight":e.fontWeight,"font-style":e.fontStyle})}function QE(i){let e=i.getData("outerFrame");return e&&e.text?e.text:""}var HE,Yu,S6=T(()=>{yt();pe();HE="outer-frame-text-edit-warp";Yu={getText:QE,createText:UE,styleTextShape:KE,styleText:ZE,onScale:VE,showEditTextBox:$E,setIsShowTextEdit:jE,removeTextEditEl:GE,hideEditTextBox:YE,updateTextEditBoxPos:WE,renderText:XE}});var A6={};tt(A6,{default:()=>JE});var Ku,Xu,Wo,JE,k6=T(()=>{pe();E6();S6();Ku={radius:5,strokeWidth:2,strokeColor:"#0984e3",strokeDasharray:"5,5",fill:"rgba(9,132,227,0.05)",fontSize:14,fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",fontWeight:"normal",fontStyle:"normal",color:"#fff",lineHeight:1.2,textFill:"#0984e3",textFillRadius:5,textFillPadding:[5,5,5,5],textAlign:"left"},Xu="outer-frame-text-edit-warp",Wo=class{constructor(e={}){this.mindMap=e.mindMap,this.draw=null,this.createDrawContainer(),this.isNotRenderOuterFrames=!1,this.textNodeList=[],this.outerFrameElList=[],this.activeOuterFrame=null,this.textEditNode=null,this.showTextEdit=!1,Object.keys(Yu).forEach(t=>{this[t]=Yu[t].bind(this)}),this.mindMap.addEditNodeClass(Xu),this.bindEvent()}createDrawContainer(){this.draw=this.mindMap.draw.group(),this.draw.addClass("smm-outer-frame-container"),this.draw.back(),this.draw.forward()}bindEvent(){this.renderOuterFrames=this.renderOuterFrames.bind(this),this.mindMap.on("node_tree_render_end",this.renderOuterFrames),this.mindMap.on("data_change",this.renderOuterFrames),this.clearActiveOuterFrame=this.clearActiveOuterFrame.bind(this),this.mindMap.on("draw_click",this.clearActiveOuterFrame),this.mindMap.on("node_click",this.clearActiveOuterFrame),this.mindMap.on("scale",this.onScale),this.onBeforeDestroy=this.onBeforeDestroy.bind(this),this.mindMap.on("beforeDestroy",this.onBeforeDestroy),this.addOuterFrame=this.addOuterFrame.bind(this),this.mindMap.command.add("ADD_OUTER_FRAME",this.addOuterFrame),this.removeActiveOuterFrame=this.removeActiveOuterFrame.bind(this),this.mindMap.keyCommand.addShortcut("Del|Backspace",this.removeActiveOuterFrame)}unBindEvent(){this.mindMap.off("node_tree_render_end",this.renderOuterFrames),this.mindMap.off("data_change",this.renderOuterFrames),this.mindMap.off("draw_click",this.clearActiveOuterFrame),this.mindMap.off("node_click",this.clearActiveOuterFrame),this.mindMap.off("scale",this.onScale),this.mindMap.off("beforeDestroy",this.onBeforeDestroy),this.mindMap.command.remove("ADD_OUTER_FRAME",this.addOuterFrame),this.mindMap.keyCommand.removeShortcut("Del|Backspace",this.removeActiveOuterFrame)}onBeforeDestroy(){this.hideEditTextBox(),this.removeTextEditEl()}addOuterFrame(e,t={}){e=Ot(e);let r=this.mindMap.renderer.activeNodeList;if(r.length<=0&&e.length<=0)return;let n=e.length>0?e:r;n=n.filter(a=>!a.isRoot&&!a.isGeneralization),T6(n).forEach(({node:a,range:o})=>{let l=a.children.slice(o[0],o[1]+1),h=wt();l.forEach(d=>{let c=d.getData("outerFrame");c?c={...c,...t,groupId:h}:c={...t,groupId:h},this.mindMap.execCommand("SET_NODE_DATA",d,{outerFrame:c})})})}getActiveOuterFrame(){return this.activeOuterFrame?{...this.activeOuterFrame}:null}removeActiveOuterFrame(){if(!this.activeOuterFrame)return;let{node:e,range:t}=this.activeOuterFrame;this.getRangeNodeList(e,t).forEach(r=>{this.mindMap.execCommand("SET_NODE_DATA",r,{outerFrame:null})}),this.mindMap.emit("outer_frame_delete")}removeActiveOuterFrameText(){this.updateActiveOuterFrame({text:""})}updateActiveOuterFrame(e={}){if(!this.activeOuterFrame)return;this.isNotRenderOuterFrames=!0;let{el:t,node:r,range:n}=this.activeOuterFrame,s="";this.getRangeNodeList(r,n).forEach(a=>{let l={...a.getData("outerFrame"),...e};s=l.strokeDasharray,this.mindMap.execCommand("SET_NODE_DATA",a,{outerFrame:l})}),t.cacheStyle={dasharray:s},this.updateOuterFrameStyle()}updateOuterFrameStyle(){let{el:e,node:t,range:r,textNode:n}=this.activeOuterFrame,s=this.getNodeRangeFirstNode(t,r),a=this.getStyle(s);this.styleOuterFrame(e,{...a,strokeDasharray:"none"});let o=this.getText(s);this.renderText(o,e,n,t,r)}getRangeNodeList(e,t){return e.children.slice(t[0],t[1]+1).filter(r=>r.getData("outerFrame"))}getNodeRangeFirstNode(e,t){return e.children[t[0]]}renderOuterFrames(){if(this.isNotRenderOuterFrames){this.isNotRenderOuterFrames=!1;return}this.clearActiveOuterFrame(),this.clearTextNodes(),this.clearOuterFrameElList();let e=this.mindMap.renderer.root;if(!e)return;let t=this.mindMap.draw.transform(),{outerFramePaddingX:r,outerFramePaddingY:n}=this.mindMap.opt;de(e,null,s=>{if(!s)return;let a=N6(s);a&&a.length>0&&a.forEach(({nodeList:o,range:l})=>{if(l[0]===-1||l[1]===-1)return;let{left:h,top:d,width:c,height:f}=D2(o);if(!Number.isFinite(h)||!Number.isFinite(d)||!Number.isFinite(c)||!Number.isFinite(f))return;let m=this.createOuterFrameEl((h-r-this.mindMap.elRect.left-t.translateX)/t.scaleX,(d-n-this.mindMap.elRect.top-t.translateY)/t.scaleY,(c+r*2)/t.scaleX,(f+n*2)/t.scaleY,this.getStyle(o[0])),g=this.createText(m,s,l);this.textNodeList.push(g),this.renderText(this.getText(o[0]),m,g,s,l),m.on("click",x=>{x.stopPropagation(),this.setActiveOuterFrame(m,s,l,g)})})},()=>{},!0,0)}setActiveOuterFrame(e,t,r,n){this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.clearActiveOuterFrame(),this.activeOuterFrame={el:e,node:t,range:r,textNode:n},e.stroke({dasharray:"none"}),this.getText(this.getNodeRangeFirstNode(t,r))||this.renderText(this.mindMap.opt.defaultOuterFrameText,e,n,t,r),this.mindMap.emit("outer_frame_active",e,t,r)}clearActiveOuterFrame(){if(!this.activeOuterFrame)return;let{el:e,textNode:t,node:r,range:n}=this.activeOuterFrame;e.stroke({dasharray:e.cacheStyle.dasharray||Ku.strokeDasharray}),this.hideEditTextBox(),this.getText(this.getNodeRangeFirstNode(r,n))||t.clear(),this.activeOuterFrame=null,this.mindMap.emit("outer_frame_deactivate")}getStyle(e){return{...Ku,...e.getData("outerFrame")||{}}}createOuterFrameEl(e,t,r,n,s={}){let a=this.draw.rect().size(r,n).x(e).y(t);return this.styleOuterFrame(a,s),a.cacheStyle={dasharray:s.strokeDasharray},this.outerFrameElList.push(a),a}styleOuterFrame(e,t){e.radius(t.radius).stroke({width:t.strokeWidth,color:t.strokeColor,dasharray:t.strokeDasharray}).fill({color:t.fill})}clearTextNodes(){this.textNodeList.forEach(e=>{e.remove()})}clearOuterFrameElList(){this.outerFrameElList.forEach(e=>{e.remove()}),this.outerFrameElList=[],this.activeOuterFrame=null}beforePluginRemove(){this.mindMap.deleteEditNodeClass(Xu),this.unBindEvent()}beforePluginDestroy(){this.mindMap.deleteEditNodeClass(Xu),this.unBindEvent()}};Wo.instanceName="outerFrame";Wo.defaultStyle=Ku;JE=Wo});var C6={};tt(C6,{default:()=>eS});var ah,eS,_6=T(()=>{pe();$e();ah=class{constructor(e){this.mindMap=e.mindMap,this.scrollbarWrapSize={width:0,height:0},this.chartHeight=0,this.chartWidth=0,this.reset(),this.bindEvent()}reset(){this.currentScrollType="",this.isMousedown=!1,this.mousedownPos={x:0,y:0},this.mousedownScrollbarPos=0}bindEvent(){this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.updateScrollbar=this.updateScrollbar.bind(this),this.updateScrollbar=Si(this.updateScrollbar,16,this),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("mouseup",this.onMouseup),this.mindMap.on("node_tree_render_end",this.updateScrollbar),this.mindMap.on("view_data_change",this.updateScrollbar),this.mindMap.on("resize",this.updateScrollbar)}unBindEvent(){this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("mouseup",this.onMouseup),this.mindMap.off("node_tree_render_end",this.updateScrollbar),this.mindMap.off("view_data_change",this.updateScrollbar),this.mindMap.off("resize",this.updateScrollbar)}updateScrollbar(){if(this.isMousedown)return;let e=this.calculationScrollbar();this.emitEvent(e)}emitEvent(e){this.mindMap.emit("scrollbar_change",e)}setScrollBarWrapSize(e,t){this.scrollbarWrapSize.width=e,this.scrollbarWrapSize.height=t}calculationScrollbar(){let e=this.mindMap.draw.rbox(),t=this.mindMap.elRect;e.x-=t.left,e.y-=t.top;let r=this.mindMap.height,n=r/2,s=e.height+n*2;this.chartHeight=s;let a=e.y-n,o=Math.min(r/s*100,100),l=-a/s*100;l<0&&(l=0),l>100-o&&(l=100-o);let h=this.mindMap.width,d=h/2,c=e.width+d*2;this.chartWidth=c;let f=e.x-d,m=Math.min(h/c*100,100),g=-f/c*100;return g<0&&(g=0),g>100-m&&(g=100-m),{vertical:{top:l,height:o},horizontal:{left:g,width:m}}}onMousedown(e,t){e.preventDefault(),e.stopPropagation(),this.currentScrollType=t,this.isMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let r=window.getComputedStyle(e.target);t===k.SCROLL_BAR_DIR.VERTICAL?this.mousedownScrollbarPos=Number.parseFloat(r.top):this.mousedownScrollbarPos=Number.parseFloat(r.left)}onMousemove(e){if(this.isMousedown)if(e.preventDefault(),e.stopPropagation(),this.currentScrollType===k.SCROLL_BAR_DIR.VERTICAL){let t=e.clientY-this.mousedownPos.y+this.mousedownScrollbarPos;this.updateMindMapView(k.SCROLL_BAR_DIR.VERTICAL,t)}else{let t=e.clientX-this.mousedownPos.x+this.mousedownScrollbarPos;this.updateMindMapView(k.SCROLL_BAR_DIR.HORIZONTAL,t)}}onMouseup(){this.isMousedown=!1,this.reset()}updateMindMapView(e,t){let r=this.calculationScrollbar(),n=this.mindMap.draw.transform(),s=this.mindMap.draw.rbox(),a=this.mindMap.renderer.root.group.rbox(),o=this.mindMap.renderer.layout.getRootCenterOffset(a.width,a.height);if(e===k.SCROLL_BAR_DIR.VERTICAL){let l=t;l<=0&&(l=0);let h=(100-r.vertical.height)/100*this.scrollbarWrapSize.height;l>=h&&(l=h);let d=l/this.scrollbarWrapSize.height*100,c=-d/100*this.chartHeight,f=a.y-s.y,m=this.mindMap.height/2,g=c+f-m*n.scaleY+m-o.y*n.scaleY+(this.mindMap.height-this.mindMap.initHeight)/2*n.scaleY;this.mindMap.view.translateYTo(g),this.emitEvent({horizontal:r.horizontal,vertical:{top:d,height:r.vertical.height}})}else{let l=t;l<=0&&(l=0);let h=(100-r.horizontal.width)/100*this.scrollbarWrapSize.width;l>=h&&(l=h);let d=l/this.scrollbarWrapSize.width*100,c=-d/100*this.chartWidth,f=a.x-s.x,m=this.mindMap.width/2,g=c+f-m*n.scaleX+m-o.x*n.scaleX+(this.mindMap.width-this.mindMap.initWidth)/2*n.scaleX;this.mindMap.view.translateXTo(g),this.emitEvent({vertical:r.vertical,horizontal:{left:d,width:r.horizontal.width}})}}onClick(e,t){let r=0;t===k.SCROLL_BAR_DIR.VERTICAL?r=e.clientY-e.currentTarget.getBoundingClientRect().top:r=e.clientX-e.currentTarget.getBoundingClientRect().left,this.updateMindMapView(t,r)}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};ah.instanceName="scrollbar";eS=ah});var L6={};tt(L6,{default:()=>tS});var oh,tS,I6=T(()=>{pe();oh=class{constructor(e){this.mindMap=e.mindMap,this.isMousedown=!1,this.mousedownPos={x:0,y:0},this.startViewPos={x:0,y:0},this.currentState=null}calculationMiniMap(e,t){let{svg:r,rect:n,origWidth:s,origHeight:a,scaleX:o,scaleY:l}=this.mindMap.getSvgData({ignoreWatermark:!0}),h=this.mindMap.elRect;n.x-=h.left,n.x2-=h.left,n.y-=h.top,n.y2-=h.top;let d=e/t,c=0,f=0;d>n.ratio?(f=t,c=n.ratio*f):(c=e,f=c/n.ratio);let m=c/n.width,g=(e-c)/2,x=(t-f)/2,y=n.width*o,b=n.height*l,S=(y-n.width)/2,A=(b-n.height)/2,C=n.x-S,I=n.x2+S,O=n.y-A,q=n.y2+A,P={left:0,top:0,right:0,bottom:0};P.left=Math.max(0,-C/y*c)+g,P.right=Math.max(0,(I-s)/y*c)+g,P.top=Math.max(0,-O/b*f)+x,P.bottom=Math.max(0,(q-a)/b*f)+x,P.top>x+f&&(P.top=x+f),P.left>g+c&&(P.left=g+c),Object.keys(P).forEach(ne=>{P[ne]=P[ne]+"px"}),this.removeNodeContent(r);let W=r.svg();return this.currentState={viewBoxStyle:{...P},miniMapBoxScale:m,miniMapBoxLeft:g,miniMapBoxTop:x},{getImgUrl:async ne=>{let re=await this.mindMap.doExport.fixSvgStrAndToBlob(W);ne(re)},svgHTML:W,viewBoxStyle:P,miniMapBoxScale:m,miniMapBoxLeft:g,miniMapBoxTop:x}}removeNodeContent(e){if(e.hasClass("smm-node")){let r=e.findOne(".smm-node-shape"),n=r.attr("fill");(Oo(n)||mu(n))&&r.attr("fill",$0(this.mindMap.themeConfig)),e.clear(),e.add(r);return}let t=e.children();t&&t.length>0&&t.forEach(r=>{this.removeNodeContent(r)})}onMousedown(e){this.isMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let t=this.mindMap.view.getTransformData();this.startViewPos={x:t.state.x,y:t.state.y}}onMousemove(e,t=5){if(!this.isMousedown||this.isViewBoxMousedown)return;let r=e.clientX-this.mousedownPos.x,n=e.clientY-this.mousedownPos.y;this.mindMap.view.translateXTo(r*t+this.startViewPos.x),this.mindMap.view.translateYTo(n*t+this.startViewPos.y)}onMouseup(){this.isMousedown=!1,this.isViewBoxMousedown=!1}onViewBoxMousedown(e){this.isViewBoxMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let t=this.mindMap.view.getTransformData();this.startViewPos={x:t.state.x,y:t.state.y}}onViewBoxMousemove(e){if(!this.isViewBoxMousedown||!this.currentState||this.isMousedown)return;let t=e.clientX-this.mousedownPos.x,r=e.clientY-this.mousedownPos.y,{viewBoxStyle:n,miniMapBoxScale:s,miniMapBoxLeft:a,miniMapBoxTop:o}=this.currentState,l=Math.max(a,Number.parseFloat(n.left)+t),h=Math.max(a,Number.parseFloat(n.right)-t),d=Math.max(o,Number.parseFloat(n.top)+r),c=Math.max(o,Number.parseFloat(n.bottom)-r);this.mindMap.emit("mini_map_view_box_position_change",{left:l+"px",right:h+"px",top:d+"px",bottom:c+"px"}),this.mindMap.view.translateXTo(-t/s+this.startViewPos.x),this.mindMap.view.translateYTo(-r/s+this.startViewPos.y)}};oh.instanceName="miniMap";tS=oh});var z6={};tt(z6,{default:()=>iS});var lh,iS,R6=T(()=>{pe();lh=class{constructor({mindMap:e}){this.mindMap=e,this.isInPainter=!1,this.painterNode=null,this.bindEvent()}bindEvent(){this.painterOneNode=this.painterOneNode.bind(this),this.onEndPainter=this.onEndPainter.bind(this),this.mindMap.on("node_click",this.painterOneNode),this.mindMap.on("draw_click",this.onEndPainter)}unBindEvent(){this.mindMap.off("node_click",this.painterOneNode),this.mindMap.off("draw_click",this.onEndPainter)}startPainter(){if(this.mindMap.opt.readonly)return;let e=this.mindMap.renderer.activeNodeList;e.length<=0||(this.painterNode=e[0],this.isInPainter=!0,this.mindMap.emit("painter_start"))}endPainter(){this.painterNode=null,this.isInPainter=!1}onEndPainter(){this.isInPainter&&(this.endPainter(),this.mindMap.emit("painter_end"))}painterOneNode(e){if(!e||!this.isInPainter||!this.painterNode||!e||e.uid===this.painterNode.uid)return;let t={};this.mindMap.opt.onlyPainterNodeCustomStyles||(t={...this.painterNode.effectiveStyles});let r=this.painterNode.getData();Object.keys(r).forEach(n=>{hs(n)&&(t[n]=r[n])}),this.mindMap.renderer._handleRemoveCustomStyles(e.getData()),e.setStyles(t)}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};lh.instanceName="painter";iS=lh});function lS(i){return String(i).replace(oS,e=>aS[e])}function uS(i){if(i.default)return i.default;var e=i.type,t=Array.isArray(e)?e[0]:e;if(typeof t!="string")return t.enum[0];switch(t){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}function vS(i){for(var e=0;e=n[0]&&i<=n[1])return t.name}return null}function f4(i){for(var e=0;e=wh[e]&&i<=wh[e+1])return!0;return!1}function _S(i,e){dr[i]=e}function T1(i,e,t){if(!dr[e])throw new Error("Font metrics not found for font: "+e+".");var r=i.charCodeAt(0),n=dr[e][r];if(!n&&i[0]in O6&&(r=O6[i[0]].charCodeAt(0),n=dr[e][r]),!n&&t==="text"&&f4(r)&&(n=dr[e][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}function LS(i){var e;if(i>=5?e=0:i>=3?e=1:e=2,!Zu[e]){var t=Zu[e]={cssEmPerMu:hh.quad[e]/18};for(var r in hh)hh.hasOwnProperty(r)&&(t[r]=hh[r][e])}return Zu[e]}function F6(i){if(i instanceof ei)return i;throw new Error("Expected symbolNode but got "+String(i)+".")}function OS(i){if(i instanceof ps)return i;throw new Error("Expected span but got "+String(i)+".")}function u(i,e,t,r,n,s){Oe[i][n]={font:e,group:t,replace:r},s&&r&&(Oe[i][r]=Oe[i][n])}function Z(i){for(var{type:e,names:t,props:r,handler:n,htmlBuilder:s,mathmlBuilder:a}=i,o={type:e,numArgs:r.numArgs,argTypes:r.argTypes,allowedInArgument:!!r.allowedInArgument,allowedInText:!!r.allowedInText,allowedInMath:r.allowedInMath===void 0?!0:r.allowedInMath,numOptionalArgs:r.numOptionalArgs||0,infix:!!r.infix,primitive:!!r.primitive,handler:n},l=0;l0&&(s.push(gh(a,e)),a=[]),s.push(r[o]));a.length>0&&s.push(gh(a,e));var h;t?(h=gh(ct(t,e,!0)),h.classes=["tag"],s.push(h)):n&&s.push(n);var d=zr(["katex-html"],s);if(d.setAttribute("aria-hidden","true"),h){var c=h.children[0];c.style.height=V(d.height+d.depth),d.depth&&(c.style.verticalAlign=V(-d.depth))}return d}function E4(i){return new ms(i)}function e1(i){if(!i)return!1;if(i.type==="mi"&&i.children.length===1){var e=i.children[0];return e instanceof ki&&e.text==="."}else if(i.type==="mo"&&i.children.length===1&&i.getAttribute("separator")==="true"&&i.getAttribute("lspace")==="0em"&&i.getAttribute("rspace")==="0em"){var t=i.children[0];return t instanceof ki&&t.text===","}else return!1}function j6(i,e,t,r,n){var s=ti(i,t),a;s.length===1&&s[0]instanceof Bt&&["mrow","mtable"].includes(s[0].type)?a=s[0]:a=new $.MathNode("mrow",s);var o=new $.MathNode("annotation",[new $.TextNode(e)]);o.setAttribute("encoding","application/x-tex");var l=new $.MathNode("semantics",[a,o]),h=new $.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),r&&h.setAttribute("display","block");var d=n?"katex":"katex-mathml";return z.makeSpan([d],[h])}function me(i,e){if(!i||i.type!==e)throw new Error("Expected node of type "+e+", but got "+(i?"node of type "+i.type:String(i)));return i}function A1(i){var e=Ih(i);if(!e)throw new Error("Expected node of symbol group type, but got "+(i?"node of type "+i.type:String(i)));return e}function Ih(i){return i&&(i.type==="atom"||PS.hasOwnProperty(i.type))?i:null}function C4(i,e){var t=ct(i.body,e,!0);return mA([i.mclass],t,e)}function _4(i,e){var t,r=ti(i.body,e);return i.mclass==="minner"?t=new $.MathNode("mpadded",r):i.mclass==="mord"?i.isCharacterBox?(t=r[0],t.type="mi"):t=new $.MathNode("mi",r):(i.isCharacterBox?(t=r[0],t.type="mo"):t=new $.MathNode("mo",r),i.mclass==="mbin"?(t.attributes.lspace="0.22em",t.attributes.rspace="0.22em"):i.mclass==="mpunct"?(t.attributes.lspace="0em",t.attributes.rspace="0.17em"):i.mclass==="mopen"||i.mclass==="mclose"?(t.attributes.lspace="0em",t.attributes.rspace="0em"):i.mclass==="minner"&&(t.attributes.lspace="0.0556em",t.attributes.width="+0.1111em")),t}function xA(i,e,t){var r=pA[i];switch(r){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return t.callFunction(r,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var n=t.callFunction("\\\\cdleft",[e[0]],[]),s={type:"atom",text:r,mode:"math",family:"rel"},a=t.callFunction("\\Big",[s],[]),o=t.callFunction("\\\\cdright",[e[1]],[]),l={type:"ordgroup",mode:"math",body:[n,a,o]};return t.callFunction("\\\\cdparent",[l],[])}case"\\\\cdlongequal":return t.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return t.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function yA(i){var e=[];for(i.gullet.beginGroup(),i.gullet.macros.set("\\cr","\\\\\\relax"),i.gullet.beginGroup();;){e.push(i.parseExpression(!1,"\\\\")),i.gullet.endGroup(),i.gullet.beginGroup();var t=i.fetch().text;if(t==="&"||t==="\\\\")i.consume();else if(t==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new G("Expected \\\\ or \\cr or \\end",i.nextToken)}for(var r=[],n=[r],s=0;s-1))if("<>AV".indexOf(h)>-1)for(var c=0;c<2;c++){for(var f=!0,m=l+1;mAV=|." after @',a[l]);var g=xA(h,d,i),x={type:"styling",body:[g],mode:"math",style:"display"};r.push(x),o=G6()}s%2===0?r.push(o):r.shift(),r=[],n.push(r)}i.gullet.endGroup(),i.gullet.endGroup();var y=new Array(n[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:n,arraystretch:1,addJot:!0,rowGaps:[null],cols:y,colSeparationType:"CD",hLinesBeforeRow:new Array(n.length+1).fill([])}}function Rh(i,e){var t=Ih(i);if(t&&LA.includes(t.text))return t;throw t?new G("Invalid delimiter '"+t.text+"' after '"+e.funcName+"'",i):new G("Invalid delimiter type '"+i.type+"'",i)}function Y6(i){if(!i.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}function ur(i){for(var{type:e,names:t,props:r,handler:n,htmlBuilder:s,mathmlBuilder:a}=i,o={type:e,numArgs:r.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l1||!d)&&x.pop(),b.length{Jt=class i{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?!e||!e.loc||!t.loc||e.loc.lexer!==t.loc.lexer?null:new i(e.loc.lexer,e.loc.start,t.loc.end):e&&e.loc}},ui=class i{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new i(t,Jt.range(this,e))}},G=class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r="KaTeX parse error: "+e,n,s,a=t&&t.loc;if(a&&a.start<=a.end){var o=a.lexer.input;n=a.start,s=a.end,n===o.length?r+=" at end of input: ":r+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332"),h;n>15?h="\u2026"+o.slice(n-15,n):h=o.slice(0,n);var d;s+15":">","<":"<",'"':""","'":"'"},oS=/[&><"']/g;u4=function i(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?i(e.body[0]):e:e.type==="font"?i(e.body):e},hS=function(e){var t=u4(e);return t.type==="mathord"||t.type==="textord"||t.type==="atom"},dS=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},cS=function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?t[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?null:t[1].toLowerCase():"_relative"},Ne={deflt:rS,escape:lS,hyphenate:sS,getBaseElem:u4,isCharacterBox:hS,protocolFromUrl:cS},bh={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:i=>"#"+i},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(i,e)=>(e.push(i),e)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:i=>Math.max(0,i),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:i=>Math.max(0,i),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:i=>Math.max(0,i),cli:"-e, --max-expand ",cliProcessor:i=>i==="Infinity"?1/0:parseInt(i)},globalGroup:{type:"boolean",cli:!1}};Qo=class{constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var t in bh)if(bh.hasOwnProperty(t)){var r=bh[t];this[t]=e[t]!==void 0?r.processor?r.processor(e[t]):e[t]:uS(r)}}reportNonstrict(e,t,r){var n=this.strict;if(typeof n=="function"&&(n=n(e,t,r)),!(!n||n==="ignore")){if(n===!0||n==="error")throw new G("LaTeX-incompatible input and strict mode is set to 'error': "+(t+" ["+e+"]"),r);n==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(t+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+n+"': "+t+" ["+e+"]"))}}useStrictBehavior(e,t,r){var n=this.strict;if(typeof n=="function")try{n=n(e,t,r)}catch{n="error"}return!n||n==="ignore"?!1:n===!0||n==="error"?!0:n==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(t+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+n+"': "+t+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var t=Ne.protocolFromUrl(e.url);if(t==null)return!1;e.protocol=t}var r=typeof this.trust=="function"?this.trust(e):this.trust;return!!r}},lr=class{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return hr[fS[this.id]]}sub(){return hr[mS[this.id]]}fracNum(){return hr[pS[this.id]]}fracDen(){return hr[gS[this.id]]}cramp(){return hr[xS[this.id]]}text(){return hr[yS[this.id]]}isTight(){return this.size>=2}},M1=0,Mh=1,ua=2,Lr=3,Jo=4,Ai=5,fa=6,Pt=7,hr=[new lr(M1,0,!1),new lr(Mh,0,!0),new lr(ua,1,!1),new lr(Lr,1,!0),new lr(Jo,2,!1),new lr(Ai,2,!0),new lr(fa,3,!1),new lr(Pt,3,!0)],fS=[Jo,Ai,Jo,Ai,fa,Pt,fa,Pt],mS=[Ai,Ai,Ai,Ai,Pt,Pt,Pt,Pt],pS=[ua,Lr,Jo,Ai,fa,Pt,fa,Pt],gS=[Lr,Lr,Ai,Ai,Pt,Pt,Pt,Pt],xS=[Mh,Mh,Lr,Lr,Ai,Ai,Pt,Pt],yS=[M1,Mh,ua,Lr,ua,Lr,ua,Lr],ae={DISPLAY:hr[M1],TEXT:hr[ua],SCRIPT:hr[Jo],SCRIPTSCRIPT:hr[fa]},d1=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];wh=[];d1.forEach(i=>i.blocks.forEach(e=>wh.push(...e)));ca=80,bS=function(e,t){return"M95,"+(622+e+t)+` + `,this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",g=>{g.stopPropagation()}),this.textEditNode.addEventListener("click",g=>{g.stopPropagation()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let{node:e,range:t}=this.activeOuterFrame,r=this.getStyle(this.getNodeRangeFirstNode(e,t)),[n,s,a,o]=r.textFillPadding,{defaultOuterFrameText:l,nodeTextEditZIndex:h}=this.mindMap.opt,d=this.mindMap.view.scale,c=this.getText(this.getNodeRangeFirstNode(e,t)),f=(c||l).split(/\n/gim);this.textEditNode.style.padding=`${n}px ${s}px ${a}px ${o}px`,this.textEditNode.style.fontFamily=r.fontFamily,this.textEditNode.style.fontSize=r.fontSize*d+"px",this.textEditNode.style.fontWeight=r.fontWeight,this.textEditNode.style.fontStyle=r.fontStyle,this.textEditNode.style.lineHeight=f.length>1?r.lineHeight:"normal",this.textEditNode.style.zIndex=h,this.textEditNode.innerHTML=f.join("
    "),this.textEditNode.style.display="block",this.updateTextEditBoxPos(i),this.setIsShowTextEdit(!0),c===""||c===l?ha(this.textEditNode):la(this.textEditNode)}function mS(i){this.showTextEdit=i,i?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}function pS(){if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}function gS(){this.hideEditTextBox()}function xS(i){let e=i.node.getBoundingClientRect();this.textEditNode&&(this.textEditNode.style.minWidth=`${e.width}px`,this.textEditNode.style.minHeight=`${e.height}px`,this.textEditNode.style.left=`${e.left}px`,this.textEditNode.style.top=`${e.top}px`)}function yS(){if(!this.showTextEdit)return;let{el:i,textNode:e,node:t,range:r}=this.activeOuterFrame,n=sa(this.textEditNode.innerHTML);n=n===this.mindMap.opt.defaultOuterFrameText?"":n,this.updateActiveOuterFrame({text:n}),this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.setIsShowTextEdit(!1),this.renderText(n,i,e,t,r),this.mindMap.emit("hide_text_edit")}function vS(i,e,t,r,n){if(!i)return;t.clear();let s=new Ve;t.add(s);let a=this.getStyle(this.getNodeRangeFirstNode(r,n)),[o,l,h,d]=a.textFillPadding,c=i.replace(/\n$/g,"").split(/\n/gim),f=new Le;c.forEach((k,L)=>{k===""&&(k="\uFEFF");let I=new _e().text(k);I.y(a.fontSize*a.lineHeight*L),this.styleText(I,a),f.add(I)}),t.add(f);let{width:m,height:g}=t.bbox(),x=m+o+h,y=g+l+d;s.size(x,y).x(0).dy(0),this.styleTextShape(s,a);let b=0;switch(a.textAlign){case"left":b=e.x();break;case"center":b=e.x()+e.width()/2-x/2;break;case"right":b=e.x()+e.width()-x;break;default:break}let E=e.y()-y;s.x(b),s.y(E),f.x(b+o),f.y(E+l)}function bS(i,e){i.fill({color:e.textFill}).radius(e.textFillRadius)}function wS(i,e){i.fill({color:e.color}).css({"font-family":e.fontFamily,"font-size":e.fontSize+"px","font-weight":e.fontWeight,"font-style":e.fontStyle})}function MS(i){let e=i.getData("outerFrame");return e&&e.text?e.text:""}var cS,s1,q6=T(()=>{wt();pe();cS="outer-frame-text-edit-warp";s1={getText:MS,createText:uS,styleTextShape:bS,styleText:wS,onScale:gS,showEditTextBox:fS,setIsShowTextEdit:mS,removeTextEditEl:pS,hideEditTextBox:yS,updateTextEditBoxPos:xS,renderText:vS}});var H6={};tt(H6,{default:()=>TS});var o1,a1,Jo,TS,U6=T(()=>{pe();F6();q6();o1={radius:5,strokeWidth:2,strokeColor:"#0984e3",strokeDasharray:"5,5",fill:"rgba(9,132,227,0.05)",fontSize:14,fontFamily:"\u5FAE\u8F6F\u96C5\u9ED1, Microsoft YaHei",fontWeight:"normal",fontStyle:"normal",color:"#fff",lineHeight:1.2,textFill:"#0984e3",textFillRadius:5,textFillPadding:[5,5,5,5],textAlign:"left"},a1="outer-frame-text-edit-warp",Jo=class{constructor(e={}){this.mindMap=e.mindMap,this.draw=null,this.createDrawContainer(),this.isNotRenderOuterFrames=!1,this.textNodeList=[],this.outerFrameElList=[],this.activeOuterFrame=null,this.textEditNode=null,this.showTextEdit=!1,Object.keys(s1).forEach(t=>{this[t]=s1[t].bind(this)}),this.mindMap.addEditNodeClass(a1),this.bindEvent()}createDrawContainer(){this.draw=this.mindMap.draw.group(),this.draw.addClass("smm-outer-frame-container"),this.draw.back(),this.draw.forward()}bindEvent(){this.renderOuterFrames=this.renderOuterFrames.bind(this),this.mindMap.on("node_tree_render_end",this.renderOuterFrames),this.mindMap.on("data_change",this.renderOuterFrames),this.clearActiveOuterFrame=this.clearActiveOuterFrame.bind(this),this.mindMap.on("draw_click",this.clearActiveOuterFrame),this.mindMap.on("node_click",this.clearActiveOuterFrame),this.mindMap.on("scale",this.onScale),this.onBeforeDestroy=this.onBeforeDestroy.bind(this),this.mindMap.on("beforeDestroy",this.onBeforeDestroy),this.addOuterFrame=this.addOuterFrame.bind(this),this.mindMap.command.add("ADD_OUTER_FRAME",this.addOuterFrame),this.removeActiveOuterFrame=this.removeActiveOuterFrame.bind(this),this.mindMap.keyCommand.addShortcut("Del|Backspace",this.removeActiveOuterFrame)}unBindEvent(){this.mindMap.off("node_tree_render_end",this.renderOuterFrames),this.mindMap.off("data_change",this.renderOuterFrames),this.mindMap.off("draw_click",this.clearActiveOuterFrame),this.mindMap.off("node_click",this.clearActiveOuterFrame),this.mindMap.off("scale",this.onScale),this.mindMap.off("beforeDestroy",this.onBeforeDestroy),this.mindMap.command.remove("ADD_OUTER_FRAME",this.addOuterFrame),this.mindMap.keyCommand.removeShortcut("Del|Backspace",this.removeActiveOuterFrame)}onBeforeDestroy(){this.hideEditTextBox(),this.removeTextEditEl()}addOuterFrame(e,t={}){e=Ot(e);let r=this.mindMap.renderer.activeNodeList;if(r.length<=0&&e.length<=0)return;let n=e.length>0?e:r;n=n.filter(a=>!a.isRoot&&!a.isGeneralization),B6(n).forEach(({node:a,range:o})=>{let l=a.children.slice(o[0],o[1]+1),h=Tt();l.forEach(d=>{let c=d.getData("outerFrame");c?c={...c,...t,groupId:h}:c={...t,groupId:h},this.mindMap.execCommand("SET_NODE_DATA",d,{outerFrame:c})})})}getActiveOuterFrame(){return this.activeOuterFrame?{...this.activeOuterFrame}:null}removeActiveOuterFrame(){if(!this.activeOuterFrame)return;let{node:e,range:t}=this.activeOuterFrame;this.getRangeNodeList(e,t).forEach(r=>{this.mindMap.execCommand("SET_NODE_DATA",r,{outerFrame:null})}),this.mindMap.emit("outer_frame_delete")}removeActiveOuterFrameText(){this.updateActiveOuterFrame({text:""})}updateActiveOuterFrame(e={}){if(!this.activeOuterFrame)return;this.isNotRenderOuterFrames=!0;let{el:t,node:r,range:n}=this.activeOuterFrame,s="";this.getRangeNodeList(r,n).forEach(a=>{let l={...a.getData("outerFrame"),...e};s=l.strokeDasharray,this.mindMap.execCommand("SET_NODE_DATA",a,{outerFrame:l})}),t.cacheStyle={dasharray:s},this.updateOuterFrameStyle()}updateOuterFrameStyle(){let{el:e,node:t,range:r,textNode:n}=this.activeOuterFrame,s=this.getNodeRangeFirstNode(t,r),a=this.getStyle(s);this.styleOuterFrame(e,{...a,strokeDasharray:"none"});let o=this.getText(s);this.renderText(o,e,n,t,r)}getRangeNodeList(e,t){return e.children.slice(t[0],t[1]+1).filter(r=>r.getData("outerFrame"))}getNodeRangeFirstNode(e,t){return e.children[t[0]]}renderOuterFrames(){if(this.isNotRenderOuterFrames){this.isNotRenderOuterFrames=!1;return}this.clearActiveOuterFrame(),this.clearTextNodes(),this.clearOuterFrameElList();let e=this.mindMap.renderer.root;if(!e)return;let t=this.mindMap.draw.transform(),{outerFramePaddingX:r,outerFramePaddingY:n}=this.mindMap.opt;ue(e,null,s=>{if(!s)return;let a=P6(s);a&&a.length>0&&a.forEach(({nodeList:o,range:l})=>{if(l[0]===-1||l[1]===-1)return;let{left:h,top:d,width:c,height:f}=X2(o);if(!Number.isFinite(h)||!Number.isFinite(d)||!Number.isFinite(c)||!Number.isFinite(f))return;let m=this.createOuterFrameEl((h-r-this.mindMap.elRect.left-t.translateX)/t.scaleX,(d-n-this.mindMap.elRect.top-t.translateY)/t.scaleY,(c+r*2)/t.scaleX,(f+n*2)/t.scaleY,this.getStyle(o[0])),g=this.createText(m,s,l);this.textNodeList.push(g),this.renderText(this.getText(o[0]),m,g,s,l),m.on("click",x=>{x.stopPropagation(),this.setActiveOuterFrame(m,s,l,g)})})},()=>{},!0,0)}setActiveOuterFrame(e,t,r,n){this.mindMap.execCommand("CLEAR_ACTIVE_NODE"),this.clearActiveOuterFrame(),this.activeOuterFrame={el:e,node:t,range:r,textNode:n},e.stroke({dasharray:"none"}),this.getText(this.getNodeRangeFirstNode(t,r))||this.renderText(this.mindMap.opt.defaultOuterFrameText,e,n,t,r),this.mindMap.emit("outer_frame_active",e,t,r)}clearActiveOuterFrame(){if(!this.activeOuterFrame)return;let{el:e,textNode:t,node:r,range:n}=this.activeOuterFrame;e.stroke({dasharray:e.cacheStyle.dasharray||o1.strokeDasharray}),this.hideEditTextBox(),this.getText(this.getNodeRangeFirstNode(r,n))||t.clear(),this.activeOuterFrame=null,this.mindMap.emit("outer_frame_deactivate")}getStyle(e){return{...o1,...e.getData("outerFrame")||{}}}createOuterFrameEl(e,t,r,n,s={}){let a=this.draw.rect().size(r,n).x(e).y(t);return this.styleOuterFrame(a,s),a.cacheStyle={dasharray:s.strokeDasharray},this.outerFrameElList.push(a),a}styleOuterFrame(e,t){e.radius(t.radius).stroke({width:t.strokeWidth,color:t.strokeColor,dasharray:t.strokeDasharray}).fill({color:t.fill})}clearTextNodes(){this.textNodeList.forEach(e=>{e.remove()})}clearOuterFrameElList(){this.outerFrameElList.forEach(e=>{e.remove()}),this.outerFrameElList=[],this.activeOuterFrame=null}beforePluginRemove(){this.mindMap.deleteEditNodeClass(a1),this.unBindEvent()}beforePluginDestroy(){this.mindMap.deleteEditNodeClass(a1),this.unBindEvent()}};Jo.instanceName="outerFrame";Jo.defaultStyle=o1;TS=Jo});var $6={};tt($6,{default:()=>NS});var mh,NS,j6=T(()=>{pe();Ge();mh=class{constructor(e){this.mindMap=e.mindMap,this.scrollbarWrapSize={width:0,height:0},this.chartHeight=0,this.chartWidth=0,this.reset(),this.bindEvent()}reset(){this.currentScrollType="",this.isMousedown=!1,this.mousedownPos={x:0,y:0},this.mousedownScrollbarPos=0}bindEvent(){this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.updateScrollbar=this.updateScrollbar.bind(this),this.updateScrollbar=Ai(this.updateScrollbar,16,this),this.mindMap.on("mousemove",this.onMousemove),this.mindMap.on("mouseup",this.onMouseup),this.mindMap.on("node_tree_render_end",this.updateScrollbar),this.mindMap.on("view_data_change",this.updateScrollbar),this.mindMap.on("resize",this.updateScrollbar)}unBindEvent(){this.mindMap.off("mousemove",this.onMousemove),this.mindMap.off("mouseup",this.onMouseup),this.mindMap.off("node_tree_render_end",this.updateScrollbar),this.mindMap.off("view_data_change",this.updateScrollbar),this.mindMap.off("resize",this.updateScrollbar)}updateScrollbar(){if(this.isMousedown)return;let e=this.calculationScrollbar();this.emitEvent(e)}emitEvent(e){this.mindMap.emit("scrollbar_change",e)}setScrollBarWrapSize(e,t){this.scrollbarWrapSize.width=e,this.scrollbarWrapSize.height=t}calculationScrollbar(){let e=this.mindMap.draw.rbox(),t=this.mindMap.elRect;e.x-=t.left,e.y-=t.top;let r=this.mindMap.height,n=r/2,s=e.height+n*2;this.chartHeight=s;let a=e.y-n,o=Math.min(r/s*100,100),l=-a/s*100;l<0&&(l=0),l>100-o&&(l=100-o);let h=this.mindMap.width,d=h/2,c=e.width+d*2;this.chartWidth=c;let f=e.x-d,m=Math.min(h/c*100,100),g=-f/c*100;return g<0&&(g=0),g>100-m&&(g=100-m),{vertical:{top:l,height:o},horizontal:{left:g,width:m}}}onMousedown(e,t){e.preventDefault(),e.stopPropagation(),this.currentScrollType=t,this.isMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let r=window.getComputedStyle(e.target);t===C.SCROLL_BAR_DIR.VERTICAL?this.mousedownScrollbarPos=Number.parseFloat(r.top):this.mousedownScrollbarPos=Number.parseFloat(r.left)}onMousemove(e){if(this.isMousedown)if(e.preventDefault(),e.stopPropagation(),this.currentScrollType===C.SCROLL_BAR_DIR.VERTICAL){let t=e.clientY-this.mousedownPos.y+this.mousedownScrollbarPos;this.updateMindMapView(C.SCROLL_BAR_DIR.VERTICAL,t)}else{let t=e.clientX-this.mousedownPos.x+this.mousedownScrollbarPos;this.updateMindMapView(C.SCROLL_BAR_DIR.HORIZONTAL,t)}}onMouseup(){this.isMousedown=!1,this.reset()}updateMindMapView(e,t){let r=this.calculationScrollbar(),n=this.mindMap.draw.transform(),s=this.mindMap.draw.rbox(),a=this.mindMap.renderer.root.group.rbox(),o=this.mindMap.renderer.layout.getRootCenterOffset(a.width,a.height);if(e===C.SCROLL_BAR_DIR.VERTICAL){let l=t;l<=0&&(l=0);let h=(100-r.vertical.height)/100*this.scrollbarWrapSize.height;l>=h&&(l=h);let d=l/this.scrollbarWrapSize.height*100,c=-d/100*this.chartHeight,f=a.y-s.y,m=this.mindMap.height/2,g=c+f-m*n.scaleY+m-o.y*n.scaleY+(this.mindMap.height-this.mindMap.initHeight)/2*n.scaleY;this.mindMap.view.translateYTo(g),this.emitEvent({horizontal:r.horizontal,vertical:{top:d,height:r.vertical.height}})}else{let l=t;l<=0&&(l=0);let h=(100-r.horizontal.width)/100*this.scrollbarWrapSize.width;l>=h&&(l=h);let d=l/this.scrollbarWrapSize.width*100,c=-d/100*this.chartWidth,f=a.x-s.x,m=this.mindMap.width/2,g=c+f-m*n.scaleX+m-o.x*n.scaleX+(this.mindMap.width-this.mindMap.initWidth)/2*n.scaleX;this.mindMap.view.translateXTo(g),this.emitEvent({vertical:r.vertical,horizontal:{left:d,width:r.horizontal.width}})}}onClick(e,t){let r=0;t===C.SCROLL_BAR_DIR.VERTICAL?r=e.clientY-e.currentTarget.getBoundingClientRect().top:r=e.clientX-e.currentTarget.getBoundingClientRect().left,this.updateMindMapView(t,r)}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};mh.instanceName="scrollbar";NS=mh});var G6={};tt(G6,{default:()=>ES});var ph,ES,W6=T(()=>{pe();ph=class{constructor(e){this.mindMap=e.mindMap,this.isMousedown=!1,this.mousedownPos={x:0,y:0},this.startViewPos={x:0,y:0},this.currentState=null}calculationMiniMap(e,t){let{svg:r,rect:n,origWidth:s,origHeight:a,scaleX:o,scaleY:l}=this.mindMap.getSvgData({ignoreWatermark:!0}),h=this.mindMap.elRect;n.x-=h.left,n.x2-=h.left,n.y-=h.top,n.y2-=h.top;let d=e/t,c=0,f=0;d>n.ratio?(f=t,c=n.ratio*f):(c=e,f=c/n.ratio);let m=c/n.width,g=(e-c)/2,x=(t-f)/2,y=n.width*o,b=n.height*l,E=(y-n.width)/2,k=(b-n.height)/2,L=n.x-E,I=n.x2+E,O=n.y-k,q=n.y2+k,F={left:0,top:0,right:0,bottom:0};F.left=Math.max(0,-L/y*c)+g,F.right=Math.max(0,(I-s)/y*c)+g,F.top=Math.max(0,-O/b*f)+x,F.bottom=Math.max(0,(q-a)/b*f)+x,F.top>x+f&&(F.top=x+f),F.left>g+c&&(F.left=g+c),Object.keys(F).forEach(ne=>{F[ne]=F[ne]+"px"}),this.removeNodeContent(r);let W=r.svg();return this.currentState={viewBoxStyle:{...F},miniMapBoxScale:m,miniMapBoxLeft:g,miniMapBoxTop:x},{getImgUrl:async ne=>{let re=await this.mindMap.doExport.fixSvgStrAndToBlob(W);ne(re)},svgHTML:W,viewBoxStyle:F,miniMapBoxScale:m,miniMapBoxLeft:g,miniMapBoxTop:x}}removeNodeContent(e){if(e.hasClass("smm-node")){let r=e.findOne(".smm-node-shape"),n=r.attr("fill");(Uo(n)||Eu(n))&&r.attr("fill",Z0(this.mindMap.themeConfig)),e.clear(),e.add(r);return}let t=e.children();t&&t.length>0&&t.forEach(r=>{this.removeNodeContent(r)})}onMousedown(e){this.isMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let t=this.mindMap.view.getTransformData();this.startViewPos={x:t.state.x,y:t.state.y}}onMousemove(e,t=5){if(!this.isMousedown||this.isViewBoxMousedown)return;let r=e.clientX-this.mousedownPos.x,n=e.clientY-this.mousedownPos.y;this.mindMap.view.translateXTo(r*t+this.startViewPos.x),this.mindMap.view.translateYTo(n*t+this.startViewPos.y)}onMouseup(){this.isMousedown=!1,this.isViewBoxMousedown=!1}onViewBoxMousedown(e){this.isViewBoxMousedown=!0,this.mousedownPos={x:e.clientX,y:e.clientY};let t=this.mindMap.view.getTransformData();this.startViewPos={x:t.state.x,y:t.state.y}}onViewBoxMousemove(e){if(!this.isViewBoxMousedown||!this.currentState||this.isMousedown)return;let t=e.clientX-this.mousedownPos.x,r=e.clientY-this.mousedownPos.y,{viewBoxStyle:n,miniMapBoxScale:s,miniMapBoxLeft:a,miniMapBoxTop:o}=this.currentState,l=Math.max(a,Number.parseFloat(n.left)+t),h=Math.max(a,Number.parseFloat(n.right)-t),d=Math.max(o,Number.parseFloat(n.top)+r),c=Math.max(o,Number.parseFloat(n.bottom)-r);this.mindMap.emit("mini_map_view_box_position_change",{left:l+"px",right:h+"px",top:d+"px",bottom:c+"px"}),this.mindMap.view.translateXTo(-t/s+this.startViewPos.x),this.mindMap.view.translateYTo(-r/s+this.startViewPos.y)}};ph.instanceName="miniMap";ES=ph});var V6={};tt(V6,{default:()=>SS});var gh,SS,Y6=T(()=>{pe();gh=class{constructor({mindMap:e}){this.mindMap=e,this.isInPainter=!1,this.painterNode=null,this.bindEvent()}bindEvent(){this.painterOneNode=this.painterOneNode.bind(this),this.onEndPainter=this.onEndPainter.bind(this),this.mindMap.on("node_click",this.painterOneNode),this.mindMap.on("draw_click",this.onEndPainter)}unBindEvent(){this.mindMap.off("node_click",this.painterOneNode),this.mindMap.off("draw_click",this.onEndPainter)}startPainter(){if(this.mindMap.opt.readonly)return;let e=this.mindMap.renderer.activeNodeList;e.length<=0||(this.painterNode=e[0],this.isInPainter=!0,this.mindMap.emit("painter_start"))}endPainter(){this.painterNode=null,this.isInPainter=!1}onEndPainter(){this.isInPainter&&(this.endPainter(),this.mindMap.emit("painter_end"))}painterOneNode(e){if(!e||!this.isInPainter||!this.painterNode||!e||e.uid===this.painterNode.uid)return;let t={};this.mindMap.opt.onlyPainterNodeCustomStyles||(t={...this.painterNode.effectiveStyles});let r=this.painterNode.getData();Object.keys(r).forEach(n=>{hs(n)&&(t[n]=r[n])}),this.mindMap.renderer._handleRemoveCustomStyles(e.getData()),e.setStyles(t)}beforePluginRemove(){this.unBindEvent()}beforePluginDestroy(){this.unBindEvent()}};gh.instanceName="painter";SS=gh});function IS(i){return String(i).replace(LS,e=>_S[e])}function OS(i){if(i.default)return i.default;var e=i.type,t=Array.isArray(e)?e[0]:e;if(typeof t!="string")return t.enum[0];switch(t){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}function $S(i){for(var e=0;e=n[0]&&i<=n[1])return t.name}return null}function A4(i){for(var e=0;e=Ch[e]&&i<=Ch[e+1])return!0;return!1}function eA(i,e){lr[i]=e}function R1(i,e,t){if(!lr[e])throw new Error("Font metrics not found for font: "+e+".");var r=i.charCodeAt(0),n=lr[e][r];if(!n&&i[0]in K6&&(r=K6[i[0]].charCodeAt(0),n=lr[e][r]),!n&&t==="text"&&A4(r)&&(n=lr[e][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}function tA(i){var e;if(i>=5?e=0:i>=3?e=1:e=2,!l1[e]){var t=l1[e]={cssEmPerMu:xh.quad[e]/18};for(var r in xh)xh.hasOwnProperty(r)&&(t[r]=xh[r][e])}return l1[e]}function J6(i){if(i instanceof ii)return i;throw new Error("Expected symbolNode but got "+String(i)+".")}function aA(i){if(i instanceof ps)return i;throw new Error("Expected span but got "+String(i)+".")}function u(i,e,t,r,n,s){Be[i][n]={font:e,group:t,replace:r},s&&r&&(Be[i][r]=Be[i][n])}function Z(i){for(var{type:e,names:t,props:r,handler:n,htmlBuilder:s,mathmlBuilder:a}=i,o={type:e,numArgs:r.numArgs,argTypes:r.argTypes,allowedInArgument:!!r.allowedInArgument,allowedInText:!!r.allowedInText,allowedInMath:r.allowedInMath===void 0?!0:r.allowedInMath,numOptionalArgs:r.numOptionalArgs||0,infix:!!r.infix,primitive:!!r.primitive,handler:n},l=0;l0&&(s.push(Nh(a,e)),a=[]),s.push(r[o]));a.length>0&&s.push(Nh(a,e));var h;t?(h=Nh(mt(t,e,!0)),h.classes=["tag"],s.push(h)):n&&s.push(n);var d=zr(["katex-html"],s);if(d.setAttribute("aria-hidden","true"),h){var c=h.children[0];c.style.height=V(d.height+d.depth),d.depth&&(c.style.verticalAlign=V(-d.depth))}return d}function F4(i){return new ms(i)}function c1(i){if(!i)return!1;if(i.type==="mi"&&i.children.length===1){var e=i.children[0];return e instanceof Ci&&e.text==="."}else if(i.type==="mo"&&i.children.length===1&&i.getAttribute("separator")==="true"&&i.getAttribute("lspace")==="0em"&&i.getAttribute("rspace")==="0em"){var t=i.children[0];return t instanceof Ci&&t.text===","}else return!1}function n4(i,e,t,r,n){var s=ri(i,t),a;s.length===1&&s[0]instanceof Bt&&["mrow","mtable"].includes(s[0].type)?a=s[0]:a=new $.MathNode("mrow",s);var o=new $.MathNode("annotation",[new $.TextNode(e)]);o.setAttribute("encoding","application/x-tex");var l=new $.MathNode("semantics",[a,o]),h=new $.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),r&&h.setAttribute("display","block");var d=n?"katex":"katex-mathml";return z.makeSpan([d],[h])}function me(i,e){if(!i||i.type!==e)throw new Error("Expected node of type "+e+", but got "+(i?"node of type "+i.type:String(i)));return i}function P1(i){var e=qh(i);if(!e)throw new Error("Expected node of symbol group type, but got "+(i?"node of type "+i.type:String(i)));return e}function qh(i){return i&&(i.type==="atom"||lA.hasOwnProperty(i.type))?i:null}function $4(i,e){var t=mt(i.body,e,!0);return PA([i.mclass],t,e)}function j4(i,e){var t,r=ri(i.body,e);return i.mclass==="minner"?t=new $.MathNode("mpadded",r):i.mclass==="mord"?i.isCharacterBox?(t=r[0],t.type="mi"):t=new $.MathNode("mi",r):(i.isCharacterBox?(t=r[0],t.type="mo"):t=new $.MathNode("mo",r),i.mclass==="mbin"?(t.attributes.lspace="0.22em",t.attributes.rspace="0.22em"):i.mclass==="mpunct"?(t.attributes.lspace="0em",t.attributes.rspace="0.17em"):i.mclass==="mopen"||i.mclass==="mclose"?(t.attributes.lspace="0em",t.attributes.rspace="0em"):i.mclass==="minner"&&(t.attributes.lspace="0.0556em",t.attributes.width="+0.1111em")),t}function HA(i,e,t){var r=FA[i];switch(r){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return t.callFunction(r,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var n=t.callFunction("\\\\cdleft",[e[0]],[]),s={type:"atom",text:r,mode:"math",family:"rel"},a=t.callFunction("\\Big",[s],[]),o=t.callFunction("\\\\cdright",[e[1]],[]),l={type:"ordgroup",mode:"math",body:[n,a,o]};return t.callFunction("\\\\cdparent",[l],[])}case"\\\\cdlongequal":return t.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return t.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function UA(i){var e=[];for(i.gullet.beginGroup(),i.gullet.macros.set("\\cr","\\\\\\relax"),i.gullet.beginGroup();;){e.push(i.parseExpression(!1,"\\\\")),i.gullet.endGroup(),i.gullet.beginGroup();var t=i.fetch().text;if(t==="&"||t==="\\\\")i.consume();else if(t==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new G("Expected \\\\ or \\cr or \\end",i.nextToken)}for(var r=[],n=[r],s=0;s-1))if("<>AV".indexOf(h)>-1)for(var c=0;c<2;c++){for(var f=!0,m=l+1;mAV=|." after @',a[l]);var g=HA(h,d,i),x={type:"styling",body:[g],mode:"math",style:"display"};r.push(x),o=s4()}s%2===0?r.push(o):r.shift(),r=[],n.push(r)}i.gullet.endGroup(),i.gullet.endGroup();var y=new Array(n[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:n,arraystretch:1,addJot:!0,rowGaps:[null],cols:y,colSeparationType:"CD",hLinesBeforeRow:new Array(n.length+1).fill([])}}function Uh(i,e){var t=qh(i);if(t&&tk.includes(t.text))return t;throw t?new G("Invalid delimiter '"+t.text+"' after '"+e.funcName+"'",i):new G("Invalid delimiter type '"+i.type+"'",i)}function l4(i){if(!i.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}function dr(i){for(var{type:e,names:t,props:r,handler:n,htmlBuilder:s,mathmlBuilder:a}=i,o={type:e,numArgs:r.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l1||!d)&&x.pop(),b.length{ti=class i{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?!e||!e.loc||!t.loc||e.loc.lexer!==t.loc.lexer?null:new i(e.loc.lexer,e.loc.start,t.loc.end):e&&e.loc}},mi=class i{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new i(t,ti.range(this,e))}},G=class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r="KaTeX parse error: "+e,n,s,a=t&&t.loc;if(a&&a.start<=a.end){var o=a.lexer.input;n=a.start,s=a.end,n===o.length?r+=" at end of input: ":r+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332"),h;n>15?h="\u2026"+o.slice(n-15,n):h=o.slice(0,n);var d;s+15":">","<":"<",'"':""","'":"'"},LS=/[&><"']/g;S4=function i(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?i(e.body[0]):e:e.type==="font"?i(e.body):e},zS=function(e){var t=S4(e);return t.type==="mathord"||t.type==="textord"||t.type==="atom"},RS=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},DS=function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?t[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?null:t[1].toLowerCase():"_relative"},Ee={deflt:AS,escape:IS,hyphenate:CS,getBaseElem:S4,isCharacterBox:zS,protocolFromUrl:DS},kh={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:i=>"#"+i},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(i,e)=>(e.push(i),e)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:i=>Math.max(0,i),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:i=>Math.max(0,i),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:i=>Math.max(0,i),cli:"-e, --max-expand ",cliProcessor:i=>i==="Infinity"?1/0:parseInt(i)},globalGroup:{type:"boolean",cli:!1}};nl=class{constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var t in kh)if(kh.hasOwnProperty(t)){var r=kh[t];this[t]=e[t]!==void 0?r.processor?r.processor(e[t]):e[t]:OS(r)}}reportNonstrict(e,t,r){var n=this.strict;if(typeof n=="function"&&(n=n(e,t,r)),!(!n||n==="ignore")){if(n===!0||n==="error")throw new G("LaTeX-incompatible input and strict mode is set to 'error': "+(t+" ["+e+"]"),r);n==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(t+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+n+"': "+t+" ["+e+"]"))}}useStrictBehavior(e,t,r){var n=this.strict;if(typeof n=="function")try{n=n(e,t,r)}catch{n="error"}return!n||n==="ignore"?!1:n===!0||n==="error"?!0:n==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(t+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+n+"': "+t+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var t=Ee.protocolFromUrl(e.url);if(t==null)return!1;e.protocol=t}var r=typeof this.trust=="function"?this.trust(e):this.trust;return!!r}},ar=class{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return or[BS[this.id]]}sub(){return or[PS[this.id]]}fracNum(){return or[FS[this.id]]}fracDen(){return or[qS[this.id]]}cramp(){return or[HS[this.id]]}text(){return or[US[this.id]]}isTight(){return this.size>=2}},z1=0,_h=1,fa=2,Lr=3,sl=4,ki=5,ma=6,Pt=7,or=[new ar(z1,0,!1),new ar(_h,0,!0),new ar(fa,1,!1),new ar(Lr,1,!0),new ar(sl,2,!1),new ar(ki,2,!0),new ar(ma,3,!1),new ar(Pt,3,!0)],BS=[sl,ki,sl,ki,ma,Pt,ma,Pt],PS=[ki,ki,ki,ki,Pt,Pt,Pt,Pt],FS=[fa,Lr,sl,ki,ma,Pt,ma,Pt],qS=[Lr,Lr,ki,ki,Pt,Pt,Pt,Pt],HS=[_h,_h,Lr,Lr,ki,ki,Pt,Pt],US=[z1,_h,fa,Lr,fa,Lr,fa,Lr],ae={DISPLAY:or[z1],TEXT:or[fa],SCRIPT:or[sl],SCRIPTSCRIPT:or[ma]},w1=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];Ch=[];w1.forEach(i=>i.blocks.forEach(e=>Ch.push(...e)));ua=80,jS=function(e,t){return"M95,"+(622+e+t)+` c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 @@ -90,7 +90,7 @@ c5.3,-9.3,12,-14,20,-14 H400000v`+(40+e)+`H845.2724 s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z -M`+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},wS=function(e,t){return"M263,"+(601+e+t)+`c0.7,0,18,39.7,52,119 +M`+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},GS=function(e,t){return"M263,"+(601+e+t)+`c0.7,0,18,39.7,52,119 c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 c340,-704.7,510.7,-1060.3,512,-1067 l`+e/2.084+" -"+e+` @@ -100,7 +100,7 @@ s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5, c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z -M`+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},MS=function(e,t){return"M983 "+(10+e+t)+` +M`+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},WS=function(e,t){return"M983 "+(10+e+t)+` l`+e/3.13+" -"+e+` c4,-6.7,10,-10,18,-10 H400000v`+(40+e)+` H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7 @@ -109,7 +109,7 @@ c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30 c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722 c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5 c53.7,-170.3,84.5,-266.8,92.5,-289.5z -M`+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},TS=function(e,t){return"M424,"+(2398+e+t)+` +M`+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"},VS=function(e,t){return"M424,"+(2398+e+t)+` c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514 c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20 s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121 @@ -119,18 +119,18 @@ v`+(40+e)+`H1014.6 s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185 c-2,6,-10,9,-24,9 c-8,0,-12,-0.7,-12,-2z M`+(1001+e)+" "+t+` -h400000v`+(40+e)+"h-400000z"},NS=function(e,t){return"M473,"+(2713+e+t)+` +h400000v`+(40+e)+"h-400000z"},YS=function(e,t){return"M473,"+(2713+e+t)+` c339.3,-1799.3,509.3,-2700,510,-2702 l`+e/5.298+" -"+e+` c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+e)+`H1017.7 s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9 c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200 c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26 s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104, -606zM`+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"},ES=function(e){var t=e/2;return"M400000 "+e+" H0 L"+t+" 0 l65 45 L145 "+(e-80)+" H400000z"},SS=function(e,t,r){var n=r-54-t-e;return"M702 "+(e+t)+"H400000"+(40+e)+` +606zM`+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"},XS=function(e){var t=e/2;return"M400000 "+e+" H0 L"+t+" 0 l65 45 L145 "+(e-80)+" H400000z"},KS=function(e,t,r){var n=r-54-t-e;return"M702 "+(e+t)+"H400000"+(40+e)+` H742v`+n+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1 h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170 c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 -219 661 l218 661zM702 `+t+"H400000v"+(40+e)+"H742z"},AS=function(e,t,r){t=1e3*t;var n="";switch(e){case"sqrtMain":n=bS(t,ca);break;case"sqrtSize1":n=wS(t,ca);break;case"sqrtSize2":n=MS(t,ca);break;case"sqrtSize3":n=TS(t,ca);break;case"sqrtSize4":n=NS(t,ca);break;case"sqrtTall":n=SS(t,ca,r)}return n},kS=function(e,t){switch(e){case"\u239C":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z"+("M367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z");case"\u239F":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23A2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23A5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23AA":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23D0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257z"+("M478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z");default:return""}},D6={doubleleftarrow:`M262 157 +219 661 l218 661zM702 `+t+"H400000v"+(40+e)+"H742z"},ZS=function(e,t,r){t=1e3*t;var n="";switch(e){case"sqrtMain":n=jS(t,ua);break;case"sqrtSize1":n=GS(t,ua);break;case"sqrtSize2":n=WS(t,ua);break;case"sqrtSize3":n=VS(t,ua);break;case"sqrtSize4":n=YS(t,ua);break;case"sqrtTall":n=KS(t,ua,r)}return n},QS=function(e,t){switch(e){case"\u239C":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z"+("M367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z");case"\u239F":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23A2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23A5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23AA":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23D0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257z"+("M478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z");default:return""}},X6={doubleleftarrow:`M262 157 l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5 @@ -305,7 +305,7 @@ M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z` c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199, -231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6 c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z -M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},CS=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+` v1759 h347 v-84 +M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},JS=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+` v1759 h347 v-84 H403z M403 1759 V0 H319 V1759 v`+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+` v1759 H0 v84 H347z M347 1759 V0 H263 V1759 v`+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+` v585 c2.667,10,9.667,15,21,15 c10,0,16.667,-5,20,-15 v-585 v`+-t+` v-585 c-2.667,-10,-9.667,-15,-21,-15 @@ -333,61 +333,61 @@ c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6 c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17 c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558 l0,-`+(t+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7, --470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}},ms=class{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return this.classes.includes(e)}toNode(){for(var e=document.createDocumentFragment(),t=0;tt.toText();return this.children.map(e).join("")}},dr={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},hh={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},O6={\u00C5:"A",\u00D0:"D",\u00DE:"o",\u00E5:"a",\u00F0:"d",\u00FE:"o",\u0410:"A",\u0411:"B",\u0412:"B",\u0413:"F",\u0414:"A",\u0415:"E",\u0416:"K",\u0417:"3",\u0418:"N",\u0419:"N",\u041A:"K",\u041B:"N",\u041C:"M",\u041D:"H",\u041E:"O",\u041F:"N",\u0420:"P",\u0421:"C",\u0422:"T",\u0423:"y",\u0424:"O",\u0425:"X",\u0426:"U",\u0427:"h",\u0428:"W",\u0429:"W",\u042A:"B",\u042B:"X",\u042C:"B",\u042D:"3",\u042E:"X",\u042F:"R",\u0430:"a",\u0431:"b",\u0432:"a",\u0433:"r",\u0434:"y",\u0435:"e",\u0436:"m",\u0437:"e",\u0438:"n",\u0439:"n",\u043A:"n",\u043B:"n",\u043C:"m",\u043D:"n",\u043E:"o",\u043F:"n",\u0440:"p",\u0441:"c",\u0442:"o",\u0443:"y",\u0444:"b",\u0445:"x",\u0446:"n",\u0447:"n",\u0448:"w",\u0449:"w",\u044A:"a",\u044B:"m",\u044C:"a",\u044D:"e",\u044E:"m",\u044F:"r"};Zu={};IS=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],B6=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],P6=function(e,t){return t.size<2?e:IS[e-1][t.size-1]},Th=class i{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||i.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=B6[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new i(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:P6(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:B6[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=P6(i.BASESIZE,e);return this.size===t&&this.textSize===i.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==i.BASESIZE?["sizing","reset-size"+this.size,"size"+i.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=LS(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}};Th.BASESIZE=6;c1={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},zS={ex:!0,em:!0,mu:!0},m4=function(e){return typeof e!="string"&&(e=e.unit),e in c1||e in zS||e==="ex"},Xe=function(e,t){var r;if(e.unit in c1)r=c1[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if(e.unit==="mu")r=t.fontMetrics().cssEmPerMu;else{var n;if(t.style.isTight()?n=t.havingStyle(t.style.text()):n=t,e.unit==="ex")r=n.fontMetrics().xHeight;else if(e.unit==="em")r=n.fontMetrics().quad;else throw new G("Invalid unit: '"+e.unit+"'");n!==t&&(r*=n.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},V=function(e){return+e.toFixed(4)+"em"},yn=function(e){return e.filter(t=>t).join(" ")},p4=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},g4=function(e){var t=document.createElement(e);t.className=yn(this.classes);for(var r in this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var s=0;s/=\x00-\x1f]/,x4=function(e){var t="<"+e;this.classes.length&&(t+=' class="'+Ne.escape(yn(this.classes))+'"');var r="";for(var n in this.style)this.style.hasOwnProperty(n)&&(r+=Ne.hyphenate(n)+":"+this.style[n]+";");r&&(t+=' style="'+Ne.escape(r)+'"');for(var s in this.attributes)if(this.attributes.hasOwnProperty(s)){if(RS.test(s))throw new G("Invalid attribute name '"+s+"'");t+=" "+s+'="'+Ne.escape(this.attributes[s])+'"'}t+=">";for(var a=0;a",t},ps=class{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,p4.call(this,e,r,n),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return g4.call(this,"span")}toMarkup(){return x4.call(this,"span")}},el=class{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,p4.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return g4.call(this,"a")}toMarkup(){return x4.call(this,"a")}},u1=class{constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return this.classes.includes(e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var t in this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e=''+Ne.escape(this.alt)+'0&&(t=document.createElement("span"),t.style.marginRight=V(this.italic)),this.classes.length>0&&(t=t||document.createElement("span"),t.className=yn(this.classes));for(var r in this.style)this.style.hasOwnProperty(r)&&(t=t||document.createElement("span"),t.style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;");for(var n in this.style)this.style.hasOwnProperty(n)&&(r+=Ne.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+Ne.escape(r)+'"');var s=Ne.escape(this.text);return e?(t+=">",t+=s,t+="",t):s}},Xi=class{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"svg");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&t.setAttribute(r,this.attributes[r]);for(var n=0;n':''}},tl=class{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"line");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&t.setAttribute(r,this.attributes[r]);return t}toMarkup(){var e="","\\gt",!0);u(p,v,E,"\u2208","\\in",!0);u(p,v,E,"\uE020","\\@not");u(p,v,E,"\u2282","\\subset",!0);u(p,v,E,"\u2283","\\supset",!0);u(p,v,E,"\u2286","\\subseteq",!0);u(p,v,E,"\u2287","\\supseteq",!0);u(p,N,E,"\u2288","\\nsubseteq",!0);u(p,N,E,"\u2289","\\nsupseteq",!0);u(p,v,E,"\u22A8","\\models");u(p,v,E,"\u2190","\\leftarrow",!0);u(p,v,E,"\u2264","\\le");u(p,v,E,"\u2264","\\leq",!0);u(p,v,E,"<","\\lt",!0);u(p,v,E,"\u2192","\\rightarrow",!0);u(p,v,E,"\u2192","\\to");u(p,N,E,"\u2271","\\ngeq",!0);u(p,N,E,"\u2270","\\nleq",!0);u(p,v,Dr,"\xA0","\\ ");u(p,v,Dr,"\xA0","\\space");u(p,v,Dr,"\xA0","\\nobreakspace");u(H,v,Dr,"\xA0","\\ ");u(H,v,Dr,"\xA0"," ");u(H,v,Dr,"\xA0","\\space");u(H,v,Dr,"\xA0","\\nobreakspace");u(p,v,Dr,null,"\\nobreak");u(p,v,Dr,null,"\\allowbreak");u(p,v,_h,",",",");u(p,v,_h,";",";");u(p,N,ie,"\u22BC","\\barwedge",!0);u(p,N,ie,"\u22BB","\\veebar",!0);u(p,v,ie,"\u2299","\\odot",!0);u(p,v,ie,"\u2295","\\oplus",!0);u(p,v,ie,"\u2297","\\otimes",!0);u(p,v,_,"\u2202","\\partial",!0);u(p,v,ie,"\u2298","\\oslash",!0);u(p,N,ie,"\u229A","\\circledcirc",!0);u(p,N,ie,"\u22A1","\\boxdot",!0);u(p,v,ie,"\u25B3","\\bigtriangleup");u(p,v,ie,"\u25BD","\\bigtriangledown");u(p,v,ie,"\u2020","\\dagger");u(p,v,ie,"\u22C4","\\diamond");u(p,v,ie,"\u22C6","\\star");u(p,v,ie,"\u25C3","\\triangleleft");u(p,v,ie,"\u25B9","\\triangleright");u(p,v,fi,"{","\\{");u(H,v,_,"{","\\{");u(H,v,_,"{","\\textbraceleft");u(p,v,Ft,"}","\\}");u(H,v,_,"}","\\}");u(H,v,_,"}","\\textbraceright");u(p,v,fi,"{","\\lbrace");u(p,v,Ft,"}","\\rbrace");u(p,v,fi,"[","\\lbrack",!0);u(H,v,_,"[","\\lbrack",!0);u(p,v,Ft,"]","\\rbrack",!0);u(H,v,_,"]","\\rbrack",!0);u(p,v,fi,"(","\\lparen",!0);u(p,v,Ft,")","\\rparen",!0);u(H,v,_,"<","\\textless",!0);u(H,v,_,">","\\textgreater",!0);u(p,v,fi,"\u230A","\\lfloor",!0);u(p,v,Ft,"\u230B","\\rfloor",!0);u(p,v,fi,"\u2308","\\lceil",!0);u(p,v,Ft,"\u2309","\\rceil",!0);u(p,v,_,"\\","\\backslash");u(p,v,_,"\u2223","|");u(p,v,_,"\u2223","\\vert");u(H,v,_,"|","\\textbar",!0);u(p,v,_,"\u2225","\\|");u(p,v,_,"\u2225","\\Vert");u(H,v,_,"\u2225","\\textbardbl");u(H,v,_,"~","\\textasciitilde");u(H,v,_,"\\","\\textbackslash");u(H,v,_,"^","\\textasciicircum");u(p,v,E,"\u2191","\\uparrow",!0);u(p,v,E,"\u21D1","\\Uparrow",!0);u(p,v,E,"\u2193","\\downarrow",!0);u(p,v,E,"\u21D3","\\Downarrow",!0);u(p,v,E,"\u2195","\\updownarrow",!0);u(p,v,E,"\u21D5","\\Updownarrow",!0);u(p,v,ot,"\u2210","\\coprod");u(p,v,ot,"\u22C1","\\bigvee");u(p,v,ot,"\u22C0","\\bigwedge");u(p,v,ot,"\u2A04","\\biguplus");u(p,v,ot,"\u22C2","\\bigcap");u(p,v,ot,"\u22C3","\\bigcup");u(p,v,ot,"\u222B","\\int");u(p,v,ot,"\u222B","\\intop");u(p,v,ot,"\u222C","\\iint");u(p,v,ot,"\u222D","\\iiint");u(p,v,ot,"\u220F","\\prod");u(p,v,ot,"\u2211","\\sum");u(p,v,ot,"\u2A02","\\bigotimes");u(p,v,ot,"\u2A01","\\bigoplus");u(p,v,ot,"\u2A00","\\bigodot");u(p,v,ot,"\u222E","\\oint");u(p,v,ot,"\u222F","\\oiint");u(p,v,ot,"\u2230","\\oiiint");u(p,v,ot,"\u2A06","\\bigsqcup");u(p,v,ot,"\u222B","\\smallint");u(H,v,ma,"\u2026","\\textellipsis");u(p,v,ma,"\u2026","\\mathellipsis");u(H,v,ma,"\u2026","\\ldots",!0);u(p,v,ma,"\u2026","\\ldots",!0);u(p,v,ma,"\u22EF","\\@cdots",!0);u(p,v,ma,"\u22F1","\\ddots",!0);u(p,v,_,"\u22EE","\\varvdots");u(H,v,_,"\u22EE","\\varvdots");u(p,v,je,"\u02CA","\\acute");u(p,v,je,"\u02CB","\\grave");u(p,v,je,"\xA8","\\ddot");u(p,v,je,"~","\\tilde");u(p,v,je,"\u02C9","\\bar");u(p,v,je,"\u02D8","\\breve");u(p,v,je,"\u02C7","\\check");u(p,v,je,"^","\\hat");u(p,v,je,"\u20D7","\\vec");u(p,v,je,"\u02D9","\\dot");u(p,v,je,"\u02DA","\\mathring");u(p,v,se,"\uE131","\\@imath");u(p,v,se,"\uE237","\\@jmath");u(p,v,_,"\u0131","\u0131");u(p,v,_,"\u0237","\u0237");u(H,v,_,"\u0131","\\i",!0);u(H,v,_,"\u0237","\\j",!0);u(H,v,_,"\xDF","\\ss",!0);u(H,v,_,"\xE6","\\ae",!0);u(H,v,_,"\u0153","\\oe",!0);u(H,v,_,"\xF8","\\o",!0);u(H,v,_,"\xC6","\\AE",!0);u(H,v,_,"\u0152","\\OE",!0);u(H,v,_,"\xD8","\\O",!0);u(H,v,je,"\u02CA","\\'");u(H,v,je,"\u02CB","\\`");u(H,v,je,"\u02C6","\\^");u(H,v,je,"\u02DC","\\~");u(H,v,je,"\u02C9","\\=");u(H,v,je,"\u02D8","\\u");u(H,v,je,"\u02D9","\\.");u(H,v,je,"\xB8","\\c");u(H,v,je,"\u02DA","\\r");u(H,v,je,"\u02C7","\\v");u(H,v,je,"\xA8",'\\"');u(H,v,je,"\u02DD","\\H");u(H,v,je,"\u25EF","\\textcircled");y4={"--":!0,"---":!0,"``":!0,"''":!0};u(H,v,_,"\u2013","--",!0);u(H,v,_,"\u2013","\\textendash");u(H,v,_,"\u2014","---",!0);u(H,v,_,"\u2014","\\textemdash");u(H,v,_,"\u2018","`",!0);u(H,v,_,"\u2018","\\textquoteleft");u(H,v,_,"\u2019","'",!0);u(H,v,_,"\u2019","\\textquoteright");u(H,v,_,"\u201C","``",!0);u(H,v,_,"\u201C","\\textquotedblleft");u(H,v,_,"\u201D","''",!0);u(H,v,_,"\u201D","\\textquotedblright");u(p,v,_,"\xB0","\\degree",!0);u(H,v,_,"\xB0","\\degree");u(H,v,_,"\xB0","\\textdegree",!0);u(p,v,_,"\xA3","\\pounds");u(p,v,_,"\xA3","\\mathsterling",!0);u(H,v,_,"\xA3","\\pounds");u(H,v,_,"\xA3","\\textsterling",!0);u(p,N,_,"\u2720","\\maltese");u(H,N,_,"\u2720","\\maltese");q6='0123456789/@."';for(dh=0;dh0)return Yi(s,h,n,t,a.concat(d));if(l){var c,f;if(l==="boldsymbol"){var m=HS(s,n,t,a,r);c=m.fontName,f=[m.fontClass]}else o?(c=w4[l].fontName,f=[l]):(c=ph(l,t.fontWeight,t.fontShape),f=[l,t.fontWeight,t.fontShape]);if(Lh(s,c,n).metrics)return Yi(s,c,n,t,a.concat(f));if(y4.hasOwnProperty(s)&&c.slice(0,10)==="Typewriter"){for(var g=[],x=0;x{if(yn(i.classes)!==yn(e.classes)||i.skew!==e.skew||i.maxFontSize!==e.maxFontSize)return!1;if(i.classes.length===1){var t=i.classes[0];if(t==="mbin"||t==="mord")return!1}for(var r in i.style)if(i.style.hasOwnProperty(r)&&i.style[r]!==e.style[r])return!1;for(var n in e.style)if(e.style.hasOwnProperty(n)&&i.style[n]!==e.style[n])return!1;return!0},jS=i=>{for(var e=0;et&&(t=a.height),a.depth>r&&(r=a.depth),a.maxFontSize>n&&(n=a.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Qt=function(e,t,r,n){var s=new ps(e,t,r,n);return N1(s),s},v4=(i,e,t,r)=>new ps(i,e,t,r),GS=function(e,t,r){var n=Qt([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=V(n.height),n.maxFontSize=1,n},VS=function(e,t,r,n){var s=new el(e,t,r,n);return N1(s),s},b4=function(e){var t=new ms(e);return N1(t),t},WS=function(e,t){return e instanceof ms?Qt([],[e],t):e},YS=function(e){if(e.positionType==="individualShift"){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,s=n,a=1;a{var t=Qt(["mspace"],[],e),r=Xe(i,e);return t.style.marginRight=V(r),t},ph=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}var s;return t==="textbf"&&r==="textit"?s="BoldItalic":t==="textbf"?s="Bold":t==="textit"?s="Italic":s="Regular",n+"-"+s},w4={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},M4={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},ZS=function(e,t){var[r,n,s]=M4[e],a=new cr(r),o=new Xi([a],{width:V(n),height:V(s),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+1e3*s,preserveAspectRatio:"xMinYMin"}),l=v4(["overlay"],[o],t);return l.height=s,l.style.height=V(s),l.style.width=V(n),l},z={fontMap:w4,makeSymbol:Yi,mathsym:qS,makeSpan:Qt,makeSvgSpan:v4,makeLineSpan:GS,makeAnchor:VS,makeFragment:b4,wrapFragment:WS,makeVList:XS,makeOrd:US,makeGlue:KS,staticSvg:ZS,svgData:M4,tryCombineChars:jS},Ye={number:3,unit:"mu"},fs={number:4,unit:"mu"},_r={number:5,unit:"mu"},QS={mord:{mop:Ye,mbin:fs,mrel:_r,minner:Ye},mop:{mord:Ye,mop:Ye,mrel:_r,minner:Ye},mbin:{mord:fs,mop:fs,mopen:fs,minner:fs},mrel:{mord:_r,mop:_r,mopen:_r,minner:_r},mopen:{},mclose:{mop:Ye,mbin:fs,mrel:_r,minner:Ye},mpunct:{mord:Ye,mop:Ye,mrel:_r,mopen:Ye,mclose:Ye,mpunct:Ye,minner:Ye},minner:{mord:Ye,mop:Ye,mbin:fs,mrel:_r,mopen:Ye,mpunct:Ye,minner:Ye}},JS={mord:{mop:Ye},mop:{mord:Ye,mop:Ye},mbin:{},mrel:{},mopen:{},mclose:{mop:Ye},mpunct:{},minner:{mop:Ye}},T4={},Eh={},Sh={};Ah=function(e){return e.type==="ordgroup"&&e.body.length===1?e.body[0]:e},rt=function(e){return e.type==="ordgroup"?e.body:[e]},zr=z.makeSpan,eA=["leftmost","mbin","mopen","mrel","mop","mpunct"],tA=["rightmost","mrel","mclose","mpunct"],iA={display:ae.DISPLAY,text:ae.TEXT,script:ae.SCRIPT,scriptscript:ae.SCRIPTSCRIPT},rA={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},ct=function(e,t,r,n){n===void 0&&(n=[null,null]);for(var s=[],a=0;a{var y=x.classes[0],b=g.classes[0];y==="mbin"&&tA.includes(b)?x.classes[0]="mord":b==="mbin"&&eA.includes(y)&&(g.classes[0]="mord")},{node:c},f,m),$6(s,(g,x)=>{var y=m1(x),b=m1(g),S=y&&b?g.hasClass("mtight")?JS[y][b]:QS[y][b]:null;if(S)return z.makeGlue(S,h)},{node:c},f,m),s},$6=function i(e,t,r,n,s){n&&e.push(n);for(var a=0;af=>{e.splice(c+1,0,f),a++})(a)}n&&e.pop()},N4=function(e){return e instanceof ms||e instanceof el||e instanceof ps&&e.hasClass("enclosing")?e:null},nA=function i(e,t){var r=N4(e);if(r){var n=r.children;if(n.length){if(t==="right")return i(n[n.length-1],"right");if(t==="left")return i(n[0],"left")}}return e},m1=function(e,t){return e?(t&&(e=nA(e,t)),rA[e.classes[0]]||null):null},il=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return zr(t.concat(r))},Me=function(e,t,r){if(!e)return zr();if(Eh[e.type]){var n=Eh[e.type](e,t);if(r&&t.size!==r.size){n=zr(t.sizingClasses(r),[n],t);var s=t.sizeMultiplier/r.sizeMultiplier;n.height*=s,n.depth*=s}return n}else throw new G("Got group of unknown type: '"+e.type+"'")};Bt=class{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=yn(this.classes));for(var r=0;r0&&(e+=' class ="'+Ne.escape(yn(this.classes))+'"'),e+=">";for(var r=0;r",e}toText(){return this.children.map(e=>e.toText()).join("")}},ki=class{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return Ne.escape(this.toText())}toText(){return this.text}},g1=class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character="\u200A":e>=.1666&&e<=.1667?this.character="\u2009":e>=.2222&&e<=.2223?this.character="\u2005":e>=.2777&&e<=.2778?this.character="\u2005\u200A":e>=-.05556&&e<=-.05555?this.character="\u200A\u2063":e>=-.1667&&e<=-.1666?this.character="\u2009\u2063":e>=-.2223&&e<=-.2222?this.character="\u205F\u2063":e>=-.2778&&e<=-.2777?this.character="\u2005\u2063":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",V(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},$={MathNode:Bt,TextNode:ki,SpaceNode:g1,newDocumentFragment:E4},Ci=function(e,t,r){return Oe[t][e]&&Oe[t][e].replace&&e.charCodeAt(0)!==55349&&!(y4.hasOwnProperty(e)&&r&&(r.fontFamily&&r.fontFamily.slice(4,6)==="tt"||r.font&&r.font.slice(4,6)==="tt"))&&(e=Oe[t][e].replace),new $.TextNode(e)},E1=function(e){return e.length===1?e[0]:new $.MathNode("mrow",e)},S1=function(e,t){if(t.fontFamily==="texttt")return"monospace";if(t.fontFamily==="textsf")return t.fontShape==="textit"&&t.fontWeight==="textbf"?"sans-serif-bold-italic":t.fontShape==="textit"?"sans-serif-italic":t.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(t.fontShape==="textit"&&t.fontWeight==="textbf")return"bold-italic";if(t.fontShape==="textit")return"italic";if(t.fontWeight==="textbf")return"bold";var r=t.font;if(!r||r==="mathnormal")return null;var n=e.mode;if(r==="mathit")return"italic";if(r==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(r==="mathbf")return"bold";if(r==="mathbb")return"double-struck";if(r==="mathsfit")return"sans-serif-italic";if(r==="mathfrak")return"fraktur";if(r==="mathscr"||r==="mathcal")return"script";if(r==="mathsf")return"sans-serif";if(r==="mathtt")return"monospace";var s=e.text;if(["\\imath","\\jmath"].includes(s))return null;Oe[n][s]&&Oe[n][s].replace&&(s=Oe[n][s].replace);var a=z.fontMap[r].fontName;return T1(s,a,n)?z.fontMap[r].variant:null};ti=function(e,t,r){if(e.length===1){var n=ze(e[0],t);return r&&n instanceof Bt&&n.type==="mo"&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var s=[],a,o=0;o=1&&(a.type==="mn"||e1(a))){var h=l.children[0];h instanceof Bt&&h.type==="mn"&&(h.children=[...a.children,...h.children],s.pop())}else if(a.type==="mi"&&a.children.length===1){var d=a.children[0];if(d instanceof ki&&d.text==="\u0338"&&(l.type==="mo"||l.type==="mi"||l.type==="mn")){var c=l.children[0];c instanceof ki&&c.text.length>0&&(c.text=c.text.slice(0,1)+"\u0338"+c.text.slice(1),s.pop())}}}s.push(l),a=l}return s},vn=function(e,t,r){return E1(ti(e,t,r))},ze=function(e,t){if(!e)return new $.MathNode("mrow");if(Sh[e.type]){var r=Sh[e.type](e,t);return r}else throw new G("Got group of unknown type: '"+e.type+"'")};S4=function(e){return new Th({style:e.displayMode?ae.DISPLAY:ae.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},A4=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=z.makeSpan(r,[e])}return e},sA=function(e,t,r){var n=S4(r),s;if(r.output==="mathml")return j6(e,t,n,r.displayMode,!0);if(r.output==="html"){var a=p1(e,n);s=z.makeSpan(["katex"],[a])}else{var o=j6(e,t,n,r.displayMode,!1),l=p1(e,n);s=z.makeSpan(["katex"],[o,l])}return A4(s,r)},aA=function(e,t,r){var n=S4(r),s=p1(e,n),a=z.makeSpan(["katex"],[s]);return A4(a,r)},oA={widehat:"^",widecheck:"\u02C7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23DF",overbrace:"\u23DE",overgroup:"\u23E0",undergroup:"\u23E1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21D2",xRightarrow:"\u21D2",overleftharpoon:"\u21BC",xleftharpoonup:"\u21BC",overrightharpoon:"\u21C0",xrightharpoonup:"\u21C0",xLeftarrow:"\u21D0",xLeftrightarrow:"\u21D4",xhookleftarrow:"\u21A9",xhookrightarrow:"\u21AA",xmapsto:"\u21A6",xrightharpoondown:"\u21C1",xleftharpoondown:"\u21BD",xrightleftharpoons:"\u21CC",xleftrightharpoons:"\u21CB",xtwoheadleftarrow:"\u219E",xtwoheadrightarrow:"\u21A0",xlongequal:"=",xtofrom:"\u21C4",xrightleftarrows:"\u21C4",xrightequilibrium:"\u21CC",xleftequilibrium:"\u21CB","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},lA=function(e){var t=new $.MathNode("mo",[new $.TextNode(oA[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},hA={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},dA=function(e){return e.type==="ordgroup"?e.body.length:1},cA=function(e,t){function r(){var o=4e5,l=e.label.slice(1);if(["widehat","widecheck","widetilde","utilde"].includes(l)){var h=e,d=dA(h.base),c,f,m;if(d>5)l==="widehat"||l==="widecheck"?(c=420,o=2364,m=.42,f=l+"4"):(c=312,o=2340,m=.34,f="tilde4");else{var g=[1,1,2,2,3,3][d];l==="widehat"||l==="widecheck"?(o=[0,1062,2364,2364,2364][g],c=[0,239,300,360,420][g],m=[0,.24,.3,.3,.36,.42][g],f=l+g):(o=[0,600,1033,2339,2340][g],c=[0,260,286,306,312][g],m=[0,.26,.286,.3,.306,.34][g],f="tilde"+g)}var x=new cr(f),y=new Xi([x],{width:"100%",height:V(m),viewBox:"0 0 "+o+" "+c,preserveAspectRatio:"none"});return{span:z.makeSvgSpan([],[y],t),minWidth:0,height:m}}else{var b=[],S=hA[l],[A,C,I]=S,O=I/1e3,q=A.length,P,W;if(q===1){var ne=S[3];P=["hide-tail"],W=[ne]}else if(q===2)P=["halfarrow-left","halfarrow-right"],W=["xMinYMin","xMaxYMin"];else if(q===3)P=["brace-left","brace-center","brace-right"],W=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support - `+q+" children.");for(var re=0;re0&&(n.style.minWidth=V(s)),n},uA=function(e,t,r,n,s){var a,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(a=z.makeSpan(["stretchy",t],[],s),t==="fbox"){var l=s.color&&s.getColor();l&&(a.style.borderColor=l)}}else{var h=[];/^[bx]cancel$/.test(t)&&h.push(new tl({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&h.push(new tl({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var d=new Xi(h,{width:"100%",height:V(o)});a=z.makeSvgSpan([],[d],s)}return a.height=o,a.style.height=V(o),a},Rr={encloseSpan:uA,mathMLnode:lA,svgSpan:cA};k1=(i,e)=>{var t,r,n;i&&i.type==="supsub"?(r=me(i.base,"accent"),t=r.base,i.base=t,n=OS(Me(i,e)),i.base=r):(r=me(i,"accent"),t=r.base);var s=Me(t,e.havingCrampedStyle()),a=r.isShifty&&Ne.isCharacterBox(t),o=0;if(a){var l=Ne.getBaseElem(t),h=Me(l,e.havingCrampedStyle());o=F6(h).skew}var d=r.label==="\\c",c=d?s.height+s.depth:Math.min(s.height,e.fontMetrics().xHeight),f;if(r.isStretchy)f=Rr.svgSpan(r,e),f=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"elem",elem:f,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+V(2*o)+")",marginLeft:V(2*o)}:void 0}]},e);else{var m,g;r.label==="\\vec"?(m=z.staticSvg("vec",e),g=z.svgData.vec[1]):(m=z.makeOrd({mode:r.mode,text:r.label},e,"textord"),m=F6(m),m.italic=0,g=m.width,d&&(c+=m.depth)),f=z.makeSpan(["accent-body"],[m]);var x=r.label==="\\textcircled";x&&(f.classes.push("accent-full"),c=s.height);var y=o;x||(y-=g/2),f.style.left=V(y),r.label==="\\textcircled"&&(f.style.top=".2em"),f=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:-c},{type:"elem",elem:f}]},e)}var b=z.makeSpan(["mord","accent"],[f],e);return n?(n.children[0]=b,n.height=Math.max(b.height,n.height),n.classes[0]="mord",n):b},k4=(i,e)=>{var t=i.isStretchy?Rr.mathMLnode(i.label):new $.MathNode("mo",[Ci(i.label,i.mode)]),r=new $.MathNode("mover",[ze(i.base,e),t]);return r.setAttribute("accent","true"),r},fA=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(i=>"\\"+i).join("|"));Z({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(i,e)=>{var t=Ah(e[0]),r=!fA.test(i.funcName),n=!r||i.funcName==="\\widehat"||i.funcName==="\\widetilde"||i.funcName==="\\widecheck";return{type:"accent",mode:i.parser.mode,label:i.funcName,isStretchy:r,isShifty:n,base:t}},htmlBuilder:k1,mathmlBuilder:k4});Z({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(i,e)=>{var t=e[0],r=i.parser.mode;return r==="math"&&(i.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+i.funcName+" works only in text mode"),r="text"),{type:"accent",mode:r,label:i.funcName,isStretchy:!1,isShifty:!0,base:t}},htmlBuilder:k1,mathmlBuilder:k4});Z({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"accentUnder",mode:t.mode,label:r,base:n}},htmlBuilder:(i,e)=>{var t=Me(i.base,e),r=Rr.svgSpan(i,e),n=i.label==="\\utilde"?.12:0,s=z.makeVList({positionType:"top",positionData:t.height,children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:t}]},e);return z.makeSpan(["mord","accentunder"],[s],e)},mathmlBuilder:(i,e)=>{var t=Rr.mathMLnode(i.label),r=new $.MathNode("munder",[ze(i.base,e),t]);return r.setAttribute("accentunder","true"),r}});xh=i=>{var e=new $.MathNode("mpadded",i?[i]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e};Z({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(i,e,t){var{parser:r,funcName:n}=i;return{type:"xArrow",mode:r.mode,label:n,body:e[0],below:t[0]}},htmlBuilder(i,e){var t=e.style,r=e.havingStyle(t.sup()),n=z.wrapFragment(Me(i.body,r,e),e),s=i.label.slice(0,2)==="\\x"?"x":"cd";n.classes.push(s+"-arrow-pad");var a;i.below&&(r=e.havingStyle(t.sub()),a=z.wrapFragment(Me(i.below,r,e),e),a.classes.push(s+"-arrow-pad"));var o=Rr.svgSpan(i,e),l=-e.fontMetrics().axisHeight+.5*o.height,h=-e.fontMetrics().axisHeight-.5*o.height-.111;(n.depth>.25||i.label==="\\xleftequilibrium")&&(h-=n.depth);var d;if(a){var c=-e.fontMetrics().axisHeight+a.height+.5*o.height+.111;d=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:h},{type:"elem",elem:o,shift:l},{type:"elem",elem:a,shift:c}]},e)}else d=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:h},{type:"elem",elem:o,shift:l}]},e);return d.children[0].children[0].children[1].classes.push("svg-align"),z.makeSpan(["mrel","x-arrow"],[d],e)},mathmlBuilder(i,e){var t=Rr.mathMLnode(i.label);t.setAttribute("minsize",i.label.charAt(0)==="x"?"1.75em":"3.0em");var r;if(i.body){var n=xh(ze(i.body,e));if(i.below){var s=xh(ze(i.below,e));r=new $.MathNode("munderover",[t,s,n])}else r=new $.MathNode("mover",[t,n])}else if(i.below){var a=xh(ze(i.below,e));r=new $.MathNode("munder",[t,a])}else r=xh(),r=new $.MathNode("mover",[t,r]);return r}});mA=z.makeSpan;Z({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"mclass",mode:t.mode,mclass:"m"+r.slice(5),body:rt(n),isCharacterBox:Ne.isCharacterBox(n)}},htmlBuilder:C4,mathmlBuilder:_4});zh=i=>{var e=i.type==="ordgroup"&&i.body.length?i.body[0]:i;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"};Z({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(i,e){var{parser:t}=i;return{type:"mclass",mode:t.mode,mclass:zh(e[0]),body:rt(e[1]),isCharacterBox:Ne.isCharacterBox(e[1])}}});Z({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(i,e){var{parser:t,funcName:r}=i,n=e[1],s=e[0],a;r!=="\\stackrel"?a=zh(n):a="mrel";var o={type:"op",mode:n.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:r!=="\\stackrel",body:rt(n)},l={type:"supsub",mode:s.mode,base:o,sup:r==="\\underset"?null:s,sub:r==="\\underset"?s:null};return{type:"mclass",mode:t.mode,mclass:a,body:[l],isCharacterBox:Ne.isCharacterBox(l)}},htmlBuilder:C4,mathmlBuilder:_4});Z({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"pmb",mode:t.mode,mclass:zh(e[0]),body:rt(e[0])}},htmlBuilder(i,e){var t=ct(i.body,e,!0),r=z.makeSpan([i.mclass],t,e);return r.style.textShadow="0.02em 0.01em 0.04px",r},mathmlBuilder(i,e){var t=ti(i.body,e),r=new $.MathNode("mstyle",t);return r.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),r}});pA={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},G6=()=>({type:"styling",body:[],mode:"math",style:"display"}),V6=i=>i.type==="textord"&&i.text==="@",gA=(i,e)=>(i.type==="mathord"||i.type==="atom")&&i.text===e;Z({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i;return{type:"cdlabel",mode:t.mode,side:r.slice(4),label:e[0]}},htmlBuilder(i,e){var t=e.havingStyle(e.style.sup()),r=z.wrapFragment(Me(i.label,t,e),e);return r.classes.push("cd-label-"+i.side),r.style.bottom=V(.8-r.depth),r.height=0,r.depth=0,r},mathmlBuilder(i,e){var t=new $.MathNode("mrow",[ze(i.label,e)]);return t=new $.MathNode("mpadded",[t]),t.setAttribute("width","0"),i.side==="left"&&t.setAttribute("lspace","-1width"),t.setAttribute("voffset","0.7em"),t=new $.MathNode("mstyle",[t]),t.setAttribute("displaystyle","false"),t.setAttribute("scriptlevel","1"),t}});Z({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(i,e){var{parser:t}=i;return{type:"cdlabelparent",mode:t.mode,fragment:e[0]}},htmlBuilder(i,e){var t=z.wrapFragment(Me(i.fragment,e),e);return t.classes.push("cd-vert-arrow"),t},mathmlBuilder(i,e){return new $.MathNode("mrow",[ze(i.fragment,e)])}});Z({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(i,e){for(var{parser:t}=i,r=me(e[0],"ordgroup"),n=r.body,s="",a=0;a=1114111)throw new G("\\@char with invalid code point "+s);return l<=65535?h=String.fromCharCode(l):(l-=65536,h=String.fromCharCode((l>>10)+55296,(l&1023)+56320)),{type:"textord",mode:t.mode,text:h}}});L4=(i,e)=>{var t=ct(i.body,e.withColor(i.color),!1);return z.makeFragment(t)},I4=(i,e)=>{var t=ti(i.body,e.withColor(i.color)),r=new $.MathNode("mstyle",t);return r.setAttribute("mathcolor",i.color),r};Z({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(i,e){var{parser:t}=i,r=me(e[0],"color-token").color,n=e[1];return{type:"color",mode:t.mode,color:r,body:rt(n)}},htmlBuilder:L4,mathmlBuilder:I4});Z({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(i,e){var{parser:t,breakOnTokenText:r}=i,n=me(e[0],"color-token").color;t.gullet.macros.set("\\current@color",n);var s=t.parseExpression(!0,r);return{type:"color",mode:t.mode,color:n,body:s}},htmlBuilder:L4,mathmlBuilder:I4});Z({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(i,e,t){var{parser:r}=i,n=r.gullet.future().text==="["?r.parseSizeGroup(!0):null,s=!r.settings.displayMode||!r.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:r.mode,newLine:s,size:n&&me(n,"size").value}},htmlBuilder(i,e){var t=z.makeSpan(["mspace"],[],e);return i.newLine&&(t.classes.push("newline"),i.size&&(t.style.marginTop=V(Xe(i.size,e)))),t},mathmlBuilder(i,e){var t=new $.MathNode("mspace");return i.newLine&&(t.setAttribute("linebreak","newline"),i.size&&t.setAttribute("height",V(Xe(i.size,e)))),t}});x1={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},z4=i=>{var e=i.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new G("Expected a control sequence",i);return e},vA=i=>{var e=i.gullet.popToken();return e.text==="="&&(e=i.gullet.popToken(),e.text===" "&&(e=i.gullet.popToken())),e},R4=(i,e,t,r)=>{var n=i.gullet.macros.get(t.text);n==null&&(t.noexpand=!0,n={tokens:[t],numArgs:0,unexpandable:!i.gullet.isExpandable(t.text)}),i.gullet.macros.set(e,n,r)};Z({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(i){var{parser:e,funcName:t}=i;e.consumeSpaces();var r=e.fetch();if(x1[r.text])return(t==="\\global"||t==="\\\\globallong")&&(r.text=x1[r.text]),me(e.parseFunction(),"internal");throw new G("Invalid token after macro prefix",r)}});Z({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=e.gullet.popToken(),n=r.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new G("Expected a control sequence",r);for(var s=0,a,o=[[]];e.gullet.future().text!=="{";)if(r=e.gullet.popToken(),r.text==="#"){if(e.gullet.future().text==="{"){a=e.gullet.future(),o[s].push("{");break}if(r=e.gullet.popToken(),!/^[1-9]$/.test(r.text))throw new G('Invalid argument number "'+r.text+'"');if(parseInt(r.text)!==s+1)throw new G('Argument number "'+r.text+'" out of order');s++,o.push([])}else{if(r.text==="EOF")throw new G("Expected a macro definition");o[s].push(r.text)}var{tokens:l}=e.gullet.consumeArg();return a&&l.unshift(a),(t==="\\edef"||t==="\\xdef")&&(l=e.gullet.expandTokens(l),l.reverse()),e.gullet.macros.set(n,{tokens:l,numArgs:s,delimiters:o},t===x1[t]),{type:"internal",mode:e.mode}}});Z({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=z4(e.gullet.popToken());e.gullet.consumeSpaces();var n=vA(e);return R4(e,r,n,t==="\\\\globallet"),{type:"internal",mode:e.mode}}});Z({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=z4(e.gullet.popToken()),n=e.gullet.popToken(),s=e.gullet.popToken();return R4(e,r,s,t==="\\\\globalfuture"),e.gullet.pushToken(s),e.gullet.pushToken(n),{type:"internal",mode:e.mode}}});Ko=function(e,t,r){var n=Oe.math[e]&&Oe.math[e].replace,s=T1(n||e,t,r);if(!s)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return s},C1=function(e,t,r,n){var s=r.havingBaseStyle(t),a=z.makeSpan(n.concat(s.sizingClasses(r)),[e],r),o=s.sizeMultiplier/r.sizeMultiplier;return a.height*=o,a.depth*=o,a.maxFontSize=s.sizeMultiplier,a},D4=function(e,t,r){var n=t.havingBaseStyle(r),s=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=V(s),e.height-=s,e.depth+=s},bA=function(e,t,r,n,s,a){var o=z.makeSymbol(e,"Main-Regular",s,n),l=C1(o,t,n,a);return r&&D4(l,n,t),l},wA=function(e,t,r,n){return z.makeSymbol(e,"Size"+t+"-Regular",r,n)},O4=function(e,t,r,n,s,a){var o=wA(e,t,s,n),l=C1(z.makeSpan(["delimsizing","size"+t],[o],n),ae.TEXT,n,a);return r&&D4(l,n,ae.TEXT),l},t1=function(e,t,r){var n;t==="Size1-Regular"?n="delim-size1":n="delim-size4";var s=z.makeSpan(["delimsizinginner",n],[z.makeSpan([],[z.makeSymbol(e,t,r)])]);return{type:"elem",elem:s}},i1=function(e,t,r){var n=dr["Size4-Regular"][e.charCodeAt(0)]?dr["Size4-Regular"][e.charCodeAt(0)][4]:dr["Size1-Regular"][e.charCodeAt(0)][4],s=new cr("inner",kS(e,Math.round(1e3*t))),a=new Xi([s],{width:V(n),height:V(t),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=z.makeSvgSpan([],[a],r);return o.height=t,o.style.height=V(t),o.style.width=V(n),{type:"elem",elem:o}},y1=.008,yh={type:"kern",size:-1*y1},MA=["|","\\lvert","\\rvert","\\vert"],TA=["\\|","\\lVert","\\rVert","\\Vert"],B4=function(e,t,r,n,s,a){var o,l,h,d,c="",f=0;o=h=d=e,l=null;var m="Size1-Regular";e==="\\uparrow"?h=d="\u23D0":e==="\\Uparrow"?h=d="\u2016":e==="\\downarrow"?o=h="\u23D0":e==="\\Downarrow"?o=h="\u2016":e==="\\updownarrow"?(o="\\uparrow",h="\u23D0",d="\\downarrow"):e==="\\Updownarrow"?(o="\\Uparrow",h="\u2016",d="\\Downarrow"):MA.includes(e)?(h="\u2223",c="vert",f=333):TA.includes(e)?(h="\u2225",c="doublevert",f=556):e==="["||e==="\\lbrack"?(o="\u23A1",h="\u23A2",d="\u23A3",m="Size4-Regular",c="lbrack",f=667):e==="]"||e==="\\rbrack"?(o="\u23A4",h="\u23A5",d="\u23A6",m="Size4-Regular",c="rbrack",f=667):e==="\\lfloor"||e==="\u230A"?(h=o="\u23A2",d="\u23A3",m="Size4-Regular",c="lfloor",f=667):e==="\\lceil"||e==="\u2308"?(o="\u23A1",h=d="\u23A2",m="Size4-Regular",c="lceil",f=667):e==="\\rfloor"||e==="\u230B"?(h=o="\u23A5",d="\u23A6",m="Size4-Regular",c="rfloor",f=667):e==="\\rceil"||e==="\u2309"?(o="\u23A4",h=d="\u23A5",m="Size4-Regular",c="rceil",f=667):e==="("||e==="\\lparen"?(o="\u239B",h="\u239C",d="\u239D",m="Size4-Regular",c="lparen",f=875):e===")"||e==="\\rparen"?(o="\u239E",h="\u239F",d="\u23A0",m="Size4-Regular",c="rparen",f=875):e==="\\{"||e==="\\lbrace"?(o="\u23A7",l="\u23A8",d="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(o="\u23AB",l="\u23AC",d="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lgroup"||e==="\u27EE"?(o="\u23A7",d="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\rgroup"||e==="\u27EF"?(o="\u23AB",d="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lmoustache"||e==="\u23B0"?(o="\u23A7",d="\u23AD",h="\u23AA",m="Size4-Regular"):(e==="\\rmoustache"||e==="\u23B1")&&(o="\u23AB",d="\u23A9",h="\u23AA",m="Size4-Regular");var g=Ko(o,m,s),x=g.height+g.depth,y=Ko(h,m,s),b=y.height+y.depth,S=Ko(d,m,s),A=S.height+S.depth,C=0,I=1;if(l!==null){var O=Ko(l,m,s);C=O.height+O.depth,I=2}var q=x+A+C,P=Math.max(0,Math.ceil((t-q)/(I*b))),W=q+P*I*b,ne=n.fontMetrics().axisHeight;r&&(ne*=n.sizeMultiplier);var re=W/2-ne,oe=[];if(c.length>0){var ke=W-x-A,Q=Math.round(W*1e3),Y=CS(c,Math.round(ke*1e3)),le=new cr(c,Y),ce=(f/1e3).toFixed(3)+"em",at=(Q/1e3).toFixed(3)+"em",It=new Xi([le],{width:ce,height:at,viewBox:"0 0 "+f+" "+Q}),bt=z.makeSvgSpan([],[It],n);bt.height=Q/1e3,bt.style.width=ce,bt.style.height=at,oe.push({type:"elem",elem:bt})}else{if(oe.push(t1(d,m,s)),oe.push(yh),l===null){var qi=W-x-A+2*y1;oe.push(i1(h,qi,n))}else{var zt=(W-x-A-C)/2+2*y1;oe.push(i1(h,zt,n)),oe.push(yh),oe.push(t1(l,m,s)),oe.push(yh),oe.push(i1(h,zt,n))}oe.push(yh),oe.push(t1(o,m,s))}var di=n.havingBaseStyle(ae.TEXT),nn=z.makeVList({positionType:"bottom",positionData:re,children:oe},di);return C1(z.makeSpan(["delimsizing","mult"],[nn],di),ae.TEXT,n,a)},r1=80,n1=.08,s1=function(e,t,r,n,s){var a=AS(e,n,r),o=new cr(e,a),l=new Xi([o],{width:"400em",height:V(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return z.makeSvgSpan(["hide-tail"],[l],s)},NA=function(e,t){var r=t.havingBaseSizing(),n=H4("\\surd",e*r.sizeMultiplier,q4,r),s=r.sizeMultiplier,a=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),o,l=0,h=0,d=0,c;return n.type==="small"?(d=1e3+1e3*a+r1,e<1?s=1:e<1.4&&(s=.7),l=(1+a+n1)/s,h=(1+a)/s,o=s1("sqrtMain",l,d,a,t),o.style.minWidth="0.853em",c=.833/s):n.type==="large"?(d=(1e3+r1)*Zo[n.size],h=(Zo[n.size]+a)/s,l=(Zo[n.size]+a+n1)/s,o=s1("sqrtSize"+n.size,l,d,a,t),o.style.minWidth="1.02em",c=1/s):(l=e+a+n1,h=e+a,d=Math.floor(1e3*e+a)+r1,o=s1("sqrtTall",l,d,a,t),o.style.minWidth="0.742em",c=1.056),o.height=h,o.style.height=V(l),{span:o,advanceWidth:c,ruleWidth:(t.fontMetrics().sqrtRuleThickness+a)*s}},P4=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","\\surd"],EA=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1"],F4=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],Zo=[0,1.2,1.8,2.4,3],SA=function(e,t,r,n,s){if(e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle"),P4.includes(e)||F4.includes(e))return O4(e,t,!1,r,n,s);if(EA.includes(e))return B4(e,Zo[t],!1,r,n,s);throw new G("Illegal delimiter: '"+e+"'")},AA=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],kA=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"stack"}],q4=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],CA=function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},H4=function(e,t,r,n){for(var s=Math.min(2,3-n.style.size),a=s;at)return r[a]}return r[r.length-1]},U4=function(e,t,r,n,s,a){e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle");var o;F4.includes(e)?o=AA:P4.includes(e)?o=q4:o=kA;var l=H4(e,t,o,n);return l.type==="small"?bA(e,l.style,r,n,s,a):l.type==="large"?O4(e,l.size,r,n,s,a):B4(e,t,r,n,s,a)},_A=function(e,t,r,n,s,a){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,l=901,h=5/n.fontMetrics().ptPerEm,d=Math.max(t-o,r+o),c=Math.max(d/500*l,2*d-h);return U4(e,c,!0,n,s,a)},Ir={sqrtImage:NA,sizedDelim:SA,sizeToMaxHeight:Zo,customSizedDelim:U4,leftRightDelim:_A},W6={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},LA=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27E8","\\rangle","\u27E9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];Z({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(i,e)=>{var t=Rh(e[0],i);return{type:"delimsizing",mode:i.parser.mode,size:W6[i.funcName].size,mclass:W6[i.funcName].mclass,delim:t.text}},htmlBuilder:(i,e)=>i.delim==="."?z.makeSpan([i.mclass]):Ir.sizedDelim(i.delim,i.size,e,i.mode,[i.mclass]),mathmlBuilder:i=>{var e=[];i.delim!=="."&&e.push(Ci(i.delim,i.mode));var t=new $.MathNode("mo",e);i.mclass==="mopen"||i.mclass==="mclose"?t.setAttribute("fence","true"):t.setAttribute("fence","false"),t.setAttribute("stretchy","true");var r=V(Ir.sizeToMaxHeight[i.size]);return t.setAttribute("minsize",r),t.setAttribute("maxsize",r),t}});Z({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=i.parser.gullet.macros.get("\\current@color");if(t&&typeof t!="string")throw new G("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:i.parser.mode,delim:Rh(e[0],i).text,color:t}}});Z({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=Rh(e[0],i),r=i.parser;++r.leftrightDepth;var n=r.parseExpression(!1);--r.leftrightDepth,r.expect("\\right",!1);var s=me(r.parseFunction(),"leftright-right");return{type:"leftright",mode:r.mode,body:n,left:t.text,right:s.delim,rightColor:s.color}},htmlBuilder:(i,e)=>{Y6(i);for(var t=ct(i.body,e,!0,["mopen","mclose"]),r=0,n=0,s=!1,a=0;a{Y6(i);var t=ti(i.body,e);if(i.left!=="."){var r=new $.MathNode("mo",[Ci(i.left,i.mode)]);r.setAttribute("fence","true"),t.unshift(r)}if(i.right!=="."){var n=new $.MathNode("mo",[Ci(i.right,i.mode)]);n.setAttribute("fence","true"),i.rightColor&&n.setAttribute("mathcolor",i.rightColor),t.push(n)}return E1(t)}});Z({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=Rh(e[0],i);if(!i.parser.leftrightDepth)throw new G("\\middle without preceding \\left",t);return{type:"middle",mode:i.parser.mode,delim:t.text}},htmlBuilder:(i,e)=>{var t;if(i.delim===".")t=il(e,[]);else{t=Ir.sizedDelim(i.delim,1,e,i.mode,[]);var r={delim:i.delim,options:e};t.isMiddle=r}return t},mathmlBuilder:(i,e)=>{var t=i.delim==="\\vert"||i.delim==="|"?Ci("|","text"):Ci(i.delim,i.mode),r=new $.MathNode("mo",[t]);return r.setAttribute("fence","true"),r.setAttribute("lspace","0.05em"),r.setAttribute("rspace","0.05em"),r}});_1=(i,e)=>{var t=z.wrapFragment(Me(i.body,e),e),r=i.label.slice(1),n=e.sizeMultiplier,s,a=0,o=Ne.isCharacterBox(i.body);if(r==="sout")s=z.makeSpan(["stretchy","sout"]),s.height=e.fontMetrics().defaultRuleThickness/n,a=-.5*e.fontMetrics().xHeight;else if(r==="phase"){var l=Xe({number:.6,unit:"pt"},e),h=Xe({number:.35,unit:"ex"},e),d=e.havingBaseSizing();n=n/d.sizeMultiplier;var c=t.height+t.depth+l+h;t.style.paddingLeft=V(c/2+l);var f=Math.floor(1e3*c*n),m=ES(f),g=new Xi([new cr("phase",m)],{width:"400em",height:V(f/1e3),viewBox:"0 0 400000 "+f,preserveAspectRatio:"xMinYMin slice"});s=z.makeSvgSpan(["hide-tail"],[g],e),s.style.height=V(c),a=t.depth+l+h}else{/cancel/.test(r)?o||t.classes.push("cancel-pad"):r==="angl"?t.classes.push("anglpad"):t.classes.push("boxpad");var x=0,y=0,b=0;/box/.test(r)?(b=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),x=e.fontMetrics().fboxsep+(r==="colorbox"?0:b),y=x):r==="angl"?(b=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),x=4*b,y=Math.max(0,.25-t.depth)):(x=o?.2:0,y=x),s=Rr.encloseSpan(t,r,x,y,e),/fbox|boxed|fcolorbox/.test(r)?(s.style.borderStyle="solid",s.style.borderWidth=V(b)):r==="angl"&&b!==.049&&(s.style.borderTopWidth=V(b),s.style.borderRightWidth=V(b)),a=t.depth+y,i.backgroundColor&&(s.style.backgroundColor=i.backgroundColor,i.borderColor&&(s.style.borderColor=i.borderColor))}var S;if(i.backgroundColor)S=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:s,shift:a},{type:"elem",elem:t,shift:0}]},e);else{var A=/cancel|phase/.test(r)?["svg-align"]:[];S=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:t,shift:0},{type:"elem",elem:s,shift:a,wrapperClasses:A}]},e)}return/cancel/.test(r)&&(S.height=t.height,S.depth=t.depth),/cancel/.test(r)&&!o?z.makeSpan(["mord","cancel-lap"],[S],e):z.makeSpan(["mord"],[S],e)},L1=(i,e)=>{var t=0,r=new $.MathNode(i.label.indexOf("colorbox")>-1?"mpadded":"menclose",[ze(i.body,e)]);switch(i.label){case"\\cancel":r.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":r.setAttribute("notation","downdiagonalstrike");break;case"\\phase":r.setAttribute("notation","phasorangle");break;case"\\sout":r.setAttribute("notation","horizontalstrike");break;case"\\fbox":r.setAttribute("notation","box");break;case"\\angl":r.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(t=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,r.setAttribute("width","+"+2*t+"pt"),r.setAttribute("height","+"+2*t+"pt"),r.setAttribute("lspace",t+"pt"),r.setAttribute("voffset",t+"pt"),i.label==="\\fcolorbox"){var n=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);r.setAttribute("style","border: "+n+"em solid "+String(i.borderColor))}break;case"\\xcancel":r.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return i.backgroundColor&&r.setAttribute("mathbackground",i.backgroundColor),r};Z({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(i,e,t){var{parser:r,funcName:n}=i,s=me(e[0],"color-token").color,a=e[1];return{type:"enclose",mode:r.mode,label:n,backgroundColor:s,body:a}},htmlBuilder:_1,mathmlBuilder:L1});Z({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(i,e,t){var{parser:r,funcName:n}=i,s=me(e[0],"color-token").color,a=me(e[1],"color-token").color,o=e[2];return{type:"enclose",mode:r.mode,label:n,backgroundColor:a,borderColor:s,body:o}},htmlBuilder:_1,mathmlBuilder:L1});Z({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"enclose",mode:t.mode,label:"\\fbox",body:e[0]}}});Z({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"enclose",mode:t.mode,label:r,body:n}},htmlBuilder:_1,mathmlBuilder:L1});Z({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(i,e){var{parser:t}=i;return{type:"enclose",mode:t.mode,label:"\\angl",body:e[0]}}});$4={};j4={};Dh=i=>{var e=i.parser.settings;if(!e.displayMode)throw new G("{"+i.envName+"} can be used only in display mode.")};fr=function(e,t){var r,n,s=e.body.length,a=e.hLinesBeforeRow,o=0,l=new Array(s),h=[],d=Math.max(t.fontMetrics().arrayRuleWidth,t.minRuleThickness),c=1/t.fontMetrics().ptPerEm,f=5*c;if(e.colSeparationType&&e.colSeparationType==="small"){var m=t.havingStyle(ae.SCRIPT).sizeMultiplier;f=.2778*(m/t.sizeMultiplier)}var g=e.colSeparationType==="CD"?Xe({number:3,unit:"ex"},t):12*c,x=3*c,y=e.arraystretch*g,b=.7*y,S=.3*y,A=0;function C(Bs){for(var $i=0;$i0&&(A+=.25),h.push({pos:A,isDashed:Bs[$i]})}for(C(a[0]),r=0;r0&&(re+=S,qBs))for(r=0;r=o)){var Mr=void 0;(n>0||e.hskipBeforeAndAfter)&&(Mr=Ne.deflt(zt.pregap,f),Mr!==0&&(Y=z.makeSpan(["arraycolsep"],[]),Y.style.width=V(Mr),Q.push(Y)));var tr=[];for(r=0;r0){for(var wi=z.makeLineSpan("hline",t,d),Je=z.makeLineSpan("hdashline",t,d),ve=[{type:"elem",elem:l,shift:0}];h.length>0;){var an=h.pop(),R=an.pos-oe;an.isDashed?ve.push({type:"elem",elem:Je,shift:R}):ve.push({type:"elem",elem:wi,shift:R})}l=z.makeVList({positionType:"individualShift",children:ve},t)}if(ce.length===0)return z.makeSpan(["mord"],[l],t);var Wn=z.makeVList({positionType:"individualShift",children:ce},t);return Wn=z.makeSpan(["tag"],[Wn],t),z.makeFragment([l,Wn])},IA={c:"center ",l:"left ",r:"right "},mr=function(e,t){for(var r=[],n=new $.MathNode("mtd",[],["mtr-glue"]),s=new $.MathNode("mtd",[],["mml-eqn-num"]),a=0;a0){var g=e.cols,x="",y=!1,b=0,S=g.length;g[0].type==="separator"&&(f+="top ",b=1),g[g.length-1].type==="separator"&&(f+="bottom ",S-=1);for(var A=b;A0?"left ":"",f+=P[P.length-1].length>0?"right ":"";for(var W=1;W-1?"alignat":"align",s=e.envName==="split",a=bn(e.parser,{cols:r,addJot:!0,autoTag:s?void 0:I1(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:s?2:void 0,leqno:e.parser.settings.leqno},"display"),o,l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&t[0].type==="ordgroup"){for(var d="",c=0;c0&&m&&(y=1),r[g]={type:"align",align:x,pregap:y,postgap:0}}return a.colSeparationType=m?"align":"alignat",a};ur({type:"array",names:["array","darray"],props:{numArgs:1},handler(i,e){var t=Ih(e[0]),r=t?[e[0]]:me(e[0],"ordgroup").body,n=r.map(function(a){var o=A1(a),l=o.text;if("lcr".indexOf(l)!==-1)return{type:"align",align:l};if(l==="|")return{type:"separator",separator:"|"};if(l===":")return{type:"separator",separator:":"};throw new G("Unknown column alignment: "+l,a)}),s={cols:n,hskipBeforeAndAfter:!0,maxNumCols:n.length};return bn(i.parser,s,z1(i.envName))},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(i){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[i.envName.replace("*","")],t="c",r={hskipBeforeAndAfter:!1,cols:[{type:"align",align:t}]};if(i.envName.charAt(i.envName.length-1)==="*"){var n=i.parser;if(n.consumeSpaces(),n.fetch().text==="["){if(n.consume(),n.consumeSpaces(),t=n.fetch().text,"lcr".indexOf(t)===-1)throw new G("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),r.cols=[{type:"align",align:t}]}}var s=bn(i.parser,r,z1(i.envName)),a=Math.max(0,...s.body.map(o=>o.length));return s.cols=new Array(a).fill({type:"align",align:t}),e?{type:"leftright",mode:i.mode,body:[s],left:e[0],right:e[1],rightColor:void 0}:s},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(i){var e={arraystretch:.5},t=bn(i.parser,e,"script");return t.colSeparationType="small",t},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["subarray"],props:{numArgs:1},handler(i,e){var t=Ih(e[0]),r=t?[e[0]]:me(e[0],"ordgroup").body,n=r.map(function(a){var o=A1(a),l=o.text;if("lc".indexOf(l)!==-1)return{type:"align",align:l};throw new G("Unknown column alignment: "+l,a)});if(n.length>1)throw new G("{subarray} can contain only one column");var s={cols:n,hskipBeforeAndAfter:!1,arraystretch:.5};if(s=bn(i.parser,s,"script"),s.body.length>0&&s.body[0].length>1)throw new G("{subarray} can contain only one column");return s},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(i){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},t=bn(i.parser,e,z1(i.envName));return{type:"leftright",mode:i.mode,body:[t],left:i.envName.indexOf("r")>-1?".":"\\{",right:i.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:G4,htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(i){["gather","gather*"].includes(i.envName)&&Dh(i);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:I1(i.envName),emptySingleRow:!0,leqno:i.parser.settings.leqno};return bn(i.parser,e,"display")},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:G4,htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(i){Dh(i);var e={autoTag:I1(i.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:i.parser.settings.leqno};return bn(i.parser,e,"display")},htmlBuilder:fr,mathmlBuilder:mr});ur({type:"array",names:["CD"],props:{numArgs:0},handler(i){return Dh(i),yA(i.parser)},htmlBuilder:fr,mathmlBuilder:mr});w("\\nonumber","\\gdef\\@eqnsw{0}");w("\\notag","\\nonumber");Z({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(i,e){throw new G(i.funcName+" valid only within array environment")}});K6=$4;Z({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];if(n.type!=="ordgroup")throw new G("Invalid environment name",n);for(var s="",a=0;a{var t=i.font,r=e.withFont(t);return Me(i.body,r)},W4=(i,e)=>{var t=i.font,r=e.withFont(t);return ze(i.body,r)},Z6={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Z({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=Ah(e[0]),s=r;return s in Z6&&(s=Z6[s]),{type:"font",mode:t.mode,font:s.slice(1),body:n}},htmlBuilder:V4,mathmlBuilder:W4});Z({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(i,e)=>{var{parser:t}=i,r=e[0],n=Ne.isCharacterBox(r);return{type:"mclass",mode:t.mode,mclass:zh(r),body:[{type:"font",mode:t.mode,font:"boldsymbol",body:r}],isCharacterBox:n}}});Z({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(i,e)=>{var{parser:t,funcName:r,breakOnTokenText:n}=i,{mode:s}=t,a=t.parseExpression(!0,n),o="math"+r.slice(1);return{type:"font",mode:s,font:o,body:{type:"ordgroup",mode:t.mode,body:a}}},htmlBuilder:V4,mathmlBuilder:W4});Y4=(i,e)=>{var t=e;return i==="display"?t=t.id>=ae.SCRIPT.id?t.text():ae.DISPLAY:i==="text"&&t.size===ae.DISPLAY.size?t=ae.TEXT:i==="script"?t=ae.SCRIPT:i==="scriptscript"&&(t=ae.SCRIPTSCRIPT),t},R1=(i,e)=>{var t=Y4(i.size,e.style),r=t.fracNum(),n=t.fracDen(),s;s=e.havingStyle(r);var a=Me(i.numer,s,e);if(i.continued){var o=8.5/e.fontMetrics().ptPerEm,l=3.5/e.fontMetrics().ptPerEm;a.height=a.height0?g=3*f:g=7*f,x=e.fontMetrics().denom1):(c>0?(m=e.fontMetrics().num2,g=f):(m=e.fontMetrics().num3,g=3*f),x=e.fontMetrics().denom2);var y;if(d){var S=e.fontMetrics().axisHeight;m-a.depth-(S+.5*c){var t=new $.MathNode("mfrac",[ze(i.numer,e),ze(i.denom,e)]);if(!i.hasBarLine)t.setAttribute("linethickness","0px");else if(i.barSize){var r=Xe(i.barSize,e);t.setAttribute("linethickness",V(r))}var n=Y4(i.size,e.style);if(n.size!==e.style.size){t=new $.MathNode("mstyle",[t]);var s=n.size===ae.DISPLAY.size?"true":"false";t.setAttribute("displaystyle",s),t.setAttribute("scriptlevel","0")}if(i.leftDelim!=null||i.rightDelim!=null){var a=[];if(i.leftDelim!=null){var o=new $.MathNode("mo",[new $.TextNode(i.leftDelim.replace("\\",""))]);o.setAttribute("fence","true"),a.push(o)}if(a.push(t),i.rightDelim!=null){var l=new $.MathNode("mo",[new $.TextNode(i.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),a.push(l)}return E1(a)}return t};Z({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=e[1],a,o=null,l=null,h="auto";switch(r){case"\\dfrac":case"\\frac":case"\\tfrac":a=!0;break;case"\\\\atopfrac":a=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":a=!1,o="(",l=")";break;case"\\\\bracefrac":a=!1,o="\\{",l="\\}";break;case"\\\\brackfrac":a=!1,o="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(r){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:t.mode,continued:!1,numer:n,denom:s,hasBarLine:a,leftDelim:o,rightDelim:l,size:h,barSize:null}},htmlBuilder:R1,mathmlBuilder:D1});Z({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=e[1];return{type:"genfrac",mode:t.mode,continued:!0,numer:n,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}});Z({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(i){var{parser:e,funcName:t,token:r}=i,n;switch(t){case"\\over":n="\\frac";break;case"\\choose":n="\\binom";break;case"\\atop":n="\\\\atopfrac";break;case"\\brace":n="\\\\bracefrac";break;case"\\brack":n="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:n,token:r}}});Q6=["display","text","script","scriptscript"],J6=function(e){var t=null;return e.length>0&&(t=e,t=t==="."?null:t),t};Z({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(i,e){var{parser:t}=i,r=e[4],n=e[5],s=Ah(e[0]),a=s.type==="atom"&&s.family==="open"?J6(s.text):null,o=Ah(e[1]),l=o.type==="atom"&&o.family==="close"?J6(o.text):null,h=me(e[2],"size"),d,c=null;h.isBlank?d=!0:(c=h.value,d=c.number>0);var f="auto",m=e[3];if(m.type==="ordgroup"){if(m.body.length>0){var g=me(m.body[0],"textord");f=Q6[Number(g.text)]}}else m=me(m,"textord"),f=Q6[Number(m.text)];return{type:"genfrac",mode:t.mode,numer:r,denom:n,continued:!1,hasBarLine:d,barSize:c,leftDelim:a,rightDelim:l,size:f}},htmlBuilder:R1,mathmlBuilder:D1});Z({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(i,e){var{parser:t,funcName:r,token:n}=i;return{type:"infix",mode:t.mode,replaceWith:"\\\\abovefrac",size:me(e[0],"size").value,token:n}}});Z({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=dS(me(e[1],"infix").size),a=e[2],o=s.number>0;return{type:"genfrac",mode:t.mode,numer:n,denom:a,continued:!1,hasBarLine:o,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:R1,mathmlBuilder:D1});X4=(i,e)=>{var t=e.style,r,n;i.type==="supsub"?(r=i.sup?Me(i.sup,e.havingStyle(t.sup()),e):Me(i.sub,e.havingStyle(t.sub()),e),n=me(i.base,"horizBrace")):n=me(i,"horizBrace");var s=Me(n.base,e.havingBaseStyle(ae.DISPLAY)),a=Rr.svgSpan(n,e),o;if(n.isOver?(o=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:a}]},e),o.children[0].children[0].children[1].classes.push("svg-align")):(o=z.makeVList({positionType:"bottom",positionData:s.depth+.1+a.height,children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:s}]},e),o.children[0].children[0].children[0].classes.push("svg-align")),r){var l=z.makeSpan(["mord",n.isOver?"mover":"munder"],[o],e);n.isOver?o=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},e):o=z.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},e)}return z.makeSpan(["mord",n.isOver?"mover":"munder"],[o],e)},zA=(i,e)=>{var t=Rr.mathMLnode(i.label);return new $.MathNode(i.isOver?"mover":"munder",[ze(i.base,e),t])};Z({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i;return{type:"horizBrace",mode:t.mode,label:r,isOver:/^\\over/.test(r),base:e[0]}},htmlBuilder:X4,mathmlBuilder:zA});Z({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[1],n=me(e[0],"url").url;return t.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:t.mode,href:n,body:rt(r)}:t.formatUnsupportedCmd("\\href")},htmlBuilder:(i,e)=>{var t=ct(i.body,e,!1);return z.makeAnchor(i.href,[],t,e)},mathmlBuilder:(i,e)=>{var t=vn(i.body,e);return t instanceof Bt||(t=new Bt("mrow",[t])),t.setAttribute("href",i.href),t}});Z({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=me(e[0],"url").url;if(!t.settings.isTrusted({command:"\\url",url:r}))return t.formatUnsupportedCmd("\\url");for(var n=[],s=0;s{var{parser:t,funcName:r,token:n}=i,s=me(e[0],"raw").string,a=e[1];t.settings.strict&&t.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var o,l={};switch(r){case"\\htmlClass":l.class=s,o={command:"\\htmlClass",class:s};break;case"\\htmlId":l.id=s,o={command:"\\htmlId",id:s};break;case"\\htmlStyle":l.style=s,o={command:"\\htmlStyle",style:s};break;case"\\htmlData":{for(var h=s.split(","),d=0;d{var t=ct(i.body,e,!1),r=["enclosing"];i.attributes.class&&r.push(...i.attributes.class.trim().split(/\s+/));var n=z.makeSpan(r,t,e);for(var s in i.attributes)s!=="class"&&i.attributes.hasOwnProperty(s)&&n.setAttribute(s,i.attributes[s]);return n},mathmlBuilder:(i,e)=>vn(i.body,e)});Z({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i;return{type:"htmlmathml",mode:t.mode,html:rt(e[0]),mathml:rt(e[1])}},htmlBuilder:(i,e)=>{var t=ct(i.html,e,!1);return z.makeFragment(t)},mathmlBuilder:(i,e)=>vn(i.mathml,e)});a1=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new G("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!m4(r))throw new G("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};Z({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(i,e,t)=>{var{parser:r}=i,n={number:0,unit:"em"},s={number:.9,unit:"em"},a={number:0,unit:"em"},o="";if(t[0])for(var l=me(t[0],"raw").string,h=l.split(","),d=0;d{var t=Xe(i.height,e),r=0;i.totalheight.number>0&&(r=Xe(i.totalheight,e)-t);var n=0;i.width.number>0&&(n=Xe(i.width,e));var s={height:V(t+r)};n>0&&(s.width=V(n)),r>0&&(s.verticalAlign=V(-r));var a=new u1(i.src,i.alt,s);return a.height=t,a.depth=r,a},mathmlBuilder:(i,e)=>{var t=new $.MathNode("mglyph",[]);t.setAttribute("alt",i.alt);var r=Xe(i.height,e),n=0;if(i.totalheight.number>0&&(n=Xe(i.totalheight,e)-r,t.setAttribute("valign",V(-n))),t.setAttribute("height",V(r+n)),i.width.number>0){var s=Xe(i.width,e);t.setAttribute("width",V(s))}return t.setAttribute("src",i.src),t}});Z({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(i,e){var{parser:t,funcName:r}=i,n=me(e[0],"size");if(t.settings.strict){var s=r[1]==="m",a=n.value.unit==="mu";s?(a||t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" supports only mu units, "+("not "+n.value.unit+" units")),t.mode!=="math"&&t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" works only in math mode")):a&&t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" doesn't support mu units")}return{type:"kern",mode:t.mode,dimension:n.value}},htmlBuilder(i,e){return z.makeGlue(i.dimension,e)},mathmlBuilder(i,e){var t=Xe(i.dimension,e);return new $.SpaceNode(t)}});Z({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"lap",mode:t.mode,alignment:r.slice(5),body:n}},htmlBuilder:(i,e)=>{var t;i.alignment==="clap"?(t=z.makeSpan([],[Me(i.body,e)]),t=z.makeSpan(["inner"],[t],e)):t=z.makeSpan(["inner"],[Me(i.body,e)]);var r=z.makeSpan(["fix"],[]),n=z.makeSpan([i.alignment],[t,r],e),s=z.makeSpan(["strut"]);return s.style.height=V(n.height+n.depth),n.depth&&(s.style.verticalAlign=V(-n.depth)),n.children.unshift(s),n=z.makeSpan(["thinbox"],[n],e),z.makeSpan(["mord","vbox"],[n],e)},mathmlBuilder:(i,e)=>{var t=new $.MathNode("mpadded",[ze(i.body,e)]);if(i.alignment!=="rlap"){var r=i.alignment==="llap"?"-1":"-0.5";t.setAttribute("lspace",r+"width")}return t.setAttribute("width","0px"),t}});Z({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,e){var{funcName:t,parser:r}=i,n=r.mode;r.switchMode("math");var s=t==="\\("?"\\)":"$",a=r.parseExpression(!1,s);return r.expect(s),r.switchMode(n),{type:"styling",mode:r.mode,style:"text",body:a}}});Z({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,e){throw new G("Mismatched "+i.funcName)}});e4=(i,e)=>{switch(e.style.size){case ae.DISPLAY.size:return i.display;case ae.TEXT.size:return i.text;case ae.SCRIPT.size:return i.script;case ae.SCRIPTSCRIPT.size:return i.scriptscript;default:return i.text}};Z({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(i,e)=>{var{parser:t}=i;return{type:"mathchoice",mode:t.mode,display:rt(e[0]),text:rt(e[1]),script:rt(e[2]),scriptscript:rt(e[3])}},htmlBuilder:(i,e)=>{var t=e4(i,e),r=ct(t,e,!1);return z.makeFragment(r)},mathmlBuilder:(i,e)=>{var t=e4(i,e);return vn(t,e)}});K4=(i,e,t,r,n,s,a)=>{i=z.makeSpan([],[i]);var o=t&&Ne.isCharacterBox(t),l,h;if(e){var d=Me(e,r.havingStyle(n.sup()),r);h={elem:d,kern:Math.max(r.fontMetrics().bigOpSpacing1,r.fontMetrics().bigOpSpacing3-d.depth)}}if(t){var c=Me(t,r.havingStyle(n.sub()),r);l={elem:c,kern:Math.max(r.fontMetrics().bigOpSpacing2,r.fontMetrics().bigOpSpacing4-c.height)}}var f;if(h&&l){var m=r.fontMetrics().bigOpSpacing5+l.elem.height+l.elem.depth+l.kern+i.depth+a;f=z.makeVList({positionType:"bottom",positionData:m,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:l.elem,marginLeft:V(-s)},{type:"kern",size:l.kern},{type:"elem",elem:i},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(s)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else if(l){var g=i.height-a;f=z.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:l.elem,marginLeft:V(-s)},{type:"kern",size:l.kern},{type:"elem",elem:i}]},r)}else if(h){var x=i.depth+a;f=z.makeVList({positionType:"bottom",positionData:x,children:[{type:"elem",elem:i},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(s)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else return i;var y=[f];if(l&&s!==0&&!o){var b=z.makeSpan(["mspace"],[],r);b.style.marginRight=V(s),y.unshift(b)}return z.makeSpan(["mop","op-limits"],y,r)},Z4=["\\smallint"],pa=(i,e)=>{var t,r,n=!1,s;i.type==="supsub"?(t=i.sup,r=i.sub,s=me(i.base,"op"),n=!0):s=me(i,"op");var a=e.style,o=!1;a.size===ae.DISPLAY.size&&s.symbol&&!Z4.includes(s.name)&&(o=!0);var l;if(s.symbol){var h=o?"Size2-Regular":"Size1-Regular",d="";if((s.name==="\\oiint"||s.name==="\\oiiint")&&(d=s.name.slice(1),s.name=d==="oiint"?"\\iint":"\\iiint"),l=z.makeSymbol(s.name,h,"math",e,["mop","op-symbol",o?"large-op":"small-op"]),d.length>0){var c=l.italic,f=z.staticSvg(d+"Size"+(o?"2":"1"),e);l=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:l,shift:0},{type:"elem",elem:f,shift:o?.08:0}]},e),s.name="\\"+d,l.classes.unshift("mop"),l.italic=c}}else if(s.body){var m=ct(s.body,e,!0);m.length===1&&m[0]instanceof ei?(l=m[0],l.classes[0]="mop"):l=z.makeSpan(["mop"],m,e)}else{for(var g=[],x=1;x{var t;if(i.symbol)t=new Bt("mo",[Ci(i.name,i.mode)]),Z4.includes(i.name)&&t.setAttribute("largeop","false");else if(i.body)t=new Bt("mo",ti(i.body,e));else{t=new Bt("mi",[new ki(i.name.slice(1))]);var r=new Bt("mo",[Ci("\u2061","text")]);i.parentIsSupSub?t=new Bt("mrow",[t,r]):t=E4([t,r])}return t},RA={"\u220F":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22C0":"\\bigwedge","\u22C1":"\\bigvee","\u22C2":"\\bigcap","\u22C3":"\\bigcup","\u2A00":"\\bigodot","\u2A01":"\\bigoplus","\u2A02":"\\bigotimes","\u2A04":"\\biguplus","\u2A06":"\\bigsqcup"};Z({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220F","\u2210","\u2211","\u22C0","\u22C1","\u22C2","\u22C3","\u2A00","\u2A01","\u2A02","\u2A04","\u2A06"],props:{numArgs:0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=r;return n.length===1&&(n=RA[n]),{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:pa,mathmlBuilder:rl});Z({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:rt(r)}},htmlBuilder:pa,mathmlBuilder:rl});DA={"\u222B":"\\int","\u222C":"\\iint","\u222D":"\\iiint","\u222E":"\\oint","\u222F":"\\oiint","\u2230":"\\oiiint"};Z({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(i){var{parser:e,funcName:t}=i;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:t}},htmlBuilder:pa,mathmlBuilder:rl});Z({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(i){var{parser:e,funcName:t}=i;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:t}},htmlBuilder:pa,mathmlBuilder:rl});Z({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222B","\u222C","\u222D","\u222E","\u222F","\u2230"],props:{numArgs:0,allowedInArgument:!0},handler(i){var{parser:e,funcName:t}=i,r=t;return r.length===1&&(r=DA[r]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:r}},htmlBuilder:pa,mathmlBuilder:rl});Q4=(i,e)=>{var t,r,n=!1,s;i.type==="supsub"?(t=i.sup,r=i.sub,s=me(i.base,"operatorname"),n=!0):s=me(i,"operatorname");var a;if(s.body.length>0){for(var o=s.body.map(c=>{var f=c.text;return typeof f=="string"?{type:"textord",mode:c.mode,text:f}:c}),l=ct(o,e.withFont("mathrm"),!0),h=0;h{for(var t=ti(i.body,e.withFont("mathrm")),r=!0,n=0;nd.toText()).join("");t=[new $.TextNode(o)]}var l=new $.MathNode("mi",t);l.setAttribute("mathvariant","normal");var h=new $.MathNode("mo",[Ci("\u2061","text")]);return i.parentIsSupSub?new $.MathNode("mrow",[l,h]):$.newDocumentFragment([l,h])};Z({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"operatorname",mode:t.mode,body:rt(n),alwaysHandleSupSub:r==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},htmlBuilder:Q4,mathmlBuilder:OA});w("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");gs({type:"ordgroup",htmlBuilder(i,e){return i.semisimple?z.makeFragment(ct(i.body,e,!1)):z.makeSpan(["mord"],ct(i.body,e,!0),e)},mathmlBuilder(i,e){return vn(i.body,e,!0)}});Z({type:"overline",names:["\\overline"],props:{numArgs:1},handler(i,e){var{parser:t}=i,r=e[0];return{type:"overline",mode:t.mode,body:r}},htmlBuilder(i,e){var t=Me(i.body,e.havingCrampedStyle()),r=z.makeLineSpan("overline-line",e),n=e.fontMetrics().defaultRuleThickness,s=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:t},{type:"kern",size:3*n},{type:"elem",elem:r},{type:"kern",size:n}]},e);return z.makeSpan(["mord","overline"],[s],e)},mathmlBuilder(i,e){var t=new $.MathNode("mo",[new $.TextNode("\u203E")]);t.setAttribute("stretchy","true");var r=new $.MathNode("mover",[ze(i.body,e),t]);return r.setAttribute("accent","true"),r}});Z({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"phantom",mode:t.mode,body:rt(r)}},htmlBuilder:(i,e)=>{var t=ct(i.body,e.withPhantom(),!1);return z.makeFragment(t)},mathmlBuilder:(i,e)=>{var t=ti(i.body,e);return new $.MathNode("mphantom",t)}});Z({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"hphantom",mode:t.mode,body:r}},htmlBuilder:(i,e)=>{var t=z.makeSpan([],[Me(i.body,e.withPhantom())]);if(t.height=0,t.depth=0,t.children)for(var r=0;r{var t=ti(rt(i.body),e),r=new $.MathNode("mphantom",t),n=new $.MathNode("mpadded",[r]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}});Z({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"vphantom",mode:t.mode,body:r}},htmlBuilder:(i,e)=>{var t=z.makeSpan(["inner"],[Me(i.body,e.withPhantom())]),r=z.makeSpan(["fix"],[]);return z.makeSpan(["mord","rlap"],[t,r],e)},mathmlBuilder:(i,e)=>{var t=ti(rt(i.body),e),r=new $.MathNode("mphantom",t),n=new $.MathNode("mpadded",[r]);return n.setAttribute("width","0px"),n}});Z({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(i,e){var{parser:t}=i,r=me(e[0],"size").value,n=e[1];return{type:"raisebox",mode:t.mode,dy:r,body:n}},htmlBuilder(i,e){var t=Me(i.body,e),r=Xe(i.dy,e);return z.makeVList({positionType:"shift",positionData:-r,children:[{type:"elem",elem:t}]},e)},mathmlBuilder(i,e){var t=new $.MathNode("mpadded",[ze(i.body,e)]),r=i.dy.number+i.dy.unit;return t.setAttribute("voffset",r),t}});Z({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(i){var{parser:e}=i;return{type:"internal",mode:e.mode}}});Z({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(i,e,t){var{parser:r}=i,n=t[0],s=me(e[0],"size"),a=me(e[1],"size");return{type:"rule",mode:r.mode,shift:n&&me(n,"size").value,width:s.value,height:a.value}},htmlBuilder(i,e){var t=z.makeSpan(["mord","rule"],[],e),r=Xe(i.width,e),n=Xe(i.height,e),s=i.shift?Xe(i.shift,e):0;return t.style.borderRightWidth=V(r),t.style.borderTopWidth=V(n),t.style.bottom=V(s),t.width=r,t.height=n+s,t.depth=-s,t.maxFontSize=n*1.125*e.sizeMultiplier,t},mathmlBuilder(i,e){var t=Xe(i.width,e),r=Xe(i.height,e),n=i.shift?Xe(i.shift,e):0,s=e.color&&e.getColor()||"black",a=new $.MathNode("mspace");a.setAttribute("mathbackground",s),a.setAttribute("width",V(t)),a.setAttribute("height",V(r));var o=new $.MathNode("mpadded",[a]);return n>=0?o.setAttribute("height",V(n)):(o.setAttribute("height",V(n)),o.setAttribute("depth",V(-n))),o.setAttribute("voffset",V(n)),o}});t4=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],BA=(i,e)=>{var t=e.havingSize(i.size);return J4(i.body,t,e)};Z({type:"sizing",names:t4,props:{numArgs:0,allowedInText:!0},handler:(i,e)=>{var{breakOnTokenText:t,funcName:r,parser:n}=i,s=n.parseExpression(!1,t);return{type:"sizing",mode:n.mode,size:t4.indexOf(r)+1,body:s}},htmlBuilder:BA,mathmlBuilder:(i,e)=>{var t=e.havingSize(i.size),r=ti(i.body,t),n=new $.MathNode("mstyle",r);return n.setAttribute("mathsize",V(t.sizeMultiplier)),n}});Z({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(i,e,t)=>{var{parser:r}=i,n=!1,s=!1,a=t[0]&&me(t[0],"ordgroup");if(a)for(var o="",l=0;l{var t=z.makeSpan([],[Me(i.body,e)]);if(!i.smashHeight&&!i.smashDepth)return t;if(i.smashHeight&&(t.height=0,t.children))for(var r=0;r{var t=new $.MathNode("mpadded",[ze(i.body,e)]);return i.smashHeight&&t.setAttribute("height","0px"),i.smashDepth&&t.setAttribute("depth","0px"),t}});Z({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(i,e,t){var{parser:r}=i,n=t[0],s=e[0];return{type:"sqrt",mode:r.mode,body:s,index:n}},htmlBuilder(i,e){var t=Me(i.body,e.havingCrampedStyle());t.height===0&&(t.height=e.fontMetrics().xHeight),t=z.wrapFragment(t,e);var r=e.fontMetrics(),n=r.defaultRuleThickness,s=n;e.style.idt.height+t.depth+a&&(a=(a+c-t.height-t.depth)/2);var f=l.height-t.height-a-h;t.style.paddingLeft=V(d);var m=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:t,wrapperClasses:["svg-align"]},{type:"kern",size:-(t.height+f)},{type:"elem",elem:l},{type:"kern",size:h}]},e);if(i.index){var g=e.havingStyle(ae.SCRIPTSCRIPT),x=Me(i.index,g,e),y=.6*(m.height-m.depth),b=z.makeVList({positionType:"shift",positionData:-y,children:[{type:"elem",elem:x}]},e),S=z.makeSpan(["root"],[b]);return z.makeSpan(["mord","sqrt"],[S,m],e)}else return z.makeSpan(["mord","sqrt"],[m],e)},mathmlBuilder(i,e){var{body:t,index:r}=i;return r?new $.MathNode("mroot",[ze(t,e),ze(r,e)]):new $.MathNode("msqrt",[ze(t,e)])}});i4={display:ae.DISPLAY,text:ae.TEXT,script:ae.SCRIPT,scriptscript:ae.SCRIPTSCRIPT};Z({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i,e){var{breakOnTokenText:t,funcName:r,parser:n}=i,s=n.parseExpression(!0,t),a=r.slice(1,r.length-5);return{type:"styling",mode:n.mode,style:a,body:s}},htmlBuilder(i,e){var t=i4[i.style],r=e.havingStyle(t).withFont("");return J4(i.body,r,e)},mathmlBuilder(i,e){var t=i4[i.style],r=e.havingStyle(t),n=ti(i.body,r),s=new $.MathNode("mstyle",n),a={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},o=a[i.style];return s.setAttribute("scriptlevel",o[0]),s.setAttribute("displaystyle",o[1]),s}});PA=function(e,t){var r=e.base;if(r)if(r.type==="op"){var n=r.limits&&(t.style.size===ae.DISPLAY.size||r.alwaysHandleSupSub);return n?pa:null}else if(r.type==="operatorname"){var s=r.alwaysHandleSupSub&&(t.style.size===ae.DISPLAY.size||r.limits);return s?Q4:null}else{if(r.type==="accent")return Ne.isCharacterBox(r.base)?k1:null;if(r.type==="horizBrace"){var a=!e.sub;return a===r.isOver?X4:null}else return null}else return null};gs({type:"supsub",htmlBuilder(i,e){var t=PA(i,e);if(t)return t(i,e);var{base:r,sup:n,sub:s}=i,a=Me(r,e),o,l,h=e.fontMetrics(),d=0,c=0,f=r&&Ne.isCharacterBox(r);if(n){var m=e.havingStyle(e.style.sup());o=Me(n,m,e),f||(d=a.height-m.fontMetrics().supDrop*m.sizeMultiplier/e.sizeMultiplier)}if(s){var g=e.havingStyle(e.style.sub());l=Me(s,g,e),f||(c=a.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}var x;e.style===ae.DISPLAY?x=h.sup1:e.style.cramped?x=h.sup3:x=h.sup2;var y=e.sizeMultiplier,b=V(.5/h.ptPerEm/y),S=null;if(l){var A=i.base&&i.base.type==="op"&&i.base.name&&(i.base.name==="\\oiint"||i.base.name==="\\oiiint");(a instanceof ei||A)&&(S=V(-a.italic))}var C;if(o&&l){d=Math.max(d,x,o.depth+.25*h.xHeight),c=Math.max(c,h.sub2);var I=h.defaultRuleThickness,O=4*I;if(d-o.depth-(l.height-c)0&&(d+=q,c-=q)}var P=[{type:"elem",elem:l,shift:c,marginRight:b,marginLeft:S},{type:"elem",elem:o,shift:-d,marginRight:b}];C=z.makeVList({positionType:"individualShift",children:P},e)}else if(l){c=Math.max(c,h.sub1,l.height-.8*h.xHeight);var W=[{type:"elem",elem:l,marginLeft:S,marginRight:b}];C=z.makeVList({positionType:"shift",positionData:c,children:W},e)}else if(o)d=Math.max(d,x,o.depth+.25*h.xHeight),C=z.makeVList({positionType:"shift",positionData:-d,children:[{type:"elem",elem:o,marginRight:b}]},e);else throw new Error("supsub must have either sup or sub.");var ne=m1(a,"right")||"mord";return z.makeSpan([ne],[a,z.makeSpan(["msupsub"],[C])],e)},mathmlBuilder(i,e){var t=!1,r,n;i.base&&i.base.type==="horizBrace"&&(n=!!i.sup,n===i.base.isOver&&(t=!0,r=i.base.isOver)),i.base&&(i.base.type==="op"||i.base.type==="operatorname")&&(i.base.parentIsSupSub=!0);var s=[ze(i.base,e)];i.sub&&s.push(ze(i.sub,e)),i.sup&&s.push(ze(i.sup,e));var a;if(t)a=r?"mover":"munder";else if(i.sub)if(i.sup){var h=i.base;h&&h.type==="op"&&h.limits&&e.style===ae.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===ae.DISPLAY||h.limits)?a="munderover":a="msubsup"}else{var l=i.base;l&&l.type==="op"&&l.limits&&(e.style===ae.DISPLAY||l.alwaysHandleSupSub)||l&&l.type==="operatorname"&&l.alwaysHandleSupSub&&(l.limits||e.style===ae.DISPLAY)?a="munder":a="msub"}else{var o=i.base;o&&o.type==="op"&&o.limits&&(e.style===ae.DISPLAY||o.alwaysHandleSupSub)||o&&o.type==="operatorname"&&o.alwaysHandleSupSub&&(o.limits||e.style===ae.DISPLAY)?a="mover":a="msup"}return new $.MathNode(a,s)}});gs({type:"atom",htmlBuilder(i,e){return z.mathsym(i.text,i.mode,e,["m"+i.family])},mathmlBuilder(i,e){var t=new $.MathNode("mo",[Ci(i.text,i.mode)]);if(i.family==="bin"){var r=S1(i,e);r==="bold-italic"&&t.setAttribute("mathvariant",r)}else i.family==="punct"?t.setAttribute("separator","true"):(i.family==="open"||i.family==="close")&&t.setAttribute("stretchy","false");return t}});eg={mi:"italic",mn:"normal",mtext:"normal"};gs({type:"mathord",htmlBuilder(i,e){return z.makeOrd(i,e,"mathord")},mathmlBuilder(i,e){var t=new $.MathNode("mi",[Ci(i.text,i.mode,e)]),r=S1(i,e)||"italic";return r!==eg[t.type]&&t.setAttribute("mathvariant",r),t}});gs({type:"textord",htmlBuilder(i,e){return z.makeOrd(i,e,"textord")},mathmlBuilder(i,e){var t=Ci(i.text,i.mode,e),r=S1(i,e)||"normal",n;return i.mode==="text"?n=new $.MathNode("mtext",[t]):/[0-9]/.test(i.text)?n=new $.MathNode("mn",[t]):i.text==="\\prime"?n=new $.MathNode("mo",[t]):n=new $.MathNode("mi",[t]),r!==eg[n.type]&&n.setAttribute("mathvariant",r),n}});o1={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},l1={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};gs({type:"spacing",htmlBuilder(i,e){if(l1.hasOwnProperty(i.text)){var t=l1[i.text].className||"";if(i.mode==="text"){var r=z.makeOrd(i,e,"textord");return r.classes.push(t),r}else return z.makeSpan(["mspace",t],[z.mathsym(i.text,i.mode,e)],e)}else{if(o1.hasOwnProperty(i.text))return z.makeSpan(["mspace",o1[i.text]],[],e);throw new G('Unknown type of space "'+i.text+'"')}},mathmlBuilder(i,e){var t;if(l1.hasOwnProperty(i.text))t=new $.MathNode("mtext",[new $.TextNode("\xA0")]);else{if(o1.hasOwnProperty(i.text))return new $.MathNode("mspace");throw new G('Unknown type of space "'+i.text+'"')}return t}});r4=()=>{var i=new $.MathNode("mtd",[]);return i.setAttribute("width","50%"),i};gs({type:"tag",mathmlBuilder(i,e){var t=new $.MathNode("mtable",[new $.MathNode("mtr",[r4(),new $.MathNode("mtd",[vn(i.body,e)]),r4(),new $.MathNode("mtd",[vn(i.tag,e)])])]);return t.setAttribute("width","100%"),t}});n4={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},s4={"\\textbf":"textbf","\\textmd":"textmd"},FA={"\\textit":"textit","\\textup":"textup"},a4=(i,e)=>{var t=i.font;if(t){if(n4[t])return e.withTextFontFamily(n4[t]);if(s4[t])return e.withTextFontWeight(s4[t]);if(t==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(FA[t])};Z({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"text",mode:t.mode,body:rt(n),font:r}},htmlBuilder(i,e){var t=a4(i,e),r=ct(i.body,t,!0);return z.makeSpan(["mord","text"],r,t)},mathmlBuilder(i,e){var t=a4(i,e);return vn(i.body,t)}});Z({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"underline",mode:t.mode,body:e[0]}},htmlBuilder(i,e){var t=Me(i.body,e),r=z.makeLineSpan("underline-line",e),n=e.fontMetrics().defaultRuleThickness,s=z.makeVList({positionType:"top",positionData:t.height,children:[{type:"kern",size:n},{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:t}]},e);return z.makeSpan(["mord","underline"],[s],e)},mathmlBuilder(i,e){var t=new $.MathNode("mo",[new $.TextNode("\u203E")]);t.setAttribute("stretchy","true");var r=new $.MathNode("munder",[ze(i.body,e),t]);return r.setAttribute("accentunder","true"),r}});Z({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(i,e){var{parser:t}=i;return{type:"vcenter",mode:t.mode,body:e[0]}},htmlBuilder(i,e){var t=Me(i.body,e),r=e.fontMetrics().axisHeight,n=.5*(t.height-r-(t.depth+r));return z.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:t}]},e)},mathmlBuilder(i,e){return new $.MathNode("mpadded",[ze(i.body,e)],["vcenter"])}});Z({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(i,e,t){throw new G("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(i,e){for(var t=o4(i),r=[],n=e.havingStyle(e.style.text()),s=0;si.body.replace(/ /g,i.star?"\u2423":"\xA0"),xn=T4,tg=`[ \r - ]`,qA="\\\\[a-zA-Z@]+",HA="\\\\[^\uD800-\uDFFF]",UA="("+qA+")"+tg+"*",$A=`\\\\( +-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}},ms=class{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return this.classes.includes(e)}toNode(){for(var e=document.createDocumentFragment(),t=0;tt.toText();return this.children.map(e).join("")}},lr={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},xh={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},K6={\u00C5:"A",\u00D0:"D",\u00DE:"o",\u00E5:"a",\u00F0:"d",\u00FE:"o",\u0410:"A",\u0411:"B",\u0412:"B",\u0413:"F",\u0414:"A",\u0415:"E",\u0416:"K",\u0417:"3",\u0418:"N",\u0419:"N",\u041A:"K",\u041B:"N",\u041C:"M",\u041D:"H",\u041E:"O",\u041F:"N",\u0420:"P",\u0421:"C",\u0422:"T",\u0423:"y",\u0424:"O",\u0425:"X",\u0426:"U",\u0427:"h",\u0428:"W",\u0429:"W",\u042A:"B",\u042B:"X",\u042C:"B",\u042D:"3",\u042E:"X",\u042F:"R",\u0430:"a",\u0431:"b",\u0432:"a",\u0433:"r",\u0434:"y",\u0435:"e",\u0436:"m",\u0437:"e",\u0438:"n",\u0439:"n",\u043A:"n",\u043B:"n",\u043C:"m",\u043D:"n",\u043E:"o",\u043F:"n",\u0440:"p",\u0441:"c",\u0442:"o",\u0443:"y",\u0444:"b",\u0445:"x",\u0446:"n",\u0447:"n",\u0448:"w",\u0449:"w",\u044A:"a",\u044B:"m",\u044C:"a",\u044D:"e",\u044E:"m",\u044F:"r"};l1={};iA=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],Z6=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],Q6=function(e,t){return t.size<2?e:iA[e-1][t.size-1]},Lh=class i{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||i.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=Z6[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new i(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:Q6(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:Z6[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=Q6(i.BASESIZE,e);return this.size===t&&this.textSize===i.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==i.BASESIZE?["sizing","reset-size"+this.size,"size"+i.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=tA(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}};Lh.BASESIZE=6;M1={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},rA={ex:!0,em:!0,mu:!0},k4=function(e){return typeof e!="string"&&(e=e.unit),e in M1||e in rA||e==="ex"},Ke=function(e,t){var r;if(e.unit in M1)r=M1[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if(e.unit==="mu")r=t.fontMetrics().cssEmPerMu;else{var n;if(t.style.isTight()?n=t.havingStyle(t.style.text()):n=t,e.unit==="ex")r=n.fontMetrics().xHeight;else if(e.unit==="em")r=n.fontMetrics().quad;else throw new G("Invalid unit: '"+e.unit+"'");n!==t&&(r*=n.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},V=function(e){return+e.toFixed(4)+"em"},xn=function(e){return e.filter(t=>t).join(" ")},C4=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},_4=function(e){var t=document.createElement(e);t.className=xn(this.classes);for(var r in this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var s=0;s/=\x00-\x1f]/,L4=function(e){var t="<"+e;this.classes.length&&(t+=' class="'+Ee.escape(xn(this.classes))+'"');var r="";for(var n in this.style)this.style.hasOwnProperty(n)&&(r+=Ee.hyphenate(n)+":"+this.style[n]+";");r&&(t+=' style="'+Ee.escape(r)+'"');for(var s in this.attributes)if(this.attributes.hasOwnProperty(s)){if(nA.test(s))throw new G("Invalid attribute name '"+s+"'");t+=" "+s+'="'+Ee.escape(this.attributes[s])+'"'}t+=">";for(var a=0;a",t},ps=class{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,C4.call(this,e,r,n),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return _4.call(this,"span")}toMarkup(){return L4.call(this,"span")}},al=class{constructor(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,C4.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return this.classes.includes(e)}toNode(){return _4.call(this,"a")}toMarkup(){return L4.call(this,"a")}},T1=class{constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return this.classes.includes(e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var t in this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e=''+Ee.escape(this.alt)+'0&&(t=document.createElement("span"),t.style.marginRight=V(this.italic)),this.classes.length>0&&(t=t||document.createElement("span"),t.className=xn(this.classes));for(var r in this.style)this.style.hasOwnProperty(r)&&(t=t||document.createElement("span"),t.style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;");for(var n in this.style)this.style.hasOwnProperty(n)&&(r+=Ee.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+Ee.escape(r)+'"');var s=Ee.escape(this.text);return e?(t+=">",t+=s,t+="",t):s}},Yi=class{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"svg");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&t.setAttribute(r,this.attributes[r]);for(var n=0;n':''}},ol=class{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"line");for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&t.setAttribute(r,this.attributes[r]);return t}toMarkup(){var e="","\\gt",!0);u(p,v,S,"\u2208","\\in",!0);u(p,v,S,"\uE020","\\@not");u(p,v,S,"\u2282","\\subset",!0);u(p,v,S,"\u2283","\\supset",!0);u(p,v,S,"\u2286","\\subseteq",!0);u(p,v,S,"\u2287","\\supseteq",!0);u(p,N,S,"\u2288","\\nsubseteq",!0);u(p,N,S,"\u2289","\\nsupseteq",!0);u(p,v,S,"\u22A8","\\models");u(p,v,S,"\u2190","\\leftarrow",!0);u(p,v,S,"\u2264","\\le");u(p,v,S,"\u2264","\\leq",!0);u(p,v,S,"<","\\lt",!0);u(p,v,S,"\u2192","\\rightarrow",!0);u(p,v,S,"\u2192","\\to");u(p,N,S,"\u2271","\\ngeq",!0);u(p,N,S,"\u2270","\\nleq",!0);u(p,v,Dr,"\xA0","\\ ");u(p,v,Dr,"\xA0","\\space");u(p,v,Dr,"\xA0","\\nobreakspace");u(H,v,Dr,"\xA0","\\ ");u(H,v,Dr,"\xA0"," ");u(H,v,Dr,"\xA0","\\space");u(H,v,Dr,"\xA0","\\nobreakspace");u(p,v,Dr,null,"\\nobreak");u(p,v,Dr,null,"\\allowbreak");u(p,v,Ph,",",",");u(p,v,Ph,";",";");u(p,N,ie,"\u22BC","\\barwedge",!0);u(p,N,ie,"\u22BB","\\veebar",!0);u(p,v,ie,"\u2299","\\odot",!0);u(p,v,ie,"\u2295","\\oplus",!0);u(p,v,ie,"\u2297","\\otimes",!0);u(p,v,_,"\u2202","\\partial",!0);u(p,v,ie,"\u2298","\\oslash",!0);u(p,N,ie,"\u229A","\\circledcirc",!0);u(p,N,ie,"\u22A1","\\boxdot",!0);u(p,v,ie,"\u25B3","\\bigtriangleup");u(p,v,ie,"\u25BD","\\bigtriangledown");u(p,v,ie,"\u2020","\\dagger");u(p,v,ie,"\u22C4","\\diamond");u(p,v,ie,"\u22C6","\\star");u(p,v,ie,"\u25C3","\\triangleleft");u(p,v,ie,"\u25B9","\\triangleright");u(p,v,pi,"{","\\{");u(H,v,_,"{","\\{");u(H,v,_,"{","\\textbraceleft");u(p,v,Ft,"}","\\}");u(H,v,_,"}","\\}");u(H,v,_,"}","\\textbraceright");u(p,v,pi,"{","\\lbrace");u(p,v,Ft,"}","\\rbrace");u(p,v,pi,"[","\\lbrack",!0);u(H,v,_,"[","\\lbrack",!0);u(p,v,Ft,"]","\\rbrack",!0);u(H,v,_,"]","\\rbrack",!0);u(p,v,pi,"(","\\lparen",!0);u(p,v,Ft,")","\\rparen",!0);u(H,v,_,"<","\\textless",!0);u(H,v,_,">","\\textgreater",!0);u(p,v,pi,"\u230A","\\lfloor",!0);u(p,v,Ft,"\u230B","\\rfloor",!0);u(p,v,pi,"\u2308","\\lceil",!0);u(p,v,Ft,"\u2309","\\rceil",!0);u(p,v,_,"\\","\\backslash");u(p,v,_,"\u2223","|");u(p,v,_,"\u2223","\\vert");u(H,v,_,"|","\\textbar",!0);u(p,v,_,"\u2225","\\|");u(p,v,_,"\u2225","\\Vert");u(H,v,_,"\u2225","\\textbardbl");u(H,v,_,"~","\\textasciitilde");u(H,v,_,"\\","\\textbackslash");u(H,v,_,"^","\\textasciicircum");u(p,v,S,"\u2191","\\uparrow",!0);u(p,v,S,"\u21D1","\\Uparrow",!0);u(p,v,S,"\u2193","\\downarrow",!0);u(p,v,S,"\u21D3","\\Downarrow",!0);u(p,v,S,"\u2195","\\updownarrow",!0);u(p,v,S,"\u21D5","\\Updownarrow",!0);u(p,v,lt,"\u2210","\\coprod");u(p,v,lt,"\u22C1","\\bigvee");u(p,v,lt,"\u22C0","\\bigwedge");u(p,v,lt,"\u2A04","\\biguplus");u(p,v,lt,"\u22C2","\\bigcap");u(p,v,lt,"\u22C3","\\bigcup");u(p,v,lt,"\u222B","\\int");u(p,v,lt,"\u222B","\\intop");u(p,v,lt,"\u222C","\\iint");u(p,v,lt,"\u222D","\\iiint");u(p,v,lt,"\u220F","\\prod");u(p,v,lt,"\u2211","\\sum");u(p,v,lt,"\u2A02","\\bigotimes");u(p,v,lt,"\u2A01","\\bigoplus");u(p,v,lt,"\u2A00","\\bigodot");u(p,v,lt,"\u222E","\\oint");u(p,v,lt,"\u222F","\\oiint");u(p,v,lt,"\u2230","\\oiiint");u(p,v,lt,"\u2A06","\\bigsqcup");u(p,v,lt,"\u222B","\\smallint");u(H,v,pa,"\u2026","\\textellipsis");u(p,v,pa,"\u2026","\\mathellipsis");u(H,v,pa,"\u2026","\\ldots",!0);u(p,v,pa,"\u2026","\\ldots",!0);u(p,v,pa,"\u22EF","\\@cdots",!0);u(p,v,pa,"\u22F1","\\ddots",!0);u(p,v,_,"\u22EE","\\varvdots");u(H,v,_,"\u22EE","\\varvdots");u(p,v,We,"\u02CA","\\acute");u(p,v,We,"\u02CB","\\grave");u(p,v,We,"\xA8","\\ddot");u(p,v,We,"~","\\tilde");u(p,v,We,"\u02C9","\\bar");u(p,v,We,"\u02D8","\\breve");u(p,v,We,"\u02C7","\\check");u(p,v,We,"^","\\hat");u(p,v,We,"\u20D7","\\vec");u(p,v,We,"\u02D9","\\dot");u(p,v,We,"\u02DA","\\mathring");u(p,v,se,"\uE131","\\@imath");u(p,v,se,"\uE237","\\@jmath");u(p,v,_,"\u0131","\u0131");u(p,v,_,"\u0237","\u0237");u(H,v,_,"\u0131","\\i",!0);u(H,v,_,"\u0237","\\j",!0);u(H,v,_,"\xDF","\\ss",!0);u(H,v,_,"\xE6","\\ae",!0);u(H,v,_,"\u0153","\\oe",!0);u(H,v,_,"\xF8","\\o",!0);u(H,v,_,"\xC6","\\AE",!0);u(H,v,_,"\u0152","\\OE",!0);u(H,v,_,"\xD8","\\O",!0);u(H,v,We,"\u02CA","\\'");u(H,v,We,"\u02CB","\\`");u(H,v,We,"\u02C6","\\^");u(H,v,We,"\u02DC","\\~");u(H,v,We,"\u02C9","\\=");u(H,v,We,"\u02D8","\\u");u(H,v,We,"\u02D9","\\.");u(H,v,We,"\xB8","\\c");u(H,v,We,"\u02DA","\\r");u(H,v,We,"\u02C7","\\v");u(H,v,We,"\xA8",'\\"');u(H,v,We,"\u02DD","\\H");u(H,v,We,"\u25EF","\\textcircled");I4={"--":!0,"---":!0,"``":!0,"''":!0};u(H,v,_,"\u2013","--",!0);u(H,v,_,"\u2013","\\textendash");u(H,v,_,"\u2014","---",!0);u(H,v,_,"\u2014","\\textemdash");u(H,v,_,"\u2018","`",!0);u(H,v,_,"\u2018","\\textquoteleft");u(H,v,_,"\u2019","'",!0);u(H,v,_,"\u2019","\\textquoteright");u(H,v,_,"\u201C","``",!0);u(H,v,_,"\u201C","\\textquotedblleft");u(H,v,_,"\u201D","''",!0);u(H,v,_,"\u201D","\\textquotedblright");u(p,v,_,"\xB0","\\degree",!0);u(H,v,_,"\xB0","\\degree");u(H,v,_,"\xB0","\\textdegree",!0);u(p,v,_,"\xA3","\\pounds");u(p,v,_,"\xA3","\\mathsterling",!0);u(H,v,_,"\xA3","\\pounds");u(H,v,_,"\xA3","\\textsterling",!0);u(p,N,_,"\u2720","\\maltese");u(H,N,_,"\u2720","\\maltese");e4='0123456789/@."';for(yh=0;yh0)return Vi(s,h,n,t,a.concat(d));if(l){var c,f;if(l==="boldsymbol"){var m=cA(s,n,t,a,r);c=m.fontName,f=[m.fontClass]}else o?(c=D4[l].fontName,f=[l]):(c=Th(l,t.fontWeight,t.fontShape),f=[l,t.fontWeight,t.fontShape]);if(Fh(s,c,n).metrics)return Vi(s,c,n,t,a.concat(f));if(I4.hasOwnProperty(s)&&c.slice(0,10)==="Typewriter"){for(var g=[],x=0;x{if(xn(i.classes)!==xn(e.classes)||i.skew!==e.skew||i.maxFontSize!==e.maxFontSize)return!1;if(i.classes.length===1){var t=i.classes[0];if(t==="mbin"||t==="mord")return!1}for(var r in i.style)if(i.style.hasOwnProperty(r)&&i.style[r]!==e.style[r])return!1;for(var n in e.style)if(e.style.hasOwnProperty(n)&&i.style[n]!==e.style[n])return!1;return!0},mA=i=>{for(var e=0;et&&(t=a.height),a.depth>r&&(r=a.depth),a.maxFontSize>n&&(n=a.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},ei=function(e,t,r,n){var s=new ps(e,t,r,n);return D1(s),s},z4=(i,e,t,r)=>new ps(i,e,t,r),pA=function(e,t,r){var n=ei([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=V(n.height),n.maxFontSize=1,n},gA=function(e,t,r,n){var s=new al(e,t,r,n);return D1(s),s},R4=function(e){var t=new ms(e);return D1(t),t},xA=function(e,t){return e instanceof ms?ei([],[e],t):e},yA=function(e){if(e.positionType==="individualShift"){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,s=n,a=1;a{var t=ei(["mspace"],[],e),r=Ke(i,e);return t.style.marginRight=V(r),t},Th=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}var s;return t==="textbf"&&r==="textit"?s="BoldItalic":t==="textbf"?s="Bold":t==="textit"?s="Italic":s="Regular",n+"-"+s},D4={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathsfit:{variant:"sans-serif-italic",fontName:"SansSerif-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},O4={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},wA=function(e,t){var[r,n,s]=O4[e],a=new hr(r),o=new Yi([a],{width:V(n),height:V(s),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+1e3*s,preserveAspectRatio:"xMinYMin"}),l=z4(["overlay"],[o],t);return l.height=s,l.style.height=V(s),l.style.width=V(n),l},z={fontMap:D4,makeSymbol:Vi,mathsym:dA,makeSpan:ei,makeSvgSpan:z4,makeLineSpan:pA,makeAnchor:gA,makeFragment:R4,wrapFragment:xA,makeVList:vA,makeOrd:uA,makeGlue:bA,staticSvg:wA,svgData:O4,tryCombineChars:mA},Xe={number:3,unit:"mu"},fs={number:4,unit:"mu"},_r={number:5,unit:"mu"},MA={mord:{mop:Xe,mbin:fs,mrel:_r,minner:Xe},mop:{mord:Xe,mop:Xe,mrel:_r,minner:Xe},mbin:{mord:fs,mop:fs,mopen:fs,minner:fs},mrel:{mord:_r,mop:_r,mopen:_r,minner:_r},mopen:{},mclose:{mop:Xe,mbin:fs,mrel:_r,minner:Xe},mpunct:{mord:Xe,mop:Xe,mrel:_r,mopen:Xe,mclose:Xe,mpunct:Xe,minner:Xe},minner:{mord:Xe,mop:Xe,mbin:fs,mrel:_r,mopen:Xe,mpunct:Xe,minner:Xe}},TA={mord:{mop:Xe},mop:{mord:Xe,mop:Xe},mbin:{},mrel:{},mopen:{},mclose:{mop:Xe},mpunct:{},minner:{mop:Xe}},B4={},zh={},Rh={};Dh=function(e){return e.type==="ordgroup"&&e.body.length===1?e.body[0]:e},rt=function(e){return e.type==="ordgroup"?e.body:[e]},zr=z.makeSpan,NA=["leftmost","mbin","mopen","mrel","mop","mpunct"],EA=["rightmost","mrel","mclose","mpunct"],SA={display:ae.DISPLAY,text:ae.TEXT,script:ae.SCRIPT,scriptscript:ae.SCRIPTSCRIPT},AA={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},mt=function(e,t,r,n){n===void 0&&(n=[null,null]);for(var s=[],a=0;a{var y=x.classes[0],b=g.classes[0];y==="mbin"&&EA.includes(b)?x.classes[0]="mord":b==="mbin"&&NA.includes(y)&&(g.classes[0]="mord")},{node:c},f,m),r4(s,(g,x)=>{var y=E1(x),b=E1(g),E=y&&b?g.hasClass("mtight")?TA[y][b]:MA[y][b]:null;if(E)return z.makeGlue(E,h)},{node:c},f,m),s},r4=function i(e,t,r,n,s){n&&e.push(n);for(var a=0;af=>{e.splice(c+1,0,f),a++})(a)}n&&e.pop()},P4=function(e){return e instanceof ms||e instanceof al||e instanceof ps&&e.hasClass("enclosing")?e:null},kA=function i(e,t){var r=P4(e);if(r){var n=r.children;if(n.length){if(t==="right")return i(n[n.length-1],"right");if(t==="left")return i(n[0],"left")}}return e},E1=function(e,t){return e?(t&&(e=kA(e,t)),AA[e.classes[0]]||null):null},ll=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return zr(t.concat(r))},Te=function(e,t,r){if(!e)return zr();if(zh[e.type]){var n=zh[e.type](e,t);if(r&&t.size!==r.size){n=zr(t.sizingClasses(r),[n],t);var s=t.sizeMultiplier/r.sizeMultiplier;n.height*=s,n.depth*=s}return n}else throw new G("Got group of unknown type: '"+e.type+"'")};Bt=class{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=xn(this.classes));for(var r=0;r0&&(e+=' class ="'+Ee.escape(xn(this.classes))+'"'),e+=">";for(var r=0;r",e}toText(){return this.children.map(e=>e.toText()).join("")}},Ci=class{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return Ee.escape(this.toText())}toText(){return this.text}},A1=class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character="\u200A":e>=.1666&&e<=.1667?this.character="\u2009":e>=.2222&&e<=.2223?this.character="\u2005":e>=.2777&&e<=.2778?this.character="\u2005\u200A":e>=-.05556&&e<=-.05555?this.character="\u200A\u2063":e>=-.1667&&e<=-.1666?this.character="\u2009\u2063":e>=-.2223&&e<=-.2222?this.character="\u205F\u2063":e>=-.2778&&e<=-.2777?this.character="\u2005\u2063":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",V(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},$={MathNode:Bt,TextNode:Ci,SpaceNode:A1,newDocumentFragment:F4},_i=function(e,t,r){return Be[t][e]&&Be[t][e].replace&&e.charCodeAt(0)!==55349&&!(I4.hasOwnProperty(e)&&r&&(r.fontFamily&&r.fontFamily.slice(4,6)==="tt"||r.font&&r.font.slice(4,6)==="tt"))&&(e=Be[t][e].replace),new $.TextNode(e)},O1=function(e){return e.length===1?e[0]:new $.MathNode("mrow",e)},B1=function(e,t){if(t.fontFamily==="texttt")return"monospace";if(t.fontFamily==="textsf")return t.fontShape==="textit"&&t.fontWeight==="textbf"?"sans-serif-bold-italic":t.fontShape==="textit"?"sans-serif-italic":t.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(t.fontShape==="textit"&&t.fontWeight==="textbf")return"bold-italic";if(t.fontShape==="textit")return"italic";if(t.fontWeight==="textbf")return"bold";var r=t.font;if(!r||r==="mathnormal")return null;var n=e.mode;if(r==="mathit")return"italic";if(r==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(r==="mathbf")return"bold";if(r==="mathbb")return"double-struck";if(r==="mathsfit")return"sans-serif-italic";if(r==="mathfrak")return"fraktur";if(r==="mathscr"||r==="mathcal")return"script";if(r==="mathsf")return"sans-serif";if(r==="mathtt")return"monospace";var s=e.text;if(["\\imath","\\jmath"].includes(s))return null;Be[n][s]&&Be[n][s].replace&&(s=Be[n][s].replace);var a=z.fontMap[r].fontName;return R1(s,a,n)?z.fontMap[r].variant:null};ri=function(e,t,r){if(e.length===1){var n=Re(e[0],t);return r&&n instanceof Bt&&n.type==="mo"&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var s=[],a,o=0;o=1&&(a.type==="mn"||c1(a))){var h=l.children[0];h instanceof Bt&&h.type==="mn"&&(h.children=[...a.children,...h.children],s.pop())}else if(a.type==="mi"&&a.children.length===1){var d=a.children[0];if(d instanceof Ci&&d.text==="\u0338"&&(l.type==="mo"||l.type==="mi"||l.type==="mn")){var c=l.children[0];c instanceof Ci&&c.text.length>0&&(c.text=c.text.slice(0,1)+"\u0338"+c.text.slice(1),s.pop())}}}s.push(l),a=l}return s},yn=function(e,t,r){return O1(ri(e,t,r))},Re=function(e,t){if(!e)return new $.MathNode("mrow");if(Rh[e.type]){var r=Rh[e.type](e,t);return r}else throw new G("Got group of unknown type: '"+e.type+"'")};q4=function(e){return new Lh({style:e.displayMode?ae.DISPLAY:ae.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},H4=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=z.makeSpan(r,[e])}return e},CA=function(e,t,r){var n=q4(r),s;if(r.output==="mathml")return n4(e,t,n,r.displayMode,!0);if(r.output==="html"){var a=S1(e,n);s=z.makeSpan(["katex"],[a])}else{var o=n4(e,t,n,r.displayMode,!1),l=S1(e,n);s=z.makeSpan(["katex"],[o,l])}return H4(s,r)},_A=function(e,t,r){var n=q4(r),s=S1(e,n),a=z.makeSpan(["katex"],[s]);return H4(a,r)},LA={widehat:"^",widecheck:"\u02C7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23DF",overbrace:"\u23DE",overgroup:"\u23E0",undergroup:"\u23E1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21D2",xRightarrow:"\u21D2",overleftharpoon:"\u21BC",xleftharpoonup:"\u21BC",overrightharpoon:"\u21C0",xrightharpoonup:"\u21C0",xLeftarrow:"\u21D0",xLeftrightarrow:"\u21D4",xhookleftarrow:"\u21A9",xhookrightarrow:"\u21AA",xmapsto:"\u21A6",xrightharpoondown:"\u21C1",xleftharpoondown:"\u21BD",xrightleftharpoons:"\u21CC",xleftrightharpoons:"\u21CB",xtwoheadleftarrow:"\u219E",xtwoheadrightarrow:"\u21A0",xlongequal:"=",xtofrom:"\u21C4",xrightleftarrows:"\u21C4",xrightequilibrium:"\u21CC",xleftequilibrium:"\u21CB","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},IA=function(e){var t=new $.MathNode("mo",[new $.TextNode(LA[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},zA={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},RA=function(e){return e.type==="ordgroup"?e.body.length:1},DA=function(e,t){function r(){var o=4e5,l=e.label.slice(1);if(["widehat","widecheck","widetilde","utilde"].includes(l)){var h=e,d=RA(h.base),c,f,m;if(d>5)l==="widehat"||l==="widecheck"?(c=420,o=2364,m=.42,f=l+"4"):(c=312,o=2340,m=.34,f="tilde4");else{var g=[1,1,2,2,3,3][d];l==="widehat"||l==="widecheck"?(o=[0,1062,2364,2364,2364][g],c=[0,239,300,360,420][g],m=[0,.24,.3,.3,.36,.42][g],f=l+g):(o=[0,600,1033,2339,2340][g],c=[0,260,286,306,312][g],m=[0,.26,.286,.3,.306,.34][g],f="tilde"+g)}var x=new hr(f),y=new Yi([x],{width:"100%",height:V(m),viewBox:"0 0 "+o+" "+c,preserveAspectRatio:"none"});return{span:z.makeSvgSpan([],[y],t),minWidth:0,height:m}}else{var b=[],E=zA[l],[k,L,I]=E,O=I/1e3,q=k.length,F,W;if(q===1){var ne=E[3];F=["hide-tail"],W=[ne]}else if(q===2)F=["halfarrow-left","halfarrow-right"],W=["xMinYMin","xMaxYMin"];else if(q===3)F=["brace-left","brace-center","brace-right"],W=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support + `+q+" children.");for(var re=0;re0&&(n.style.minWidth=V(s)),n},OA=function(e,t,r,n,s){var a,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(a=z.makeSpan(["stretchy",t],[],s),t==="fbox"){var l=s.color&&s.getColor();l&&(a.style.borderColor=l)}}else{var h=[];/^[bx]cancel$/.test(t)&&h.push(new ol({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&h.push(new ol({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var d=new Yi(h,{width:"100%",height:V(o)});a=z.makeSvgSpan([],[d],s)}return a.height=o,a.style.height=V(o),a},Rr={encloseSpan:OA,mathMLnode:IA,svgSpan:DA};F1=(i,e)=>{var t,r,n;i&&i.type==="supsub"?(r=me(i.base,"accent"),t=r.base,i.base=t,n=aA(Te(i,e)),i.base=r):(r=me(i,"accent"),t=r.base);var s=Te(t,e.havingCrampedStyle()),a=r.isShifty&&Ee.isCharacterBox(t),o=0;if(a){var l=Ee.getBaseElem(t),h=Te(l,e.havingCrampedStyle());o=J6(h).skew}var d=r.label==="\\c",c=d?s.height+s.depth:Math.min(s.height,e.fontMetrics().xHeight),f;if(r.isStretchy)f=Rr.svgSpan(r,e),f=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"elem",elem:f,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+V(2*o)+")",marginLeft:V(2*o)}:void 0}]},e);else{var m,g;r.label==="\\vec"?(m=z.staticSvg("vec",e),g=z.svgData.vec[1]):(m=z.makeOrd({mode:r.mode,text:r.label},e,"textord"),m=J6(m),m.italic=0,g=m.width,d&&(c+=m.depth)),f=z.makeSpan(["accent-body"],[m]);var x=r.label==="\\textcircled";x&&(f.classes.push("accent-full"),c=s.height);var y=o;x||(y-=g/2),f.style.left=V(y),r.label==="\\textcircled"&&(f.style.top=".2em"),f=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:-c},{type:"elem",elem:f}]},e)}var b=z.makeSpan(["mord","accent"],[f],e);return n?(n.children[0]=b,n.height=Math.max(b.height,n.height),n.classes[0]="mord",n):b},U4=(i,e)=>{var t=i.isStretchy?Rr.mathMLnode(i.label):new $.MathNode("mo",[_i(i.label,i.mode)]),r=new $.MathNode("mover",[Re(i.base,e),t]);return r.setAttribute("accent","true"),r},BA=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(i=>"\\"+i).join("|"));Z({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(i,e)=>{var t=Dh(e[0]),r=!BA.test(i.funcName),n=!r||i.funcName==="\\widehat"||i.funcName==="\\widetilde"||i.funcName==="\\widecheck";return{type:"accent",mode:i.parser.mode,label:i.funcName,isStretchy:r,isShifty:n,base:t}},htmlBuilder:F1,mathmlBuilder:U4});Z({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(i,e)=>{var t=e[0],r=i.parser.mode;return r==="math"&&(i.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+i.funcName+" works only in text mode"),r="text"),{type:"accent",mode:r,label:i.funcName,isStretchy:!1,isShifty:!0,base:t}},htmlBuilder:F1,mathmlBuilder:U4});Z({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"accentUnder",mode:t.mode,label:r,base:n}},htmlBuilder:(i,e)=>{var t=Te(i.base,e),r=Rr.svgSpan(i,e),n=i.label==="\\utilde"?.12:0,s=z.makeVList({positionType:"top",positionData:t.height,children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:t}]},e);return z.makeSpan(["mord","accentunder"],[s],e)},mathmlBuilder:(i,e)=>{var t=Rr.mathMLnode(i.label),r=new $.MathNode("munder",[Re(i.base,e),t]);return r.setAttribute("accentunder","true"),r}});Eh=i=>{var e=new $.MathNode("mpadded",i?[i]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e};Z({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(i,e,t){var{parser:r,funcName:n}=i;return{type:"xArrow",mode:r.mode,label:n,body:e[0],below:t[0]}},htmlBuilder(i,e){var t=e.style,r=e.havingStyle(t.sup()),n=z.wrapFragment(Te(i.body,r,e),e),s=i.label.slice(0,2)==="\\x"?"x":"cd";n.classes.push(s+"-arrow-pad");var a;i.below&&(r=e.havingStyle(t.sub()),a=z.wrapFragment(Te(i.below,r,e),e),a.classes.push(s+"-arrow-pad"));var o=Rr.svgSpan(i,e),l=-e.fontMetrics().axisHeight+.5*o.height,h=-e.fontMetrics().axisHeight-.5*o.height-.111;(n.depth>.25||i.label==="\\xleftequilibrium")&&(h-=n.depth);var d;if(a){var c=-e.fontMetrics().axisHeight+a.height+.5*o.height+.111;d=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:h},{type:"elem",elem:o,shift:l},{type:"elem",elem:a,shift:c}]},e)}else d=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:h},{type:"elem",elem:o,shift:l}]},e);return d.children[0].children[0].children[1].classes.push("svg-align"),z.makeSpan(["mrel","x-arrow"],[d],e)},mathmlBuilder(i,e){var t=Rr.mathMLnode(i.label);t.setAttribute("minsize",i.label.charAt(0)==="x"?"1.75em":"3.0em");var r;if(i.body){var n=Eh(Re(i.body,e));if(i.below){var s=Eh(Re(i.below,e));r=new $.MathNode("munderover",[t,s,n])}else r=new $.MathNode("mover",[t,n])}else if(i.below){var a=Eh(Re(i.below,e));r=new $.MathNode("munder",[t,a])}else r=Eh(),r=new $.MathNode("mover",[t,r]);return r}});PA=z.makeSpan;Z({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"mclass",mode:t.mode,mclass:"m"+r.slice(5),body:rt(n),isCharacterBox:Ee.isCharacterBox(n)}},htmlBuilder:$4,mathmlBuilder:j4});Hh=i=>{var e=i.type==="ordgroup"&&i.body.length?i.body[0]:i;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"};Z({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(i,e){var{parser:t}=i;return{type:"mclass",mode:t.mode,mclass:Hh(e[0]),body:rt(e[1]),isCharacterBox:Ee.isCharacterBox(e[1])}}});Z({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(i,e){var{parser:t,funcName:r}=i,n=e[1],s=e[0],a;r!=="\\stackrel"?a=Hh(n):a="mrel";var o={type:"op",mode:n.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:r!=="\\stackrel",body:rt(n)},l={type:"supsub",mode:s.mode,base:o,sup:r==="\\underset"?null:s,sub:r==="\\underset"?s:null};return{type:"mclass",mode:t.mode,mclass:a,body:[l],isCharacterBox:Ee.isCharacterBox(l)}},htmlBuilder:$4,mathmlBuilder:j4});Z({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"pmb",mode:t.mode,mclass:Hh(e[0]),body:rt(e[0])}},htmlBuilder(i,e){var t=mt(i.body,e,!0),r=z.makeSpan([i.mclass],t,e);return r.style.textShadow="0.02em 0.01em 0.04px",r},mathmlBuilder(i,e){var t=ri(i.body,e),r=new $.MathNode("mstyle",t);return r.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),r}});FA={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},s4=()=>({type:"styling",body:[],mode:"math",style:"display"}),a4=i=>i.type==="textord"&&i.text==="@",qA=(i,e)=>(i.type==="mathord"||i.type==="atom")&&i.text===e;Z({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i;return{type:"cdlabel",mode:t.mode,side:r.slice(4),label:e[0]}},htmlBuilder(i,e){var t=e.havingStyle(e.style.sup()),r=z.wrapFragment(Te(i.label,t,e),e);return r.classes.push("cd-label-"+i.side),r.style.bottom=V(.8-r.depth),r.height=0,r.depth=0,r},mathmlBuilder(i,e){var t=new $.MathNode("mrow",[Re(i.label,e)]);return t=new $.MathNode("mpadded",[t]),t.setAttribute("width","0"),i.side==="left"&&t.setAttribute("lspace","-1width"),t.setAttribute("voffset","0.7em"),t=new $.MathNode("mstyle",[t]),t.setAttribute("displaystyle","false"),t.setAttribute("scriptlevel","1"),t}});Z({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(i,e){var{parser:t}=i;return{type:"cdlabelparent",mode:t.mode,fragment:e[0]}},htmlBuilder(i,e){var t=z.wrapFragment(Te(i.fragment,e),e);return t.classes.push("cd-vert-arrow"),t},mathmlBuilder(i,e){return new $.MathNode("mrow",[Re(i.fragment,e)])}});Z({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(i,e){for(var{parser:t}=i,r=me(e[0],"ordgroup"),n=r.body,s="",a=0;a=1114111)throw new G("\\@char with invalid code point "+s);return l<=65535?h=String.fromCharCode(l):(l-=65536,h=String.fromCharCode((l>>10)+55296,(l&1023)+56320)),{type:"textord",mode:t.mode,text:h}}});G4=(i,e)=>{var t=mt(i.body,e.withColor(i.color),!1);return z.makeFragment(t)},W4=(i,e)=>{var t=ri(i.body,e.withColor(i.color)),r=new $.MathNode("mstyle",t);return r.setAttribute("mathcolor",i.color),r};Z({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(i,e){var{parser:t}=i,r=me(e[0],"color-token").color,n=e[1];return{type:"color",mode:t.mode,color:r,body:rt(n)}},htmlBuilder:G4,mathmlBuilder:W4});Z({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(i,e){var{parser:t,breakOnTokenText:r}=i,n=me(e[0],"color-token").color;t.gullet.macros.set("\\current@color",n);var s=t.parseExpression(!0,r);return{type:"color",mode:t.mode,color:n,body:s}},htmlBuilder:G4,mathmlBuilder:W4});Z({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(i,e,t){var{parser:r}=i,n=r.gullet.future().text==="["?r.parseSizeGroup(!0):null,s=!r.settings.displayMode||!r.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:r.mode,newLine:s,size:n&&me(n,"size").value}},htmlBuilder(i,e){var t=z.makeSpan(["mspace"],[],e);return i.newLine&&(t.classes.push("newline"),i.size&&(t.style.marginTop=V(Ke(i.size,e)))),t},mathmlBuilder(i,e){var t=new $.MathNode("mspace");return i.newLine&&(t.setAttribute("linebreak","newline"),i.size&&t.setAttribute("height",V(Ke(i.size,e)))),t}});k1={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},V4=i=>{var e=i.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new G("Expected a control sequence",i);return e},$A=i=>{var e=i.gullet.popToken();return e.text==="="&&(e=i.gullet.popToken(),e.text===" "&&(e=i.gullet.popToken())),e},Y4=(i,e,t,r)=>{var n=i.gullet.macros.get(t.text);n==null&&(t.noexpand=!0,n={tokens:[t],numArgs:0,unexpandable:!i.gullet.isExpandable(t.text)}),i.gullet.macros.set(e,n,r)};Z({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(i){var{parser:e,funcName:t}=i;e.consumeSpaces();var r=e.fetch();if(k1[r.text])return(t==="\\global"||t==="\\\\globallong")&&(r.text=k1[r.text]),me(e.parseFunction(),"internal");throw new G("Invalid token after macro prefix",r)}});Z({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=e.gullet.popToken(),n=r.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new G("Expected a control sequence",r);for(var s=0,a,o=[[]];e.gullet.future().text!=="{";)if(r=e.gullet.popToken(),r.text==="#"){if(e.gullet.future().text==="{"){a=e.gullet.future(),o[s].push("{");break}if(r=e.gullet.popToken(),!/^[1-9]$/.test(r.text))throw new G('Invalid argument number "'+r.text+'"');if(parseInt(r.text)!==s+1)throw new G('Argument number "'+r.text+'" out of order');s++,o.push([])}else{if(r.text==="EOF")throw new G("Expected a macro definition");o[s].push(r.text)}var{tokens:l}=e.gullet.consumeArg();return a&&l.unshift(a),(t==="\\edef"||t==="\\xdef")&&(l=e.gullet.expandTokens(l),l.reverse()),e.gullet.macros.set(n,{tokens:l,numArgs:s,delimiters:o},t===k1[t]),{type:"internal",mode:e.mode}}});Z({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=V4(e.gullet.popToken());e.gullet.consumeSpaces();var n=$A(e);return Y4(e,r,n,t==="\\\\globallet"),{type:"internal",mode:e.mode}}});Z({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i){var{parser:e,funcName:t}=i,r=V4(e.gullet.popToken()),n=e.gullet.popToken(),s=e.gullet.popToken();return Y4(e,r,s,t==="\\\\globalfuture"),e.gullet.pushToken(s),e.gullet.pushToken(n),{type:"internal",mode:e.mode}}});il=function(e,t,r){var n=Be.math[e]&&Be.math[e].replace,s=R1(n||e,t,r);if(!s)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return s},q1=function(e,t,r,n){var s=r.havingBaseStyle(t),a=z.makeSpan(n.concat(s.sizingClasses(r)),[e],r),o=s.sizeMultiplier/r.sizeMultiplier;return a.height*=o,a.depth*=o,a.maxFontSize=s.sizeMultiplier,a},X4=function(e,t,r){var n=t.havingBaseStyle(r),s=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=V(s),e.height-=s,e.depth+=s},jA=function(e,t,r,n,s,a){var o=z.makeSymbol(e,"Main-Regular",s,n),l=q1(o,t,n,a);return r&&X4(l,n,t),l},GA=function(e,t,r,n){return z.makeSymbol(e,"Size"+t+"-Regular",r,n)},K4=function(e,t,r,n,s,a){var o=GA(e,t,s,n),l=q1(z.makeSpan(["delimsizing","size"+t],[o],n),ae.TEXT,n,a);return r&&X4(l,n,ae.TEXT),l},u1=function(e,t,r){var n;t==="Size1-Regular"?n="delim-size1":n="delim-size4";var s=z.makeSpan(["delimsizinginner",n],[z.makeSpan([],[z.makeSymbol(e,t,r)])]);return{type:"elem",elem:s}},f1=function(e,t,r){var n=lr["Size4-Regular"][e.charCodeAt(0)]?lr["Size4-Regular"][e.charCodeAt(0)][4]:lr["Size1-Regular"][e.charCodeAt(0)][4],s=new hr("inner",QS(e,Math.round(1e3*t))),a=new Yi([s],{width:V(n),height:V(t),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=z.makeSvgSpan([],[a],r);return o.height=t,o.style.height=V(t),o.style.width=V(n),{type:"elem",elem:o}},C1=.008,Sh={type:"kern",size:-1*C1},WA=["|","\\lvert","\\rvert","\\vert"],VA=["\\|","\\lVert","\\rVert","\\Vert"],Z4=function(e,t,r,n,s,a){var o,l,h,d,c="",f=0;o=h=d=e,l=null;var m="Size1-Regular";e==="\\uparrow"?h=d="\u23D0":e==="\\Uparrow"?h=d="\u2016":e==="\\downarrow"?o=h="\u23D0":e==="\\Downarrow"?o=h="\u2016":e==="\\updownarrow"?(o="\\uparrow",h="\u23D0",d="\\downarrow"):e==="\\Updownarrow"?(o="\\Uparrow",h="\u2016",d="\\Downarrow"):WA.includes(e)?(h="\u2223",c="vert",f=333):VA.includes(e)?(h="\u2225",c="doublevert",f=556):e==="["||e==="\\lbrack"?(o="\u23A1",h="\u23A2",d="\u23A3",m="Size4-Regular",c="lbrack",f=667):e==="]"||e==="\\rbrack"?(o="\u23A4",h="\u23A5",d="\u23A6",m="Size4-Regular",c="rbrack",f=667):e==="\\lfloor"||e==="\u230A"?(h=o="\u23A2",d="\u23A3",m="Size4-Regular",c="lfloor",f=667):e==="\\lceil"||e==="\u2308"?(o="\u23A1",h=d="\u23A2",m="Size4-Regular",c="lceil",f=667):e==="\\rfloor"||e==="\u230B"?(h=o="\u23A5",d="\u23A6",m="Size4-Regular",c="rfloor",f=667):e==="\\rceil"||e==="\u2309"?(o="\u23A4",h=d="\u23A5",m="Size4-Regular",c="rceil",f=667):e==="("||e==="\\lparen"?(o="\u239B",h="\u239C",d="\u239D",m="Size4-Regular",c="lparen",f=875):e===")"||e==="\\rparen"?(o="\u239E",h="\u239F",d="\u23A0",m="Size4-Regular",c="rparen",f=875):e==="\\{"||e==="\\lbrace"?(o="\u23A7",l="\u23A8",d="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(o="\u23AB",l="\u23AC",d="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lgroup"||e==="\u27EE"?(o="\u23A7",d="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\rgroup"||e==="\u27EF"?(o="\u23AB",d="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lmoustache"||e==="\u23B0"?(o="\u23A7",d="\u23AD",h="\u23AA",m="Size4-Regular"):(e==="\\rmoustache"||e==="\u23B1")&&(o="\u23AB",d="\u23A9",h="\u23AA",m="Size4-Regular");var g=il(o,m,s),x=g.height+g.depth,y=il(h,m,s),b=y.height+y.depth,E=il(d,m,s),k=E.height+E.depth,L=0,I=1;if(l!==null){var O=il(l,m,s);L=O.height+O.depth,I=2}var q=x+k+L,F=Math.max(0,Math.ceil((t-q)/(I*b))),W=q+F*I*b,ne=n.fontMetrics().axisHeight;r&&(ne*=n.sizeMultiplier);var re=W/2-ne,le=[];if(c.length>0){var Ce=W-x-k,te=Math.round(W*1e3),Q=JS(c,Math.round(Ce*1e3)),oe=new hr(c,Q),he=(f/1e3).toFixed(3)+"em",ui=(te/1e3).toFixed(3)+"em",Mi=new Yi([oe],{width:he,height:ui,viewBox:"0 0 "+f+" "+te}),ut=z.makeSvgSpan([],[Mi],n);ut.height=te/1e3,ut.style.width=he,ut.style.height=ui,le.push({type:"elem",elem:ut})}else{if(le.push(u1(d,m,s)),le.push(Sh),l===null){var at=W-x-k+2*C1;le.push(f1(h,at,n))}else{var ot=(W-x-k-L)/2+2*C1;le.push(f1(h,ot,n)),le.push(Sh),le.push(u1(l,m,s)),le.push(Sh),le.push(f1(h,ot,n))}le.push(Sh),le.push(u1(o,m,s))}var nn=n.havingBaseStyle(ae.TEXT),Bs=z.makeVList({positionType:"bottom",positionData:re,children:le},nn);return q1(z.makeSpan(["delimsizing","mult"],[Bs],nn),ae.TEXT,n,a)},m1=80,p1=.08,g1=function(e,t,r,n,s){var a=ZS(e,n,r),o=new hr(e,a),l=new Yi([o],{width:"400em",height:V(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return z.makeSvgSpan(["hide-tail"],[l],s)},YA=function(e,t){var r=t.havingBaseSizing(),n=tg("\\surd",e*r.sizeMultiplier,eg,r),s=r.sizeMultiplier,a=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),o,l=0,h=0,d=0,c;return n.type==="small"?(d=1e3+1e3*a+m1,e<1?s=1:e<1.4&&(s=.7),l=(1+a+p1)/s,h=(1+a)/s,o=g1("sqrtMain",l,d,a,t),o.style.minWidth="0.853em",c=.833/s):n.type==="large"?(d=(1e3+m1)*rl[n.size],h=(rl[n.size]+a)/s,l=(rl[n.size]+a+p1)/s,o=g1("sqrtSize"+n.size,l,d,a,t),o.style.minWidth="1.02em",c=1/s):(l=e+a+p1,h=e+a,d=Math.floor(1e3*e+a)+m1,o=g1("sqrtTall",l,d,a,t),o.style.minWidth="0.742em",c=1.056),o.height=h,o.style.height=V(l),{span:o,advanceWidth:c,ruleWidth:(t.fontMetrics().sqrtRuleThickness+a)*s}},Q4=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","\\surd"],XA=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1"],J4=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],rl=[0,1.2,1.8,2.4,3],KA=function(e,t,r,n,s){if(e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle"),Q4.includes(e)||J4.includes(e))return K4(e,t,!1,r,n,s);if(XA.includes(e))return Z4(e,rl[t],!1,r,n,s);throw new G("Illegal delimiter: '"+e+"'")},ZA=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],QA=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"stack"}],eg=[{type:"small",style:ae.SCRIPTSCRIPT},{type:"small",style:ae.SCRIPT},{type:"small",style:ae.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],JA=function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},tg=function(e,t,r,n){for(var s=Math.min(2,3-n.style.size),a=s;at)return r[a]}return r[r.length-1]},ig=function(e,t,r,n,s,a){e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle");var o;J4.includes(e)?o=ZA:Q4.includes(e)?o=eg:o=QA;var l=tg(e,t,o,n);return l.type==="small"?jA(e,l.style,r,n,s,a):l.type==="large"?K4(e,l.size,r,n,s,a):Z4(e,t,r,n,s,a)},ek=function(e,t,r,n,s,a){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,l=901,h=5/n.fontMetrics().ptPerEm,d=Math.max(t-o,r+o),c=Math.max(d/500*l,2*d-h);return ig(e,c,!0,n,s,a)},Ir={sqrtImage:YA,sizedDelim:KA,sizeToMaxHeight:rl,customSizedDelim:ig,leftRightDelim:ek},o4={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},tk=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27E8","\\rangle","\u27E9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];Z({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(i,e)=>{var t=Uh(e[0],i);return{type:"delimsizing",mode:i.parser.mode,size:o4[i.funcName].size,mclass:o4[i.funcName].mclass,delim:t.text}},htmlBuilder:(i,e)=>i.delim==="."?z.makeSpan([i.mclass]):Ir.sizedDelim(i.delim,i.size,e,i.mode,[i.mclass]),mathmlBuilder:i=>{var e=[];i.delim!=="."&&e.push(_i(i.delim,i.mode));var t=new $.MathNode("mo",e);i.mclass==="mopen"||i.mclass==="mclose"?t.setAttribute("fence","true"):t.setAttribute("fence","false"),t.setAttribute("stretchy","true");var r=V(Ir.sizeToMaxHeight[i.size]);return t.setAttribute("minsize",r),t.setAttribute("maxsize",r),t}});Z({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=i.parser.gullet.macros.get("\\current@color");if(t&&typeof t!="string")throw new G("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:i.parser.mode,delim:Uh(e[0],i).text,color:t}}});Z({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=Uh(e[0],i),r=i.parser;++r.leftrightDepth;var n=r.parseExpression(!1);--r.leftrightDepth,r.expect("\\right",!1);var s=me(r.parseFunction(),"leftright-right");return{type:"leftright",mode:r.mode,body:n,left:t.text,right:s.delim,rightColor:s.color}},htmlBuilder:(i,e)=>{l4(i);for(var t=mt(i.body,e,!0,["mopen","mclose"]),r=0,n=0,s=!1,a=0;a{l4(i);var t=ri(i.body,e);if(i.left!=="."){var r=new $.MathNode("mo",[_i(i.left,i.mode)]);r.setAttribute("fence","true"),t.unshift(r)}if(i.right!=="."){var n=new $.MathNode("mo",[_i(i.right,i.mode)]);n.setAttribute("fence","true"),i.rightColor&&n.setAttribute("mathcolor",i.rightColor),t.push(n)}return O1(t)}});Z({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var t=Uh(e[0],i);if(!i.parser.leftrightDepth)throw new G("\\middle without preceding \\left",t);return{type:"middle",mode:i.parser.mode,delim:t.text}},htmlBuilder:(i,e)=>{var t;if(i.delim===".")t=ll(e,[]);else{t=Ir.sizedDelim(i.delim,1,e,i.mode,[]);var r={delim:i.delim,options:e};t.isMiddle=r}return t},mathmlBuilder:(i,e)=>{var t=i.delim==="\\vert"||i.delim==="|"?_i("|","text"):_i(i.delim,i.mode),r=new $.MathNode("mo",[t]);return r.setAttribute("fence","true"),r.setAttribute("lspace","0.05em"),r.setAttribute("rspace","0.05em"),r}});H1=(i,e)=>{var t=z.wrapFragment(Te(i.body,e),e),r=i.label.slice(1),n=e.sizeMultiplier,s,a=0,o=Ee.isCharacterBox(i.body);if(r==="sout")s=z.makeSpan(["stretchy","sout"]),s.height=e.fontMetrics().defaultRuleThickness/n,a=-.5*e.fontMetrics().xHeight;else if(r==="phase"){var l=Ke({number:.6,unit:"pt"},e),h=Ke({number:.35,unit:"ex"},e),d=e.havingBaseSizing();n=n/d.sizeMultiplier;var c=t.height+t.depth+l+h;t.style.paddingLeft=V(c/2+l);var f=Math.floor(1e3*c*n),m=XS(f),g=new Yi([new hr("phase",m)],{width:"400em",height:V(f/1e3),viewBox:"0 0 400000 "+f,preserveAspectRatio:"xMinYMin slice"});s=z.makeSvgSpan(["hide-tail"],[g],e),s.style.height=V(c),a=t.depth+l+h}else{/cancel/.test(r)?o||t.classes.push("cancel-pad"):r==="angl"?t.classes.push("anglpad"):t.classes.push("boxpad");var x=0,y=0,b=0;/box/.test(r)?(b=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),x=e.fontMetrics().fboxsep+(r==="colorbox"?0:b),y=x):r==="angl"?(b=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),x=4*b,y=Math.max(0,.25-t.depth)):(x=o?.2:0,y=x),s=Rr.encloseSpan(t,r,x,y,e),/fbox|boxed|fcolorbox/.test(r)?(s.style.borderStyle="solid",s.style.borderWidth=V(b)):r==="angl"&&b!==.049&&(s.style.borderTopWidth=V(b),s.style.borderRightWidth=V(b)),a=t.depth+y,i.backgroundColor&&(s.style.backgroundColor=i.backgroundColor,i.borderColor&&(s.style.borderColor=i.borderColor))}var E;if(i.backgroundColor)E=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:s,shift:a},{type:"elem",elem:t,shift:0}]},e);else{var k=/cancel|phase/.test(r)?["svg-align"]:[];E=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:t,shift:0},{type:"elem",elem:s,shift:a,wrapperClasses:k}]},e)}return/cancel/.test(r)&&(E.height=t.height,E.depth=t.depth),/cancel/.test(r)&&!o?z.makeSpan(["mord","cancel-lap"],[E],e):z.makeSpan(["mord"],[E],e)},U1=(i,e)=>{var t=0,r=new $.MathNode(i.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Re(i.body,e)]);switch(i.label){case"\\cancel":r.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":r.setAttribute("notation","downdiagonalstrike");break;case"\\phase":r.setAttribute("notation","phasorangle");break;case"\\sout":r.setAttribute("notation","horizontalstrike");break;case"\\fbox":r.setAttribute("notation","box");break;case"\\angl":r.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(t=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,r.setAttribute("width","+"+2*t+"pt"),r.setAttribute("height","+"+2*t+"pt"),r.setAttribute("lspace",t+"pt"),r.setAttribute("voffset",t+"pt"),i.label==="\\fcolorbox"){var n=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);r.setAttribute("style","border: "+n+"em solid "+String(i.borderColor))}break;case"\\xcancel":r.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return i.backgroundColor&&r.setAttribute("mathbackground",i.backgroundColor),r};Z({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(i,e,t){var{parser:r,funcName:n}=i,s=me(e[0],"color-token").color,a=e[1];return{type:"enclose",mode:r.mode,label:n,backgroundColor:s,body:a}},htmlBuilder:H1,mathmlBuilder:U1});Z({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(i,e,t){var{parser:r,funcName:n}=i,s=me(e[0],"color-token").color,a=me(e[1],"color-token").color,o=e[2];return{type:"enclose",mode:r.mode,label:n,backgroundColor:a,borderColor:s,body:o}},htmlBuilder:H1,mathmlBuilder:U1});Z({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"enclose",mode:t.mode,label:"\\fbox",body:e[0]}}});Z({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"enclose",mode:t.mode,label:r,body:n}},htmlBuilder:H1,mathmlBuilder:U1});Z({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(i,e){var{parser:t}=i;return{type:"enclose",mode:t.mode,label:"\\angl",body:e[0]}}});rg={};ng={};$h=i=>{var e=i.parser.settings;if(!e.displayMode)throw new G("{"+i.envName+"} can be used only in display mode.")};cr=function(e,t){var r,n,s=e.body.length,a=e.hLinesBeforeRow,o=0,l=new Array(s),h=[],d=Math.max(t.fontMetrics().arrayRuleWidth,t.minRuleThickness),c=1/t.fontMetrics().ptPerEm,f=5*c;if(e.colSeparationType&&e.colSeparationType==="small"){var m=t.havingStyle(ae.SCRIPT).sizeMultiplier;f=.2778*(m/t.sizeMultiplier)}var g=e.colSeparationType==="CD"?Ke({number:3,unit:"ex"},t):12*c,x=3*c,y=e.arraystretch*g,b=.7*y,E=.3*y,k=0;function L(D){for(var ft=0;ft0&&(k+=.25),h.push({pos:k,isDashed:D[ft]})}for(L(a[0]),r=0;r0&&(re+=E,qD))for(r=0;r=o)){var Hi=void 0;(n>0||e.hskipBeforeAndAfter)&&(Hi=Ee.deflt(ot.pregap,f),Hi!==0&&(Q=z.makeSpan(["arraycolsep"],[]),Q.style.width=V(Hi),te.push(Q)));var br=[];for(r=0;r0){for(var wr=z.makeLineSpan("hline",t,d),Ui=z.makeLineSpan("hdashline",t,d),Wt=[{type:"elem",elem:l,shift:0}];h.length>0;){var ge=h.pop(),ye=ge.pos-le;ge.isDashed?Wt.push({type:"elem",elem:Ui,shift:ye}):Wt.push({type:"elem",elem:wr,shift:ye})}l=z.makeVList({positionType:"individualShift",children:Wt},t)}if(he.length===0)return z.makeSpan(["mord"],[l],t);var Mr=z.makeVList({positionType:"individualShift",children:he},t);return Mr=z.makeSpan(["tag"],[Mr],t),z.makeFragment([l,Mr])},ik={c:"center ",l:"left ",r:"right "},ur=function(e,t){for(var r=[],n=new $.MathNode("mtd",[],["mtr-glue"]),s=new $.MathNode("mtd",[],["mml-eqn-num"]),a=0;a0){var g=e.cols,x="",y=!1,b=0,E=g.length;g[0].type==="separator"&&(f+="top ",b=1),g[g.length-1].type==="separator"&&(f+="bottom ",E-=1);for(var k=b;k0?"left ":"",f+=F[F.length-1].length>0?"right ":"";for(var W=1;W-1?"alignat":"align",s=e.envName==="split",a=vn(e.parser,{cols:r,addJot:!0,autoTag:s?void 0:$1(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:s?2:void 0,leqno:e.parser.settings.leqno},"display"),o,l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&t[0].type==="ordgroup"){for(var d="",c=0;c0&&m&&(y=1),r[g]={type:"align",align:x,pregap:y,postgap:0}}return a.colSeparationType=m?"align":"alignat",a};dr({type:"array",names:["array","darray"],props:{numArgs:1},handler(i,e){var t=qh(e[0]),r=t?[e[0]]:me(e[0],"ordgroup").body,n=r.map(function(a){var o=P1(a),l=o.text;if("lcr".indexOf(l)!==-1)return{type:"align",align:l};if(l==="|")return{type:"separator",separator:"|"};if(l===":")return{type:"separator",separator:":"};throw new G("Unknown column alignment: "+l,a)}),s={cols:n,hskipBeforeAndAfter:!0,maxNumCols:n.length};return vn(i.parser,s,j1(i.envName))},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(i){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[i.envName.replace("*","")],t="c",r={hskipBeforeAndAfter:!1,cols:[{type:"align",align:t}]};if(i.envName.charAt(i.envName.length-1)==="*"){var n=i.parser;if(n.consumeSpaces(),n.fetch().text==="["){if(n.consume(),n.consumeSpaces(),t=n.fetch().text,"lcr".indexOf(t)===-1)throw new G("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),r.cols=[{type:"align",align:t}]}}var s=vn(i.parser,r,j1(i.envName)),a=Math.max(0,...s.body.map(o=>o.length));return s.cols=new Array(a).fill({type:"align",align:t}),e?{type:"leftright",mode:i.mode,body:[s],left:e[0],right:e[1],rightColor:void 0}:s},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(i){var e={arraystretch:.5},t=vn(i.parser,e,"script");return t.colSeparationType="small",t},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["subarray"],props:{numArgs:1},handler(i,e){var t=qh(e[0]),r=t?[e[0]]:me(e[0],"ordgroup").body,n=r.map(function(a){var o=P1(a),l=o.text;if("lc".indexOf(l)!==-1)return{type:"align",align:l};throw new G("Unknown column alignment: "+l,a)});if(n.length>1)throw new G("{subarray} can contain only one column");var s={cols:n,hskipBeforeAndAfter:!1,arraystretch:.5};if(s=vn(i.parser,s,"script"),s.body.length>0&&s.body[0].length>1)throw new G("{subarray} can contain only one column");return s},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(i){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},t=vn(i.parser,e,j1(i.envName));return{type:"leftright",mode:i.mode,body:[t],left:i.envName.indexOf("r")>-1?".":"\\{",right:i.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:sg,htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(i){["gather","gather*"].includes(i.envName)&&$h(i);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:$1(i.envName),emptySingleRow:!0,leqno:i.parser.settings.leqno};return vn(i.parser,e,"display")},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:sg,htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(i){$h(i);var e={autoTag:$1(i.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:i.parser.settings.leqno};return vn(i.parser,e,"display")},htmlBuilder:cr,mathmlBuilder:ur});dr({type:"array",names:["CD"],props:{numArgs:0},handler(i){return $h(i),UA(i.parser)},htmlBuilder:cr,mathmlBuilder:ur});M("\\nonumber","\\gdef\\@eqnsw{0}");M("\\notag","\\nonumber");Z({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(i,e){throw new G(i.funcName+" valid only within array environment")}});d4=rg;Z({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];if(n.type!=="ordgroup")throw new G("Invalid environment name",n);for(var s="",a=0;a{var t=i.font,r=e.withFont(t);return Te(i.body,r)},og=(i,e)=>{var t=i.font,r=e.withFont(t);return Re(i.body,r)},c4={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Z({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathsfit","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=Dh(e[0]),s=r;return s in c4&&(s=c4[s]),{type:"font",mode:t.mode,font:s.slice(1),body:n}},htmlBuilder:ag,mathmlBuilder:og});Z({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(i,e)=>{var{parser:t}=i,r=e[0],n=Ee.isCharacterBox(r);return{type:"mclass",mode:t.mode,mclass:Hh(r),body:[{type:"font",mode:t.mode,font:"boldsymbol",body:r}],isCharacterBox:n}}});Z({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(i,e)=>{var{parser:t,funcName:r,breakOnTokenText:n}=i,{mode:s}=t,a=t.parseExpression(!0,n),o="math"+r.slice(1);return{type:"font",mode:s,font:o,body:{type:"ordgroup",mode:t.mode,body:a}}},htmlBuilder:ag,mathmlBuilder:og});lg=(i,e)=>{var t=e;return i==="display"?t=t.id>=ae.SCRIPT.id?t.text():ae.DISPLAY:i==="text"&&t.size===ae.DISPLAY.size?t=ae.TEXT:i==="script"?t=ae.SCRIPT:i==="scriptscript"&&(t=ae.SCRIPTSCRIPT),t},G1=(i,e)=>{var t=lg(i.size,e.style),r=t.fracNum(),n=t.fracDen(),s;s=e.havingStyle(r);var a=Te(i.numer,s,e);if(i.continued){var o=8.5/e.fontMetrics().ptPerEm,l=3.5/e.fontMetrics().ptPerEm;a.height=a.height0?g=3*f:g=7*f,x=e.fontMetrics().denom1):(c>0?(m=e.fontMetrics().num2,g=f):(m=e.fontMetrics().num3,g=3*f),x=e.fontMetrics().denom2);var y;if(d){var E=e.fontMetrics().axisHeight;m-a.depth-(E+.5*c){var t=new $.MathNode("mfrac",[Re(i.numer,e),Re(i.denom,e)]);if(!i.hasBarLine)t.setAttribute("linethickness","0px");else if(i.barSize){var r=Ke(i.barSize,e);t.setAttribute("linethickness",V(r))}var n=lg(i.size,e.style);if(n.size!==e.style.size){t=new $.MathNode("mstyle",[t]);var s=n.size===ae.DISPLAY.size?"true":"false";t.setAttribute("displaystyle",s),t.setAttribute("scriptlevel","0")}if(i.leftDelim!=null||i.rightDelim!=null){var a=[];if(i.leftDelim!=null){var o=new $.MathNode("mo",[new $.TextNode(i.leftDelim.replace("\\",""))]);o.setAttribute("fence","true"),a.push(o)}if(a.push(t),i.rightDelim!=null){var l=new $.MathNode("mo",[new $.TextNode(i.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),a.push(l)}return O1(a)}return t};Z({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=e[1],a,o=null,l=null,h="auto";switch(r){case"\\dfrac":case"\\frac":case"\\tfrac":a=!0;break;case"\\\\atopfrac":a=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":a=!1,o="(",l=")";break;case"\\\\bracefrac":a=!1,o="\\{",l="\\}";break;case"\\\\brackfrac":a=!1,o="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(r){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:t.mode,continued:!1,numer:n,denom:s,hasBarLine:a,leftDelim:o,rightDelim:l,size:h,barSize:null}},htmlBuilder:G1,mathmlBuilder:W1});Z({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=e[1];return{type:"genfrac",mode:t.mode,continued:!0,numer:n,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}});Z({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(i){var{parser:e,funcName:t,token:r}=i,n;switch(t){case"\\over":n="\\frac";break;case"\\choose":n="\\binom";break;case"\\atop":n="\\\\atopfrac";break;case"\\brace":n="\\\\bracefrac";break;case"\\brack":n="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:n,token:r}}});u4=["display","text","script","scriptscript"],f4=function(e){var t=null;return e.length>0&&(t=e,t=t==="."?null:t),t};Z({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(i,e){var{parser:t}=i,r=e[4],n=e[5],s=Dh(e[0]),a=s.type==="atom"&&s.family==="open"?f4(s.text):null,o=Dh(e[1]),l=o.type==="atom"&&o.family==="close"?f4(o.text):null,h=me(e[2],"size"),d,c=null;h.isBlank?d=!0:(c=h.value,d=c.number>0);var f="auto",m=e[3];if(m.type==="ordgroup"){if(m.body.length>0){var g=me(m.body[0],"textord");f=u4[Number(g.text)]}}else m=me(m,"textord"),f=u4[Number(m.text)];return{type:"genfrac",mode:t.mode,numer:r,denom:n,continued:!1,hasBarLine:d,barSize:c,leftDelim:a,rightDelim:l,size:f}},htmlBuilder:G1,mathmlBuilder:W1});Z({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(i,e){var{parser:t,funcName:r,token:n}=i;return{type:"infix",mode:t.mode,replaceWith:"\\\\abovefrac",size:me(e[0],"size").value,token:n}}});Z({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0],s=RS(me(e[1],"infix").size),a=e[2],o=s.number>0;return{type:"genfrac",mode:t.mode,numer:n,denom:a,continued:!1,hasBarLine:o,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:G1,mathmlBuilder:W1});hg=(i,e)=>{var t=e.style,r,n;i.type==="supsub"?(r=i.sup?Te(i.sup,e.havingStyle(t.sup()),e):Te(i.sub,e.havingStyle(t.sub()),e),n=me(i.base,"horizBrace")):n=me(i,"horizBrace");var s=Te(n.base,e.havingBaseStyle(ae.DISPLAY)),a=Rr.svgSpan(n,e),o;if(n.isOver?(o=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:a}]},e),o.children[0].children[0].children[1].classes.push("svg-align")):(o=z.makeVList({positionType:"bottom",positionData:s.depth+.1+a.height,children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:s}]},e),o.children[0].children[0].children[0].classes.push("svg-align")),r){var l=z.makeSpan(["mord",n.isOver?"mover":"munder"],[o],e);n.isOver?o=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},e):o=z.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},e)}return z.makeSpan(["mord",n.isOver?"mover":"munder"],[o],e)},rk=(i,e)=>{var t=Rr.mathMLnode(i.label);return new $.MathNode(i.isOver?"mover":"munder",[Re(i.base,e),t])};Z({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(i,e){var{parser:t,funcName:r}=i;return{type:"horizBrace",mode:t.mode,label:r,isOver:/^\\over/.test(r),base:e[0]}},htmlBuilder:hg,mathmlBuilder:rk});Z({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[1],n=me(e[0],"url").url;return t.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:t.mode,href:n,body:rt(r)}:t.formatUnsupportedCmd("\\href")},htmlBuilder:(i,e)=>{var t=mt(i.body,e,!1);return z.makeAnchor(i.href,[],t,e)},mathmlBuilder:(i,e)=>{var t=yn(i.body,e);return t instanceof Bt||(t=new Bt("mrow",[t])),t.setAttribute("href",i.href),t}});Z({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=me(e[0],"url").url;if(!t.settings.isTrusted({command:"\\url",url:r}))return t.formatUnsupportedCmd("\\url");for(var n=[],s=0;s{var{parser:t,funcName:r,token:n}=i,s=me(e[0],"raw").string,a=e[1];t.settings.strict&&t.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var o,l={};switch(r){case"\\htmlClass":l.class=s,o={command:"\\htmlClass",class:s};break;case"\\htmlId":l.id=s,o={command:"\\htmlId",id:s};break;case"\\htmlStyle":l.style=s,o={command:"\\htmlStyle",style:s};break;case"\\htmlData":{for(var h=s.split(","),d=0;d{var t=mt(i.body,e,!1),r=["enclosing"];i.attributes.class&&r.push(...i.attributes.class.trim().split(/\s+/));var n=z.makeSpan(r,t,e);for(var s in i.attributes)s!=="class"&&i.attributes.hasOwnProperty(s)&&n.setAttribute(s,i.attributes[s]);return n},mathmlBuilder:(i,e)=>yn(i.body,e)});Z({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i;return{type:"htmlmathml",mode:t.mode,html:rt(e[0]),mathml:rt(e[1])}},htmlBuilder:(i,e)=>{var t=mt(i.html,e,!1);return z.makeFragment(t)},mathmlBuilder:(i,e)=>yn(i.mathml,e)});x1=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new G("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!k4(r))throw new G("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};Z({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(i,e,t)=>{var{parser:r}=i,n={number:0,unit:"em"},s={number:.9,unit:"em"},a={number:0,unit:"em"},o="";if(t[0])for(var l=me(t[0],"raw").string,h=l.split(","),d=0;d{var t=Ke(i.height,e),r=0;i.totalheight.number>0&&(r=Ke(i.totalheight,e)-t);var n=0;i.width.number>0&&(n=Ke(i.width,e));var s={height:V(t+r)};n>0&&(s.width=V(n)),r>0&&(s.verticalAlign=V(-r));var a=new T1(i.src,i.alt,s);return a.height=t,a.depth=r,a},mathmlBuilder:(i,e)=>{var t=new $.MathNode("mglyph",[]);t.setAttribute("alt",i.alt);var r=Ke(i.height,e),n=0;if(i.totalheight.number>0&&(n=Ke(i.totalheight,e)-r,t.setAttribute("valign",V(-n))),t.setAttribute("height",V(r+n)),i.width.number>0){var s=Ke(i.width,e);t.setAttribute("width",V(s))}return t.setAttribute("src",i.src),t}});Z({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(i,e){var{parser:t,funcName:r}=i,n=me(e[0],"size");if(t.settings.strict){var s=r[1]==="m",a=n.value.unit==="mu";s?(a||t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" supports only mu units, "+("not "+n.value.unit+" units")),t.mode!=="math"&&t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" works only in math mode")):a&&t.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+r+" doesn't support mu units")}return{type:"kern",mode:t.mode,dimension:n.value}},htmlBuilder(i,e){return z.makeGlue(i.dimension,e)},mathmlBuilder(i,e){var t=Ke(i.dimension,e);return new $.SpaceNode(t)}});Z({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"lap",mode:t.mode,alignment:r.slice(5),body:n}},htmlBuilder:(i,e)=>{var t;i.alignment==="clap"?(t=z.makeSpan([],[Te(i.body,e)]),t=z.makeSpan(["inner"],[t],e)):t=z.makeSpan(["inner"],[Te(i.body,e)]);var r=z.makeSpan(["fix"],[]),n=z.makeSpan([i.alignment],[t,r],e),s=z.makeSpan(["strut"]);return s.style.height=V(n.height+n.depth),n.depth&&(s.style.verticalAlign=V(-n.depth)),n.children.unshift(s),n=z.makeSpan(["thinbox"],[n],e),z.makeSpan(["mord","vbox"],[n],e)},mathmlBuilder:(i,e)=>{var t=new $.MathNode("mpadded",[Re(i.body,e)]);if(i.alignment!=="rlap"){var r=i.alignment==="llap"?"-1":"-0.5";t.setAttribute("lspace",r+"width")}return t.setAttribute("width","0px"),t}});Z({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,e){var{funcName:t,parser:r}=i,n=r.mode;r.switchMode("math");var s=t==="\\("?"\\)":"$",a=r.parseExpression(!1,s);return r.expect(s),r.switchMode(n),{type:"styling",mode:r.mode,style:"text",body:a}}});Z({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(i,e){throw new G("Mismatched "+i.funcName)}});m4=(i,e)=>{switch(e.style.size){case ae.DISPLAY.size:return i.display;case ae.TEXT.size:return i.text;case ae.SCRIPT.size:return i.script;case ae.SCRIPTSCRIPT.size:return i.scriptscript;default:return i.text}};Z({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(i,e)=>{var{parser:t}=i;return{type:"mathchoice",mode:t.mode,display:rt(e[0]),text:rt(e[1]),script:rt(e[2]),scriptscript:rt(e[3])}},htmlBuilder:(i,e)=>{var t=m4(i,e),r=mt(t,e,!1);return z.makeFragment(r)},mathmlBuilder:(i,e)=>{var t=m4(i,e);return yn(t,e)}});dg=(i,e,t,r,n,s,a)=>{i=z.makeSpan([],[i]);var o=t&&Ee.isCharacterBox(t),l,h;if(e){var d=Te(e,r.havingStyle(n.sup()),r);h={elem:d,kern:Math.max(r.fontMetrics().bigOpSpacing1,r.fontMetrics().bigOpSpacing3-d.depth)}}if(t){var c=Te(t,r.havingStyle(n.sub()),r);l={elem:c,kern:Math.max(r.fontMetrics().bigOpSpacing2,r.fontMetrics().bigOpSpacing4-c.height)}}var f;if(h&&l){var m=r.fontMetrics().bigOpSpacing5+l.elem.height+l.elem.depth+l.kern+i.depth+a;f=z.makeVList({positionType:"bottom",positionData:m,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:l.elem,marginLeft:V(-s)},{type:"kern",size:l.kern},{type:"elem",elem:i},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(s)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else if(l){var g=i.height-a;f=z.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:r.fontMetrics().bigOpSpacing5},{type:"elem",elem:l.elem,marginLeft:V(-s)},{type:"kern",size:l.kern},{type:"elem",elem:i}]},r)}else if(h){var x=i.depth+a;f=z.makeVList({positionType:"bottom",positionData:x,children:[{type:"elem",elem:i},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(s)},{type:"kern",size:r.fontMetrics().bigOpSpacing5}]},r)}else return i;var y=[f];if(l&&s!==0&&!o){var b=z.makeSpan(["mspace"],[],r);b.style.marginRight=V(s),y.unshift(b)}return z.makeSpan(["mop","op-limits"],y,r)},cg=["\\smallint"],ga=(i,e)=>{var t,r,n=!1,s;i.type==="supsub"?(t=i.sup,r=i.sub,s=me(i.base,"op"),n=!0):s=me(i,"op");var a=e.style,o=!1;a.size===ae.DISPLAY.size&&s.symbol&&!cg.includes(s.name)&&(o=!0);var l;if(s.symbol){var h=o?"Size2-Regular":"Size1-Regular",d="";if((s.name==="\\oiint"||s.name==="\\oiiint")&&(d=s.name.slice(1),s.name=d==="oiint"?"\\iint":"\\iiint"),l=z.makeSymbol(s.name,h,"math",e,["mop","op-symbol",o?"large-op":"small-op"]),d.length>0){var c=l.italic,f=z.staticSvg(d+"Size"+(o?"2":"1"),e);l=z.makeVList({positionType:"individualShift",children:[{type:"elem",elem:l,shift:0},{type:"elem",elem:f,shift:o?.08:0}]},e),s.name="\\"+d,l.classes.unshift("mop"),l.italic=c}}else if(s.body){var m=mt(s.body,e,!0);m.length===1&&m[0]instanceof ii?(l=m[0],l.classes[0]="mop"):l=z.makeSpan(["mop"],m,e)}else{for(var g=[],x=1;x{var t;if(i.symbol)t=new Bt("mo",[_i(i.name,i.mode)]),cg.includes(i.name)&&t.setAttribute("largeop","false");else if(i.body)t=new Bt("mo",ri(i.body,e));else{t=new Bt("mi",[new Ci(i.name.slice(1))]);var r=new Bt("mo",[_i("\u2061","text")]);i.parentIsSupSub?t=new Bt("mrow",[t,r]):t=F4([t,r])}return t},nk={"\u220F":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22C0":"\\bigwedge","\u22C1":"\\bigvee","\u22C2":"\\bigcap","\u22C3":"\\bigcup","\u2A00":"\\bigodot","\u2A01":"\\bigoplus","\u2A02":"\\bigotimes","\u2A04":"\\biguplus","\u2A06":"\\bigsqcup"};Z({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220F","\u2210","\u2211","\u22C0","\u22C1","\u22C2","\u22C3","\u2A00","\u2A01","\u2A02","\u2A04","\u2A06"],props:{numArgs:0},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=r;return n.length===1&&(n=nk[n]),{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:ga,mathmlBuilder:hl});Z({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:rt(r)}},htmlBuilder:ga,mathmlBuilder:hl});sk={"\u222B":"\\int","\u222C":"\\iint","\u222D":"\\iiint","\u222E":"\\oint","\u222F":"\\oiint","\u2230":"\\oiiint"};Z({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(i){var{parser:e,funcName:t}=i;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:t}},htmlBuilder:ga,mathmlBuilder:hl});Z({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(i){var{parser:e,funcName:t}=i;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:t}},htmlBuilder:ga,mathmlBuilder:hl});Z({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222B","\u222C","\u222D","\u222E","\u222F","\u2230"],props:{numArgs:0,allowedInArgument:!0},handler(i){var{parser:e,funcName:t}=i,r=t;return r.length===1&&(r=sk[r]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:r}},htmlBuilder:ga,mathmlBuilder:hl});ug=(i,e)=>{var t,r,n=!1,s;i.type==="supsub"?(t=i.sup,r=i.sub,s=me(i.base,"operatorname"),n=!0):s=me(i,"operatorname");var a;if(s.body.length>0){for(var o=s.body.map(c=>{var f=c.text;return typeof f=="string"?{type:"textord",mode:c.mode,text:f}:c}),l=mt(o,e.withFont("mathrm"),!0),h=0;h{for(var t=ri(i.body,e.withFont("mathrm")),r=!0,n=0;nd.toText()).join("");t=[new $.TextNode(o)]}var l=new $.MathNode("mi",t);l.setAttribute("mathvariant","normal");var h=new $.MathNode("mo",[_i("\u2061","text")]);return i.parentIsSupSub?new $.MathNode("mrow",[l,h]):$.newDocumentFragment([l,h])};Z({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:(i,e)=>{var{parser:t,funcName:r}=i,n=e[0];return{type:"operatorname",mode:t.mode,body:rt(n),alwaysHandleSupSub:r==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},htmlBuilder:ug,mathmlBuilder:ak});M("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");gs({type:"ordgroup",htmlBuilder(i,e){return i.semisimple?z.makeFragment(mt(i.body,e,!1)):z.makeSpan(["mord"],mt(i.body,e,!0),e)},mathmlBuilder(i,e){return yn(i.body,e,!0)}});Z({type:"overline",names:["\\overline"],props:{numArgs:1},handler(i,e){var{parser:t}=i,r=e[0];return{type:"overline",mode:t.mode,body:r}},htmlBuilder(i,e){var t=Te(i.body,e.havingCrampedStyle()),r=z.makeLineSpan("overline-line",e),n=e.fontMetrics().defaultRuleThickness,s=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:t},{type:"kern",size:3*n},{type:"elem",elem:r},{type:"kern",size:n}]},e);return z.makeSpan(["mord","overline"],[s],e)},mathmlBuilder(i,e){var t=new $.MathNode("mo",[new $.TextNode("\u203E")]);t.setAttribute("stretchy","true");var r=new $.MathNode("mover",[Re(i.body,e),t]);return r.setAttribute("accent","true"),r}});Z({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"phantom",mode:t.mode,body:rt(r)}},htmlBuilder:(i,e)=>{var t=mt(i.body,e.withPhantom(),!1);return z.makeFragment(t)},mathmlBuilder:(i,e)=>{var t=ri(i.body,e);return new $.MathNode("mphantom",t)}});Z({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"hphantom",mode:t.mode,body:r}},htmlBuilder:(i,e)=>{var t=z.makeSpan([],[Te(i.body,e.withPhantom())]);if(t.height=0,t.depth=0,t.children)for(var r=0;r{var t=ri(rt(i.body),e),r=new $.MathNode("mphantom",t),n=new $.MathNode("mpadded",[r]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}});Z({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(i,e)=>{var{parser:t}=i,r=e[0];return{type:"vphantom",mode:t.mode,body:r}},htmlBuilder:(i,e)=>{var t=z.makeSpan(["inner"],[Te(i.body,e.withPhantom())]),r=z.makeSpan(["fix"],[]);return z.makeSpan(["mord","rlap"],[t,r],e)},mathmlBuilder:(i,e)=>{var t=ri(rt(i.body),e),r=new $.MathNode("mphantom",t),n=new $.MathNode("mpadded",[r]);return n.setAttribute("width","0px"),n}});Z({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(i,e){var{parser:t}=i,r=me(e[0],"size").value,n=e[1];return{type:"raisebox",mode:t.mode,dy:r,body:n}},htmlBuilder(i,e){var t=Te(i.body,e),r=Ke(i.dy,e);return z.makeVList({positionType:"shift",positionData:-r,children:[{type:"elem",elem:t}]},e)},mathmlBuilder(i,e){var t=new $.MathNode("mpadded",[Re(i.body,e)]),r=i.dy.number+i.dy.unit;return t.setAttribute("voffset",r),t}});Z({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0,allowedInArgument:!0},handler(i){var{parser:e}=i;return{type:"internal",mode:e.mode}}});Z({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["size","size","size"]},handler(i,e,t){var{parser:r}=i,n=t[0],s=me(e[0],"size"),a=me(e[1],"size");return{type:"rule",mode:r.mode,shift:n&&me(n,"size").value,width:s.value,height:a.value}},htmlBuilder(i,e){var t=z.makeSpan(["mord","rule"],[],e),r=Ke(i.width,e),n=Ke(i.height,e),s=i.shift?Ke(i.shift,e):0;return t.style.borderRightWidth=V(r),t.style.borderTopWidth=V(n),t.style.bottom=V(s),t.width=r,t.height=n+s,t.depth=-s,t.maxFontSize=n*1.125*e.sizeMultiplier,t},mathmlBuilder(i,e){var t=Ke(i.width,e),r=Ke(i.height,e),n=i.shift?Ke(i.shift,e):0,s=e.color&&e.getColor()||"black",a=new $.MathNode("mspace");a.setAttribute("mathbackground",s),a.setAttribute("width",V(t)),a.setAttribute("height",V(r));var o=new $.MathNode("mpadded",[a]);return n>=0?o.setAttribute("height",V(n)):(o.setAttribute("height",V(n)),o.setAttribute("depth",V(-n))),o.setAttribute("voffset",V(n)),o}});p4=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],ok=(i,e)=>{var t=e.havingSize(i.size);return fg(i.body,t,e)};Z({type:"sizing",names:p4,props:{numArgs:0,allowedInText:!0},handler:(i,e)=>{var{breakOnTokenText:t,funcName:r,parser:n}=i,s=n.parseExpression(!1,t);return{type:"sizing",mode:n.mode,size:p4.indexOf(r)+1,body:s}},htmlBuilder:ok,mathmlBuilder:(i,e)=>{var t=e.havingSize(i.size),r=ri(i.body,t),n=new $.MathNode("mstyle",r);return n.setAttribute("mathsize",V(t.sizeMultiplier)),n}});Z({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(i,e,t)=>{var{parser:r}=i,n=!1,s=!1,a=t[0]&&me(t[0],"ordgroup");if(a)for(var o="",l=0;l{var t=z.makeSpan([],[Te(i.body,e)]);if(!i.smashHeight&&!i.smashDepth)return t;if(i.smashHeight&&(t.height=0,t.children))for(var r=0;r{var t=new $.MathNode("mpadded",[Re(i.body,e)]);return i.smashHeight&&t.setAttribute("height","0px"),i.smashDepth&&t.setAttribute("depth","0px"),t}});Z({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(i,e,t){var{parser:r}=i,n=t[0],s=e[0];return{type:"sqrt",mode:r.mode,body:s,index:n}},htmlBuilder(i,e){var t=Te(i.body,e.havingCrampedStyle());t.height===0&&(t.height=e.fontMetrics().xHeight),t=z.wrapFragment(t,e);var r=e.fontMetrics(),n=r.defaultRuleThickness,s=n;e.style.idt.height+t.depth+a&&(a=(a+c-t.height-t.depth)/2);var f=l.height-t.height-a-h;t.style.paddingLeft=V(d);var m=z.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:t,wrapperClasses:["svg-align"]},{type:"kern",size:-(t.height+f)},{type:"elem",elem:l},{type:"kern",size:h}]},e);if(i.index){var g=e.havingStyle(ae.SCRIPTSCRIPT),x=Te(i.index,g,e),y=.6*(m.height-m.depth),b=z.makeVList({positionType:"shift",positionData:-y,children:[{type:"elem",elem:x}]},e),E=z.makeSpan(["root"],[b]);return z.makeSpan(["mord","sqrt"],[E,m],e)}else return z.makeSpan(["mord","sqrt"],[m],e)},mathmlBuilder(i,e){var{body:t,index:r}=i;return r?new $.MathNode("mroot",[Re(t,e),Re(r,e)]):new $.MathNode("msqrt",[Re(t,e)])}});g4={display:ae.DISPLAY,text:ae.TEXT,script:ae.SCRIPT,scriptscript:ae.SCRIPTSCRIPT};Z({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(i,e){var{breakOnTokenText:t,funcName:r,parser:n}=i,s=n.parseExpression(!0,t),a=r.slice(1,r.length-5);return{type:"styling",mode:n.mode,style:a,body:s}},htmlBuilder(i,e){var t=g4[i.style],r=e.havingStyle(t).withFont("");return fg(i.body,r,e)},mathmlBuilder(i,e){var t=g4[i.style],r=e.havingStyle(t),n=ri(i.body,r),s=new $.MathNode("mstyle",n),a={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},o=a[i.style];return s.setAttribute("scriptlevel",o[0]),s.setAttribute("displaystyle",o[1]),s}});lk=function(e,t){var r=e.base;if(r)if(r.type==="op"){var n=r.limits&&(t.style.size===ae.DISPLAY.size||r.alwaysHandleSupSub);return n?ga:null}else if(r.type==="operatorname"){var s=r.alwaysHandleSupSub&&(t.style.size===ae.DISPLAY.size||r.limits);return s?ug:null}else{if(r.type==="accent")return Ee.isCharacterBox(r.base)?F1:null;if(r.type==="horizBrace"){var a=!e.sub;return a===r.isOver?hg:null}else return null}else return null};gs({type:"supsub",htmlBuilder(i,e){var t=lk(i,e);if(t)return t(i,e);var{base:r,sup:n,sub:s}=i,a=Te(r,e),o,l,h=e.fontMetrics(),d=0,c=0,f=r&&Ee.isCharacterBox(r);if(n){var m=e.havingStyle(e.style.sup());o=Te(n,m,e),f||(d=a.height-m.fontMetrics().supDrop*m.sizeMultiplier/e.sizeMultiplier)}if(s){var g=e.havingStyle(e.style.sub());l=Te(s,g,e),f||(c=a.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}var x;e.style===ae.DISPLAY?x=h.sup1:e.style.cramped?x=h.sup3:x=h.sup2;var y=e.sizeMultiplier,b=V(.5/h.ptPerEm/y),E=null;if(l){var k=i.base&&i.base.type==="op"&&i.base.name&&(i.base.name==="\\oiint"||i.base.name==="\\oiiint");(a instanceof ii||k)&&(E=V(-a.italic))}var L;if(o&&l){d=Math.max(d,x,o.depth+.25*h.xHeight),c=Math.max(c,h.sub2);var I=h.defaultRuleThickness,O=4*I;if(d-o.depth-(l.height-c)0&&(d+=q,c-=q)}var F=[{type:"elem",elem:l,shift:c,marginRight:b,marginLeft:E},{type:"elem",elem:o,shift:-d,marginRight:b}];L=z.makeVList({positionType:"individualShift",children:F},e)}else if(l){c=Math.max(c,h.sub1,l.height-.8*h.xHeight);var W=[{type:"elem",elem:l,marginLeft:E,marginRight:b}];L=z.makeVList({positionType:"shift",positionData:c,children:W},e)}else if(o)d=Math.max(d,x,o.depth+.25*h.xHeight),L=z.makeVList({positionType:"shift",positionData:-d,children:[{type:"elem",elem:o,marginRight:b}]},e);else throw new Error("supsub must have either sup or sub.");var ne=E1(a,"right")||"mord";return z.makeSpan([ne],[a,z.makeSpan(["msupsub"],[L])],e)},mathmlBuilder(i,e){var t=!1,r,n;i.base&&i.base.type==="horizBrace"&&(n=!!i.sup,n===i.base.isOver&&(t=!0,r=i.base.isOver)),i.base&&(i.base.type==="op"||i.base.type==="operatorname")&&(i.base.parentIsSupSub=!0);var s=[Re(i.base,e)];i.sub&&s.push(Re(i.sub,e)),i.sup&&s.push(Re(i.sup,e));var a;if(t)a=r?"mover":"munder";else if(i.sub)if(i.sup){var h=i.base;h&&h.type==="op"&&h.limits&&e.style===ae.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===ae.DISPLAY||h.limits)?a="munderover":a="msubsup"}else{var l=i.base;l&&l.type==="op"&&l.limits&&(e.style===ae.DISPLAY||l.alwaysHandleSupSub)||l&&l.type==="operatorname"&&l.alwaysHandleSupSub&&(l.limits||e.style===ae.DISPLAY)?a="munder":a="msub"}else{var o=i.base;o&&o.type==="op"&&o.limits&&(e.style===ae.DISPLAY||o.alwaysHandleSupSub)||o&&o.type==="operatorname"&&o.alwaysHandleSupSub&&(o.limits||e.style===ae.DISPLAY)?a="mover":a="msup"}return new $.MathNode(a,s)}});gs({type:"atom",htmlBuilder(i,e){return z.mathsym(i.text,i.mode,e,["m"+i.family])},mathmlBuilder(i,e){var t=new $.MathNode("mo",[_i(i.text,i.mode)]);if(i.family==="bin"){var r=B1(i,e);r==="bold-italic"&&t.setAttribute("mathvariant",r)}else i.family==="punct"?t.setAttribute("separator","true"):(i.family==="open"||i.family==="close")&&t.setAttribute("stretchy","false");return t}});mg={mi:"italic",mn:"normal",mtext:"normal"};gs({type:"mathord",htmlBuilder(i,e){return z.makeOrd(i,e,"mathord")},mathmlBuilder(i,e){var t=new $.MathNode("mi",[_i(i.text,i.mode,e)]),r=B1(i,e)||"italic";return r!==mg[t.type]&&t.setAttribute("mathvariant",r),t}});gs({type:"textord",htmlBuilder(i,e){return z.makeOrd(i,e,"textord")},mathmlBuilder(i,e){var t=_i(i.text,i.mode,e),r=B1(i,e)||"normal",n;return i.mode==="text"?n=new $.MathNode("mtext",[t]):/[0-9]/.test(i.text)?n=new $.MathNode("mn",[t]):i.text==="\\prime"?n=new $.MathNode("mo",[t]):n=new $.MathNode("mi",[t]),r!==mg[n.type]&&n.setAttribute("mathvariant",r),n}});y1={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},v1={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};gs({type:"spacing",htmlBuilder(i,e){if(v1.hasOwnProperty(i.text)){var t=v1[i.text].className||"";if(i.mode==="text"){var r=z.makeOrd(i,e,"textord");return r.classes.push(t),r}else return z.makeSpan(["mspace",t],[z.mathsym(i.text,i.mode,e)],e)}else{if(y1.hasOwnProperty(i.text))return z.makeSpan(["mspace",y1[i.text]],[],e);throw new G('Unknown type of space "'+i.text+'"')}},mathmlBuilder(i,e){var t;if(v1.hasOwnProperty(i.text))t=new $.MathNode("mtext",[new $.TextNode("\xA0")]);else{if(y1.hasOwnProperty(i.text))return new $.MathNode("mspace");throw new G('Unknown type of space "'+i.text+'"')}return t}});x4=()=>{var i=new $.MathNode("mtd",[]);return i.setAttribute("width","50%"),i};gs({type:"tag",mathmlBuilder(i,e){var t=new $.MathNode("mtable",[new $.MathNode("mtr",[x4(),new $.MathNode("mtd",[yn(i.body,e)]),x4(),new $.MathNode("mtd",[yn(i.tag,e)])])]);return t.setAttribute("width","100%"),t}});y4={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},v4={"\\textbf":"textbf","\\textmd":"textmd"},hk={"\\textit":"textit","\\textup":"textup"},b4=(i,e)=>{var t=i.font;if(t){if(y4[t])return e.withTextFontFamily(y4[t]);if(v4[t])return e.withTextFontWeight(v4[t]);if(t==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(hk[t])};Z({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(i,e){var{parser:t,funcName:r}=i,n=e[0];return{type:"text",mode:t.mode,body:rt(n),font:r}},htmlBuilder(i,e){var t=b4(i,e),r=mt(i.body,t,!0);return z.makeSpan(["mord","text"],r,t)},mathmlBuilder(i,e){var t=b4(i,e);return yn(i.body,t)}});Z({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(i,e){var{parser:t}=i;return{type:"underline",mode:t.mode,body:e[0]}},htmlBuilder(i,e){var t=Te(i.body,e),r=z.makeLineSpan("underline-line",e),n=e.fontMetrics().defaultRuleThickness,s=z.makeVList({positionType:"top",positionData:t.height,children:[{type:"kern",size:n},{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:t}]},e);return z.makeSpan(["mord","underline"],[s],e)},mathmlBuilder(i,e){var t=new $.MathNode("mo",[new $.TextNode("\u203E")]);t.setAttribute("stretchy","true");var r=new $.MathNode("munder",[Re(i.body,e),t]);return r.setAttribute("accentunder","true"),r}});Z({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(i,e){var{parser:t}=i;return{type:"vcenter",mode:t.mode,body:e[0]}},htmlBuilder(i,e){var t=Te(i.body,e),r=e.fontMetrics().axisHeight,n=.5*(t.height-r-(t.depth+r));return z.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:t}]},e)},mathmlBuilder(i,e){return new $.MathNode("mpadded",[Re(i.body,e)],["vcenter"])}});Z({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(i,e,t){throw new G("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(i,e){for(var t=w4(i),r=[],n=e.havingStyle(e.style.text()),s=0;si.body.replace(/ /g,i.star?"\u2423":"\xA0"),gn=B4,pg=`[ \r + ]`,dk="\\\\[a-zA-Z@]+",ck="\\\\[^\uD800-\uDFFF]",uk="("+dk+")"+pg+"*",fk=`\\\\( |[ \r ]+ -?)[ \r ]*`,v1="[\u0300-\u036F]",jA=new RegExp(v1+"+$"),GA="("+tg+"+)|"+($A+"|")+"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]"+(v1+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(v1+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+UA)+("|"+HA+")"),kh=class{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(GA,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new ui("EOF",new Jt(this,t,t));var r=this.tokenRegex.exec(e);if(r===null||r.index!==t)throw new G("Unexpected character: '"+e[t]+"'",new ui(e[t],new Jt(this,t,t+1)));var n=r[6]||r[3]||(r[2]?"\\ ":" ");if(this.catcodes[n]===14){var s=e.indexOf(` -`,this.tokenRegex.lastIndex);return s===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new ui(n,new Jt(this,t,this.tokenRegex.lastIndex))}},b1=class{constructor(e,t){e===void 0&&(e={}),t===void 0&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new G("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(e[t]==null?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(r===void 0&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var s=this.undefStack[this.undefStack.length-1];s&&!s.hasOwnProperty(e)&&(s[e]=this.current[e])}t==null?delete this.current[e]:this.current[e]=t}},VA=j4;w("\\noexpand",function(i){var e=i.popToken();return i.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});w("\\expandafter",function(i){var e=i.popToken();return i.expandOnce(!0),{tokens:[e],numArgs:0}});w("\\@firstoftwo",function(i){var e=i.consumeArgs(2);return{tokens:e[0],numArgs:0}});w("\\@secondoftwo",function(i){var e=i.consumeArgs(2);return{tokens:e[1],numArgs:0}});w("\\@ifnextchar",function(i){var e=i.consumeArgs(3);i.consumeSpaces();var t=i.future();return e[0].length===1&&e[0][0].text===t.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});w("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");w("\\TextOrMath",function(i){var e=i.consumeArgs(2);return i.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});l4={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};w("\\char",function(i){var e=i.popToken(),t,r="";if(e.text==="'")t=8,e=i.popToken();else if(e.text==='"')t=16,e=i.popToken();else if(e.text==="`")if(e=i.popToken(),e.text[0]==="\\")r=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new G("\\char` missing argument");r=e.text.charCodeAt(0)}else t=10;if(t){if(r=l4[e.text],r==null||r>=t)throw new G("Invalid base-"+t+" digit "+e.text);for(var n;(n=l4[i.future().text])!=null&&n{var n=i.consumeArg().tokens;if(n.length!==1)throw new G("\\newcommand's first argument must be a macro name");var s=n[0].text,a=i.isDefined(s);if(a&&!e)throw new G("\\newcommand{"+s+"} attempting to redefine "+(s+"; use \\renewcommand"));if(!a&&!t)throw new G("\\renewcommand{"+s+"} when command "+s+" does not yet exist; use \\newcommand");var o=0;if(n=i.consumeArg().tokens,n.length===1&&n[0].text==="["){for(var l="",h=i.expandNextToken();h.text!=="]"&&h.text!=="EOF";)l+=h.text,h=i.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new G("Invalid number of arguments: "+l);o=parseInt(l),n=i.consumeArg().tokens}return a&&r||i.macros.set(s,{tokens:n,numArgs:o}),""};w("\\newcommand",i=>O1(i,!1,!0,!1));w("\\renewcommand",i=>O1(i,!0,!1,!1));w("\\providecommand",i=>O1(i,!0,!0,!0));w("\\message",i=>{var e=i.consumeArgs(1)[0];return console.log(e.reverse().map(t=>t.text).join("")),""});w("\\errmessage",i=>{var e=i.consumeArgs(1)[0];return console.error(e.reverse().map(t=>t.text).join("")),""});w("\\show",i=>{var e=i.popToken(),t=e.text;return console.log(e,i.macros.get(t),xn[t],Oe.math[t],Oe.text[t]),""});w("\\bgroup","{");w("\\egroup","}");w("~","\\nobreakspace");w("\\lq","`");w("\\rq","'");w("\\aa","\\r a");w("\\AA","\\r A");w("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xA9}");w("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");w("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xAE}");w("\u212C","\\mathscr{B}");w("\u2130","\\mathscr{E}");w("\u2131","\\mathscr{F}");w("\u210B","\\mathscr{H}");w("\u2110","\\mathscr{I}");w("\u2112","\\mathscr{L}");w("\u2133","\\mathscr{M}");w("\u211B","\\mathscr{R}");w("\u212D","\\mathfrak{C}");w("\u210C","\\mathfrak{H}");w("\u2128","\\mathfrak{Z}");w("\\Bbbk","\\Bbb{k}");w("\xB7","\\cdotp");w("\\llap","\\mathllap{\\textrm{#1}}");w("\\rlap","\\mathrlap{\\textrm{#1}}");w("\\clap","\\mathclap{\\textrm{#1}}");w("\\mathstrut","\\vphantom{(}");w("\\underbar","\\underline{\\text{#1}}");w("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');w("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}");w("\\ne","\\neq");w("\u2260","\\neq");w("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}");w("\u2209","\\notin");w("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}");w("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");w("\u225A","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");w("\u225B","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225B}}");w("\u225D","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225D}}");w("\u225E","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225E}}");w("\u225F","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}");w("\u27C2","\\perp");w("\u203C","\\mathclose{!\\mkern-0.8mu!}");w("\u220C","\\notni");w("\u231C","\\ulcorner");w("\u231D","\\urcorner");w("\u231E","\\llcorner");w("\u231F","\\lrcorner");w("\xA9","\\copyright");w("\xAE","\\textregistered");w("\uFE0F","\\textregistered");w("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');w("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');w("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');w("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');w("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");w("\u22EE","\\vdots");w("\\varGamma","\\mathit{\\Gamma}");w("\\varDelta","\\mathit{\\Delta}");w("\\varTheta","\\mathit{\\Theta}");w("\\varLambda","\\mathit{\\Lambda}");w("\\varXi","\\mathit{\\Xi}");w("\\varPi","\\mathit{\\Pi}");w("\\varSigma","\\mathit{\\Sigma}");w("\\varUpsilon","\\mathit{\\Upsilon}");w("\\varPhi","\\mathit{\\Phi}");w("\\varPsi","\\mathit{\\Psi}");w("\\varOmega","\\mathit{\\Omega}");w("\\substack","\\begin{subarray}{c}#1\\end{subarray}");w("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");w("\\boxed","\\fbox{$\\displaystyle{#1}$}");w("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");w("\\implies","\\DOTSB\\;\\Longrightarrow\\;");w("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");w("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");w("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");h4={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};w("\\dots",function(i){var e="\\dotso",t=i.expandAfterFuture().text;return t in h4?e=h4[t]:(t.slice(0,4)==="\\not"||t in Oe.math&&["bin","rel"].includes(Oe.math[t].group))&&(e="\\dotsb"),e});B1={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};w("\\dotso",function(i){var e=i.future().text;return e in B1?"\\ldots\\,":"\\ldots"});w("\\dotsc",function(i){var e=i.future().text;return e in B1&&e!==","?"\\ldots\\,":"\\ldots"});w("\\cdots",function(i){var e=i.future().text;return e in B1?"\\@cdots\\,":"\\@cdots"});w("\\dotsb","\\cdots");w("\\dotsm","\\cdots");w("\\dotsi","\\!\\cdots");w("\\dotsx","\\ldots\\,");w("\\DOTSI","\\relax");w("\\DOTSB","\\relax");w("\\DOTSX","\\relax");w("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");w("\\,","\\tmspace+{3mu}{.1667em}");w("\\thinspace","\\,");w("\\>","\\mskip{4mu}");w("\\:","\\tmspace+{4mu}{.2222em}");w("\\medspace","\\:");w("\\;","\\tmspace+{5mu}{.2777em}");w("\\thickspace","\\;");w("\\!","\\tmspace-{3mu}{.1667em}");w("\\negthinspace","\\!");w("\\negmedspace","\\tmspace-{4mu}{.2222em}");w("\\negthickspace","\\tmspace-{5mu}{.277em}");w("\\enspace","\\kern.5em ");w("\\enskip","\\hskip.5em\\relax");w("\\quad","\\hskip1em\\relax");w("\\qquad","\\hskip2em\\relax");w("\\tag","\\@ifstar\\tag@literal\\tag@paren");w("\\tag@paren","\\tag@literal{({#1})}");w("\\tag@literal",i=>{if(i.macros.get("\\df@tag"))throw new G("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});w("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");w("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");w("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");w("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");w("\\newline","\\\\\\relax");w("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");ig=V(dr["Main-Regular"][84][1]-.7*dr["Main-Regular"][65][1]);w("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+ig+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");w("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+ig+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");w("\\hspace","\\@ifstar\\@hspacer\\@hspace");w("\\@hspace","\\hskip #1\\relax");w("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");w("\\ordinarycolon",":");w("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");w("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');w("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');w("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');w("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');w("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');w("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');w("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');w("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');w("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');w("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');w("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');w("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');w("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');w("\u2237","\\dblcolon");w("\u2239","\\eqcolon");w("\u2254","\\coloneqq");w("\u2255","\\eqqcolon");w("\u2A74","\\Coloneqq");w("\\ratio","\\vcentcolon");w("\\coloncolon","\\dblcolon");w("\\colonequals","\\coloneqq");w("\\coloncolonequals","\\Coloneqq");w("\\equalscolon","\\eqqcolon");w("\\equalscoloncolon","\\Eqqcolon");w("\\colonminus","\\coloneq");w("\\coloncolonminus","\\Coloneq");w("\\minuscolon","\\eqcolon");w("\\minuscoloncolon","\\Eqcolon");w("\\coloncolonapprox","\\Colonapprox");w("\\coloncolonsim","\\Colonsim");w("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");w("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");w("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");w("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");w("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");w("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");w("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");w("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");w("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");w("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");w("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");w("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");w("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");w("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}");w("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}");w("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}");w("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}");w("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}");w("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}");w("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}");w("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}");w("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}");w("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}");w("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228A}");w("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2ACB}");w("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228B}");w("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2ACC}");w("\\imath","\\html@mathml{\\@imath}{\u0131}");w("\\jmath","\\html@mathml{\\@jmath}{\u0237}");w("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27E6}}");w("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27E7}}");w("\u27E6","\\llbracket");w("\u27E7","\\rrbracket");w("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}");w("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}");w("\u2983","\\lBrace");w("\u2984","\\rBrace");w("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29B5}}");w("\u29B5","\\minuso");w("\\darr","\\downarrow");w("\\dArr","\\Downarrow");w("\\Darr","\\Downarrow");w("\\lang","\\langle");w("\\rang","\\rangle");w("\\uarr","\\uparrow");w("\\uArr","\\Uparrow");w("\\Uarr","\\Uparrow");w("\\N","\\mathbb{N}");w("\\R","\\mathbb{R}");w("\\Z","\\mathbb{Z}");w("\\alef","\\aleph");w("\\alefsym","\\aleph");w("\\Alpha","\\mathrm{A}");w("\\Beta","\\mathrm{B}");w("\\bull","\\bullet");w("\\Chi","\\mathrm{X}");w("\\clubs","\\clubsuit");w("\\cnums","\\mathbb{C}");w("\\Complex","\\mathbb{C}");w("\\Dagger","\\ddagger");w("\\diamonds","\\diamondsuit");w("\\empty","\\emptyset");w("\\Epsilon","\\mathrm{E}");w("\\Eta","\\mathrm{H}");w("\\exist","\\exists");w("\\harr","\\leftrightarrow");w("\\hArr","\\Leftrightarrow");w("\\Harr","\\Leftrightarrow");w("\\hearts","\\heartsuit");w("\\image","\\Im");w("\\infin","\\infty");w("\\Iota","\\mathrm{I}");w("\\isin","\\in");w("\\Kappa","\\mathrm{K}");w("\\larr","\\leftarrow");w("\\lArr","\\Leftarrow");w("\\Larr","\\Leftarrow");w("\\lrarr","\\leftrightarrow");w("\\lrArr","\\Leftrightarrow");w("\\Lrarr","\\Leftrightarrow");w("\\Mu","\\mathrm{M}");w("\\natnums","\\mathbb{N}");w("\\Nu","\\mathrm{N}");w("\\Omicron","\\mathrm{O}");w("\\plusmn","\\pm");w("\\rarr","\\rightarrow");w("\\rArr","\\Rightarrow");w("\\Rarr","\\Rightarrow");w("\\real","\\Re");w("\\reals","\\mathbb{R}");w("\\Reals","\\mathbb{R}");w("\\Rho","\\mathrm{P}");w("\\sdot","\\cdot");w("\\sect","\\S");w("\\spades","\\spadesuit");w("\\sub","\\subset");w("\\sube","\\subseteq");w("\\supe","\\supseteq");w("\\Tau","\\mathrm{T}");w("\\thetasym","\\vartheta");w("\\weierp","\\wp");w("\\Zeta","\\mathrm{Z}");w("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");w("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");w("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");w("\\bra","\\mathinner{\\langle{#1}|}");w("\\ket","\\mathinner{|{#1}\\rangle}");w("\\braket","\\mathinner{\\langle{#1}\\rangle}");w("\\Bra","\\left\\langle#1\\right|");w("\\Ket","\\left|#1\\right\\rangle");rg=i=>e=>{var t=e.consumeArg().tokens,r=e.consumeArg().tokens,n=e.consumeArg().tokens,s=e.consumeArg().tokens,a=e.macros.get("|"),o=e.macros.get("\\|");e.macros.beginGroup();var l=c=>f=>{i&&(f.macros.set("|",a),n.length&&f.macros.set("\\|",o));var m=c;if(!c&&n.length){var g=f.future();g.text==="|"&&(f.popToken(),m=!0)}return{tokens:m?n:r,numArgs:0}};e.macros.set("|",l(!1)),n.length&&e.macros.set("\\|",l(!0));var h=e.consumeArg().tokens,d=e.expandTokens([...s,...h,...t]);return e.macros.endGroup(),{tokens:d.reverse(),numArgs:0}};w("\\bra@ket",rg(!1));w("\\bra@set",rg(!0));w("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");w("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");w("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");w("\\angln","{\\angl n}");w("\\blue","\\textcolor{##6495ed}{#1}");w("\\orange","\\textcolor{##ffa500}{#1}");w("\\pink","\\textcolor{##ff00af}{#1}");w("\\red","\\textcolor{##df0030}{#1}");w("\\green","\\textcolor{##28ae7b}{#1}");w("\\gray","\\textcolor{gray}{#1}");w("\\purple","\\textcolor{##9d38bd}{#1}");w("\\blueA","\\textcolor{##ccfaff}{#1}");w("\\blueB","\\textcolor{##80f6ff}{#1}");w("\\blueC","\\textcolor{##63d9ea}{#1}");w("\\blueD","\\textcolor{##11accd}{#1}");w("\\blueE","\\textcolor{##0c7f99}{#1}");w("\\tealA","\\textcolor{##94fff5}{#1}");w("\\tealB","\\textcolor{##26edd5}{#1}");w("\\tealC","\\textcolor{##01d1c1}{#1}");w("\\tealD","\\textcolor{##01a995}{#1}");w("\\tealE","\\textcolor{##208170}{#1}");w("\\greenA","\\textcolor{##b6ffb0}{#1}");w("\\greenB","\\textcolor{##8af281}{#1}");w("\\greenC","\\textcolor{##74cf70}{#1}");w("\\greenD","\\textcolor{##1fab54}{#1}");w("\\greenE","\\textcolor{##0d923f}{#1}");w("\\goldA","\\textcolor{##ffd0a9}{#1}");w("\\goldB","\\textcolor{##ffbb71}{#1}");w("\\goldC","\\textcolor{##ff9c39}{#1}");w("\\goldD","\\textcolor{##e07d10}{#1}");w("\\goldE","\\textcolor{##a75a05}{#1}");w("\\redA","\\textcolor{##fca9a9}{#1}");w("\\redB","\\textcolor{##ff8482}{#1}");w("\\redC","\\textcolor{##f9685d}{#1}");w("\\redD","\\textcolor{##e84d39}{#1}");w("\\redE","\\textcolor{##bc2612}{#1}");w("\\maroonA","\\textcolor{##ffbde0}{#1}");w("\\maroonB","\\textcolor{##ff92c6}{#1}");w("\\maroonC","\\textcolor{##ed5fa6}{#1}");w("\\maroonD","\\textcolor{##ca337c}{#1}");w("\\maroonE","\\textcolor{##9e034e}{#1}");w("\\purpleA","\\textcolor{##ddd7ff}{#1}");w("\\purpleB","\\textcolor{##c6b9fc}{#1}");w("\\purpleC","\\textcolor{##aa87ff}{#1}");w("\\purpleD","\\textcolor{##7854ab}{#1}");w("\\purpleE","\\textcolor{##543b78}{#1}");w("\\mintA","\\textcolor{##f5f9e8}{#1}");w("\\mintB","\\textcolor{##edf2df}{#1}");w("\\mintC","\\textcolor{##e0e5cc}{#1}");w("\\grayA","\\textcolor{##f6f7f7}{#1}");w("\\grayB","\\textcolor{##f0f1f2}{#1}");w("\\grayC","\\textcolor{##e3e5e6}{#1}");w("\\grayD","\\textcolor{##d6d8da}{#1}");w("\\grayE","\\textcolor{##babec2}{#1}");w("\\grayF","\\textcolor{##888d93}{#1}");w("\\grayG","\\textcolor{##626569}{#1}");w("\\grayH","\\textcolor{##3b3e40}{#1}");w("\\grayI","\\textcolor{##21242c}{#1}");w("\\kaBlue","\\textcolor{##314453}{#1}");w("\\kaGreen","\\textcolor{##71B307}{#1}");ng={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},w1=class{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new b1(VA,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new kh(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,n;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;t=this.popToken(),{tokens:n,end:r}=this.consumeArg(["]"])}else({tokens:n,start:t,end:r}=this.consumeArg());return this.pushToken(new ui("EOF",r.loc)),this.pushTokens(n),new ui("",Jt.range(t,r))}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var n=this.future(),s,a=0,o=0;do{if(s=this.popToken(),t.push(s),s.text==="{")++a;else if(s.text==="}"){if(--a,a===-1)throw new G("Extra }",s)}else if(s.text==="EOF")throw new G("Unexpected end of input in a macro argument, expected '"+(e&&r?e[o]:"}")+"'",s);if(e&&r)if((a===0||a===1&&e[o]==="{")&&s.text===e[o]){if(++o,o===e.length){t.splice(-o,o);break}}else o=0}while(a!==0||r);return n.text==="{"&&t[t.length-1].text==="}"&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:s}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new G("The length of delimiters doesn't match the number of args!");for(var r=t[0],n=0;nthis.settings.maxExpand)throw new G("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,n=t.noexpand?null:this._getExpansion(r);if(n==null||e&&n.unexpandable){if(e&&n==null&&r[0]==="\\"&&!this.isDefined(r))throw new G("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var s=n.tokens,a=this.consumeArgs(n.numArgs,n.delimiters);if(n.numArgs){s=s.slice();for(var o=s.length-1;o>=0;--o){var l=s[o];if(l.text==="#"){if(o===0)throw new G("Incomplete placeholder at end of macro body",l);if(l=s[--o],l.text==="#")s.splice(o+1,1);else if(/^[1-9]$/.test(l.text))s.splice(o,2,...a[+l.text-1]);else throw new G("Not a valid argument number",l)}}}return this.pushTokens(s),s.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new ui(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(this.expandOnce(!0)===!1){var n=this.stack.pop();n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(n)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t&&t.map(r=>r.text).join("")}_getExpansion(e){var t=this.macros.get(e);if(t==null)return t;if(e.length===1){var r=this.lexer.catcodes[e];if(r!=null&&r!==13)return}var n=typeof t=="function"?t(this):t;if(typeof n=="string"){var s=0;if(n.indexOf("#")!==-1)for(var a=n.replace(/##/g,"");a.indexOf("#"+(s+1))!==-1;)++s;for(var o=new kh(n,this.settings),l=[],h=o.lex();h.text!=="EOF";)l.push(h),h=o.lex();l.reverse();var d={tokens:l,numArgs:s};return d}return n}isDefined(e){return this.macros.has(e)||xn.hasOwnProperty(e)||Oe.math.hasOwnProperty(e)||Oe.text.hasOwnProperty(e)||ng.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return t!=null?typeof t=="string"||typeof t=="function"||!t.unexpandable:xn.hasOwnProperty(e)&&!xn[e].primitive}},d4=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,vh=Object.freeze({"\u208A":"+","\u208B":"-","\u208C":"=","\u208D":"(","\u208E":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1D62":"i","\u2C7C":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209A":"p","\u1D63":"r","\u209B":"s","\u209C":"t","\u1D64":"u","\u1D65":"v","\u2093":"x","\u1D66":"\u03B2","\u1D67":"\u03B3","\u1D68":"\u03C1","\u1D69":"\u03D5","\u1D6A":"\u03C7","\u207A":"+","\u207B":"-","\u207C":"=","\u207D":"(","\u207E":")","\u2070":"0","\xB9":"1","\xB2":"2","\xB3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1D2C":"A","\u1D2E":"B","\u1D30":"D","\u1D31":"E","\u1D33":"G","\u1D34":"H","\u1D35":"I","\u1D36":"J","\u1D37":"K","\u1D38":"L","\u1D39":"M","\u1D3A":"N","\u1D3C":"O","\u1D3E":"P","\u1D3F":"R","\u1D40":"T","\u1D41":"U","\u2C7D":"V","\u1D42":"W","\u1D43":"a","\u1D47":"b","\u1D9C":"c","\u1D48":"d","\u1D49":"e","\u1DA0":"f","\u1D4D":"g",\u02B0:"h","\u2071":"i",\u02B2:"j","\u1D4F":"k",\u02E1:"l","\u1D50":"m",\u207F:"n","\u1D52":"o","\u1D56":"p",\u02B3:"r",\u02E2:"s","\u1D57":"t","\u1D58":"u","\u1D5B":"v",\u02B7:"w",\u02E3:"x",\u02B8:"y","\u1DBB":"z","\u1D5D":"\u03B2","\u1D5E":"\u03B3","\u1D5F":"\u03B4","\u1D60":"\u03D5","\u1D61":"\u03C7","\u1DBF":"\u03B8"}),h1={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030C":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030A":{text:"\\r",math:"\\mathring"},"\u030B":{text:"\\H"},"\u0327":{text:"\\c"}},c4={\u00E1:"a\u0301",\u00E0:"a\u0300",\u00E4:"a\u0308",\u01DF:"a\u0308\u0304",\u00E3:"a\u0303",\u0101:"a\u0304",\u0103:"a\u0306",\u1EAF:"a\u0306\u0301",\u1EB1:"a\u0306\u0300",\u1EB5:"a\u0306\u0303",\u01CE:"a\u030C",\u00E2:"a\u0302",\u1EA5:"a\u0302\u0301",\u1EA7:"a\u0302\u0300",\u1EAB:"a\u0302\u0303",\u0227:"a\u0307",\u01E1:"a\u0307\u0304",\u00E5:"a\u030A",\u01FB:"a\u030A\u0301",\u1E03:"b\u0307",\u0107:"c\u0301",\u1E09:"c\u0327\u0301",\u010D:"c\u030C",\u0109:"c\u0302",\u010B:"c\u0307",\u00E7:"c\u0327",\u010F:"d\u030C",\u1E0B:"d\u0307",\u1E11:"d\u0327",\u00E9:"e\u0301",\u00E8:"e\u0300",\u00EB:"e\u0308",\u1EBD:"e\u0303",\u0113:"e\u0304",\u1E17:"e\u0304\u0301",\u1E15:"e\u0304\u0300",\u0115:"e\u0306",\u1E1D:"e\u0327\u0306",\u011B:"e\u030C",\u00EA:"e\u0302",\u1EBF:"e\u0302\u0301",\u1EC1:"e\u0302\u0300",\u1EC5:"e\u0302\u0303",\u0117:"e\u0307",\u0229:"e\u0327",\u1E1F:"f\u0307",\u01F5:"g\u0301",\u1E21:"g\u0304",\u011F:"g\u0306",\u01E7:"g\u030C",\u011D:"g\u0302",\u0121:"g\u0307",\u0123:"g\u0327",\u1E27:"h\u0308",\u021F:"h\u030C",\u0125:"h\u0302",\u1E23:"h\u0307",\u1E29:"h\u0327",\u00ED:"i\u0301",\u00EC:"i\u0300",\u00EF:"i\u0308",\u1E2F:"i\u0308\u0301",\u0129:"i\u0303",\u012B:"i\u0304",\u012D:"i\u0306",\u01D0:"i\u030C",\u00EE:"i\u0302",\u01F0:"j\u030C",\u0135:"j\u0302",\u1E31:"k\u0301",\u01E9:"k\u030C",\u0137:"k\u0327",\u013A:"l\u0301",\u013E:"l\u030C",\u013C:"l\u0327",\u1E3F:"m\u0301",\u1E41:"m\u0307",\u0144:"n\u0301",\u01F9:"n\u0300",\u00F1:"n\u0303",\u0148:"n\u030C",\u1E45:"n\u0307",\u0146:"n\u0327",\u00F3:"o\u0301",\u00F2:"o\u0300",\u00F6:"o\u0308",\u022B:"o\u0308\u0304",\u00F5:"o\u0303",\u1E4D:"o\u0303\u0301",\u1E4F:"o\u0303\u0308",\u022D:"o\u0303\u0304",\u014D:"o\u0304",\u1E53:"o\u0304\u0301",\u1E51:"o\u0304\u0300",\u014F:"o\u0306",\u01D2:"o\u030C",\u00F4:"o\u0302",\u1ED1:"o\u0302\u0301",\u1ED3:"o\u0302\u0300",\u1ED7:"o\u0302\u0303",\u022F:"o\u0307",\u0231:"o\u0307\u0304",\u0151:"o\u030B",\u1E55:"p\u0301",\u1E57:"p\u0307",\u0155:"r\u0301",\u0159:"r\u030C",\u1E59:"r\u0307",\u0157:"r\u0327",\u015B:"s\u0301",\u1E65:"s\u0301\u0307",\u0161:"s\u030C",\u1E67:"s\u030C\u0307",\u015D:"s\u0302",\u1E61:"s\u0307",\u015F:"s\u0327",\u1E97:"t\u0308",\u0165:"t\u030C",\u1E6B:"t\u0307",\u0163:"t\u0327",\u00FA:"u\u0301",\u00F9:"u\u0300",\u00FC:"u\u0308",\u01D8:"u\u0308\u0301",\u01DC:"u\u0308\u0300",\u01D6:"u\u0308\u0304",\u01DA:"u\u0308\u030C",\u0169:"u\u0303",\u1E79:"u\u0303\u0301",\u016B:"u\u0304",\u1E7B:"u\u0304\u0308",\u016D:"u\u0306",\u01D4:"u\u030C",\u00FB:"u\u0302",\u016F:"u\u030A",\u0171:"u\u030B",\u1E7D:"v\u0303",\u1E83:"w\u0301",\u1E81:"w\u0300",\u1E85:"w\u0308",\u0175:"w\u0302",\u1E87:"w\u0307",\u1E98:"w\u030A",\u1E8D:"x\u0308",\u1E8B:"x\u0307",\u00FD:"y\u0301",\u1EF3:"y\u0300",\u00FF:"y\u0308",\u1EF9:"y\u0303",\u0233:"y\u0304",\u0177:"y\u0302",\u1E8F:"y\u0307",\u1E99:"y\u030A",\u017A:"z\u0301",\u017E:"z\u030C",\u1E91:"z\u0302",\u017C:"z\u0307",\u00C1:"A\u0301",\u00C0:"A\u0300",\u00C4:"A\u0308",\u01DE:"A\u0308\u0304",\u00C3:"A\u0303",\u0100:"A\u0304",\u0102:"A\u0306",\u1EAE:"A\u0306\u0301",\u1EB0:"A\u0306\u0300",\u1EB4:"A\u0306\u0303",\u01CD:"A\u030C",\u00C2:"A\u0302",\u1EA4:"A\u0302\u0301",\u1EA6:"A\u0302\u0300",\u1EAA:"A\u0302\u0303",\u0226:"A\u0307",\u01E0:"A\u0307\u0304",\u00C5:"A\u030A",\u01FA:"A\u030A\u0301",\u1E02:"B\u0307",\u0106:"C\u0301",\u1E08:"C\u0327\u0301",\u010C:"C\u030C",\u0108:"C\u0302",\u010A:"C\u0307",\u00C7:"C\u0327",\u010E:"D\u030C",\u1E0A:"D\u0307",\u1E10:"D\u0327",\u00C9:"E\u0301",\u00C8:"E\u0300",\u00CB:"E\u0308",\u1EBC:"E\u0303",\u0112:"E\u0304",\u1E16:"E\u0304\u0301",\u1E14:"E\u0304\u0300",\u0114:"E\u0306",\u1E1C:"E\u0327\u0306",\u011A:"E\u030C",\u00CA:"E\u0302",\u1EBE:"E\u0302\u0301",\u1EC0:"E\u0302\u0300",\u1EC4:"E\u0302\u0303",\u0116:"E\u0307",\u0228:"E\u0327",\u1E1E:"F\u0307",\u01F4:"G\u0301",\u1E20:"G\u0304",\u011E:"G\u0306",\u01E6:"G\u030C",\u011C:"G\u0302",\u0120:"G\u0307",\u0122:"G\u0327",\u1E26:"H\u0308",\u021E:"H\u030C",\u0124:"H\u0302",\u1E22:"H\u0307",\u1E28:"H\u0327",\u00CD:"I\u0301",\u00CC:"I\u0300",\u00CF:"I\u0308",\u1E2E:"I\u0308\u0301",\u0128:"I\u0303",\u012A:"I\u0304",\u012C:"I\u0306",\u01CF:"I\u030C",\u00CE:"I\u0302",\u0130:"I\u0307",\u0134:"J\u0302",\u1E30:"K\u0301",\u01E8:"K\u030C",\u0136:"K\u0327",\u0139:"L\u0301",\u013D:"L\u030C",\u013B:"L\u0327",\u1E3E:"M\u0301",\u1E40:"M\u0307",\u0143:"N\u0301",\u01F8:"N\u0300",\u00D1:"N\u0303",\u0147:"N\u030C",\u1E44:"N\u0307",\u0145:"N\u0327",\u00D3:"O\u0301",\u00D2:"O\u0300",\u00D6:"O\u0308",\u022A:"O\u0308\u0304",\u00D5:"O\u0303",\u1E4C:"O\u0303\u0301",\u1E4E:"O\u0303\u0308",\u022C:"O\u0303\u0304",\u014C:"O\u0304",\u1E52:"O\u0304\u0301",\u1E50:"O\u0304\u0300",\u014E:"O\u0306",\u01D1:"O\u030C",\u00D4:"O\u0302",\u1ED0:"O\u0302\u0301",\u1ED2:"O\u0302\u0300",\u1ED6:"O\u0302\u0303",\u022E:"O\u0307",\u0230:"O\u0307\u0304",\u0150:"O\u030B",\u1E54:"P\u0301",\u1E56:"P\u0307",\u0154:"R\u0301",\u0158:"R\u030C",\u1E58:"R\u0307",\u0156:"R\u0327",\u015A:"S\u0301",\u1E64:"S\u0301\u0307",\u0160:"S\u030C",\u1E66:"S\u030C\u0307",\u015C:"S\u0302",\u1E60:"S\u0307",\u015E:"S\u0327",\u0164:"T\u030C",\u1E6A:"T\u0307",\u0162:"T\u0327",\u00DA:"U\u0301",\u00D9:"U\u0300",\u00DC:"U\u0308",\u01D7:"U\u0308\u0301",\u01DB:"U\u0308\u0300",\u01D5:"U\u0308\u0304",\u01D9:"U\u0308\u030C",\u0168:"U\u0303",\u1E78:"U\u0303\u0301",\u016A:"U\u0304",\u1E7A:"U\u0304\u0308",\u016C:"U\u0306",\u01D3:"U\u030C",\u00DB:"U\u0302",\u016E:"U\u030A",\u0170:"U\u030B",\u1E7C:"V\u0303",\u1E82:"W\u0301",\u1E80:"W\u0300",\u1E84:"W\u0308",\u0174:"W\u0302",\u1E86:"W\u0307",\u1E8C:"X\u0308",\u1E8A:"X\u0307",\u00DD:"Y\u0301",\u1EF2:"Y\u0300",\u0178:"Y\u0308",\u1EF8:"Y\u0303",\u0232:"Y\u0304",\u0176:"Y\u0302",\u1E8E:"Y\u0307",\u0179:"Z\u0301",\u017D:"Z\u030C",\u1E90:"Z\u0302",\u017B:"Z\u0307",\u03AC:"\u03B1\u0301",\u1F70:"\u03B1\u0300",\u1FB1:"\u03B1\u0304",\u1FB0:"\u03B1\u0306",\u03AD:"\u03B5\u0301",\u1F72:"\u03B5\u0300",\u03AE:"\u03B7\u0301",\u1F74:"\u03B7\u0300",\u03AF:"\u03B9\u0301",\u1F76:"\u03B9\u0300",\u03CA:"\u03B9\u0308",\u0390:"\u03B9\u0308\u0301",\u1FD2:"\u03B9\u0308\u0300",\u1FD1:"\u03B9\u0304",\u1FD0:"\u03B9\u0306",\u03CC:"\u03BF\u0301",\u1F78:"\u03BF\u0300",\u03CD:"\u03C5\u0301",\u1F7A:"\u03C5\u0300",\u03CB:"\u03C5\u0308",\u03B0:"\u03C5\u0308\u0301",\u1FE2:"\u03C5\u0308\u0300",\u1FE1:"\u03C5\u0304",\u1FE0:"\u03C5\u0306",\u03CE:"\u03C9\u0301",\u1F7C:"\u03C9\u0300",\u038E:"\u03A5\u0301",\u1FEA:"\u03A5\u0300",\u03AB:"\u03A5\u0308",\u1FE9:"\u03A5\u0304",\u1FE8:"\u03A5\u0306",\u038F:"\u03A9\u0301",\u1FFA:"\u03A9\u0300"},Ch=class i{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new w1(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(t===void 0&&(t=!0),this.fetch().text!==e)throw new G("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new ui("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){this.mode==="math"&&this.consumeSpaces();var n=this.fetch();if(i.endOfExpression.indexOf(n.text)!==-1||t&&n.text===t||e&&xn[n.text]&&xn[n.text].infix)break;var s=this.parseAtom(t);if(s){if(s.type==="internal")continue}else break;r.push(s)}return this.mode==="text"&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t=-1,r,n=0;n=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var o=Oe[this.mode][t].group,l=Jt.range(e),h;if(BS.hasOwnProperty(o)){var d=o;h={type:"atom",mode:this.mode,family:d,loc:l,text:t}}else h={type:o,mode:this.mode,loc:l,text:t};a=h}else if(t.charCodeAt(0)>=128)this.settings.strict&&(f4(t.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'"'+(" ("+t.charCodeAt(0)+")"),e)),a={type:"textord",mode:"text",loc:Jt.range(e),text:t};else return null;if(this.consume(),s)for(var c=0;c{QA=typeof global=="object"&&global&&global.Object===Object&&global,Bh=QA});var JA,ek,lt,Ki=T(()=>{q1();JA=typeof self=="object"&&self&&self.Object===Object&&self,ek=Bh||JA||Function("return this")(),lt=ek});var tk,_i,nl=T(()=>{Ki();tk=lt.Symbol,_i=tk});function nk(i){var e=ik.call(i,sl),t=i[sl];try{i[sl]=void 0;var r=!0}catch{}var n=rk.call(i);return r&&(e?i[sl]=t:delete i[sl]),n}var lg,ik,rk,sl,hg,dg=T(()=>{nl();lg=Object.prototype,ik=lg.hasOwnProperty,rk=lg.toString,sl=_i?_i.toStringTag:void 0;hg=nk});function ok(i){return ak.call(i)}var sk,ak,cg,ug=T(()=>{sk=Object.prototype,ak=sk.toString;cg=ok});function dk(i){return i==null?i===void 0?hk:lk:fg&&fg in Object(i)?hg(i):cg(i)}var lk,hk,fg,Zi,ga=T(()=>{nl();dg();ug();lk="[object Null]",hk="[object Undefined]",fg=_i?_i.toStringTag:void 0;Zi=dk});function ck(i){return i!=null&&typeof i=="object"}var vt,Or=T(()=>{vt=ck});var uk,Li,xa=T(()=>{uk=Array.isArray,Li=uk});function fk(i){var e=typeof i;return i!=null&&(e=="object"||e=="function")}var Nt,Br=T(()=>{Nt=fk});function mk(i){return i}var Ph,H1=T(()=>{Ph=mk});function vk(i){if(!Nt(i))return!1;var e=Zi(i);return e==gk||e==xk||e==pk||e==yk}var pk,gk,xk,yk,ya,Fh=T(()=>{ga();Br();pk="[object AsyncFunction]",gk="[object Function]",xk="[object GeneratorFunction]",yk="[object Proxy]";ya=vk});var bk,qh,mg=T(()=>{Ki();bk=lt["__core-js_shared__"],qh=bk});function wk(i){return!!pg&&pg in i}var pg,gg,xg=T(()=>{mg();pg=(function(){var i=/[^.]+$/.exec(qh&&qh.keys&&qh.keys.IE_PROTO||"");return i?"Symbol(src)_1."+i:""})();gg=wk});function Nk(i){if(i!=null){try{return Tk.call(i)}catch{}try{return i+""}catch{}}return""}var Mk,Tk,Pr,U1=T(()=>{Mk=Function.prototype,Tk=Mk.toString;Pr=Nk});function Ik(i){if(!Nt(i)||gg(i))return!1;var e=ya(i)?Lk:Sk;return e.test(Pr(i))}var Ek,Sk,Ak,kk,Ck,_k,Lk,yg,vg=T(()=>{Fh();xg();Br();U1();Ek=/[\\^$.*+?()[\]{}|]/g,Sk=/^\[object .+?Constructor\]$/,Ak=Function.prototype,kk=Object.prototype,Ck=Ak.toString,_k=kk.hasOwnProperty,Lk=RegExp("^"+Ck.call(_k).replace(Ek,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");yg=Ik});function zk(i,e){return i?.[e]}var bg,wg=T(()=>{bg=zk});function Rk(i,e){var t=bg(i,e);return yg(t)?t:void 0}var ii,wn=T(()=>{vg();wg();ii=Rk});var Dk,Hh,Mg=T(()=>{wn();Ki();Dk=ii(lt,"WeakMap"),Hh=Dk});var Tg,Ok,Ng,Eg=T(()=>{Br();Tg=Object.create,Ok=(function(){function i(){}return function(e){if(!Nt(e))return{};if(Tg)return Tg(e);i.prototype=e;var t=new i;return i.prototype=void 0,t}})(),Ng=Ok});function Bk(i,e,t){switch(t.length){case 0:return i.call(e);case 1:return i.call(e,t[0]);case 2:return i.call(e,t[0],t[1]);case 3:return i.call(e,t[0],t[1],t[2])}return i.apply(e,t)}var Sg,Ag=T(()=>{Sg=Bk});function Pk(i,e){var t=-1,r=i.length;for(e||(e=Array(r));++t{Uh=Pk});function Uk(i){var e=0,t=0;return function(){var r=Hk(),n=qk-(r-t);if(t=r,n>0){if(++e>=Fk)return arguments[0]}else e=0;return i.apply(void 0,arguments)}}var Fk,qk,Hk,kg,Cg=T(()=>{Fk=800,qk=16,Hk=Date.now;kg=Uk});function $k(i){return function(){return i}}var _g,Lg=T(()=>{_g=$k});var jk,va,j1=T(()=>{wn();jk=(function(){try{var i=ii(Object,"defineProperty");return i({},"",{}),i}catch{}})(),va=jk});var Gk,Ig,zg=T(()=>{Lg();j1();H1();Gk=va?function(i,e){return va(i,"toString",{configurable:!0,enumerable:!1,value:_g(e),writable:!0})}:Ph,Ig=Gk});var Vk,Rg,Dg=T(()=>{zg();Cg();Vk=kg(Ig),Rg=Vk});function Wk(i,e){for(var t=-1,r=i==null?0:i.length;++t{Og=Wk});function Kk(i,e){var t=typeof i;return e=e??Yk,!!e&&(t=="number"||t!="symbol"&&Xk.test(i))&&i>-1&&i%1==0&&i{Yk=9007199254740991,Xk=/^(?:0|[1-9]\d*)$/;$h=Kk});function Zk(i,e,t){e=="__proto__"&&va?va(i,e,{configurable:!0,enumerable:!0,value:t,writable:!0}):i[e]=t}var ba,jh=T(()=>{j1();ba=Zk});function Qk(i,e){return i===e||i!==i&&e!==e}var pr,wa=T(()=>{pr=Qk});function tC(i,e,t){var r=i[e];(!(eC.call(i,e)&&pr(r,t))||t===void 0&&!(e in i))&&ba(i,e,t)}var Jk,eC,Gh,V1=T(()=>{jh();wa();Jk=Object.prototype,eC=Jk.hasOwnProperty;Gh=tC});function iC(i,e,t,r){var n=!t;t||(t={});for(var s=-1,a=e.length;++s{V1();jh();gr=iC});function rC(i,e,t){return e=Pg(e===void 0?i.length-1:e,0),function(){for(var r=arguments,n=-1,s=Pg(r.length-e,0),a=Array(s);++n{Ag();Pg=Math.max;Fg=rC});function nC(i,e){return Rg(Fg(i,e,Ph),i+"")}var Hg,Ug=T(()=>{H1();qg();Dg();Hg=nC});function aC(i){return typeof i=="number"&&i>-1&&i%1==0&&i<=sC}var sC,Vh,W1=T(()=>{sC=9007199254740991;Vh=aC});function oC(i){return i!=null&&Vh(i.length)&&!ya(i)}var Mn,al=T(()=>{Fh();W1();Mn=oC});function lC(i,e,t){if(!Nt(t))return!1;var r=typeof e;return(r=="number"?Mn(t)&&$h(e,t.length):r=="string"&&e in t)?pr(t[e],i):!1}var $g,jg=T(()=>{wa();al();G1();Br();$g=lC});function hC(i){return Hg(function(e,t){var r=-1,n=t.length,s=n>1?t[n-1]:void 0,a=n>2?t[2]:void 0;for(s=i.length>3&&typeof s=="function"?(n--,s):void 0,a&&$g(t[0],t[1],a)&&(s=n<3?void 0:s,n=1),e=Object(e);++r{Ug();jg();Gg=hC});function cC(i){var e=i&&i.constructor,t=typeof e=="function"&&e.prototype||dC;return i===t}var dC,Ta,Wh=T(()=>{dC=Object.prototype;Ta=cC});function uC(i,e){for(var t=-1,r=Array(i);++t{Wg=uC});function mC(i){return vt(i)&&Zi(i)==fC}var fC,Y1,Xg=T(()=>{ga();Or();fC="[object Arguments]";Y1=mC});var Kg,pC,gC,xC,ol,X1=T(()=>{Xg();Or();Kg=Object.prototype,pC=Kg.hasOwnProperty,gC=Kg.propertyIsEnumerable,xC=Y1((function(){return arguments})())?Y1:function(i){return vt(i)&&pC.call(i,"callee")&&!gC.call(i,"callee")},ol=xC});function yC(){return!1}var Zg,Qg=T(()=>{Zg=yC});var t5,Jg,vC,e5,bC,wC,Fr,ll=T(()=>{Ki();Qg();t5=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Jg=t5&&typeof module=="object"&&module&&!module.nodeType&&module,vC=Jg&&Jg.exports===t5,e5=vC?lt.Buffer:void 0,bC=e5?e5.isBuffer:void 0,wC=bC||Zg,Fr=wC});function VC(i){return vt(i)&&Vh(i.length)&&!!He[Zi(i)]}var MC,TC,NC,EC,SC,AC,kC,CC,_C,LC,IC,zC,RC,DC,OC,BC,PC,FC,qC,HC,UC,$C,jC,GC,He,i5,r5=T(()=>{ga();W1();Or();MC="[object Arguments]",TC="[object Array]",NC="[object Boolean]",EC="[object Date]",SC="[object Error]",AC="[object Function]",kC="[object Map]",CC="[object Number]",_C="[object Object]",LC="[object RegExp]",IC="[object Set]",zC="[object String]",RC="[object WeakMap]",DC="[object ArrayBuffer]",OC="[object DataView]",BC="[object Float32Array]",PC="[object Float64Array]",FC="[object Int8Array]",qC="[object Int16Array]",HC="[object Int32Array]",UC="[object Uint8Array]",$C="[object Uint8ClampedArray]",jC="[object Uint16Array]",GC="[object Uint32Array]",He={};He[BC]=He[PC]=He[FC]=He[qC]=He[HC]=He[UC]=He[$C]=He[jC]=He[GC]=!0;He[MC]=He[TC]=He[DC]=He[NC]=He[OC]=He[EC]=He[SC]=He[AC]=He[kC]=He[CC]=He[_C]=He[LC]=He[IC]=He[zC]=He[RC]=!1;i5=VC});function WC(i){return function(e){return i(e)}}var Na,Yh=T(()=>{Na=WC});var n5,hl,YC,K1,XC,qr,Xh=T(()=>{q1();n5=typeof exports=="object"&&exports&&!exports.nodeType&&exports,hl=n5&&typeof module=="object"&&module&&!module.nodeType&&module,YC=hl&&hl.exports===n5,K1=YC&&Bh.process,XC=(function(){try{var i=hl&&hl.require&&hl.require("util").types;return i||K1&&K1.binding&&K1.binding("util")}catch{}})(),qr=XC});var s5,KC,Ea,Kh=T(()=>{r5();Yh();Xh();s5=qr&&qr.isTypedArray,KC=s5?Na(s5):i5,Ea=KC});function JC(i,e){var t=Li(i),r=!t&&ol(i),n=!t&&!r&&Fr(i),s=!t&&!r&&!n&&Ea(i),a=t||r||n||s,o=a?Wg(i.length,String):[],l=o.length;for(var h in i)(e||QC.call(i,h))&&!(a&&(h=="length"||n&&(h=="offset"||h=="parent")||s&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||$h(h,l)))&&o.push(h);return o}var ZC,QC,Zh,Z1=T(()=>{Yg();X1();xa();ll();G1();Kh();ZC=Object.prototype,QC=ZC.hasOwnProperty;Zh=JC});function e_(i,e){return function(t){return i(e(t))}}var Qh,Q1=T(()=>{Qh=e_});var t_,a5,o5=T(()=>{Q1();t_=Qh(Object.keys,Object),a5=t_});function n_(i){if(!Ta(i))return a5(i);var e=[];for(var t in Object(i))r_.call(i,t)&&t!="constructor"&&e.push(t);return e}var i_,r_,l5,h5=T(()=>{Wh();o5();i_=Object.prototype,r_=i_.hasOwnProperty;l5=n_});function s_(i){return Mn(i)?Zh(i):l5(i)}var Sa,Jh=T(()=>{Z1();h5();al();Sa=s_});function a_(i){var e=[];if(i!=null)for(var t in Object(i))e.push(t);return e}var d5,c5=T(()=>{d5=a_});function h_(i){if(!Nt(i))return d5(i);var e=Ta(i),t=[];for(var r in i)r=="constructor"&&(e||!l_.call(i,r))||t.push(r);return t}var o_,l_,u5,f5=T(()=>{Br();Wh();c5();o_=Object.prototype,l_=o_.hasOwnProperty;u5=h_});function d_(i){return Mn(i)?Zh(i,!0):u5(i)}var xr,Aa=T(()=>{Z1();f5();al();xr=d_});var c_,Hr,dl=T(()=>{wn();c_=ii(Object,"create"),Hr=c_});function u_(){this.__data__=Hr?Hr(null):{},this.size=0}var m5,p5=T(()=>{dl();m5=u_});function f_(i){var e=this.has(i)&&delete this.__data__[i];return this.size-=e?1:0,e}var g5,x5=T(()=>{g5=f_});function x_(i){var e=this.__data__;if(Hr){var t=e[i];return t===m_?void 0:t}return g_.call(e,i)?e[i]:void 0}var m_,p_,g_,y5,v5=T(()=>{dl();m_="__lodash_hash_undefined__",p_=Object.prototype,g_=p_.hasOwnProperty;y5=x_});function b_(i){var e=this.__data__;return Hr?e[i]!==void 0:v_.call(e,i)}var y_,v_,b5,w5=T(()=>{dl();y_=Object.prototype,v_=y_.hasOwnProperty;b5=b_});function M_(i,e){var t=this.__data__;return this.size+=this.has(i)?0:1,t[i]=Hr&&e===void 0?w_:e,this}var w_,M5,T5=T(()=>{dl();w_="__lodash_hash_undefined__";M5=M_});function ka(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{p5();x5();v5();w5();T5();ka.prototype.clear=m5;ka.prototype.delete=g5;ka.prototype.get=y5;ka.prototype.has=b5;ka.prototype.set=M5;J1=ka});function T_(){this.__data__=[],this.size=0}var E5,S5=T(()=>{E5=T_});function N_(i,e){for(var t=i.length;t--;)if(pr(i[t][0],e))return t;return-1}var Tn,cl=T(()=>{wa();Tn=N_});function A_(i){var e=this.__data__,t=Tn(e,i);if(t<0)return!1;var r=e.length-1;return t==r?e.pop():S_.call(e,t,1),--this.size,!0}var E_,S_,A5,k5=T(()=>{cl();E_=Array.prototype,S_=E_.splice;A5=A_});function k_(i){var e=this.__data__,t=Tn(e,i);return t<0?void 0:e[t][1]}var C5,_5=T(()=>{cl();C5=k_});function C_(i){return Tn(this.__data__,i)>-1}var L5,I5=T(()=>{cl();L5=C_});function __(i,e){var t=this.__data__,r=Tn(t,i);return r<0?(++this.size,t.push([i,e])):t[r][1]=e,this}var z5,R5=T(()=>{cl();z5=__});function Ca(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{S5();k5();_5();I5();R5();Ca.prototype.clear=E5;Ca.prototype.delete=A5;Ca.prototype.get=C5;Ca.prototype.has=L5;Ca.prototype.set=z5;Nn=Ca});var L_,En,ed=T(()=>{wn();Ki();L_=ii(lt,"Map"),En=L_});function I_(){this.size=0,this.__data__={hash:new J1,map:new(En||Nn),string:new J1}}var D5,O5=T(()=>{N5();ul();ed();D5=I_});function z_(i){var e=typeof i;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?i!=="__proto__":i===null}var B5,P5=T(()=>{B5=z_});function R_(i,e){var t=i.__data__;return B5(e)?t[typeof e=="string"?"string":"hash"]:t.map}var Sn,fl=T(()=>{P5();Sn=R_});function D_(i){var e=Sn(this,i).delete(i);return this.size-=e?1:0,e}var F5,q5=T(()=>{fl();F5=D_});function O_(i){return Sn(this,i).get(i)}var H5,U5=T(()=>{fl();H5=O_});function B_(i){return Sn(this,i).has(i)}var $5,j5=T(()=>{fl();$5=B_});function P_(i,e){var t=Sn(this,i),r=t.size;return t.set(i,e),this.size+=t.size==r?0:1,this}var G5,V5=T(()=>{fl();G5=P_});function _a(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{O5();q5();U5();j5();V5();_a.prototype.clear=D5;_a.prototype.delete=F5;_a.prototype.get=H5;_a.prototype.has=$5;_a.prototype.set=G5;td=_a});function F_(i,e){for(var t=-1,r=e.length,n=i.length;++t{id=F_});var q_,La,rd=T(()=>{Q1();q_=Qh(Object.getPrototypeOf,Object),La=q_});function V_(i){if(!vt(i)||Zi(i)!=H_)return!1;var e=La(i);if(e===null)return!0;var t=j_.call(e,"constructor")&&e.constructor;return typeof t=="function"&&t instanceof t&&W5.call(t)==G_}var H_,U_,$_,W5,j_,G_,Y5,X5=T(()=>{ga();rd();Or();H_="[object Object]",U_=Function.prototype,$_=Object.prototype,W5=U_.toString,j_=$_.hasOwnProperty,G_=W5.call(Object);Y5=V_});function W_(){this.__data__=new Nn,this.size=0}var K5,Z5=T(()=>{ul();K5=W_});function Y_(i){var e=this.__data__,t=e.delete(i);return this.size=e.size,t}var Q5,J5=T(()=>{Q5=Y_});function X_(i){return this.__data__.get(i)}var e7,t7=T(()=>{e7=X_});function K_(i){return this.__data__.has(i)}var i7,r7=T(()=>{i7=K_});function Q_(i,e){var t=this.__data__;if(t instanceof Nn){var r=t.__data__;if(!En||r.length{ul();ed();ef();Z_=200;n7=Q_});function Ia(i){var e=this.__data__=new Nn(i);this.size=e.size}var An,nd=T(()=>{ul();Z5();J5();t7();r7();s7();Ia.prototype.clear=K5;Ia.prototype.delete=Q5;Ia.prototype.get=e7;Ia.prototype.has=i7;Ia.prototype.set=n7;An=Ia});function J_(i,e){return i&&gr(e,Sa(e),i)}var a7,o7=T(()=>{Ma();Jh();a7=J_});function eL(i,e){return i&&gr(e,xr(e),i)}var l7,h7=T(()=>{Ma();Aa();l7=eL});function iL(i,e){if(e)return i.slice();var t=i.length,r=u7?u7(t):new i.constructor(t);return i.copy(r),r}var f7,d7,tL,c7,u7,sd,rf=T(()=>{Ki();f7=typeof exports=="object"&&exports&&!exports.nodeType&&exports,d7=f7&&typeof module=="object"&&module&&!module.nodeType&&module,tL=d7&&d7.exports===f7,c7=tL?lt.Buffer:void 0,u7=c7?c7.allocUnsafe:void 0;sd=iL});function rL(i,e){for(var t=-1,r=i==null?0:i.length,n=0,s=[];++t{m7=rL});function nL(){return[]}var ad,nf=T(()=>{ad=nL});var sL,aL,g7,oL,za,od=T(()=>{p7();nf();sL=Object.prototype,aL=sL.propertyIsEnumerable,g7=Object.getOwnPropertySymbols,oL=g7?function(i){return i==null?[]:(i=Object(i),m7(g7(i),function(e){return aL.call(i,e)}))}:ad,za=oL});function lL(i,e){return gr(i,za(i),e)}var x7,y7=T(()=>{Ma();od();x7=lL});var hL,dL,ld,sf=T(()=>{tf();rd();od();nf();hL=Object.getOwnPropertySymbols,dL=hL?function(i){for(var e=[];i;)id(e,za(i)),i=La(i);return e}:ad,ld=dL});function cL(i,e){return gr(i,ld(i),e)}var v7,b7=T(()=>{Ma();sf();v7=cL});function uL(i,e,t){var r=e(i);return Li(i)?r:id(r,t(i))}var hd,af=T(()=>{tf();xa();hd=uL});function fL(i){return hd(i,Sa,za)}var ml,of=T(()=>{af();od();Jh();ml=fL});function mL(i){return hd(i,xr,ld)}var w7,M7=T(()=>{af();sf();Aa();w7=mL});var pL,dd,T7=T(()=>{wn();Ki();pL=ii(lt,"DataView"),dd=pL});var gL,cd,N7=T(()=>{wn();Ki();gL=ii(lt,"Promise"),cd=gL});var xL,ud,E7=T(()=>{wn();Ki();xL=ii(lt,"Set"),ud=xL});var S7,yL,A7,k7,C7,_7,vL,bL,wL,ML,TL,xs,Ur,pl=T(()=>{T7();ed();N7();E7();Mg();ga();U1();S7="[object Map]",yL="[object Object]",A7="[object Promise]",k7="[object Set]",C7="[object WeakMap]",_7="[object DataView]",vL=Pr(dd),bL=Pr(En),wL=Pr(cd),ML=Pr(ud),TL=Pr(Hh),xs=Zi;(dd&&xs(new dd(new ArrayBuffer(1)))!=_7||En&&xs(new En)!=S7||cd&&xs(cd.resolve())!=A7||ud&&xs(new ud)!=k7||Hh&&xs(new Hh)!=C7)&&(xs=function(i){var e=Zi(i),t=e==yL?i.constructor:void 0,r=t?Pr(t):"";if(r)switch(r){case vL:return _7;case bL:return S7;case wL:return A7;case ML:return k7;case TL:return C7}return e});Ur=xs});function SL(i){var e=i.length,t=new i.constructor(e);return e&&typeof i[0]=="string"&&EL.call(i,"index")&&(t.index=i.index,t.input=i.input),t}var NL,EL,L7,I7=T(()=>{NL=Object.prototype,EL=NL.hasOwnProperty;L7=SL});var AL,Ra,lf=T(()=>{Ki();AL=lt.Uint8Array,Ra=AL});function kL(i){var e=new i.constructor(i.byteLength);return new Ra(e).set(new Ra(i)),e}var Da,fd=T(()=>{lf();Da=kL});function CL(i,e){var t=e?Da(i.buffer):i.buffer;return new i.constructor(t,i.byteOffset,i.byteLength)}var z7,R7=T(()=>{fd();z7=CL});function LL(i){var e=new i.constructor(i.source,_L.exec(i));return e.lastIndex=i.lastIndex,e}var _L,D7,O7=T(()=>{_L=/\w*$/;D7=LL});function IL(i){return P7?Object(P7.call(i)):{}}var B7,P7,F7,q7=T(()=>{nl();B7=_i?_i.prototype:void 0,P7=B7?B7.valueOf:void 0;F7=IL});function zL(i,e){var t=e?Da(i.buffer):i.buffer;return new i.constructor(t,i.byteOffset,i.length)}var md,hf=T(()=>{fd();md=zL});function JL(i,e,t){var r=i.constructor;switch(e){case UL:return Da(i);case RL:case DL:return new r(+i);case $L:return z7(i,t);case jL:case GL:case VL:case WL:case YL:case XL:case KL:case ZL:case QL:return md(i,t);case OL:return new r;case BL:case qL:return new r(i);case PL:return D7(i);case FL:return new r;case HL:return F7(i)}}var RL,DL,OL,BL,PL,FL,qL,HL,UL,$L,jL,GL,VL,WL,YL,XL,KL,ZL,QL,H7,U7=T(()=>{fd();R7();O7();q7();hf();RL="[object Boolean]",DL="[object Date]",OL="[object Map]",BL="[object Number]",PL="[object RegExp]",FL="[object Set]",qL="[object String]",HL="[object Symbol]",UL="[object ArrayBuffer]",$L="[object DataView]",jL="[object Float32Array]",GL="[object Float64Array]",VL="[object Int8Array]",WL="[object Int16Array]",YL="[object Int32Array]",XL="[object Uint8Array]",KL="[object Uint8ClampedArray]",ZL="[object Uint16Array]",QL="[object Uint32Array]";H7=JL});function eI(i){return typeof i.constructor=="function"&&!Ta(i)?Ng(La(i)):{}}var pd,df=T(()=>{Eg();rd();Wh();pd=eI});function iI(i){return vt(i)&&Ur(i)==tI}var tI,$7,j7=T(()=>{pl();Or();tI="[object Map]";$7=iI});var G7,rI,V7,W7=T(()=>{j7();Yh();Xh();G7=qr&&qr.isMap,rI=G7?Na(G7):$7,V7=rI});function sI(i){return vt(i)&&Ur(i)==nI}var nI,Y7,X7=T(()=>{pl();Or();nI="[object Set]";Y7=sI});var K7,aI,Z7,Q7=T(()=>{X7();Yh();Xh();K7=qr&&qr.isSet,aI=K7?Na(K7):Y7,Z7=aI});function gd(i,e,t,r,n,s){var a,o=e&oI,l=e&lI,h=e&hI;if(t&&(a=n?t(i,r,n,s):t(i)),a!==void 0)return a;if(!Nt(i))return i;var d=Li(i);if(d){if(a=L7(i),!o)return Uh(i,a)}else{var c=Ur(i),f=c==e8||c==mI;if(Fr(i))return sd(i,o);if(c==t8||c==J7||f&&!n){if(a=l||f?{}:pd(i),!o)return l?v7(i,l7(a,i)):x7(i,a7(a,i))}else{if(!Be[c])return n?i:{};a=H7(i,c,o)}}s||(s=new An);var m=s.get(i);if(m)return m;s.set(i,a),Z7(i)?i.forEach(function(y){a.add(gd(y,e,t,y,i,s))}):V7(i)&&i.forEach(function(y,b){a.set(b,gd(y,e,t,b,i,s))});var g=h?l?w7:ml:l?xr:Sa,x=d?void 0:g(i);return Og(x||i,function(y,b){x&&(b=y,y=i[b]),Gh(a,b,gd(y,e,t,b,i,s))}),a}var oI,lI,hI,J7,dI,cI,uI,fI,e8,mI,pI,gI,t8,xI,yI,vI,bI,wI,MI,TI,NI,EI,SI,AI,kI,CI,_I,LI,II,Be,i8,r8=T(()=>{nd();Bg();V1();o7();h7();rf();$1();y7();b7();of();M7();pl();I7();U7();df();xa();ll();W7();Br();Q7();Jh();Aa();oI=1,lI=2,hI=4,J7="[object Arguments]",dI="[object Array]",cI="[object Boolean]",uI="[object Date]",fI="[object Error]",e8="[object Function]",mI="[object GeneratorFunction]",pI="[object Map]",gI="[object Number]",t8="[object Object]",xI="[object RegExp]",yI="[object Set]",vI="[object String]",bI="[object Symbol]",wI="[object WeakMap]",MI="[object ArrayBuffer]",TI="[object DataView]",NI="[object Float32Array]",EI="[object Float64Array]",SI="[object Int8Array]",AI="[object Int16Array]",kI="[object Int32Array]",CI="[object Uint8Array]",_I="[object Uint8ClampedArray]",LI="[object Uint16Array]",II="[object Uint32Array]",Be={};Be[J7]=Be[dI]=Be[MI]=Be[TI]=Be[cI]=Be[uI]=Be[NI]=Be[EI]=Be[SI]=Be[AI]=Be[kI]=Be[pI]=Be[gI]=Be[t8]=Be[xI]=Be[yI]=Be[vI]=Be[bI]=Be[CI]=Be[_I]=Be[LI]=Be[II]=!0;Be[fI]=Be[e8]=Be[wI]=!1;i8=gd});function DI(i){return i8(i,zI|RI)}var zI,RI,yr,n8=T(()=>{r8();zI=1,RI=4;yr=DI});function BI(i){return this.__data__.set(i,OI),this}var OI,s8,a8=T(()=>{OI="__lodash_hash_undefined__";s8=BI});function PI(i){return this.__data__.has(i)}var o8,l8=T(()=>{o8=PI});function xd(i){var e=-1,t=i==null?0:i.length;for(this.__data__=new td;++e{ef();a8();l8();xd.prototype.add=xd.prototype.push=s8;xd.prototype.has=o8;h8=xd});function FI(i,e){for(var t=-1,r=i==null?0:i.length;++t{c8=FI});function qI(i,e){return i.has(e)}var f8,m8=T(()=>{f8=qI});function $I(i,e,t,r,n,s){var a=t&HI,o=i.length,l=e.length;if(o!=l&&!(a&&l>o))return!1;var h=s.get(i),d=s.get(e);if(h&&d)return h==e&&d==i;var c=-1,f=!0,m=t&UI?new h8:void 0;for(s.set(i,e),s.set(e,i);++c{d8();u8();m8();HI=1,UI=2;yd=$I});function jI(i){var e=-1,t=Array(i.size);return i.forEach(function(r,n){t[++e]=[n,r]}),t}var p8,g8=T(()=>{p8=jI});function GI(i){var e=-1,t=Array(i.size);return i.forEach(function(r){t[++e]=r}),t}var x8,y8=T(()=>{x8=GI});function sz(i,e,t,r,n,s,a){switch(t){case nz:if(i.byteLength!=e.byteLength||i.byteOffset!=e.byteOffset)return!1;i=i.buffer,e=e.buffer;case rz:return!(i.byteLength!=e.byteLength||!s(new Ra(i),new Ra(e)));case YI:case XI:case QI:return pr(+i,+e);case KI:return i.name==e.name&&i.message==e.message;case JI:case tz:return i==e+"";case ZI:var o=p8;case ez:var l=r&VI;if(o||(o=x8),i.size!=e.size&&!l)return!1;var h=a.get(i);if(h)return h==e;r|=WI,a.set(i,e);var d=yd(o(i),o(e),r,n,s,a);return a.delete(i),d;case iz:if(uf)return uf.call(i)==uf.call(e)}return!1}var VI,WI,YI,XI,KI,ZI,QI,JI,ez,tz,iz,rz,nz,v8,uf,b8,w8=T(()=>{nl();lf();wa();cf();g8();y8();VI=1,WI=2,YI="[object Boolean]",XI="[object Date]",KI="[object Error]",ZI="[object Map]",QI="[object Number]",JI="[object RegExp]",ez="[object Set]",tz="[object String]",iz="[object Symbol]",rz="[object ArrayBuffer]",nz="[object DataView]",v8=_i?_i.prototype:void 0,uf=v8?v8.valueOf:void 0;b8=sz});function hz(i,e,t,r,n,s){var a=t&az,o=ml(i),l=o.length,h=ml(e),d=h.length;if(l!=d&&!a)return!1;for(var c=l;c--;){var f=o[c];if(!(a?f in e:lz.call(e,f)))return!1}var m=s.get(i),g=s.get(e);if(m&&g)return m==e&&g==i;var x=!0;s.set(i,e),s.set(e,i);for(var y=a;++c{of();az=1,oz=Object.prototype,lz=oz.hasOwnProperty;M8=hz});function uz(i,e,t,r,n,s){var a=Li(i),o=Li(e),l=a?E8:Ur(i),h=o?E8:Ur(e);l=l==N8?vd:l,h=h==N8?vd:h;var d=l==vd,c=h==vd,f=l==h;if(f&&Fr(i)){if(!Fr(e))return!1;a=!0,d=!1}if(f&&!d)return s||(s=new An),a||Ea(i)?yd(i,e,t,r,n,s):b8(i,e,l,t,r,n,s);if(!(t&dz)){var m=d&&S8.call(i,"__wrapped__"),g=c&&S8.call(e,"__wrapped__");if(m||g){var x=m?i.value():i,y=g?e.value():e;return s||(s=new An),n(x,y,t,r,s)}}return f?(s||(s=new An),M8(i,e,t,r,n,s)):!1}var dz,N8,E8,vd,cz,S8,A8,k8=T(()=>{nd();cf();w8();T8();pl();xa();ll();Kh();dz=1,N8="[object Arguments]",E8="[object Array]",vd="[object Object]",cz=Object.prototype,S8=cz.hasOwnProperty;A8=uz});function C8(i,e,t,r,n){return i===e?!0:i==null||e==null||!vt(i)&&!vt(e)?i!==i&&e!==e:A8(i,e,t,r,C8,n)}var _8,L8=T(()=>{k8();Or();_8=C8});function fz(i){return function(e,t,r){for(var n=-1,s=Object(e),a=r(e),o=a.length;o--;){var l=a[i?o:++n];if(t(s[l],l,s)===!1)break}return e}}var I8,z8=T(()=>{I8=fz});var mz,R8,D8=T(()=>{z8();mz=I8(),R8=mz});function pz(i,e,t){(t!==void 0&&!pr(i[e],t)||t===void 0&&!(e in i))&&ba(i,e,t)}var gl,ff=T(()=>{jh();wa();gl=pz});function gz(i){return vt(i)&&Mn(i)}var O8,B8=T(()=>{al();Or();O8=gz});function xz(i,e){if(!(e==="constructor"&&typeof i[e]=="function")&&e!="__proto__")return i[e]}var xl,mf=T(()=>{xl=xz});function yz(i){return gr(i,xr(i))}var P8,F8=T(()=>{Ma();Aa();P8=yz});function vz(i,e,t,r,n,s,a){var o=xl(i,t),l=xl(e,t),h=a.get(l);if(h){gl(i,t,h);return}var d=s?s(o,l,t+"",i,e,a):void 0,c=d===void 0;if(c){var f=Li(l),m=!f&&Fr(l),g=!f&&!m&&Ea(l);d=l,f||m||g?Li(o)?d=o:O8(o)?d=Uh(o):m?(c=!1,d=sd(l,!0)):g?(c=!1,d=md(l,!0)):d=[]:Y5(l)||ol(l)?(d=o,ol(o)?d=P8(o):(!Nt(o)||ya(o))&&(d=pd(l))):c=!1}c&&(a.set(l,d),n(d,l,r,s,a),a.delete(l)),gl(i,t,d)}var q8,H8=T(()=>{ff();rf();hf();$1();df();X1();xa();B8();ll();Fh();Br();X5();Kh();mf();F8();q8=vz});function U8(i,e,t,r,n){i!==e&&R8(e,function(s,a){if(n||(n=new An),Nt(s))q8(i,e,a,t,U8,r,n);else{var o=r?r(xl(i,a),s,a+"",i,e,n):void 0;o===void 0&&(o=s),gl(i,a,o)}},xr)}var $8,j8=T(()=>{nd();ff();D8();H8();Br();Aa();mf();$8=U8});function bz(i,e){return _8(i,e)}var ys,G8=T(()=>{L8();ys=bz});var wz,ri,V8=T(()=>{j8();Vg();wz=Gg(function(i,e,t){$8(i,e,t)}),ri=wz});var kn=T(()=>{n8();G8();V8();});var bl={};tt(bl,{Attributor:()=>qt,AttributorStore:()=>yl,BlockBlot:()=>vs,ClassAttributor:()=>ht,ContainerBlot:()=>qa,EmbedBlot:()=>Ke,InlineBlot:()=>bd,LeafBlot:()=>dt,ParentBlot:()=>ni,Registry:()=>Ln,Scope:()=>X,ScrollBlot:()=>vl,StyleAttributor:()=>si,TextBlot:()=>Ha});function W8(i,e){return(i.getAttribute("class")||"").split(/\s+/).filter(t=>t.indexOf(`${e}-`)===0)}function pf(i){let e=i.split("-"),t=e.slice(1).map(r=>r[0].toUpperCase()+r.slice(1)).join("");return e[0]+t}function Y8(i,e){let t=e.find(i);if(t)return t;try{return e.create(i)}catch{let r=e.create(X.INLINE);return Array.from(i.childNodes).forEach(n=>{r.domNode.appendChild(n)}),i.parentNode&&i.parentNode.replaceChild(r.domNode,i),r.attach(),r}}function Nz(i,e){if(Object.keys(i).length!==Object.keys(e).length)return!1;for(let t in i)if(i[t]!==e[t])return!1;return!0}var X,qt,_n,X8,Ln,xf,ht,yf,si,vf,yl,K8,Z8,Q8,Mz,dt,bf,J8,Tz,ni,Oa,Ez,bd,Pa,Sz,vs,Mf,Az,qa,Tf,Ke,kz,Cz,Fa,_z,vl,Nf,Lz,Ha,Re=T(()=>{X=(i=>(i[i.TYPE=3]="TYPE",i[i.LEVEL=12]="LEVEL",i[i.ATTRIBUTE=13]="ATTRIBUTE",i[i.BLOT=14]="BLOT",i[i.INLINE=7]="INLINE",i[i.BLOCK=11]="BLOCK",i[i.BLOCK_BLOT=10]="BLOCK_BLOT",i[i.INLINE_BLOT=6]="INLINE_BLOT",i[i.BLOCK_ATTRIBUTE=9]="BLOCK_ATTRIBUTE",i[i.INLINE_ATTRIBUTE=5]="INLINE_ATTRIBUTE",i[i.ANY=15]="ANY",i))(X||{}),qt=class{constructor(e,t,r={}){this.attrName=e,this.keyName=t;let n=X.TYPE&X.ATTRIBUTE;this.scope=r.scope!=null?r.scope&X.LEVEL|n:X.ATTRIBUTE,r.whitelist!=null&&(this.whitelist=r.whitelist)}static keys(e){return Array.from(e.attributes).map(t=>t.name)}add(e,t){return this.canAdd(e,t)?(e.setAttribute(this.keyName,t),!0):!1}canAdd(e,t){return this.whitelist==null?!0:typeof t=="string"?this.whitelist.indexOf(t.replace(/["']/g,""))>-1:this.whitelist.indexOf(t)>-1}remove(e){e.removeAttribute(this.keyName)}value(e){let t=e.getAttribute(this.keyName);return this.canAdd(e,t)&&t?t:""}},_n=class extends Error{constructor(e){e="[Parchment] "+e,super(e),this.message=e,this.name=this.constructor.name}},X8=class gf{constructor(){this.attributes={},this.classes={},this.tags={},this.types={}}static find(e,t=!1){if(e==null)return null;if(this.blots.has(e))return this.blots.get(e)||null;if(t){let r=null;try{r=e.parentNode}catch{return null}return this.find(r,t)}return null}create(e,t,r){let n=this.query(t);if(n==null)throw new _n(`Unable to create ${t} blot`);let s=n,a=t instanceof Node||t.nodeType===Node.TEXT_NODE?t:s.create(r),o=new s(e,a,r);return gf.blots.set(o.domNode,o),o}find(e,t=!1){return gf.find(e,t)}query(e,t=X.ANY){let r;return typeof e=="string"?r=this.types[e]||this.attributes[e]:e instanceof Text||e.nodeType===Node.TEXT_NODE?r=this.types.text:typeof e=="number"?e&X.LEVEL&X.BLOCK?r=this.types.block:e&X.LEVEL&X.INLINE&&(r=this.types.inline):e instanceof Element&&((e.getAttribute("class")||"").split(/\s+/).some(n=>(r=this.classes[n],!!r)),r=r||this.tags[e.tagName]),r==null?null:"scope"in r&&t&X.LEVEL&r.scope&&t&X.TYPE&r.scope?r:null}register(...e){return e.map(t=>{let r="blotName"in t,n="attrName"in t;if(!r&&!n)throw new _n("Invalid definition");if(r&&t.blotName==="abstract")throw new _n("Cannot register abstract class");let s=r?t.blotName:n?t.attrName:void 0;return this.types[s]=t,n?typeof t.keyName=="string"&&(this.attributes[t.keyName]=t):r&&(t.className&&(this.classes[t.className]=t),t.tagName&&(Array.isArray(t.tagName)?t.tagName=t.tagName.map(a=>a.toUpperCase()):t.tagName=t.tagName.toUpperCase(),(Array.isArray(t.tagName)?t.tagName:[t.tagName]).forEach(a=>{(this.tags[a]==null||t.className==null)&&(this.tags[a]=t)}))),t})}};X8.blots=new WeakMap;Ln=X8;xf=class extends qt{static keys(e){return(e.getAttribute("class")||"").split(/\s+/).map(t=>t.split("-").slice(0,-1).join("-"))}add(e,t){return this.canAdd(e,t)?(this.remove(e),e.classList.add(`${this.keyName}-${t}`),!0):!1}remove(e){W8(e,this.keyName).forEach(t=>{e.classList.remove(t)}),e.classList.length===0&&e.removeAttribute("class")}value(e){let t=(W8(e,this.keyName)[0]||"").slice(this.keyName.length+1);return this.canAdd(e,t)?t:""}},ht=xf;yf=class extends qt{static keys(e){return(e.getAttribute("style")||"").split(";").map(t=>t.split(":")[0].trim())}add(e,t){return this.canAdd(e,t)?(e.style[pf(this.keyName)]=t,!0):!1}remove(e){e.style[pf(this.keyName)]="",e.getAttribute("style")||e.removeAttribute("style")}value(e){let t=e.style[pf(this.keyName)];return this.canAdd(e,t)?t:""}},si=yf,vf=class{constructor(e){this.attributes={},this.domNode=e,this.build()}attribute(e,t){t?e.add(this.domNode,t)&&(e.value(this.domNode)!=null?this.attributes[e.attrName]=e:delete this.attributes[e.attrName]):(e.remove(this.domNode),delete this.attributes[e.attrName])}build(){this.attributes={};let e=Ln.find(this.domNode);if(e==null)return;let t=qt.keys(this.domNode),r=ht.keys(this.domNode),n=si.keys(this.domNode);t.concat(r).concat(n).forEach(s=>{let a=e.scroll.query(s,X.ATTRIBUTE);a instanceof qt&&(this.attributes[a.attrName]=a)})}copy(e){Object.keys(this.attributes).forEach(t=>{let r=this.attributes[t].value(this.domNode);e.format(t,r)})}move(e){this.copy(e),Object.keys(this.attributes).forEach(t=>{this.attributes[t].remove(this.domNode)}),this.attributes={}}values(){return Object.keys(this.attributes).reduce((e,t)=>(e[t]=this.attributes[t].value(this.domNode),e),{})}},yl=vf,K8=class{constructor(e,t){this.scroll=e,this.domNode=t,Ln.blots.set(t,this),this.prev=null,this.next=null}static create(e){if(this.tagName==null)throw new _n("Blot definition missing tagName");let t,r;return Array.isArray(this.tagName)?(typeof e=="string"?(r=e.toUpperCase(),parseInt(r,10).toString()===r&&(r=parseInt(r,10))):typeof e=="number"&&(r=e),typeof r=="number"?t=document.createElement(this.tagName[r-1]):r&&this.tagName.indexOf(r)>-1?t=document.createElement(r):t=document.createElement(this.tagName[0])):t=document.createElement(this.tagName),this.className&&t.classList.add(this.className),t}get statics(){return this.constructor}attach(){}clone(){let e=this.domNode.cloneNode(!1);return this.scroll.create(e)}detach(){this.parent!=null&&this.parent.removeChild(this),Ln.blots.delete(this.domNode)}deleteAt(e,t){this.isolate(e,t).remove()}formatAt(e,t,r,n){let s=this.isolate(e,t);if(this.scroll.query(r,X.BLOT)!=null&&n)s.wrap(r,n);else if(this.scroll.query(r,X.ATTRIBUTE)!=null){let a=this.scroll.create(this.statics.scope);s.wrap(a),a.format(r,n)}}insertAt(e,t,r){let n=r==null?this.scroll.create("text",t):this.scroll.create(t,r),s=this.split(e);this.parent.insertBefore(n,s||void 0)}isolate(e,t){let r=this.split(e);if(r==null)throw new Error("Attempt to isolate at end");return r.split(t),r}length(){return 1}offset(e=this.parent){return this.parent==null||this===e?0:this.parent.children.offset(this)+this.parent.offset(e)}optimize(e){this.statics.requiredContainer&&!(this.parent instanceof this.statics.requiredContainer)&&this.wrap(this.statics.requiredContainer.blotName)}remove(){this.domNode.parentNode!=null&&this.domNode.parentNode.removeChild(this.domNode),this.detach()}replaceWith(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;return this.parent!=null&&(this.parent.insertBefore(r,this.next||void 0),this.remove()),r}split(e,t){return e===0?this:this.next}update(e,t){}wrap(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;if(this.parent!=null&&this.parent.insertBefore(r,this.next||void 0),typeof r.appendChild!="function")throw new _n(`Cannot wrap ${e}`);return r.appendChild(this),r}};K8.blotName="abstract";Z8=K8,Q8=class extends Z8{static value(e){return!0}index(e,t){return this.domNode===e||this.domNode.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_CONTAINED_BY?Math.min(t,1):-1}position(e,t){let r=Array.from(this.parent.domNode.childNodes).indexOf(this.domNode);return e>0&&(r+=1),[this.parent.domNode,r]}value(){return{[this.statics.blotName]:this.statics.value(this.domNode)||!0}}};Q8.scope=X.INLINE_BLOT;Mz=Q8,dt=Mz,bf=class{constructor(){this.head=null,this.tail=null,this.length=0}append(...e){if(this.insertBefore(e[0],null),e.length>1){let t=e.slice(1);this.append(...t)}}at(e){let t=this.iterator(),r=t();for(;r&&e>0;)e-=1,r=t();return r}contains(e){let t=this.iterator(),r=t();for(;r;){if(r===e)return!0;r=t()}return!1}indexOf(e){let t=this.iterator(),r=t(),n=0;for(;r;){if(r===e)return n;n+=1,r=t()}return-1}insertBefore(e,t){e!=null&&(this.remove(e),e.next=t,t!=null?(e.prev=t.prev,t.prev!=null&&(t.prev.next=e),t.prev=e,t===this.head&&(this.head=e)):this.tail!=null?(this.tail.next=e,e.prev=this.tail,this.tail=e):(e.prev=null,this.head=this.tail=e),this.length+=1)}offset(e){let t=0,r=this.head;for(;r!=null;){if(r===e)return t;t+=r.length(),r=r.next}return-1}remove(e){this.contains(e)&&(e.prev!=null&&(e.prev.next=e.next),e.next!=null&&(e.next.prev=e.prev),e===this.head&&(this.head=e.next),e===this.tail&&(this.tail=e.prev),this.length-=1)}iterator(e=this.head){return()=>{let t=e;return e!=null&&(e=e.next),t}}find(e,t=!1){let r=this.iterator(),n=r();for(;n;){let s=n.length();if(ea?r(l,e-a,Math.min(t,a+h-e)):r(l,0,Math.min(h,e+t-a)),a+=h,l=o()}}map(e){return this.reduce((t,r)=>(t.push(e(r)),t),[])}reduce(e,t){let r=this.iterator(),n=r();for(;n;)t=e(t,n),n=r();return t}};J8=class Cn extends Z8{constructor(e,t){super(e,t),this.uiNode=null,this.build()}appendChild(e){this.insertBefore(e)}attach(){super.attach(),this.children.forEach(e=>{e.attach()})}attachUI(e){this.uiNode!=null&&this.uiNode.remove(),this.uiNode=e,Cn.uiClass&&this.uiNode.classList.add(Cn.uiClass),this.uiNode.setAttribute("contenteditable","false"),this.domNode.insertBefore(this.uiNode,this.domNode.firstChild)}build(){this.children=new bf,Array.from(this.domNode.childNodes).filter(e=>e!==this.uiNode).reverse().forEach(e=>{try{let t=Y8(e,this.scroll);this.insertBefore(t,this.children.head||void 0)}catch(t){if(t instanceof _n)return;throw t}})}deleteAt(e,t){if(e===0&&t===this.length())return this.remove();this.children.forEachAt(e,t,(r,n,s)=>{r.deleteAt(n,s)})}descendant(e,t=0){let[r,n]=this.children.find(t);return e.blotName==null&&e(r)||e.blotName!=null&&r instanceof e?[r,n]:r instanceof Cn?r.descendant(e,n):[null,-1]}descendants(e,t=0,r=Number.MAX_VALUE){let n=[],s=r;return this.children.forEachAt(t,r,(a,o,l)=>{(e.blotName==null&&e(a)||e.blotName!=null&&a instanceof e)&&n.push(a),a instanceof Cn&&(n=n.concat(a.descendants(e,o,s))),s-=l}),n}detach(){this.children.forEach(e=>{e.detach()}),super.detach()}enforceAllowedChildren(){let e=!1;this.children.forEach(t=>{e||this.statics.allowedChildren.some(r=>t instanceof r)||(t.statics.scope===X.BLOCK_BLOT?(t.next!=null&&this.splitAfter(t),t.prev!=null&&this.splitAfter(t.prev),t.parent.unwrap(),e=!0):t instanceof Cn?t.unwrap():t.remove())})}formatAt(e,t,r,n){this.children.forEachAt(e,t,(s,a,o)=>{s.formatAt(a,o,r,n)})}insertAt(e,t,r){let[n,s]=this.children.find(e);if(n)n.insertAt(s,t,r);else{let a=r==null?this.scroll.create("text",t):this.scroll.create(t,r);this.appendChild(a)}}insertBefore(e,t){e.parent!=null&&e.parent.children.remove(e);let r=null;this.children.insertBefore(e,t||null),e.parent=this,t!=null&&(r=t.domNode),(this.domNode.parentNode!==e.domNode||this.domNode.nextSibling!==r)&&this.domNode.insertBefore(e.domNode,r),e.attach()}length(){return this.children.reduce((e,t)=>e+t.length(),0)}moveChildren(e,t){this.children.forEach(r=>{e.insertBefore(r,t)})}optimize(e){if(super.optimize(e),this.enforceAllowedChildren(),this.uiNode!=null&&this.uiNode!==this.domNode.firstChild&&this.domNode.insertBefore(this.uiNode,this.domNode.firstChild),this.children.length===0)if(this.statics.defaultChild!=null){let t=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(t)}else this.remove()}path(e,t=!1){let[r,n]=this.children.find(e,t),s=[[this,e]];return r instanceof Cn?s.concat(r.path(n,t)):(r!=null&&s.push([r,n]),s)}removeChild(e){this.children.remove(e)}replaceWith(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;return r instanceof Cn&&this.moveChildren(r),super.replaceWith(r)}split(e,t=!1){if(!t){if(e===0)return this;if(e===this.length())return this.next}let r=this.clone();return this.parent&&this.parent.insertBefore(r,this.next||void 0),this.children.forEachAt(e,this.length(),(n,s,a)=>{let o=n.split(s,t);o!=null&&r.appendChild(o)}),r}splitAfter(e){let t=this.clone();for(;e.next!=null;)t.appendChild(e.next);return this.parent&&this.parent.insertBefore(t,this.next||void 0),t}unwrap(){this.parent&&this.moveChildren(this.parent,this.next||void 0),this.remove()}update(e,t){let r=[],n=[];e.forEach(s=>{s.target===this.domNode&&s.type==="childList"&&(r.push(...s.addedNodes),n.push(...s.removedNodes))}),n.forEach(s=>{if(s.parentNode!=null&&s.tagName!=="IFRAME"&&document.body.compareDocumentPosition(s)&Node.DOCUMENT_POSITION_CONTAINED_BY)return;let a=this.scroll.find(s);a!=null&&(a.domNode.parentNode==null||a.domNode.parentNode===this.domNode)&&a.detach()}),r.filter(s=>s.parentNode===this.domNode&&s!==this.uiNode).sort((s,a)=>s===a?0:s.compareDocumentPosition(a)&Node.DOCUMENT_POSITION_FOLLOWING?1:-1).forEach(s=>{let a=null;s.nextSibling!=null&&(a=this.scroll.find(s.nextSibling));let o=Y8(s,this.scroll);(o.next!==a||o.next==null)&&(o.parent!=null&&o.parent.removeChild(this),this.insertBefore(o,a||void 0))}),this.enforceAllowedChildren()}};J8.uiClass="";Tz=J8,ni=Tz;Oa=class Ba extends ni{static create(e){return super.create(e)}static formats(e,t){let r=t.query(Ba.blotName);if(!(r!=null&&e.tagName===r.tagName)){if(typeof this.tagName=="string")return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(e,t){super(e,t),this.attributes=new yl(this.domNode)}format(e,t){if(e===this.statics.blotName&&!t)this.children.forEach(r=>{r instanceof Ba||(r=r.wrap(Ba.blotName,!0)),this.attributes.copy(r)}),this.unwrap();else{let r=this.scroll.query(e,X.INLINE);if(r==null)return;r instanceof qt?this.attributes.attribute(r,t):t&&(e!==this.statics.blotName||this.formats()[e]!==t)&&this.replaceWith(e,t)}}formats(){let e=this.attributes.values(),t=this.statics.formats(this.domNode,this.scroll);return t!=null&&(e[this.statics.blotName]=t),e}formatAt(e,t,r,n){this.formats()[r]!=null||this.scroll.query(r,X.ATTRIBUTE)?this.isolate(e,t).format(r,n):super.formatAt(e,t,r,n)}optimize(e){super.optimize(e);let t=this.formats();if(Object.keys(t).length===0)return this.unwrap();let r=this.next;r instanceof Ba&&r.prev===this&&Nz(t,r.formats())&&(r.moveChildren(this),r.remove())}replaceWith(e,t){let r=super.replaceWith(e,t);return this.attributes.copy(r),r}update(e,t){super.update(e,t),e.some(r=>r.target===this.domNode&&r.type==="attributes")&&this.attributes.build()}wrap(e,t){let r=super.wrap(e,t);return r instanceof Ba&&this.attributes.move(r),r}};Oa.allowedChildren=[Oa,dt],Oa.blotName="inline",Oa.scope=X.INLINE_BLOT,Oa.tagName="SPAN";Ez=Oa,bd=Ez,Pa=class wf extends ni{static create(e){return super.create(e)}static formats(e,t){let r=t.query(wf.blotName);if(!(r!=null&&e.tagName===r.tagName)){if(typeof this.tagName=="string")return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(e,t){super(e,t),this.attributes=new yl(this.domNode)}format(e,t){let r=this.scroll.query(e,X.BLOCK);r!=null&&(r instanceof qt?this.attributes.attribute(r,t):e===this.statics.blotName&&!t?this.replaceWith(wf.blotName):t&&(e!==this.statics.blotName||this.formats()[e]!==t)&&this.replaceWith(e,t))}formats(){let e=this.attributes.values(),t=this.statics.formats(this.domNode,this.scroll);return t!=null&&(e[this.statics.blotName]=t),e}formatAt(e,t,r,n){this.scroll.query(r,X.BLOCK)!=null?this.format(r,n):super.formatAt(e,t,r,n)}insertAt(e,t,r){if(r==null||this.scroll.query(t,X.INLINE)!=null)super.insertAt(e,t,r);else{let n=this.split(e);if(n!=null){let s=this.scroll.create(t,r);n.parent.insertBefore(s,n)}else throw new Error("Attempt to insertAt after block boundaries")}}replaceWith(e,t){let r=super.replaceWith(e,t);return this.attributes.copy(r),r}update(e,t){super.update(e,t),e.some(r=>r.target===this.domNode&&r.type==="attributes")&&this.attributes.build()}};Pa.blotName="block",Pa.scope=X.BLOCK_BLOT,Pa.tagName="P",Pa.allowedChildren=[bd,Pa,dt];Sz=Pa,vs=Sz,Mf=class extends ni{checkMerge(){return this.next!==null&&this.next.statics.blotName===this.statics.blotName}deleteAt(e,t){super.deleteAt(e,t),this.enforceAllowedChildren()}formatAt(e,t,r,n){super.formatAt(e,t,r,n),this.enforceAllowedChildren()}insertAt(e,t,r){super.insertAt(e,t,r),this.enforceAllowedChildren()}optimize(e){super.optimize(e),this.children.length>0&&this.next!=null&&this.checkMerge()&&(this.next.moveChildren(this),this.next.remove())}};Mf.blotName="container",Mf.scope=X.BLOCK_BLOT;Az=Mf,qa=Az,Tf=class extends dt{static formats(e,t){}format(e,t){super.formatAt(0,this.length(),e,t)}formatAt(e,t,r,n){e===0&&t===this.length()?this.format(r,n):super.formatAt(e,t,r,n)}formats(){return this.statics.formats(this.domNode,this.scroll)}},Ke=Tf,kz={attributes:!0,characterData:!0,characterDataOldValue:!0,childList:!0,subtree:!0},Cz=100,Fa=class extends ni{constructor(e,t){super(null,t),this.registry=e,this.scroll=this,this.build(),this.observer=new MutationObserver(r=>{this.update(r)}),this.observer.observe(this.domNode,kz),this.attach()}create(e,t){return this.registry.create(this,e,t)}find(e,t=!1){let r=this.registry.find(e,t);return r?r.scroll===this?r:t?this.find(r.scroll.domNode.parentNode,!0):null:null}query(e,t=X.ANY){return this.registry.query(e,t)}register(...e){return this.registry.register(...e)}build(){this.scroll!=null&&super.build()}detach(){super.detach(),this.observer.disconnect()}deleteAt(e,t){this.update(),e===0&&t===this.length()?this.children.forEach(r=>{r.remove()}):super.deleteAt(e,t)}formatAt(e,t,r,n){this.update(),super.formatAt(e,t,r,n)}insertAt(e,t,r){this.update(),super.insertAt(e,t,r)}optimize(e=[],t={}){super.optimize(t);let r=t.mutationsMap||new WeakMap,n=Array.from(this.observer.takeRecords());for(;n.length>0;)e.push(n.pop());let s=(l,h=!0)=>{l==null||l===this||l.domNode.parentNode!=null&&(r.has(l.domNode)||r.set(l.domNode,[]),h&&s(l.parent))},a=l=>{r.has(l.domNode)&&(l instanceof ni&&l.children.forEach(a),r.delete(l.domNode),l.optimize(t))},o=e;for(let l=0;o.length>0;l+=1){if(l>=Cz)throw new Error("[Parchment] Maximum optimize iterations reached");for(o.forEach(h=>{let d=this.find(h.target,!0);d!=null&&(d.domNode===h.target&&(h.type==="childList"?(s(this.find(h.previousSibling,!1)),Array.from(h.addedNodes).forEach(c=>{let f=this.find(c,!1);s(f,!1),f instanceof ni&&f.children.forEach(m=>{s(m,!1)})})):h.type==="attributes"&&s(d.prev)),s(d))}),this.children.forEach(a),o=Array.from(this.observer.takeRecords()),n=o.slice();n.length>0;)e.push(n.pop())}}update(e,t={}){e=e||this.observer.takeRecords();let r=new WeakMap;e.map(n=>{let s=this.find(n.target,!0);return s==null?null:r.has(s.domNode)?(r.get(s.domNode).push(n),null):(r.set(s.domNode,[n]),s)}).forEach(n=>{n!=null&&n!==this&&r.has(n.domNode)&&n.update(r.get(n.domNode)||[],t)}),t.mutationsMap=r,r.has(this.domNode)&&super.update(r.get(this.domNode),t),this.optimize(e,t)}};Fa.blotName="scroll",Fa.defaultChild=vs,Fa.allowedChildren=[vs,qa],Fa.scope=X.BLOCK_BLOT,Fa.tagName="DIV";_z=Fa,vl=_z,Nf=class ex extends dt{static create(e){return document.createTextNode(e)}static value(e){return e.data}constructor(e,t){super(e,t),this.text=this.statics.value(this.domNode)}deleteAt(e,t){this.domNode.data=this.text=this.text.slice(0,e)+this.text.slice(e+t)}index(e,t){return this.domNode===e?t:-1}insertAt(e,t,r){r==null?(this.text=this.text.slice(0,e)+t+this.text.slice(e),this.domNode.data=this.text):super.insertAt(e,t,r)}length(){return this.text.length}optimize(e){super.optimize(e),this.text=this.statics.value(this.domNode),this.text.length===0?this.remove():this.next instanceof ex&&this.next.prev===this&&(this.insertAt(this.length(),this.next.value()),this.next.remove())}position(e,t=!1){return[this.domNode,e]}split(e,t=!1){if(!t){if(e===0)return this;if(e===this.length())return this.next}let r=this.scroll.create(this.domNode.splitText(e));return this.parent.insertBefore(r,this.next||void 0),this.text=this.statics.value(this.domNode),r}update(e,t){e.some(r=>r.type==="characterData"&&r.target===this.domNode)&&(this.text=this.statics.value(this.domNode))}value(){return this.text}};Nf.blotName="text",Nf.scope=X.INLINE_BLOT;Lz=Nf,Ha=Lz});var cx=rr((FZ,dx)=>{var mi=-1,Ht=1,ut=0;function wl(i,e,t,r,n){if(i===e)return i?[[ut,i]]:[];if(t!=null){var s=qz(i,e,t);if(s)return s}var a=Sf(i,e),o=i.substring(0,a);i=i.substring(a),e=e.substring(a),a=wd(i,e);var l=i.substring(i.length-a);i=i.substring(0,i.length-a),e=e.substring(0,e.length-a);var h=Iz(i,e);return o&&h.unshift([ut,o]),l&&h.push([ut,l]),Af(h,n),r&&Dz(h),h}function Iz(i,e){var t;if(!i)return[[Ht,e]];if(!e)return[[mi,i]];var r=i.length>e.length?i:e,n=i.length>e.length?e:i,s=r.indexOf(n);if(s!==-1)return t=[[Ht,r.substring(0,s)],[ut,n],[Ht,r.substring(s+n.length)]],i.length>e.length&&(t[0][0]=t[2][0]=mi),t;if(n.length===1)return[[mi,i],[Ht,e]];var a=Rz(i,e);if(a){var o=a[0],l=a[1],h=a[2],d=a[3],c=a[4],f=wl(o,h),m=wl(l,d);return f.concat([[ut,c]],m)}return zz(i,e)}function zz(i,e){for(var t=i.length,r=e.length,n=Math.ceil((t+r)/2),s=n,a=2*n,o=new Array(a),l=new Array(a),h=0;ht)m+=2;else if(C>r)f+=2;else if(c){var I=s+d-b;if(I>=0&&I=O)return tx(i,e,A,C)}}}for(var q=-y+g;q<=y-x;q+=2){var I=s+q,O;q===-y||q!==y&&l[I-1]t)x+=2;else if(P>r)g+=2;else if(!c){var S=s+d-q;if(S>=0&&S=O)return tx(i,e,A,C)}}}}return[[mi,i],[Ht,e]]}function tx(i,e,t,r){var n=i.substring(0,t),s=e.substring(0,r),a=i.substring(t),o=e.substring(r),l=wl(n,s),h=wl(a,o);return l.concat(h)}function Sf(i,e){if(!i||!e||i.charAt(0)!==e.charAt(0))return 0;for(var t=0,r=Math.min(i.length,e.length),n=r,s=0;tr?i=i.substring(t-r):te.length?i:e,r=i.length>e.length?e:i;if(t.length<4||r.length*2=m.length?[A,C,I,O,S]:null}var s=n(t,r,Math.ceil(t.length/4)),a=n(t,r,Math.ceil(t.length/2)),o;if(!s&&!a)return null;a?s?o=s[4].length>a[4].length?s:a:o=a:o=s;var l,h,d,c;i.length>e.length?(l=o[0],h=o[1],d=o[2],c=o[3]):(d=o[0],c=o[1],l=o[2],h=o[3]);var f=o[4];return[l,h,d,c,f]}function Dz(i){for(var e=!1,t=[],r=0,n=null,s=0,a=0,o=0,l=0,h=0;s0?t[r-1]:-1,a=0,o=0,l=0,h=0,n=null,e=!0)),s++;for(e&&Af(i),Pz(i),s=1;s=m?(f>=d.length/2||f>=c.length/2)&&(i.splice(s,0,[ut,c.substring(0,f)]),i[s-1][1]=d.substring(0,d.length-f),i[s+1][1]=c.substring(f),s++):(m>=d.length/2||m>=c.length/2)&&(i.splice(s,0,[ut,d.substring(0,m)]),i[s-1][0]=Ht,i[s-1][1]=c.substring(0,c.length-m),i[s+1][0]=mi,i[s+1][1]=d.substring(m),s++),s++}s++}}var rx=/[^a-zA-Z0-9]/,nx=/\s/,sx=/[\r\n]/,Oz=/\n\r?\n$/,Bz=/^\r?\n\r?\n/;function Pz(i){function e(m,g){if(!m||!g)return 6;var x=m.charAt(m.length-1),y=g.charAt(0),b=x.match(rx),S=y.match(rx),A=b&&x.match(nx),C=S&&y.match(nx),I=A&&x.match(sx),O=C&&y.match(sx),q=I&&m.match(Oz),P=O&&g.match(Bz);return q||P?5:I||O?4:b&&!A&&C?3:A||C?2:b||S?1:0}for(var t=1;t=c&&(c=f,l=r,h=n,d=s)}i[t-1][1]!=l&&(l?i[t-1][1]=l:(i.splice(t-1,1),t--),i[t][1]=h,d?i[t+1][1]=d:(i.splice(t+1,1),t--))}t++}}function Af(i,e){i.push([ut,""]);for(var t=0,r=0,n=0,s="",a="",o;t=0&&hx(i[l][1])){var h=i[l][1].slice(-1);if(i[l][1]=i[l][1].slice(0,-1),s=h+s,a=h+a,!i[l][1]){i.splice(l,1),t--;var d=l-1;i[d]&&i[d][0]===Ht&&(n++,a=i[d][1]+a,d--),i[d]&&i[d][0]===mi&&(r++,s=i[d][1]+s,d--),l=d}}if(lx(i[t][1])){var h=i[t][1].charAt(0);i[t][1]=i[t][1].slice(1),s+=h,a+=h}}if(t0||a.length>0){s.length>0&&a.length>0&&(o=Sf(a,s),o!==0&&(l>=0?i[l][1]+=a.substring(0,o):(i.splice(0,0,[ut,a.substring(0,o)]),t++),a=a.substring(o),s=s.substring(o)),o=wd(a,s),o!==0&&(i[t][1]=a.substring(a.length-o)+i[t][1],a=a.substring(0,a.length-o),s=s.substring(0,s.length-o)));var c=n+r;s.length===0&&a.length===0?(i.splice(t-c,c),t=t-c):s.length===0?(i.splice(t-c,c,[Ht,a]),t=t-c+1):a.length===0?(i.splice(t-c,c,[mi,s]),t=t-c+1):(i.splice(t-c,c,[mi,s],[Ht,a]),t=t-c+2)}t!==0&&i[t-1][0]===ut?(i[t-1][1]+=i[t][1],i.splice(t,1)):t++,n=0,r=0,s="",a="";break}}i[i.length-1][1]===""&&i.pop();var f=!1;for(t=1;t=55296&&i<=56319}function ox(i){return i>=56320&&i<=57343}function lx(i){return ox(i.charCodeAt(0))}function hx(i){return ax(i.charCodeAt(i.length-1))}function Fz(i){for(var e=[],t=0;t0&&e.push(i[t]);return e}function Ef(i,e,t,r){return hx(i)||lx(r)?null:Fz([[ut,i],[mi,e],[Ht,t],[ut,r]])}function qz(i,e,t){var r=typeof t=="number"?{index:t,length:0}:t.oldRange,n=typeof t=="number"?null:t.newRange,s=i.length,a=e.length;if(r.length===0&&(n===null||n.length===0)){var o=r.index,l=i.slice(0,o),h=i.slice(o),d=n?n.index:null;e:{var c=o+a-s;if(d!==null&&d!==c||c<0||c>a)break e;var f=e.slice(0,c),m=e.slice(c);if(m!==h)break e;var g=Math.min(o,c),x=l.slice(0,g),y=f.slice(0,g);if(x!==y)break e;var b=l.slice(g),S=f.slice(g);return Ef(x,b,S,h)}e:{if(d!==null&&d!==o)break e;var A=o,f=e.slice(0,A),m=e.slice(A);if(f!==l)break e;var C=Math.min(s-A,a-A),I=h.slice(h.length-C),O=m.slice(m.length-C);if(I!==O)break e;var b=h.slice(0,h.length-C),S=m.slice(0,m.length-C);return Ef(l,b,S,I)}}if(r.length>0&&n&&n.length===0)e:{var x=i.slice(0,r.index),I=i.slice(r.index+r.length),g=x.length,C=I.length;if(a{var Hz=200,Tx="__lodash_hash_undefined__",Nx=9007199254740991,Df="[object Arguments]",Uz="[object Array]",Ex="[object Boolean]",Sx="[object Date]",$z="[object Error]",Of="[object Function]",Ax="[object GeneratorFunction]",Td="[object Map]",kx="[object Number]",Bf="[object Object]",ux="[object Promise]",Cx="[object RegExp]",Nd="[object Set]",_x="[object String]",Lx="[object Symbol]",Cf="[object WeakMap]",Ix="[object ArrayBuffer]",Ed="[object DataView]",zx="[object Float32Array]",Rx="[object Float64Array]",Dx="[object Int8Array]",Ox="[object Int16Array]",Bx="[object Int32Array]",Px="[object Uint8Array]",Fx="[object Uint8ClampedArray]",qx="[object Uint16Array]",Hx="[object Uint32Array]",jz=/[\\^$.*+?()[\]{}|]/g,Gz=/\w*$/,Vz=/^\[object .+?Constructor\]$/,Wz=/^(?:0|[1-9]\d*)$/,Pe={};Pe[Df]=Pe[Uz]=Pe[Ix]=Pe[Ed]=Pe[Ex]=Pe[Sx]=Pe[zx]=Pe[Rx]=Pe[Dx]=Pe[Ox]=Pe[Bx]=Pe[Td]=Pe[kx]=Pe[Bf]=Pe[Cx]=Pe[Nd]=Pe[_x]=Pe[Lx]=Pe[Px]=Pe[Fx]=Pe[qx]=Pe[Hx]=!0;Pe[$z]=Pe[Of]=Pe[Cf]=!1;var Yz=typeof global=="object"&&global&&global.Object===Object&&global,Xz=typeof self=="object"&&self&&self.Object===Object&&self,$r=Yz||Xz||Function("return this")(),Ux=typeof Ml=="object"&&Ml&&!Ml.nodeType&&Ml,fx=Ux&&typeof Ua=="object"&&Ua&&!Ua.nodeType&&Ua,Kz=fx&&fx.exports===Ux;function Zz(i,e){return i.set(e[0],e[1]),i}function Qz(i,e){return i.add(e),i}function Jz(i,e){for(var t=-1,r=i?i.length:0;++t-1}function SR(i,e){var t=this.__data__,r=kd(t,i);return r<0?t.push([i,e]):t[r][1]=e,this}jr.prototype.clear=MR;jr.prototype.delete=TR;jr.prototype.get=NR;jr.prototype.has=ER;jr.prototype.set=SR;function $a(i){var e=-1,t=i?i.length:0;for(this.clear();++e-1&&i%1==0&&i-1&&i%1==0&&i<=Nx}function _d(i){var e=typeof i;return!!i&&(e=="object"||e=="function")}function cD(i){return!!i&&typeof i=="object"}function Hf(i){return Zx(i)?BR(i):$R(i)}function uD(){return[]}function fD(){return!1}Ua.exports=aD});var em=rr((El,Wa)=>{var mD=200,Jf="__lodash_hash_undefined__",Pd=1,d9=2,c9=9007199254740991,Ld="[object Arguments]",Vf="[object Array]",pD="[object AsyncFunction]",u9="[object Boolean]",f9="[object Date]",m9="[object Error]",p9="[object Function]",gD="[object GeneratorFunction]",Id="[object Map]",g9="[object Number]",xD="[object Null]",Va="[object Object]",Jx="[object Promise]",yD="[object Proxy]",x9="[object RegExp]",zd="[object Set]",y9="[object String]",vD="[object Symbol]",bD="[object Undefined]",Wf="[object WeakMap]",v9="[object ArrayBuffer]",Rd="[object DataView]",wD="[object Float32Array]",MD="[object Float64Array]",TD="[object Int8Array]",ND="[object Int16Array]",ED="[object Int32Array]",SD="[object Uint8Array]",AD="[object Uint8ClampedArray]",kD="[object Uint16Array]",CD="[object Uint32Array]",_D=/[\\^$.*+?()[\]{}|]/g,LD=/^\[object .+?Constructor\]$/,ID=/^(?:0|[1-9]\d*)$/,Ue={};Ue[wD]=Ue[MD]=Ue[TD]=Ue[ND]=Ue[ED]=Ue[SD]=Ue[AD]=Ue[kD]=Ue[CD]=!0;Ue[Ld]=Ue[Vf]=Ue[v9]=Ue[u9]=Ue[Rd]=Ue[f9]=Ue[m9]=Ue[p9]=Ue[Id]=Ue[g9]=Ue[Va]=Ue[x9]=Ue[zd]=Ue[y9]=Ue[Wf]=!1;var b9=typeof global=="object"&&global&&global.Object===Object&&global,zD=typeof self=="object"&&self&&self.Object===Object&&self,Gr=b9||zD||Function("return this")(),w9=typeof El=="object"&&El&&!El.nodeType&&El,e9=w9&&typeof Wa=="object"&&Wa&&!Wa.nodeType&&Wa,M9=e9&&e9.exports===w9,$f=M9&&b9.process,t9=(function(){try{return $f&&$f.binding&&$f.binding("util")}catch{}})(),i9=t9&&t9.isTypedArray;function RD(i,e){for(var t=-1,r=i==null?0:i.length,n=0,s=[];++t-1}function dO(i,e){var t=this.__data__,r=qd(t,i);return r<0?(++this.size,t.push([i,e])):t[r][1]=e,this}Vr.prototype.clear=aO;Vr.prototype.delete=oO;Vr.prototype.get=lO;Vr.prototype.has=hO;Vr.prototype.set=dO;function Es(i){var e=-1,t=i==null?0:i.length;for(this.clear();++eo))return!1;var h=s.get(i);if(h&&s.get(e))return h==e;var d=-1,c=!0,f=t&d9?new Od:void 0;for(s.set(i,e),s.set(e,i);++d-1&&i%1==0&&i-1&&i%1==0&&i<=c9}function L9(i){var e=typeof i;return i!=null&&(e=="object"||e=="function")}function kl(i){return i!=null&&typeof i=="object"}var I9=i9?PD(i9):AO;function HO(i){return FO(i)?TO(i):kO(i)}function UO(){return[]}function $O(){return!1}Wa.exports=qO});var z9=rr(im=>{"use strict";Object.defineProperty(im,"__esModule",{value:!0});var jO=Uf(),GO=em(),tm;(function(i){function e(s={},a={},o=!1){typeof s!="object"&&(s={}),typeof a!="object"&&(a={});let l=jO(a);o||(l=Object.keys(l).reduce((h,d)=>(l[d]!=null&&(h[d]=l[d]),h),{}));for(let h in s)s[h]!==void 0&&a[h]===void 0&&(l[h]=s[h]);return Object.keys(l).length>0?l:void 0}i.compose=e;function t(s={},a={}){typeof s!="object"&&(s={}),typeof a!="object"&&(a={});let o=Object.keys(s).concat(Object.keys(a)).reduce((l,h)=>(GO(s[h],a[h])||(l[h]=a[h]===void 0?null:a[h]),l),{});return Object.keys(o).length>0?o:void 0}i.diff=t;function r(s={},a={}){s=s||{};let o=Object.keys(a).reduce((l,h)=>(a[h]!==s[h]&&s[h]!==void 0&&(l[h]=a[h]),l),{});return Object.keys(s).reduce((l,h)=>(s[h]!==a[h]&&a[h]===void 0&&(l[h]=null),l),o)}i.invert=r;function n(s,a,o=!1){if(typeof s!="object")return a;if(typeof a!="object")return;if(!o)return a;let l=Object.keys(a).reduce((h,d)=>(s[d]===void 0&&(h[d]=a[d]),h),{});return Object.keys(l).length>0?l:void 0}i.transform=n})(tm||(tm={}));im.default=tm});var sm=rr(nm=>{"use strict";Object.defineProperty(nm,"__esModule",{value:!0});var rm;(function(i){function e(t){return typeof t.delete=="number"?t.delete:typeof t.retain=="number"?t.retain:typeof t.retain=="object"&&t.retain!==null?1:typeof t.insert=="string"?t.insert.length:1}i.length=e})(rm||(rm={}));nm.default=rm});var D9=rr(om=>{"use strict";Object.defineProperty(om,"__esModule",{value:!0});var R9=sm(),am=class{constructor(e){this.ops=e,this.index=0,this.offset=0}hasNext(){return this.peekLength()<1/0}next(e){e||(e=1/0);let t=this.ops[this.index];if(t){let r=this.offset,n=R9.default.length(t);if(e>=n-r?(e=n-r,this.index+=1,this.offset=0):this.offset+=e,typeof t.delete=="number")return{delete:e};{let s={};return t.attributes&&(s.attributes=t.attributes),typeof t.retain=="number"?s.retain=e:typeof t.retain=="object"&&t.retain!==null?s.retain=t.retain:typeof t.insert=="string"?s.insert=t.insert.substr(r,e):s.insert=t.insert,s}}else return{retain:1/0}}peek(){return this.ops[this.index]}peekLength(){return this.ops[this.index]?R9.default.length(this.ops[this.index])-this.offset:1/0}peekType(){let e=this.ops[this.index];return e?typeof e.delete=="number"?"delete":typeof e.retain=="number"||typeof e.retain=="object"&&e.retain!==null?"retain":"insert":"retain"}rest(){if(this.hasNext()){if(this.offset===0)return this.ops.slice(this.index);{let e=this.offset,t=this.index,r=this.next(),n=this.ops.slice(this.index);return this.offset=e,this.index=t,[r].concat(n)}}else return[]}};om.default=am});var pi=rr((Yr,$d)=>{"use strict";Object.defineProperty(Yr,"__esModule",{value:!0});Yr.AttributeMap=Yr.OpIterator=Yr.Op=void 0;var Ud=cx(),VO=Uf(),lm=em(),As=z9();Yr.AttributeMap=As.default;var Wr=sm();Yr.Op=Wr.default;var Ii=D9();Yr.OpIterator=Ii.default;var WO="\0",O9=(i,e)=>{if(typeof i!="object"||i===null)throw new Error(`cannot retain a ${typeof i}`);if(typeof e!="object"||e===null)throw new Error(`cannot retain a ${typeof e}`);let t=Object.keys(i)[0];if(!t||t!==Object.keys(e)[0])throw new Error(`embed types not matched: ${t} != ${Object.keys(e)[0]}`);return[t,i[t],e[t]]},Xr=class i{constructor(e){Array.isArray(e)?this.ops=e:e!=null&&Array.isArray(e.ops)?this.ops=e.ops:this.ops=[]}static registerEmbed(e,t){this.handlers[e]=t}static unregisterEmbed(e){delete this.handlers[e]}static getHandler(e){let t=this.handlers[e];if(!t)throw new Error(`no handlers for embed type "${e}"`);return t}insert(e,t){let r={};return typeof e=="string"&&e.length===0?this:(r.insert=e,t!=null&&typeof t=="object"&&Object.keys(t).length>0&&(r.attributes=t),this.push(r))}delete(e){return e<=0?this:this.push({delete:e})}retain(e,t){if(typeof e=="number"&&e<=0)return this;let r={retain:e};return t!=null&&typeof t=="object"&&Object.keys(t).length>0&&(r.attributes=t),this.push(r)}push(e){let t=this.ops.length,r=this.ops[t-1];if(e=VO(e),typeof r=="object"){if(typeof e.delete=="number"&&typeof r.delete=="number")return this.ops[t-1]={delete:r.delete+e.delete},this;if(typeof r.delete=="number"&&e.insert!=null&&(t-=1,r=this.ops[t-1],typeof r!="object"))return this.ops.unshift(e),this;if(lm(e.attributes,r.attributes)){if(typeof e.insert=="string"&&typeof r.insert=="string")return this.ops[t-1]={insert:r.insert+e.insert},typeof e.attributes=="object"&&(this.ops[t-1].attributes=e.attributes),this;if(typeof e.retain=="number"&&typeof r.retain=="number")return this.ops[t-1]={retain:r.retain+e.retain},typeof e.attributes=="object"&&(this.ops[t-1].attributes=e.attributes),this}}return t===this.ops.length?this.ops.push(e):this.ops.splice(t,0,e),this}chop(){let e=this.ops[this.ops.length-1];return e&&typeof e.retain=="number"&&!e.attributes&&this.ops.pop(),this}filter(e){return this.ops.filter(e)}forEach(e){this.ops.forEach(e)}map(e){return this.ops.map(e)}partition(e){let t=[],r=[];return this.forEach(n=>{(e(n)?t:r).push(n)}),[t,r]}reduce(e,t){return this.ops.reduce(e,t)}changeLength(){return this.reduce((e,t)=>t.insert?e+Wr.default.length(t):t.delete?e-t.delete:e,0)}length(){return this.reduce((e,t)=>e+Wr.default.length(t),0)}slice(e=0,t=1/0){let r=[],n=new Ii.default(this.ops),s=0;for(;s0&&r.next(s.retain-o)}let a=new i(n);for(;t.hasNext()||r.hasNext();)if(r.peekType()==="insert")a.push(r.next());else if(t.peekType()==="delete")a.push(t.next());else{let o=Math.min(t.peekLength(),r.peekLength()),l=t.next(o),h=r.next(o);if(h.retain){let d={};if(typeof l.retain=="number")d.retain=typeof h.retain=="number"?o:h.retain;else if(typeof h.retain=="number")l.retain==null?d.insert=l.insert:d.retain=l.retain;else{let f=l.retain==null?"insert":"retain",[m,g,x]=O9(l[f],h.retain),y=i.getHandler(m);d[f]={[m]:y.compose(g,x,f==="retain")}}let c=As.default.compose(l.attributes,h.attributes,typeof l.retain=="number");if(c&&(d.attributes=c),a.push(d),!r.hasNext()&&lm(a.ops[a.ops.length-1],d)){let f=new i(t.rest());return a.concat(f).chop()}}else typeof h.delete=="number"&&(typeof l.retain=="number"||typeof l.retain=="object"&&l.retain!==null)&&a.push(h)}return a.chop()}concat(e){let t=new i(this.ops.slice());return e.ops.length>0&&(t.push(e.ops[0]),t.ops=t.ops.concat(e.ops.slice(1))),t}diff(e,t){if(this.ops===e.ops)return new i;let r=[this,e].map(l=>l.map(h=>{if(h.insert!=null)return typeof h.insert=="string"?h.insert:WO;let d=l===e?"on":"with";throw new Error("diff() called "+d+" non-document")}).join("")),n=new i,s=Ud(r[0],r[1],t,!0),a=new Ii.default(this.ops),o=new Ii.default(e.ops);return s.forEach(l=>{let h=l[1].length;for(;h>0;){let d=0;switch(l[0]){case Ud.INSERT:d=Math.min(o.peekLength(),h),n.push(o.next(d));break;case Ud.DELETE:d=Math.min(h,a.peekLength()),a.next(d),n.delete(d);break;case Ud.EQUAL:d=Math.min(a.peekLength(),o.peekLength(),h);let c=a.next(d),f=o.next(d);lm(c.insert,f.insert)?n.retain(d,As.default.diff(c.attributes,f.attributes)):n.push(f).delete(d);break}h-=d}}),n.chop()}eachLine(e,t=` -`){let r=new Ii.default(this.ops),n=new i,s=0;for(;r.hasNext();){if(r.peekType()!=="insert")return;let a=r.peek(),o=Wr.default.length(a)-r.peekLength(),l=typeof a.insert=="string"?a.insert.indexOf(t,o)-o:-1;if(l<0)n.push(r.next());else if(l>0)n.push(r.next(l));else{if(e(n,r.next(1).attributes||{},s)===!1)return;s+=1,n=new i}}n.length()>0&&e(n,{},s)}invert(e){let t=new i;return this.reduce((r,n)=>{if(n.insert)t.delete(Wr.default.length(n));else{if(typeof n.retain=="number"&&n.attributes==null)return t.retain(n.retain),r+n.retain;if(n.delete||typeof n.retain=="number"){let s=n.delete||n.retain;return e.slice(r,r+s).forEach(o=>{n.delete?t.push(o):n.retain&&n.attributes&&t.retain(Wr.default.length(o),As.default.invert(n.attributes,o.attributes))}),r+s}else if(typeof n.retain=="object"&&n.retain!==null){let s=e.slice(r,r+1),a=new Ii.default(s.ops).next(),[o,l,h]=O9(n.retain,a.insert),d=i.getHandler(o);return t.retain({[o]:d.invert(l,h)},As.default.invert(n.attributes,a.attributes)),r+1}}return r},0),t.chop()}transform(e,t=!1){if(t=!!t,typeof e=="number")return this.transformPosition(e,t);let r=e,n=new Ii.default(this.ops),s=new Ii.default(r.ops),a=new i;for(;n.hasNext()||s.hasNext();)if(n.peekType()==="insert"&&(t||s.peekType()!=="insert"))a.retain(Wr.default.length(n.next()));else if(s.peekType()==="insert")a.push(s.next());else{let o=Math.min(n.peekLength(),s.peekLength()),l=n.next(o),h=s.next(o);if(l.delete)continue;if(h.delete)a.push(h);else{let d=l.retain,c=h.retain,f=typeof c=="object"&&c!==null?c:o;if(typeof d=="object"&&d!==null&&typeof c=="object"&&c!==null){let m=Object.keys(d)[0];if(m===Object.keys(c)[0]){let g=i.getHandler(m);g&&(f={[m]:g.transform(d[m],c[m],t)})}}a.retain(f,As.default.transform(l.attributes,h.attributes,t))}}return a.chop()}transformPosition(e,t=!1){t=!!t;let r=new Ii.default(this.ops),n=0;for(;r.hasNext()&&n<=e;){let s=r.peekLength(),a=r.peekType();if(r.next(),a==="delete"){e-=Math.min(s,e-n);continue}else a==="insert"&&(n{Re();_l=class extends Ke{static value(){}optimize(){(this.prev||this.next)&&this.remove()}length(){return 0}value(){return""}};_l.blotName="break";_l.tagName="BR";Et=_l});function ks(i){return i.replace(/[&<>"']/g,e=>YO[e])}var nt,YO,Kr=T(()=>{Re();nt=class extends Ha{},YO={"&":"&","<":"<",">":">",'"':""","'":"'"}});var br,hm,St,Zr=T(()=>{Re();Dn();Kr();br=class br extends bd{static compare(e,t){let r=br.order.indexOf(e),n=br.order.indexOf(t);return r>=0||n>=0?r-n:e===t?0:e0){let t=this.parent.isolate(this.offset(),this.length());this.moveChildren(t),t.wrap(this)}}};U(br,"allowedChildren",[br,Et,Ke,nt]),U(br,"order",["cursor","inline","link","underline","strike","italic","bold","script","code"]);hm=br,St=hm});function cm(i){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return i.descendants(dt).reduce((t,r)=>r.length()===0?t:t.insert(r.value(),ai(r,{},e)),new dm.default).insert(` -`,ai(i))}function ai(i){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return i==null||("formats"in i&&typeof i.formats=="function"&&(e={...e,...i.formats()},t&&delete e["code-token"]),i.parent==null||i.parent.statics.blotName==="scroll"||i.parent.statics.scope!==i.statics.scope)?e:ai(i.parent,e,t)}var dm,B9,De,ft,zi=T(()=>{Re();dm=pt(pi(),1);Dn();Zr();Kr();B9=1,De=class extends vs{constructor(){super(...arguments);U(this,"cache",{})}delta(){return this.cache.delta==null&&(this.cache.delta=cm(this)),this.cache.delta}deleteAt(t,r){super.deleteAt(t,r),this.cache={}}formatAt(t,r,n,s){r<=0||(this.scroll.query(n,X.BLOCK)?t+r===this.length()&&this.format(n,s):super.formatAt(t,Math.min(r,this.length()-t-1),n,s),this.cache={})}insertAt(t,r,n){if(n!=null){super.insertAt(t,r,n),this.cache={};return}if(r.length===0)return;let s=r.split(` -`),a=s.shift();a.length>0&&(t(o=o.split(l,!0),o.insertAt(0,h),h.length),t+a.length)}insertBefore(t,r){let{head:n}=this.children;super.insertBefore(t,r),n instanceof Et&&n.remove(),this.cache={}}length(){return this.cache.length==null&&(this.cache.length=super.length()+B9),this.cache.length}moveChildren(t,r){super.moveChildren(t,r),this.cache={}}optimize(t){super.optimize(t),this.cache={}}path(t){return super.path(t,!0)}removeChild(t){super.removeChild(t),this.cache={}}split(t){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(r&&(t===0||t>=this.length()-B9)){let s=this.clone();return t===0?(this.parent.insertBefore(s,this),this):(this.parent.insertBefore(s,this.next),s)}let n=super.split(t,r);return this.cache={},n}};De.blotName="block";De.tagName="P";De.defaultChild=Et;De.allowedChildren=[Et,St,Ke,nt];ft=class extends Ke{attach(){super.attach(),this.attributes=new yl(this.domNode)}delta(){return new dm.default().insert(this.value(),{...this.formats(),...this.attributes.values()})}format(e,t){let r=this.scroll.query(e,X.BLOCK_ATTRIBUTE);r!=null&&this.attributes.attribute(r,t)}formatAt(e,t,r,n){this.format(r,n)}insertAt(e,t,r){if(r!=null){super.insertAt(e,t,r);return}let n=t.split(` -`),s=n.pop(),a=n.map(l=>{let h=this.scroll.create(De.blotName);return h.insertAt(0,l),h}),o=this.split(e);a.forEach(l=>{this.parent.insertBefore(l,o)}),s&&this.parent.insertBefore(this.scroll.create("text",s),o)}};ft.scope=X.BLOCK_BLOT});var Ri,um,On,Ll=T(()=>{Re();Kr();Ri=class Ri extends Ke{static value(){}constructor(e,t,r){super(e,t),this.selection=r,this.textNode=document.createTextNode(Ri.CONTENTS),this.domNode.appendChild(this.textNode),this.savedLength=0}detach(){this.parent!=null&&this.parent.removeChild(this)}format(e,t){if(this.savedLength!==0){super.format(e,t);return}let r=this,n=0;for(;r!=null&&r.statics.scope!==X.BLOCK_BLOT;)n+=r.offset(r.parent),r=r.parent;r!=null&&(this.savedLength=Ri.CONTENTS.length,r.optimize(),r.formatAt(n,Ri.CONTENTS.length,e,t),this.savedLength=0)}index(e,t){return e===this.textNode?0:super.index(e,t)}length(){return this.savedLength}position(){return[this.textNode,this.textNode.data.length]}remove(){super.remove(),this.parent=null}restore(){if(this.selection.composing||this.parent==null)return null;let e=this.selection.getNativeRange();for(;this.domNode.lastChild!=null&&this.domNode.lastChild!==this.textNode;)this.domNode.parentNode.insertBefore(this.domNode.lastChild,this.domNode);let t=this.prev instanceof nt?this.prev:null,r=t?t.length():0,n=this.next instanceof nt?this.next:null,s=n?n.text:"",{textNode:a}=this,o=a.data.split(Ri.CONTENTS).join("");a.data=Ri.CONTENTS;let l;if(t)l=t,(o||n)&&(t.insertAt(t.length(),o+s),n&&n.remove());else if(n)l=n,n.insertAt(0,o);else{let h=document.createTextNode(o);l=this.scroll.create(h),this.parent.insertBefore(l,this)}if(this.remove(),e){let h=(f,m)=>t&&f===t.domNode?m:f===a?r+m-1:n&&f===n.domNode?r+o.length+m:null,d=h(e.start.node,e.start.offset),c=h(e.end.node,e.end.offset);if(d!==null&&c!==null)return{startNode:l.domNode,startOffset:d,endNode:l.domNode,endOffset:c}}return null}update(e,t){if(e.some(r=>r.type==="characterData"&&r.target===this.textNode)){let r=this.restore();r&&(t.range=r)}}optimize(e){super.optimize(e);let{parent:t}=this;for(;t;){if(t.domNode.tagName==="A"){this.savedLength=Ri.CONTENTS.length,t.isolate(this.offset(t),this.length()).unwrap(),this.savedLength=0;break}t=t.parent}}value(){return""}};U(Ri,"blotName","cursor"),U(Ri,"className","ql-cursor"),U(Ri,"tagName","span"),U(Ri,"CONTENTS","\uFEFF");um=Ri,On=um});var F9=rr((lQ,fm)=>{"use strict";var XO=Object.prototype.hasOwnProperty,Ut="~";function Il(){}Object.create&&(Il.prototype=Object.create(null),new Il().__proto__||(Ut=!1));function KO(i,e,t){this.fn=i,this.context=e,this.once=t||!1}function P9(i,e,t,r,n){if(typeof t!="function")throw new TypeError("The listener must be a function");var s=new KO(t,r||i,n),a=Ut?Ut+e:e;return i._events[a]?i._events[a].fn?i._events[a]=[i._events[a],s]:i._events[a].push(s):(i._events[a]=s,i._eventsCount++),i}function jd(i,e){--i._eventsCount===0?i._events=new Il:delete i._events[e]}function At(){this._events=new Il,this._eventsCount=0}At.prototype.eventNames=function(){var e=[],t,r;if(this._eventsCount===0)return e;for(r in t=this._events)XO.call(t,r)&&e.push(Ut?r.slice(1):r);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e};At.prototype.listeners=function(e){var t=Ut?Ut+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var n=0,s=r.length,a=new Array(s);n{mm=pt(F9(),1)});var zl,pm=T(()=>{zl=new WeakMap});function H9(i){if(xm&&gm.indexOf(i)<=gm.indexOf(xm)){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r(e[t]=H9.bind(console,t,i),e),{})}var gm,xm,gi,Cs=T(()=>{gm=["error","warn","log","info"],xm="warn";ym.level=i=>{xm=i};H9.level=ym.level;gi=ym});var vm,ZO,Rl,J,Qr=T(()=>{q9();pm();Cs();vm=gi("quill:events"),ZO=["selectionchange","mousedown","mouseup","click"];ZO.forEach(i=>{document.addEventListener(i,function(){for(var e=arguments.length,t=new Array(e),r=0;r{let s=zl.get(n);s&&s.emitter&&s.emitter.handleDOM(...t)})})});Rl=class extends mm.default{constructor(){super(),this.domListeners={},this.on("error",vm.error)}emit(){for(var e=arguments.length,t=new Array(e),r=0;r1?t-1:0),n=1;n{let{node:a,handler:o}=s;(e.target===a||a.contains(e.target))&&o(e,...r)})}listenDOM(e,t,r){this.domListeners[e]||(this.domListeners[e]=[]),this.domListeners[e].push({node:t,handler:r})}};U(Rl,"events",{EDITOR_CHANGE:"editor-change",SCROLL_BEFORE_UPDATE:"scroll-before-update",SCROLL_BLOT_MOUNT:"scroll-blot-mount",SCROLL_BLOT_UNMOUNT:"scroll-blot-unmount",SCROLL_OPTIMIZE:"scroll-optimize",SCROLL_UPDATE:"scroll-update",SCROLL_EMBED_UPDATE:"scroll-embed-update",SELECTION_CHANGE:"selection-change",TEXT_CHANGE:"text-change",COMPOSITION_BEFORE_START:"composition-before-start",COMPOSITION_START:"composition-start",COMPOSITION_BEFORE_END:"composition-before-end",COMPOSITION_END:"composition-end"}),U(Rl,"sources",{API:"api",SILENT:"silent",USER:"user"});J=Rl});function wm(i,e){try{e.parentNode}catch{return!1}return i.contains(e)}var bm,$t,Mm,U9,Dl=T(()=>{Re();kn();Qr();Cs();bm=gi("quill:selection"),$t=class{constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;this.index=e,this.length=t}},Mm=class{constructor(e,t){this.emitter=t,this.scroll=e,this.composing=!1,this.mouseDown=!1,this.root=this.scroll.domNode,this.cursor=this.scroll.create("cursor",this),this.savedRange=new $t(0,0),this.lastRange=this.savedRange,this.lastNative=null,this.handleComposition(),this.handleDragging(),this.emitter.listenDOM("selectionchange",document,()=>{!this.mouseDown&&!this.composing&&setTimeout(this.update.bind(this,J.sources.USER),1)}),this.emitter.on(J.events.SCROLL_BEFORE_UPDATE,()=>{if(!this.hasFocus())return;let r=this.getNativeRange();r!=null&&r.start.node!==this.cursor.textNode&&this.emitter.once(J.events.SCROLL_UPDATE,(n,s)=>{try{this.root.contains(r.start.node)&&this.root.contains(r.end.node)&&this.setNativeRange(r.start.node,r.start.offset,r.end.node,r.end.offset);let a=s.some(o=>o.type==="characterData"||o.type==="childList"||o.type==="attributes"&&o.target===this.root);this.update(a?J.sources.SILENT:n)}catch{}})}),this.emitter.on(J.events.SCROLL_OPTIMIZE,(r,n)=>{if(n.range){let{startNode:s,startOffset:a,endNode:o,endOffset:l}=n.range;this.setNativeRange(s,a,o,l),this.update(J.sources.SILENT)}}),this.update(J.sources.SILENT)}handleComposition(){this.emitter.on(J.events.COMPOSITION_BEFORE_START,()=>{this.composing=!0}),this.emitter.on(J.events.COMPOSITION_END,()=>{if(this.composing=!1,this.cursor.parent){let e=this.cursor.restore();if(!e)return;setTimeout(()=>{this.setNativeRange(e.startNode,e.startOffset,e.endNode,e.endOffset)},1)}})}handleDragging(){this.emitter.listenDOM("mousedown",document.body,()=>{this.mouseDown=!0}),this.emitter.listenDOM("mouseup",document.body,()=>{this.mouseDown=!1,this.update(J.sources.USER)})}focus(){this.hasFocus()||(this.root.focus({preventScroll:!0}),this.setRange(this.savedRange))}format(e,t){this.scroll.update();let r=this.getNativeRange();if(!(r==null||!r.native.collapsed||this.scroll.query(e,X.BLOCK))){if(r.start.node!==this.cursor.textNode){let n=this.scroll.find(r.start.node,!1);if(n==null)return;if(n instanceof dt){let s=n.split(r.start.offset);n.parent.insertBefore(this.cursor,s)}else n.insertBefore(this.cursor,r.start.node);this.cursor.attach()}this.cursor.format(e,t),this.scroll.optimize(),this.setNativeRange(this.cursor.textNode,this.cursor.textNode.data.length),this.update()}}getBounds(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=this.scroll.length();e=Math.min(e,r-1),t=Math.min(e+t,r-1)-e;let n,[s,a]=this.scroll.leaf(e);if(s==null)return null;if(t>0&&a===s.length()){let[d]=this.scroll.leaf(e+1);if(d){let[c]=this.scroll.line(e),[f]=this.scroll.line(e+1);c===f&&(s=d,a=0)}}[n,a]=s.position(a,!0);let o=document.createRange();if(t>0)return o.setStart(n,a),[s,a]=this.scroll.leaf(e+t),s==null?null:([n,a]=s.position(a,!0),o.setEnd(n,a),o.getBoundingClientRect());let l="left",h;if(n instanceof Text){if(!n.data.length)return null;a0&&(l="right")}return{bottom:h.top+h.height,height:h.height,left:h[l],right:h[l],top:h.top,width:0}}getNativeRange(){let e=document.getSelection();if(e==null||e.rangeCount<=0)return null;let t=e.getRangeAt(0);if(t==null)return null;let r=this.normalizeNative(t);return bm.info("getNativeRange",r),r}getRange(){let e=this.scroll.domNode;if("isConnected"in e&&!e.isConnected)return[null,null];let t=this.getNativeRange();return t==null?[null,null]:[this.normalizedToRange(t),t]}hasFocus(){return document.activeElement===this.root||document.activeElement!=null&&wm(this.root,document.activeElement)}normalizedToRange(e){let t=[[e.start.node,e.start.offset]];e.native.collapsed||t.push([e.end.node,e.end.offset]);let r=t.map(a=>{let[o,l]=a,h=this.scroll.find(o,!0),d=h.offset(this.scroll);return l===0?d:h instanceof dt?d+h.index(o,l):d+h.length()}),n=Math.min(Math.max(...r),this.scroll.length()-1),s=Math.min(n,...r);return new $t(s,n-s)}normalizeNative(e){if(!wm(this.root,e.startContainer)||!e.collapsed&&!wm(this.root,e.endContainer))return null;let t={start:{node:e.startContainer,offset:e.startOffset},end:{node:e.endContainer,offset:e.endOffset},native:e};return[t.start,t.end].forEach(r=>{let{node:n,offset:s}=r;for(;!(n instanceof Text)&&n.childNodes.length>0;)if(n.childNodes.length>s)n=n.childNodes[s],s=0;else if(n.childNodes.length===s)n=n.lastChild,n instanceof Text?s=n.data.length:n.childNodes.length>0?s=n.childNodes.length:s=n.childNodes.length+1;else break;r.node=n,r.offset=s}),t}rangeToNative(e){let t=this.scroll.length(),r=(n,s)=>{n=Math.min(t-1,n);let[a,o]=this.scroll.leaf(n);return a?a.position(o,s):[null,-1]};return[...r(e.index,!1),...r(e.index+e.length,!0)]}setNativeRange(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e,n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:t,s=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1;if(bm.info("setNativeRange",e,t,r,n),e!=null&&(this.root.parentNode==null||e.parentNode==null||r.parentNode==null))return;let a=document.getSelection();if(a!=null)if(e!=null){this.hasFocus()||this.root.focus({preventScroll:!0});let{native:o}=this.getNativeRange()||{};if(o==null||s||e!==o.startContainer||t!==o.startOffset||r!==o.endContainer||n!==o.endOffset){e instanceof Element&&e.tagName==="BR"&&(t=Array.from(e.parentNode.childNodes).indexOf(e),e=e.parentNode),r instanceof Element&&r.tagName==="BR"&&(n=Array.from(r.parentNode.childNodes).indexOf(r),r=r.parentNode);let l=document.createRange();l.setStart(e,t),l.setEnd(r,n),a.removeAllRanges(),a.addRange(l)}}else a.removeAllRanges(),this.root.blur()}setRange(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:J.sources.API;if(typeof t=="string"&&(r=t,t=!1),bm.info("setRange",e),e!=null){let n=this.rangeToNative(e);this.setNativeRange(...n,t)}else this.setNativeRange(null);this.update(r)}update(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:J.sources.USER,t=this.lastRange,[r,n]=this.getRange();if(this.lastRange=r,this.lastNative=n,this.lastRange!=null&&(this.savedRange=this.lastRange),!ys(t,this.lastRange)){if(!this.composing&&n!=null&&n.native.collapsed&&n.start.node!==this.cursor.textNode){let a=this.cursor.restore();a&&this.setNativeRange(a.startNode,a.startOffset,a.endNode,a.endOffset)}let s=[J.events.SELECTION_CHANGE,yr(this.lastRange),yr(t),e];this.emitter.emit(J.events.EDITOR_CHANGE,...s),e!==J.sources.SILENT&&this.emitter.emit(...s)}}};U9=Mm});function Xa(i,e,t){if(i.length===0){let[m]=Tm(t.pop());return e<=0?``:`${Xa([],e-1,t)}`}let[{child:r,offset:n,length:s,indent:a,type:o},...l]=i,[h,d]=Tm(o);if(a>e)return t.push(o),a===e+1?`<${h}>${Ol(r,n,s)}${Xa(l,a,t)}`:`<${h}>
  • ${Xa(i,e+1,t)}`;let c=t[t.length-1];if(a===e&&o===c)return`
  • ${Ol(r,n,s)}${Xa(l,a,t)}`;let[f]=Tm(t.pop());return`${Xa(i,e-1,t)}`}function Ol(i,e,t){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if("html"in i&&typeof i.html=="function")return i.html(e,t);if(i instanceof nt)return ks(i.value().slice(e,e+t)).replaceAll(" "," ");if(i instanceof ni){if(i.statics.blotName==="list-container"){let h=[];return i.children.forEachAt(e,t,(d,c,f)=>{let m="formats"in d&&typeof d.formats=="function"?d.formats():{};h.push({child:d,offset:c,length:f,indent:m.indent||0,type:m.list})}),Xa(h,-1,[])}let n=[];if(i.children.forEachAt(e,t,(h,d,c)=>{n.push(Ol(h,d,c))}),r||i.statics.blotName==="list")return n.join("");let{outerHTML:s,innerHTML:a}=i.domNode,[o,l]=s.split(`>${a}<`);return o==="${n.join("")}<${l}`:`${o}>${n.join("")}<${l}`}return i.domNode instanceof Element?i.domNode.outerHTML:""}function JO(i,e){return Object.keys(e).reduce((t,r)=>{if(i[r]==null)return t;let n=e[r];return n===i[r]?t[r]=n:Array.isArray(n)?n.indexOf(i[r])<0?t[r]=n.concat([i[r]]):t[r]=n:t[r]=[n,i[r]],t},{})}function Tm(i){let e=i==="ordered"?"ol":"ul";switch(i){case"checked":return[e,' data-list="checked"'];case"unchecked":return[e,' data-list="unchecked"'];default:return[e,""]}}function $9(i){return i.reduce((e,t)=>{if(typeof t.insert=="string"){let r=t.insert.replace(/\r\n/g,` +?)[ \r ]*`,_1="[\u0300-\u036F]",mk=new RegExp(_1+"+$"),pk="("+pg+"+)|"+(fk+"|")+"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]"+(_1+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(_1+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+uk)+("|"+ck+")"),Oh=class{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(pk,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new mi("EOF",new ti(this,t,t));var r=this.tokenRegex.exec(e);if(r===null||r.index!==t)throw new G("Unexpected character: '"+e[t]+"'",new mi(e[t],new ti(this,t,t+1)));var n=r[6]||r[3]||(r[2]?"\\ ":" ");if(this.catcodes[n]===14){var s=e.indexOf(` +`,this.tokenRegex.lastIndex);return s===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new mi(n,new ti(this,t,this.tokenRegex.lastIndex))}},L1=class{constructor(e,t){e===void 0&&(e={}),t===void 0&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new G("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(e[t]==null?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(r===void 0&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var s=this.undefStack[this.undefStack.length-1];s&&!s.hasOwnProperty(e)&&(s[e]=this.current[e])}t==null?delete this.current[e]:this.current[e]=t}},gk=ng;M("\\noexpand",function(i){var e=i.popToken();return i.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});M("\\expandafter",function(i){var e=i.popToken();return i.expandOnce(!0),{tokens:[e],numArgs:0}});M("\\@firstoftwo",function(i){var e=i.consumeArgs(2);return{tokens:e[0],numArgs:0}});M("\\@secondoftwo",function(i){var e=i.consumeArgs(2);return{tokens:e[1],numArgs:0}});M("\\@ifnextchar",function(i){var e=i.consumeArgs(3);i.consumeSpaces();var t=i.future();return e[0].length===1&&e[0][0].text===t.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});M("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");M("\\TextOrMath",function(i){var e=i.consumeArgs(2);return i.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});M4={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};M("\\char",function(i){var e=i.popToken(),t,r="";if(e.text==="'")t=8,e=i.popToken();else if(e.text==='"')t=16,e=i.popToken();else if(e.text==="`")if(e=i.popToken(),e.text[0]==="\\")r=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new G("\\char` missing argument");r=e.text.charCodeAt(0)}else t=10;if(t){if(r=M4[e.text],r==null||r>=t)throw new G("Invalid base-"+t+" digit "+e.text);for(var n;(n=M4[i.future().text])!=null&&n{var n=i.consumeArg().tokens;if(n.length!==1)throw new G("\\newcommand's first argument must be a macro name");var s=n[0].text,a=i.isDefined(s);if(a&&!e)throw new G("\\newcommand{"+s+"} attempting to redefine "+(s+"; use \\renewcommand"));if(!a&&!t)throw new G("\\renewcommand{"+s+"} when command "+s+" does not yet exist; use \\newcommand");var o=0;if(n=i.consumeArg().tokens,n.length===1&&n[0].text==="["){for(var l="",h=i.expandNextToken();h.text!=="]"&&h.text!=="EOF";)l+=h.text,h=i.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new G("Invalid number of arguments: "+l);o=parseInt(l),n=i.consumeArg().tokens}return a&&r||i.macros.set(s,{tokens:n,numArgs:o}),""};M("\\newcommand",i=>V1(i,!1,!0,!1));M("\\renewcommand",i=>V1(i,!0,!1,!1));M("\\providecommand",i=>V1(i,!0,!0,!0));M("\\message",i=>{var e=i.consumeArgs(1)[0];return console.log(e.reverse().map(t=>t.text).join("")),""});M("\\errmessage",i=>{var e=i.consumeArgs(1)[0];return console.error(e.reverse().map(t=>t.text).join("")),""});M("\\show",i=>{var e=i.popToken(),t=e.text;return console.log(e,i.macros.get(t),gn[t],Be.math[t],Be.text[t]),""});M("\\bgroup","{");M("\\egroup","}");M("~","\\nobreakspace");M("\\lq","`");M("\\rq","'");M("\\aa","\\r a");M("\\AA","\\r A");M("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xA9}");M("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");M("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xAE}");M("\u212C","\\mathscr{B}");M("\u2130","\\mathscr{E}");M("\u2131","\\mathscr{F}");M("\u210B","\\mathscr{H}");M("\u2110","\\mathscr{I}");M("\u2112","\\mathscr{L}");M("\u2133","\\mathscr{M}");M("\u211B","\\mathscr{R}");M("\u212D","\\mathfrak{C}");M("\u210C","\\mathfrak{H}");M("\u2128","\\mathfrak{Z}");M("\\Bbbk","\\Bbb{k}");M("\xB7","\\cdotp");M("\\llap","\\mathllap{\\textrm{#1}}");M("\\rlap","\\mathrlap{\\textrm{#1}}");M("\\clap","\\mathclap{\\textrm{#1}}");M("\\mathstrut","\\vphantom{(}");M("\\underbar","\\underline{\\text{#1}}");M("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');M("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}");M("\\ne","\\neq");M("\u2260","\\neq");M("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}");M("\u2209","\\notin");M("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}");M("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");M("\u225A","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");M("\u225B","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225B}}");M("\u225D","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225D}}");M("\u225E","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225E}}");M("\u225F","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}");M("\u27C2","\\perp");M("\u203C","\\mathclose{!\\mkern-0.8mu!}");M("\u220C","\\notni");M("\u231C","\\ulcorner");M("\u231D","\\urcorner");M("\u231E","\\llcorner");M("\u231F","\\lrcorner");M("\xA9","\\copyright");M("\xAE","\\textregistered");M("\uFE0F","\\textregistered");M("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');M("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');M("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');M("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');M("\\vdots","{\\varvdots\\rule{0pt}{15pt}}");M("\u22EE","\\vdots");M("\\varGamma","\\mathit{\\Gamma}");M("\\varDelta","\\mathit{\\Delta}");M("\\varTheta","\\mathit{\\Theta}");M("\\varLambda","\\mathit{\\Lambda}");M("\\varXi","\\mathit{\\Xi}");M("\\varPi","\\mathit{\\Pi}");M("\\varSigma","\\mathit{\\Sigma}");M("\\varUpsilon","\\mathit{\\Upsilon}");M("\\varPhi","\\mathit{\\Phi}");M("\\varPsi","\\mathit{\\Psi}");M("\\varOmega","\\mathit{\\Omega}");M("\\substack","\\begin{subarray}{c}#1\\end{subarray}");M("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");M("\\boxed","\\fbox{$\\displaystyle{#1}$}");M("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");M("\\implies","\\DOTSB\\;\\Longrightarrow\\;");M("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");M("\\dddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");M("\\ddddot","{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}");T4={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};M("\\dots",function(i){var e="\\dotso",t=i.expandAfterFuture().text;return t in T4?e=T4[t]:(t.slice(0,4)==="\\not"||t in Be.math&&["bin","rel"].includes(Be.math[t].group))&&(e="\\dotsb"),e});Y1={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};M("\\dotso",function(i){var e=i.future().text;return e in Y1?"\\ldots\\,":"\\ldots"});M("\\dotsc",function(i){var e=i.future().text;return e in Y1&&e!==","?"\\ldots\\,":"\\ldots"});M("\\cdots",function(i){var e=i.future().text;return e in Y1?"\\@cdots\\,":"\\@cdots"});M("\\dotsb","\\cdots");M("\\dotsm","\\cdots");M("\\dotsi","\\!\\cdots");M("\\dotsx","\\ldots\\,");M("\\DOTSI","\\relax");M("\\DOTSB","\\relax");M("\\DOTSX","\\relax");M("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");M("\\,","\\tmspace+{3mu}{.1667em}");M("\\thinspace","\\,");M("\\>","\\mskip{4mu}");M("\\:","\\tmspace+{4mu}{.2222em}");M("\\medspace","\\:");M("\\;","\\tmspace+{5mu}{.2777em}");M("\\thickspace","\\;");M("\\!","\\tmspace-{3mu}{.1667em}");M("\\negthinspace","\\!");M("\\negmedspace","\\tmspace-{4mu}{.2222em}");M("\\negthickspace","\\tmspace-{5mu}{.277em}");M("\\enspace","\\kern.5em ");M("\\enskip","\\hskip.5em\\relax");M("\\quad","\\hskip1em\\relax");M("\\qquad","\\hskip2em\\relax");M("\\tag","\\@ifstar\\tag@literal\\tag@paren");M("\\tag@paren","\\tag@literal{({#1})}");M("\\tag@literal",i=>{if(i.macros.get("\\df@tag"))throw new G("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});M("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");M("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");M("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");M("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");M("\\newline","\\\\\\relax");M("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");gg=V(lr["Main-Regular"][84][1]-.7*lr["Main-Regular"][65][1]);M("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+gg+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");M("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+gg+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");M("\\hspace","\\@ifstar\\@hspacer\\@hspace");M("\\@hspace","\\hskip #1\\relax");M("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");M("\\ordinarycolon",":");M("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");M("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');M("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');M("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');M("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');M("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');M("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');M("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');M("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');M("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');M("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');M("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');M("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');M("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');M("\u2237","\\dblcolon");M("\u2239","\\eqcolon");M("\u2254","\\coloneqq");M("\u2255","\\eqqcolon");M("\u2A74","\\Coloneqq");M("\\ratio","\\vcentcolon");M("\\coloncolon","\\dblcolon");M("\\colonequals","\\coloneqq");M("\\coloncolonequals","\\Coloneqq");M("\\equalscolon","\\eqqcolon");M("\\equalscoloncolon","\\Eqqcolon");M("\\colonminus","\\coloneq");M("\\coloncolonminus","\\Coloneq");M("\\minuscolon","\\eqcolon");M("\\minuscoloncolon","\\Eqcolon");M("\\coloncolonapprox","\\Colonapprox");M("\\coloncolonsim","\\Colonsim");M("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");M("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");M("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");M("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");M("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");M("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");M("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");M("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");M("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");M("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");M("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");M("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");M("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");M("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}");M("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}");M("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}");M("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}");M("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}");M("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}");M("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}");M("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}");M("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}");M("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}");M("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228A}");M("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2ACB}");M("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228B}");M("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2ACC}");M("\\imath","\\html@mathml{\\@imath}{\u0131}");M("\\jmath","\\html@mathml{\\@jmath}{\u0237}");M("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27E6}}");M("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27E7}}");M("\u27E6","\\llbracket");M("\u27E7","\\rrbracket");M("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}");M("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}");M("\u2983","\\lBrace");M("\u2984","\\rBrace");M("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29B5}}");M("\u29B5","\\minuso");M("\\darr","\\downarrow");M("\\dArr","\\Downarrow");M("\\Darr","\\Downarrow");M("\\lang","\\langle");M("\\rang","\\rangle");M("\\uarr","\\uparrow");M("\\uArr","\\Uparrow");M("\\Uarr","\\Uparrow");M("\\N","\\mathbb{N}");M("\\R","\\mathbb{R}");M("\\Z","\\mathbb{Z}");M("\\alef","\\aleph");M("\\alefsym","\\aleph");M("\\Alpha","\\mathrm{A}");M("\\Beta","\\mathrm{B}");M("\\bull","\\bullet");M("\\Chi","\\mathrm{X}");M("\\clubs","\\clubsuit");M("\\cnums","\\mathbb{C}");M("\\Complex","\\mathbb{C}");M("\\Dagger","\\ddagger");M("\\diamonds","\\diamondsuit");M("\\empty","\\emptyset");M("\\Epsilon","\\mathrm{E}");M("\\Eta","\\mathrm{H}");M("\\exist","\\exists");M("\\harr","\\leftrightarrow");M("\\hArr","\\Leftrightarrow");M("\\Harr","\\Leftrightarrow");M("\\hearts","\\heartsuit");M("\\image","\\Im");M("\\infin","\\infty");M("\\Iota","\\mathrm{I}");M("\\isin","\\in");M("\\Kappa","\\mathrm{K}");M("\\larr","\\leftarrow");M("\\lArr","\\Leftarrow");M("\\Larr","\\Leftarrow");M("\\lrarr","\\leftrightarrow");M("\\lrArr","\\Leftrightarrow");M("\\Lrarr","\\Leftrightarrow");M("\\Mu","\\mathrm{M}");M("\\natnums","\\mathbb{N}");M("\\Nu","\\mathrm{N}");M("\\Omicron","\\mathrm{O}");M("\\plusmn","\\pm");M("\\rarr","\\rightarrow");M("\\rArr","\\Rightarrow");M("\\Rarr","\\Rightarrow");M("\\real","\\Re");M("\\reals","\\mathbb{R}");M("\\Reals","\\mathbb{R}");M("\\Rho","\\mathrm{P}");M("\\sdot","\\cdot");M("\\sect","\\S");M("\\spades","\\spadesuit");M("\\sub","\\subset");M("\\sube","\\subseteq");M("\\supe","\\supseteq");M("\\Tau","\\mathrm{T}");M("\\thetasym","\\vartheta");M("\\weierp","\\wp");M("\\Zeta","\\mathrm{Z}");M("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");M("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");M("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");M("\\bra","\\mathinner{\\langle{#1}|}");M("\\ket","\\mathinner{|{#1}\\rangle}");M("\\braket","\\mathinner{\\langle{#1}\\rangle}");M("\\Bra","\\left\\langle#1\\right|");M("\\Ket","\\left|#1\\right\\rangle");xg=i=>e=>{var t=e.consumeArg().tokens,r=e.consumeArg().tokens,n=e.consumeArg().tokens,s=e.consumeArg().tokens,a=e.macros.get("|"),o=e.macros.get("\\|");e.macros.beginGroup();var l=c=>f=>{i&&(f.macros.set("|",a),n.length&&f.macros.set("\\|",o));var m=c;if(!c&&n.length){var g=f.future();g.text==="|"&&(f.popToken(),m=!0)}return{tokens:m?n:r,numArgs:0}};e.macros.set("|",l(!1)),n.length&&e.macros.set("\\|",l(!0));var h=e.consumeArg().tokens,d=e.expandTokens([...s,...h,...t]);return e.macros.endGroup(),{tokens:d.reverse(),numArgs:0}};M("\\bra@ket",xg(!1));M("\\bra@set",xg(!0));M("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");M("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");M("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");M("\\angln","{\\angl n}");M("\\blue","\\textcolor{##6495ed}{#1}");M("\\orange","\\textcolor{##ffa500}{#1}");M("\\pink","\\textcolor{##ff00af}{#1}");M("\\red","\\textcolor{##df0030}{#1}");M("\\green","\\textcolor{##28ae7b}{#1}");M("\\gray","\\textcolor{gray}{#1}");M("\\purple","\\textcolor{##9d38bd}{#1}");M("\\blueA","\\textcolor{##ccfaff}{#1}");M("\\blueB","\\textcolor{##80f6ff}{#1}");M("\\blueC","\\textcolor{##63d9ea}{#1}");M("\\blueD","\\textcolor{##11accd}{#1}");M("\\blueE","\\textcolor{##0c7f99}{#1}");M("\\tealA","\\textcolor{##94fff5}{#1}");M("\\tealB","\\textcolor{##26edd5}{#1}");M("\\tealC","\\textcolor{##01d1c1}{#1}");M("\\tealD","\\textcolor{##01a995}{#1}");M("\\tealE","\\textcolor{##208170}{#1}");M("\\greenA","\\textcolor{##b6ffb0}{#1}");M("\\greenB","\\textcolor{##8af281}{#1}");M("\\greenC","\\textcolor{##74cf70}{#1}");M("\\greenD","\\textcolor{##1fab54}{#1}");M("\\greenE","\\textcolor{##0d923f}{#1}");M("\\goldA","\\textcolor{##ffd0a9}{#1}");M("\\goldB","\\textcolor{##ffbb71}{#1}");M("\\goldC","\\textcolor{##ff9c39}{#1}");M("\\goldD","\\textcolor{##e07d10}{#1}");M("\\goldE","\\textcolor{##a75a05}{#1}");M("\\redA","\\textcolor{##fca9a9}{#1}");M("\\redB","\\textcolor{##ff8482}{#1}");M("\\redC","\\textcolor{##f9685d}{#1}");M("\\redD","\\textcolor{##e84d39}{#1}");M("\\redE","\\textcolor{##bc2612}{#1}");M("\\maroonA","\\textcolor{##ffbde0}{#1}");M("\\maroonB","\\textcolor{##ff92c6}{#1}");M("\\maroonC","\\textcolor{##ed5fa6}{#1}");M("\\maroonD","\\textcolor{##ca337c}{#1}");M("\\maroonE","\\textcolor{##9e034e}{#1}");M("\\purpleA","\\textcolor{##ddd7ff}{#1}");M("\\purpleB","\\textcolor{##c6b9fc}{#1}");M("\\purpleC","\\textcolor{##aa87ff}{#1}");M("\\purpleD","\\textcolor{##7854ab}{#1}");M("\\purpleE","\\textcolor{##543b78}{#1}");M("\\mintA","\\textcolor{##f5f9e8}{#1}");M("\\mintB","\\textcolor{##edf2df}{#1}");M("\\mintC","\\textcolor{##e0e5cc}{#1}");M("\\grayA","\\textcolor{##f6f7f7}{#1}");M("\\grayB","\\textcolor{##f0f1f2}{#1}");M("\\grayC","\\textcolor{##e3e5e6}{#1}");M("\\grayD","\\textcolor{##d6d8da}{#1}");M("\\grayE","\\textcolor{##babec2}{#1}");M("\\grayF","\\textcolor{##888d93}{#1}");M("\\grayG","\\textcolor{##626569}{#1}");M("\\grayH","\\textcolor{##3b3e40}{#1}");M("\\grayI","\\textcolor{##21242c}{#1}");M("\\kaBlue","\\textcolor{##314453}{#1}");M("\\kaGreen","\\textcolor{##71B307}{#1}");yg={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},I1=class{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new L1(gk,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new Oh(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,n;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;t=this.popToken(),{tokens:n,end:r}=this.consumeArg(["]"])}else({tokens:n,start:t,end:r}=this.consumeArg());return this.pushToken(new mi("EOF",r.loc)),this.pushTokens(n),new mi("",ti.range(t,r))}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var n=this.future(),s,a=0,o=0;do{if(s=this.popToken(),t.push(s),s.text==="{")++a;else if(s.text==="}"){if(--a,a===-1)throw new G("Extra }",s)}else if(s.text==="EOF")throw new G("Unexpected end of input in a macro argument, expected '"+(e&&r?e[o]:"}")+"'",s);if(e&&r)if((a===0||a===1&&e[o]==="{")&&s.text===e[o]){if(++o,o===e.length){t.splice(-o,o);break}}else o=0}while(a!==0||r);return n.text==="{"&&t[t.length-1].text==="}"&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:s}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new G("The length of delimiters doesn't match the number of args!");for(var r=t[0],n=0;nthis.settings.maxExpand)throw new G("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,n=t.noexpand?null:this._getExpansion(r);if(n==null||e&&n.unexpandable){if(e&&n==null&&r[0]==="\\"&&!this.isDefined(r))throw new G("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var s=n.tokens,a=this.consumeArgs(n.numArgs,n.delimiters);if(n.numArgs){s=s.slice();for(var o=s.length-1;o>=0;--o){var l=s[o];if(l.text==="#"){if(o===0)throw new G("Incomplete placeholder at end of macro body",l);if(l=s[--o],l.text==="#")s.splice(o+1,1);else if(/^[1-9]$/.test(l.text))s.splice(o,2,...a[+l.text-1]);else throw new G("Not a valid argument number",l)}}}return this.pushTokens(s),s.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new mi(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(this.expandOnce(!0)===!1){var n=this.stack.pop();n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(n)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t&&t.map(r=>r.text).join("")}_getExpansion(e){var t=this.macros.get(e);if(t==null)return t;if(e.length===1){var r=this.lexer.catcodes[e];if(r!=null&&r!==13)return}var n=typeof t=="function"?t(this):t;if(typeof n=="string"){var s=0;if(n.indexOf("#")!==-1)for(var a=n.replace(/##/g,"");a.indexOf("#"+(s+1))!==-1;)++s;for(var o=new Oh(n,this.settings),l=[],h=o.lex();h.text!=="EOF";)l.push(h),h=o.lex();l.reverse();var d={tokens:l,numArgs:s};return d}return n}isDefined(e){return this.macros.has(e)||gn.hasOwnProperty(e)||Be.math.hasOwnProperty(e)||Be.text.hasOwnProperty(e)||yg.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return t!=null?typeof t=="string"||typeof t=="function"||!t.unexpandable:gn.hasOwnProperty(e)&&!gn[e].primitive}},N4=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,Ah=Object.freeze({"\u208A":"+","\u208B":"-","\u208C":"=","\u208D":"(","\u208E":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1D62":"i","\u2C7C":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209A":"p","\u1D63":"r","\u209B":"s","\u209C":"t","\u1D64":"u","\u1D65":"v","\u2093":"x","\u1D66":"\u03B2","\u1D67":"\u03B3","\u1D68":"\u03C1","\u1D69":"\u03D5","\u1D6A":"\u03C7","\u207A":"+","\u207B":"-","\u207C":"=","\u207D":"(","\u207E":")","\u2070":"0","\xB9":"1","\xB2":"2","\xB3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1D2C":"A","\u1D2E":"B","\u1D30":"D","\u1D31":"E","\u1D33":"G","\u1D34":"H","\u1D35":"I","\u1D36":"J","\u1D37":"K","\u1D38":"L","\u1D39":"M","\u1D3A":"N","\u1D3C":"O","\u1D3E":"P","\u1D3F":"R","\u1D40":"T","\u1D41":"U","\u2C7D":"V","\u1D42":"W","\u1D43":"a","\u1D47":"b","\u1D9C":"c","\u1D48":"d","\u1D49":"e","\u1DA0":"f","\u1D4D":"g",\u02B0:"h","\u2071":"i",\u02B2:"j","\u1D4F":"k",\u02E1:"l","\u1D50":"m",\u207F:"n","\u1D52":"o","\u1D56":"p",\u02B3:"r",\u02E2:"s","\u1D57":"t","\u1D58":"u","\u1D5B":"v",\u02B7:"w",\u02E3:"x",\u02B8:"y","\u1DBB":"z","\u1D5D":"\u03B2","\u1D5E":"\u03B3","\u1D5F":"\u03B4","\u1D60":"\u03D5","\u1D61":"\u03C7","\u1DBF":"\u03B8"}),b1={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030C":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030A":{text:"\\r",math:"\\mathring"},"\u030B":{text:"\\H"},"\u0327":{text:"\\c"}},E4={\u00E1:"a\u0301",\u00E0:"a\u0300",\u00E4:"a\u0308",\u01DF:"a\u0308\u0304",\u00E3:"a\u0303",\u0101:"a\u0304",\u0103:"a\u0306",\u1EAF:"a\u0306\u0301",\u1EB1:"a\u0306\u0300",\u1EB5:"a\u0306\u0303",\u01CE:"a\u030C",\u00E2:"a\u0302",\u1EA5:"a\u0302\u0301",\u1EA7:"a\u0302\u0300",\u1EAB:"a\u0302\u0303",\u0227:"a\u0307",\u01E1:"a\u0307\u0304",\u00E5:"a\u030A",\u01FB:"a\u030A\u0301",\u1E03:"b\u0307",\u0107:"c\u0301",\u1E09:"c\u0327\u0301",\u010D:"c\u030C",\u0109:"c\u0302",\u010B:"c\u0307",\u00E7:"c\u0327",\u010F:"d\u030C",\u1E0B:"d\u0307",\u1E11:"d\u0327",\u00E9:"e\u0301",\u00E8:"e\u0300",\u00EB:"e\u0308",\u1EBD:"e\u0303",\u0113:"e\u0304",\u1E17:"e\u0304\u0301",\u1E15:"e\u0304\u0300",\u0115:"e\u0306",\u1E1D:"e\u0327\u0306",\u011B:"e\u030C",\u00EA:"e\u0302",\u1EBF:"e\u0302\u0301",\u1EC1:"e\u0302\u0300",\u1EC5:"e\u0302\u0303",\u0117:"e\u0307",\u0229:"e\u0327",\u1E1F:"f\u0307",\u01F5:"g\u0301",\u1E21:"g\u0304",\u011F:"g\u0306",\u01E7:"g\u030C",\u011D:"g\u0302",\u0121:"g\u0307",\u0123:"g\u0327",\u1E27:"h\u0308",\u021F:"h\u030C",\u0125:"h\u0302",\u1E23:"h\u0307",\u1E29:"h\u0327",\u00ED:"i\u0301",\u00EC:"i\u0300",\u00EF:"i\u0308",\u1E2F:"i\u0308\u0301",\u0129:"i\u0303",\u012B:"i\u0304",\u012D:"i\u0306",\u01D0:"i\u030C",\u00EE:"i\u0302",\u01F0:"j\u030C",\u0135:"j\u0302",\u1E31:"k\u0301",\u01E9:"k\u030C",\u0137:"k\u0327",\u013A:"l\u0301",\u013E:"l\u030C",\u013C:"l\u0327",\u1E3F:"m\u0301",\u1E41:"m\u0307",\u0144:"n\u0301",\u01F9:"n\u0300",\u00F1:"n\u0303",\u0148:"n\u030C",\u1E45:"n\u0307",\u0146:"n\u0327",\u00F3:"o\u0301",\u00F2:"o\u0300",\u00F6:"o\u0308",\u022B:"o\u0308\u0304",\u00F5:"o\u0303",\u1E4D:"o\u0303\u0301",\u1E4F:"o\u0303\u0308",\u022D:"o\u0303\u0304",\u014D:"o\u0304",\u1E53:"o\u0304\u0301",\u1E51:"o\u0304\u0300",\u014F:"o\u0306",\u01D2:"o\u030C",\u00F4:"o\u0302",\u1ED1:"o\u0302\u0301",\u1ED3:"o\u0302\u0300",\u1ED7:"o\u0302\u0303",\u022F:"o\u0307",\u0231:"o\u0307\u0304",\u0151:"o\u030B",\u1E55:"p\u0301",\u1E57:"p\u0307",\u0155:"r\u0301",\u0159:"r\u030C",\u1E59:"r\u0307",\u0157:"r\u0327",\u015B:"s\u0301",\u1E65:"s\u0301\u0307",\u0161:"s\u030C",\u1E67:"s\u030C\u0307",\u015D:"s\u0302",\u1E61:"s\u0307",\u015F:"s\u0327",\u1E97:"t\u0308",\u0165:"t\u030C",\u1E6B:"t\u0307",\u0163:"t\u0327",\u00FA:"u\u0301",\u00F9:"u\u0300",\u00FC:"u\u0308",\u01D8:"u\u0308\u0301",\u01DC:"u\u0308\u0300",\u01D6:"u\u0308\u0304",\u01DA:"u\u0308\u030C",\u0169:"u\u0303",\u1E79:"u\u0303\u0301",\u016B:"u\u0304",\u1E7B:"u\u0304\u0308",\u016D:"u\u0306",\u01D4:"u\u030C",\u00FB:"u\u0302",\u016F:"u\u030A",\u0171:"u\u030B",\u1E7D:"v\u0303",\u1E83:"w\u0301",\u1E81:"w\u0300",\u1E85:"w\u0308",\u0175:"w\u0302",\u1E87:"w\u0307",\u1E98:"w\u030A",\u1E8D:"x\u0308",\u1E8B:"x\u0307",\u00FD:"y\u0301",\u1EF3:"y\u0300",\u00FF:"y\u0308",\u1EF9:"y\u0303",\u0233:"y\u0304",\u0177:"y\u0302",\u1E8F:"y\u0307",\u1E99:"y\u030A",\u017A:"z\u0301",\u017E:"z\u030C",\u1E91:"z\u0302",\u017C:"z\u0307",\u00C1:"A\u0301",\u00C0:"A\u0300",\u00C4:"A\u0308",\u01DE:"A\u0308\u0304",\u00C3:"A\u0303",\u0100:"A\u0304",\u0102:"A\u0306",\u1EAE:"A\u0306\u0301",\u1EB0:"A\u0306\u0300",\u1EB4:"A\u0306\u0303",\u01CD:"A\u030C",\u00C2:"A\u0302",\u1EA4:"A\u0302\u0301",\u1EA6:"A\u0302\u0300",\u1EAA:"A\u0302\u0303",\u0226:"A\u0307",\u01E0:"A\u0307\u0304",\u00C5:"A\u030A",\u01FA:"A\u030A\u0301",\u1E02:"B\u0307",\u0106:"C\u0301",\u1E08:"C\u0327\u0301",\u010C:"C\u030C",\u0108:"C\u0302",\u010A:"C\u0307",\u00C7:"C\u0327",\u010E:"D\u030C",\u1E0A:"D\u0307",\u1E10:"D\u0327",\u00C9:"E\u0301",\u00C8:"E\u0300",\u00CB:"E\u0308",\u1EBC:"E\u0303",\u0112:"E\u0304",\u1E16:"E\u0304\u0301",\u1E14:"E\u0304\u0300",\u0114:"E\u0306",\u1E1C:"E\u0327\u0306",\u011A:"E\u030C",\u00CA:"E\u0302",\u1EBE:"E\u0302\u0301",\u1EC0:"E\u0302\u0300",\u1EC4:"E\u0302\u0303",\u0116:"E\u0307",\u0228:"E\u0327",\u1E1E:"F\u0307",\u01F4:"G\u0301",\u1E20:"G\u0304",\u011E:"G\u0306",\u01E6:"G\u030C",\u011C:"G\u0302",\u0120:"G\u0307",\u0122:"G\u0327",\u1E26:"H\u0308",\u021E:"H\u030C",\u0124:"H\u0302",\u1E22:"H\u0307",\u1E28:"H\u0327",\u00CD:"I\u0301",\u00CC:"I\u0300",\u00CF:"I\u0308",\u1E2E:"I\u0308\u0301",\u0128:"I\u0303",\u012A:"I\u0304",\u012C:"I\u0306",\u01CF:"I\u030C",\u00CE:"I\u0302",\u0130:"I\u0307",\u0134:"J\u0302",\u1E30:"K\u0301",\u01E8:"K\u030C",\u0136:"K\u0327",\u0139:"L\u0301",\u013D:"L\u030C",\u013B:"L\u0327",\u1E3E:"M\u0301",\u1E40:"M\u0307",\u0143:"N\u0301",\u01F8:"N\u0300",\u00D1:"N\u0303",\u0147:"N\u030C",\u1E44:"N\u0307",\u0145:"N\u0327",\u00D3:"O\u0301",\u00D2:"O\u0300",\u00D6:"O\u0308",\u022A:"O\u0308\u0304",\u00D5:"O\u0303",\u1E4C:"O\u0303\u0301",\u1E4E:"O\u0303\u0308",\u022C:"O\u0303\u0304",\u014C:"O\u0304",\u1E52:"O\u0304\u0301",\u1E50:"O\u0304\u0300",\u014E:"O\u0306",\u01D1:"O\u030C",\u00D4:"O\u0302",\u1ED0:"O\u0302\u0301",\u1ED2:"O\u0302\u0300",\u1ED6:"O\u0302\u0303",\u022E:"O\u0307",\u0230:"O\u0307\u0304",\u0150:"O\u030B",\u1E54:"P\u0301",\u1E56:"P\u0307",\u0154:"R\u0301",\u0158:"R\u030C",\u1E58:"R\u0307",\u0156:"R\u0327",\u015A:"S\u0301",\u1E64:"S\u0301\u0307",\u0160:"S\u030C",\u1E66:"S\u030C\u0307",\u015C:"S\u0302",\u1E60:"S\u0307",\u015E:"S\u0327",\u0164:"T\u030C",\u1E6A:"T\u0307",\u0162:"T\u0327",\u00DA:"U\u0301",\u00D9:"U\u0300",\u00DC:"U\u0308",\u01D7:"U\u0308\u0301",\u01DB:"U\u0308\u0300",\u01D5:"U\u0308\u0304",\u01D9:"U\u0308\u030C",\u0168:"U\u0303",\u1E78:"U\u0303\u0301",\u016A:"U\u0304",\u1E7A:"U\u0304\u0308",\u016C:"U\u0306",\u01D3:"U\u030C",\u00DB:"U\u0302",\u016E:"U\u030A",\u0170:"U\u030B",\u1E7C:"V\u0303",\u1E82:"W\u0301",\u1E80:"W\u0300",\u1E84:"W\u0308",\u0174:"W\u0302",\u1E86:"W\u0307",\u1E8C:"X\u0308",\u1E8A:"X\u0307",\u00DD:"Y\u0301",\u1EF2:"Y\u0300",\u0178:"Y\u0308",\u1EF8:"Y\u0303",\u0232:"Y\u0304",\u0176:"Y\u0302",\u1E8E:"Y\u0307",\u0179:"Z\u0301",\u017D:"Z\u030C",\u1E90:"Z\u0302",\u017B:"Z\u0307",\u03AC:"\u03B1\u0301",\u1F70:"\u03B1\u0300",\u1FB1:"\u03B1\u0304",\u1FB0:"\u03B1\u0306",\u03AD:"\u03B5\u0301",\u1F72:"\u03B5\u0300",\u03AE:"\u03B7\u0301",\u1F74:"\u03B7\u0300",\u03AF:"\u03B9\u0301",\u1F76:"\u03B9\u0300",\u03CA:"\u03B9\u0308",\u0390:"\u03B9\u0308\u0301",\u1FD2:"\u03B9\u0308\u0300",\u1FD1:"\u03B9\u0304",\u1FD0:"\u03B9\u0306",\u03CC:"\u03BF\u0301",\u1F78:"\u03BF\u0300",\u03CD:"\u03C5\u0301",\u1F7A:"\u03C5\u0300",\u03CB:"\u03C5\u0308",\u03B0:"\u03C5\u0308\u0301",\u1FE2:"\u03C5\u0308\u0300",\u1FE1:"\u03C5\u0304",\u1FE0:"\u03C5\u0306",\u03CE:"\u03C9\u0301",\u1F7C:"\u03C9\u0300",\u038E:"\u03A5\u0301",\u1FEA:"\u03A5\u0300",\u03AB:"\u03A5\u0308",\u1FE9:"\u03A5\u0304",\u1FE8:"\u03A5\u0306",\u038F:"\u03A9\u0301",\u1FFA:"\u03A9\u0300"},Bh=class i{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new I1(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(t===void 0&&(t=!0),this.fetch().text!==e)throw new G("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new mi("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){this.mode==="math"&&this.consumeSpaces();var n=this.fetch();if(i.endOfExpression.indexOf(n.text)!==-1||t&&n.text===t||e&&gn[n.text]&&gn[n.text].infix)break;var s=this.parseAtom(t);if(s){if(s.type==="internal")continue}else break;r.push(s)}return this.mode==="text"&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t=-1,r,n=0;n=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var o=Be[this.mode][t].group,l=ti.range(e),h;if(oA.hasOwnProperty(o)){var d=o;h={type:"atom",mode:this.mode,family:d,loc:l,text:t}}else h={type:o,mode:this.mode,loc:l,text:t};a=h}else if(t.charCodeAt(0)>=128)this.settings.strict&&(A4(t.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'"'+(" ("+t.charCodeAt(0)+")"),e)),a={type:"textord",mode:"text",loc:ti.range(e),text:t};else return null;if(this.consume(),s)for(var c=0;c{Mk=typeof global=="object"&&global&&global.Object===Object&&global,Gh=Mk});var Tk,Nk,ht,Xi=T(()=>{Z1();Tk=typeof self=="object"&&self&&self.Object===Object&&self,Nk=Gh||Tk||Function("return this")(),ht=Nk});var Ek,Li,dl=T(()=>{Xi();Ek=ht.Symbol,Li=Ek});function kk(i){var e=Sk.call(i,cl),t=i[cl];try{i[cl]=void 0;var r=!0}catch{}var n=Ak.call(i);return r&&(e?i[cl]=t:delete i[cl]),n}var Mg,Sk,Ak,cl,Tg,Ng=T(()=>{dl();Mg=Object.prototype,Sk=Mg.hasOwnProperty,Ak=Mg.toString,cl=Li?Li.toStringTag:void 0;Tg=kk});function Lk(i){return _k.call(i)}var Ck,_k,Eg,Sg=T(()=>{Ck=Object.prototype,_k=Ck.toString;Eg=Lk});function Rk(i){return i==null?i===void 0?zk:Ik:Ag&&Ag in Object(i)?Tg(i):Eg(i)}var Ik,zk,Ag,Ki,xa=T(()=>{dl();Ng();Sg();Ik="[object Null]",zk="[object Undefined]",Ag=Li?Li.toStringTag:void 0;Ki=Rk});function Dk(i){return i!=null&&typeof i=="object"}var Mt,Or=T(()=>{Mt=Dk});var Ok,Ii,ya=T(()=>{Ok=Array.isArray,Ii=Ok});function Bk(i){var e=typeof i;return i!=null&&(e=="object"||e=="function")}var St,Br=T(()=>{St=Bk});function Pk(i){return i}var Wh,Q1=T(()=>{Wh=Pk});function $k(i){if(!St(i))return!1;var e=Ki(i);return e==qk||e==Hk||e==Fk||e==Uk}var Fk,qk,Hk,Uk,va,Vh=T(()=>{xa();Br();Fk="[object AsyncFunction]",qk="[object Function]",Hk="[object GeneratorFunction]",Uk="[object Proxy]";va=$k});var jk,Yh,kg=T(()=>{Xi();jk=ht["__core-js_shared__"],Yh=jk});function Gk(i){return!!Cg&&Cg in i}var Cg,_g,Lg=T(()=>{kg();Cg=(function(){var i=/[^.]+$/.exec(Yh&&Yh.keys&&Yh.keys.IE_PROTO||"");return i?"Symbol(src)_1."+i:""})();_g=Gk});function Yk(i){if(i!=null){try{return Vk.call(i)}catch{}try{return i+""}catch{}}return""}var Wk,Vk,Pr,J1=T(()=>{Wk=Function.prototype,Vk=Wk.toString;Pr=Yk});function iC(i){if(!St(i)||_g(i))return!1;var e=va(i)?tC:Kk;return e.test(Pr(i))}var Xk,Kk,Zk,Qk,Jk,eC,tC,Ig,zg=T(()=>{Vh();Lg();Br();J1();Xk=/[\\^$.*+?()[\]{}|]/g,Kk=/^\[object .+?Constructor\]$/,Zk=Function.prototype,Qk=Object.prototype,Jk=Zk.toString,eC=Qk.hasOwnProperty,tC=RegExp("^"+Jk.call(eC).replace(Xk,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");Ig=iC});function rC(i,e){return i?.[e]}var Rg,Dg=T(()=>{Rg=rC});function nC(i,e){var t=Rg(i,e);return Ig(t)?t:void 0}var ni,bn=T(()=>{zg();Dg();ni=nC});var sC,Xh,Og=T(()=>{bn();Xi();sC=ni(ht,"WeakMap"),Xh=sC});var Bg,aC,Pg,Fg=T(()=>{Br();Bg=Object.create,aC=(function(){function i(){}return function(e){if(!St(e))return{};if(Bg)return Bg(e);i.prototype=e;var t=new i;return i.prototype=void 0,t}})(),Pg=aC});function oC(i,e,t){switch(t.length){case 0:return i.call(e);case 1:return i.call(e,t[0]);case 2:return i.call(e,t[0],t[1]);case 3:return i.call(e,t[0],t[1],t[2])}return i.apply(e,t)}var qg,Hg=T(()=>{qg=oC});function lC(i,e){var t=-1,r=i.length;for(e||(e=Array(r));++t{Kh=lC});function uC(i){var e=0,t=0;return function(){var r=cC(),n=dC-(r-t);if(t=r,n>0){if(++e>=hC)return arguments[0]}else e=0;return i.apply(void 0,arguments)}}var hC,dC,cC,Ug,$g=T(()=>{hC=800,dC=16,cC=Date.now;Ug=uC});function fC(i){return function(){return i}}var jg,Gg=T(()=>{jg=fC});var mC,ba,tf=T(()=>{bn();mC=(function(){try{var i=ni(Object,"defineProperty");return i({},"",{}),i}catch{}})(),ba=mC});var pC,Wg,Vg=T(()=>{Gg();tf();Q1();pC=ba?function(i,e){return ba(i,"toString",{configurable:!0,enumerable:!1,value:jg(e),writable:!0})}:Wh,Wg=pC});var gC,Yg,Xg=T(()=>{Vg();$g();gC=Ug(Wg),Yg=gC});function xC(i,e){for(var t=-1,r=i==null?0:i.length;++t{Kg=xC});function bC(i,e){var t=typeof i;return e=e??yC,!!e&&(t=="number"||t!="symbol"&&vC.test(i))&&i>-1&&i%1==0&&i{yC=9007199254740991,vC=/^(?:0|[1-9]\d*)$/;Zh=bC});function wC(i,e,t){e=="__proto__"&&ba?ba(i,e,{configurable:!0,enumerable:!0,value:t,writable:!0}):i[e]=t}var wa,Qh=T(()=>{tf();wa=wC});function MC(i,e){return i===e||i!==i&&e!==e}var fr,Ma=T(()=>{fr=MC});function EC(i,e,t){var r=i[e];(!(NC.call(i,e)&&fr(r,t))||t===void 0&&!(e in i))&&wa(i,e,t)}var TC,NC,Jh,nf=T(()=>{Qh();Ma();TC=Object.prototype,NC=TC.hasOwnProperty;Jh=EC});function SC(i,e,t,r){var n=!t;t||(t={});for(var s=-1,a=e.length;++s{nf();Qh();mr=SC});function AC(i,e,t){return e=Qg(e===void 0?i.length-1:e,0),function(){for(var r=arguments,n=-1,s=Qg(r.length-e,0),a=Array(s);++n{Hg();Qg=Math.max;Jg=AC});function kC(i,e){return Yg(Jg(i,e,Wh),i+"")}var t5,i5=T(()=>{Q1();e5();Xg();t5=kC});function _C(i){return typeof i=="number"&&i>-1&&i%1==0&&i<=CC}var CC,ed,sf=T(()=>{CC=9007199254740991;ed=_C});function LC(i){return i!=null&&ed(i.length)&&!va(i)}var wn,ul=T(()=>{Vh();sf();wn=LC});function IC(i,e,t){if(!St(t))return!1;var r=typeof e;return(r=="number"?wn(t)&&Zh(e,t.length):r=="string"&&e in t)?fr(t[e],i):!1}var r5,n5=T(()=>{Ma();ul();rf();Br();r5=IC});function zC(i){return t5(function(e,t){var r=-1,n=t.length,s=n>1?t[n-1]:void 0,a=n>2?t[2]:void 0;for(s=i.length>3&&typeof s=="function"?(n--,s):void 0,a&&r5(t[0],t[1],a)&&(s=n<3?void 0:s,n=1),e=Object(e);++r{i5();n5();s5=zC});function DC(i){var e=i&&i.constructor,t=typeof e=="function"&&e.prototype||RC;return i===t}var RC,Na,td=T(()=>{RC=Object.prototype;Na=DC});function OC(i,e){for(var t=-1,r=Array(i);++t{o5=OC});function PC(i){return Mt(i)&&Ki(i)==BC}var BC,af,h5=T(()=>{xa();Or();BC="[object Arguments]";af=PC});var d5,FC,qC,HC,fl,of=T(()=>{h5();Or();d5=Object.prototype,FC=d5.hasOwnProperty,qC=d5.propertyIsEnumerable,HC=af((function(){return arguments})())?af:function(i){return Mt(i)&&FC.call(i,"callee")&&!qC.call(i,"callee")},fl=HC});function UC(){return!1}var c5,u5=T(()=>{c5=UC});var p5,f5,$C,m5,jC,GC,Fr,ml=T(()=>{Xi();u5();p5=typeof exports=="object"&&exports&&!exports.nodeType&&exports,f5=p5&&typeof module=="object"&&module&&!module.nodeType&&module,$C=f5&&f5.exports===p5,m5=$C?ht.Buffer:void 0,jC=m5?m5.isBuffer:void 0,GC=jC||c5,Fr=GC});function g_(i){return Mt(i)&&ed(i.length)&&!!$e[Ki(i)]}var WC,VC,YC,XC,KC,ZC,QC,JC,e_,t_,i_,r_,n_,s_,a_,o_,l_,h_,d_,c_,u_,f_,m_,p_,$e,g5,x5=T(()=>{xa();sf();Or();WC="[object Arguments]",VC="[object Array]",YC="[object Boolean]",XC="[object Date]",KC="[object Error]",ZC="[object Function]",QC="[object Map]",JC="[object Number]",e_="[object Object]",t_="[object RegExp]",i_="[object Set]",r_="[object String]",n_="[object WeakMap]",s_="[object ArrayBuffer]",a_="[object DataView]",o_="[object Float32Array]",l_="[object Float64Array]",h_="[object Int8Array]",d_="[object Int16Array]",c_="[object Int32Array]",u_="[object Uint8Array]",f_="[object Uint8ClampedArray]",m_="[object Uint16Array]",p_="[object Uint32Array]",$e={};$e[o_]=$e[l_]=$e[h_]=$e[d_]=$e[c_]=$e[u_]=$e[f_]=$e[m_]=$e[p_]=!0;$e[WC]=$e[VC]=$e[s_]=$e[YC]=$e[a_]=$e[XC]=$e[KC]=$e[ZC]=$e[QC]=$e[JC]=$e[e_]=$e[t_]=$e[i_]=$e[r_]=$e[n_]=!1;g5=g_});function x_(i){return function(e){return i(e)}}var Ea,id=T(()=>{Ea=x_});var y5,pl,y_,lf,v_,qr,rd=T(()=>{Z1();y5=typeof exports=="object"&&exports&&!exports.nodeType&&exports,pl=y5&&typeof module=="object"&&module&&!module.nodeType&&module,y_=pl&&pl.exports===y5,lf=y_&&Gh.process,v_=(function(){try{var i=pl&&pl.require&&pl.require("util").types;return i||lf&&lf.binding&&lf.binding("util")}catch{}})(),qr=v_});var v5,b_,Sa,nd=T(()=>{x5();id();rd();v5=qr&&qr.isTypedArray,b_=v5?Ea(v5):g5,Sa=b_});function T_(i,e){var t=Ii(i),r=!t&&fl(i),n=!t&&!r&&Fr(i),s=!t&&!r&&!n&&Sa(i),a=t||r||n||s,o=a?o5(i.length,String):[],l=o.length;for(var h in i)(e||M_.call(i,h))&&!(a&&(h=="length"||n&&(h=="offset"||h=="parent")||s&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||Zh(h,l)))&&o.push(h);return o}var w_,M_,sd,hf=T(()=>{l5();of();ya();ml();rf();nd();w_=Object.prototype,M_=w_.hasOwnProperty;sd=T_});function N_(i,e){return function(t){return i(e(t))}}var ad,df=T(()=>{ad=N_});var E_,b5,w5=T(()=>{df();E_=ad(Object.keys,Object),b5=E_});function k_(i){if(!Na(i))return b5(i);var e=[];for(var t in Object(i))A_.call(i,t)&&t!="constructor"&&e.push(t);return e}var S_,A_,M5,T5=T(()=>{td();w5();S_=Object.prototype,A_=S_.hasOwnProperty;M5=k_});function C_(i){return wn(i)?sd(i):M5(i)}var Aa,od=T(()=>{hf();T5();ul();Aa=C_});function __(i){var e=[];if(i!=null)for(var t in Object(i))e.push(t);return e}var N5,E5=T(()=>{N5=__});function z_(i){if(!St(i))return N5(i);var e=Na(i),t=[];for(var r in i)r=="constructor"&&(e||!I_.call(i,r))||t.push(r);return t}var L_,I_,S5,A5=T(()=>{Br();td();E5();L_=Object.prototype,I_=L_.hasOwnProperty;S5=z_});function R_(i){return wn(i)?sd(i,!0):S5(i)}var pr,ka=T(()=>{hf();A5();ul();pr=R_});var D_,Hr,gl=T(()=>{bn();D_=ni(Object,"create"),Hr=D_});function O_(){this.__data__=Hr?Hr(null):{},this.size=0}var k5,C5=T(()=>{gl();k5=O_});function B_(i){var e=this.has(i)&&delete this.__data__[i];return this.size-=e?1:0,e}var _5,L5=T(()=>{_5=B_});function H_(i){var e=this.__data__;if(Hr){var t=e[i];return t===P_?void 0:t}return q_.call(e,i)?e[i]:void 0}var P_,F_,q_,I5,z5=T(()=>{gl();P_="__lodash_hash_undefined__",F_=Object.prototype,q_=F_.hasOwnProperty;I5=H_});function j_(i){var e=this.__data__;return Hr?e[i]!==void 0:$_.call(e,i)}var U_,$_,R5,D5=T(()=>{gl();U_=Object.prototype,$_=U_.hasOwnProperty;R5=j_});function W_(i,e){var t=this.__data__;return this.size+=this.has(i)?0:1,t[i]=Hr&&e===void 0?G_:e,this}var G_,O5,B5=T(()=>{gl();G_="__lodash_hash_undefined__";O5=W_});function Ca(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{C5();L5();z5();D5();B5();Ca.prototype.clear=k5;Ca.prototype.delete=_5;Ca.prototype.get=I5;Ca.prototype.has=R5;Ca.prototype.set=O5;cf=Ca});function V_(){this.__data__=[],this.size=0}var F5,q5=T(()=>{F5=V_});function Y_(i,e){for(var t=i.length;t--;)if(fr(i[t][0],e))return t;return-1}var Mn,xl=T(()=>{Ma();Mn=Y_});function Z_(i){var e=this.__data__,t=Mn(e,i);if(t<0)return!1;var r=e.length-1;return t==r?e.pop():K_.call(e,t,1),--this.size,!0}var X_,K_,H5,U5=T(()=>{xl();X_=Array.prototype,K_=X_.splice;H5=Z_});function Q_(i){var e=this.__data__,t=Mn(e,i);return t<0?void 0:e[t][1]}var $5,j5=T(()=>{xl();$5=Q_});function J_(i){return Mn(this.__data__,i)>-1}var G5,W5=T(()=>{xl();G5=J_});function eL(i,e){var t=this.__data__,r=Mn(t,i);return r<0?(++this.size,t.push([i,e])):t[r][1]=e,this}var V5,Y5=T(()=>{xl();V5=eL});function _a(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{q5();U5();j5();W5();Y5();_a.prototype.clear=F5;_a.prototype.delete=H5;_a.prototype.get=$5;_a.prototype.has=G5;_a.prototype.set=V5;Tn=_a});var tL,Nn,ld=T(()=>{bn();Xi();tL=ni(ht,"Map"),Nn=tL});function iL(){this.size=0,this.__data__={hash:new cf,map:new(Nn||Tn),string:new cf}}var X5,K5=T(()=>{P5();yl();ld();X5=iL});function rL(i){var e=typeof i;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?i!=="__proto__":i===null}var Z5,Q5=T(()=>{Z5=rL});function nL(i,e){var t=i.__data__;return Z5(e)?t[typeof e=="string"?"string":"hash"]:t.map}var En,vl=T(()=>{Q5();En=nL});function sL(i){var e=En(this,i).delete(i);return this.size-=e?1:0,e}var J5,e7=T(()=>{vl();J5=sL});function aL(i){return En(this,i).get(i)}var t7,i7=T(()=>{vl();t7=aL});function oL(i){return En(this,i).has(i)}var r7,n7=T(()=>{vl();r7=oL});function lL(i,e){var t=En(this,i),r=t.size;return t.set(i,e),this.size+=t.size==r?0:1,this}var s7,a7=T(()=>{vl();s7=lL});function La(i){var e=-1,t=i==null?0:i.length;for(this.clear();++e{K5();e7();i7();n7();a7();La.prototype.clear=X5;La.prototype.delete=J5;La.prototype.get=t7;La.prototype.has=r7;La.prototype.set=s7;hd=La});function hL(i,e){for(var t=-1,r=e.length,n=i.length;++t{dd=hL});var dL,Ia,cd=T(()=>{df();dL=ad(Object.getPrototypeOf,Object),Ia=dL});function gL(i){if(!Mt(i)||Ki(i)!=cL)return!1;var e=Ia(i);if(e===null)return!0;var t=mL.call(e,"constructor")&&e.constructor;return typeof t=="function"&&t instanceof t&&o7.call(t)==pL}var cL,uL,fL,o7,mL,pL,l7,h7=T(()=>{xa();cd();Or();cL="[object Object]",uL=Function.prototype,fL=Object.prototype,o7=uL.toString,mL=fL.hasOwnProperty,pL=o7.call(Object);l7=gL});function xL(){this.__data__=new Tn,this.size=0}var d7,c7=T(()=>{yl();d7=xL});function yL(i){var e=this.__data__,t=e.delete(i);return this.size=e.size,t}var u7,f7=T(()=>{u7=yL});function vL(i){return this.__data__.get(i)}var m7,p7=T(()=>{m7=vL});function bL(i){return this.__data__.has(i)}var g7,x7=T(()=>{g7=bL});function ML(i,e){var t=this.__data__;if(t instanceof Tn){var r=t.__data__;if(!Nn||r.length{yl();ld();uf();wL=200;y7=ML});function za(i){var e=this.__data__=new Tn(i);this.size=e.size}var Sn,ud=T(()=>{yl();c7();f7();p7();x7();v7();za.prototype.clear=d7;za.prototype.delete=u7;za.prototype.get=m7;za.prototype.has=g7;za.prototype.set=y7;Sn=za});function TL(i,e){return i&&mr(e,Aa(e),i)}var b7,w7=T(()=>{Ta();od();b7=TL});function NL(i,e){return i&&mr(e,pr(e),i)}var M7,T7=T(()=>{Ta();ka();M7=NL});function SL(i,e){if(e)return i.slice();var t=i.length,r=S7?S7(t):new i.constructor(t);return i.copy(r),r}var A7,N7,EL,E7,S7,fd,mf=T(()=>{Xi();A7=typeof exports=="object"&&exports&&!exports.nodeType&&exports,N7=A7&&typeof module=="object"&&module&&!module.nodeType&&module,EL=N7&&N7.exports===A7,E7=EL?ht.Buffer:void 0,S7=E7?E7.allocUnsafe:void 0;fd=SL});function AL(i,e){for(var t=-1,r=i==null?0:i.length,n=0,s=[];++t{k7=AL});function kL(){return[]}var md,pf=T(()=>{md=kL});var CL,_L,_7,LL,Ra,pd=T(()=>{C7();pf();CL=Object.prototype,_L=CL.propertyIsEnumerable,_7=Object.getOwnPropertySymbols,LL=_7?function(i){return i==null?[]:(i=Object(i),k7(_7(i),function(e){return _L.call(i,e)}))}:md,Ra=LL});function IL(i,e){return mr(i,Ra(i),e)}var L7,I7=T(()=>{Ta();pd();L7=IL});var zL,RL,gd,gf=T(()=>{ff();cd();pd();pf();zL=Object.getOwnPropertySymbols,RL=zL?function(i){for(var e=[];i;)dd(e,Ra(i)),i=Ia(i);return e}:md,gd=RL});function DL(i,e){return mr(i,gd(i),e)}var z7,R7=T(()=>{Ta();gf();z7=DL});function OL(i,e,t){var r=e(i);return Ii(i)?r:dd(r,t(i))}var xd,xf=T(()=>{ff();ya();xd=OL});function BL(i){return xd(i,Aa,Ra)}var bl,yf=T(()=>{xf();pd();od();bl=BL});function PL(i){return xd(i,pr,gd)}var D7,O7=T(()=>{xf();gf();ka();D7=PL});var FL,yd,B7=T(()=>{bn();Xi();FL=ni(ht,"DataView"),yd=FL});var qL,vd,P7=T(()=>{bn();Xi();qL=ni(ht,"Promise"),vd=qL});var HL,bd,F7=T(()=>{bn();Xi();HL=ni(ht,"Set"),bd=HL});var q7,UL,H7,U7,$7,j7,$L,jL,GL,WL,VL,xs,Ur,wl=T(()=>{B7();ld();P7();F7();Og();xa();J1();q7="[object Map]",UL="[object Object]",H7="[object Promise]",U7="[object Set]",$7="[object WeakMap]",j7="[object DataView]",$L=Pr(yd),jL=Pr(Nn),GL=Pr(vd),WL=Pr(bd),VL=Pr(Xh),xs=Ki;(yd&&xs(new yd(new ArrayBuffer(1)))!=j7||Nn&&xs(new Nn)!=q7||vd&&xs(vd.resolve())!=H7||bd&&xs(new bd)!=U7||Xh&&xs(new Xh)!=$7)&&(xs=function(i){var e=Ki(i),t=e==UL?i.constructor:void 0,r=t?Pr(t):"";if(r)switch(r){case $L:return j7;case jL:return q7;case GL:return H7;case WL:return U7;case VL:return $7}return e});Ur=xs});function KL(i){var e=i.length,t=new i.constructor(e);return e&&typeof i[0]=="string"&&XL.call(i,"index")&&(t.index=i.index,t.input=i.input),t}var YL,XL,G7,W7=T(()=>{YL=Object.prototype,XL=YL.hasOwnProperty;G7=KL});var ZL,Da,vf=T(()=>{Xi();ZL=ht.Uint8Array,Da=ZL});function QL(i){var e=new i.constructor(i.byteLength);return new Da(e).set(new Da(i)),e}var Oa,wd=T(()=>{vf();Oa=QL});function JL(i,e){var t=e?Oa(i.buffer):i.buffer;return new i.constructor(t,i.byteOffset,i.byteLength)}var V7,Y7=T(()=>{wd();V7=JL});function tI(i){var e=new i.constructor(i.source,eI.exec(i));return e.lastIndex=i.lastIndex,e}var eI,X7,K7=T(()=>{eI=/\w*$/;X7=tI});function iI(i){return Q7?Object(Q7.call(i)):{}}var Z7,Q7,J7,e8=T(()=>{dl();Z7=Li?Li.prototype:void 0,Q7=Z7?Z7.valueOf:void 0;J7=iI});function rI(i,e){var t=e?Oa(i.buffer):i.buffer;return new i.constructor(t,i.byteOffset,i.length)}var Md,bf=T(()=>{wd();Md=rI});function TI(i,e,t){var r=i.constructor;switch(e){case uI:return Oa(i);case nI:case sI:return new r(+i);case fI:return V7(i,t);case mI:case pI:case gI:case xI:case yI:case vI:case bI:case wI:case MI:return Md(i,t);case aI:return new r;case oI:case dI:return new r(i);case lI:return X7(i);case hI:return new r;case cI:return J7(i)}}var nI,sI,aI,oI,lI,hI,dI,cI,uI,fI,mI,pI,gI,xI,yI,vI,bI,wI,MI,t8,i8=T(()=>{wd();Y7();K7();e8();bf();nI="[object Boolean]",sI="[object Date]",aI="[object Map]",oI="[object Number]",lI="[object RegExp]",hI="[object Set]",dI="[object String]",cI="[object Symbol]",uI="[object ArrayBuffer]",fI="[object DataView]",mI="[object Float32Array]",pI="[object Float64Array]",gI="[object Int8Array]",xI="[object Int16Array]",yI="[object Int32Array]",vI="[object Uint8Array]",bI="[object Uint8ClampedArray]",wI="[object Uint16Array]",MI="[object Uint32Array]";t8=TI});function NI(i){return typeof i.constructor=="function"&&!Na(i)?Pg(Ia(i)):{}}var Td,wf=T(()=>{Fg();cd();td();Td=NI});function SI(i){return Mt(i)&&Ur(i)==EI}var EI,r8,n8=T(()=>{wl();Or();EI="[object Map]";r8=SI});var s8,AI,a8,o8=T(()=>{n8();id();rd();s8=qr&&qr.isMap,AI=s8?Ea(s8):r8,a8=AI});function CI(i){return Mt(i)&&Ur(i)==kI}var kI,l8,h8=T(()=>{wl();Or();kI="[object Set]";l8=CI});var d8,_I,c8,u8=T(()=>{h8();id();rd();d8=qr&&qr.isSet,_I=d8?Ea(d8):l8,c8=_I});function Nd(i,e,t,r,n,s){var a,o=e&LI,l=e&II,h=e&zI;if(t&&(a=n?t(i,r,n,s):t(i)),a!==void 0)return a;if(!St(i))return i;var d=Ii(i);if(d){if(a=G7(i),!o)return Kh(i,a)}else{var c=Ur(i),f=c==m8||c==PI;if(Fr(i))return fd(i,o);if(c==p8||c==f8||f&&!n){if(a=l||f?{}:Td(i),!o)return l?z7(i,M7(a,i)):L7(i,b7(a,i))}else{if(!Pe[c])return n?i:{};a=t8(i,c,o)}}s||(s=new Sn);var m=s.get(i);if(m)return m;s.set(i,a),c8(i)?i.forEach(function(y){a.add(Nd(y,e,t,y,i,s))}):a8(i)&&i.forEach(function(y,b){a.set(b,Nd(y,e,t,b,i,s))});var g=h?l?D7:bl:l?pr:Aa,x=d?void 0:g(i);return Kg(x||i,function(y,b){x&&(b=y,y=i[b]),Jh(a,b,Nd(y,e,t,b,i,s))}),a}var LI,II,zI,f8,RI,DI,OI,BI,m8,PI,FI,qI,p8,HI,UI,$I,jI,GI,WI,VI,YI,XI,KI,ZI,QI,JI,ez,tz,iz,Pe,g8,x8=T(()=>{ud();Zg();nf();w7();T7();mf();ef();I7();R7();yf();O7();wl();W7();i8();wf();ya();ml();o8();Br();u8();od();ka();LI=1,II=2,zI=4,f8="[object Arguments]",RI="[object Array]",DI="[object Boolean]",OI="[object Date]",BI="[object Error]",m8="[object Function]",PI="[object GeneratorFunction]",FI="[object Map]",qI="[object Number]",p8="[object Object]",HI="[object RegExp]",UI="[object Set]",$I="[object String]",jI="[object Symbol]",GI="[object WeakMap]",WI="[object ArrayBuffer]",VI="[object DataView]",YI="[object Float32Array]",XI="[object Float64Array]",KI="[object Int8Array]",ZI="[object Int16Array]",QI="[object Int32Array]",JI="[object Uint8Array]",ez="[object Uint8ClampedArray]",tz="[object Uint16Array]",iz="[object Uint32Array]",Pe={};Pe[f8]=Pe[RI]=Pe[WI]=Pe[VI]=Pe[DI]=Pe[OI]=Pe[YI]=Pe[XI]=Pe[KI]=Pe[ZI]=Pe[QI]=Pe[FI]=Pe[qI]=Pe[p8]=Pe[HI]=Pe[UI]=Pe[$I]=Pe[jI]=Pe[JI]=Pe[ez]=Pe[tz]=Pe[iz]=!0;Pe[BI]=Pe[m8]=Pe[GI]=!1;g8=Nd});function sz(i){return g8(i,rz|nz)}var rz,nz,gr,y8=T(()=>{x8();rz=1,nz=4;gr=sz});function oz(i){return this.__data__.set(i,az),this}var az,v8,b8=T(()=>{az="__lodash_hash_undefined__";v8=oz});function lz(i){return this.__data__.has(i)}var w8,M8=T(()=>{w8=lz});function Ed(i){var e=-1,t=i==null?0:i.length;for(this.__data__=new hd;++e{uf();b8();M8();Ed.prototype.add=Ed.prototype.push=v8;Ed.prototype.has=w8;T8=Ed});function hz(i,e){for(var t=-1,r=i==null?0:i.length;++t{E8=hz});function dz(i,e){return i.has(e)}var A8,k8=T(()=>{A8=dz});function fz(i,e,t,r,n,s){var a=t&cz,o=i.length,l=e.length;if(o!=l&&!(a&&l>o))return!1;var h=s.get(i),d=s.get(e);if(h&&d)return h==e&&d==i;var c=-1,f=!0,m=t&uz?new T8:void 0;for(s.set(i,e),s.set(e,i);++c{N8();S8();k8();cz=1,uz=2;Sd=fz});function mz(i){var e=-1,t=Array(i.size);return i.forEach(function(r,n){t[++e]=[n,r]}),t}var C8,_8=T(()=>{C8=mz});function pz(i){var e=-1,t=Array(i.size);return i.forEach(function(r){t[++e]=r}),t}var L8,I8=T(()=>{L8=pz});function Cz(i,e,t,r,n,s,a){switch(t){case kz:if(i.byteLength!=e.byteLength||i.byteOffset!=e.byteOffset)return!1;i=i.buffer,e=e.buffer;case Az:return!(i.byteLength!=e.byteLength||!s(new Da(i),new Da(e)));case yz:case vz:case Mz:return fr(+i,+e);case bz:return i.name==e.name&&i.message==e.message;case Tz:case Ez:return i==e+"";case wz:var o=C8;case Nz:var l=r&gz;if(o||(o=L8),i.size!=e.size&&!l)return!1;var h=a.get(i);if(h)return h==e;r|=xz,a.set(i,e);var d=Sd(o(i),o(e),r,n,s,a);return a.delete(i),d;case Sz:if(Tf)return Tf.call(i)==Tf.call(e)}return!1}var gz,xz,yz,vz,bz,wz,Mz,Tz,Nz,Ez,Sz,Az,kz,z8,Tf,R8,D8=T(()=>{dl();vf();Ma();Mf();_8();I8();gz=1,xz=2,yz="[object Boolean]",vz="[object Date]",bz="[object Error]",wz="[object Map]",Mz="[object Number]",Tz="[object RegExp]",Nz="[object Set]",Ez="[object String]",Sz="[object Symbol]",Az="[object ArrayBuffer]",kz="[object DataView]",z8=Li?Li.prototype:void 0,Tf=z8?z8.valueOf:void 0;R8=Cz});function zz(i,e,t,r,n,s){var a=t&_z,o=bl(i),l=o.length,h=bl(e),d=h.length;if(l!=d&&!a)return!1;for(var c=l;c--;){var f=o[c];if(!(a?f in e:Iz.call(e,f)))return!1}var m=s.get(i),g=s.get(e);if(m&&g)return m==e&&g==i;var x=!0;s.set(i,e),s.set(e,i);for(var y=a;++c{yf();_z=1,Lz=Object.prototype,Iz=Lz.hasOwnProperty;O8=zz});function Oz(i,e,t,r,n,s){var a=Ii(i),o=Ii(e),l=a?F8:Ur(i),h=o?F8:Ur(e);l=l==P8?Ad:l,h=h==P8?Ad:h;var d=l==Ad,c=h==Ad,f=l==h;if(f&&Fr(i)){if(!Fr(e))return!1;a=!0,d=!1}if(f&&!d)return s||(s=new Sn),a||Sa(i)?Sd(i,e,t,r,n,s):R8(i,e,l,t,r,n,s);if(!(t&Rz)){var m=d&&q8.call(i,"__wrapped__"),g=c&&q8.call(e,"__wrapped__");if(m||g){var x=m?i.value():i,y=g?e.value():e;return s||(s=new Sn),n(x,y,t,r,s)}}return f?(s||(s=new Sn),O8(i,e,t,r,n,s)):!1}var Rz,P8,F8,Ad,Dz,q8,H8,U8=T(()=>{ud();Mf();D8();B8();wl();ya();ml();nd();Rz=1,P8="[object Arguments]",F8="[object Array]",Ad="[object Object]",Dz=Object.prototype,q8=Dz.hasOwnProperty;H8=Oz});function $8(i,e,t,r,n){return i===e?!0:i==null||e==null||!Mt(i)&&!Mt(e)?i!==i&&e!==e:H8(i,e,t,r,$8,n)}var j8,G8=T(()=>{U8();Or();j8=$8});function Bz(i){return function(e,t,r){for(var n=-1,s=Object(e),a=r(e),o=a.length;o--;){var l=a[i?o:++n];if(t(s[l],l,s)===!1)break}return e}}var W8,V8=T(()=>{W8=Bz});var Pz,Y8,X8=T(()=>{V8();Pz=W8(),Y8=Pz});function Fz(i,e,t){(t!==void 0&&!fr(i[e],t)||t===void 0&&!(e in i))&&wa(i,e,t)}var Ml,Nf=T(()=>{Qh();Ma();Ml=Fz});function qz(i){return Mt(i)&&wn(i)}var K8,Z8=T(()=>{ul();Or();K8=qz});function Hz(i,e){if(!(e==="constructor"&&typeof i[e]=="function")&&e!="__proto__")return i[e]}var Tl,Ef=T(()=>{Tl=Hz});function Uz(i){return mr(i,pr(i))}var Q8,J8=T(()=>{Ta();ka();Q8=Uz});function $z(i,e,t,r,n,s,a){var o=Tl(i,t),l=Tl(e,t),h=a.get(l);if(h){Ml(i,t,h);return}var d=s?s(o,l,t+"",i,e,a):void 0,c=d===void 0;if(c){var f=Ii(l),m=!f&&Fr(l),g=!f&&!m&&Sa(l);d=l,f||m||g?Ii(o)?d=o:K8(o)?d=Kh(o):m?(c=!1,d=fd(l,!0)):g?(c=!1,d=Md(l,!0)):d=[]:l7(l)||fl(l)?(d=o,fl(o)?d=Q8(o):(!St(o)||va(o))&&(d=Td(l))):c=!1}c&&(a.set(l,d),n(d,l,r,s,a),a.delete(l)),Ml(i,t,d)}var ex,tx=T(()=>{Nf();mf();bf();ef();wf();of();ya();Z8();ml();Vh();Br();h7();nd();Ef();J8();ex=$z});function ix(i,e,t,r,n){i!==e&&Y8(e,function(s,a){if(n||(n=new Sn),St(s))ex(i,e,a,t,ix,r,n);else{var o=r?r(Tl(i,a),s,a+"",i,e,n):void 0;o===void 0&&(o=s),Ml(i,a,o)}},pr)}var rx,nx=T(()=>{ud();Nf();X8();tx();Br();ka();Ef();rx=ix});function jz(i,e){return j8(i,e)}var ys,sx=T(()=>{G8();ys=jz});var Gz,si,ax=T(()=>{nx();a5();Gz=s5(function(i,e,t){rx(i,e,t)}),si=Gz});var An=T(()=>{y8();sx();ax();});var Sl={};tt(Sl,{Attributor:()=>qt,AttributorStore:()=>Nl,BlockBlot:()=>vs,ClassAttributor:()=>dt,ContainerBlot:()=>Ha,EmbedBlot:()=>Ze,InlineBlot:()=>kd,LeafBlot:()=>ct,ParentBlot:()=>ai,Registry:()=>_n,Scope:()=>X,ScrollBlot:()=>El,StyleAttributor:()=>oi,TextBlot:()=>Ua});function ox(i,e){return(i.getAttribute("class")||"").split(/\s+/).filter(t=>t.indexOf(`${e}-`)===0)}function Sf(i){let e=i.split("-"),t=e.slice(1).map(r=>r[0].toUpperCase()+r.slice(1)).join("");return e[0]+t}function lx(i,e){let t=e.find(i);if(t)return t;try{return e.create(i)}catch{let r=e.create(X.INLINE);return Array.from(i.childNodes).forEach(n=>{r.domNode.appendChild(n)}),i.parentNode&&i.parentNode.replaceChild(r.domNode,i),r.attach(),r}}function Yz(i,e){if(Object.keys(i).length!==Object.keys(e).length)return!1;for(let t in i)if(i[t]!==e[t])return!1;return!0}var X,qt,Cn,hx,_n,kf,dt,Cf,oi,_f,Nl,dx,cx,ux,Wz,ct,Lf,fx,Vz,ai,Ba,Xz,kd,Fa,Kz,vs,zf,Zz,Ha,Rf,Ze,Qz,Jz,qa,eR,El,Df,tR,Ua,De=T(()=>{X=(i=>(i[i.TYPE=3]="TYPE",i[i.LEVEL=12]="LEVEL",i[i.ATTRIBUTE=13]="ATTRIBUTE",i[i.BLOT=14]="BLOT",i[i.INLINE=7]="INLINE",i[i.BLOCK=11]="BLOCK",i[i.BLOCK_BLOT=10]="BLOCK_BLOT",i[i.INLINE_BLOT=6]="INLINE_BLOT",i[i.BLOCK_ATTRIBUTE=9]="BLOCK_ATTRIBUTE",i[i.INLINE_ATTRIBUTE=5]="INLINE_ATTRIBUTE",i[i.ANY=15]="ANY",i))(X||{}),qt=class{constructor(e,t,r={}){this.attrName=e,this.keyName=t;let n=X.TYPE&X.ATTRIBUTE;this.scope=r.scope!=null?r.scope&X.LEVEL|n:X.ATTRIBUTE,r.whitelist!=null&&(this.whitelist=r.whitelist)}static keys(e){return Array.from(e.attributes).map(t=>t.name)}add(e,t){return this.canAdd(e,t)?(e.setAttribute(this.keyName,t),!0):!1}canAdd(e,t){return this.whitelist==null?!0:typeof t=="string"?this.whitelist.indexOf(t.replace(/["']/g,""))>-1:this.whitelist.indexOf(t)>-1}remove(e){e.removeAttribute(this.keyName)}value(e){let t=e.getAttribute(this.keyName);return this.canAdd(e,t)&&t?t:""}},Cn=class extends Error{constructor(e){e="[Parchment] "+e,super(e),this.message=e,this.name=this.constructor.name}},hx=class Af{constructor(){this.attributes={},this.classes={},this.tags={},this.types={}}static find(e,t=!1){if(e==null)return null;if(this.blots.has(e))return this.blots.get(e)||null;if(t){let r=null;try{r=e.parentNode}catch{return null}return this.find(r,t)}return null}create(e,t,r){let n=this.query(t);if(n==null)throw new Cn(`Unable to create ${t} blot`);let s=n,a=t instanceof Node||t.nodeType===Node.TEXT_NODE?t:s.create(r),o=new s(e,a,r);return Af.blots.set(o.domNode,o),o}find(e,t=!1){return Af.find(e,t)}query(e,t=X.ANY){let r;return typeof e=="string"?r=this.types[e]||this.attributes[e]:e instanceof Text||e.nodeType===Node.TEXT_NODE?r=this.types.text:typeof e=="number"?e&X.LEVEL&X.BLOCK?r=this.types.block:e&X.LEVEL&X.INLINE&&(r=this.types.inline):e instanceof Element&&((e.getAttribute("class")||"").split(/\s+/).some(n=>(r=this.classes[n],!!r)),r=r||this.tags[e.tagName]),r==null?null:"scope"in r&&t&X.LEVEL&r.scope&&t&X.TYPE&r.scope?r:null}register(...e){return e.map(t=>{let r="blotName"in t,n="attrName"in t;if(!r&&!n)throw new Cn("Invalid definition");if(r&&t.blotName==="abstract")throw new Cn("Cannot register abstract class");let s=r?t.blotName:n?t.attrName:void 0;return this.types[s]=t,n?typeof t.keyName=="string"&&(this.attributes[t.keyName]=t):r&&(t.className&&(this.classes[t.className]=t),t.tagName&&(Array.isArray(t.tagName)?t.tagName=t.tagName.map(a=>a.toUpperCase()):t.tagName=t.tagName.toUpperCase(),(Array.isArray(t.tagName)?t.tagName:[t.tagName]).forEach(a=>{(this.tags[a]==null||t.className==null)&&(this.tags[a]=t)}))),t})}};hx.blots=new WeakMap;_n=hx;kf=class extends qt{static keys(e){return(e.getAttribute("class")||"").split(/\s+/).map(t=>t.split("-").slice(0,-1).join("-"))}add(e,t){return this.canAdd(e,t)?(this.remove(e),e.classList.add(`${this.keyName}-${t}`),!0):!1}remove(e){ox(e,this.keyName).forEach(t=>{e.classList.remove(t)}),e.classList.length===0&&e.removeAttribute("class")}value(e){let t=(ox(e,this.keyName)[0]||"").slice(this.keyName.length+1);return this.canAdd(e,t)?t:""}},dt=kf;Cf=class extends qt{static keys(e){return(e.getAttribute("style")||"").split(";").map(t=>t.split(":")[0].trim())}add(e,t){return this.canAdd(e,t)?(e.style[Sf(this.keyName)]=t,!0):!1}remove(e){e.style[Sf(this.keyName)]="",e.getAttribute("style")||e.removeAttribute("style")}value(e){let t=e.style[Sf(this.keyName)];return this.canAdd(e,t)?t:""}},oi=Cf,_f=class{constructor(e){this.attributes={},this.domNode=e,this.build()}attribute(e,t){t?e.add(this.domNode,t)&&(e.value(this.domNode)!=null?this.attributes[e.attrName]=e:delete this.attributes[e.attrName]):(e.remove(this.domNode),delete this.attributes[e.attrName])}build(){this.attributes={};let e=_n.find(this.domNode);if(e==null)return;let t=qt.keys(this.domNode),r=dt.keys(this.domNode),n=oi.keys(this.domNode);t.concat(r).concat(n).forEach(s=>{let a=e.scroll.query(s,X.ATTRIBUTE);a instanceof qt&&(this.attributes[a.attrName]=a)})}copy(e){Object.keys(this.attributes).forEach(t=>{let r=this.attributes[t].value(this.domNode);e.format(t,r)})}move(e){this.copy(e),Object.keys(this.attributes).forEach(t=>{this.attributes[t].remove(this.domNode)}),this.attributes={}}values(){return Object.keys(this.attributes).reduce((e,t)=>(e[t]=this.attributes[t].value(this.domNode),e),{})}},Nl=_f,dx=class{constructor(e,t){this.scroll=e,this.domNode=t,_n.blots.set(t,this),this.prev=null,this.next=null}static create(e){if(this.tagName==null)throw new Cn("Blot definition missing tagName");let t,r;return Array.isArray(this.tagName)?(typeof e=="string"?(r=e.toUpperCase(),parseInt(r,10).toString()===r&&(r=parseInt(r,10))):typeof e=="number"&&(r=e),typeof r=="number"?t=document.createElement(this.tagName[r-1]):r&&this.tagName.indexOf(r)>-1?t=document.createElement(r):t=document.createElement(this.tagName[0])):t=document.createElement(this.tagName),this.className&&t.classList.add(this.className),t}get statics(){return this.constructor}attach(){}clone(){let e=this.domNode.cloneNode(!1);return this.scroll.create(e)}detach(){this.parent!=null&&this.parent.removeChild(this),_n.blots.delete(this.domNode)}deleteAt(e,t){this.isolate(e,t).remove()}formatAt(e,t,r,n){let s=this.isolate(e,t);if(this.scroll.query(r,X.BLOT)!=null&&n)s.wrap(r,n);else if(this.scroll.query(r,X.ATTRIBUTE)!=null){let a=this.scroll.create(this.statics.scope);s.wrap(a),a.format(r,n)}}insertAt(e,t,r){let n=r==null?this.scroll.create("text",t):this.scroll.create(t,r),s=this.split(e);this.parent.insertBefore(n,s||void 0)}isolate(e,t){let r=this.split(e);if(r==null)throw new Error("Attempt to isolate at end");return r.split(t),r}length(){return 1}offset(e=this.parent){return this.parent==null||this===e?0:this.parent.children.offset(this)+this.parent.offset(e)}optimize(e){this.statics.requiredContainer&&!(this.parent instanceof this.statics.requiredContainer)&&this.wrap(this.statics.requiredContainer.blotName)}remove(){this.domNode.parentNode!=null&&this.domNode.parentNode.removeChild(this.domNode),this.detach()}replaceWith(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;return this.parent!=null&&(this.parent.insertBefore(r,this.next||void 0),this.remove()),r}split(e,t){return e===0?this:this.next}update(e,t){}wrap(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;if(this.parent!=null&&this.parent.insertBefore(r,this.next||void 0),typeof r.appendChild!="function")throw new Cn(`Cannot wrap ${e}`);return r.appendChild(this),r}};dx.blotName="abstract";cx=dx,ux=class extends cx{static value(e){return!0}index(e,t){return this.domNode===e||this.domNode.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_CONTAINED_BY?Math.min(t,1):-1}position(e,t){let r=Array.from(this.parent.domNode.childNodes).indexOf(this.domNode);return e>0&&(r+=1),[this.parent.domNode,r]}value(){return{[this.statics.blotName]:this.statics.value(this.domNode)||!0}}};ux.scope=X.INLINE_BLOT;Wz=ux,ct=Wz,Lf=class{constructor(){this.head=null,this.tail=null,this.length=0}append(...e){if(this.insertBefore(e[0],null),e.length>1){let t=e.slice(1);this.append(...t)}}at(e){let t=this.iterator(),r=t();for(;r&&e>0;)e-=1,r=t();return r}contains(e){let t=this.iterator(),r=t();for(;r;){if(r===e)return!0;r=t()}return!1}indexOf(e){let t=this.iterator(),r=t(),n=0;for(;r;){if(r===e)return n;n+=1,r=t()}return-1}insertBefore(e,t){e!=null&&(this.remove(e),e.next=t,t!=null?(e.prev=t.prev,t.prev!=null&&(t.prev.next=e),t.prev=e,t===this.head&&(this.head=e)):this.tail!=null?(this.tail.next=e,e.prev=this.tail,this.tail=e):(e.prev=null,this.head=this.tail=e),this.length+=1)}offset(e){let t=0,r=this.head;for(;r!=null;){if(r===e)return t;t+=r.length(),r=r.next}return-1}remove(e){this.contains(e)&&(e.prev!=null&&(e.prev.next=e.next),e.next!=null&&(e.next.prev=e.prev),e===this.head&&(this.head=e.next),e===this.tail&&(this.tail=e.prev),this.length-=1)}iterator(e=this.head){return()=>{let t=e;return e!=null&&(e=e.next),t}}find(e,t=!1){let r=this.iterator(),n=r();for(;n;){let s=n.length();if(ea?r(l,e-a,Math.min(t,a+h-e)):r(l,0,Math.min(h,e+t-a)),a+=h,l=o()}}map(e){return this.reduce((t,r)=>(t.push(e(r)),t),[])}reduce(e,t){let r=this.iterator(),n=r();for(;n;)t=e(t,n),n=r();return t}};fx=class kn extends cx{constructor(e,t){super(e,t),this.uiNode=null,this.build()}appendChild(e){this.insertBefore(e)}attach(){super.attach(),this.children.forEach(e=>{e.attach()})}attachUI(e){this.uiNode!=null&&this.uiNode.remove(),this.uiNode=e,kn.uiClass&&this.uiNode.classList.add(kn.uiClass),this.uiNode.setAttribute("contenteditable","false"),this.domNode.insertBefore(this.uiNode,this.domNode.firstChild)}build(){this.children=new Lf,Array.from(this.domNode.childNodes).filter(e=>e!==this.uiNode).reverse().forEach(e=>{try{let t=lx(e,this.scroll);this.insertBefore(t,this.children.head||void 0)}catch(t){if(t instanceof Cn)return;throw t}})}deleteAt(e,t){if(e===0&&t===this.length())return this.remove();this.children.forEachAt(e,t,(r,n,s)=>{r.deleteAt(n,s)})}descendant(e,t=0){let[r,n]=this.children.find(t);return e.blotName==null&&e(r)||e.blotName!=null&&r instanceof e?[r,n]:r instanceof kn?r.descendant(e,n):[null,-1]}descendants(e,t=0,r=Number.MAX_VALUE){let n=[],s=r;return this.children.forEachAt(t,r,(a,o,l)=>{(e.blotName==null&&e(a)||e.blotName!=null&&a instanceof e)&&n.push(a),a instanceof kn&&(n=n.concat(a.descendants(e,o,s))),s-=l}),n}detach(){this.children.forEach(e=>{e.detach()}),super.detach()}enforceAllowedChildren(){let e=!1;this.children.forEach(t=>{e||this.statics.allowedChildren.some(r=>t instanceof r)||(t.statics.scope===X.BLOCK_BLOT?(t.next!=null&&this.splitAfter(t),t.prev!=null&&this.splitAfter(t.prev),t.parent.unwrap(),e=!0):t instanceof kn?t.unwrap():t.remove())})}formatAt(e,t,r,n){this.children.forEachAt(e,t,(s,a,o)=>{s.formatAt(a,o,r,n)})}insertAt(e,t,r){let[n,s]=this.children.find(e);if(n)n.insertAt(s,t,r);else{let a=r==null?this.scroll.create("text",t):this.scroll.create(t,r);this.appendChild(a)}}insertBefore(e,t){e.parent!=null&&e.parent.children.remove(e);let r=null;this.children.insertBefore(e,t||null),e.parent=this,t!=null&&(r=t.domNode),(this.domNode.parentNode!==e.domNode||this.domNode.nextSibling!==r)&&this.domNode.insertBefore(e.domNode,r),e.attach()}length(){return this.children.reduce((e,t)=>e+t.length(),0)}moveChildren(e,t){this.children.forEach(r=>{e.insertBefore(r,t)})}optimize(e){if(super.optimize(e),this.enforceAllowedChildren(),this.uiNode!=null&&this.uiNode!==this.domNode.firstChild&&this.domNode.insertBefore(this.uiNode,this.domNode.firstChild),this.children.length===0)if(this.statics.defaultChild!=null){let t=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(t)}else this.remove()}path(e,t=!1){let[r,n]=this.children.find(e,t),s=[[this,e]];return r instanceof kn?s.concat(r.path(n,t)):(r!=null&&s.push([r,n]),s)}removeChild(e){this.children.remove(e)}replaceWith(e,t){let r=typeof e=="string"?this.scroll.create(e,t):e;return r instanceof kn&&this.moveChildren(r),super.replaceWith(r)}split(e,t=!1){if(!t){if(e===0)return this;if(e===this.length())return this.next}let r=this.clone();return this.parent&&this.parent.insertBefore(r,this.next||void 0),this.children.forEachAt(e,this.length(),(n,s,a)=>{let o=n.split(s,t);o!=null&&r.appendChild(o)}),r}splitAfter(e){let t=this.clone();for(;e.next!=null;)t.appendChild(e.next);return this.parent&&this.parent.insertBefore(t,this.next||void 0),t}unwrap(){this.parent&&this.moveChildren(this.parent,this.next||void 0),this.remove()}update(e,t){let r=[],n=[];e.forEach(s=>{s.target===this.domNode&&s.type==="childList"&&(r.push(...s.addedNodes),n.push(...s.removedNodes))}),n.forEach(s=>{if(s.parentNode!=null&&s.tagName!=="IFRAME"&&document.body.compareDocumentPosition(s)&Node.DOCUMENT_POSITION_CONTAINED_BY)return;let a=this.scroll.find(s);a!=null&&(a.domNode.parentNode==null||a.domNode.parentNode===this.domNode)&&a.detach()}),r.filter(s=>s.parentNode===this.domNode&&s!==this.uiNode).sort((s,a)=>s===a?0:s.compareDocumentPosition(a)&Node.DOCUMENT_POSITION_FOLLOWING?1:-1).forEach(s=>{let a=null;s.nextSibling!=null&&(a=this.scroll.find(s.nextSibling));let o=lx(s,this.scroll);(o.next!==a||o.next==null)&&(o.parent!=null&&o.parent.removeChild(this),this.insertBefore(o,a||void 0))}),this.enforceAllowedChildren()}};fx.uiClass="";Vz=fx,ai=Vz;Ba=class Pa extends ai{static create(e){return super.create(e)}static formats(e,t){let r=t.query(Pa.blotName);if(!(r!=null&&e.tagName===r.tagName)){if(typeof this.tagName=="string")return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(e,t){super(e,t),this.attributes=new Nl(this.domNode)}format(e,t){if(e===this.statics.blotName&&!t)this.children.forEach(r=>{r instanceof Pa||(r=r.wrap(Pa.blotName,!0)),this.attributes.copy(r)}),this.unwrap();else{let r=this.scroll.query(e,X.INLINE);if(r==null)return;r instanceof qt?this.attributes.attribute(r,t):t&&(e!==this.statics.blotName||this.formats()[e]!==t)&&this.replaceWith(e,t)}}formats(){let e=this.attributes.values(),t=this.statics.formats(this.domNode,this.scroll);return t!=null&&(e[this.statics.blotName]=t),e}formatAt(e,t,r,n){this.formats()[r]!=null||this.scroll.query(r,X.ATTRIBUTE)?this.isolate(e,t).format(r,n):super.formatAt(e,t,r,n)}optimize(e){super.optimize(e);let t=this.formats();if(Object.keys(t).length===0)return this.unwrap();let r=this.next;r instanceof Pa&&r.prev===this&&Yz(t,r.formats())&&(r.moveChildren(this),r.remove())}replaceWith(e,t){let r=super.replaceWith(e,t);return this.attributes.copy(r),r}update(e,t){super.update(e,t),e.some(r=>r.target===this.domNode&&r.type==="attributes")&&this.attributes.build()}wrap(e,t){let r=super.wrap(e,t);return r instanceof Pa&&this.attributes.move(r),r}};Ba.allowedChildren=[Ba,ct],Ba.blotName="inline",Ba.scope=X.INLINE_BLOT,Ba.tagName="SPAN";Xz=Ba,kd=Xz,Fa=class If extends ai{static create(e){return super.create(e)}static formats(e,t){let r=t.query(If.blotName);if(!(r!=null&&e.tagName===r.tagName)){if(typeof this.tagName=="string")return!0;if(Array.isArray(this.tagName))return e.tagName.toLowerCase()}}constructor(e,t){super(e,t),this.attributes=new Nl(this.domNode)}format(e,t){let r=this.scroll.query(e,X.BLOCK);r!=null&&(r instanceof qt?this.attributes.attribute(r,t):e===this.statics.blotName&&!t?this.replaceWith(If.blotName):t&&(e!==this.statics.blotName||this.formats()[e]!==t)&&this.replaceWith(e,t))}formats(){let e=this.attributes.values(),t=this.statics.formats(this.domNode,this.scroll);return t!=null&&(e[this.statics.blotName]=t),e}formatAt(e,t,r,n){this.scroll.query(r,X.BLOCK)!=null?this.format(r,n):super.formatAt(e,t,r,n)}insertAt(e,t,r){if(r==null||this.scroll.query(t,X.INLINE)!=null)super.insertAt(e,t,r);else{let n=this.split(e);if(n!=null){let s=this.scroll.create(t,r);n.parent.insertBefore(s,n)}else throw new Error("Attempt to insertAt after block boundaries")}}replaceWith(e,t){let r=super.replaceWith(e,t);return this.attributes.copy(r),r}update(e,t){super.update(e,t),e.some(r=>r.target===this.domNode&&r.type==="attributes")&&this.attributes.build()}};Fa.blotName="block",Fa.scope=X.BLOCK_BLOT,Fa.tagName="P",Fa.allowedChildren=[kd,Fa,ct];Kz=Fa,vs=Kz,zf=class extends ai{checkMerge(){return this.next!==null&&this.next.statics.blotName===this.statics.blotName}deleteAt(e,t){super.deleteAt(e,t),this.enforceAllowedChildren()}formatAt(e,t,r,n){super.formatAt(e,t,r,n),this.enforceAllowedChildren()}insertAt(e,t,r){super.insertAt(e,t,r),this.enforceAllowedChildren()}optimize(e){super.optimize(e),this.children.length>0&&this.next!=null&&this.checkMerge()&&(this.next.moveChildren(this),this.next.remove())}};zf.blotName="container",zf.scope=X.BLOCK_BLOT;Zz=zf,Ha=Zz,Rf=class extends ct{static formats(e,t){}format(e,t){super.formatAt(0,this.length(),e,t)}formatAt(e,t,r,n){e===0&&t===this.length()?this.format(r,n):super.formatAt(e,t,r,n)}formats(){return this.statics.formats(this.domNode,this.scroll)}},Ze=Rf,Qz={attributes:!0,characterData:!0,characterDataOldValue:!0,childList:!0,subtree:!0},Jz=100,qa=class extends ai{constructor(e,t){super(null,t),this.registry=e,this.scroll=this,this.build(),this.observer=new MutationObserver(r=>{this.update(r)}),this.observer.observe(this.domNode,Qz),this.attach()}create(e,t){return this.registry.create(this,e,t)}find(e,t=!1){let r=this.registry.find(e,t);return r?r.scroll===this?r:t?this.find(r.scroll.domNode.parentNode,!0):null:null}query(e,t=X.ANY){return this.registry.query(e,t)}register(...e){return this.registry.register(...e)}build(){this.scroll!=null&&super.build()}detach(){super.detach(),this.observer.disconnect()}deleteAt(e,t){this.update(),e===0&&t===this.length()?this.children.forEach(r=>{r.remove()}):super.deleteAt(e,t)}formatAt(e,t,r,n){this.update(),super.formatAt(e,t,r,n)}insertAt(e,t,r){this.update(),super.insertAt(e,t,r)}optimize(e=[],t={}){super.optimize(t);let r=t.mutationsMap||new WeakMap,n=Array.from(this.observer.takeRecords());for(;n.length>0;)e.push(n.pop());let s=(l,h=!0)=>{l==null||l===this||l.domNode.parentNode!=null&&(r.has(l.domNode)||r.set(l.domNode,[]),h&&s(l.parent))},a=l=>{r.has(l.domNode)&&(l instanceof ai&&l.children.forEach(a),r.delete(l.domNode),l.optimize(t))},o=e;for(let l=0;o.length>0;l+=1){if(l>=Jz)throw new Error("[Parchment] Maximum optimize iterations reached");for(o.forEach(h=>{let d=this.find(h.target,!0);d!=null&&(d.domNode===h.target&&(h.type==="childList"?(s(this.find(h.previousSibling,!1)),Array.from(h.addedNodes).forEach(c=>{let f=this.find(c,!1);s(f,!1),f instanceof ai&&f.children.forEach(m=>{s(m,!1)})})):h.type==="attributes"&&s(d.prev)),s(d))}),this.children.forEach(a),o=Array.from(this.observer.takeRecords()),n=o.slice();n.length>0;)e.push(n.pop())}}update(e,t={}){e=e||this.observer.takeRecords();let r=new WeakMap;e.map(n=>{let s=this.find(n.target,!0);return s==null?null:r.has(s.domNode)?(r.get(s.domNode).push(n),null):(r.set(s.domNode,[n]),s)}).forEach(n=>{n!=null&&n!==this&&r.has(n.domNode)&&n.update(r.get(n.domNode)||[],t)}),t.mutationsMap=r,r.has(this.domNode)&&super.update(r.get(this.domNode),t),this.optimize(e,t)}};qa.blotName="scroll",qa.defaultChild=vs,qa.allowedChildren=[vs,Ha],qa.scope=X.BLOCK_BLOT,qa.tagName="DIV";eR=qa,El=eR,Df=class mx extends ct{static create(e){return document.createTextNode(e)}static value(e){return e.data}constructor(e,t){super(e,t),this.text=this.statics.value(this.domNode)}deleteAt(e,t){this.domNode.data=this.text=this.text.slice(0,e)+this.text.slice(e+t)}index(e,t){return this.domNode===e?t:-1}insertAt(e,t,r){r==null?(this.text=this.text.slice(0,e)+t+this.text.slice(e),this.domNode.data=this.text):super.insertAt(e,t,r)}length(){return this.text.length}optimize(e){super.optimize(e),this.text=this.statics.value(this.domNode),this.text.length===0?this.remove():this.next instanceof mx&&this.next.prev===this&&(this.insertAt(this.length(),this.next.value()),this.next.remove())}position(e,t=!1){return[this.domNode,e]}split(e,t=!1){if(!t){if(e===0)return this;if(e===this.length())return this.next}let r=this.scroll.create(this.domNode.splitText(e));return this.parent.insertBefore(r,this.next||void 0),this.text=this.statics.value(this.domNode),r}update(e,t){e.some(r=>r.type==="characterData"&&r.target===this.domNode)&&(this.text=this.statics.value(this.domNode))}value(){return this.text}};Df.blotName="text",Df.scope=X.INLINE_BLOT;tR=Df,Ua=tR});var Ex=tr((cQ,Nx)=>{var gi=-1,Ht=1,pt=0;function Al(i,e,t,r,n){if(i===e)return i?[[pt,i]]:[];if(t!=null){var s=dR(i,e,t);if(s)return s}var a=Bf(i,e),o=i.substring(0,a);i=i.substring(a),e=e.substring(a),a=Cd(i,e);var l=i.substring(i.length-a);i=i.substring(0,i.length-a),e=e.substring(0,e.length-a);var h=iR(i,e);return o&&h.unshift([pt,o]),l&&h.push([pt,l]),Pf(h,n),r&&sR(h),h}function iR(i,e){var t;if(!i)return[[Ht,e]];if(!e)return[[gi,i]];var r=i.length>e.length?i:e,n=i.length>e.length?e:i,s=r.indexOf(n);if(s!==-1)return t=[[Ht,r.substring(0,s)],[pt,n],[Ht,r.substring(s+n.length)]],i.length>e.length&&(t[0][0]=t[2][0]=gi),t;if(n.length===1)return[[gi,i],[Ht,e]];var a=nR(i,e);if(a){var o=a[0],l=a[1],h=a[2],d=a[3],c=a[4],f=Al(o,h),m=Al(l,d);return f.concat([[pt,c]],m)}return rR(i,e)}function rR(i,e){for(var t=i.length,r=e.length,n=Math.ceil((t+r)/2),s=n,a=2*n,o=new Array(a),l=new Array(a),h=0;ht)m+=2;else if(L>r)f+=2;else if(c){var I=s+d-b;if(I>=0&&I=O)return px(i,e,k,L)}}}for(var q=-y+g;q<=y-x;q+=2){var I=s+q,O;q===-y||q!==y&&l[I-1]t)x+=2;else if(F>r)g+=2;else if(!c){var E=s+d-q;if(E>=0&&E=O)return px(i,e,k,L)}}}}return[[gi,i],[Ht,e]]}function px(i,e,t,r){var n=i.substring(0,t),s=e.substring(0,r),a=i.substring(t),o=e.substring(r),l=Al(n,s),h=Al(a,o);return l.concat(h)}function Bf(i,e){if(!i||!e||i.charAt(0)!==e.charAt(0))return 0;for(var t=0,r=Math.min(i.length,e.length),n=r,s=0;tr?i=i.substring(t-r):te.length?i:e,r=i.length>e.length?e:i;if(t.length<4||r.length*2=m.length?[k,L,I,O,E]:null}var s=n(t,r,Math.ceil(t.length/4)),a=n(t,r,Math.ceil(t.length/2)),o;if(!s&&!a)return null;a?s?o=s[4].length>a[4].length?s:a:o=a:o=s;var l,h,d,c;i.length>e.length?(l=o[0],h=o[1],d=o[2],c=o[3]):(d=o[0],c=o[1],l=o[2],h=o[3]);var f=o[4];return[l,h,d,c,f]}function sR(i){for(var e=!1,t=[],r=0,n=null,s=0,a=0,o=0,l=0,h=0;s0?t[r-1]:-1,a=0,o=0,l=0,h=0,n=null,e=!0)),s++;for(e&&Pf(i),lR(i),s=1;s=m?(f>=d.length/2||f>=c.length/2)&&(i.splice(s,0,[pt,c.substring(0,f)]),i[s-1][1]=d.substring(0,d.length-f),i[s+1][1]=c.substring(f),s++):(m>=d.length/2||m>=c.length/2)&&(i.splice(s,0,[pt,d.substring(0,m)]),i[s-1][0]=Ht,i[s-1][1]=c.substring(0,c.length-m),i[s+1][0]=gi,i[s+1][1]=d.substring(m),s++),s++}s++}}var xx=/[^a-zA-Z0-9]/,yx=/\s/,vx=/[\r\n]/,aR=/\n\r?\n$/,oR=/^\r?\n\r?\n/;function lR(i){function e(m,g){if(!m||!g)return 6;var x=m.charAt(m.length-1),y=g.charAt(0),b=x.match(xx),E=y.match(xx),k=b&&x.match(yx),L=E&&y.match(yx),I=k&&x.match(vx),O=L&&y.match(vx),q=I&&m.match(aR),F=O&&g.match(oR);return q||F?5:I||O?4:b&&!k&&L?3:k||L?2:b||E?1:0}for(var t=1;t=c&&(c=f,l=r,h=n,d=s)}i[t-1][1]!=l&&(l?i[t-1][1]=l:(i.splice(t-1,1),t--),i[t][1]=h,d?i[t+1][1]=d:(i.splice(t+1,1),t--))}t++}}function Pf(i,e){i.push([pt,""]);for(var t=0,r=0,n=0,s="",a="",o;t=0&&Tx(i[l][1])){var h=i[l][1].slice(-1);if(i[l][1]=i[l][1].slice(0,-1),s=h+s,a=h+a,!i[l][1]){i.splice(l,1),t--;var d=l-1;i[d]&&i[d][0]===Ht&&(n++,a=i[d][1]+a,d--),i[d]&&i[d][0]===gi&&(r++,s=i[d][1]+s,d--),l=d}}if(Mx(i[t][1])){var h=i[t][1].charAt(0);i[t][1]=i[t][1].slice(1),s+=h,a+=h}}if(t0||a.length>0){s.length>0&&a.length>0&&(o=Bf(a,s),o!==0&&(l>=0?i[l][1]+=a.substring(0,o):(i.splice(0,0,[pt,a.substring(0,o)]),t++),a=a.substring(o),s=s.substring(o)),o=Cd(a,s),o!==0&&(i[t][1]=a.substring(a.length-o)+i[t][1],a=a.substring(0,a.length-o),s=s.substring(0,s.length-o)));var c=n+r;s.length===0&&a.length===0?(i.splice(t-c,c),t=t-c):s.length===0?(i.splice(t-c,c,[Ht,a]),t=t-c+1):a.length===0?(i.splice(t-c,c,[gi,s]),t=t-c+1):(i.splice(t-c,c,[gi,s],[Ht,a]),t=t-c+2)}t!==0&&i[t-1][0]===pt?(i[t-1][1]+=i[t][1],i.splice(t,1)):t++,n=0,r=0,s="",a="";break}}i[i.length-1][1]===""&&i.pop();var f=!1;for(t=1;t=55296&&i<=56319}function wx(i){return i>=56320&&i<=57343}function Mx(i){return wx(i.charCodeAt(0))}function Tx(i){return bx(i.charCodeAt(i.length-1))}function hR(i){for(var e=[],t=0;t0&&e.push(i[t]);return e}function Of(i,e,t,r){return Tx(i)||Mx(r)?null:hR([[pt,i],[gi,e],[Ht,t],[pt,r]])}function dR(i,e,t){var r=typeof t=="number"?{index:t,length:0}:t.oldRange,n=typeof t=="number"?null:t.newRange,s=i.length,a=e.length;if(r.length===0&&(n===null||n.length===0)){var o=r.index,l=i.slice(0,o),h=i.slice(o),d=n?n.index:null;e:{var c=o+a-s;if(d!==null&&d!==c||c<0||c>a)break e;var f=e.slice(0,c),m=e.slice(c);if(m!==h)break e;var g=Math.min(o,c),x=l.slice(0,g),y=f.slice(0,g);if(x!==y)break e;var b=l.slice(g),E=f.slice(g);return Of(x,b,E,h)}e:{if(d!==null&&d!==o)break e;var k=o,f=e.slice(0,k),m=e.slice(k);if(f!==l)break e;var L=Math.min(s-k,a-k),I=h.slice(h.length-L),O=m.slice(m.length-L);if(I!==O)break e;var b=h.slice(0,h.length-L),E=m.slice(0,m.length-L);return Of(l,b,E,I)}}if(r.length>0&&n&&n.length===0)e:{var x=i.slice(0,r.index),I=i.slice(r.index+r.length),g=x.length,L=I.length;if(a{var cR=200,Bx="__lodash_hash_undefined__",Px=9007199254740991,Wf="[object Arguments]",uR="[object Array]",Fx="[object Boolean]",qx="[object Date]",fR="[object Error]",Vf="[object Function]",Hx="[object GeneratorFunction]",Ld="[object Map]",Ux="[object Number]",Yf="[object Object]",Sx="[object Promise]",$x="[object RegExp]",Id="[object Set]",jx="[object String]",Gx="[object Symbol]",qf="[object WeakMap]",Wx="[object ArrayBuffer]",zd="[object DataView]",Vx="[object Float32Array]",Yx="[object Float64Array]",Xx="[object Int8Array]",Kx="[object Int16Array]",Zx="[object Int32Array]",Qx="[object Uint8Array]",Jx="[object Uint8ClampedArray]",e9="[object Uint16Array]",t9="[object Uint32Array]",mR=/[\\^$.*+?()[\]{}|]/g,pR=/\w*$/,gR=/^\[object .+?Constructor\]$/,xR=/^(?:0|[1-9]\d*)$/,Fe={};Fe[Wf]=Fe[uR]=Fe[Wx]=Fe[zd]=Fe[Fx]=Fe[qx]=Fe[Vx]=Fe[Yx]=Fe[Xx]=Fe[Kx]=Fe[Zx]=Fe[Ld]=Fe[Ux]=Fe[Yf]=Fe[$x]=Fe[Id]=Fe[jx]=Fe[Gx]=Fe[Qx]=Fe[Jx]=Fe[e9]=Fe[t9]=!0;Fe[fR]=Fe[Vf]=Fe[qf]=!1;var yR=typeof global=="object"&&global&&global.Object===Object&&global,vR=typeof self=="object"&&self&&self.Object===Object&&self,$r=yR||vR||Function("return this")(),i9=typeof kl=="object"&&kl&&!kl.nodeType&&kl,Ax=i9&&typeof $a=="object"&&$a&&!$a.nodeType&&$a,bR=Ax&&Ax.exports===i9;function wR(i,e){return i.set(e[0],e[1]),i}function MR(i,e){return i.add(e),i}function TR(i,e){for(var t=-1,r=i?i.length:0;++t-1}function KR(i,e){var t=this.__data__,r=Od(t,i);return r<0?t.push([i,e]):t[r][1]=e,this}jr.prototype.clear=WR;jr.prototype.delete=VR;jr.prototype.get=YR;jr.prototype.has=XR;jr.prototype.set=KR;function ja(i){var e=-1,t=i?i.length:0;for(this.clear();++e-1&&i%1==0&&i-1&&i%1==0&&i<=Px}function Pd(i){var e=typeof i;return!!i&&(e=="object"||e=="function")}function DD(i){return!!i&&typeof i=="object"}function Qf(i){return c9(i)?oD(i):fD(i)}function OD(){return[]}function BD(){return!1}$a.exports=_D});var cm=tr((Ll,Ya)=>{var PD=200,dm="__lodash_hash_undefined__",Wd=1,N9=2,E9=9007199254740991,Fd="[object Arguments]",rm="[object Array]",FD="[object AsyncFunction]",S9="[object Boolean]",A9="[object Date]",k9="[object Error]",C9="[object Function]",qD="[object GeneratorFunction]",qd="[object Map]",_9="[object Number]",HD="[object Null]",Va="[object Object]",f9="[object Promise]",UD="[object Proxy]",L9="[object RegExp]",Hd="[object Set]",I9="[object String]",$D="[object Symbol]",jD="[object Undefined]",nm="[object WeakMap]",z9="[object ArrayBuffer]",Ud="[object DataView]",GD="[object Float32Array]",WD="[object Float64Array]",VD="[object Int8Array]",YD="[object Int16Array]",XD="[object Int32Array]",KD="[object Uint8Array]",ZD="[object Uint8ClampedArray]",QD="[object Uint16Array]",JD="[object Uint32Array]",eO=/[\\^$.*+?()[\]{}|]/g,tO=/^\[object .+?Constructor\]$/,iO=/^(?:0|[1-9]\d*)$/,je={};je[GD]=je[WD]=je[VD]=je[YD]=je[XD]=je[KD]=je[ZD]=je[QD]=je[JD]=!0;je[Fd]=je[rm]=je[z9]=je[S9]=je[Ud]=je[A9]=je[k9]=je[C9]=je[qd]=je[_9]=je[Va]=je[L9]=je[Hd]=je[I9]=je[nm]=!1;var R9=typeof global=="object"&&global&&global.Object===Object&&global,rO=typeof self=="object"&&self&&self.Object===Object&&self,Gr=R9||rO||Function("return this")(),D9=typeof Ll=="object"&&Ll&&!Ll.nodeType&&Ll,m9=D9&&typeof Ya=="object"&&Ya&&!Ya.nodeType&&Ya,O9=m9&&m9.exports===D9,em=O9&&R9.process,p9=(function(){try{return em&&em.binding&&em.binding("util")}catch{}})(),g9=p9&&p9.isTypedArray;function nO(i,e){for(var t=-1,r=i==null?0:i.length,n=0,s=[];++t-1}function RO(i,e){var t=this.__data__,r=Yd(t,i);return r<0?(++this.size,t.push([i,e])):t[r][1]=e,this}Wr.prototype.clear=_O;Wr.prototype.delete=LO;Wr.prototype.get=IO;Wr.prototype.has=zO;Wr.prototype.set=RO;function Es(i){var e=-1,t=i==null?0:i.length;for(this.clear();++eo))return!1;var h=s.get(i);if(h&&s.get(e))return h==e;var d=-1,c=!0,f=t&N9?new jd:void 0;for(s.set(i,e),s.set(e,i);++d-1&&i%1==0&&i-1&&i%1==0&&i<=E9}function G9(i){var e=typeof i;return i!=null&&(e=="object"||e=="function")}function Rl(i){return i!=null&&typeof i=="object"}var W9=g9?lO(g9):ZO;function cB(i){return hB(i)?VO(i):QO(i)}function uB(){return[]}function fB(){return!1}Ya.exports=dB});var V9=tr(fm=>{"use strict";Object.defineProperty(fm,"__esModule",{value:!0});var mB=Jf(),pB=cm(),um;(function(i){function e(s={},a={},o=!1){typeof s!="object"&&(s={}),typeof a!="object"&&(a={});let l=mB(a);o||(l=Object.keys(l).reduce((h,d)=>(l[d]!=null&&(h[d]=l[d]),h),{}));for(let h in s)s[h]!==void 0&&a[h]===void 0&&(l[h]=s[h]);return Object.keys(l).length>0?l:void 0}i.compose=e;function t(s={},a={}){typeof s!="object"&&(s={}),typeof a!="object"&&(a={});let o=Object.keys(s).concat(Object.keys(a)).reduce((l,h)=>(pB(s[h],a[h])||(l[h]=a[h]===void 0?null:a[h]),l),{});return Object.keys(o).length>0?o:void 0}i.diff=t;function r(s={},a={}){s=s||{};let o=Object.keys(a).reduce((l,h)=>(a[h]!==s[h]&&s[h]!==void 0&&(l[h]=a[h]),l),{});return Object.keys(s).reduce((l,h)=>(s[h]!==a[h]&&a[h]===void 0&&(l[h]=null),l),o)}i.invert=r;function n(s,a,o=!1){if(typeof s!="object")return a;if(typeof a!="object")return;if(!o)return a;let l=Object.keys(a).reduce((h,d)=>(s[d]===void 0&&(h[d]=a[d]),h),{});return Object.keys(l).length>0?l:void 0}i.transform=n})(um||(um={}));fm.default=um});var gm=tr(pm=>{"use strict";Object.defineProperty(pm,"__esModule",{value:!0});var mm;(function(i){function e(t){return typeof t.delete=="number"?t.delete:typeof t.retain=="number"?t.retain:typeof t.retain=="object"&&t.retain!==null?1:typeof t.insert=="string"?t.insert.length:1}i.length=e})(mm||(mm={}));pm.default=mm});var X9=tr(ym=>{"use strict";Object.defineProperty(ym,"__esModule",{value:!0});var Y9=gm(),xm=class{constructor(e){this.ops=e,this.index=0,this.offset=0}hasNext(){return this.peekLength()<1/0}next(e){e||(e=1/0);let t=this.ops[this.index];if(t){let r=this.offset,n=Y9.default.length(t);if(e>=n-r?(e=n-r,this.index+=1,this.offset=0):this.offset+=e,typeof t.delete=="number")return{delete:e};{let s={};return t.attributes&&(s.attributes=t.attributes),typeof t.retain=="number"?s.retain=e:typeof t.retain=="object"&&t.retain!==null?s.retain=t.retain:typeof t.insert=="string"?s.insert=t.insert.substr(r,e):s.insert=t.insert,s}}else return{retain:1/0}}peek(){return this.ops[this.index]}peekLength(){return this.ops[this.index]?Y9.default.length(this.ops[this.index])-this.offset:1/0}peekType(){let e=this.ops[this.index];return e?typeof e.delete=="number"?"delete":typeof e.retain=="number"||typeof e.retain=="object"&&e.retain!==null?"retain":"insert":"retain"}rest(){if(this.hasNext()){if(this.offset===0)return this.ops.slice(this.index);{let e=this.offset,t=this.index,r=this.next(),n=this.ops.slice(this.index);return this.offset=e,this.index=t,[r].concat(n)}}else return[]}};ym.default=xm});var xi=tr((Yr,Zd)=>{"use strict";Object.defineProperty(Yr,"__esModule",{value:!0});Yr.AttributeMap=Yr.OpIterator=Yr.Op=void 0;var Kd=Ex(),gB=Jf(),vm=cm(),As=V9();Yr.AttributeMap=As.default;var Vr=gm();Yr.Op=Vr.default;var zi=X9();Yr.OpIterator=zi.default;var xB="\0",K9=(i,e)=>{if(typeof i!="object"||i===null)throw new Error(`cannot retain a ${typeof i}`);if(typeof e!="object"||e===null)throw new Error(`cannot retain a ${typeof e}`);let t=Object.keys(i)[0];if(!t||t!==Object.keys(e)[0])throw new Error(`embed types not matched: ${t} != ${Object.keys(e)[0]}`);return[t,i[t],e[t]]},Xr=class i{constructor(e){Array.isArray(e)?this.ops=e:e!=null&&Array.isArray(e.ops)?this.ops=e.ops:this.ops=[]}static registerEmbed(e,t){this.handlers[e]=t}static unregisterEmbed(e){delete this.handlers[e]}static getHandler(e){let t=this.handlers[e];if(!t)throw new Error(`no handlers for embed type "${e}"`);return t}insert(e,t){let r={};return typeof e=="string"&&e.length===0?this:(r.insert=e,t!=null&&typeof t=="object"&&Object.keys(t).length>0&&(r.attributes=t),this.push(r))}delete(e){return e<=0?this:this.push({delete:e})}retain(e,t){if(typeof e=="number"&&e<=0)return this;let r={retain:e};return t!=null&&typeof t=="object"&&Object.keys(t).length>0&&(r.attributes=t),this.push(r)}push(e){let t=this.ops.length,r=this.ops[t-1];if(e=gB(e),typeof r=="object"){if(typeof e.delete=="number"&&typeof r.delete=="number")return this.ops[t-1]={delete:r.delete+e.delete},this;if(typeof r.delete=="number"&&e.insert!=null&&(t-=1,r=this.ops[t-1],typeof r!="object"))return this.ops.unshift(e),this;if(vm(e.attributes,r.attributes)){if(typeof e.insert=="string"&&typeof r.insert=="string")return this.ops[t-1]={insert:r.insert+e.insert},typeof e.attributes=="object"&&(this.ops[t-1].attributes=e.attributes),this;if(typeof e.retain=="number"&&typeof r.retain=="number")return this.ops[t-1]={retain:r.retain+e.retain},typeof e.attributes=="object"&&(this.ops[t-1].attributes=e.attributes),this}}return t===this.ops.length?this.ops.push(e):this.ops.splice(t,0,e),this}chop(){let e=this.ops[this.ops.length-1];return e&&typeof e.retain=="number"&&!e.attributes&&this.ops.pop(),this}filter(e){return this.ops.filter(e)}forEach(e){this.ops.forEach(e)}map(e){return this.ops.map(e)}partition(e){let t=[],r=[];return this.forEach(n=>{(e(n)?t:r).push(n)}),[t,r]}reduce(e,t){return this.ops.reduce(e,t)}changeLength(){return this.reduce((e,t)=>t.insert?e+Vr.default.length(t):t.delete?e-t.delete:e,0)}length(){return this.reduce((e,t)=>e+Vr.default.length(t),0)}slice(e=0,t=1/0){let r=[],n=new zi.default(this.ops),s=0;for(;s0&&r.next(s.retain-o)}let a=new i(n);for(;t.hasNext()||r.hasNext();)if(r.peekType()==="insert")a.push(r.next());else if(t.peekType()==="delete")a.push(t.next());else{let o=Math.min(t.peekLength(),r.peekLength()),l=t.next(o),h=r.next(o);if(h.retain){let d={};if(typeof l.retain=="number")d.retain=typeof h.retain=="number"?o:h.retain;else if(typeof h.retain=="number")l.retain==null?d.insert=l.insert:d.retain=l.retain;else{let f=l.retain==null?"insert":"retain",[m,g,x]=K9(l[f],h.retain),y=i.getHandler(m);d[f]={[m]:y.compose(g,x,f==="retain")}}let c=As.default.compose(l.attributes,h.attributes,typeof l.retain=="number");if(c&&(d.attributes=c),a.push(d),!r.hasNext()&&vm(a.ops[a.ops.length-1],d)){let f=new i(t.rest());return a.concat(f).chop()}}else typeof h.delete=="number"&&(typeof l.retain=="number"||typeof l.retain=="object"&&l.retain!==null)&&a.push(h)}return a.chop()}concat(e){let t=new i(this.ops.slice());return e.ops.length>0&&(t.push(e.ops[0]),t.ops=t.ops.concat(e.ops.slice(1))),t}diff(e,t){if(this.ops===e.ops)return new i;let r=[this,e].map(l=>l.map(h=>{if(h.insert!=null)return typeof h.insert=="string"?h.insert:xB;let d=l===e?"on":"with";throw new Error("diff() called "+d+" non-document")}).join("")),n=new i,s=Kd(r[0],r[1],t,!0),a=new zi.default(this.ops),o=new zi.default(e.ops);return s.forEach(l=>{let h=l[1].length;for(;h>0;){let d=0;switch(l[0]){case Kd.INSERT:d=Math.min(o.peekLength(),h),n.push(o.next(d));break;case Kd.DELETE:d=Math.min(h,a.peekLength()),a.next(d),n.delete(d);break;case Kd.EQUAL:d=Math.min(a.peekLength(),o.peekLength(),h);let c=a.next(d),f=o.next(d);vm(c.insert,f.insert)?n.retain(d,As.default.diff(c.attributes,f.attributes)):n.push(f).delete(d);break}h-=d}}),n.chop()}eachLine(e,t=` +`){let r=new zi.default(this.ops),n=new i,s=0;for(;r.hasNext();){if(r.peekType()!=="insert")return;let a=r.peek(),o=Vr.default.length(a)-r.peekLength(),l=typeof a.insert=="string"?a.insert.indexOf(t,o)-o:-1;if(l<0)n.push(r.next());else if(l>0)n.push(r.next(l));else{if(e(n,r.next(1).attributes||{},s)===!1)return;s+=1,n=new i}}n.length()>0&&e(n,{},s)}invert(e){let t=new i;return this.reduce((r,n)=>{if(n.insert)t.delete(Vr.default.length(n));else{if(typeof n.retain=="number"&&n.attributes==null)return t.retain(n.retain),r+n.retain;if(n.delete||typeof n.retain=="number"){let s=n.delete||n.retain;return e.slice(r,r+s).forEach(o=>{n.delete?t.push(o):n.retain&&n.attributes&&t.retain(Vr.default.length(o),As.default.invert(n.attributes,o.attributes))}),r+s}else if(typeof n.retain=="object"&&n.retain!==null){let s=e.slice(r,r+1),a=new zi.default(s.ops).next(),[o,l,h]=K9(n.retain,a.insert),d=i.getHandler(o);return t.retain({[o]:d.invert(l,h)},As.default.invert(n.attributes,a.attributes)),r+1}}return r},0),t.chop()}transform(e,t=!1){if(t=!!t,typeof e=="number")return this.transformPosition(e,t);let r=e,n=new zi.default(this.ops),s=new zi.default(r.ops),a=new i;for(;n.hasNext()||s.hasNext();)if(n.peekType()==="insert"&&(t||s.peekType()!=="insert"))a.retain(Vr.default.length(n.next()));else if(s.peekType()==="insert")a.push(s.next());else{let o=Math.min(n.peekLength(),s.peekLength()),l=n.next(o),h=s.next(o);if(l.delete)continue;if(h.delete)a.push(h);else{let d=l.retain,c=h.retain,f=typeof c=="object"&&c!==null?c:o;if(typeof d=="object"&&d!==null&&typeof c=="object"&&c!==null){let m=Object.keys(d)[0];if(m===Object.keys(c)[0]){let g=i.getHandler(m);g&&(f={[m]:g.transform(d[m],c[m],t)})}}a.retain(f,As.default.transform(l.attributes,h.attributes,t))}}return a.chop()}transformPosition(e,t=!1){t=!!t;let r=new zi.default(this.ops),n=0;for(;r.hasNext()&&n<=e;){let s=r.peekLength(),a=r.peekType();if(r.next(),a==="delete"){e-=Math.min(s,e-n);continue}else a==="insert"&&(n{De();Ol=class extends Ze{static value(){}optimize(){(this.prev||this.next)&&this.remove()}length(){return 0}value(){return""}};Ol.blotName="break";Ol.tagName="BR";At=Ol});function ks(i){return i.replace(/[&<>"']/g,e=>yB[e])}var nt,yB,Kr=T(()=>{De();nt=class extends Ua{},yB={"&":"&","<":"<",">":">",'"':""","'":"'"}});var yr,bm,kt,Zr=T(()=>{De();Rn();Kr();yr=class yr extends kd{static compare(e,t){let r=yr.order.indexOf(e),n=yr.order.indexOf(t);return r>=0||n>=0?r-n:e===t?0:e0){let t=this.parent.isolate(this.offset(),this.length());this.moveChildren(t),t.wrap(this)}}};U(yr,"allowedChildren",[yr,At,Ze,nt]),U(yr,"order",["cursor","inline","link","underline","strike","italic","bold","script","code"]);bm=yr,kt=bm});function Mm(i){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return i.descendants(ct).reduce((t,r)=>r.length()===0?t:t.insert(r.value(),li(r,{},e)),new wm.default).insert(` +`,li(i))}function li(i){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return i==null||("formats"in i&&typeof i.formats=="function"&&(e={...e,...i.formats()},t&&delete e["code-token"]),i.parent==null||i.parent.statics.blotName==="scroll"||i.parent.statics.scope!==i.statics.scope)?e:li(i.parent,e,t)}var wm,Z9,Oe,gt,Ri=T(()=>{De();wm=yt(xi(),1);Rn();Zr();Kr();Z9=1,Oe=class extends vs{constructor(){super(...arguments);U(this,"cache",{})}delta(){return this.cache.delta==null&&(this.cache.delta=Mm(this)),this.cache.delta}deleteAt(t,r){super.deleteAt(t,r),this.cache={}}formatAt(t,r,n,s){r<=0||(this.scroll.query(n,X.BLOCK)?t+r===this.length()&&this.format(n,s):super.formatAt(t,Math.min(r,this.length()-t-1),n,s),this.cache={})}insertAt(t,r,n){if(n!=null){super.insertAt(t,r,n),this.cache={};return}if(r.length===0)return;let s=r.split(` +`),a=s.shift();a.length>0&&(t(o=o.split(l,!0),o.insertAt(0,h),h.length),t+a.length)}insertBefore(t,r){let{head:n}=this.children;super.insertBefore(t,r),n instanceof At&&n.remove(),this.cache={}}length(){return this.cache.length==null&&(this.cache.length=super.length()+Z9),this.cache.length}moveChildren(t,r){super.moveChildren(t,r),this.cache={}}optimize(t){super.optimize(t),this.cache={}}path(t){return super.path(t,!0)}removeChild(t){super.removeChild(t),this.cache={}}split(t){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(r&&(t===0||t>=this.length()-Z9)){let s=this.clone();return t===0?(this.parent.insertBefore(s,this),this):(this.parent.insertBefore(s,this.next),s)}let n=super.split(t,r);return this.cache={},n}};Oe.blotName="block";Oe.tagName="P";Oe.defaultChild=At;Oe.allowedChildren=[At,kt,Ze,nt];gt=class extends Ze{attach(){super.attach(),this.attributes=new Nl(this.domNode)}delta(){return new wm.default().insert(this.value(),{...this.formats(),...this.attributes.values()})}format(e,t){let r=this.scroll.query(e,X.BLOCK_ATTRIBUTE);r!=null&&this.attributes.attribute(r,t)}formatAt(e,t,r,n){this.format(r,n)}insertAt(e,t,r){if(r!=null){super.insertAt(e,t,r);return}let n=t.split(` +`),s=n.pop(),a=n.map(l=>{let h=this.scroll.create(Oe.blotName);return h.insertAt(0,l),h}),o=this.split(e);a.forEach(l=>{this.parent.insertBefore(l,o)}),s&&this.parent.insertBefore(this.scroll.create("text",s),o)}};gt.scope=X.BLOCK_BLOT});var Di,Tm,Dn,Bl=T(()=>{De();Kr();Di=class Di extends Ze{static value(){}constructor(e,t,r){super(e,t),this.selection=r,this.textNode=document.createTextNode(Di.CONTENTS),this.domNode.appendChild(this.textNode),this.savedLength=0}detach(){this.parent!=null&&this.parent.removeChild(this)}format(e,t){if(this.savedLength!==0){super.format(e,t);return}let r=this,n=0;for(;r!=null&&r.statics.scope!==X.BLOCK_BLOT;)n+=r.offset(r.parent),r=r.parent;r!=null&&(this.savedLength=Di.CONTENTS.length,r.optimize(),r.formatAt(n,Di.CONTENTS.length,e,t),this.savedLength=0)}index(e,t){return e===this.textNode?0:super.index(e,t)}length(){return this.savedLength}position(){return[this.textNode,this.textNode.data.length]}remove(){super.remove(),this.parent=null}restore(){if(this.selection.composing||this.parent==null)return null;let e=this.selection.getNativeRange();for(;this.domNode.lastChild!=null&&this.domNode.lastChild!==this.textNode;)this.domNode.parentNode.insertBefore(this.domNode.lastChild,this.domNode);let t=this.prev instanceof nt?this.prev:null,r=t?t.length():0,n=this.next instanceof nt?this.next:null,s=n?n.text:"",{textNode:a}=this,o=a.data.split(Di.CONTENTS).join("");a.data=Di.CONTENTS;let l;if(t)l=t,(o||n)&&(t.insertAt(t.length(),o+s),n&&n.remove());else if(n)l=n,n.insertAt(0,o);else{let h=document.createTextNode(o);l=this.scroll.create(h),this.parent.insertBefore(l,this)}if(this.remove(),e){let h=(f,m)=>t&&f===t.domNode?m:f===a?r+m-1:n&&f===n.domNode?r+o.length+m:null,d=h(e.start.node,e.start.offset),c=h(e.end.node,e.end.offset);if(d!==null&&c!==null)return{startNode:l.domNode,startOffset:d,endNode:l.domNode,endOffset:c}}return null}update(e,t){if(e.some(r=>r.type==="characterData"&&r.target===this.textNode)){let r=this.restore();r&&(t.range=r)}}optimize(e){super.optimize(e);let{parent:t}=this;for(;t;){if(t.domNode.tagName==="A"){this.savedLength=Di.CONTENTS.length,t.isolate(this.offset(t),this.length()).unwrap(),this.savedLength=0;break}t=t.parent}}value(){return""}};U(Di,"blotName","cursor"),U(Di,"className","ql-cursor"),U(Di,"tagName","span"),U(Di,"CONTENTS","\uFEFF");Tm=Di,Dn=Tm});var J9=tr((RQ,Nm)=>{"use strict";var vB=Object.prototype.hasOwnProperty,Ut="~";function Pl(){}Object.create&&(Pl.prototype=Object.create(null),new Pl().__proto__||(Ut=!1));function bB(i,e,t){this.fn=i,this.context=e,this.once=t||!1}function Q9(i,e,t,r,n){if(typeof t!="function")throw new TypeError("The listener must be a function");var s=new bB(t,r||i,n),a=Ut?Ut+e:e;return i._events[a]?i._events[a].fn?i._events[a]=[i._events[a],s]:i._events[a].push(s):(i._events[a]=s,i._eventsCount++),i}function Qd(i,e){--i._eventsCount===0?i._events=new Pl:delete i._events[e]}function Ct(){this._events=new Pl,this._eventsCount=0}Ct.prototype.eventNames=function(){var e=[],t,r;if(this._eventsCount===0)return e;for(r in t=this._events)vB.call(t,r)&&e.push(Ut?r.slice(1):r);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e};Ct.prototype.listeners=function(e){var t=Ut?Ut+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var n=0,s=r.length,a=new Array(s);n{Em=yt(J9(),1)});var Fl,Sm=T(()=>{Fl=new WeakMap});function ty(i){if(km&&Am.indexOf(i)<=Am.indexOf(km)){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r(e[t]=ty.bind(console,t,i),e),{})}var Am,km,yi,Cs=T(()=>{Am=["error","warn","log","info"],km="warn";Cm.level=i=>{km=i};ty.level=Cm.level;yi=Cm});var _m,wB,ql,ee,Qr=T(()=>{ey();Sm();Cs();_m=yi("quill:events"),wB=["selectionchange","mousedown","mouseup","click"];wB.forEach(i=>{document.addEventListener(i,function(){for(var e=arguments.length,t=new Array(e),r=0;r{let s=Fl.get(n);s&&s.emitter&&s.emitter.handleDOM(...t)})})});ql=class extends Em.default{constructor(){super(),this.domListeners={},this.on("error",_m.error)}emit(){for(var e=arguments.length,t=new Array(e),r=0;r1?t-1:0),n=1;n{let{node:a,handler:o}=s;(e.target===a||a.contains(e.target))&&o(e,...r)})}listenDOM(e,t,r){this.domListeners[e]||(this.domListeners[e]=[]),this.domListeners[e].push({node:t,handler:r})}};U(ql,"events",{EDITOR_CHANGE:"editor-change",SCROLL_BEFORE_UPDATE:"scroll-before-update",SCROLL_BLOT_MOUNT:"scroll-blot-mount",SCROLL_BLOT_UNMOUNT:"scroll-blot-unmount",SCROLL_OPTIMIZE:"scroll-optimize",SCROLL_UPDATE:"scroll-update",SCROLL_EMBED_UPDATE:"scroll-embed-update",SELECTION_CHANGE:"selection-change",TEXT_CHANGE:"text-change",COMPOSITION_BEFORE_START:"composition-before-start",COMPOSITION_START:"composition-start",COMPOSITION_BEFORE_END:"composition-before-end",COMPOSITION_END:"composition-end"}),U(ql,"sources",{API:"api",SILENT:"silent",USER:"user"});ee=ql});function Im(i,e){try{e.parentNode}catch{return!1}return i.contains(e)}var Lm,$t,zm,iy,Hl=T(()=>{De();An();Qr();Cs();Lm=yi("quill:selection"),$t=class{constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;this.index=e,this.length=t}},zm=class{constructor(e,t){this.emitter=t,this.scroll=e,this.composing=!1,this.mouseDown=!1,this.root=this.scroll.domNode,this.cursor=this.scroll.create("cursor",this),this.savedRange=new $t(0,0),this.lastRange=this.savedRange,this.lastNative=null,this.handleComposition(),this.handleDragging(),this.emitter.listenDOM("selectionchange",document,()=>{!this.mouseDown&&!this.composing&&setTimeout(this.update.bind(this,ee.sources.USER),1)}),this.emitter.on(ee.events.SCROLL_BEFORE_UPDATE,()=>{if(!this.hasFocus())return;let r=this.getNativeRange();r!=null&&r.start.node!==this.cursor.textNode&&this.emitter.once(ee.events.SCROLL_UPDATE,(n,s)=>{try{this.root.contains(r.start.node)&&this.root.contains(r.end.node)&&this.setNativeRange(r.start.node,r.start.offset,r.end.node,r.end.offset);let a=s.some(o=>o.type==="characterData"||o.type==="childList"||o.type==="attributes"&&o.target===this.root);this.update(a?ee.sources.SILENT:n)}catch{}})}),this.emitter.on(ee.events.SCROLL_OPTIMIZE,(r,n)=>{if(n.range){let{startNode:s,startOffset:a,endNode:o,endOffset:l}=n.range;this.setNativeRange(s,a,o,l),this.update(ee.sources.SILENT)}}),this.update(ee.sources.SILENT)}handleComposition(){this.emitter.on(ee.events.COMPOSITION_BEFORE_START,()=>{this.composing=!0}),this.emitter.on(ee.events.COMPOSITION_END,()=>{if(this.composing=!1,this.cursor.parent){let e=this.cursor.restore();if(!e)return;setTimeout(()=>{this.setNativeRange(e.startNode,e.startOffset,e.endNode,e.endOffset)},1)}})}handleDragging(){this.emitter.listenDOM("mousedown",document.body,()=>{this.mouseDown=!0}),this.emitter.listenDOM("mouseup",document.body,()=>{this.mouseDown=!1,this.update(ee.sources.USER)})}focus(){this.hasFocus()||(this.root.focus({preventScroll:!0}),this.setRange(this.savedRange))}format(e,t){this.scroll.update();let r=this.getNativeRange();if(!(r==null||!r.native.collapsed||this.scroll.query(e,X.BLOCK))){if(r.start.node!==this.cursor.textNode){let n=this.scroll.find(r.start.node,!1);if(n==null)return;if(n instanceof ct){let s=n.split(r.start.offset);n.parent.insertBefore(this.cursor,s)}else n.insertBefore(this.cursor,r.start.node);this.cursor.attach()}this.cursor.format(e,t),this.scroll.optimize(),this.setNativeRange(this.cursor.textNode,this.cursor.textNode.data.length),this.update()}}getBounds(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=this.scroll.length();e=Math.min(e,r-1),t=Math.min(e+t,r-1)-e;let n,[s,a]=this.scroll.leaf(e);if(s==null)return null;if(t>0&&a===s.length()){let[d]=this.scroll.leaf(e+1);if(d){let[c]=this.scroll.line(e),[f]=this.scroll.line(e+1);c===f&&(s=d,a=0)}}[n,a]=s.position(a,!0);let o=document.createRange();if(t>0)return o.setStart(n,a),[s,a]=this.scroll.leaf(e+t),s==null?null:([n,a]=s.position(a,!0),o.setEnd(n,a),o.getBoundingClientRect());let l="left",h;if(n instanceof Text){if(!n.data.length)return null;a0&&(l="right")}return{bottom:h.top+h.height,height:h.height,left:h[l],right:h[l],top:h.top,width:0}}getNativeRange(){let e=document.getSelection();if(e==null||e.rangeCount<=0)return null;let t=e.getRangeAt(0);if(t==null)return null;let r=this.normalizeNative(t);return Lm.info("getNativeRange",r),r}getRange(){let e=this.scroll.domNode;if("isConnected"in e&&!e.isConnected)return[null,null];let t=this.getNativeRange();return t==null?[null,null]:[this.normalizedToRange(t),t]}hasFocus(){return document.activeElement===this.root||document.activeElement!=null&&Im(this.root,document.activeElement)}normalizedToRange(e){let t=[[e.start.node,e.start.offset]];e.native.collapsed||t.push([e.end.node,e.end.offset]);let r=t.map(a=>{let[o,l]=a,h=this.scroll.find(o,!0),d=h.offset(this.scroll);return l===0?d:h instanceof ct?d+h.index(o,l):d+h.length()}),n=Math.min(Math.max(...r),this.scroll.length()-1),s=Math.min(n,...r);return new $t(s,n-s)}normalizeNative(e){if(!Im(this.root,e.startContainer)||!e.collapsed&&!Im(this.root,e.endContainer))return null;let t={start:{node:e.startContainer,offset:e.startOffset},end:{node:e.endContainer,offset:e.endOffset},native:e};return[t.start,t.end].forEach(r=>{let{node:n,offset:s}=r;for(;!(n instanceof Text)&&n.childNodes.length>0;)if(n.childNodes.length>s)n=n.childNodes[s],s=0;else if(n.childNodes.length===s)n=n.lastChild,n instanceof Text?s=n.data.length:n.childNodes.length>0?s=n.childNodes.length:s=n.childNodes.length+1;else break;r.node=n,r.offset=s}),t}rangeToNative(e){let t=this.scroll.length(),r=(n,s)=>{n=Math.min(t-1,n);let[a,o]=this.scroll.leaf(n);return a?a.position(o,s):[null,-1]};return[...r(e.index,!1),...r(e.index+e.length,!0)]}setNativeRange(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e,n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:t,s=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1;if(Lm.info("setNativeRange",e,t,r,n),e!=null&&(this.root.parentNode==null||e.parentNode==null||r.parentNode==null))return;let a=document.getSelection();if(a!=null)if(e!=null){this.hasFocus()||this.root.focus({preventScroll:!0});let{native:o}=this.getNativeRange()||{};if(o==null||s||e!==o.startContainer||t!==o.startOffset||r!==o.endContainer||n!==o.endOffset){e instanceof Element&&e.tagName==="BR"&&(t=Array.from(e.parentNode.childNodes).indexOf(e),e=e.parentNode),r instanceof Element&&r.tagName==="BR"&&(n=Array.from(r.parentNode.childNodes).indexOf(r),r=r.parentNode);let l=document.createRange();l.setStart(e,t),l.setEnd(r,n),a.removeAllRanges(),a.addRange(l)}}else a.removeAllRanges(),this.root.blur()}setRange(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:ee.sources.API;if(typeof t=="string"&&(r=t,t=!1),Lm.info("setRange",e),e!=null){let n=this.rangeToNative(e);this.setNativeRange(...n,t)}else this.setNativeRange(null);this.update(r)}update(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ee.sources.USER,t=this.lastRange,[r,n]=this.getRange();if(this.lastRange=r,this.lastNative=n,this.lastRange!=null&&(this.savedRange=this.lastRange),!ys(t,this.lastRange)){if(!this.composing&&n!=null&&n.native.collapsed&&n.start.node!==this.cursor.textNode){let a=this.cursor.restore();a&&this.setNativeRange(a.startNode,a.startOffset,a.endNode,a.endOffset)}let s=[ee.events.SELECTION_CHANGE,gr(this.lastRange),gr(t),e];this.emitter.emit(ee.events.EDITOR_CHANGE,...s),e!==ee.sources.SILENT&&this.emitter.emit(...s)}}};iy=zm});function Ka(i,e,t){if(i.length===0){let[m]=Rm(t.pop());return e<=0?``:`${Ka([],e-1,t)}`}let[{child:r,offset:n,length:s,indent:a,type:o},...l]=i,[h,d]=Rm(o);if(a>e)return t.push(o),a===e+1?`<${h}>${Ul(r,n,s)}${Ka(l,a,t)}`:`<${h}>
  • ${Ka(i,e+1,t)}`;let c=t[t.length-1];if(a===e&&o===c)return`
  • ${Ul(r,n,s)}${Ka(l,a,t)}`;let[f]=Rm(t.pop());return`${Ka(i,e-1,t)}`}function Ul(i,e,t){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if("html"in i&&typeof i.html=="function")return i.html(e,t);if(i instanceof nt)return ks(i.value().slice(e,e+t)).replaceAll(" "," ");if(i instanceof ai){if(i.statics.blotName==="list-container"){let h=[];return i.children.forEachAt(e,t,(d,c,f)=>{let m="formats"in d&&typeof d.formats=="function"?d.formats():{};h.push({child:d,offset:c,length:f,indent:m.indent||0,type:m.list})}),Ka(h,-1,[])}let n=[];if(i.children.forEachAt(e,t,(h,d,c)=>{n.push(Ul(h,d,c))}),r||i.statics.blotName==="list")return n.join("");let{outerHTML:s,innerHTML:a}=i.domNode,[o,l]=s.split(`>${a}<`);return o==="${n.join("")}<${l}`:`${o}>${n.join("")}<${l}`}return i.domNode instanceof Element?i.domNode.outerHTML:""}function TB(i,e){return Object.keys(e).reduce((t,r)=>{if(i[r]==null)return t;let n=e[r];return n===i[r]?t[r]=n:Array.isArray(n)?n.indexOf(i[r])<0?t[r]=n.concat([i[r]]):t[r]=n:t[r]=[n,i[r]],t},{})}function Rm(i){let e=i==="ordered"?"ol":"ul";switch(i){case"checked":return[e,' data-list="checked"'];case"unchecked":return[e,' data-list="unchecked"'];default:return[e,""]}}function ry(i){return i.reduce((e,t)=>{if(typeof t.insert=="string"){let r=t.insert.replace(/\r\n/g,` `).replace(/\r/g,` -`);return e.insert(r,t.attributes)}return e.push(t)},new Ze.default)}function j9(i,e){let{index:t,length:r}=i;return new $t(t+e,r)}function eB(i){let e=[];return i.forEach(t=>{typeof t.insert=="string"?t.insert.split(` +`);return e.insert(r,t.attributes)}return e.push(t)},new Qe.default)}function ny(i,e){let{index:t,length:r}=i;return new $t(t+e,r)}function NB(i){let e=[];return i.forEach(t=>{typeof t.insert=="string"?t.insert.split(` `).forEach((n,s)=>{s&&e.push({insert:` -`,attributes:t.attributes}),n&&e.push({insert:n,attributes:t.attributes})}):e.push(t)}),e}var Ze,QO,Nm,G9,V9=T(()=>{kn();Re();Ze=pt(pi(),1);zi();Dn();Ll();Kr();Dl();QO=/^[ -~]*$/,Nm=class{constructor(e){this.scroll=e,this.delta=this.getDelta()}applyDelta(e){this.scroll.update();let t=this.scroll.length();this.scroll.batchStart();let r=$9(e),n=new Ze.default;return eB(r.ops.slice()).reduce((a,o)=>{let l=Ze.Op.length(o),h=o.attributes||{},d=!1,c=!1;if(o.insert!=null){if(n.retain(l),typeof o.insert=="string"){let g=o.insert;c=!g.endsWith(` -`)&&(t<=a||!!this.scroll.descendant(ft,a)[0]),this.scroll.insertAt(a,g);let[x,y]=this.scroll.line(a),b=ri({},ai(x));if(x instanceof De){let[S]=x.descendant(dt,y);S&&(b=ri(b,ai(S)))}h=Ze.AttributeMap.diff(b,h)||{}}else if(typeof o.insert=="object"){let g=Object.keys(o.insert)[0];if(g==null)return a;let x=this.scroll.query(g,X.INLINE)!=null;if(x)(t<=a||this.scroll.descendant(ft,a)[0])&&(c=!0);else if(a>0){let[y,b]=this.scroll.descendant(dt,a-1);y instanceof nt?y.value()[b]!==` -`&&(d=!0):y instanceof Ke&&y.statics.scope===X.INLINE_BLOT&&(d=!0)}if(this.scroll.insertAt(a,g,o.insert[g]),x){let[y]=this.scroll.descendant(dt,a);if(y){let b=ri({},ai(y));h=Ze.AttributeMap.diff(b,h)||{}}}}t+=l}else if(n.push(o),o.retain!==null&&typeof o.retain=="object"){let g=Object.keys(o.retain)[0];if(g==null)return a;this.scroll.updateEmbedAt(a,g,o.retain[g])}Object.keys(h).forEach(g=>{this.scroll.formatAt(a,l,g,h[g])});let f=d?1:0,m=c?1:0;return t+=f+m,n.retain(f),n.delete(m),a+l+f+m},0),n.reduce((a,o)=>typeof o.delete=="number"?(this.scroll.deleteAt(a,o.delete),a):a+Ze.Op.length(o),0),this.scroll.batchEnd(),this.scroll.optimize(),this.update(r)}deleteText(e,t){return this.scroll.deleteAt(e,t),this.update(new Ze.default().retain(e).delete(t))}formatLine(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};this.scroll.update(),Object.keys(r).forEach(s=>{this.scroll.lines(e,Math.max(t,1)).forEach(a=>{a.format(s,r[s])})}),this.scroll.optimize();let n=new Ze.default().retain(e).retain(t,yr(r));return this.update(n)}formatText(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};Object.keys(r).forEach(s=>{this.scroll.formatAt(e,t,s,r[s])});let n=new Ze.default().retain(e).retain(t,yr(r));return this.update(n)}getContents(e,t){return this.delta.slice(e,e+t)}getDelta(){return this.scroll.lines().reduce((e,t)=>e.concat(t.delta()),new Ze.default)}getFormat(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=[],n=[];t===0?this.scroll.path(e).forEach(o=>{let[l]=o;l instanceof De?r.push(l):l instanceof dt&&n.push(l)}):(r=this.scroll.lines(e,t),n=this.scroll.descendants(dt,e,t));let[s,a]=[r,n].map(o=>{let l=o.shift();if(l==null)return{};let h=ai(l);for(;Object.keys(h).length>0;){let d=o.shift();if(d==null)return h;h=JO(ai(d),h)}return h});return{...s,...a}}getHTML(e,t){let[r,n]=this.scroll.line(e);if(r){let s=r.length();return r.length()>=n+t&&!(n===0&&t===s)?Ol(r,n,t,!0):Ol(this.scroll,e,t,!0)}return""}getText(e,t){return this.getContents(e,t).filter(r=>typeof r.insert=="string").map(r=>r.insert).join("")}insertContents(e,t){let r=$9(t),n=new Ze.default().retain(e).concat(r);return this.scroll.insertContents(e,r),this.update(n)}insertEmbed(e,t,r){return this.scroll.insertAt(e,t,r),this.update(new Ze.default().retain(e).insert({[t]:r}))}insertText(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return t=t.replace(/\r\n/g,` +`,attributes:t.attributes}),n&&e.push({insert:n,attributes:t.attributes})}):e.push(t)}),e}var Qe,MB,Dm,sy,ay=T(()=>{An();De();Qe=yt(xi(),1);Ri();Rn();Bl();Kr();Hl();MB=/^[ -~]*$/,Dm=class{constructor(e){this.scroll=e,this.delta=this.getDelta()}applyDelta(e){this.scroll.update();let t=this.scroll.length();this.scroll.batchStart();let r=ry(e),n=new Qe.default;return NB(r.ops.slice()).reduce((a,o)=>{let l=Qe.Op.length(o),h=o.attributes||{},d=!1,c=!1;if(o.insert!=null){if(n.retain(l),typeof o.insert=="string"){let g=o.insert;c=!g.endsWith(` +`)&&(t<=a||!!this.scroll.descendant(gt,a)[0]),this.scroll.insertAt(a,g);let[x,y]=this.scroll.line(a),b=si({},li(x));if(x instanceof Oe){let[E]=x.descendant(ct,y);E&&(b=si(b,li(E)))}h=Qe.AttributeMap.diff(b,h)||{}}else if(typeof o.insert=="object"){let g=Object.keys(o.insert)[0];if(g==null)return a;let x=this.scroll.query(g,X.INLINE)!=null;if(x)(t<=a||this.scroll.descendant(gt,a)[0])&&(c=!0);else if(a>0){let[y,b]=this.scroll.descendant(ct,a-1);y instanceof nt?y.value()[b]!==` +`&&(d=!0):y instanceof Ze&&y.statics.scope===X.INLINE_BLOT&&(d=!0)}if(this.scroll.insertAt(a,g,o.insert[g]),x){let[y]=this.scroll.descendant(ct,a);if(y){let b=si({},li(y));h=Qe.AttributeMap.diff(b,h)||{}}}}t+=l}else if(n.push(o),o.retain!==null&&typeof o.retain=="object"){let g=Object.keys(o.retain)[0];if(g==null)return a;this.scroll.updateEmbedAt(a,g,o.retain[g])}Object.keys(h).forEach(g=>{this.scroll.formatAt(a,l,g,h[g])});let f=d?1:0,m=c?1:0;return t+=f+m,n.retain(f),n.delete(m),a+l+f+m},0),n.reduce((a,o)=>typeof o.delete=="number"?(this.scroll.deleteAt(a,o.delete),a):a+Qe.Op.length(o),0),this.scroll.batchEnd(),this.scroll.optimize(),this.update(r)}deleteText(e,t){return this.scroll.deleteAt(e,t),this.update(new Qe.default().retain(e).delete(t))}formatLine(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};this.scroll.update(),Object.keys(r).forEach(s=>{this.scroll.lines(e,Math.max(t,1)).forEach(a=>{a.format(s,r[s])})}),this.scroll.optimize();let n=new Qe.default().retain(e).retain(t,gr(r));return this.update(n)}formatText(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};Object.keys(r).forEach(s=>{this.scroll.formatAt(e,t,s,r[s])});let n=new Qe.default().retain(e).retain(t,gr(r));return this.update(n)}getContents(e,t){return this.delta.slice(e,e+t)}getDelta(){return this.scroll.lines().reduce((e,t)=>e.concat(t.delta()),new Qe.default)}getFormat(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=[],n=[];t===0?this.scroll.path(e).forEach(o=>{let[l]=o;l instanceof Oe?r.push(l):l instanceof ct&&n.push(l)}):(r=this.scroll.lines(e,t),n=this.scroll.descendants(ct,e,t));let[s,a]=[r,n].map(o=>{let l=o.shift();if(l==null)return{};let h=li(l);for(;Object.keys(h).length>0;){let d=o.shift();if(d==null)return h;h=TB(li(d),h)}return h});return{...s,...a}}getHTML(e,t){let[r,n]=this.scroll.line(e);if(r){let s=r.length();return r.length()>=n+t&&!(n===0&&t===s)?Ul(r,n,t,!0):Ul(this.scroll,e,t,!0)}return""}getText(e,t){return this.getContents(e,t).filter(r=>typeof r.insert=="string").map(r=>r.insert).join("")}insertContents(e,t){let r=ry(t),n=new Qe.default().retain(e).concat(r);return this.scroll.insertContents(e,r),this.update(n)}insertEmbed(e,t,r){return this.scroll.insertAt(e,t,r),this.update(new Qe.default().retain(e).insert({[t]:r}))}insertText(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return t=t.replace(/\r\n/g,` `).replace(/\r/g,` -`),this.scroll.insertAt(e,t),Object.keys(r).forEach(n=>{this.scroll.formatAt(e,t.length,n,r[n])}),this.update(new Ze.default().retain(e).insert(t,yr(r)))}isBlank(){if(this.scroll.children.length===0)return!0;if(this.scroll.children.length>1)return!1;let e=this.scroll.children.head;if(e?.statics.blotName!==De.blotName)return!1;let t=e;return t.children.length>1?!1:t.children.head instanceof Et}removeFormat(e,t){let r=this.getText(e,t),[n,s]=this.scroll.line(e+t),a=0,o=new Ze.default;n!=null&&(a=n.length()-s,o=n.delta().slice(s,s+a-1).insert(` -`));let h=this.getContents(e,t+a).diff(new Ze.default().insert(r).concat(o)),d=new Ze.default().retain(e).concat(h);return this.applyDelta(d)}update(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[],r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:void 0,n=this.delta;if(t.length===1&&t[0].type==="characterData"&&t[0].target.data.match(QO)&&this.scroll.find(t[0].target)){let s=this.scroll.find(t[0].target),a=ai(s),o=s.offset(this.scroll),l=t[0].oldValue.replace(On.CONTENTS,""),h=new Ze.default().insert(l),d=new Ze.default().insert(s.value()),c=r&&{oldRange:j9(r.oldRange,-o),newRange:j9(r.newRange,-o)};e=new Ze.default().retain(o).concat(h.diff(d,c)).reduce((m,g)=>g.insert?m.insert(g.insert,a):m.push(g),new Ze.default),this.delta=n.compose(e)}else this.delta=this.getDelta(),(!e||!ys(n.compose(e),this.delta))&&(e=n.diff(this.delta,r));return e}};G9=Nm});var Gd,Qe,Di=T(()=>{Gd=class{constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.quill=e,this.options=t}};U(Gd,"DEFAULTS",{});Qe=Gd});var Vd,Em,Ka,Wd=T(()=>{Re();Kr();Vd="\uFEFF",Em=class extends Ke{constructor(e,t){super(e,t),this.contentNode=document.createElement("span"),this.contentNode.setAttribute("contenteditable","false"),Array.from(this.domNode.childNodes).forEach(r=>{this.contentNode.appendChild(r)}),this.leftGuard=document.createTextNode(Vd),this.rightGuard=document.createTextNode(Vd),this.domNode.appendChild(this.leftGuard),this.domNode.appendChild(this.contentNode),this.domNode.appendChild(this.rightGuard)}index(e,t){return e===this.leftGuard?0:e===this.rightGuard?1:super.index(e,t)}restore(e){let t=null,r,n=e.data.split(Vd).join("");if(e===this.leftGuard)if(this.prev instanceof nt){let s=this.prev.length();this.prev.insertAt(s,n),t={startNode:this.prev.domNode,startOffset:s+n.length}}else r=document.createTextNode(n),this.parent.insertBefore(this.scroll.create(r),this),t={startNode:r,startOffset:n.length};else e===this.rightGuard&&(this.next instanceof nt?(this.next.insertAt(0,n),t={startNode:this.next.domNode,startOffset:n.length}):(r=document.createTextNode(n),this.parent.insertBefore(this.scroll.create(r),this.next),t={startNode:r,startOffset:n.length}));return e.data=Vd,t}update(e,t){e.forEach(r=>{if(r.type==="characterData"&&(r.target===this.leftGuard||r.target===this.rightGuard)){let n=this.restore(r.target);n&&(t.range=n)}})}},Ka=Em});var Sm,W9,Y9=T(()=>{Wd();Qr();Sm=class{constructor(e,t){U(this,"isComposing",!1);this.scroll=e,this.emitter=t,this.setupListeners()}setupListeners(){this.scroll.domNode.addEventListener("compositionstart",e=>{this.isComposing||this.handleCompositionStart(e)}),this.scroll.domNode.addEventListener("compositionend",e=>{this.isComposing&&queueMicrotask(()=>{this.handleCompositionEnd(e)})})}handleCompositionStart(e){let t=e.target instanceof Node?this.scroll.find(e.target,!0):null;t&&!(t instanceof Ka)&&(this.emitter.emit(J.events.COMPOSITION_BEFORE_START,e),this.scroll.batchStart(),this.emitter.emit(J.events.COMPOSITION_START,e),this.isComposing=!0)}handleCompositionEnd(e){this.emitter.emit(J.events.COMPOSITION_BEFORE_END,e),this.scroll.batchEnd(),this.emitter.emit(J.events.COMPOSITION_END,e),this.isComposing=!1}},W9=Sm});var Bl,Am,Za,km=T(()=>{Bl=class Bl{constructor(e,t){U(this,"modules",{});this.quill=e,this.options=t}init(){Object.keys(this.options.modules).forEach(e=>{this.modules[e]==null&&this.addModule(e)})}addModule(e){let t=this.quill.constructor.import(`modules/${e}`);return this.modules[e]=new t(this.quill,this.options.modules[e]||{}),this.modules[e]}};U(Bl,"DEFAULTS",{modules:{}}),U(Bl,"themes",{default:Bl});Am=Bl,Za=Am});var tB,iB,Yd,X9,rB,K9,Z9=T(()=>{tB=i=>i.parentElement||i.getRootNode().host||null,iB=i=>{let e=i.getBoundingClientRect(),t="offsetWidth"in i&&Math.abs(e.width)/i.offsetWidth||1,r="offsetHeight"in i&&Math.abs(e.height)/i.offsetHeight||1;return{top:e.top,right:e.left+i.clientWidth*t,bottom:e.top+i.clientHeight*r,left:e.left}},Yd=i=>{let e=parseInt(i,10);return Number.isNaN(e)?0:e},X9=(i,e,t,r,n,s)=>ir?0:ir?e-i>r-t?i+n-t:e-r+s:0,rB=(i,e)=>{let t=i.ownerDocument,r=e,n=i;for(;n;){let s=n===t.body,a=s?{top:0,right:window.visualViewport?.width??t.documentElement.clientWidth,bottom:window.visualViewport?.height??t.documentElement.clientHeight,left:0}:iB(n),o=getComputedStyle(n),l=X9(r.left,r.right,a.left,a.right,Yd(o.scrollPaddingLeft),Yd(o.scrollPaddingRight)),h=X9(r.top,r.bottom,a.top,a.bottom,Yd(o.scrollPaddingTop),Yd(o.scrollPaddingBottom));if(l||h)if(s)t.defaultView?.scrollBy(l,h);else{let{scrollLeft:d,scrollTop:c}=n;h&&(n.scrollTop+=h),l&&(n.scrollLeft+=l);let f=n.scrollLeft-d,m=n.scrollTop-c;r={left:r.left-f,top:r.top-m,right:r.right-f,bottom:r.bottom-m}}n=s||o.position==="fixed"?null:tB(n)}},K9=rB});var nB,sB,aB,Q9,J9=T(()=>{Re();nB=100,sB=["block","break","cursor","inline","scroll","text"],aB=(i,e,t)=>{let r=new Ln;return sB.forEach(n=>{let s=e.query(n);s&&r.register(s)}),i.forEach(n=>{let s=e.query(n);s||t.error(`Cannot register "${n}" specified in "formats" config. Are you sure it was registered?`);let a=0;for(;s;)if(r.register(s),s="blotName"in s?s.requiredContainer??null:null,a+=1,a>nB){t.error(`Cycle detected in registering blot requiredContainer: "${n}"`);break}}),r},Q9=aB});function ey(i){return typeof i=="string"?document.querySelector(i):i}function Cm(i){return Object.entries(i??{}).reduce((e,t)=>{let[r,n]=t;return{...e,[r]:n===!0?{}:n}},{})}function ty(i){return Object.fromEntries(Object.entries(i).filter(e=>e[1]!==void 0))}function oB(i,e){let t=ey(i);if(!t)throw new Error("Invalid Quill container");let n=!e.theme||e.theme===B.DEFAULTS.theme?Za:B.import(`themes/${e.theme}`);if(!n)throw new Error(`Invalid theme ${e.theme}. Did you register it?`);let{modules:s,...a}=B.DEFAULTS,{modules:o,...l}=n.DEFAULTS,h=Cm(e.modules);h!=null&&h.toolbar&&h.toolbar.constructor!==Object&&(h={...h,toolbar:{container:h.toolbar}});let d=ri({},Cm(s),Cm(o),h),c={...a,...ty(l),...ty(e)},f=e.registry;return f?e.formats&&Qa.warn('Ignoring "formats" option because "registry" is specified'):f=e.formats?Q9(e.formats,c.registry,Qa):c.registry,{...c,registry:f,container:t,theme:n,modules:Object.entries(d).reduce((m,g)=>{let[x,y]=g;if(!y)return m;let b=B.import(`modules/${x}`);return b==null?(Qa.error(`Cannot load ${x} module. Are you sure you registered it?`),m):{...m,[x]:ri({},b.DEFAULTS||{},y)}},{}),bounds:ey(c.bounds)}}function Qi(i,e,t,r){if(!this.isEnabled()&&e===J.sources.USER&&!this.allowReadOnlyEdits)return new Bn.default;let n=t==null?null:this.getSelection(),s=this.editor.delta,a=i();if(n!=null&&(t===!0&&(t=n.index),r==null?n=iy(n,a,e):r!==0&&(n=iy(n,t,r,e)),this.setSelection(n,J.sources.SILENT)),a.length()>0){let o=[J.events.TEXT_CHANGE,a,s,e];this.emitter.emit(J.events.EDITOR_CHANGE,...o),e!==J.sources.SILENT&&this.emitter.emit(...o)}return a}function Jr(i,e,t,r,n){let s={};return typeof i.index=="number"&&typeof i.length=="number"?typeof e!="number"?(n=r,r=t,t=e,e=i.length,i=i.index):(e=i.length,i=i.index):typeof e!="number"&&(n=r,r=t,t=e,e=0),typeof t=="object"?(s=t,n=r):typeof t=="string"&&(r!=null?s[t]=r:n=t),n=n||J.sources.API,[i,e,s,n]}function iy(i,e,t,r){let n=typeof t=="number"?t:0;if(i==null)return null;let s,a;return e&&typeof e.transformPosition=="function"?[s,a]=[i.index,i.index+i.length].map(o=>e.transformPosition(o,r!==J.sources.USER)):[s,a]=[i.index,i.index+i.length].map(o=>o=0?o+n:Math.max(e,o+n)),new $t(s,a-s)}var Bn,Qa,Xd,Ji,B,oi=T(()=>{kn();Re();Bn=pt(pi(),1);V9();Qr();pm();Cs();Di();Dl();Y9();km();Z9();J9();Qa=gi("quill"),Xd=new Ln;ni.uiClass="ql-ui";Ji=class Ji{static debug(e){e===!0&&(e="log"),gi.level(e)}static find(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;return zl.get(e)||Xd.find(e,t)}static import(e){return this.imports[e]==null&&Qa.error(`Cannot import ${e}. Are you sure it was registered?`),this.imports[e]}static register(){if(typeof(arguments.length<=0?void 0:arguments[0])!="string"){let e=arguments.length<=0?void 0:arguments[0],t=!!(!(arguments.length<=1)&&arguments[1]),r="attrName"in e?e.attrName:e.blotName;typeof r=="string"?this.register(`formats/${r}`,e,t):Object.keys(e).forEach(n=>{this.register(n,e[n],t)})}else{let e=arguments.length<=0?void 0:arguments[0],t=arguments.length<=1?void 0:arguments[1],r=!!(!(arguments.length<=2)&&arguments[2]);this.imports[e]!=null&&!r&&Qa.warn(`Overwriting ${e} with`,t),this.imports[e]=t,(e.startsWith("blots/")||e.startsWith("formats/"))&&t&&typeof t!="boolean"&&t.blotName!=="abstract"&&Xd.register(t),typeof t.register=="function"&&t.register(Xd)}}constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(this.options=oB(e,t),this.container=this.options.container,this.container==null){Qa.error("Invalid Quill container",e);return}this.options.debug&&Ji.debug(this.options.debug);let r=this.container.innerHTML.trim();this.container.classList.add("ql-container"),this.container.innerHTML="",zl.set(this.container,this),this.root=this.addContainer("ql-editor"),this.root.classList.add("ql-blank"),this.emitter=new J;let n=vl.blotName,s=this.options.registry.query(n);if(!s||!("blotName"in s))throw new Error(`Cannot initialize Quill without "${n}" blot`);if(this.scroll=new s(this.options.registry,this.root,{emitter:this.emitter}),this.editor=new G9(this.scroll),this.selection=new U9(this.scroll,this.emitter),this.composition=new W9(this.scroll,this.emitter),this.theme=new this.options.theme(this,this.options),this.keyboard=this.theme.addModule("keyboard"),this.clipboard=this.theme.addModule("clipboard"),this.history=this.theme.addModule("history"),this.uploader=this.theme.addModule("uploader"),this.theme.addModule("input"),this.theme.addModule("uiNode"),this.theme.init(),this.emitter.on(J.events.EDITOR_CHANGE,a=>{a===J.events.TEXT_CHANGE&&this.root.classList.toggle("ql-blank",this.editor.isBlank())}),this.emitter.on(J.events.SCROLL_UPDATE,(a,o)=>{let l=this.selection.lastRange,[h]=this.selection.getRange(),d=l&&h?{oldRange:l,newRange:h}:void 0;Qi.call(this,()=>this.editor.update(null,o,d),a)}),this.emitter.on(J.events.SCROLL_EMBED_UPDATE,(a,o)=>{let l=this.selection.lastRange,[h]=this.selection.getRange(),d=l&&h?{oldRange:l,newRange:h}:void 0;Qi.call(this,()=>{let c=new Bn.default().retain(a.offset(this)).retain({[a.statics.blotName]:o});return this.editor.update(c,[],d)},Ji.sources.USER)}),r){let a=this.clipboard.convert({html:`${r}


    `,text:` -`});this.setContents(a)}this.history.clear(),this.options.placeholder&&this.root.setAttribute("data-placeholder",this.options.placeholder),this.options.readOnly&&this.disable(),this.allowReadOnlyEdits=!1}addContainer(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(typeof e=="string"){let r=e;e=document.createElement("div"),e.classList.add(r)}return this.container.insertBefore(e,t),e}blur(){this.selection.setRange(null)}deleteText(e,t,r){return[e,t,,r]=Jr(e,t,r),Qi.call(this,()=>this.editor.deleteText(e,t),r,e,-1*t)}disable(){this.enable(!1)}editReadOnly(e){this.allowReadOnlyEdits=!0;let t=e();return this.allowReadOnlyEdits=!1,t}enable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;this.scroll.enable(e),this.container.classList.toggle("ql-disabled",!e)}focus(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.selection.focus(),e.preventScroll||this.scrollSelectionIntoView()}format(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:J.sources.API;return Qi.call(this,()=>{let n=this.getSelection(!0),s=new Bn.default;if(n==null)return s;if(this.scroll.query(e,X.BLOCK))s=this.editor.formatLine(n.index,n.length,{[e]:t});else{if(n.length===0)return this.selection.format(e,t),s;s=this.editor.formatText(n.index,n.length,{[e]:t})}return this.setSelection(n,J.sources.SILENT),s},r)}formatLine(e,t,r,n,s){let a;return[e,t,a,s]=Jr(e,t,r,n,s),Qi.call(this,()=>this.editor.formatLine(e,t,a),s,e,0)}formatText(e,t,r,n,s){let a;return[e,t,a,s]=Jr(e,t,r,n,s),Qi.call(this,()=>this.editor.formatText(e,t,a),s,e,0)}getBounds(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=null;if(typeof e=="number"?r=this.selection.getBounds(e,t):r=this.selection.getBounds(e.index,e.length),!r)return null;let n=this.container.getBoundingClientRect();return{bottom:r.bottom-n.top,height:r.height,left:r.left-n.left,right:r.right-n.left,top:r.top-n.top,width:r.width}}getContents(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.getLength()-e;return[e,t]=Jr(e,t),this.editor.getContents(e,t)}getFormat(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.getSelection(!0),t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return typeof e=="number"?this.editor.getFormat(e,t):this.editor.getFormat(e.index,e.length)}getIndex(e){return e.offset(this.scroll)}getLength(){return this.scroll.length()}getLeaf(e){return this.scroll.leaf(e)}getLine(e){return this.scroll.line(e)}getLines(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Number.MAX_VALUE;return typeof e!="number"?this.scroll.lines(e.index,e.length):this.scroll.lines(e,t)}getModule(e){return this.theme.modules[e]}getSelection(){return arguments.length>0&&arguments[0]!==void 0&&arguments[0]&&this.focus(),this.update(),this.selection.getRange()[0]}getSemanticHTML(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;return typeof e=="number"&&(t=t??this.getLength()-e),[e,t]=Jr(e,t),this.editor.getHTML(e,t)}getText(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;return typeof e=="number"&&(t=t??this.getLength()-e),[e,t]=Jr(e,t),this.editor.getText(e,t)}hasFocus(){return this.selection.hasFocus()}insertEmbed(e,t,r){let n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:Ji.sources.API;return Qi.call(this,()=>this.editor.insertEmbed(e,t,r),n,e)}insertText(e,t,r,n,s){let a;return[e,,a,s]=Jr(e,0,r,n,s),Qi.call(this,()=>this.editor.insertText(e,t,a),s,e,t.length)}isEnabled(){return this.scroll.isEnabled()}off(){return this.emitter.off(...arguments)}on(){return this.emitter.on(...arguments)}once(){return this.emitter.once(...arguments)}removeFormat(e,t,r){return[e,t,,r]=Jr(e,t,r),Qi.call(this,()=>this.editor.removeFormat(e,t),r,e)}scrollRectIntoView(e){K9(this.root,e)}scrollIntoView(){console.warn("Quill#scrollIntoView() has been deprecated and will be removed in the near future. Please use Quill#scrollSelectionIntoView() instead."),this.scrollSelectionIntoView()}scrollSelectionIntoView(){let e=this.selection.lastRange,t=e&&this.selection.getBounds(e.index,e.length);t&&this.scrollRectIntoView(t)}setContents(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:J.sources.API;return Qi.call(this,()=>{e=new Bn.default(e);let r=this.getLength(),n=this.editor.deleteText(0,r),s=this.editor.insertContents(0,e),a=this.editor.deleteText(this.getLength()-1,1);return n.compose(s).compose(a)},t)}setSelection(e,t,r){e==null?this.selection.setRange(null,t||Ji.sources.API):([e,t,,r]=Jr(e,t,r),this.selection.setRange(new $t(Math.max(0,e),t),r),r!==J.sources.SILENT&&this.scrollSelectionIntoView())}setText(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:J.sources.API,r=new Bn.default().insert(e);return this.setContents(r,t)}update(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:J.sources.USER,t=this.scroll.update(e);return this.selection.update(e),t}updateContents(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:J.sources.API;return Qi.call(this,()=>(e=new Bn.default(e),this.editor.applyDelta(e)),t,!0)}};U(Ji,"DEFAULTS",{bounds:null,modules:{clipboard:!0,keyboard:!0,history:!0,uploader:!0},placeholder:"",readOnly:!1,registry:Xd,theme:"default"}),U(Ji,"events",J.events),U(Ji,"sources",J.sources),U(Ji,"version","2.0.3"),U(Ji,"imports",{delta:Bn.default,parchment:bl,"core/module":Qe,"core/theme":Za});B=Ji});var _m,Oi,Ja=T(()=>{Re();_m=class extends qa{},Oi=_m});function ry(i){return i instanceof De||i instanceof ft}function ny(i){return typeof i.updateContent=="function"}function Lm(i,e,t){t.reduce((r,n)=>{let s=Bi.Op.length(n),a=n.attributes||{};if(n.insert!=null){if(typeof n.insert=="string"){let o=n.insert;i.insertAt(r,o);let[l]=i.descendant(dt,r),h=ai(l);a=Bi.AttributeMap.diff(h,a)||{}}else if(typeof n.insert=="object"){let o=Object.keys(n.insert)[0];if(o==null)return r;if(i.insertAt(r,o,n.insert[o]),i.scroll.query(o,X.INLINE)!=null){let[h]=i.descendant(dt,r),d=ai(h);a=Bi.AttributeMap.diff(d,a)||{}}}}return Object.keys(a).forEach(o=>{i.formatAt(r,s,o,a[o])}),r+s},e)}var Bi,Pn,sy,ay=T(()=>{Re();Bi=pt(pi(),1);Qr();zi();Dn();Ja();Pn=class extends vl{constructor(e,t,r){let{emitter:n}=r;super(e,t),this.emitter=n,this.batch=!1,this.optimize(),this.enable(),this.domNode.addEventListener("dragstart",s=>this.handleDragStart(s))}batchStart(){Array.isArray(this.batch)||(this.batch=[])}batchEnd(){if(!this.batch)return;let e=this.batch;this.batch=!1,this.update(e)}emitMount(e){this.emitter.emit(J.events.SCROLL_BLOT_MOUNT,e)}emitUnmount(e){this.emitter.emit(J.events.SCROLL_BLOT_UNMOUNT,e)}emitEmbedUpdate(e,t){this.emitter.emit(J.events.SCROLL_EMBED_UPDATE,e,t)}deleteAt(e,t){let[r,n]=this.line(e),[s]=this.line(e+t);if(super.deleteAt(e,t),s!=null&&r!==s&&n>0){if(r instanceof ft||s instanceof ft){this.optimize();return}let a=s.children.head instanceof Et?null:s.children.head;r.moveChildren(s,a),r.remove()}this.optimize()}enable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;this.domNode.setAttribute("contenteditable",e?"true":"false")}formatAt(e,t,r,n){super.formatAt(e,t,r,n),this.optimize()}insertAt(e,t,r){if(e>=this.length())if(r==null||this.scroll.query(t,X.BLOCK)==null){let n=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(n),r==null&&t.endsWith(` -`)?n.insertAt(0,t.slice(0,-1),r):n.insertAt(0,t,r)}else{let n=this.scroll.create(t,r);this.appendChild(n)}else super.insertAt(e,t,r);this.optimize()}insertBefore(e,t){if(e.statics.scope===X.INLINE_BLOT){let r=this.scroll.create(this.statics.defaultChild.blotName);r.appendChild(e),super.insertBefore(r,t)}else super.insertBefore(e,t)}insertContents(e,t){let r=this.deltaToRenderBlocks(t.concat(new Bi.default().insert(` -`))),n=r.pop();if(n==null)return;this.batchStart();let s=r.shift();if(s){let l=s.type==="block"&&(s.delta.length()===0||!this.descendant(ft,e)[0]&&e{this.formatAt(c-1,1,g,m[g])}),e=c}let[a,o]=this.children.find(e);if(r.length&&(a&&(a=a.split(o),o=0),r.forEach(l=>{if(l.type==="block"){let h=this.createBlock(l.attributes,a||void 0);Lm(h,0,l.delta)}else{let h=this.create(l.key,l.value);this.insertBefore(h,a||void 0),Object.keys(l.attributes).forEach(d=>{h.format(d,l.attributes[d])})}})),n.type==="block"&&n.delta.length()){let l=a?a.offset(a.scroll)+o:this.length();Lm(this,l,n.delta)}this.batchEnd(),this.optimize()}isEnabled(){return this.domNode.getAttribute("contenteditable")==="true"}leaf(e){let t=this.path(e).pop();if(!t)return[null,-1];let[r,n]=t;return r instanceof dt?[r,n]:[null,-1]}line(e){return e===this.length()?this.line(e-1):this.descendant(ry,e)}lines(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Number.MAX_VALUE,r=(n,s,a)=>{let o=[],l=a;return n.children.forEachAt(s,a,(h,d,c)=>{ry(h)?o.push(h):h instanceof qa&&(o=o.concat(r(h,d,l))),l-=c}),o};return r(this,e,t)}optimize(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.batch||(super.optimize(e,t),e.length>0&&this.emitter.emit(J.events.SCROLL_OPTIMIZE,e,t))}path(e){return super.path(e).slice(1)}remove(){}update(e){if(this.batch){Array.isArray(e)&&(this.batch=this.batch.concat(e));return}let t=J.sources.USER;typeof e=="string"&&(t=e),Array.isArray(e)||(e=this.observer.takeRecords()),e=e.filter(r=>{let{target:n}=r,s=this.find(n,!0);return s&&!ny(s)}),e.length>0&&this.emitter.emit(J.events.SCROLL_BEFORE_UPDATE,t,e),super.update(e.concat([])),e.length>0&&this.emitter.emit(J.events.SCROLL_UPDATE,t,e)}updateEmbedAt(e,t,r){let[n]=this.descendant(s=>s instanceof ft,e);n&&n.statics.blotName===t&&ny(n)&&n.updateContent(r)}handleDragStart(e){e.preventDefault()}deltaToRenderBlocks(e){let t=[],r=new Bi.default;return e.forEach(n=>{let s=n?.insert;if(s)if(typeof s=="string"){let a=s.split(` -`);a.slice(0,-1).forEach(l=>{r.insert(l,n.attributes),t.push({type:"block",delta:r,attributes:n.attributes??{}}),r=new Bi.default});let o=a[a.length-1];o&&r.insert(o,n.attributes)}else{let a=Object.keys(s)[0];if(!a)return;this.query(a,X.INLINE)?r.push(n):(r.length()&&t.push({type:"block",delta:r,attributes:{}}),r=new Bi.default,t.push({type:"blockEmbed",key:a,value:s[a],attributes:n.attributes??{}}))}}),r.length()&&t.push({type:"block",delta:r,attributes:{}}),t}createBlock(e,t){let r,n={};Object.entries(e).forEach(o=>{let[l,h]=o;this.query(l,X.BLOCK&X.BLOT)!=null?r=l:n[l]=h});let s=this.create(r||this.statics.defaultChild.blotName,r?e[r]:void 0);this.insertBefore(s,t||void 0);let a=s.length();return Object.entries(n).forEach(o=>{let[l,h]=o;s.formatAt(0,a,l,h)}),s}};U(Pn,"blotName","scroll"),U(Pn,"className","ql-editor"),U(Pn,"tagName","DIV"),U(Pn,"defaultChild",De),U(Pn,"allowedChildren",[De,ft,Oi]);sy=Pn});var Im,oy,zm,Kd,Rm=T(()=>{Re();Im={scope:X.BLOCK,whitelist:["right","center","justify"]},oy=new qt("align","align",Im),zm=new ht("align","ql-align",Im),Kd=new si("align","text-align",Im)});var Pl,ly,Fl,Zd=T(()=>{Re();Pl=class extends si{value(e){let t=super.value(e);return t.startsWith("rgb(")?(t=t.replace(/^[^\d]+/,"").replace(/[^\d]+$/,""),`#${t.split(",").map(n=>`00${parseInt(n,10).toString(16)}`.slice(-2)).join("")}`):t}},ly=new ht("color","ql-color",{scope:X.INLINE}),Fl=new Pl("color","color",{scope:X.INLINE})});var hy,ql,Dm=T(()=>{Re();Zd();hy=new ht("background","ql-bg",{scope:X.INLINE}),ql=new Pl("background","background-color",{scope:X.INLINE})});var wr,st,eo,Qd=T(()=>{zi();Dn();Ll();Zr();Kr();Ja();oi();wr=class extends Oi{static create(e){let t=super.create(e);return t.setAttribute("spellcheck","false"),t}code(e,t){return this.children.map(r=>r.length()<=1?"":r.domNode.innerText).join(` +`),this.scroll.insertAt(e,t),Object.keys(r).forEach(n=>{this.scroll.formatAt(e,t.length,n,r[n])}),this.update(new Qe.default().retain(e).insert(t,gr(r)))}isBlank(){if(this.scroll.children.length===0)return!0;if(this.scroll.children.length>1)return!1;let e=this.scroll.children.head;if(e?.statics.blotName!==Oe.blotName)return!1;let t=e;return t.children.length>1?!1:t.children.head instanceof At}removeFormat(e,t){let r=this.getText(e,t),[n,s]=this.scroll.line(e+t),a=0,o=new Qe.default;n!=null&&(a=n.length()-s,o=n.delta().slice(s,s+a-1).insert(` +`));let h=this.getContents(e,t+a).diff(new Qe.default().insert(r).concat(o)),d=new Qe.default().retain(e).concat(h);return this.applyDelta(d)}update(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[],r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:void 0,n=this.delta;if(t.length===1&&t[0].type==="characterData"&&t[0].target.data.match(MB)&&this.scroll.find(t[0].target)){let s=this.scroll.find(t[0].target),a=li(s),o=s.offset(this.scroll),l=t[0].oldValue.replace(Dn.CONTENTS,""),h=new Qe.default().insert(l),d=new Qe.default().insert(s.value()),c=r&&{oldRange:ny(r.oldRange,-o),newRange:ny(r.newRange,-o)};e=new Qe.default().retain(o).concat(h.diff(d,c)).reduce((m,g)=>g.insert?m.insert(g.insert,a):m.push(g),new Qe.default),this.delta=n.compose(e)}else this.delta=this.getDelta(),(!e||!ys(n.compose(e),this.delta))&&(e=n.diff(this.delta,r));return e}};sy=Dm});var Jd,Je,Oi=T(()=>{Jd=class{constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.quill=e,this.options=t}};U(Jd,"DEFAULTS",{});Je=Jd});var ec,Om,Za,tc=T(()=>{De();Kr();ec="\uFEFF",Om=class extends Ze{constructor(e,t){super(e,t),this.contentNode=document.createElement("span"),this.contentNode.setAttribute("contenteditable","false"),Array.from(this.domNode.childNodes).forEach(r=>{this.contentNode.appendChild(r)}),this.leftGuard=document.createTextNode(ec),this.rightGuard=document.createTextNode(ec),this.domNode.appendChild(this.leftGuard),this.domNode.appendChild(this.contentNode),this.domNode.appendChild(this.rightGuard)}index(e,t){return e===this.leftGuard?0:e===this.rightGuard?1:super.index(e,t)}restore(e){let t=null,r,n=e.data.split(ec).join("");if(e===this.leftGuard)if(this.prev instanceof nt){let s=this.prev.length();this.prev.insertAt(s,n),t={startNode:this.prev.domNode,startOffset:s+n.length}}else r=document.createTextNode(n),this.parent.insertBefore(this.scroll.create(r),this),t={startNode:r,startOffset:n.length};else e===this.rightGuard&&(this.next instanceof nt?(this.next.insertAt(0,n),t={startNode:this.next.domNode,startOffset:n.length}):(r=document.createTextNode(n),this.parent.insertBefore(this.scroll.create(r),this.next),t={startNode:r,startOffset:n.length}));return e.data=ec,t}update(e,t){e.forEach(r=>{if(r.type==="characterData"&&(r.target===this.leftGuard||r.target===this.rightGuard)){let n=this.restore(r.target);n&&(t.range=n)}})}},Za=Om});var Bm,oy,ly=T(()=>{tc();Qr();Bm=class{constructor(e,t){U(this,"isComposing",!1);this.scroll=e,this.emitter=t,this.setupListeners()}setupListeners(){this.scroll.domNode.addEventListener("compositionstart",e=>{this.isComposing||this.handleCompositionStart(e)}),this.scroll.domNode.addEventListener("compositionend",e=>{this.isComposing&&queueMicrotask(()=>{this.handleCompositionEnd(e)})})}handleCompositionStart(e){let t=e.target instanceof Node?this.scroll.find(e.target,!0):null;t&&!(t instanceof Za)&&(this.emitter.emit(ee.events.COMPOSITION_BEFORE_START,e),this.scroll.batchStart(),this.emitter.emit(ee.events.COMPOSITION_START,e),this.isComposing=!0)}handleCompositionEnd(e){this.emitter.emit(ee.events.COMPOSITION_BEFORE_END,e),this.scroll.batchEnd(),this.emitter.emit(ee.events.COMPOSITION_END,e),this.isComposing=!1}},oy=Bm});var $l,Pm,Qa,Fm=T(()=>{$l=class $l{constructor(e,t){U(this,"modules",{});this.quill=e,this.options=t}init(){Object.keys(this.options.modules).forEach(e=>{this.modules[e]==null&&this.addModule(e)})}addModule(e){let t=this.quill.constructor.import(`modules/${e}`);return this.modules[e]=new t(this.quill,this.options.modules[e]||{}),this.modules[e]}};U($l,"DEFAULTS",{modules:{}}),U($l,"themes",{default:$l});Pm=$l,Qa=Pm});var EB,SB,ic,hy,AB,dy,cy=T(()=>{EB=i=>i.parentElement||i.getRootNode().host||null,SB=i=>{let e=i.getBoundingClientRect(),t="offsetWidth"in i&&Math.abs(e.width)/i.offsetWidth||1,r="offsetHeight"in i&&Math.abs(e.height)/i.offsetHeight||1;return{top:e.top,right:e.left+i.clientWidth*t,bottom:e.top+i.clientHeight*r,left:e.left}},ic=i=>{let e=parseInt(i,10);return Number.isNaN(e)?0:e},hy=(i,e,t,r,n,s)=>ir?0:ir?e-i>r-t?i+n-t:e-r+s:0,AB=(i,e)=>{let t=i.ownerDocument,r=e,n=i;for(;n;){let s=n===t.body,a=s?{top:0,right:window.visualViewport?.width??t.documentElement.clientWidth,bottom:window.visualViewport?.height??t.documentElement.clientHeight,left:0}:SB(n),o=getComputedStyle(n),l=hy(r.left,r.right,a.left,a.right,ic(o.scrollPaddingLeft),ic(o.scrollPaddingRight)),h=hy(r.top,r.bottom,a.top,a.bottom,ic(o.scrollPaddingTop),ic(o.scrollPaddingBottom));if(l||h)if(s)t.defaultView?.scrollBy(l,h);else{let{scrollLeft:d,scrollTop:c}=n;h&&(n.scrollTop+=h),l&&(n.scrollLeft+=l);let f=n.scrollLeft-d,m=n.scrollTop-c;r={left:r.left-f,top:r.top-m,right:r.right-f,bottom:r.bottom-m}}n=s||o.position==="fixed"?null:EB(n)}},dy=AB});var kB,CB,_B,uy,fy=T(()=>{De();kB=100,CB=["block","break","cursor","inline","scroll","text"],_B=(i,e,t)=>{let r=new _n;return CB.forEach(n=>{let s=e.query(n);s&&r.register(s)}),i.forEach(n=>{let s=e.query(n);s||t.error(`Cannot register "${n}" specified in "formats" config. Are you sure it was registered?`);let a=0;for(;s;)if(r.register(s),s="blotName"in s?s.requiredContainer??null:null,a+=1,a>kB){t.error(`Cycle detected in registering blot requiredContainer: "${n}"`);break}}),r},uy=_B});function my(i){return typeof i=="string"?document.querySelector(i):i}function qm(i){return Object.entries(i??{}).reduce((e,t)=>{let[r,n]=t;return{...e,[r]:n===!0?{}:n}},{})}function py(i){return Object.fromEntries(Object.entries(i).filter(e=>e[1]!==void 0))}function LB(i,e){let t=my(i);if(!t)throw new Error("Invalid Quill container");let n=!e.theme||e.theme===B.DEFAULTS.theme?Qa:B.import(`themes/${e.theme}`);if(!n)throw new Error(`Invalid theme ${e.theme}. Did you register it?`);let{modules:s,...a}=B.DEFAULTS,{modules:o,...l}=n.DEFAULTS,h=qm(e.modules);h!=null&&h.toolbar&&h.toolbar.constructor!==Object&&(h={...h,toolbar:{container:h.toolbar}});let d=si({},qm(s),qm(o),h),c={...a,...py(l),...py(e)},f=e.registry;return f?e.formats&&Ja.warn('Ignoring "formats" option because "registry" is specified'):f=e.formats?uy(e.formats,c.registry,Ja):c.registry,{...c,registry:f,container:t,theme:n,modules:Object.entries(d).reduce((m,g)=>{let[x,y]=g;if(!y)return m;let b=B.import(`modules/${x}`);return b==null?(Ja.error(`Cannot load ${x} module. Are you sure you registered it?`),m):{...m,[x]:si({},b.DEFAULTS||{},y)}},{}),bounds:my(c.bounds)}}function Zi(i,e,t,r){if(!this.isEnabled()&&e===ee.sources.USER&&!this.allowReadOnlyEdits)return new On.default;let n=t==null?null:this.getSelection(),s=this.editor.delta,a=i();if(n!=null&&(t===!0&&(t=n.index),r==null?n=gy(n,a,e):r!==0&&(n=gy(n,t,r,e)),this.setSelection(n,ee.sources.SILENT)),a.length()>0){let o=[ee.events.TEXT_CHANGE,a,s,e];this.emitter.emit(ee.events.EDITOR_CHANGE,...o),e!==ee.sources.SILENT&&this.emitter.emit(...o)}return a}function Jr(i,e,t,r,n){let s={};return typeof i.index=="number"&&typeof i.length=="number"?typeof e!="number"?(n=r,r=t,t=e,e=i.length,i=i.index):(e=i.length,i=i.index):typeof e!="number"&&(n=r,r=t,t=e,e=0),typeof t=="object"?(s=t,n=r):typeof t=="string"&&(r!=null?s[t]=r:n=t),n=n||ee.sources.API,[i,e,s,n]}function gy(i,e,t,r){let n=typeof t=="number"?t:0;if(i==null)return null;let s,a;return e&&typeof e.transformPosition=="function"?[s,a]=[i.index,i.index+i.length].map(o=>e.transformPosition(o,r!==ee.sources.USER)):[s,a]=[i.index,i.index+i.length].map(o=>o=0?o+n:Math.max(e,o+n)),new $t(s,a-s)}var On,Ja,rc,Qi,B,hi=T(()=>{An();De();On=yt(xi(),1);ay();Qr();Sm();Cs();Oi();Hl();ly();Fm();cy();fy();Ja=yi("quill"),rc=new _n;ai.uiClass="ql-ui";Qi=class Qi{static debug(e){e===!0&&(e="log"),yi.level(e)}static find(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;return Fl.get(e)||rc.find(e,t)}static import(e){return this.imports[e]==null&&Ja.error(`Cannot import ${e}. Are you sure it was registered?`),this.imports[e]}static register(){if(typeof(arguments.length<=0?void 0:arguments[0])!="string"){let e=arguments.length<=0?void 0:arguments[0],t=!!(!(arguments.length<=1)&&arguments[1]),r="attrName"in e?e.attrName:e.blotName;typeof r=="string"?this.register(`formats/${r}`,e,t):Object.keys(e).forEach(n=>{this.register(n,e[n],t)})}else{let e=arguments.length<=0?void 0:arguments[0],t=arguments.length<=1?void 0:arguments[1],r=!!(!(arguments.length<=2)&&arguments[2]);this.imports[e]!=null&&!r&&Ja.warn(`Overwriting ${e} with`,t),this.imports[e]=t,(e.startsWith("blots/")||e.startsWith("formats/"))&&t&&typeof t!="boolean"&&t.blotName!=="abstract"&&rc.register(t),typeof t.register=="function"&&t.register(rc)}}constructor(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(this.options=LB(e,t),this.container=this.options.container,this.container==null){Ja.error("Invalid Quill container",e);return}this.options.debug&&Qi.debug(this.options.debug);let r=this.container.innerHTML.trim();this.container.classList.add("ql-container"),this.container.innerHTML="",Fl.set(this.container,this),this.root=this.addContainer("ql-editor"),this.root.classList.add("ql-blank"),this.emitter=new ee;let n=El.blotName,s=this.options.registry.query(n);if(!s||!("blotName"in s))throw new Error(`Cannot initialize Quill without "${n}" blot`);if(this.scroll=new s(this.options.registry,this.root,{emitter:this.emitter}),this.editor=new sy(this.scroll),this.selection=new iy(this.scroll,this.emitter),this.composition=new oy(this.scroll,this.emitter),this.theme=new this.options.theme(this,this.options),this.keyboard=this.theme.addModule("keyboard"),this.clipboard=this.theme.addModule("clipboard"),this.history=this.theme.addModule("history"),this.uploader=this.theme.addModule("uploader"),this.theme.addModule("input"),this.theme.addModule("uiNode"),this.theme.init(),this.emitter.on(ee.events.EDITOR_CHANGE,a=>{a===ee.events.TEXT_CHANGE&&this.root.classList.toggle("ql-blank",this.editor.isBlank())}),this.emitter.on(ee.events.SCROLL_UPDATE,(a,o)=>{let l=this.selection.lastRange,[h]=this.selection.getRange(),d=l&&h?{oldRange:l,newRange:h}:void 0;Zi.call(this,()=>this.editor.update(null,o,d),a)}),this.emitter.on(ee.events.SCROLL_EMBED_UPDATE,(a,o)=>{let l=this.selection.lastRange,[h]=this.selection.getRange(),d=l&&h?{oldRange:l,newRange:h}:void 0;Zi.call(this,()=>{let c=new On.default().retain(a.offset(this)).retain({[a.statics.blotName]:o});return this.editor.update(c,[],d)},Qi.sources.USER)}),r){let a=this.clipboard.convert({html:`${r}


    `,text:` +`});this.setContents(a)}this.history.clear(),this.options.placeholder&&this.root.setAttribute("data-placeholder",this.options.placeholder),this.options.readOnly&&this.disable(),this.allowReadOnlyEdits=!1}addContainer(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(typeof e=="string"){let r=e;e=document.createElement("div"),e.classList.add(r)}return this.container.insertBefore(e,t),e}blur(){this.selection.setRange(null)}deleteText(e,t,r){return[e,t,,r]=Jr(e,t,r),Zi.call(this,()=>this.editor.deleteText(e,t),r,e,-1*t)}disable(){this.enable(!1)}editReadOnly(e){this.allowReadOnlyEdits=!0;let t=e();return this.allowReadOnlyEdits=!1,t}enable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;this.scroll.enable(e),this.container.classList.toggle("ql-disabled",!e)}focus(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.selection.focus(),e.preventScroll||this.scrollSelectionIntoView()}format(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:ee.sources.API;return Zi.call(this,()=>{let n=this.getSelection(!0),s=new On.default;if(n==null)return s;if(this.scroll.query(e,X.BLOCK))s=this.editor.formatLine(n.index,n.length,{[e]:t});else{if(n.length===0)return this.selection.format(e,t),s;s=this.editor.formatText(n.index,n.length,{[e]:t})}return this.setSelection(n,ee.sources.SILENT),s},r)}formatLine(e,t,r,n,s){let a;return[e,t,a,s]=Jr(e,t,r,n,s),Zi.call(this,()=>this.editor.formatLine(e,t,a),s,e,0)}formatText(e,t,r,n,s){let a;return[e,t,a,s]=Jr(e,t,r,n,s),Zi.call(this,()=>this.editor.formatText(e,t,a),s,e,0)}getBounds(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,r=null;if(typeof e=="number"?r=this.selection.getBounds(e,t):r=this.selection.getBounds(e.index,e.length),!r)return null;let n=this.container.getBoundingClientRect();return{bottom:r.bottom-n.top,height:r.height,left:r.left-n.left,right:r.right-n.left,top:r.top-n.top,width:r.width}}getContents(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.getLength()-e;return[e,t]=Jr(e,t),this.editor.getContents(e,t)}getFormat(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.getSelection(!0),t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return typeof e=="number"?this.editor.getFormat(e,t):this.editor.getFormat(e.index,e.length)}getIndex(e){return e.offset(this.scroll)}getLength(){return this.scroll.length()}getLeaf(e){return this.scroll.leaf(e)}getLine(e){return this.scroll.line(e)}getLines(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Number.MAX_VALUE;return typeof e!="number"?this.scroll.lines(e.index,e.length):this.scroll.lines(e,t)}getModule(e){return this.theme.modules[e]}getSelection(){return arguments.length>0&&arguments[0]!==void 0&&arguments[0]&&this.focus(),this.update(),this.selection.getRange()[0]}getSemanticHTML(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;return typeof e=="number"&&(t=t??this.getLength()-e),[e,t]=Jr(e,t),this.editor.getHTML(e,t)}getText(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;return typeof e=="number"&&(t=t??this.getLength()-e),[e,t]=Jr(e,t),this.editor.getText(e,t)}hasFocus(){return this.selection.hasFocus()}insertEmbed(e,t,r){let n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:Qi.sources.API;return Zi.call(this,()=>this.editor.insertEmbed(e,t,r),n,e)}insertText(e,t,r,n,s){let a;return[e,,a,s]=Jr(e,0,r,n,s),Zi.call(this,()=>this.editor.insertText(e,t,a),s,e,t.length)}isEnabled(){return this.scroll.isEnabled()}off(){return this.emitter.off(...arguments)}on(){return this.emitter.on(...arguments)}once(){return this.emitter.once(...arguments)}removeFormat(e,t,r){return[e,t,,r]=Jr(e,t,r),Zi.call(this,()=>this.editor.removeFormat(e,t),r,e)}scrollRectIntoView(e){dy(this.root,e)}scrollIntoView(){console.warn("Quill#scrollIntoView() has been deprecated and will be removed in the near future. Please use Quill#scrollSelectionIntoView() instead."),this.scrollSelectionIntoView()}scrollSelectionIntoView(){let e=this.selection.lastRange,t=e&&this.selection.getBounds(e.index,e.length);t&&this.scrollRectIntoView(t)}setContents(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:ee.sources.API;return Zi.call(this,()=>{e=new On.default(e);let r=this.getLength(),n=this.editor.deleteText(0,r),s=this.editor.insertContents(0,e),a=this.editor.deleteText(this.getLength()-1,1);return n.compose(s).compose(a)},t)}setSelection(e,t,r){e==null?this.selection.setRange(null,t||Qi.sources.API):([e,t,,r]=Jr(e,t,r),this.selection.setRange(new $t(Math.max(0,e),t),r),r!==ee.sources.SILENT&&this.scrollSelectionIntoView())}setText(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:ee.sources.API,r=new On.default().insert(e);return this.setContents(r,t)}update(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ee.sources.USER,t=this.scroll.update(e);return this.selection.update(e),t}updateContents(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:ee.sources.API;return Zi.call(this,()=>(e=new On.default(e),this.editor.applyDelta(e)),t,!0)}};U(Qi,"DEFAULTS",{bounds:null,modules:{clipboard:!0,keyboard:!0,history:!0,uploader:!0},placeholder:"",readOnly:!1,registry:rc,theme:"default"}),U(Qi,"events",ee.events),U(Qi,"sources",ee.sources),U(Qi,"version","2.0.3"),U(Qi,"imports",{delta:On.default,parchment:Sl,"core/module":Je,"core/theme":Qa});B=Qi});var Hm,Bi,eo=T(()=>{De();Hm=class extends Ha{},Bi=Hm});function xy(i){return i instanceof Oe||i instanceof gt}function yy(i){return typeof i.updateContent=="function"}function Um(i,e,t){t.reduce((r,n)=>{let s=Pi.Op.length(n),a=n.attributes||{};if(n.insert!=null){if(typeof n.insert=="string"){let o=n.insert;i.insertAt(r,o);let[l]=i.descendant(ct,r),h=li(l);a=Pi.AttributeMap.diff(h,a)||{}}else if(typeof n.insert=="object"){let o=Object.keys(n.insert)[0];if(o==null)return r;if(i.insertAt(r,o,n.insert[o]),i.scroll.query(o,X.INLINE)!=null){let[h]=i.descendant(ct,r),d=li(h);a=Pi.AttributeMap.diff(d,a)||{}}}}return Object.keys(a).forEach(o=>{i.formatAt(r,s,o,a[o])}),r+s},e)}var Pi,Bn,vy,by=T(()=>{De();Pi=yt(xi(),1);Qr();Ri();Rn();eo();Bn=class extends El{constructor(e,t,r){let{emitter:n}=r;super(e,t),this.emitter=n,this.batch=!1,this.optimize(),this.enable(),this.domNode.addEventListener("dragstart",s=>this.handleDragStart(s))}batchStart(){Array.isArray(this.batch)||(this.batch=[])}batchEnd(){if(!this.batch)return;let e=this.batch;this.batch=!1,this.update(e)}emitMount(e){this.emitter.emit(ee.events.SCROLL_BLOT_MOUNT,e)}emitUnmount(e){this.emitter.emit(ee.events.SCROLL_BLOT_UNMOUNT,e)}emitEmbedUpdate(e,t){this.emitter.emit(ee.events.SCROLL_EMBED_UPDATE,e,t)}deleteAt(e,t){let[r,n]=this.line(e),[s]=this.line(e+t);if(super.deleteAt(e,t),s!=null&&r!==s&&n>0){if(r instanceof gt||s instanceof gt){this.optimize();return}let a=s.children.head instanceof At?null:s.children.head;r.moveChildren(s,a),r.remove()}this.optimize()}enable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;this.domNode.setAttribute("contenteditable",e?"true":"false")}formatAt(e,t,r,n){super.formatAt(e,t,r,n),this.optimize()}insertAt(e,t,r){if(e>=this.length())if(r==null||this.scroll.query(t,X.BLOCK)==null){let n=this.scroll.create(this.statics.defaultChild.blotName);this.appendChild(n),r==null&&t.endsWith(` +`)?n.insertAt(0,t.slice(0,-1),r):n.insertAt(0,t,r)}else{let n=this.scroll.create(t,r);this.appendChild(n)}else super.insertAt(e,t,r);this.optimize()}insertBefore(e,t){if(e.statics.scope===X.INLINE_BLOT){let r=this.scroll.create(this.statics.defaultChild.blotName);r.appendChild(e),super.insertBefore(r,t)}else super.insertBefore(e,t)}insertContents(e,t){let r=this.deltaToRenderBlocks(t.concat(new Pi.default().insert(` +`))),n=r.pop();if(n==null)return;this.batchStart();let s=r.shift();if(s){let l=s.type==="block"&&(s.delta.length()===0||!this.descendant(gt,e)[0]&&e{this.formatAt(c-1,1,g,m[g])}),e=c}let[a,o]=this.children.find(e);if(r.length&&(a&&(a=a.split(o),o=0),r.forEach(l=>{if(l.type==="block"){let h=this.createBlock(l.attributes,a||void 0);Um(h,0,l.delta)}else{let h=this.create(l.key,l.value);this.insertBefore(h,a||void 0),Object.keys(l.attributes).forEach(d=>{h.format(d,l.attributes[d])})}})),n.type==="block"&&n.delta.length()){let l=a?a.offset(a.scroll)+o:this.length();Um(this,l,n.delta)}this.batchEnd(),this.optimize()}isEnabled(){return this.domNode.getAttribute("contenteditable")==="true"}leaf(e){let t=this.path(e).pop();if(!t)return[null,-1];let[r,n]=t;return r instanceof ct?[r,n]:[null,-1]}line(e){return e===this.length()?this.line(e-1):this.descendant(xy,e)}lines(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Number.MAX_VALUE,r=(n,s,a)=>{let o=[],l=a;return n.children.forEachAt(s,a,(h,d,c)=>{xy(h)?o.push(h):h instanceof Ha&&(o=o.concat(r(h,d,l))),l-=c}),o};return r(this,e,t)}optimize(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.batch||(super.optimize(e,t),e.length>0&&this.emitter.emit(ee.events.SCROLL_OPTIMIZE,e,t))}path(e){return super.path(e).slice(1)}remove(){}update(e){if(this.batch){Array.isArray(e)&&(this.batch=this.batch.concat(e));return}let t=ee.sources.USER;typeof e=="string"&&(t=e),Array.isArray(e)||(e=this.observer.takeRecords()),e=e.filter(r=>{let{target:n}=r,s=this.find(n,!0);return s&&!yy(s)}),e.length>0&&this.emitter.emit(ee.events.SCROLL_BEFORE_UPDATE,t,e),super.update(e.concat([])),e.length>0&&this.emitter.emit(ee.events.SCROLL_UPDATE,t,e)}updateEmbedAt(e,t,r){let[n]=this.descendant(s=>s instanceof gt,e);n&&n.statics.blotName===t&&yy(n)&&n.updateContent(r)}handleDragStart(e){e.preventDefault()}deltaToRenderBlocks(e){let t=[],r=new Pi.default;return e.forEach(n=>{let s=n?.insert;if(s)if(typeof s=="string"){let a=s.split(` +`);a.slice(0,-1).forEach(l=>{r.insert(l,n.attributes),t.push({type:"block",delta:r,attributes:n.attributes??{}}),r=new Pi.default});let o=a[a.length-1];o&&r.insert(o,n.attributes)}else{let a=Object.keys(s)[0];if(!a)return;this.query(a,X.INLINE)?r.push(n):(r.length()&&t.push({type:"block",delta:r,attributes:{}}),r=new Pi.default,t.push({type:"blockEmbed",key:a,value:s[a],attributes:n.attributes??{}}))}}),r.length()&&t.push({type:"block",delta:r,attributes:{}}),t}createBlock(e,t){let r,n={};Object.entries(e).forEach(o=>{let[l,h]=o;this.query(l,X.BLOCK&X.BLOT)!=null?r=l:n[l]=h});let s=this.create(r||this.statics.defaultChild.blotName,r?e[r]:void 0);this.insertBefore(s,t||void 0);let a=s.length();return Object.entries(n).forEach(o=>{let[l,h]=o;s.formatAt(0,a,l,h)}),s}};U(Bn,"blotName","scroll"),U(Bn,"className","ql-editor"),U(Bn,"tagName","DIV"),U(Bn,"defaultChild",Oe),U(Bn,"allowedChildren",[Oe,gt,Bi]);vy=Bn});var $m,wy,jm,nc,Gm=T(()=>{De();$m={scope:X.BLOCK,whitelist:["right","center","justify"]},wy=new qt("align","align",$m),jm=new dt("align","ql-align",$m),nc=new oi("align","text-align",$m)});var jl,My,Gl,sc=T(()=>{De();jl=class extends oi{value(e){let t=super.value(e);return t.startsWith("rgb(")?(t=t.replace(/^[^\d]+/,"").replace(/[^\d]+$/,""),`#${t.split(",").map(n=>`00${parseInt(n,10).toString(16)}`.slice(-2)).join("")}`):t}},My=new dt("color","ql-color",{scope:X.INLINE}),Gl=new jl("color","color",{scope:X.INLINE})});var Ty,Wl,Wm=T(()=>{De();sc();Ty=new dt("background","ql-bg",{scope:X.INLINE}),Wl=new jl("background","background-color",{scope:X.INLINE})});var vr,st,to,ac=T(()=>{Ri();Rn();Bl();Zr();Kr();eo();hi();vr=class extends Bi{static create(e){let t=super.create(e);return t.setAttribute("spellcheck","false"),t}code(e,t){return this.children.map(r=>r.length()<=1?"":r.domNode.innerText).join(` `).slice(e,e+t)}html(e,t){return`
     ${ks(this.code(e,t))}
    -
    `}},st=class extends De{static register(){B.register(wr)}};U(st,"TAB"," ");eo=class extends St{};eo.blotName="code";eo.tagName="CODE";st.blotName="code-block";st.className="ql-code-block";st.tagName="DIV";wr.blotName="code-block-container";wr.className="ql-code-block-container";wr.tagName="DIV";wr.allowedChildren=[st];st.allowedChildren=[nt,Et,On];st.requiredContainer=wr});var Om,Jd,Bm,ec,Pm=T(()=>{Re();Om={scope:X.BLOCK,whitelist:["rtl"]},Jd=new qt("direction","dir",Om),Bm=new ht("direction","ql-direction",Om),ec=new si("direction","direction",Om)});var dy,qm,Fm,tc,Hm=T(()=>{Re();dy={scope:X.INLINE,whitelist:["serif","monospace"]},qm=new ht("font","ql-font",dy),Fm=class extends si{value(e){return super.value(e).replace(/["']/g,"")}},tc=new Fm("font","font-family",dy)});var Um,ic,$m=T(()=>{Re();Um=new ht("size","ql-size",{scope:X.INLINE,whitelist:["small","large","huge"]}),ic=new si("size","font-size",{scope:X.INLINE,whitelist:["10px","18px","32px"]})});function cy(i){return{key:"Tab",shiftKey:!i,format:{"code-block":!0},handler(e,t){let{event:r}=t,n=this.quill.scroll.query("code-block"),{TAB:s}=n;if(e.length===0&&!r.shiftKey){this.quill.insertText(e.index,s,B.sources.USER),this.quill.setSelection(e.index+s.length,B.sources.SILENT);return}let a=e.length===0?this.quill.getLines(e.index,1):this.quill.getLines(e),{index:o,length:l}=e;a.forEach((h,d)=>{i?(h.insertAt(0,s),d===0?o+=s.length:l+=s.length):h.domNode.textContent.startsWith(s)&&(h.deleteAt(0,s.length),d===0?o-=s.length:l-=s.length)}),this.quill.update(B.sources.USER),this.quill.setSelection(o,l,B.sources.SILENT)}}}function rc(i,e){return{key:i,shiftKey:e,altKey:null,[i==="ArrowLeft"?"prefix":"suffix"]:/^$/,handler(r){let{index:n}=r;i==="ArrowRight"&&(n+=r.length+1);let[s]=this.quill.getLeaf(n);return s instanceof Ke?(i==="ArrowLeft"?e?this.quill.setSelection(r.index-1,r.length+1,B.sources.USER):this.quill.setSelection(r.index-1,B.sources.USER):e?this.quill.setSelection(r.index,r.length+1,B.sources.USER):this.quill.setSelection(r.index+r.length+1,B.sources.USER),!1):!0}}}function jm(i){return{key:i[0],shortKey:!0,handler(e,t){this.quill.format(i,!t.format[i],B.sources.USER)}}}function uy(i){return{key:i?"ArrowUp":"ArrowDown",collapsed:!0,format:["table"],handler(e,t){let r=i?"prev":"next",n=t.line,s=n.parent[r];if(s!=null){if(s.statics.blotName==="table-row"){let a=s.children.head,o=n;for(;o.prev!=null;)o=o.prev,a=a.next;let l=a.offset(this.quill.scroll)+Math.min(t.offset,a.length()-1);this.quill.setSelection(l,0,B.sources.USER)}}else{let a=n.table()[r];a!=null&&(i?this.quill.setSelection(a.offset(this.quill.scroll)+a.length()-1,0,B.sources.USER):this.quill.setSelection(a.offset(this.quill.scroll),0,B.sources.USER))}return!1}}}function cB(i){if(typeof i=="string"||typeof i=="number")i={key:i};else if(typeof i=="object")i=yr(i);else return null;return i.shortKey&&(i[hB]=i.shortKey,delete i.shortKey),i}function Ul(i){let{quill:e,range:t}=i,r=e.getLines(t),n={};if(r.length>1){let s=r[0].formats(),a=r[r.length-1].formats();n=kt.AttributeMap.diff(a,s)||{}}e.deleteText(t,B.sources.USER),Object.keys(n).length>0&&e.formatLine(t.index,1,n,B.sources.USER),e.setSelection(t.index,B.sources.SILENT)}function uB(i,e,t,r){return e.prev==null&&e.next==null?t.prev==null&&t.next==null?r===0?-1:1:t.prev==null?-1:1:e.prev==null?-1:e.next==null?1:null}var kt,lB,hB,Hl,dB,nc=T(()=>{kn();kt=pt(pi(),1);Re();oi();Cs();Di();lB=gi("quill:keyboard"),hB=/Mac/i.test(navigator.platform)?"metaKey":"ctrlKey",Hl=class i extends Qe{static match(e,t){return["altKey","ctrlKey","metaKey","shiftKey"].some(r=>!!t[r]!==e[r]&&t[r]!==null)?!1:t.key===e.key||t.key===e.which}constructor(e,t){super(e,t),this.bindings={},Object.keys(this.options.bindings).forEach(r=>{this.options.bindings[r]&&this.addBinding(this.options.bindings[r])}),this.addBinding({key:"Enter",shiftKey:null},this.handleEnter),this.addBinding({key:"Enter",metaKey:null,ctrlKey:null,altKey:null},()=>{}),/Firefox/i.test(navigator.userAgent)?(this.addBinding({key:"Backspace"},{collapsed:!0},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0},this.handleDelete)):(this.addBinding({key:"Backspace"},{collapsed:!0,prefix:/^.?$/},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0,suffix:/^.?$/},this.handleDelete)),this.addBinding({key:"Backspace"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Delete"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Backspace",altKey:null,ctrlKey:null,metaKey:null,shiftKey:null},{collapsed:!0,offset:0},this.handleBackspace),this.listen()}addBinding(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},n=cB(e);if(n==null){lB.warn("Attempted to add invalid keyboard binding",n);return}typeof t=="function"&&(t={handler:t}),typeof r=="function"&&(r={handler:r}),(Array.isArray(n.key)?n.key:[n.key]).forEach(a=>{let o={...n,key:a,...t,...r};this.bindings[o.key]=this.bindings[o.key]||[],this.bindings[o.key].push(o)})}listen(){this.quill.root.addEventListener("keydown",e=>{if(e.defaultPrevented||e.isComposing||e.keyCode===229&&(e.key==="Enter"||e.key==="Backspace"))return;let n=(this.bindings[e.key]||[]).concat(this.bindings[e.which]||[]).filter(b=>i.match(e,b));if(n.length===0)return;let s=B.find(e.target,!0);if(s&&s.scroll!==this.quill.scroll)return;let a=this.quill.getSelection();if(a==null||!this.quill.hasFocus())return;let[o,l]=this.quill.getLine(a.index),[h,d]=this.quill.getLeaf(a.index),[c,f]=a.length===0?[h,d]:this.quill.getLeaf(a.index+a.length),m=h instanceof Ha?h.value().slice(0,d):"",g=c instanceof Ha?c.value().slice(f):"",x={collapsed:a.length===0,empty:a.length===0&&o.length()<=1,format:this.quill.getFormat(a),line:o,offset:l,prefix:m,suffix:g,event:e};n.some(b=>{if(b.collapsed!=null&&b.collapsed!==x.collapsed||b.empty!=null&&b.empty!==x.empty||b.offset!=null&&b.offset!==x.offset)return!1;if(Array.isArray(b.format)){if(b.format.every(S=>x.format[S]==null))return!1}else if(typeof b.format=="object"&&!Object.keys(b.format).every(S=>b.format[S]===!0?x.format[S]!=null:b.format[S]===!1?x.format[S]==null:ys(b.format[S],x.format[S])))return!1;return b.prefix!=null&&!b.prefix.test(x.prefix)||b.suffix!=null&&!b.suffix.test(x.suffix)?!1:b.handler.call(this,a,x,b)!==!0})&&e.preventDefault()})}handleBackspace(e,t){let r=/[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(t.prefix)?2:1;if(e.index===0||this.quill.getLength()<=1)return;let n={},[s]=this.quill.getLine(e.index),a=new kt.default().retain(e.index-r).delete(r);if(t.offset===0){let[o]=this.quill.getLine(e.index-1);if(o&&!(o.statics.blotName==="block"&&o.length()<=1)){let h=s.formats(),d=this.quill.getFormat(e.index-1,1);if(n=kt.AttributeMap.diff(h,d)||{},Object.keys(n).length>0){let c=new kt.default().retain(e.index+s.length()-2).retain(1,n);a=a.compose(c)}}}this.quill.updateContents(a,B.sources.USER),this.quill.focus()}handleDelete(e,t){let r=/^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(t.suffix)?2:1;if(e.index>=this.quill.getLength()-r)return;let n={},[s]=this.quill.getLine(e.index),a=new kt.default().retain(e.index).delete(r);if(t.offset>=s.length()-1){let[o]=this.quill.getLine(e.index+1);if(o){let l=s.formats(),h=this.quill.getFormat(e.index,1);n=kt.AttributeMap.diff(l,h)||{},Object.keys(n).length>0&&(a=a.retain(o.length()-1).retain(1,n))}}this.quill.updateContents(a,B.sources.USER),this.quill.focus()}handleDeleteRange(e){Ul({range:e,quill:this.quill}),this.quill.focus()}handleEnter(e,t){let r=Object.keys(t.format).reduce((s,a)=>(this.quill.scroll.query(a,X.BLOCK)&&!Array.isArray(t.format[a])&&(s[a]=t.format[a]),s),{}),n=new kt.default().retain(e.index).delete(e.length).insert(` -`,r);this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(e.index+1,B.sources.SILENT),this.quill.focus()}},dB={bindings:{bold:jm("bold"),italic:jm("italic"),underline:jm("underline"),indent:{key:"Tab",format:["blockquote","indent","list"],handler(i,e){return e.collapsed&&e.offset!==0?!0:(this.quill.format("indent","+1",B.sources.USER),!1)}},outdent:{key:"Tab",shiftKey:!0,format:["blockquote","indent","list"],handler(i,e){return e.collapsed&&e.offset!==0?!0:(this.quill.format("indent","-1",B.sources.USER),!1)}},"outdent backspace":{key:"Backspace",collapsed:!0,shiftKey:null,metaKey:null,ctrlKey:null,altKey:null,format:["indent","list"],offset:0,handler(i,e){e.format.indent!=null?this.quill.format("indent","-1",B.sources.USER):e.format.list!=null&&this.quill.format("list",!1,B.sources.USER)}},"indent code-block":cy(!0),"outdent code-block":cy(!1),"remove tab":{key:"Tab",shiftKey:!0,collapsed:!0,prefix:/\t$/,handler(i){this.quill.deleteText(i.index-1,1,B.sources.USER)}},tab:{key:"Tab",handler(i,e){if(e.format.table)return!0;this.quill.history.cutoff();let t=new kt.default().retain(i.index).delete(i.length).insert(" ");return this.quill.updateContents(t,B.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(i.index+1,B.sources.SILENT),!1}},"blockquote empty enter":{key:"Enter",collapsed:!0,format:["blockquote"],empty:!0,handler(){this.quill.format("blockquote",!1,B.sources.USER)}},"list empty enter":{key:"Enter",collapsed:!0,format:["list"],empty:!0,handler(i,e){let t={list:!1};e.format.indent&&(t.indent=!1),this.quill.formatLine(i.index,i.length,t,B.sources.USER)}},"checklist enter":{key:"Enter",collapsed:!0,format:{list:"checked"},handler(i){let[e,t]=this.quill.getLine(i.index),r={...e.formats(),list:"checked"},n=new kt.default().retain(i.index).insert(` -`,r).retain(e.length()-t-1).retain(1,{list:"unchecked"});this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(i.index+1,B.sources.SILENT),this.quill.scrollSelectionIntoView()}},"header enter":{key:"Enter",collapsed:!0,format:["header"],suffix:/^$/,handler(i,e){let[t,r]=this.quill.getLine(i.index),n=new kt.default().retain(i.index).insert(` -`,e.format).retain(t.length()-r-1).retain(1,{header:null});this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(i.index+1,B.sources.SILENT),this.quill.scrollSelectionIntoView()}},"table backspace":{key:"Backspace",format:["table"],collapsed:!0,offset:0,handler(){}},"table delete":{key:"Delete",format:["table"],collapsed:!0,suffix:/^$/,handler(){}},"table enter":{key:"Enter",shiftKey:null,format:["table"],handler(i){let e=this.quill.getModule("table");if(e){let[t,r,n,s]=e.getTable(i),a=uB(t,r,n,s);if(a==null)return;let o=t.offset();if(a<0){let l=new kt.default().retain(o).insert(` -`);this.quill.updateContents(l,B.sources.USER),this.quill.setSelection(i.index+1,i.length,B.sources.SILENT)}else if(a>0){o+=t.length();let l=new kt.default().retain(o).insert(` -`);this.quill.updateContents(l,B.sources.USER),this.quill.setSelection(o,B.sources.USER)}}}},"table tab":{key:"Tab",shiftKey:null,format:["table"],handler(i,e){let{event:t,line:r}=e,n=r.offset(this.quill.scroll);t.shiftKey?this.quill.setSelection(n-1,B.sources.USER):this.quill.setSelection(n+r.length(),B.sources.USER)}},"list autofill":{key:" ",shiftKey:null,collapsed:!0,format:{"code-block":!1,blockquote:!1,table:!1},prefix:/^\s*?(\d+\.|-|\*|\[ ?\]|\[x\])$/,handler(i,e){if(this.quill.scroll.query("list")==null)return!0;let{length:t}=e.prefix,[r,n]=this.quill.getLine(i.index);if(n>t)return!0;let s;switch(e.prefix.trim()){case"[]":case"[ ]":s="unchecked";break;case"[x]":s="checked";break;case"-":case"*":s="bullet";break;default:s="ordered"}this.quill.insertText(i.index," ",B.sources.USER),this.quill.history.cutoff();let a=new kt.default().retain(i.index-n).delete(t+1).retain(r.length()-2-n).retain(1,{list:s});return this.quill.updateContents(a,B.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(i.index-t,B.sources.SILENT),!1}},"code exit":{key:"Enter",collapsed:!0,format:["code-block"],prefix:/^$/,suffix:/^\s*$/,handler(i){let[e,t]=this.quill.getLine(i.index),r=2,n=e;for(;n!=null&&n.length()<=1&&n.formats()["code-block"];)if(n=n.prev,r-=1,r<=0){let s=new kt.default().retain(i.index+e.length()-t-2).retain(1,{"code-block":null}).delete(1);return this.quill.updateContents(s,B.sources.USER),this.quill.setSelection(i.index-1,B.sources.SILENT),!1}return!0}},"embed left":rc("ArrowLeft",!1),"embed left shift":rc("ArrowLeft",!0),"embed right":rc("ArrowRight",!1),"embed right shift":rc("ArrowRight",!0),"table down":uy(!1),"table up":uy(!0)}};Hl.DEFAULTS=dB});function Gm(i){i.querySelector('[id^="docs-internal-guid-"]')&&(gB(i),pB(i))}var fB,mB,fy,pB,gB,my=T(()=>{fB=/font-weight:\s*normal/,mB=["P","OL","UL"],fy=i=>i&&mB.includes(i.tagName),pB=i=>{Array.from(i.querySelectorAll("br")).filter(e=>fy(e.previousElementSibling)&&fy(e.nextElementSibling)).forEach(e=>{e.parentNode?.removeChild(e)})},gB=i=>{Array.from(i.querySelectorAll('b[style*="font-weight"]')).filter(e=>e.getAttribute("style")?.match(fB)).forEach(e=>{let t=i.createDocumentFragment();t.append(...e.childNodes),e.parentNode?.replaceChild(t,e)})}});function Vm(i){i.documentElement.getAttribute("xmlns:w")==="urn:schemas-microsoft-com:office:word"&&wB(i)}var xB,yB,vB,bB,wB,py=T(()=>{xB=/\bmso-list:[^;]*ignore/i,yB=/\bmso-list:[^;]*\bl(\d+)/i,vB=/\bmso-list:[^;]*\blevel(\d+)/i,bB=(i,e)=>{let t=i.getAttribute("style"),r=t?.match(yB);if(!r)return null;let n=Number(r[1]),s=t?.match(vB),a=s?Number(s[1]):1,o=new RegExp(`@list l${n}:level${a}\\s*\\{[^\\}]*mso-level-number-format:\\s*([\\w-]+)`,"i"),l=e.match(o),h=l&&l[1]==="bullet"?"bullet":"ordered";return{id:n,indent:a,type:h,element:i}},wB=i=>{let e=Array.from(i.querySelectorAll("[style*=mso-list]")),t=[],r=[];e.forEach(a=>{(a.getAttribute("style")||"").match(xB)?t.push(a):r.push(a)}),t.forEach(a=>a.parentNode?.removeChild(a));let n=i.documentElement.innerHTML,s=r.map(a=>bB(a,n)).filter(a=>a);for(;s.length;){let a=[],o=s.shift();for(;o;)a.push(o),o=s.length&&s[0]?.element===o.element.nextElementSibling&&s[0].id===o.id?s.shift():null;let l=document.createElement("ul");a.forEach(c=>{let f=document.createElement("li");f.setAttribute("data-list",c.type),c.indent>1&&f.setAttribute("class",`ql-indent-${c.indent-1}`),f.innerHTML=c.element.innerHTML,l.appendChild(f)});let h=a[0]?.element,{parentNode:d}=h??{};h&&d?.replaceChild(l,h),a.slice(1).forEach(c=>{let{element:f}=c;d?.removeChild(f)})}}});var MB,TB,gy,xy=T(()=>{my();py();MB=[Vm,Gm],TB=i=>{i.documentElement&&MB.forEach(e=>{e(i)})},gy=TB});function _s(i,e,t,r){return r.query(e)?i.reduce((n,s)=>{if(!s.insert)return n;if(s.attributes&&s.attributes[e])return n.push(s);let a=t?{[e]:t}:{};return n.insert(s.insert,{...a,...s.attributes})},new li.default):i}function jl(i,e){let t="";for(let r=i.ops.length-1;r>=0&&t.lengtha(e,s,i),new li.default):e.nodeType===e.ELEMENT_NODE?Array.from(e.childNodes||[]).reduce((s,a)=>{let o=ac(i,a,t,r,n);return a.nodeType===e.ELEMENT_NODE&&(o=t.reduce((l,h)=>h(a,l,i),o),o=(n.get(a)||[]).reduce((l,h)=>h(a,l,i),o)),s.concat(o)},new li.default):new li.default}function Wm(i){return(e,t,r)=>_s(t,i,!0,r)}function kB(i,e,t){let r=qt.keys(i),n=ht.keys(i),s=si.keys(i),a={};return r.concat(n).concat(s).forEach(o=>{let l=t.query(o,X.ATTRIBUTE);l!=null&&(a[l.attrName]=l.value(i),a[l.attrName])||(l=SB[o],l!=null&&(l.attrName===o||l.keyName===o)&&(a[l.attrName]=l.value(i)||void 0),l=yy[o],l!=null&&(l.attrName===o||l.keyName===o)&&(l=yy[o],a[l.attrName]=l.value(i)||void 0))}),Object.entries(a).reduce((o,l)=>{let[h,d]=l;return _s(o,h,d,t)},e)}function CB(i,e,t){let r=t.query(i);if(r==null)return e;if(r.prototype instanceof Ke){let n={},s=r.value(i);if(s!=null)return n[r.blotName]=s,new li.default().insert(n,r.formats(i,t))}else if(r.prototype instanceof vs&&!jl(e,` +`}},st=class extends Oe{static register(){B.register(vr)}};U(st,"TAB"," ");to=class extends kt{};to.blotName="code";to.tagName="CODE";st.blotName="code-block";st.className="ql-code-block";st.tagName="DIV";vr.blotName="code-block-container";vr.className="ql-code-block-container";vr.tagName="DIV";vr.allowedChildren=[st];st.allowedChildren=[nt,At,Dn];st.requiredContainer=vr});var Vm,oc,Ym,lc,Xm=T(()=>{De();Vm={scope:X.BLOCK,whitelist:["rtl"]},oc=new qt("direction","dir",Vm),Ym=new dt("direction","ql-direction",Vm),lc=new oi("direction","direction",Vm)});var Ny,Zm,Km,hc,Qm=T(()=>{De();Ny={scope:X.INLINE,whitelist:["serif","monospace"]},Zm=new dt("font","ql-font",Ny),Km=class extends oi{value(e){return super.value(e).replace(/["']/g,"")}},hc=new Km("font","font-family",Ny)});var Jm,dc,ep=T(()=>{De();Jm=new dt("size","ql-size",{scope:X.INLINE,whitelist:["small","large","huge"]}),dc=new oi("size","font-size",{scope:X.INLINE,whitelist:["10px","18px","32px"]})});function Ey(i){return{key:"Tab",shiftKey:!i,format:{"code-block":!0},handler(e,t){let{event:r}=t,n=this.quill.scroll.query("code-block"),{TAB:s}=n;if(e.length===0&&!r.shiftKey){this.quill.insertText(e.index,s,B.sources.USER),this.quill.setSelection(e.index+s.length,B.sources.SILENT);return}let a=e.length===0?this.quill.getLines(e.index,1):this.quill.getLines(e),{index:o,length:l}=e;a.forEach((h,d)=>{i?(h.insertAt(0,s),d===0?o+=s.length:l+=s.length):h.domNode.textContent.startsWith(s)&&(h.deleteAt(0,s.length),d===0?o-=s.length:l-=s.length)}),this.quill.update(B.sources.USER),this.quill.setSelection(o,l,B.sources.SILENT)}}}function cc(i,e){return{key:i,shiftKey:e,altKey:null,[i==="ArrowLeft"?"prefix":"suffix"]:/^$/,handler(r){let{index:n}=r;i==="ArrowRight"&&(n+=r.length+1);let[s]=this.quill.getLeaf(n);return s instanceof Ze?(i==="ArrowLeft"?e?this.quill.setSelection(r.index-1,r.length+1,B.sources.USER):this.quill.setSelection(r.index-1,B.sources.USER):e?this.quill.setSelection(r.index,r.length+1,B.sources.USER):this.quill.setSelection(r.index+r.length+1,B.sources.USER),!1):!0}}}function tp(i){return{key:i[0],shortKey:!0,handler(e,t){this.quill.format(i,!t.format[i],B.sources.USER)}}}function Sy(i){return{key:i?"ArrowUp":"ArrowDown",collapsed:!0,format:["table"],handler(e,t){let r=i?"prev":"next",n=t.line,s=n.parent[r];if(s!=null){if(s.statics.blotName==="table-row"){let a=s.children.head,o=n;for(;o.prev!=null;)o=o.prev,a=a.next;let l=a.offset(this.quill.scroll)+Math.min(t.offset,a.length()-1);this.quill.setSelection(l,0,B.sources.USER)}}else{let a=n.table()[r];a!=null&&(i?this.quill.setSelection(a.offset(this.quill.scroll)+a.length()-1,0,B.sources.USER):this.quill.setSelection(a.offset(this.quill.scroll),0,B.sources.USER))}return!1}}}function DB(i){if(typeof i=="string"||typeof i=="number")i={key:i};else if(typeof i=="object")i=gr(i);else return null;return i.shortKey&&(i[zB]=i.shortKey,delete i.shortKey),i}function Yl(i){let{quill:e,range:t}=i,r=e.getLines(t),n={};if(r.length>1){let s=r[0].formats(),a=r[r.length-1].formats();n=_t.AttributeMap.diff(a,s)||{}}e.deleteText(t,B.sources.USER),Object.keys(n).length>0&&e.formatLine(t.index,1,n,B.sources.USER),e.setSelection(t.index,B.sources.SILENT)}function OB(i,e,t,r){return e.prev==null&&e.next==null?t.prev==null&&t.next==null?r===0?-1:1:t.prev==null?-1:1:e.prev==null?-1:e.next==null?1:null}var _t,IB,zB,Vl,RB,uc=T(()=>{An();_t=yt(xi(),1);De();hi();Cs();Oi();IB=yi("quill:keyboard"),zB=/Mac/i.test(navigator.platform)?"metaKey":"ctrlKey",Vl=class i extends Je{static match(e,t){return["altKey","ctrlKey","metaKey","shiftKey"].some(r=>!!t[r]!==e[r]&&t[r]!==null)?!1:t.key===e.key||t.key===e.which}constructor(e,t){super(e,t),this.bindings={},Object.keys(this.options.bindings).forEach(r=>{this.options.bindings[r]&&this.addBinding(this.options.bindings[r])}),this.addBinding({key:"Enter",shiftKey:null},this.handleEnter),this.addBinding({key:"Enter",metaKey:null,ctrlKey:null,altKey:null},()=>{}),/Firefox/i.test(navigator.userAgent)?(this.addBinding({key:"Backspace"},{collapsed:!0},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0},this.handleDelete)):(this.addBinding({key:"Backspace"},{collapsed:!0,prefix:/^.?$/},this.handleBackspace),this.addBinding({key:"Delete"},{collapsed:!0,suffix:/^.?$/},this.handleDelete)),this.addBinding({key:"Backspace"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Delete"},{collapsed:!1},this.handleDeleteRange),this.addBinding({key:"Backspace",altKey:null,ctrlKey:null,metaKey:null,shiftKey:null},{collapsed:!0,offset:0},this.handleBackspace),this.listen()}addBinding(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},n=DB(e);if(n==null){IB.warn("Attempted to add invalid keyboard binding",n);return}typeof t=="function"&&(t={handler:t}),typeof r=="function"&&(r={handler:r}),(Array.isArray(n.key)?n.key:[n.key]).forEach(a=>{let o={...n,key:a,...t,...r};this.bindings[o.key]=this.bindings[o.key]||[],this.bindings[o.key].push(o)})}listen(){this.quill.root.addEventListener("keydown",e=>{if(e.defaultPrevented||e.isComposing||e.keyCode===229&&(e.key==="Enter"||e.key==="Backspace"))return;let n=(this.bindings[e.key]||[]).concat(this.bindings[e.which]||[]).filter(b=>i.match(e,b));if(n.length===0)return;let s=B.find(e.target,!0);if(s&&s.scroll!==this.quill.scroll)return;let a=this.quill.getSelection();if(a==null||!this.quill.hasFocus())return;let[o,l]=this.quill.getLine(a.index),[h,d]=this.quill.getLeaf(a.index),[c,f]=a.length===0?[h,d]:this.quill.getLeaf(a.index+a.length),m=h instanceof Ua?h.value().slice(0,d):"",g=c instanceof Ua?c.value().slice(f):"",x={collapsed:a.length===0,empty:a.length===0&&o.length()<=1,format:this.quill.getFormat(a),line:o,offset:l,prefix:m,suffix:g,event:e};n.some(b=>{if(b.collapsed!=null&&b.collapsed!==x.collapsed||b.empty!=null&&b.empty!==x.empty||b.offset!=null&&b.offset!==x.offset)return!1;if(Array.isArray(b.format)){if(b.format.every(E=>x.format[E]==null))return!1}else if(typeof b.format=="object"&&!Object.keys(b.format).every(E=>b.format[E]===!0?x.format[E]!=null:b.format[E]===!1?x.format[E]==null:ys(b.format[E],x.format[E])))return!1;return b.prefix!=null&&!b.prefix.test(x.prefix)||b.suffix!=null&&!b.suffix.test(x.suffix)?!1:b.handler.call(this,a,x,b)!==!0})&&e.preventDefault()})}handleBackspace(e,t){let r=/[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(t.prefix)?2:1;if(e.index===0||this.quill.getLength()<=1)return;let n={},[s]=this.quill.getLine(e.index),a=new _t.default().retain(e.index-r).delete(r);if(t.offset===0){let[o]=this.quill.getLine(e.index-1);if(o&&!(o.statics.blotName==="block"&&o.length()<=1)){let h=s.formats(),d=this.quill.getFormat(e.index-1,1);if(n=_t.AttributeMap.diff(h,d)||{},Object.keys(n).length>0){let c=new _t.default().retain(e.index+s.length()-2).retain(1,n);a=a.compose(c)}}}this.quill.updateContents(a,B.sources.USER),this.quill.focus()}handleDelete(e,t){let r=/^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(t.suffix)?2:1;if(e.index>=this.quill.getLength()-r)return;let n={},[s]=this.quill.getLine(e.index),a=new _t.default().retain(e.index).delete(r);if(t.offset>=s.length()-1){let[o]=this.quill.getLine(e.index+1);if(o){let l=s.formats(),h=this.quill.getFormat(e.index,1);n=_t.AttributeMap.diff(l,h)||{},Object.keys(n).length>0&&(a=a.retain(o.length()-1).retain(1,n))}}this.quill.updateContents(a,B.sources.USER),this.quill.focus()}handleDeleteRange(e){Yl({range:e,quill:this.quill}),this.quill.focus()}handleEnter(e,t){let r=Object.keys(t.format).reduce((s,a)=>(this.quill.scroll.query(a,X.BLOCK)&&!Array.isArray(t.format[a])&&(s[a]=t.format[a]),s),{}),n=new _t.default().retain(e.index).delete(e.length).insert(` +`,r);this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(e.index+1,B.sources.SILENT),this.quill.focus()}},RB={bindings:{bold:tp("bold"),italic:tp("italic"),underline:tp("underline"),indent:{key:"Tab",format:["blockquote","indent","list"],handler(i,e){return e.collapsed&&e.offset!==0?!0:(this.quill.format("indent","+1",B.sources.USER),!1)}},outdent:{key:"Tab",shiftKey:!0,format:["blockquote","indent","list"],handler(i,e){return e.collapsed&&e.offset!==0?!0:(this.quill.format("indent","-1",B.sources.USER),!1)}},"outdent backspace":{key:"Backspace",collapsed:!0,shiftKey:null,metaKey:null,ctrlKey:null,altKey:null,format:["indent","list"],offset:0,handler(i,e){e.format.indent!=null?this.quill.format("indent","-1",B.sources.USER):e.format.list!=null&&this.quill.format("list",!1,B.sources.USER)}},"indent code-block":Ey(!0),"outdent code-block":Ey(!1),"remove tab":{key:"Tab",shiftKey:!0,collapsed:!0,prefix:/\t$/,handler(i){this.quill.deleteText(i.index-1,1,B.sources.USER)}},tab:{key:"Tab",handler(i,e){if(e.format.table)return!0;this.quill.history.cutoff();let t=new _t.default().retain(i.index).delete(i.length).insert(" ");return this.quill.updateContents(t,B.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(i.index+1,B.sources.SILENT),!1}},"blockquote empty enter":{key:"Enter",collapsed:!0,format:["blockquote"],empty:!0,handler(){this.quill.format("blockquote",!1,B.sources.USER)}},"list empty enter":{key:"Enter",collapsed:!0,format:["list"],empty:!0,handler(i,e){let t={list:!1};e.format.indent&&(t.indent=!1),this.quill.formatLine(i.index,i.length,t,B.sources.USER)}},"checklist enter":{key:"Enter",collapsed:!0,format:{list:"checked"},handler(i){let[e,t]=this.quill.getLine(i.index),r={...e.formats(),list:"checked"},n=new _t.default().retain(i.index).insert(` +`,r).retain(e.length()-t-1).retain(1,{list:"unchecked"});this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(i.index+1,B.sources.SILENT),this.quill.scrollSelectionIntoView()}},"header enter":{key:"Enter",collapsed:!0,format:["header"],suffix:/^$/,handler(i,e){let[t,r]=this.quill.getLine(i.index),n=new _t.default().retain(i.index).insert(` +`,e.format).retain(t.length()-r-1).retain(1,{header:null});this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(i.index+1,B.sources.SILENT),this.quill.scrollSelectionIntoView()}},"table backspace":{key:"Backspace",format:["table"],collapsed:!0,offset:0,handler(){}},"table delete":{key:"Delete",format:["table"],collapsed:!0,suffix:/^$/,handler(){}},"table enter":{key:"Enter",shiftKey:null,format:["table"],handler(i){let e=this.quill.getModule("table");if(e){let[t,r,n,s]=e.getTable(i),a=OB(t,r,n,s);if(a==null)return;let o=t.offset();if(a<0){let l=new _t.default().retain(o).insert(` +`);this.quill.updateContents(l,B.sources.USER),this.quill.setSelection(i.index+1,i.length,B.sources.SILENT)}else if(a>0){o+=t.length();let l=new _t.default().retain(o).insert(` +`);this.quill.updateContents(l,B.sources.USER),this.quill.setSelection(o,B.sources.USER)}}}},"table tab":{key:"Tab",shiftKey:null,format:["table"],handler(i,e){let{event:t,line:r}=e,n=r.offset(this.quill.scroll);t.shiftKey?this.quill.setSelection(n-1,B.sources.USER):this.quill.setSelection(n+r.length(),B.sources.USER)}},"list autofill":{key:" ",shiftKey:null,collapsed:!0,format:{"code-block":!1,blockquote:!1,table:!1},prefix:/^\s*?(\d+\.|-|\*|\[ ?\]|\[x\])$/,handler(i,e){if(this.quill.scroll.query("list")==null)return!0;let{length:t}=e.prefix,[r,n]=this.quill.getLine(i.index);if(n>t)return!0;let s;switch(e.prefix.trim()){case"[]":case"[ ]":s="unchecked";break;case"[x]":s="checked";break;case"-":case"*":s="bullet";break;default:s="ordered"}this.quill.insertText(i.index," ",B.sources.USER),this.quill.history.cutoff();let a=new _t.default().retain(i.index-n).delete(t+1).retain(r.length()-2-n).retain(1,{list:s});return this.quill.updateContents(a,B.sources.USER),this.quill.history.cutoff(),this.quill.setSelection(i.index-t,B.sources.SILENT),!1}},"code exit":{key:"Enter",collapsed:!0,format:["code-block"],prefix:/^$/,suffix:/^\s*$/,handler(i){let[e,t]=this.quill.getLine(i.index),r=2,n=e;for(;n!=null&&n.length()<=1&&n.formats()["code-block"];)if(n=n.prev,r-=1,r<=0){let s=new _t.default().retain(i.index+e.length()-t-2).retain(1,{"code-block":null}).delete(1);return this.quill.updateContents(s,B.sources.USER),this.quill.setSelection(i.index-1,B.sources.SILENT),!1}return!0}},"embed left":cc("ArrowLeft",!1),"embed left shift":cc("ArrowLeft",!0),"embed right":cc("ArrowRight",!1),"embed right shift":cc("ArrowRight",!0),"table down":Sy(!1),"table up":Sy(!0)}};Vl.DEFAULTS=RB});function ip(i){i.querySelector('[id^="docs-internal-guid-"]')&&(qB(i),FB(i))}var BB,PB,Ay,FB,qB,ky=T(()=>{BB=/font-weight:\s*normal/,PB=["P","OL","UL"],Ay=i=>i&&PB.includes(i.tagName),FB=i=>{Array.from(i.querySelectorAll("br")).filter(e=>Ay(e.previousElementSibling)&&Ay(e.nextElementSibling)).forEach(e=>{e.parentNode?.removeChild(e)})},qB=i=>{Array.from(i.querySelectorAll('b[style*="font-weight"]')).filter(e=>e.getAttribute("style")?.match(BB)).forEach(e=>{let t=i.createDocumentFragment();t.append(...e.childNodes),e.parentNode?.replaceChild(t,e)})}});function rp(i){i.documentElement.getAttribute("xmlns:w")==="urn:schemas-microsoft-com:office:word"&&GB(i)}var HB,UB,$B,jB,GB,Cy=T(()=>{HB=/\bmso-list:[^;]*ignore/i,UB=/\bmso-list:[^;]*\bl(\d+)/i,$B=/\bmso-list:[^;]*\blevel(\d+)/i,jB=(i,e)=>{let t=i.getAttribute("style"),r=t?.match(UB);if(!r)return null;let n=Number(r[1]),s=t?.match($B),a=s?Number(s[1]):1,o=new RegExp(`@list l${n}:level${a}\\s*\\{[^\\}]*mso-level-number-format:\\s*([\\w-]+)`,"i"),l=e.match(o),h=l&&l[1]==="bullet"?"bullet":"ordered";return{id:n,indent:a,type:h,element:i}},GB=i=>{let e=Array.from(i.querySelectorAll("[style*=mso-list]")),t=[],r=[];e.forEach(a=>{(a.getAttribute("style")||"").match(HB)?t.push(a):r.push(a)}),t.forEach(a=>a.parentNode?.removeChild(a));let n=i.documentElement.innerHTML,s=r.map(a=>jB(a,n)).filter(a=>a);for(;s.length;){let a=[],o=s.shift();for(;o;)a.push(o),o=s.length&&s[0]?.element===o.element.nextElementSibling&&s[0].id===o.id?s.shift():null;let l=document.createElement("ul");a.forEach(c=>{let f=document.createElement("li");f.setAttribute("data-list",c.type),c.indent>1&&f.setAttribute("class",`ql-indent-${c.indent-1}`),f.innerHTML=c.element.innerHTML,l.appendChild(f)});let h=a[0]?.element,{parentNode:d}=h??{};h&&d?.replaceChild(l,h),a.slice(1).forEach(c=>{let{element:f}=c;d?.removeChild(f)})}}});var WB,VB,_y,Ly=T(()=>{ky();Cy();WB=[rp,ip],VB=i=>{i.documentElement&&WB.forEach(e=>{e(i)})},_y=VB});function _s(i,e,t,r){return r.query(e)?i.reduce((n,s)=>{if(!s.insert)return n;if(s.attributes&&s.attributes[e])return n.push(s);let a=t?{[e]:t}:{};return n.insert(s.insert,{...a,...s.attributes})},new di.default):i}function Kl(i,e){let t="";for(let r=i.ops.length-1;r>=0&&t.lengtha(e,s,i),new di.default):e.nodeType===e.ELEMENT_NODE?Array.from(e.childNodes||[]).reduce((s,a)=>{let o=mc(i,a,t,r,n);return a.nodeType===e.ELEMENT_NODE&&(o=t.reduce((l,h)=>h(a,l,i),o),o=(n.get(a)||[]).reduce((l,h)=>h(a,l,i),o)),s.concat(o)},new di.default):new di.default}function np(i){return(e,t,r)=>_s(t,i,!0,r)}function QB(i,e,t){let r=qt.keys(i),n=dt.keys(i),s=oi.keys(i),a={};return r.concat(n).concat(s).forEach(o=>{let l=t.query(o,X.ATTRIBUTE);l!=null&&(a[l.attrName]=l.value(i),a[l.attrName])||(l=KB[o],l!=null&&(l.attrName===o||l.keyName===o)&&(a[l.attrName]=l.value(i)||void 0),l=Iy[o],l!=null&&(l.attrName===o||l.keyName===o)&&(l=Iy[o],a[l.attrName]=l.value(i)||void 0))}),Object.entries(a).reduce((o,l)=>{let[h,d]=l;return _s(o,h,d,t)},e)}function JB(i,e,t){let r=t.query(i);if(r==null)return e;if(r.prototype instanceof Ze){let n={},s=r.value(i);if(s!=null)return n[r.blotName]=s,new di.default().insert(n,r.formats(i,t))}else if(r.prototype instanceof vs&&!Kl(e,` `)&&e.insert(` -`),"blotName"in r&&"formats"in r&&typeof r.formats=="function")return _s(e,r.blotName,r.formats(i,t),t);return e}function _B(i,e){return jl(e,` +`),"blotName"in r&&"formats"in r&&typeof r.formats=="function")return _s(e,r.blotName,r.formats(i,t),t);return e}function eP(i,e){return Kl(e,` `)||e.insert(` -`),e}function LB(i,e,t){let r=t.query("code-block"),n=r&&"formats"in r&&typeof r.formats=="function"?r.formats(i,t):!0;return _s(e,"code-block",n,t)}function IB(){return new li.default}function zB(i,e,t){let r=t.query(i);if(r==null||r.blotName!=="list"||!jl(e,` -`))return e;let n=-1,s=i.parentNode;for(;s!=null;)["OL","UL"].includes(s.tagName)&&(n+=1),s=s.parentNode;return n<=0?e:e.reduce((a,o)=>o.insert?o.attributes&&typeof o.attributes.indent=="number"?a.push(o):a.insert(o.insert,{indent:n,...o.attributes||{}}):a,new li.default)}function RB(i,e,t){let r=i,n=r.tagName==="OL"?"ordered":"bullet",s=r.getAttribute("data-checked");return s&&(n=s==="true"?"checked":"unchecked"),_s(e,"list",n,t)}function vy(i,e,t){if(!jl(e,` -`)){if(Fn(i,t)&&(i.childNodes.length>0||i instanceof HTMLParagraphElement))return e.insert(` -`);if(e.length()>0&&i.nextSibling){let r=i.nextSibling;for(;r!=null;){if(Fn(r,t))return e.insert(` -`);let n=t.query(r);if(n&&n.prototype instanceof ft)return e.insert(` -`);r=r.firstChild}}}return e}function DB(i,e,t){let r={},n=i.style||{};return n.fontStyle==="italic"&&(r.italic=!0),n.textDecoration==="underline"&&(r.underline=!0),n.textDecoration==="line-through"&&(r.strike=!0),(n.fontWeight?.startsWith("bold")||parseInt(n.fontWeight,10)>=700)&&(r.bold=!0),e=Object.entries(r).reduce((s,a)=>{let[o,l]=a;return _s(s,o,l,t)},e),parseFloat(n.textIndent||0)>0?new li.default().insert(" ").concat(e):e}function OB(i,e,t){let r=i.parentElement?.tagName==="TABLE"?i.parentElement:i.parentElement?.parentElement;if(r!=null){let s=Array.from(r.querySelectorAll("tr")).indexOf(i)+1;return _s(e,"table",s,t)}return e}function BB(i,e,t){let r=i.data;if(i.parentElement?.tagName==="O:P")return e.insert(r.trim());if(!by(i)){if(r.trim().length===0&&r.includes(` -`)&&!AB(i,t))return e;r=r.replace(/[^\S\u00a0]/g," "),r=r.replace(/ {2,}/g," "),(i.previousSibling==null&&i.parentElement!=null&&Fn(i.parentElement,t)||i.previousSibling instanceof Element&&Fn(i.previousSibling,t))&&(r=r.replace(/^ /,"")),(i.nextSibling==null&&i.parentElement!=null&&Fn(i.parentElement,t)||i.nextSibling instanceof Element&&Fn(i.nextSibling,t))&&(r=r.replace(/ $/,"")),r=r.replaceAll("\xA0"," ")}return e.insert(r)}var li,NB,EB,SB,yy,$l,sc,Ym=T(()=>{Re();li=pt(pi(),1);zi();Cs();Di();oi();Rm();Dm();Qd();Zd();Pm();Hm();$m();nc();xy();NB=gi("quill:clipboard"),EB=[[Node.TEXT_NODE,BB],[Node.TEXT_NODE,vy],["br",_B],[Node.ELEMENT_NODE,vy],[Node.ELEMENT_NODE,CB],[Node.ELEMENT_NODE,kB],[Node.ELEMENT_NODE,DB],["li",zB],["ol, ul",RB],["pre",LB],["tr",OB],["b",Wm("bold")],["i",Wm("italic")],["strike",Wm("strike")],["style",IB]],SB=[oy,Jd].reduce((i,e)=>(i[e.keyName]=e,i),{}),yy=[Kd,ql,Fl,ec,tc,ic].reduce((i,e)=>(i[e.keyName]=e,i),{}),$l=class extends Qe{constructor(e,t){super(e,t),this.quill.root.addEventListener("copy",r=>this.onCaptureCopy(r,!1)),this.quill.root.addEventListener("cut",r=>this.onCaptureCopy(r,!0)),this.quill.root.addEventListener("paste",this.onCapturePaste.bind(this)),this.matchers=[],EB.concat(this.options.matchers??[]).forEach(r=>{let[n,s]=r;this.addMatcher(n,s)})}addMatcher(e,t){this.matchers.push([e,t])}convert(e){let{html:t,text:r}=e,n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(n[st.blotName])return new li.default().insert(r||"",{[st.blotName]:n[st.blotName]});if(!t)return new li.default().insert(r||"",n);let s=this.convertHTML(t);return jl(s,` -`)&&(s.ops[s.ops.length-1].attributes==null||n.table)?s.compose(new li.default().retain(s.length()-1).delete(1)):s}normalizeHTML(e){gy(e)}convertHTML(e){let t=new DOMParser().parseFromString(e,"text/html");this.normalizeHTML(t);let r=t.body,n=new WeakMap,[s,a]=this.prepareMatching(r,n);return ac(this.quill.scroll,r,s,a,n)}dangerouslyPasteHTML(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:B.sources.API;if(typeof e=="string"){let n=this.convert({html:e,text:""});this.quill.setContents(n,t),this.quill.setSelection(0,B.sources.SILENT)}else{let n=this.convert({html:t,text:""});this.quill.updateContents(new li.default().retain(e).concat(n),r),this.quill.setSelection(e+n.length(),B.sources.SILENT)}}onCaptureCopy(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(e.defaultPrevented)return;e.preventDefault();let[r]=this.quill.selection.getRange();if(r==null)return;let{html:n,text:s}=this.onCopy(r,t);e.clipboardData?.setData("text/plain",s),e.clipboardData?.setData("text/html",n),t&&Ul({range:r,quill:this.quill})}normalizeURIList(e){return e.split(/\r?\n/).filter(t=>t[0]!=="#").join(` -`)}onCapturePaste(e){if(e.defaultPrevented||!this.quill.isEnabled())return;e.preventDefault();let t=this.quill.getSelection(!0);if(t==null)return;let r=e.clipboardData?.getData("text/html"),n=e.clipboardData?.getData("text/plain");if(!r&&!n){let a=e.clipboardData?.getData("text/uri-list");a&&(n=this.normalizeURIList(a))}let s=Array.from(e.clipboardData?.files||[]);if(!r&&s.length>0){this.quill.uploader.upload(t,s);return}if(r&&s.length>0){let a=new DOMParser().parseFromString(r,"text/html");if(a.body.childElementCount===1&&a.body.firstElementChild?.tagName==="IMG"){this.quill.uploader.upload(t,s);return}}this.onPaste(t,{html:r,text:n})}onCopy(e){let t=this.quill.getText(e);return{html:this.quill.getSemanticHTML(e),text:t}}onPaste(e,t){let{text:r,html:n}=t,s=this.quill.getFormat(e.index),a=this.convert({text:r,html:n},s);NB.log("onPaste",a,{text:r,html:n});let o=new li.default().retain(e.index).delete(e.length).concat(a);this.quill.updateContents(o,B.sources.USER),this.quill.setSelection(o.length()-e.length,B.sources.SILENT),this.quill.scrollSelectionIntoView()}prepareMatching(e,t){let r=[],n=[];return this.matchers.forEach(s=>{let[a,o]=s;switch(a){case Node.TEXT_NODE:n.push(o);break;case Node.ELEMENT_NODE:r.push(o);break;default:Array.from(e.querySelectorAll(a)).forEach(l=>{t.has(l)?t.get(l)?.push(o):t.set(l,[o])});break}}),[r,n]}};U($l,"DEFAULTS",{matchers:[]});sc=new WeakMap});function wy(i,e){let t=e;for(let r=i.length-1;r>=0;r-=1){let n=i[r];i[r]={delta:t.transform(n.delta,!0),range:n.range&&Xm(n.range,t)},t=n.delta.transform(t),i[r].delta.length()===0&&i.splice(r,1)}}function PB(i,e){let t=e.ops[e.ops.length-1];return t==null?!1:t.insert!=null?typeof t.insert=="string"&&t.insert.endsWith(` -`):t.attributes!=null?Object.keys(t.attributes).some(r=>i.query(r,X.BLOCK)!=null):!1}function FB(i,e){let t=e.reduce((n,s)=>n+(s.delete||0),0),r=e.length()-t;return PB(i,e)&&(r-=1),r}function Xm(i,e){if(!i)return i;let t=e.transformPosition(i.index),r=e.transformPosition(i.index+i.length);return{index:t,length:r-t}}var Gl,My=T(()=>{Re();Di();oi();Gl=class extends Qe{constructor(t,r){super(t,r);U(this,"lastRecorded",0);U(this,"ignoreChange",!1);U(this,"stack",{undo:[],redo:[]});U(this,"currentRange",null);this.quill.on(B.events.EDITOR_CHANGE,(n,s,a,o)=>{n===B.events.SELECTION_CHANGE?s&&o!==B.sources.SILENT&&(this.currentRange=s):n===B.events.TEXT_CHANGE&&(this.ignoreChange||(!this.options.userOnly||o===B.sources.USER?this.record(s,a):this.transform(s)),this.currentRange=Xm(this.currentRange,s))}),this.quill.keyboard.addBinding({key:"z",shortKey:!0},this.undo.bind(this)),this.quill.keyboard.addBinding({key:["z","Z"],shortKey:!0,shiftKey:!0},this.redo.bind(this)),/Win/i.test(navigator.platform)&&this.quill.keyboard.addBinding({key:"y",shortKey:!0},this.redo.bind(this)),this.quill.root.addEventListener("beforeinput",n=>{n.inputType==="historyUndo"?(this.undo(),n.preventDefault()):n.inputType==="historyRedo"&&(this.redo(),n.preventDefault())})}change(t,r){if(this.stack[t].length===0)return;let n=this.stack[t].pop();if(!n)return;let s=this.quill.getContents(),a=n.delta.invert(s);this.stack[r].push({delta:a,range:Xm(n.range,a)}),this.lastRecorded=0,this.ignoreChange=!0,this.quill.updateContents(n.delta,B.sources.USER),this.ignoreChange=!1,this.restoreSelection(n)}clear(){this.stack={undo:[],redo:[]}}cutoff(){this.lastRecorded=0}record(t,r){if(t.ops.length===0)return;this.stack.redo=[];let n=t.invert(r),s=this.currentRange,a=Date.now();if(this.lastRecorded+this.options.delay>a&&this.stack.undo.length>0){let o=this.stack.undo.pop();o&&(n=n.compose(o.delta),s=o.range)}else this.lastRecorded=a;n.length()!==0&&(this.stack.undo.push({delta:n,range:s}),this.stack.undo.length>this.options.maxStack&&this.stack.undo.shift())}redo(){this.change("redo","undo")}transform(t){wy(this.stack.undo,t),wy(this.stack.redo,t)}undo(){this.change("undo","redo")}restoreSelection(t){if(t.range)this.quill.setSelection(t.range,B.sources.USER);else{let r=FB(this.quill.scroll,t.delta);this.quill.setSelection(r,B.sources.USER)}}};U(Gl,"DEFAULTS",{delay:1e3,maxStack:100,userOnly:!1})});var Ty,oc,Ny,Ey=T(()=>{Ty=pt(pi(),1);Qr();Di();oc=class extends Qe{constructor(e,t){super(e,t),e.root.addEventListener("drop",r=>{r.preventDefault();let n=null;if(document.caretRangeFromPoint)n=document.caretRangeFromPoint(r.clientX,r.clientY);else if(document.caretPositionFromPoint){let a=document.caretPositionFromPoint(r.clientX,r.clientY);n=document.createRange(),n.setStart(a.offsetNode,a.offset),n.setEnd(a.offsetNode,a.offset)}let s=n&&e.selection.normalizeNative(n);if(s){let a=e.selection.normalizedToRange(s);r.dataTransfer?.files&&this.upload(a,r.dataTransfer.files)}})}upload(e,t){let r=[];Array.from(t).forEach(n=>{n&&this.options.mimetypes?.includes(n.type)&&r.push(n)}),r.length>0&&this.options.handler.call(this,e,r)}};oc.DEFAULTS={mimetypes:["image/png","image/jpeg"],handler(i,e){if(!this.quill.scroll.query("image"))return;let t=e.map(r=>new Promise(n=>{let s=new FileReader;s.onload=()=>{n(s.result)},s.readAsDataURL(r)}));Promise.all(t).then(r=>{let n=r.reduce((s,a)=>s.insert({image:a}),new Ty.default().retain(i.index).delete(i.length));this.quill.updateContents(n,J.sources.USER),this.quill.setSelection(i.index+r.length,J.sources.SILENT)})}};Ny=oc});function HB(i){return typeof i.data=="string"?i.data:i.dataTransfer?.types.includes("text/plain")?i.dataTransfer.getData("text/plain"):null}var Sy,qB,Km,Ay,ky=T(()=>{Sy=pt(pi(),1);Di();oi();nc();qB=["insertText","insertReplacementText"],Km=class extends Qe{constructor(e,t){super(e,t),e.root.addEventListener("beforeinput",r=>{this.handleBeforeInput(r)}),/Android/i.test(navigator.userAgent)||e.on(B.events.COMPOSITION_BEFORE_START,()=>{this.handleCompositionStart()})}deleteRange(e){Ul({range:e,quill:this.quill})}replaceText(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";if(e.length===0)return!1;if(t){let r=this.quill.getFormat(e.index,1);this.deleteRange(e),this.quill.updateContents(new Sy.default().retain(e.index).insert(t,r),B.sources.USER)}else this.deleteRange(e);return this.quill.setSelection(e.index+t.length,0,B.sources.SILENT),!0}handleBeforeInput(e){if(this.quill.composition.isComposing||e.defaultPrevented||!qB.includes(e.inputType))return;let t=e.getTargetRanges?e.getTargetRanges()[0]:null;if(!t||t.collapsed===!0)return;let r=HB(e);if(r==null)return;let n=this.quill.selection.normalizeNative(t),s=n?this.quill.selection.normalizedToRange(n):null;s&&this.replaceText(s,r)&&e.preventDefault()}handleCompositionStart(){let e=this.quill.getSelection();e&&this.replaceText(e)}};Ay=Km});var UB,$B,jB,Zm,Cy,_y=T(()=>{Re();Di();oi();UB=/Mac/i.test(navigator.platform),$B=100,jB=i=>!!(i.key==="ArrowLeft"||i.key==="ArrowRight"||i.key==="ArrowUp"||i.key==="ArrowDown"||i.key==="Home"||UB&&i.key==="a"&&i.ctrlKey===!0),Zm=class extends Qe{constructor(t,r){super(t,r);U(this,"isListening",!1);U(this,"selectionChangeDeadline",0);this.handleArrowKeys(),this.handleNavigationShortcuts()}handleArrowKeys(){this.quill.keyboard.addBinding({key:["ArrowLeft","ArrowRight"],offset:0,shiftKey:null,handler(t,r){let{line:n,event:s}=r;if(!(n instanceof ni)||!n.uiNode)return!0;let a=getComputedStyle(n.domNode).direction==="rtl";return a&&s.key!=="ArrowRight"||!a&&s.key!=="ArrowLeft"?!0:(this.quill.setSelection(t.index-1,t.length+(s.shiftKey?1:0),B.sources.USER),!1)}})}handleNavigationShortcuts(){this.quill.root.addEventListener("keydown",t=>{!t.defaultPrevented&&jB(t)&&this.ensureListeningToSelectionChange()})}ensureListeningToSelectionChange(){if(this.selectionChangeDeadline=Date.now()+$B,this.isListening)return;this.isListening=!0;let t=()=>{this.isListening=!1,Date.now()<=this.selectionChangeDeadline&&this.handleSelectionChange()};document.addEventListener("selectionchange",t,{once:!0})}handleSelectionChange(){let t=document.getSelection();if(!t)return;let r=t.getRangeAt(0);if(r.collapsed!==!0||r.startOffset!==0)return;let n=this.quill.scroll.find(r.startContainer);if(!(n instanceof ni)||!n.uiNode)return;let s=document.createRange();s.setStartAfter(n.uiNode),s.setEndAfter(n.uiNode),t.removeAllRanges(),t.addRange(s)}},Cy=Zm});var qn,lc,Qm=T(()=>{oi();zi();Dn();Ja();Ll();Wd();Zr();ay();Kr();Ym();My();nc();Ey();qn=pt(pi(),1);ky();_y();Di();B.register({"blots/block":De,"blots/block/embed":ft,"blots/break":Et,"blots/container":Oi,"blots/cursor":On,"blots/embed":Ka,"blots/inline":St,"blots/scroll":sy,"blots/text":nt,"modules/clipboard":$l,"modules/history":Gl,"modules/keyboard":Hl,"modules/uploader":Ny,"modules/input":Ay,"modules/uiNode":Cy});lc=B});var Jm,GB,Ly,Iy=T(()=>{Re();Jm=class extends ht{add(e,t){let r=0;if(t==="+1"||t==="-1"){let n=this.value(e)||0;r=t==="+1"?n+1:n-1}else typeof t=="number"&&(r=t);return r===0?(this.remove(e),!0):super.add(e,r.toString())}canAdd(e,t){return super.canAdd(e,t)||super.canAdd(e,parseInt(t,10))}value(e){return parseInt(super.value(e),10)||void 0}},GB=new Jm("indent","ql-indent",{scope:X.BLOCK,whitelist:[1,2,3,4,5,6,7,8]}),Ly=GB});var Vl,zy,Ry=T(()=>{zi();Vl=class extends De{};U(Vl,"blotName","blockquote"),U(Vl,"tagName","blockquote");zy=Vl});var Wl,Dy,Oy=T(()=>{zi();Wl=class extends De{static formats(e){return this.tagName.indexOf(e.tagName)+1}};U(Wl,"blotName","header"),U(Wl,"tagName",["H1","H2","H3","H4","H5","H6"]);Dy=Wl});var Ls,Hn,By=T(()=>{zi();Ja();oi();Ls=class extends Oi{};Ls.blotName="list-container";Ls.tagName="OL";Hn=class extends De{static create(e){let t=super.create();return t.setAttribute("data-list",e),t}static formats(e){return e.getAttribute("data-list")||void 0}static register(){B.register(Ls)}constructor(e,t){super(e,t);let r=t.ownerDocument.createElement("span"),n=s=>{if(!e.isEnabled())return;let a=this.statics.formats(t,e);a==="checked"?(this.format("list","unchecked"),s.preventDefault()):a==="unchecked"&&(this.format("list","checked"),s.preventDefault())};r.addEventListener("mousedown",n),r.addEventListener("touchstart",n),this.attachUI(r)}format(e,t){e===this.statics.blotName&&t?this.domNode.setAttribute("data-list",t):super.format(e,t)}};Hn.blotName="list";Hn.tagName="LI";Ls.allowedChildren=[Hn];Hn.requiredContainer=Ls});var Yl,to,hc=T(()=>{Zr();Yl=class extends St{static create(){return super.create()}static formats(){return!0}optimize(e){super.optimize(e),this.domNode.tagName!==this.statics.tagName[0]&&this.replaceWith(this.statics.blotName)}};U(Yl,"blotName","bold"),U(Yl,"tagName",["STRONG","B"]);to=Yl});var Xl,Py,Fy=T(()=>{hc();Xl=class extends to{};U(Xl,"blotName","italic"),U(Xl,"tagName",["EM","I"]);Py=Xl});function ep(i,e){let t=document.createElement("a");t.href=i;let r=t.href.slice(0,t.href.indexOf(":"));return e.indexOf(r)>-1}var xi,Kl=T(()=>{Zr();xi=class extends St{static create(e){let t=super.create(e);return t.setAttribute("href",this.sanitize(e)),t.setAttribute("rel","noopener noreferrer"),t.setAttribute("target","_blank"),t}static formats(e){return e.getAttribute("href")}static sanitize(e){return ep(e,this.PROTOCOL_WHITELIST)?e:this.SANITIZED_URL}format(e,t){e!==this.statics.blotName||!t?super.format(e,t):this.domNode.setAttribute("href",this.constructor.sanitize(t))}};U(xi,"blotName","link"),U(xi,"tagName","A"),U(xi,"SANITIZED_URL","about:blank"),U(xi,"PROTOCOL_WHITELIST",["http","https","mailto","tel","sms"])});var Zl,qy,Hy=T(()=>{Zr();Zl=class extends St{static create(e){return e==="super"?document.createElement("sup"):e==="sub"?document.createElement("sub"):super.create(e)}static formats(e){if(e.tagName==="SUB")return"sub";if(e.tagName==="SUP")return"super"}};U(Zl,"blotName","script"),U(Zl,"tagName",["SUB","SUP"]);qy=Zl});var Ql,Uy,$y=T(()=>{hc();Ql=class extends to{};U(Ql,"blotName","strike"),U(Ql,"tagName",["S","STRIKE"]);Uy=Ql});var Jl,jy,Gy=T(()=>{Zr();Jl=class extends St{};U(Jl,"blotName","underline"),U(Jl,"tagName","U");jy=Jl});var io,Vy,Wy=T(()=>{Wd();io=class extends Ka{static create(e){if(window.katex==null)throw new Error("Formula module requires KaTeX.");let t=super.create(e);return typeof e=="string"&&(window.katex.render(e,t,{throwOnError:!1,errorColor:"#f00"}),t.setAttribute("data-value",e)),t}static value(e){return e.getAttribute("data-value")}html(){let{formula:e}=this.value();return`${e}`}};U(io,"blotName","formula"),U(io,"className","ql-formula"),U(io,"tagName","SPAN");Vy=io});var Yy,e0,Xy,Ky=T(()=>{Re();Kl();Yy=["alt","height","width"],e0=class extends Ke{static create(e){let t=super.create(e);return typeof e=="string"&&t.setAttribute("src",this.sanitize(e)),t}static formats(e){return Yy.reduce((t,r)=>(e.hasAttribute(r)&&(t[r]=e.getAttribute(r)),t),{})}static match(e){return/\.(jpe?g|gif|png)$/.test(e)||/^data:image\/.+;base64/.test(e)}static sanitize(e){return ep(e,["http","https","data"])?e:"//:0"}static value(e){return e.getAttribute("src")}format(e,t){Yy.indexOf(e)>-1?t?this.domNode.setAttribute(e,t):this.domNode.removeAttribute(e):super.format(e,t)}};U(e0,"blotName","image"),U(e0,"tagName","IMG");Xy=e0});var Zy,ro,Qy,Jy=T(()=>{zi();Kl();Zy=["height","width"],ro=class extends ft{static create(e){let t=super.create(e);return t.setAttribute("frameborder","0"),t.setAttribute("allowfullscreen","true"),t.setAttribute("src",this.sanitize(e)),t}static formats(e){return Zy.reduce((t,r)=>(e.hasAttribute(r)&&(t[r]=e.getAttribute(r)),t),{})}static sanitize(e){return xi.sanitize(e)}static value(e){return e.getAttribute("src")}format(e,t){Zy.indexOf(e)>-1?t?this.domNode.setAttribute(e,t):this.domNode.removeAttribute(e):super.format(e,t)}html(){let{video:e}=this.value();return`
    ${e}`}};U(ro,"blotName","video"),U(ro,"className","ql-video"),U(ro,"tagName","IFRAME");Qy=ro});var dc,t0,en,hi,Is,VB,i0,ev=T(()=>{dc=pt(pi(),1);Re();Zr();oi();Di();zi();Dn();Ll();Kr();Qd();Ym();t0=new ht("code-token","hljs",{scope:X.INLINE}),en=class i extends St{static formats(e,t){for(;e!=null&&e!==t.domNode;){if(e.classList&&e.classList.contains(st.className))return super.formats(e,t);e=e.parentNode}}constructor(e,t,r){super(e,t,r),t0.add(this.domNode,r)}format(e,t){e!==i.blotName?super.format(e,t):t?t0.add(this.domNode,t):(t0.remove(this.domNode),this.domNode.classList.remove(this.statics.className))}optimize(){super.optimize(...arguments),t0.value(this.domNode)||this.unwrap()}};en.blotName="code-token";en.className="ql-token";hi=class extends st{static create(e){let t=super.create(e);return typeof e=="string"&&t.setAttribute("data-language",e),t}static formats(e){return e.getAttribute("data-language")||"plain"}static register(){}format(e,t){e===this.statics.blotName&&t?this.domNode.setAttribute("data-language",t):super.format(e,t)}replaceWith(e,t){return this.formatAt(0,this.length(),en.blotName,!1),super.replaceWith(e,t)}},Is=class extends wr{attach(){super.attach(),this.forceNext=!1,this.scroll.emitMount(this)}format(e,t){e===hi.blotName&&(this.forceNext=!0,this.children.forEach(r=>{r.format(e,t)}))}formatAt(e,t,r,n){r===hi.blotName&&(this.forceNext=!0),super.formatAt(e,t,r,n)}highlight(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(this.children.head==null)return;let n=`${Array.from(this.domNode.childNodes).filter(a=>a!==this.uiNode).map(a=>a.textContent).join(` +`),e}function tP(i,e,t){let r=t.query("code-block"),n=r&&"formats"in r&&typeof r.formats=="function"?r.formats(i,t):!0;return _s(e,"code-block",n,t)}function iP(){return new di.default}function rP(i,e,t){let r=t.query(i);if(r==null||r.blotName!=="list"||!Kl(e,` +`))return e;let n=-1,s=i.parentNode;for(;s!=null;)["OL","UL"].includes(s.tagName)&&(n+=1),s=s.parentNode;return n<=0?e:e.reduce((a,o)=>o.insert?o.attributes&&typeof o.attributes.indent=="number"?a.push(o):a.insert(o.insert,{indent:n,...o.attributes||{}}):a,new di.default)}function nP(i,e,t){let r=i,n=r.tagName==="OL"?"ordered":"bullet",s=r.getAttribute("data-checked");return s&&(n=s==="true"?"checked":"unchecked"),_s(e,"list",n,t)}function zy(i,e,t){if(!Kl(e,` +`)){if(Pn(i,t)&&(i.childNodes.length>0||i instanceof HTMLParagraphElement))return e.insert(` +`);if(e.length()>0&&i.nextSibling){let r=i.nextSibling;for(;r!=null;){if(Pn(r,t))return e.insert(` +`);let n=t.query(r);if(n&&n.prototype instanceof gt)return e.insert(` +`);r=r.firstChild}}}return e}function sP(i,e,t){let r={},n=i.style||{};return n.fontStyle==="italic"&&(r.italic=!0),n.textDecoration==="underline"&&(r.underline=!0),n.textDecoration==="line-through"&&(r.strike=!0),(n.fontWeight?.startsWith("bold")||parseInt(n.fontWeight,10)>=700)&&(r.bold=!0),e=Object.entries(r).reduce((s,a)=>{let[o,l]=a;return _s(s,o,l,t)},e),parseFloat(n.textIndent||0)>0?new di.default().insert(" ").concat(e):e}function aP(i,e,t){let r=i.parentElement?.tagName==="TABLE"?i.parentElement:i.parentElement?.parentElement;if(r!=null){let s=Array.from(r.querySelectorAll("tr")).indexOf(i)+1;return _s(e,"table",s,t)}return e}function oP(i,e,t){let r=i.data;if(i.parentElement?.tagName==="O:P")return e.insert(r.trim());if(!Ry(i)){if(r.trim().length===0&&r.includes(` +`)&&!ZB(i,t))return e;r=r.replace(/[^\S\u00a0]/g," "),r=r.replace(/ {2,}/g," "),(i.previousSibling==null&&i.parentElement!=null&&Pn(i.parentElement,t)||i.previousSibling instanceof Element&&Pn(i.previousSibling,t))&&(r=r.replace(/^ /,"")),(i.nextSibling==null&&i.parentElement!=null&&Pn(i.parentElement,t)||i.nextSibling instanceof Element&&Pn(i.nextSibling,t))&&(r=r.replace(/ $/,"")),r=r.replaceAll("\xA0"," ")}return e.insert(r)}var di,YB,XB,KB,Iy,Xl,fc,sp=T(()=>{De();di=yt(xi(),1);Ri();Cs();Oi();hi();Gm();Wm();ac();sc();Xm();Qm();ep();uc();Ly();YB=yi("quill:clipboard"),XB=[[Node.TEXT_NODE,oP],[Node.TEXT_NODE,zy],["br",eP],[Node.ELEMENT_NODE,zy],[Node.ELEMENT_NODE,JB],[Node.ELEMENT_NODE,QB],[Node.ELEMENT_NODE,sP],["li",rP],["ol, ul",nP],["pre",tP],["tr",aP],["b",np("bold")],["i",np("italic")],["strike",np("strike")],["style",iP]],KB=[wy,oc].reduce((i,e)=>(i[e.keyName]=e,i),{}),Iy=[nc,Wl,Gl,lc,hc,dc].reduce((i,e)=>(i[e.keyName]=e,i),{}),Xl=class extends Je{constructor(e,t){super(e,t),this.quill.root.addEventListener("copy",r=>this.onCaptureCopy(r,!1)),this.quill.root.addEventListener("cut",r=>this.onCaptureCopy(r,!0)),this.quill.root.addEventListener("paste",this.onCapturePaste.bind(this)),this.matchers=[],XB.concat(this.options.matchers??[]).forEach(r=>{let[n,s]=r;this.addMatcher(n,s)})}addMatcher(e,t){this.matchers.push([e,t])}convert(e){let{html:t,text:r}=e,n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(n[st.blotName])return new di.default().insert(r||"",{[st.blotName]:n[st.blotName]});if(!t)return new di.default().insert(r||"",n);let s=this.convertHTML(t);return Kl(s,` +`)&&(s.ops[s.ops.length-1].attributes==null||n.table)?s.compose(new di.default().retain(s.length()-1).delete(1)):s}normalizeHTML(e){_y(e)}convertHTML(e){let t=new DOMParser().parseFromString(e,"text/html");this.normalizeHTML(t);let r=t.body,n=new WeakMap,[s,a]=this.prepareMatching(r,n);return mc(this.quill.scroll,r,s,a,n)}dangerouslyPasteHTML(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:B.sources.API;if(typeof e=="string"){let n=this.convert({html:e,text:""});this.quill.setContents(n,t),this.quill.setSelection(0,B.sources.SILENT)}else{let n=this.convert({html:t,text:""});this.quill.updateContents(new di.default().retain(e).concat(n),r),this.quill.setSelection(e+n.length(),B.sources.SILENT)}}onCaptureCopy(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(e.defaultPrevented)return;e.preventDefault();let[r]=this.quill.selection.getRange();if(r==null)return;let{html:n,text:s}=this.onCopy(r,t);e.clipboardData?.setData("text/plain",s),e.clipboardData?.setData("text/html",n),t&&Yl({range:r,quill:this.quill})}normalizeURIList(e){return e.split(/\r?\n/).filter(t=>t[0]!=="#").join(` +`)}onCapturePaste(e){if(e.defaultPrevented||!this.quill.isEnabled())return;e.preventDefault();let t=this.quill.getSelection(!0);if(t==null)return;let r=e.clipboardData?.getData("text/html"),n=e.clipboardData?.getData("text/plain");if(!r&&!n){let a=e.clipboardData?.getData("text/uri-list");a&&(n=this.normalizeURIList(a))}let s=Array.from(e.clipboardData?.files||[]);if(!r&&s.length>0){this.quill.uploader.upload(t,s);return}if(r&&s.length>0){let a=new DOMParser().parseFromString(r,"text/html");if(a.body.childElementCount===1&&a.body.firstElementChild?.tagName==="IMG"){this.quill.uploader.upload(t,s);return}}this.onPaste(t,{html:r,text:n})}onCopy(e){let t=this.quill.getText(e);return{html:this.quill.getSemanticHTML(e),text:t}}onPaste(e,t){let{text:r,html:n}=t,s=this.quill.getFormat(e.index),a=this.convert({text:r,html:n},s);YB.log("onPaste",a,{text:r,html:n});let o=new di.default().retain(e.index).delete(e.length).concat(a);this.quill.updateContents(o,B.sources.USER),this.quill.setSelection(o.length()-e.length,B.sources.SILENT),this.quill.scrollSelectionIntoView()}prepareMatching(e,t){let r=[],n=[];return this.matchers.forEach(s=>{let[a,o]=s;switch(a){case Node.TEXT_NODE:n.push(o);break;case Node.ELEMENT_NODE:r.push(o);break;default:Array.from(e.querySelectorAll(a)).forEach(l=>{t.has(l)?t.get(l)?.push(o):t.set(l,[o])});break}}),[r,n]}};U(Xl,"DEFAULTS",{matchers:[]});fc=new WeakMap});function Dy(i,e){let t=e;for(let r=i.length-1;r>=0;r-=1){let n=i[r];i[r]={delta:t.transform(n.delta,!0),range:n.range&&ap(n.range,t)},t=n.delta.transform(t),i[r].delta.length()===0&&i.splice(r,1)}}function lP(i,e){let t=e.ops[e.ops.length-1];return t==null?!1:t.insert!=null?typeof t.insert=="string"&&t.insert.endsWith(` +`):t.attributes!=null?Object.keys(t.attributes).some(r=>i.query(r,X.BLOCK)!=null):!1}function hP(i,e){let t=e.reduce((n,s)=>n+(s.delete||0),0),r=e.length()-t;return lP(i,e)&&(r-=1),r}function ap(i,e){if(!i)return i;let t=e.transformPosition(i.index),r=e.transformPosition(i.index+i.length);return{index:t,length:r-t}}var Zl,Oy=T(()=>{De();Oi();hi();Zl=class extends Je{constructor(t,r){super(t,r);U(this,"lastRecorded",0);U(this,"ignoreChange",!1);U(this,"stack",{undo:[],redo:[]});U(this,"currentRange",null);this.quill.on(B.events.EDITOR_CHANGE,(n,s,a,o)=>{n===B.events.SELECTION_CHANGE?s&&o!==B.sources.SILENT&&(this.currentRange=s):n===B.events.TEXT_CHANGE&&(this.ignoreChange||(!this.options.userOnly||o===B.sources.USER?this.record(s,a):this.transform(s)),this.currentRange=ap(this.currentRange,s))}),this.quill.keyboard.addBinding({key:"z",shortKey:!0},this.undo.bind(this)),this.quill.keyboard.addBinding({key:["z","Z"],shortKey:!0,shiftKey:!0},this.redo.bind(this)),/Win/i.test(navigator.platform)&&this.quill.keyboard.addBinding({key:"y",shortKey:!0},this.redo.bind(this)),this.quill.root.addEventListener("beforeinput",n=>{n.inputType==="historyUndo"?(this.undo(),n.preventDefault()):n.inputType==="historyRedo"&&(this.redo(),n.preventDefault())})}change(t,r){if(this.stack[t].length===0)return;let n=this.stack[t].pop();if(!n)return;let s=this.quill.getContents(),a=n.delta.invert(s);this.stack[r].push({delta:a,range:ap(n.range,a)}),this.lastRecorded=0,this.ignoreChange=!0,this.quill.updateContents(n.delta,B.sources.USER),this.ignoreChange=!1,this.restoreSelection(n)}clear(){this.stack={undo:[],redo:[]}}cutoff(){this.lastRecorded=0}record(t,r){if(t.ops.length===0)return;this.stack.redo=[];let n=t.invert(r),s=this.currentRange,a=Date.now();if(this.lastRecorded+this.options.delay>a&&this.stack.undo.length>0){let o=this.stack.undo.pop();o&&(n=n.compose(o.delta),s=o.range)}else this.lastRecorded=a;n.length()!==0&&(this.stack.undo.push({delta:n,range:s}),this.stack.undo.length>this.options.maxStack&&this.stack.undo.shift())}redo(){this.change("redo","undo")}transform(t){Dy(this.stack.undo,t),Dy(this.stack.redo,t)}undo(){this.change("undo","redo")}restoreSelection(t){if(t.range)this.quill.setSelection(t.range,B.sources.USER);else{let r=hP(this.quill.scroll,t.delta);this.quill.setSelection(r,B.sources.USER)}}};U(Zl,"DEFAULTS",{delay:1e3,maxStack:100,userOnly:!1})});var By,pc,Py,Fy=T(()=>{By=yt(xi(),1);Qr();Oi();pc=class extends Je{constructor(e,t){super(e,t),e.root.addEventListener("drop",r=>{r.preventDefault();let n=null;if(document.caretRangeFromPoint)n=document.caretRangeFromPoint(r.clientX,r.clientY);else if(document.caretPositionFromPoint){let a=document.caretPositionFromPoint(r.clientX,r.clientY);n=document.createRange(),n.setStart(a.offsetNode,a.offset),n.setEnd(a.offsetNode,a.offset)}let s=n&&e.selection.normalizeNative(n);if(s){let a=e.selection.normalizedToRange(s);r.dataTransfer?.files&&this.upload(a,r.dataTransfer.files)}})}upload(e,t){let r=[];Array.from(t).forEach(n=>{n&&this.options.mimetypes?.includes(n.type)&&r.push(n)}),r.length>0&&this.options.handler.call(this,e,r)}};pc.DEFAULTS={mimetypes:["image/png","image/jpeg"],handler(i,e){if(!this.quill.scroll.query("image"))return;let t=e.map(r=>new Promise(n=>{let s=new FileReader;s.onload=()=>{n(s.result)},s.readAsDataURL(r)}));Promise.all(t).then(r=>{let n=r.reduce((s,a)=>s.insert({image:a}),new By.default().retain(i.index).delete(i.length));this.quill.updateContents(n,ee.sources.USER),this.quill.setSelection(i.index+r.length,ee.sources.SILENT)})}};Py=pc});function cP(i){return typeof i.data=="string"?i.data:i.dataTransfer?.types.includes("text/plain")?i.dataTransfer.getData("text/plain"):null}var qy,dP,op,Hy,Uy=T(()=>{qy=yt(xi(),1);Oi();hi();uc();dP=["insertText","insertReplacementText"],op=class extends Je{constructor(e,t){super(e,t),e.root.addEventListener("beforeinput",r=>{this.handleBeforeInput(r)}),/Android/i.test(navigator.userAgent)||e.on(B.events.COMPOSITION_BEFORE_START,()=>{this.handleCompositionStart()})}deleteRange(e){Yl({range:e,quill:this.quill})}replaceText(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";if(e.length===0)return!1;if(t){let r=this.quill.getFormat(e.index,1);this.deleteRange(e),this.quill.updateContents(new qy.default().retain(e.index).insert(t,r),B.sources.USER)}else this.deleteRange(e);return this.quill.setSelection(e.index+t.length,0,B.sources.SILENT),!0}handleBeforeInput(e){if(this.quill.composition.isComposing||e.defaultPrevented||!dP.includes(e.inputType))return;let t=e.getTargetRanges?e.getTargetRanges()[0]:null;if(!t||t.collapsed===!0)return;let r=cP(e);if(r==null)return;let n=this.quill.selection.normalizeNative(t),s=n?this.quill.selection.normalizedToRange(n):null;s&&this.replaceText(s,r)&&e.preventDefault()}handleCompositionStart(){let e=this.quill.getSelection();e&&this.replaceText(e)}};Hy=op});var uP,fP,mP,lp,$y,jy=T(()=>{De();Oi();hi();uP=/Mac/i.test(navigator.platform),fP=100,mP=i=>!!(i.key==="ArrowLeft"||i.key==="ArrowRight"||i.key==="ArrowUp"||i.key==="ArrowDown"||i.key==="Home"||uP&&i.key==="a"&&i.ctrlKey===!0),lp=class extends Je{constructor(t,r){super(t,r);U(this,"isListening",!1);U(this,"selectionChangeDeadline",0);this.handleArrowKeys(),this.handleNavigationShortcuts()}handleArrowKeys(){this.quill.keyboard.addBinding({key:["ArrowLeft","ArrowRight"],offset:0,shiftKey:null,handler(t,r){let{line:n,event:s}=r;if(!(n instanceof ai)||!n.uiNode)return!0;let a=getComputedStyle(n.domNode).direction==="rtl";return a&&s.key!=="ArrowRight"||!a&&s.key!=="ArrowLeft"?!0:(this.quill.setSelection(t.index-1,t.length+(s.shiftKey?1:0),B.sources.USER),!1)}})}handleNavigationShortcuts(){this.quill.root.addEventListener("keydown",t=>{!t.defaultPrevented&&mP(t)&&this.ensureListeningToSelectionChange()})}ensureListeningToSelectionChange(){if(this.selectionChangeDeadline=Date.now()+fP,this.isListening)return;this.isListening=!0;let t=()=>{this.isListening=!1,Date.now()<=this.selectionChangeDeadline&&this.handleSelectionChange()};document.addEventListener("selectionchange",t,{once:!0})}handleSelectionChange(){let t=document.getSelection();if(!t)return;let r=t.getRangeAt(0);if(r.collapsed!==!0||r.startOffset!==0)return;let n=this.quill.scroll.find(r.startContainer);if(!(n instanceof ai)||!n.uiNode)return;let s=document.createRange();s.setStartAfter(n.uiNode),s.setEndAfter(n.uiNode),t.removeAllRanges(),t.addRange(s)}},$y=lp});var Fn,gc,hp=T(()=>{hi();Ri();Rn();eo();Bl();tc();Zr();by();Kr();sp();Oy();uc();Fy();Fn=yt(xi(),1);Uy();jy();Oi();B.register({"blots/block":Oe,"blots/block/embed":gt,"blots/break":At,"blots/container":Bi,"blots/cursor":Dn,"blots/embed":Za,"blots/inline":kt,"blots/scroll":vy,"blots/text":nt,"modules/clipboard":Xl,"modules/history":Zl,"modules/keyboard":Vl,"modules/uploader":Py,"modules/input":Hy,"modules/uiNode":$y});gc=B});var dp,pP,Gy,Wy=T(()=>{De();dp=class extends dt{add(e,t){let r=0;if(t==="+1"||t==="-1"){let n=this.value(e)||0;r=t==="+1"?n+1:n-1}else typeof t=="number"&&(r=t);return r===0?(this.remove(e),!0):super.add(e,r.toString())}canAdd(e,t){return super.canAdd(e,t)||super.canAdd(e,parseInt(t,10))}value(e){return parseInt(super.value(e),10)||void 0}},pP=new dp("indent","ql-indent",{scope:X.BLOCK,whitelist:[1,2,3,4,5,6,7,8]}),Gy=pP});var Ql,Vy,Yy=T(()=>{Ri();Ql=class extends Oe{};U(Ql,"blotName","blockquote"),U(Ql,"tagName","blockquote");Vy=Ql});var Jl,Xy,Ky=T(()=>{Ri();Jl=class extends Oe{static formats(e){return this.tagName.indexOf(e.tagName)+1}};U(Jl,"blotName","header"),U(Jl,"tagName",["H1","H2","H3","H4","H5","H6"]);Xy=Jl});var Ls,qn,Zy=T(()=>{Ri();eo();hi();Ls=class extends Bi{};Ls.blotName="list-container";Ls.tagName="OL";qn=class extends Oe{static create(e){let t=super.create();return t.setAttribute("data-list",e),t}static formats(e){return e.getAttribute("data-list")||void 0}static register(){B.register(Ls)}constructor(e,t){super(e,t);let r=t.ownerDocument.createElement("span"),n=s=>{if(!e.isEnabled())return;let a=this.statics.formats(t,e);a==="checked"?(this.format("list","unchecked"),s.preventDefault()):a==="unchecked"&&(this.format("list","checked"),s.preventDefault())};r.addEventListener("mousedown",n),r.addEventListener("touchstart",n),this.attachUI(r)}format(e,t){e===this.statics.blotName&&t?this.domNode.setAttribute("data-list",t):super.format(e,t)}};qn.blotName="list";qn.tagName="LI";Ls.allowedChildren=[qn];qn.requiredContainer=Ls});var e0,io,xc=T(()=>{Zr();e0=class extends kt{static create(){return super.create()}static formats(){return!0}optimize(e){super.optimize(e),this.domNode.tagName!==this.statics.tagName[0]&&this.replaceWith(this.statics.blotName)}};U(e0,"blotName","bold"),U(e0,"tagName",["STRONG","B"]);io=e0});var t0,Qy,Jy=T(()=>{xc();t0=class extends io{};U(t0,"blotName","italic"),U(t0,"tagName",["EM","I"]);Qy=t0});function cp(i,e){let t=document.createElement("a");t.href=i;let r=t.href.slice(0,t.href.indexOf(":"));return e.indexOf(r)>-1}var vi,i0=T(()=>{Zr();vi=class extends kt{static create(e){let t=super.create(e);return t.setAttribute("href",this.sanitize(e)),t.setAttribute("rel","noopener noreferrer"),t.setAttribute("target","_blank"),t}static formats(e){return e.getAttribute("href")}static sanitize(e){return cp(e,this.PROTOCOL_WHITELIST)?e:this.SANITIZED_URL}format(e,t){e!==this.statics.blotName||!t?super.format(e,t):this.domNode.setAttribute("href",this.constructor.sanitize(t))}};U(vi,"blotName","link"),U(vi,"tagName","A"),U(vi,"SANITIZED_URL","about:blank"),U(vi,"PROTOCOL_WHITELIST",["http","https","mailto","tel","sms"])});var r0,ev,tv=T(()=>{Zr();r0=class extends kt{static create(e){return e==="super"?document.createElement("sup"):e==="sub"?document.createElement("sub"):super.create(e)}static formats(e){if(e.tagName==="SUB")return"sub";if(e.tagName==="SUP")return"super"}};U(r0,"blotName","script"),U(r0,"tagName",["SUB","SUP"]);ev=r0});var n0,iv,rv=T(()=>{xc();n0=class extends io{};U(n0,"blotName","strike"),U(n0,"tagName",["S","STRIKE"]);iv=n0});var s0,nv,sv=T(()=>{Zr();s0=class extends kt{};U(s0,"blotName","underline"),U(s0,"tagName","U");nv=s0});var ro,av,ov=T(()=>{tc();ro=class extends Za{static create(e){if(window.katex==null)throw new Error("Formula module requires KaTeX.");let t=super.create(e);return typeof e=="string"&&(window.katex.render(e,t,{throwOnError:!1,errorColor:"#f00"}),t.setAttribute("data-value",e)),t}static value(e){return e.getAttribute("data-value")}html(){let{formula:e}=this.value();return`${e}`}};U(ro,"blotName","formula"),U(ro,"className","ql-formula"),U(ro,"tagName","SPAN");av=ro});var lv,a0,hv,dv=T(()=>{De();i0();lv=["alt","height","width"],a0=class extends Ze{static create(e){let t=super.create(e);return typeof e=="string"&&t.setAttribute("src",this.sanitize(e)),t}static formats(e){return lv.reduce((t,r)=>(e.hasAttribute(r)&&(t[r]=e.getAttribute(r)),t),{})}static match(e){return/\.(jpe?g|gif|png)$/.test(e)||/^data:image\/.+;base64/.test(e)}static sanitize(e){return cp(e,["http","https","data"])?e:"//:0"}static value(e){return e.getAttribute("src")}format(e,t){lv.indexOf(e)>-1?t?this.domNode.setAttribute(e,t):this.domNode.removeAttribute(e):super.format(e,t)}};U(a0,"blotName","image"),U(a0,"tagName","IMG");hv=a0});var cv,no,uv,fv=T(()=>{Ri();i0();cv=["height","width"],no=class extends gt{static create(e){let t=super.create(e);return t.setAttribute("frameborder","0"),t.setAttribute("allowfullscreen","true"),t.setAttribute("src",this.sanitize(e)),t}static formats(e){return cv.reduce((t,r)=>(e.hasAttribute(r)&&(t[r]=e.getAttribute(r)),t),{})}static sanitize(e){return vi.sanitize(e)}static value(e){return e.getAttribute("src")}format(e,t){cv.indexOf(e)>-1?t?this.domNode.setAttribute(e,t):this.domNode.removeAttribute(e):super.format(e,t)}html(){let{video:e}=this.value();return`${e}`}};U(no,"blotName","video"),U(no,"className","ql-video"),U(no,"tagName","IFRAME");uv=no});var yc,o0,en,ci,Is,gP,l0,mv=T(()=>{yc=yt(xi(),1);De();Zr();hi();Oi();Ri();Rn();Bl();Kr();ac();sp();o0=new dt("code-token","hljs",{scope:X.INLINE}),en=class i extends kt{static formats(e,t){for(;e!=null&&e!==t.domNode;){if(e.classList&&e.classList.contains(st.className))return super.formats(e,t);e=e.parentNode}}constructor(e,t,r){super(e,t,r),o0.add(this.domNode,r)}format(e,t){e!==i.blotName?super.format(e,t):t?o0.add(this.domNode,t):(o0.remove(this.domNode),this.domNode.classList.remove(this.statics.className))}optimize(){super.optimize(...arguments),o0.value(this.domNode)||this.unwrap()}};en.blotName="code-token";en.className="ql-token";ci=class extends st{static create(e){let t=super.create(e);return typeof e=="string"&&t.setAttribute("data-language",e),t}static formats(e){return e.getAttribute("data-language")||"plain"}static register(){}format(e,t){e===this.statics.blotName&&t?this.domNode.setAttribute("data-language",t):super.format(e,t)}replaceWith(e,t){return this.formatAt(0,this.length(),en.blotName,!1),super.replaceWith(e,t)}},Is=class extends vr{attach(){super.attach(),this.forceNext=!1,this.scroll.emitMount(this)}format(e,t){e===ci.blotName&&(this.forceNext=!0,this.children.forEach(r=>{r.format(e,t)}))}formatAt(e,t,r,n){r===ci.blotName&&(this.forceNext=!0),super.formatAt(e,t,r,n)}highlight(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(this.children.head==null)return;let n=`${Array.from(this.domNode.childNodes).filter(a=>a!==this.uiNode).map(a=>a.textContent).join(` `)} -`,s=hi.formats(this.children.head.domNode);if(t||this.forceNext||this.cachedText!==n){if(n.trim().length>0||this.cachedText==null){let a=this.children.reduce((l,h)=>l.concat(cm(h,!1)),new dc.default),o=e(n,s);a.diff(o).reduce((l,h)=>{let{retain:d,attributes:c}=h;return d?(c&&Object.keys(c).forEach(f=>{[hi.blotName,en.blotName].includes(f)&&this.formatAt(l,d,f,c[f])}),l+d):l},0)}this.cachedText=n,this.forceNext=!1}}html(e,t){let[r]=this.children.find(e);return`
    +`,s=ci.formats(this.children.head.domNode);if(t||this.forceNext||this.cachedText!==n){if(n.trim().length>0||this.cachedText==null){let a=this.children.reduce((l,h)=>l.concat(Mm(h,!1)),new yc.default),o=e(n,s);a.diff(o).reduce((l,h)=>{let{retain:d,attributes:c}=h;return d?(c&&Object.keys(c).forEach(f=>{[ci.blotName,en.blotName].includes(f)&&this.formatAt(l,d,f,c[f])}),l+d):l},0)}this.cachedText=n,this.forceNext=!1}}html(e,t){let[r]=this.children.find(e);return`
     ${ks(this.code(e,t))}
    -
    `}optimize(e){if(super.optimize(e),this.parent!=null&&this.children.head!=null&&this.uiNode!=null){let t=hi.formats(this.children.head.domNode);t!==this.uiNode.value&&(this.uiNode.value=t)}}};Is.allowedChildren=[hi];hi.requiredContainer=Is;hi.allowedChildren=[en,On,nt,Et];VB=(i,e,t)=>{if(typeof i.versionString=="string"){let r=i.versionString.split(".")[0];if(parseInt(r,10)>=11)return i.highlight(t,{language:e}).value}return i.highlight(e,t).value},i0=class extends Qe{static register(){B.register(en,!0),B.register(hi,!0),B.register(Is,!0)}constructor(e,t){if(super(e,t),this.options.hljs==null)throw new Error("Syntax module requires highlight.js. Please include the library on the page before Quill.");this.languages=this.options.languages.reduce((r,n)=>{let{key:s}=n;return r[s]=!0,r},{}),this.highlightBlot=this.highlightBlot.bind(this),this.initListener(),this.initTimer()}initListener(){this.quill.on(B.events.SCROLL_BLOT_MOUNT,e=>{if(!(e instanceof Is))return;let t=this.quill.root.ownerDocument.createElement("select");this.options.languages.forEach(r=>{let{key:n,label:s}=r,a=t.ownerDocument.createElement("option");a.textContent=s,a.setAttribute("value",n),t.appendChild(a)}),t.addEventListener("change",()=>{e.format(hi.blotName,t.value),this.quill.root.focus(),this.highlight(e,!0)}),e.uiNode==null&&(e.attachUI(t),e.children.head&&(t.value=hi.formats(e.children.head.domNode)))})}initTimer(){let e=null;this.quill.on(B.events.SCROLL_OPTIMIZE,()=>{e&&clearTimeout(e),e=setTimeout(()=>{this.highlight(),e=null},this.options.interval)})}highlight(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:null,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(this.quill.selection.composing)return;this.quill.update(B.sources.USER);let r=this.quill.getSelection();(e==null?this.quill.scroll.descendants(Is):[e]).forEach(s=>{s.highlight(this.highlightBlot,t)}),this.quill.update(B.sources.SILENT),r!=null&&this.quill.setSelection(r,B.sources.SILENT)}highlightBlot(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"plain";if(t=this.languages[t]?t:"plain",t==="plain")return ks(e).split(` +
    `}optimize(e){if(super.optimize(e),this.parent!=null&&this.children.head!=null&&this.uiNode!=null){let t=ci.formats(this.children.head.domNode);t!==this.uiNode.value&&(this.uiNode.value=t)}}};Is.allowedChildren=[ci];ci.requiredContainer=Is;ci.allowedChildren=[en,Dn,nt,At];gP=(i,e,t)=>{if(typeof i.versionString=="string"){let r=i.versionString.split(".")[0];if(parseInt(r,10)>=11)return i.highlight(t,{language:e}).value}return i.highlight(e,t).value},l0=class extends Je{static register(){B.register(en,!0),B.register(ci,!0),B.register(Is,!0)}constructor(e,t){if(super(e,t),this.options.hljs==null)throw new Error("Syntax module requires highlight.js. Please include the library on the page before Quill.");this.languages=this.options.languages.reduce((r,n)=>{let{key:s}=n;return r[s]=!0,r},{}),this.highlightBlot=this.highlightBlot.bind(this),this.initListener(),this.initTimer()}initListener(){this.quill.on(B.events.SCROLL_BLOT_MOUNT,e=>{if(!(e instanceof Is))return;let t=this.quill.root.ownerDocument.createElement("select");this.options.languages.forEach(r=>{let{key:n,label:s}=r,a=t.ownerDocument.createElement("option");a.textContent=s,a.setAttribute("value",n),t.appendChild(a)}),t.addEventListener("change",()=>{e.format(ci.blotName,t.value),this.quill.root.focus(),this.highlight(e,!0)}),e.uiNode==null&&(e.attachUI(t),e.children.head&&(t.value=ci.formats(e.children.head.domNode)))})}initTimer(){let e=null;this.quill.on(B.events.SCROLL_OPTIMIZE,()=>{e&&clearTimeout(e),e=setTimeout(()=>{this.highlight(),e=null},this.options.interval)})}highlight(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:null,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(this.quill.selection.composing)return;this.quill.update(B.sources.USER);let r=this.quill.getSelection();(e==null?this.quill.scroll.descendants(Is):[e]).forEach(s=>{s.highlight(this.highlightBlot,t)}),this.quill.update(B.sources.SILENT),r!=null&&this.quill.setSelection(r,B.sources.SILENT)}highlightBlot(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"plain";if(t=this.languages[t]?t:"plain",t==="plain")return ks(e).split(` `).reduce((n,s,a)=>(a!==0&&n.insert(` -`,{[st.blotName]:t}),n.insert(s)),new dc.default);let r=this.quill.root.ownerDocument.createElement("div");return r.classList.add(st.className),r.innerHTML=VB(this.options.hljs,t,e),ac(this.quill.scroll,r,[(n,s)=>{let a=t0.value(n);return a?s.compose(new dc.default().retain(s.length(),{[en.blotName]:a})):s}],[(n,s)=>n.data.split(` +`,{[st.blotName]:t}),n.insert(s)),new yc.default);let r=this.quill.root.ownerDocument.createElement("div");return r.classList.add(st.className),r.innerHTML=gP(this.options.hljs,t,e),mc(this.quill.scroll,r,[(n,s)=>{let a=o0.value(n);return a?s.compose(new yc.default().retain(s.length(),{[en.blotName]:a})):s}],[(n,s)=>n.data.split(` `).reduce((a,o,l)=>(l!==0&&a.insert(` -`,{[st.blotName]:t}),a.insert(o)),s)],new WeakMap)}};i0.DEFAULTS={hljs:window.hljs,interval:1e3,languages:[{key:"plain",label:"Plain"},{key:"bash",label:"Bash"},{key:"cpp",label:"C++"},{key:"cs",label:"C#"},{key:"css",label:"CSS"},{key:"diff",label:"Diff"},{key:"xml",label:"HTML/XML"},{key:"java",label:"Java"},{key:"javascript",label:"JavaScript"},{key:"markdown",label:"Markdown"},{key:"php",label:"PHP"},{key:"python",label:"Python"},{key:"ruby",label:"Ruby"},{key:"sql",label:"SQL"}]}});function cc(){return`row-${Math.random().toString(36).slice(2,6)}`}var r0,Pi,Fi,yi,tn,tv=T(()=>{zi();Ja();r0=class r0 extends De{static create(e){let t=super.create();return e?t.setAttribute("data-row",e):t.setAttribute("data-row",cc()),t}static formats(e){if(e.hasAttribute("data-row"))return e.getAttribute("data-row")}cellOffset(){return this.parent?this.parent.children.indexOf(this):-1}format(e,t){e===r0.blotName&&t?this.domNode.setAttribute("data-row",t):super.format(e,t)}row(){return this.parent}rowOffset(){return this.row()?this.row().rowOffset():-1}table(){return this.row()&&this.row().table()}};U(r0,"blotName","table"),U(r0,"tagName","TD");Pi=r0,Fi=class extends Oi{checkMerge(){if(super.checkMerge()&&this.next.children.head!=null){let e=this.children.head.formats(),t=this.children.tail.formats(),r=this.next.children.head.formats(),n=this.next.children.tail.formats();return e.table===t.table&&e.table===r.table&&e.table===n.table}return!1}optimize(e){super.optimize(e),this.children.forEach(t=>{if(t.next==null)return;let r=t.formats(),n=t.next.formats();if(r.table!==n.table){let s=this.splitAfter(t);s&&s.optimize(),this.prev&&this.prev.optimize()}})}rowOffset(){return this.parent?this.parent.children.indexOf(this):-1}table(){return this.parent&&this.parent.parent}};U(Fi,"blotName","table-row"),U(Fi,"tagName","TR");yi=class extends Oi{};U(yi,"blotName","table-body"),U(yi,"tagName","TBODY");tn=class extends Oi{balanceCells(){let e=this.descendants(Fi),t=e.reduce((r,n)=>Math.max(n.children.length,r),0);e.forEach(r=>{new Array(t-r.children.length).fill(0).forEach(()=>{let n;r.children.head!=null&&(n=Pi.formats(r.children.head.domNode));let s=this.scroll.create(Pi.blotName,n);r.appendChild(s),s.optimize()})})}cells(e){return this.rows().map(t=>t.children.at(e))}deleteColumn(e){let[t]=this.descendant(yi);t==null||t.children.head==null||t.children.forEach(r=>{let n=r.children.at(e);n?.remove()})}insertColumn(e){let[t]=this.descendant(yi);t==null||t.children.head==null||t.children.forEach(r=>{let n=r.children.at(e),s=Pi.formats(r.children.head.domNode),a=this.scroll.create(Pi.blotName,s);r.insertBefore(a,n)})}insertRow(e){let[t]=this.descendant(yi);if(t==null||t.children.head==null)return;let r=cc(),n=this.scroll.create(Fi.blotName);t.children.head.children.forEach(()=>{let a=this.scroll.create(Pi.blotName,r);n.appendChild(a)});let s=t.children.at(e);t.insertBefore(n,s)}rows(){let e=this.children.head;return e==null?[]:e.children.map(t=>t)}};U(tn,"blotName","table-container"),U(tn,"tagName","TABLE");tn.allowedChildren=[yi];yi.requiredContainer=tn;yi.allowedChildren=[Fi];Fi.requiredContainer=yi;Fi.allowedChildren=[Pi];Pi.requiredContainer=Fi});var iv,tp,rv,nv=T(()=>{iv=pt(pi(),1);oi();Di();tv();tp=class extends Qe{static register(){B.register(Pi),B.register(Fi),B.register(yi),B.register(tn)}constructor(){super(...arguments),this.listenBalanceCells()}balanceTables(){this.quill.scroll.descendants(tn).forEach(e=>{e.balanceCells()})}deleteColumn(){let[e,,t]=this.getTable();t!=null&&(e.deleteColumn(t.cellOffset()),this.quill.update(B.sources.USER))}deleteRow(){let[,e]=this.getTable();e!=null&&(e.remove(),this.quill.update(B.sources.USER))}deleteTable(){let[e]=this.getTable();if(e==null)return;let t=e.offset();e.remove(),this.quill.update(B.sources.USER),this.quill.setSelection(t,B.sources.SILENT)}getTable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.quill.getSelection();if(e==null)return[null,null,null,-1];let[t,r]=this.quill.getLine(e.index);if(t==null||t.statics.blotName!==Pi.blotName)return[null,null,null,-1];let n=t.parent;return[n.parent.parent,n,t,r]}insertColumn(e){let t=this.quill.getSelection();if(!t)return;let[r,n,s]=this.getTable(t);if(s==null)return;let a=s.cellOffset();r.insertColumn(a+e),this.quill.update(B.sources.USER);let o=n.rowOffset();e===0&&(o+=1),this.quill.setSelection(t.index+o,t.length,B.sources.SILENT)}insertColumnLeft(){this.insertColumn(0)}insertColumnRight(){this.insertColumn(1)}insertRow(e){let t=this.quill.getSelection();if(!t)return;let[r,n,s]=this.getTable(t);if(s==null)return;let a=n.rowOffset();r.insertRow(a+e),this.quill.update(B.sources.USER),e>0?this.quill.setSelection(t,B.sources.SILENT):this.quill.setSelection(t.index+n.children.length,t.length,B.sources.SILENT)}insertRowAbove(){this.insertRow(0)}insertRowBelow(){this.insertRow(1)}insertTable(e,t){let r=this.quill.getSelection();if(r==null)return;let n=new Array(e).fill(0).reduce(s=>{let a=new Array(t).fill(` -`).join("");return s.insert(a,{table:cc()})},new iv.default().retain(r.index));this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(r.index,B.sources.SILENT),this.balanceTables()}listenBalanceCells(){this.quill.on(B.events.SCROLL_OPTIMIZE,e=>{e.some(t=>["TD","TR","TBODY","TABLE"].includes(t.target.tagName)?(this.quill.once(B.events.TEXT_CHANGE,(r,n,s)=>{s===B.sources.USER&&this.balanceTables()}),!0):!1)})}},rv=tp});function av(i,e,t){let r=document.createElement("button");r.setAttribute("type","button"),r.classList.add(`ql-${e}`),r.setAttribute("aria-pressed","false"),t!=null?(r.value=t,r.setAttribute("aria-label",`${e}: ${t}`)):r.setAttribute("aria-label",e),i.appendChild(r)}function WB(i,e){Array.isArray(e[0])||(e=[e]),e.forEach(t=>{let r=document.createElement("span");r.classList.add("ql-formats"),t.forEach(n=>{if(typeof n=="string")av(r,n);else{let s=Object.keys(n)[0],a=n[s];Array.isArray(a)?YB(r,s,a):av(r,s,a)}}),i.appendChild(r)})}function YB(i,e,t){let r=document.createElement("select");r.classList.add(`ql-${e}`),t.forEach(n=>{let s=document.createElement("option");n!==!1?s.setAttribute("value",String(n)):s.setAttribute("selected","selected"),r.appendChild(s)}),i.appendChild(r)}var ov,sv,no,lv=T(()=>{ov=pt(pi(),1);Re();oi();Cs();Di();sv=gi("quill:toolbar"),no=class extends Qe{constructor(e,t){if(super(e,t),Array.isArray(this.options.container)){let r=document.createElement("div");r.setAttribute("role","toolbar"),WB(r,this.options.container),e.container?.parentNode?.insertBefore(r,e.container),this.container=r}else typeof this.options.container=="string"?this.container=document.querySelector(this.options.container):this.container=this.options.container;if(!(this.container instanceof HTMLElement)){sv.error("Container required for toolbar",this.options);return}this.container.classList.add("ql-toolbar"),this.controls=[],this.handlers={},this.options.handlers&&Object.keys(this.options.handlers).forEach(r=>{let n=this.options.handlers?.[r];n&&this.addHandler(r,n)}),Array.from(this.container.querySelectorAll("button, select")).forEach(r=>{this.attach(r)}),this.quill.on(B.events.EDITOR_CHANGE,()=>{let[r]=this.quill.selection.getRange();this.update(r)})}addHandler(e,t){this.handlers[e]=t}attach(e){let t=Array.from(e.classList).find(n=>n.indexOf("ql-")===0);if(!t)return;if(t=t.slice(3),e.tagName==="BUTTON"&&e.setAttribute("type","button"),this.handlers[t]==null&&this.quill.scroll.query(t)==null){sv.warn("ignoring attaching to nonexistent format",t,e);return}let r=e.tagName==="SELECT"?"change":"click";e.addEventListener(r,n=>{let s;if(e.tagName==="SELECT"){if(e.selectedIndex<0)return;let o=e.options[e.selectedIndex];o.hasAttribute("selected")?s=!1:s=o.value||!1}else e.classList.contains("ql-active")?s=!1:s=e.value||!e.hasAttribute("value"),n.preventDefault();this.quill.focus();let[a]=this.quill.selection.getRange();if(this.handlers[t]!=null)this.handlers[t].call(this,s);else if(this.quill.scroll.query(t).prototype instanceof Ke){if(s=prompt(`Enter ${t}`),!s)return;this.quill.updateContents(new ov.default().retain(a.index).delete(a.length).insert({[t]:s}),B.sources.USER)}else this.quill.format(t,s,B.sources.USER);this.update(a)}),this.controls.push([t,e])}update(e){let t=e==null?{}:this.quill.getFormat(e);this.controls.forEach(r=>{let[n,s]=r;if(s.tagName==="SELECT"){let a=null;if(e==null)a=null;else if(t[n]==null)a=s.querySelector("option[selected]");else if(!Array.isArray(t[n])){let o=t[n];typeof o=="string"&&(o=o.replace(/"/g,'\\"')),a=s.querySelector(`option[value="${o}"]`)}a==null?(s.value="",s.selectedIndex=-1):a.selected=!0}else if(e==null)s.classList.remove("ql-active"),s.setAttribute("aria-pressed","false");else if(s.hasAttribute("value")){let a=t[n],o=a===s.getAttribute("value")||a!=null&&a.toString()===s.getAttribute("value")||a==null&&!s.getAttribute("value");s.classList.toggle("ql-active",o),s.setAttribute("aria-pressed",o.toString())}else{let a=t[n]!=null;s.classList.toggle("ql-active",a),s.setAttribute("aria-pressed",a.toString())}})}};no.DEFAULTS={};no.DEFAULTS={container:null,handlers:{clean(){let i=this.quill.getSelection();if(i!=null)if(i.length===0){let e=this.quill.getFormat();Object.keys(e).forEach(t=>{this.quill.scroll.query(t,X.INLINE)!=null&&this.quill.format(t,!1,B.sources.USER)})}else this.quill.removeFormat(i.index,i.length,B.sources.USER)},direction(i){let{align:e}=this.quill.getFormat();i==="rtl"&&e==null?this.quill.format("align","right",B.sources.USER):!i&&e==="right"&&this.quill.format("align",!1,B.sources.USER),this.quill.format("direction",i,B.sources.USER)},indent(i){let e=this.quill.getSelection(),t=this.quill.getFormat(e),r=parseInt(t.indent||0,10);if(i==="+1"||i==="-1"){let n=i==="+1"?1:-1;t.direction==="rtl"&&(n*=-1),this.quill.format("indent",r+n,B.sources.USER)}},link(i){i===!0&&(i=prompt("Enter link URL:")),this.quill.format("link",i,B.sources.USER)},list(i){let e=this.quill.getSelection(),t=this.quill.getFormat(e);i==="check"?t.list==="checked"||t.list==="unchecked"?this.quill.format("list",!1,B.sources.USER):this.quill.format("list","unchecked",B.sources.USER):this.quill.format("list",i,B.sources.USER)}}}});var XB,KB,ZB,QB,JB,eP,tP,iP,hv,rP,nP,sP,aP,oP,lP,hP,dP,cP,uP,fP,mP,pP,gP,xP,yP,vP,bP,wP,MP,TP,NP,EP,SP,Un,uc=T(()=>{XB='',KB='',ZB='',QB='',JB='',eP='',tP='',iP='',hv='',rP='',nP='',sP='',aP='',oP='',lP='',hP='',dP='',cP='',uP='',fP='',mP='',pP='',gP='',xP='',yP='',vP='',bP='',wP='',MP='',TP='',NP='',EP='',SP='',Un={align:{"":XB,center:KB,right:ZB,justify:QB},background:JB,blockquote:eP,bold:tP,clean:iP,code:hv,"code-block":hv,color:rP,direction:{"":nP,rtl:sP},formula:aP,header:{1:oP,2:lP,3:hP,4:dP,5:cP,6:uP},italic:fP,image:mP,indent:{"+1":pP,"-1":gP},link:xP,list:{bullet:yP,check:vP,ordered:bP},script:{sub:wP,super:MP},strike:TP,table:NP,underline:EP,video:SP}});function cv(i,e){i.setAttribute(e,`${i.getAttribute(e)!=="true"}`)}var AP,dv,ip,$n,n0=T(()=>{AP='',dv=0;ip=class{constructor(e){this.select=e,this.container=document.createElement("span"),this.buildPicker(),this.select.style.display="none",this.select.parentNode.insertBefore(this.container,this.select),this.label.addEventListener("mousedown",()=>{this.togglePicker()}),this.label.addEventListener("keydown",t=>{switch(t.key){case"Enter":this.togglePicker();break;case"Escape":this.escape(),t.preventDefault();break;default:}}),this.select.addEventListener("change",this.update.bind(this))}togglePicker(){this.container.classList.toggle("ql-expanded"),cv(this.label,"aria-expanded"),cv(this.options,"aria-hidden")}buildItem(e){let t=document.createElement("span");t.tabIndex="0",t.setAttribute("role","button"),t.classList.add("ql-picker-item");let r=e.getAttribute("value");return r&&t.setAttribute("data-value",r),e.textContent&&t.setAttribute("data-label",e.textContent),t.addEventListener("click",()=>{this.selectItem(t,!0)}),t.addEventListener("keydown",n=>{switch(n.key){case"Enter":this.selectItem(t,!0),n.preventDefault();break;case"Escape":this.escape(),n.preventDefault();break;default:}}),t}buildLabel(){let e=document.createElement("span");return e.classList.add("ql-picker-label"),e.innerHTML=AP,e.tabIndex="0",e.setAttribute("role","button"),e.setAttribute("aria-expanded","false"),this.container.appendChild(e),e}buildOptions(){let e=document.createElement("span");e.classList.add("ql-picker-options"),e.setAttribute("aria-hidden","true"),e.tabIndex="-1",e.id=`ql-picker-options-${dv}`,dv+=1,this.label.setAttribute("aria-controls",e.id),this.options=e,Array.from(this.select.options).forEach(t=>{let r=this.buildItem(t);e.appendChild(r),t.selected===!0&&this.selectItem(r)}),this.container.appendChild(e)}buildPicker(){Array.from(this.select.attributes).forEach(e=>{this.container.setAttribute(e.name,e.value)}),this.container.classList.add("ql-picker"),this.label=this.buildLabel(),this.buildOptions()}escape(){this.close(),setTimeout(()=>this.label.focus(),1)}close(){this.container.classList.remove("ql-expanded"),this.label.setAttribute("aria-expanded","false"),this.options.setAttribute("aria-hidden","true")}selectItem(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,r=this.container.querySelector(".ql-selected");e!==r&&(r?.classList.remove("ql-selected"),e!=null&&(e.classList.add("ql-selected"),this.select.selectedIndex=Array.from(e.parentNode.children).indexOf(e),e.hasAttribute("data-value")?this.label.setAttribute("data-value",e.getAttribute("data-value")):this.label.removeAttribute("data-value"),e.hasAttribute("data-label")?this.label.setAttribute("data-label",e.getAttribute("data-label")):this.label.removeAttribute("data-label"),t&&(this.select.dispatchEvent(new Event("change")),this.close())))}update(){let e;if(this.select.selectedIndex>-1){let r=this.container.querySelector(".ql-picker-options").children[this.select.selectedIndex];e=this.select.options[this.select.selectedIndex],this.selectItem(r)}else this.selectItem(null);let t=e!=null&&e!==this.select.querySelector("option[selected]");this.label.classList.toggle("ql-active",t)}},$n=ip});var rp,fc,np=T(()=>{n0();rp=class extends $n{constructor(e,t){super(e),this.label.innerHTML=t,this.container.classList.add("ql-color-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).slice(0,7).forEach(r=>{r.classList.add("ql-primary")})}buildItem(e){let t=super.buildItem(e);return t.style.backgroundColor=e.getAttribute("value")||"",t}selectItem(e,t){super.selectItem(e,t);let r=this.label.querySelector(".ql-color-label"),n=e&&e.getAttribute("data-value")||"";r&&(r.tagName==="line"?r.style.stroke=n:r.style.fill=n)}},fc=rp});var sp,mc,ap=T(()=>{n0();sp=class extends $n{constructor(e,t){super(e),this.container.classList.add("ql-icon-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).forEach(r=>{r.innerHTML=t[r.getAttribute("data-value")||""]}),this.defaultItem=this.container.querySelector(".ql-selected"),this.selectItem(this.defaultItem)}selectItem(e,t){super.selectItem(e,t);let r=e||this.defaultItem;if(r!=null){if(this.label.innerHTML===r.innerHTML)return;this.label.innerHTML=r.innerHTML}}},mc=sp});var kP,op,pc,lp=T(()=>{kP=i=>{let{overflowY:e}=getComputedStyle(i,null);return e!=="visible"&&e!=="clip"},op=class{constructor(e,t){this.quill=e,this.boundsContainer=t||document.body,this.root=e.addContainer("ql-tooltip"),this.root.innerHTML=this.constructor.TEMPLATE,kP(this.quill.root)&&this.quill.root.addEventListener("scroll",()=>{this.root.style.marginTop=`${-1*this.quill.root.scrollTop}px`}),this.hide()}hide(){this.root.classList.add("ql-hidden")}position(e){let t=e.left+e.width/2-this.root.offsetWidth/2,r=e.bottom+this.quill.root.scrollTop;this.root.style.left=`${t}px`,this.root.style.top=`${r}px`,this.root.classList.remove("ql-flip");let n=this.boundsContainer.getBoundingClientRect(),s=this.root.getBoundingClientRect(),a=0;if(s.right>n.right&&(a=n.right-s.right,this.root.style.left=`${t+a}px`),s.leftn.bottom){let o=s.bottom-s.top,l=e.bottom-e.top+o;this.root.style.top=`${r-l}px`,this.root.classList.add("ql-flip")}return a}show(){this.root.classList.remove("ql-editing"),this.root.classList.remove("ql-hidden")}},pc=op});function RP(i){let e=i.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtube\.com\/watch.*v=([a-zA-Z0-9_-]+)/)||i.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtu\.be\/([a-zA-Z0-9_-]+)/);return e?`${e[1]||"https"}://www.youtube.com/embed/${e[2]}?showinfo=0`:(e=i.match(/^(?:(https?):\/\/)?(?:www\.)?vimeo\.com\/(\d+)/))?`${e[1]||"https"}://player.vimeo.com/video/${e[2]}/`:i}function s0(i,e){let t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;e.forEach(r=>{let n=document.createElement("option");r===t?n.setAttribute("selected","selected"):n.setAttribute("value",String(r)),i.appendChild(n)})}var CP,_P,LP,IP,zP,rn,so,hp=T(()=>{kn();Qr();km();np();ap();n0();lp();CP=[!1,"center","right","justify"],_P=["#000000","#e60000","#ff9900","#ffff00","#008a00","#0066cc","#9933ff","#ffffff","#facccc","#ffebcc","#ffffcc","#cce8cc","#cce0f5","#ebd6ff","#bbbbbb","#f06666","#ffc266","#ffff66","#66b966","#66a3e0","#c285ff","#888888","#a10000","#b26b00","#b2b200","#006100","#0047b2","#6b24b2","#444444","#5c0000","#663d00","#666600","#003700","#002966","#3d1466"],LP=[!1,"serif","monospace"],IP=["1","2","3",!1],zP=["small",!1,"large","huge"],rn=class extends Za{constructor(e,t){super(e,t);let r=n=>{if(!document.body.contains(e.root)){document.body.removeEventListener("click",r);return}this.tooltip!=null&&!this.tooltip.root.contains(n.target)&&document.activeElement!==this.tooltip.textbox&&!this.quill.hasFocus()&&this.tooltip.hide(),this.pickers!=null&&this.pickers.forEach(s=>{s.container.contains(n.target)||s.close()})};e.emitter.listenDOM("click",document.body,r)}addModule(e){let t=super.addModule(e);return e==="toolbar"&&this.extendToolbar(t),t}buildButtons(e,t){Array.from(e).forEach(r=>{(r.getAttribute("class")||"").split(/\s+/).forEach(s=>{if(s.startsWith("ql-")&&(s=s.slice(3),t[s]!=null))if(s==="direction")r.innerHTML=t[s][""]+t[s].rtl;else if(typeof t[s]=="string")r.innerHTML=t[s];else{let a=r.value||"";a!=null&&t[s][a]&&(r.innerHTML=t[s][a])}})})}buildPickers(e,t){this.pickers=Array.from(e).map(n=>{if(n.classList.contains("ql-align")&&(n.querySelector("option")==null&&s0(n,CP),typeof t.align=="object"))return new mc(n,t.align);if(n.classList.contains("ql-background")||n.classList.contains("ql-color")){let s=n.classList.contains("ql-background")?"background":"color";return n.querySelector("option")==null&&s0(n,_P,s==="background"?"#ffffff":"#000000"),new fc(n,t[s])}return n.querySelector("option")==null&&(n.classList.contains("ql-font")?s0(n,LP):n.classList.contains("ql-header")?s0(n,IP):n.classList.contains("ql-size")&&s0(n,zP)),new $n(n)});let r=()=>{this.pickers.forEach(n=>{n.update()})};this.quill.on(J.events.EDITOR_CHANGE,r)}};rn.DEFAULTS=ri({},Za.DEFAULTS,{modules:{toolbar:{handlers:{formula(){this.quill.theme.tooltip.edit("formula")},image(){let i=this.container.querySelector("input.ql-image[type=file]");i==null&&(i=document.createElement("input"),i.setAttribute("type","file"),i.setAttribute("accept",this.quill.uploader.options.mimetypes.join(", ")),i.classList.add("ql-image"),i.addEventListener("change",()=>{let e=this.quill.getSelection(!0);this.quill.uploader.upload(e,i.files),i.value=""}),this.container.appendChild(i)),i.click()},video(){this.quill.theme.tooltip.edit("video")}}}}});so=class extends pc{constructor(e,t){super(e,t),this.textbox=this.root.querySelector('input[type="text"]'),this.listen()}listen(){this.textbox.addEventListener("keydown",e=>{e.key==="Enter"?(this.save(),e.preventDefault()):e.key==="Escape"&&(this.cancel(),e.preventDefault())})}cancel(){this.hide(),this.restoreFocus()}edit(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"link",t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(this.root.classList.remove("ql-hidden"),this.root.classList.add("ql-editing"),this.textbox==null)return;t!=null?this.textbox.value=t:e!==this.root.getAttribute("data-mode")&&(this.textbox.value="");let r=this.quill.getBounds(this.quill.selection.savedRange);r!=null&&this.position(r),this.textbox.select(),this.textbox.setAttribute("placeholder",this.textbox.getAttribute(`data-${e}`)||""),this.root.setAttribute("data-mode",e)}restoreFocus(){this.quill.focus({preventScroll:!0})}save(){let{value:e}=this.textbox;switch(this.root.getAttribute("data-mode")){case"link":{let{scrollTop:t}=this.quill.root;this.linkRange?(this.quill.formatText(this.linkRange,"link",e,J.sources.USER),delete this.linkRange):(this.restoreFocus(),this.quill.format("link",e,J.sources.USER)),this.quill.root.scrollTop=t;break}case"video":e=RP(e);case"formula":{if(!e)break;let t=this.quill.getSelection(!0);if(t!=null){let r=t.index+t.length;this.quill.insertEmbed(r,this.root.getAttribute("data-mode"),e,J.sources.USER),this.root.getAttribute("data-mode")==="formula"&&this.quill.insertText(r+1," ",J.sources.USER),this.quill.setSelection(r+2,J.sources.USER)}break}default:}this.textbox.value="",this.hide()}}});var DP,gc,a0,uv=T(()=>{kn();Qr();hp();Dl();uc();oi();DP=[["bold","italic","link"],[{header:1},{header:2},"blockquote"]],gc=class extends so{constructor(e,t){super(e,t),this.quill.on(J.events.EDITOR_CHANGE,(r,n,s,a)=>{if(r===J.events.SELECTION_CHANGE)if(n!=null&&n.length>0&&a===J.sources.USER){this.show(),this.root.style.left="0px",this.root.style.width="",this.root.style.width=`${this.root.offsetWidth}px`;let o=this.quill.getLines(n.index,n.length);if(o.length===1){let l=this.quill.getBounds(n);l!=null&&this.position(l)}else{let l=o[o.length-1],h=this.quill.getIndex(l),d=Math.min(l.length()-1,n.index+n.length-h),c=this.quill.getBounds(new $t(h,d));c!=null&&this.position(c)}}else document.activeElement!==this.textbox&&this.quill.hasFocus()&&this.hide()})}listen(){super.listen(),this.root.querySelector(".ql-close").addEventListener("click",()=>{this.root.classList.remove("ql-editing")}),this.quill.on(J.events.SCROLL_OPTIMIZE,()=>{setTimeout(()=>{if(this.root.classList.contains("ql-hidden"))return;let e=this.quill.getSelection();if(e!=null){let t=this.quill.getBounds(e);t!=null&&this.position(t)}},1)})}cancel(){this.show()}position(e){let t=super.position(e),r=this.root.querySelector(".ql-tooltip-arrow");return r.style.marginLeft="",t!==0&&(r.style.marginLeft=`${-1*t-r.offsetWidth/2}px`),t}};U(gc,"TEMPLATE",['','
    ','','',"
    "].join(""));a0=class extends rn{constructor(e,t){t.modules.toolbar!=null&&t.modules.toolbar.container==null&&(t.modules.toolbar.container=DP),super(e,t),this.quill.container.classList.add("ql-bubble")}extendToolbar(e){this.tooltip=new gc(this.quill,this.options.bounds),e.container!=null&&(this.tooltip.root.appendChild(e.container),this.buildButtons(e.container.querySelectorAll("button"),Un),this.buildPickers(e.container.querySelectorAll("select"),Un))}};a0.DEFAULTS=ri({},rn.DEFAULTS,{modules:{toolbar:{handlers:{link(i){i?this.quill.theme.tooltip.edit():this.quill.format("link",!1,B.sources.USER)}}}}})});var OP,xc,yc,fv,mv=T(()=>{kn();Qr();hp();Kl();Dl();uc();oi();OP=[[{header:["1","2","3",!1]}],["bold","italic","underline","link"],[{list:"ordered"},{list:"bullet"}],["clean"]],xc=class extends so{constructor(){super(...arguments);U(this,"preview",this.root.querySelector("a.ql-preview"))}listen(){super.listen(),this.root.querySelector("a.ql-action").addEventListener("click",t=>{this.root.classList.contains("ql-editing")?this.save():this.edit("link",this.preview.textContent),t.preventDefault()}),this.root.querySelector("a.ql-remove").addEventListener("click",t=>{if(this.linkRange!=null){let r=this.linkRange;this.restoreFocus(),this.quill.formatText(r,"link",!1,J.sources.USER),delete this.linkRange}t.preventDefault(),this.hide()}),this.quill.on(J.events.SELECTION_CHANGE,(t,r,n)=>{if(t!=null){if(t.length===0&&n===J.sources.USER){let[s,a]=this.quill.scroll.descendant(xi,t.index);if(s!=null){this.linkRange=new $t(t.index-a,s.length());let o=xi.formats(s.domNode);this.preview.textContent=o,this.preview.setAttribute("href",o),this.show();let l=this.quill.getBounds(this.linkRange);l!=null&&this.position(l);return}}else delete this.linkRange;this.hide()}})}show(){super.show(),this.root.removeAttribute("data-mode")}};U(xc,"TEMPLATE",['','','',''].join(""));yc=class extends rn{constructor(e,t){t.modules.toolbar!=null&&t.modules.toolbar.container==null&&(t.modules.toolbar.container=OP),super(e,t),this.quill.container.classList.add("ql-snow")}extendToolbar(e){e.container!=null&&(e.container.classList.add("ql-snow"),this.buildButtons(e.container.querySelectorAll("button"),Un),this.buildPickers(e.container.querySelectorAll("select"),Un),this.tooltip=new xc(this.quill,this.options.bounds),e.container.querySelector(".ql-link")&&this.quill.keyboard.addBinding({key:"k",shortKey:!0},(t,r)=>{e.handlers.link.call(e,!r.format.link)}))}};yc.DEFAULTS=ri({},rn.DEFAULTS,{modules:{toolbar:{handlers:{link(i){if(i){let e=this.quill.getSelection();if(e==null||e.length===0)return;let t=this.quill.getText(e);/^\S+@\S+\.\S+$/.test(t)&&t.indexOf("mailto:")!==0&&(t=`mailto:${t}`);let{tooltip:r}=this.quill.theme;r.edit("link",t)}else this.quill.format("link",!1,B.sources.USER)}}}}});fv=yc});var vc,pv=T(()=>{Qm();Rm();Pm();Iy();Ry();Oy();By();Dm();Zd();Hm();$m();hc();Fy();Kl();Hy();$y();Gy();Wy();Ky();Jy();Qd();ev();nv();lv();uc();n0();np();ap();lp();uv();mv();Qm();lc.register({"attributors/attribute/direction":Jd,"attributors/class/align":zm,"attributors/class/background":hy,"attributors/class/color":ly,"attributors/class/direction":Bm,"attributors/class/font":qm,"attributors/class/size":Um,"attributors/style/align":Kd,"attributors/style/background":ql,"attributors/style/color":Fl,"attributors/style/direction":ec,"attributors/style/font":tc,"attributors/style/size":ic},!0);lc.register({"formats/align":zm,"formats/direction":Bm,"formats/indent":Ly,"formats/background":ql,"formats/color":Fl,"formats/font":qm,"formats/size":Um,"formats/blockquote":zy,"formats/code-block":st,"formats/header":Dy,"formats/list":Hn,"formats/bold":to,"formats/code":eo,"formats/italic":Py,"formats/link":xi,"formats/script":qy,"formats/strike":Uy,"formats/underline":jy,"formats/formula":Vy,"formats/image":Xy,"formats/video":Qy,"modules/syntax":i0,"modules/table":rv,"modules/toolbar":no,"themes/bubble":a0,"themes/snow":fv,"ui/icons":Un,"ui/picker":$n,"ui/icon-picker":mc,"ui/color-picker":fc,"ui/tooltip":pc},!0);vc=lc});var gv,xv,yv=T(()=>{gv=i=>` +`,{[st.blotName]:t}),a.insert(o)),s)],new WeakMap)}};l0.DEFAULTS={hljs:window.hljs,interval:1e3,languages:[{key:"plain",label:"Plain"},{key:"bash",label:"Bash"},{key:"cpp",label:"C++"},{key:"cs",label:"C#"},{key:"css",label:"CSS"},{key:"diff",label:"Diff"},{key:"xml",label:"HTML/XML"},{key:"java",label:"Java"},{key:"javascript",label:"JavaScript"},{key:"markdown",label:"Markdown"},{key:"php",label:"PHP"},{key:"python",label:"Python"},{key:"ruby",label:"Ruby"},{key:"sql",label:"SQL"}]}});function vc(){return`row-${Math.random().toString(36).slice(2,6)}`}var h0,Fi,qi,bi,tn,pv=T(()=>{Ri();eo();h0=class h0 extends Oe{static create(e){let t=super.create();return e?t.setAttribute("data-row",e):t.setAttribute("data-row",vc()),t}static formats(e){if(e.hasAttribute("data-row"))return e.getAttribute("data-row")}cellOffset(){return this.parent?this.parent.children.indexOf(this):-1}format(e,t){e===h0.blotName&&t?this.domNode.setAttribute("data-row",t):super.format(e,t)}row(){return this.parent}rowOffset(){return this.row()?this.row().rowOffset():-1}table(){return this.row()&&this.row().table()}};U(h0,"blotName","table"),U(h0,"tagName","TD");Fi=h0,qi=class extends Bi{checkMerge(){if(super.checkMerge()&&this.next.children.head!=null){let e=this.children.head.formats(),t=this.children.tail.formats(),r=this.next.children.head.formats(),n=this.next.children.tail.formats();return e.table===t.table&&e.table===r.table&&e.table===n.table}return!1}optimize(e){super.optimize(e),this.children.forEach(t=>{if(t.next==null)return;let r=t.formats(),n=t.next.formats();if(r.table!==n.table){let s=this.splitAfter(t);s&&s.optimize(),this.prev&&this.prev.optimize()}})}rowOffset(){return this.parent?this.parent.children.indexOf(this):-1}table(){return this.parent&&this.parent.parent}};U(qi,"blotName","table-row"),U(qi,"tagName","TR");bi=class extends Bi{};U(bi,"blotName","table-body"),U(bi,"tagName","TBODY");tn=class extends Bi{balanceCells(){let e=this.descendants(qi),t=e.reduce((r,n)=>Math.max(n.children.length,r),0);e.forEach(r=>{new Array(t-r.children.length).fill(0).forEach(()=>{let n;r.children.head!=null&&(n=Fi.formats(r.children.head.domNode));let s=this.scroll.create(Fi.blotName,n);r.appendChild(s),s.optimize()})})}cells(e){return this.rows().map(t=>t.children.at(e))}deleteColumn(e){let[t]=this.descendant(bi);t==null||t.children.head==null||t.children.forEach(r=>{let n=r.children.at(e);n?.remove()})}insertColumn(e){let[t]=this.descendant(bi);t==null||t.children.head==null||t.children.forEach(r=>{let n=r.children.at(e),s=Fi.formats(r.children.head.domNode),a=this.scroll.create(Fi.blotName,s);r.insertBefore(a,n)})}insertRow(e){let[t]=this.descendant(bi);if(t==null||t.children.head==null)return;let r=vc(),n=this.scroll.create(qi.blotName);t.children.head.children.forEach(()=>{let a=this.scroll.create(Fi.blotName,r);n.appendChild(a)});let s=t.children.at(e);t.insertBefore(n,s)}rows(){let e=this.children.head;return e==null?[]:e.children.map(t=>t)}};U(tn,"blotName","table-container"),U(tn,"tagName","TABLE");tn.allowedChildren=[bi];bi.requiredContainer=tn;bi.allowedChildren=[qi];qi.requiredContainer=bi;qi.allowedChildren=[Fi];Fi.requiredContainer=qi});var gv,up,xv,yv=T(()=>{gv=yt(xi(),1);hi();Oi();pv();up=class extends Je{static register(){B.register(Fi),B.register(qi),B.register(bi),B.register(tn)}constructor(){super(...arguments),this.listenBalanceCells()}balanceTables(){this.quill.scroll.descendants(tn).forEach(e=>{e.balanceCells()})}deleteColumn(){let[e,,t]=this.getTable();t!=null&&(e.deleteColumn(t.cellOffset()),this.quill.update(B.sources.USER))}deleteRow(){let[,e]=this.getTable();e!=null&&(e.remove(),this.quill.update(B.sources.USER))}deleteTable(){let[e]=this.getTable();if(e==null)return;let t=e.offset();e.remove(),this.quill.update(B.sources.USER),this.quill.setSelection(t,B.sources.SILENT)}getTable(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.quill.getSelection();if(e==null)return[null,null,null,-1];let[t,r]=this.quill.getLine(e.index);if(t==null||t.statics.blotName!==Fi.blotName)return[null,null,null,-1];let n=t.parent;return[n.parent.parent,n,t,r]}insertColumn(e){let t=this.quill.getSelection();if(!t)return;let[r,n,s]=this.getTable(t);if(s==null)return;let a=s.cellOffset();r.insertColumn(a+e),this.quill.update(B.sources.USER);let o=n.rowOffset();e===0&&(o+=1),this.quill.setSelection(t.index+o,t.length,B.sources.SILENT)}insertColumnLeft(){this.insertColumn(0)}insertColumnRight(){this.insertColumn(1)}insertRow(e){let t=this.quill.getSelection();if(!t)return;let[r,n,s]=this.getTable(t);if(s==null)return;let a=n.rowOffset();r.insertRow(a+e),this.quill.update(B.sources.USER),e>0?this.quill.setSelection(t,B.sources.SILENT):this.quill.setSelection(t.index+n.children.length,t.length,B.sources.SILENT)}insertRowAbove(){this.insertRow(0)}insertRowBelow(){this.insertRow(1)}insertTable(e,t){let r=this.quill.getSelection();if(r==null)return;let n=new Array(e).fill(0).reduce(s=>{let a=new Array(t).fill(` +`).join("");return s.insert(a,{table:vc()})},new gv.default().retain(r.index));this.quill.updateContents(n,B.sources.USER),this.quill.setSelection(r.index,B.sources.SILENT),this.balanceTables()}listenBalanceCells(){this.quill.on(B.events.SCROLL_OPTIMIZE,e=>{e.some(t=>["TD","TR","TBODY","TABLE"].includes(t.target.tagName)?(this.quill.once(B.events.TEXT_CHANGE,(r,n,s)=>{s===B.sources.USER&&this.balanceTables()}),!0):!1)})}},xv=up});function bv(i,e,t){let r=document.createElement("button");r.setAttribute("type","button"),r.classList.add(`ql-${e}`),r.setAttribute("aria-pressed","false"),t!=null?(r.value=t,r.setAttribute("aria-label",`${e}: ${t}`)):r.setAttribute("aria-label",e),i.appendChild(r)}function xP(i,e){Array.isArray(e[0])||(e=[e]),e.forEach(t=>{let r=document.createElement("span");r.classList.add("ql-formats"),t.forEach(n=>{if(typeof n=="string")bv(r,n);else{let s=Object.keys(n)[0],a=n[s];Array.isArray(a)?yP(r,s,a):bv(r,s,a)}}),i.appendChild(r)})}function yP(i,e,t){let r=document.createElement("select");r.classList.add(`ql-${e}`),t.forEach(n=>{let s=document.createElement("option");n!==!1?s.setAttribute("value",String(n)):s.setAttribute("selected","selected"),r.appendChild(s)}),i.appendChild(r)}var wv,vv,so,Mv=T(()=>{wv=yt(xi(),1);De();hi();Cs();Oi();vv=yi("quill:toolbar"),so=class extends Je{constructor(e,t){if(super(e,t),Array.isArray(this.options.container)){let r=document.createElement("div");r.setAttribute("role","toolbar"),xP(r,this.options.container),e.container?.parentNode?.insertBefore(r,e.container),this.container=r}else typeof this.options.container=="string"?this.container=document.querySelector(this.options.container):this.container=this.options.container;if(!(this.container instanceof HTMLElement)){vv.error("Container required for toolbar",this.options);return}this.container.classList.add("ql-toolbar"),this.controls=[],this.handlers={},this.options.handlers&&Object.keys(this.options.handlers).forEach(r=>{let n=this.options.handlers?.[r];n&&this.addHandler(r,n)}),Array.from(this.container.querySelectorAll("button, select")).forEach(r=>{this.attach(r)}),this.quill.on(B.events.EDITOR_CHANGE,()=>{let[r]=this.quill.selection.getRange();this.update(r)})}addHandler(e,t){this.handlers[e]=t}attach(e){let t=Array.from(e.classList).find(n=>n.indexOf("ql-")===0);if(!t)return;if(t=t.slice(3),e.tagName==="BUTTON"&&e.setAttribute("type","button"),this.handlers[t]==null&&this.quill.scroll.query(t)==null){vv.warn("ignoring attaching to nonexistent format",t,e);return}let r=e.tagName==="SELECT"?"change":"click";e.addEventListener(r,n=>{let s;if(e.tagName==="SELECT"){if(e.selectedIndex<0)return;let o=e.options[e.selectedIndex];o.hasAttribute("selected")?s=!1:s=o.value||!1}else e.classList.contains("ql-active")?s=!1:s=e.value||!e.hasAttribute("value"),n.preventDefault();this.quill.focus();let[a]=this.quill.selection.getRange();if(this.handlers[t]!=null)this.handlers[t].call(this,s);else if(this.quill.scroll.query(t).prototype instanceof Ze){if(s=prompt(`Enter ${t}`),!s)return;this.quill.updateContents(new wv.default().retain(a.index).delete(a.length).insert({[t]:s}),B.sources.USER)}else this.quill.format(t,s,B.sources.USER);this.update(a)}),this.controls.push([t,e])}update(e){let t=e==null?{}:this.quill.getFormat(e);this.controls.forEach(r=>{let[n,s]=r;if(s.tagName==="SELECT"){let a=null;if(e==null)a=null;else if(t[n]==null)a=s.querySelector("option[selected]");else if(!Array.isArray(t[n])){let o=t[n];typeof o=="string"&&(o=o.replace(/"/g,'\\"')),a=s.querySelector(`option[value="${o}"]`)}a==null?(s.value="",s.selectedIndex=-1):a.selected=!0}else if(e==null)s.classList.remove("ql-active"),s.setAttribute("aria-pressed","false");else if(s.hasAttribute("value")){let a=t[n],o=a===s.getAttribute("value")||a!=null&&a.toString()===s.getAttribute("value")||a==null&&!s.getAttribute("value");s.classList.toggle("ql-active",o),s.setAttribute("aria-pressed",o.toString())}else{let a=t[n]!=null;s.classList.toggle("ql-active",a),s.setAttribute("aria-pressed",a.toString())}})}};so.DEFAULTS={};so.DEFAULTS={container:null,handlers:{clean(){let i=this.quill.getSelection();if(i!=null)if(i.length===0){let e=this.quill.getFormat();Object.keys(e).forEach(t=>{this.quill.scroll.query(t,X.INLINE)!=null&&this.quill.format(t,!1,B.sources.USER)})}else this.quill.removeFormat(i.index,i.length,B.sources.USER)},direction(i){let{align:e}=this.quill.getFormat();i==="rtl"&&e==null?this.quill.format("align","right",B.sources.USER):!i&&e==="right"&&this.quill.format("align",!1,B.sources.USER),this.quill.format("direction",i,B.sources.USER)},indent(i){let e=this.quill.getSelection(),t=this.quill.getFormat(e),r=parseInt(t.indent||0,10);if(i==="+1"||i==="-1"){let n=i==="+1"?1:-1;t.direction==="rtl"&&(n*=-1),this.quill.format("indent",r+n,B.sources.USER)}},link(i){i===!0&&(i=prompt("Enter link URL:")),this.quill.format("link",i,B.sources.USER)},list(i){let e=this.quill.getSelection(),t=this.quill.getFormat(e);i==="check"?t.list==="checked"||t.list==="unchecked"?this.quill.format("list",!1,B.sources.USER):this.quill.format("list","unchecked",B.sources.USER):this.quill.format("list",i,B.sources.USER)}}}});var vP,bP,wP,MP,TP,NP,EP,SP,Tv,AP,kP,CP,_P,LP,IP,zP,RP,DP,OP,BP,PP,FP,qP,HP,UP,$P,jP,GP,WP,VP,YP,XP,KP,Hn,bc=T(()=>{vP='',bP='',wP='',MP='',TP='',NP='',EP='',SP='',Tv='',AP='',kP='',CP='',_P='',LP='',IP='',zP='',RP='',DP='',OP='',BP='',PP='',FP='',qP='',HP='',UP='',$P='',jP='',GP='',WP='',VP='',YP='',XP='',KP='',Hn={align:{"":vP,center:bP,right:wP,justify:MP},background:TP,blockquote:NP,bold:EP,clean:SP,code:Tv,"code-block":Tv,color:AP,direction:{"":kP,rtl:CP},formula:_P,header:{1:LP,2:IP,3:zP,4:RP,5:DP,6:OP},italic:BP,image:PP,indent:{"+1":FP,"-1":qP},link:HP,list:{bullet:UP,check:$P,ordered:jP},script:{sub:GP,super:WP},strike:VP,table:YP,underline:XP,video:KP}});function Ev(i,e){i.setAttribute(e,`${i.getAttribute(e)!=="true"}`)}var ZP,Nv,fp,Un,d0=T(()=>{ZP='',Nv=0;fp=class{constructor(e){this.select=e,this.container=document.createElement("span"),this.buildPicker(),this.select.style.display="none",this.select.parentNode.insertBefore(this.container,this.select),this.label.addEventListener("mousedown",()=>{this.togglePicker()}),this.label.addEventListener("keydown",t=>{switch(t.key){case"Enter":this.togglePicker();break;case"Escape":this.escape(),t.preventDefault();break;default:}}),this.select.addEventListener("change",this.update.bind(this))}togglePicker(){this.container.classList.toggle("ql-expanded"),Ev(this.label,"aria-expanded"),Ev(this.options,"aria-hidden")}buildItem(e){let t=document.createElement("span");t.tabIndex="0",t.setAttribute("role","button"),t.classList.add("ql-picker-item");let r=e.getAttribute("value");return r&&t.setAttribute("data-value",r),e.textContent&&t.setAttribute("data-label",e.textContent),t.addEventListener("click",()=>{this.selectItem(t,!0)}),t.addEventListener("keydown",n=>{switch(n.key){case"Enter":this.selectItem(t,!0),n.preventDefault();break;case"Escape":this.escape(),n.preventDefault();break;default:}}),t}buildLabel(){let e=document.createElement("span");return e.classList.add("ql-picker-label"),e.innerHTML=ZP,e.tabIndex="0",e.setAttribute("role","button"),e.setAttribute("aria-expanded","false"),this.container.appendChild(e),e}buildOptions(){let e=document.createElement("span");e.classList.add("ql-picker-options"),e.setAttribute("aria-hidden","true"),e.tabIndex="-1",e.id=`ql-picker-options-${Nv}`,Nv+=1,this.label.setAttribute("aria-controls",e.id),this.options=e,Array.from(this.select.options).forEach(t=>{let r=this.buildItem(t);e.appendChild(r),t.selected===!0&&this.selectItem(r)}),this.container.appendChild(e)}buildPicker(){Array.from(this.select.attributes).forEach(e=>{this.container.setAttribute(e.name,e.value)}),this.container.classList.add("ql-picker"),this.label=this.buildLabel(),this.buildOptions()}escape(){this.close(),setTimeout(()=>this.label.focus(),1)}close(){this.container.classList.remove("ql-expanded"),this.label.setAttribute("aria-expanded","false"),this.options.setAttribute("aria-hidden","true")}selectItem(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,r=this.container.querySelector(".ql-selected");e!==r&&(r?.classList.remove("ql-selected"),e!=null&&(e.classList.add("ql-selected"),this.select.selectedIndex=Array.from(e.parentNode.children).indexOf(e),e.hasAttribute("data-value")?this.label.setAttribute("data-value",e.getAttribute("data-value")):this.label.removeAttribute("data-value"),e.hasAttribute("data-label")?this.label.setAttribute("data-label",e.getAttribute("data-label")):this.label.removeAttribute("data-label"),t&&(this.select.dispatchEvent(new Event("change")),this.close())))}update(){let e;if(this.select.selectedIndex>-1){let r=this.container.querySelector(".ql-picker-options").children[this.select.selectedIndex];e=this.select.options[this.select.selectedIndex],this.selectItem(r)}else this.selectItem(null);let t=e!=null&&e!==this.select.querySelector("option[selected]");this.label.classList.toggle("ql-active",t)}},Un=fp});var mp,wc,pp=T(()=>{d0();mp=class extends Un{constructor(e,t){super(e),this.label.innerHTML=t,this.container.classList.add("ql-color-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).slice(0,7).forEach(r=>{r.classList.add("ql-primary")})}buildItem(e){let t=super.buildItem(e);return t.style.backgroundColor=e.getAttribute("value")||"",t}selectItem(e,t){super.selectItem(e,t);let r=this.label.querySelector(".ql-color-label"),n=e&&e.getAttribute("data-value")||"";r&&(r.tagName==="line"?r.style.stroke=n:r.style.fill=n)}},wc=mp});var gp,Mc,xp=T(()=>{d0();gp=class extends Un{constructor(e,t){super(e),this.container.classList.add("ql-icon-picker"),Array.from(this.container.querySelectorAll(".ql-picker-item")).forEach(r=>{r.innerHTML=t[r.getAttribute("data-value")||""]}),this.defaultItem=this.container.querySelector(".ql-selected"),this.selectItem(this.defaultItem)}selectItem(e,t){super.selectItem(e,t);let r=e||this.defaultItem;if(r!=null){if(this.label.innerHTML===r.innerHTML)return;this.label.innerHTML=r.innerHTML}}},Mc=gp});var QP,yp,Tc,vp=T(()=>{QP=i=>{let{overflowY:e}=getComputedStyle(i,null);return e!=="visible"&&e!=="clip"},yp=class{constructor(e,t){this.quill=e,this.boundsContainer=t||document.body,this.root=e.addContainer("ql-tooltip"),this.root.innerHTML=this.constructor.TEMPLATE,QP(this.quill.root)&&this.quill.root.addEventListener("scroll",()=>{this.root.style.marginTop=`${-1*this.quill.root.scrollTop}px`}),this.hide()}hide(){this.root.classList.add("ql-hidden")}position(e){let t=e.left+e.width/2-this.root.offsetWidth/2,r=e.bottom+this.quill.root.scrollTop;this.root.style.left=`${t}px`,this.root.style.top=`${r}px`,this.root.classList.remove("ql-flip");let n=this.boundsContainer.getBoundingClientRect(),s=this.root.getBoundingClientRect(),a=0;if(s.right>n.right&&(a=n.right-s.right,this.root.style.left=`${t+a}px`),s.leftn.bottom){let o=s.bottom-s.top,l=e.bottom-e.top+o;this.root.style.top=`${r-l}px`,this.root.classList.add("ql-flip")}return a}show(){this.root.classList.remove("ql-editing"),this.root.classList.remove("ql-hidden")}},Tc=yp});function nF(i){let e=i.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtube\.com\/watch.*v=([a-zA-Z0-9_-]+)/)||i.match(/^(?:(https?):\/\/)?(?:(?:www|m)\.)?youtu\.be\/([a-zA-Z0-9_-]+)/);return e?`${e[1]||"https"}://www.youtube.com/embed/${e[2]}?showinfo=0`:(e=i.match(/^(?:(https?):\/\/)?(?:www\.)?vimeo\.com\/(\d+)/))?`${e[1]||"https"}://player.vimeo.com/video/${e[2]}/`:i}function c0(i,e){let t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;e.forEach(r=>{let n=document.createElement("option");r===t?n.setAttribute("selected","selected"):n.setAttribute("value",String(r)),i.appendChild(n)})}var JP,eF,tF,iF,rF,rn,ao,bp=T(()=>{An();Qr();Fm();pp();xp();d0();vp();JP=[!1,"center","right","justify"],eF=["#000000","#e60000","#ff9900","#ffff00","#008a00","#0066cc","#9933ff","#ffffff","#facccc","#ffebcc","#ffffcc","#cce8cc","#cce0f5","#ebd6ff","#bbbbbb","#f06666","#ffc266","#ffff66","#66b966","#66a3e0","#c285ff","#888888","#a10000","#b26b00","#b2b200","#006100","#0047b2","#6b24b2","#444444","#5c0000","#663d00","#666600","#003700","#002966","#3d1466"],tF=[!1,"serif","monospace"],iF=["1","2","3",!1],rF=["small",!1,"large","huge"],rn=class extends Qa{constructor(e,t){super(e,t);let r=n=>{if(!document.body.contains(e.root)){document.body.removeEventListener("click",r);return}this.tooltip!=null&&!this.tooltip.root.contains(n.target)&&document.activeElement!==this.tooltip.textbox&&!this.quill.hasFocus()&&this.tooltip.hide(),this.pickers!=null&&this.pickers.forEach(s=>{s.container.contains(n.target)||s.close()})};e.emitter.listenDOM("click",document.body,r)}addModule(e){let t=super.addModule(e);return e==="toolbar"&&this.extendToolbar(t),t}buildButtons(e,t){Array.from(e).forEach(r=>{(r.getAttribute("class")||"").split(/\s+/).forEach(s=>{if(s.startsWith("ql-")&&(s=s.slice(3),t[s]!=null))if(s==="direction")r.innerHTML=t[s][""]+t[s].rtl;else if(typeof t[s]=="string")r.innerHTML=t[s];else{let a=r.value||"";a!=null&&t[s][a]&&(r.innerHTML=t[s][a])}})})}buildPickers(e,t){this.pickers=Array.from(e).map(n=>{if(n.classList.contains("ql-align")&&(n.querySelector("option")==null&&c0(n,JP),typeof t.align=="object"))return new Mc(n,t.align);if(n.classList.contains("ql-background")||n.classList.contains("ql-color")){let s=n.classList.contains("ql-background")?"background":"color";return n.querySelector("option")==null&&c0(n,eF,s==="background"?"#ffffff":"#000000"),new wc(n,t[s])}return n.querySelector("option")==null&&(n.classList.contains("ql-font")?c0(n,tF):n.classList.contains("ql-header")?c0(n,iF):n.classList.contains("ql-size")&&c0(n,rF)),new Un(n)});let r=()=>{this.pickers.forEach(n=>{n.update()})};this.quill.on(ee.events.EDITOR_CHANGE,r)}};rn.DEFAULTS=si({},Qa.DEFAULTS,{modules:{toolbar:{handlers:{formula(){this.quill.theme.tooltip.edit("formula")},image(){let i=this.container.querySelector("input.ql-image[type=file]");i==null&&(i=document.createElement("input"),i.setAttribute("type","file"),i.setAttribute("accept",this.quill.uploader.options.mimetypes.join(", ")),i.classList.add("ql-image"),i.addEventListener("change",()=>{let e=this.quill.getSelection(!0);this.quill.uploader.upload(e,i.files),i.value=""}),this.container.appendChild(i)),i.click()},video(){this.quill.theme.tooltip.edit("video")}}}}});ao=class extends Tc{constructor(e,t){super(e,t),this.textbox=this.root.querySelector('input[type="text"]'),this.listen()}listen(){this.textbox.addEventListener("keydown",e=>{e.key==="Enter"?(this.save(),e.preventDefault()):e.key==="Escape"&&(this.cancel(),e.preventDefault())})}cancel(){this.hide(),this.restoreFocus()}edit(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"link",t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(this.root.classList.remove("ql-hidden"),this.root.classList.add("ql-editing"),this.textbox==null)return;t!=null?this.textbox.value=t:e!==this.root.getAttribute("data-mode")&&(this.textbox.value="");let r=this.quill.getBounds(this.quill.selection.savedRange);r!=null&&this.position(r),this.textbox.select(),this.textbox.setAttribute("placeholder",this.textbox.getAttribute(`data-${e}`)||""),this.root.setAttribute("data-mode",e)}restoreFocus(){this.quill.focus({preventScroll:!0})}save(){let{value:e}=this.textbox;switch(this.root.getAttribute("data-mode")){case"link":{let{scrollTop:t}=this.quill.root;this.linkRange?(this.quill.formatText(this.linkRange,"link",e,ee.sources.USER),delete this.linkRange):(this.restoreFocus(),this.quill.format("link",e,ee.sources.USER)),this.quill.root.scrollTop=t;break}case"video":e=nF(e);case"formula":{if(!e)break;let t=this.quill.getSelection(!0);if(t!=null){let r=t.index+t.length;this.quill.insertEmbed(r,this.root.getAttribute("data-mode"),e,ee.sources.USER),this.root.getAttribute("data-mode")==="formula"&&this.quill.insertText(r+1," ",ee.sources.USER),this.quill.setSelection(r+2,ee.sources.USER)}break}default:}this.textbox.value="",this.hide()}}});var sF,Nc,u0,Sv=T(()=>{An();Qr();bp();Hl();bc();hi();sF=[["bold","italic","link"],[{header:1},{header:2},"blockquote"]],Nc=class extends ao{constructor(e,t){super(e,t),this.quill.on(ee.events.EDITOR_CHANGE,(r,n,s,a)=>{if(r===ee.events.SELECTION_CHANGE)if(n!=null&&n.length>0&&a===ee.sources.USER){this.show(),this.root.style.left="0px",this.root.style.width="",this.root.style.width=`${this.root.offsetWidth}px`;let o=this.quill.getLines(n.index,n.length);if(o.length===1){let l=this.quill.getBounds(n);l!=null&&this.position(l)}else{let l=o[o.length-1],h=this.quill.getIndex(l),d=Math.min(l.length()-1,n.index+n.length-h),c=this.quill.getBounds(new $t(h,d));c!=null&&this.position(c)}}else document.activeElement!==this.textbox&&this.quill.hasFocus()&&this.hide()})}listen(){super.listen(),this.root.querySelector(".ql-close").addEventListener("click",()=>{this.root.classList.remove("ql-editing")}),this.quill.on(ee.events.SCROLL_OPTIMIZE,()=>{setTimeout(()=>{if(this.root.classList.contains("ql-hidden"))return;let e=this.quill.getSelection();if(e!=null){let t=this.quill.getBounds(e);t!=null&&this.position(t)}},1)})}cancel(){this.show()}position(e){let t=super.position(e),r=this.root.querySelector(".ql-tooltip-arrow");return r.style.marginLeft="",t!==0&&(r.style.marginLeft=`${-1*t-r.offsetWidth/2}px`),t}};U(Nc,"TEMPLATE",['','
    ','','',"
    "].join(""));u0=class extends rn{constructor(e,t){t.modules.toolbar!=null&&t.modules.toolbar.container==null&&(t.modules.toolbar.container=sF),super(e,t),this.quill.container.classList.add("ql-bubble")}extendToolbar(e){this.tooltip=new Nc(this.quill,this.options.bounds),e.container!=null&&(this.tooltip.root.appendChild(e.container),this.buildButtons(e.container.querySelectorAll("button"),Hn),this.buildPickers(e.container.querySelectorAll("select"),Hn))}};u0.DEFAULTS=si({},rn.DEFAULTS,{modules:{toolbar:{handlers:{link(i){i?this.quill.theme.tooltip.edit():this.quill.format("link",!1,B.sources.USER)}}}}})});var aF,Ec,Sc,Av,kv=T(()=>{An();Qr();bp();i0();Hl();bc();hi();aF=[[{header:["1","2","3",!1]}],["bold","italic","underline","link"],[{list:"ordered"},{list:"bullet"}],["clean"]],Ec=class extends ao{constructor(){super(...arguments);U(this,"preview",this.root.querySelector("a.ql-preview"))}listen(){super.listen(),this.root.querySelector("a.ql-action").addEventListener("click",t=>{this.root.classList.contains("ql-editing")?this.save():this.edit("link",this.preview.textContent),t.preventDefault()}),this.root.querySelector("a.ql-remove").addEventListener("click",t=>{if(this.linkRange!=null){let r=this.linkRange;this.restoreFocus(),this.quill.formatText(r,"link",!1,ee.sources.USER),delete this.linkRange}t.preventDefault(),this.hide()}),this.quill.on(ee.events.SELECTION_CHANGE,(t,r,n)=>{if(t!=null){if(t.length===0&&n===ee.sources.USER){let[s,a]=this.quill.scroll.descendant(vi,t.index);if(s!=null){this.linkRange=new $t(t.index-a,s.length());let o=vi.formats(s.domNode);this.preview.textContent=o,this.preview.setAttribute("href",o),this.show();let l=this.quill.getBounds(this.linkRange);l!=null&&this.position(l);return}}else delete this.linkRange;this.hide()}})}show(){super.show(),this.root.removeAttribute("data-mode")}};U(Ec,"TEMPLATE",['','','',''].join(""));Sc=class extends rn{constructor(e,t){t.modules.toolbar!=null&&t.modules.toolbar.container==null&&(t.modules.toolbar.container=aF),super(e,t),this.quill.container.classList.add("ql-snow")}extendToolbar(e){e.container!=null&&(e.container.classList.add("ql-snow"),this.buildButtons(e.container.querySelectorAll("button"),Hn),this.buildPickers(e.container.querySelectorAll("select"),Hn),this.tooltip=new Ec(this.quill,this.options.bounds),e.container.querySelector(".ql-link")&&this.quill.keyboard.addBinding({key:"k",shortKey:!0},(t,r)=>{e.handlers.link.call(e,!r.format.link)}))}};Sc.DEFAULTS=si({},rn.DEFAULTS,{modules:{toolbar:{handlers:{link(i){if(i){let e=this.quill.getSelection();if(e==null||e.length===0)return;let t=this.quill.getText(e);/^\S+@\S+\.\S+$/.test(t)&&t.indexOf("mailto:")!==0&&(t=`mailto:${t}`);let{tooltip:r}=this.quill.theme;r.edit("link",t)}else this.quill.format("link",!1,B.sources.USER)}}}}});Av=Sc});var Ac,Cv=T(()=>{hp();Gm();Xm();Wy();Yy();Ky();Zy();Wm();sc();Qm();ep();xc();Jy();i0();tv();rv();sv();ov();dv();fv();ac();mv();yv();Mv();bc();d0();pp();xp();vp();Sv();kv();hp();gc.register({"attributors/attribute/direction":oc,"attributors/class/align":jm,"attributors/class/background":Ty,"attributors/class/color":My,"attributors/class/direction":Ym,"attributors/class/font":Zm,"attributors/class/size":Jm,"attributors/style/align":nc,"attributors/style/background":Wl,"attributors/style/color":Gl,"attributors/style/direction":lc,"attributors/style/font":hc,"attributors/style/size":dc},!0);gc.register({"formats/align":jm,"formats/direction":Ym,"formats/indent":Gy,"formats/background":Wl,"formats/color":Gl,"formats/font":Zm,"formats/size":Jm,"formats/blockquote":Vy,"formats/code-block":st,"formats/header":Xy,"formats/list":qn,"formats/bold":io,"formats/code":to,"formats/italic":Qy,"formats/link":vi,"formats/script":ev,"formats/strike":iv,"formats/underline":nv,"formats/formula":av,"formats/image":hv,"formats/video":uv,"modules/syntax":l0,"modules/table":xv,"modules/toolbar":so,"themes/bubble":u0,"themes/snow":Av,"ui/icons":Hn,"ui/picker":Un,"ui/icon-picker":Mc,"ui/color-picker":wc,"ui/tooltip":Tc},!0);Ac=gc});var _v,Lv,Iv=T(()=>{_v=i=>` @font-face { font-family: 'KaTeX_AMS'; src: url(${i}fonts/KaTeX_AMS-Regular.woff2) format('woff2'), url(${i}fonts/KaTeX_AMS-Regular.woff) format('woff'), url(${i}fonts/KaTeX_AMS-Regular.ttf) format('truetype'); @@ -508,7 +508,7 @@ ${ks(this.code(e,t))} font-weight: normal; font-style: normal; } - `,xv=()=>` + `,Lv=()=>` .katex { font: normal 1.21em KaTeX_Main, Times New Roman, serif; line-height: 1.2; @@ -1472,8 +1472,8 @@ ewline is an empty block at top level, between .base elements */ body { counter-reset: katexEqnNo mmlEqnNo; } -`});var bv={};tt(bv,{default:()=>BP});var dp,vv,bc,BP,wv=T(()=>{og();pv();pe();yv();dp=!1,vv=vc.import("formats/formula"),bc=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,window.katex=Oh,this.init(),this.config=this.getKatexConfig(),this.cssEl=null,this.addStyle(),this.extendQuill(),this.onDestroy=this.onDestroy.bind(this),this.mindMap.on("beforeDestroy",this.onDestroy)}onDestroy(){Object.getPrototypeOf(this.mindMap).constructor.instanceCount<=1&&(dp=!1,vc.register("formats/formula",vv,!0))}init(){this.mindMap.opt.enableEditFormulaInRichTextEdit&&(this.mindMap.opt.transformRichTextOnEnterEdit=this.latexRichToText.bind(this),this.mindMap.opt.beforeHideRichTextEdit=this.formatLatex.bind(this))}getKatexConfig(){let e={throwOnError:!1,errorColor:"#f00",output:"mathml"},{getKatexOutputType:t}=this.mindMap.opt;t=t||function(){let n=I2();if(n&&n<=100)return"html"};let r=t()||"mathml";return e.output=["mathml","html"].includes(r)?r:"mathml",e}extendQuill(){if(dp)return;dp=!0;let e=this;class t extends vv{static create(n){let s=super.create(n);return typeof n=="string"&&(Oh.render(n,s,e.config),s.setAttribute("data-value",mn(n))),s}}vc.register("formats/formula",t,!0)}getStyleText(){let{katexFontPath:e}=this.mindMap.opt,t="";return this.config.output==="html"&&(t=gv(e)),t+=xv(),t}addStyle(){this.cssEl=document.createElement("style"),this.cssEl.type="text/css",this.cssEl.innerHTML=this.getStyleText(),document.head.appendChild(this.cssEl)}removeStyle(){document.head.removeChild(this.cssEl)}insertFormulaToNode(e,t){let r=this.mindMap.richText;r.showEditText({node:e}),r.quill.insertEmbed(r.quill.getLength()-1,"formula",t),r.hideEditText([e])}latexRichToText(e){if(e.indexOf('class="ql-formula"')!==-1){let n=new DOMParser().parseFromString(e,"text/html").getElementsByClassName("ql-formula");for(let s of n)e=e.replace(s.outerHTML,`$${s.getAttribute("data-value")}$`);this.mindMap.opt.openRealtimeRenderOnNodeTextEdit&&setTimeout(()=>{this.mindMap.emit("node_text_edit_change",{node:this.mindMap.richText.node,text:this.mindMap.richText.getEditText(),richText:!0})},0)}return e}formatLatex(e){let t=e.quill.getContents(),r=t.ops,n=!1;for(let s=r.length-1;s>=0;s--){let o=r[s].insert;if(o&&typeof o!="object"&&o!==` -`&&/\$.+?\$/g.test(o)){let l=[...o.matchAll(/\$.+?\$/g)],h=o.split(/\$.+?\$/g);for(let d=l.length-1;d>=0;d--){let c=l[d]&&l[d][0]&&l[d][0].slice(1,-1)||null;c!==null&&c.trim().length>0&&this.checkFormulaIsLegal(c)?(h.splice(d+1,0,{insert:{formula:c}}),n=!0):h.splice(d+1,0,"")}for(;h.length>0;){let d=h.pop();if(typeof d=="string"){if(d.length<1)continue;d={insert:d}}d.attributes=r[s].attributes,r.splice(s+1,0,d)}r.splice(s,1)}}n&&e.quill.setContents(t)}checkFormulaIsLegal(e){try{return Oh.renderToString(e),!0}catch{return!1}}beforePluginRemove(){this.removeStyle(),this.mindMap.off("beforeDestroy",this.onDestroy)}beforePluginDestroy(){this.removeStyle(),this.mindMap.off("beforeDestroy",this.onDestroy)}};bc.instanceName="formula";BP=bc});var cp,Mv,Tv=T(()=>{$e();cp=class{constructor(e={}){this.opt=e,this.mindMap=this.opt.mindMap,this.scale=1,this.sx=0,this.sy=0,this.x=0,this.y=0,this.firstDrag=!0,this.setTransformData(this.mindMap.opt.viewData),this.bind()}bind(){this.mindMap.keyCommand.addShortcut("Control+=",()=>{this.enlarge()}),this.mindMap.keyCommand.addShortcut("Control+-",()=>{this.narrow()}),this.mindMap.keyCommand.addShortcut("Control+i",()=>{this.fit()}),this.mindMap.event.on("mousedown",e=>{let{isDisableDrag:t,mousedownEventPreventDefault:r}=this.mindMap.opt;t||(r&&e.preventDefault(),this.sx=this.x,this.sy=this.y)}),this.mindMap.event.on("drag",(e,t)=>{e.ctrlKey||e.metaKey||this.mindMap.opt.isDisableDrag||(this.firstDrag&&(this.firstDrag=!1,this.mindMap.renderer.activeNodeList.length>0&&this.mindMap.execCommand("CLEAR_ACTIVE_NODE")),this.x=this.sx+t.mousemoveOffset.x,this.y=this.sy+t.mousemoveOffset.y,this.transform())}),this.mindMap.event.on("mouseup",()=>{this.firstDrag=!0}),this.mindMap.event.on("mousewheel",(e,t,r,n)=>{let{customHandleMousewheel:s,mousewheelAction:a,mouseScaleCenterUseMousePosition:o,mousewheelMoveStep:l,mousewheelZoomActionReverse:h,disableMouseWheelZoom:d,translateRatio:c}=this.mindMap.opt;if(s&&typeof s=="function")return s(e);if(a===k.MOUSE_WHEEL_ACTION.ZOOM||e.ctrlKey||e.metaKey){if(d)return;let{x:f,y:m}=this.mindMap.toPos(e.clientX,e.clientY),g=o?f:void 0,x=o?m:void 0;switch(n&&(t.includes(k.DIR.LEFT)||t.includes(k.DIR.RIGHT))&&(t=t.filter(y=>![k.DIR.LEFT,k.DIR.RIGHT].includes(y))),!0){case t.includes(k.DIR.UP||k.DIR.LEFT):h?this.enlarge(g,x,n):this.narrow(g,x,n);break;case t.includes(k.DIR.DOWN||k.DIR.RIGHT):h?this.narrow(g,x,n):this.enlarge(g,x,n);break}}else{let f=0,m=0;n?(f=Math.abs(e.wheelDeltaX),m=Math.abs(e.wheelDeltaY)):f=m=l;let g=0,x=0;t.includes(k.DIR.DOWN)&&(x=-m),t.includes(k.DIR.UP)&&(x=m),t.includes(k.DIR.LEFT)&&(g=f),t.includes(k.DIR.RIGHT)&&(g=-f),this.translateXY(g*c,x*c)}}),this.mindMap.on("resize",()=>{this.checkNeedMindMapInCanvas()&&this.transform()})}getTransformData(){return{transform:this.mindMap.draw.transform(),state:{scale:this.scale,x:this.x,y:this.y,sx:this.sx,sy:this.sy}}}setTransformData(e){e&&(Object.keys(e.state).forEach(t=>{this[t]=e.state[t]}),this.mindMap.draw.transform({...e.transform}),this.mindMap.emit("view_data_change",this.getTransformData()),this.emitEvent("scale"),this.emitEvent("translate"))}translateXY(e,t){e===0&&t===0||(this.x+=e,this.y+=t,this.transform(),this.emitEvent("translate"))}translateX(e){e!==0&&(this.x+=e,this.transform(),this.emitEvent("translate"))}translateXTo(e){this.x=e,this.transform(),this.emitEvent("translate")}translateY(e){e!==0&&(this.y+=e,this.transform(),this.emitEvent("translate"))}translateYTo(e){this.y=e,this.transform(),this.emitEvent("translate")}transform(){try{this.limitMindMapInCanvas()}catch{}this.mindMap.draw.transform({origin:[0,0],scale:this.scale,translate:[this.x,this.y]}),this.mindMap.emit("view_data_change",this.getTransformData())}reset(){let e=this.scale!==1,t=this.x!==0||this.y!==0;this.scale=1,this.x=0,this.y=0,this.transform(),e&&this.emitEvent("scale"),t&&this.emitEvent("translate")}narrow(e,t,r){let{scaleRatio:n,minZoomRatio:s}=this.mindMap.opt;n=n/(r?5:1);let a=Math.max(this.scale-n,s/100);this.scaleInCenter(a,e,t),this.transform(),this.emitEvent("scale")}enlarge(e,t,r){let{scaleRatio:n,maxZoomRatio:s}=this.mindMap.opt;n=n/(r?5:1);let a=0;s===-1?a=this.scale+n:a=Math.min(this.scale+n,s/100),this.scaleInCenter(a,e,t),this.transform(),this.emitEvent("scale")}scaleInCenter(e,t,r){(t===void 0||r===void 0)&&(t=this.mindMap.width/2,r=this.mindMap.height/2);let n=this.scale,s=1-e/n,a=(t-this.x)*s,o=(r-this.y)*s;this.x+=a,this.y+=o,this.scale=e}setScale(e,t,r){t!==void 0&&r!==void 0?this.scaleInCenter(e,t,r):this.scale=e,this.transform(),this.emitEvent("scale")}fit(e=()=>{},t=!1,r){r=r===void 0?this.mindMap.opt.fitPadding:r;let n=this.mindMap.draw,s=n.transform(),a=e()||n.rbox(),o=a.width/s.scaleX,l=a.height/s.scaleY,h=o/l,{width:d,height:c}=this.mindMap.elRect;d=d-r*2,c=c-r*2;let f=d/c,m=0,g="";if(o<=d&&l<=c&&!t)m=1,g=1;else{let S=0,A=0;h>f?(S=d,A=d/h,g=2):(A=c,S=c*h,g=3),m=S/o}this.setScale(m);let x=e()||n.rbox();x.x-=this.mindMap.elRect.left,x.y-=this.mindMap.elRect.top;let y=0,b=0;g===1?(y=-x.x+r+(d-x.width)/2,b=-x.y+r+(c-x.height)/2):g===2?(y=-x.x+r,b=-x.y+r+(c-x.height)/2):g===3&&(y=-x.x+r+(d-x.width)/2,b=-x.y+r),this.translateXY(y,b)}checkNeedMindMapInCanvas(){if(this.mindMap.demonstrate&&this.mindMap.demonstrate.isInDemonstrate)return!1;let{isLimitMindMapInCanvasWhenHasScrollbar:e,isLimitMindMapInCanvas:t}=this.mindMap.opt;return this.mindMap.scrollbar?e:t}limitMindMapInCanvas(){if(!this.checkNeedMindMapInCanvas())return;let{scale:e,left:t,top:r,right:n,bottom:s}=this.getPositionLimit(),a=(this.mindMap.width-this.mindMap.initWidth)/2*e,o=(this.mindMap.height-this.mindMap.initHeight)/2*e,l=this.scale/e;t*=l,n*=l,r*=l,s*=l;let h=this.mindMap.width/2,d=this.mindMap.height/2,c=this.scale-1;t-=c*h-a,n-=c*h-a,r-=c*d-o,s-=c*d-o,this.x>t&&(this.x=t),this.xr&&(this.y=r),this.y{"use strict";var PP=Object.prototype.hasOwnProperty,jt="~";function o0(){}Object.create&&(o0.prototype=Object.create(null),new o0().__proto__||(jt=!1));function FP(i,e,t){this.fn=i,this.context=e,this.once=t||!1}function Nv(i,e,t,r,n){if(typeof t!="function")throw new TypeError("The listener must be a function");var s=new FP(t,r||i,n),a=jt?jt+e:e;return i._events[a]?i._events[a].fn?i._events[a]=[i._events[a],s]:i._events[a].push(s):(i._events[a]=s,i._eventsCount++),i}function wc(i,e){--i._eventsCount===0?i._events=new o0:delete i._events[e]}function Ct(){this._events=new o0,this._eventsCount=0}Ct.prototype.eventNames=function(){var e=[],t,r;if(this._eventsCount===0)return e;for(r in t=this._events)PP.call(t,r)&&e.push(jt?r.slice(1):r);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e};Ct.prototype.listeners=function(e){var t=jt?jt+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var n=0,s=r.length,a=new Array(s);n{Sv=pt(Ev());$e();fp=class extends Sv.default{constructor(e={}){super(),this.opt=e,this.mindMap=e.mindMap,this.isLeftMousedown=!1,this.isRightMousedown=!1,this.isMiddleMousedown=!1,this.mousedownPos={x:0,y:0},this.mousemovePos={x:0,y:0},this.mousemoveOffset={x:0,y:0},this.bindFn(),this.bind()}bindFn(){this.onBodyMousedown=this.onBodyMousedown.bind(this),this.onBodyClick=this.onBodyClick.bind(this),this.onDrawClick=this.onDrawClick.bind(this),this.onMousedown=this.onMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.onNodeMouseup=this.onNodeMouseup.bind(this),this.onMousewheel=this.onMousewheel.bind(this),this.onContextmenu=this.onContextmenu.bind(this),this.onSvgMousedown=this.onSvgMousedown.bind(this),this.onKeyup=this.onKeyup.bind(this),this.onMouseenter=this.onMouseenter.bind(this),this.onMouseleave=this.onMouseleave.bind(this)}bind(){document.body.addEventListener("mousedown",this.onBodyMousedown),document.body.addEventListener("click",this.onBodyClick),this.mindMap.svg.on("click",this.onDrawClick),this.mindMap.el.addEventListener("mousedown",this.onMousedown),this.mindMap.svg.on("mousedown",this.onSvgMousedown),window.addEventListener("mousemove",this.onMousemove),window.addEventListener("mouseup",this.onMouseup),this.on("node_mouseup",this.onNodeMouseup),this.mindMap.el.addEventListener("wheel",this.onMousewheel),this.mindMap.svg.on("contextmenu",this.onContextmenu),this.mindMap.svg.on("mouseenter",this.onMouseenter),this.mindMap.svg.on("mouseleave",this.onMouseleave),window.addEventListener("keyup",this.onKeyup)}unbind(){document.body.removeEventListener("mousedown",this.onBodyMousedown),document.body.removeEventListener("click",this.onBodyClick),this.mindMap.svg.off("click",this.onDrawClick),this.mindMap.el.removeEventListener("mousedown",this.onMousedown),window.removeEventListener("mousemove",this.onMousemove),window.removeEventListener("mouseup",this.onMouseup),this.off("node_mouseup",this.onNodeMouseup),this.mindMap.el.removeEventListener("wheel",this.onMousewheel),this.mindMap.svg.off("contextmenu",this.onContextmenu),this.mindMap.svg.off("mouseenter",this.onMouseenter),this.mindMap.svg.off("mouseleave",this.onMouseleave),window.removeEventListener("keyup",this.onKeyup)}onDrawClick(e){this.emit("draw_click",e)}onBodyMousedown(e){this.emit("body_mousedown",e)}onBodyClick(e){this.emit("body_click",e)}onSvgMousedown(e){this.emit("svg_mousedown",e)}onMousedown(e){e.which===1?this.isLeftMousedown=!0:e.which===3?this.isRightMousedown=!0:e.which===2&&(this.isMiddleMousedown=!0),this.mousedownPos.x=e.clientX,this.mousedownPos.y=e.clientY,this.emit("mousedown",e,this)}onMousemove(e){let{useLeftKeySelectionRightKeyDrag:t}=this.mindMap.opt;this.mousemovePos.x=e.clientX,this.mousemovePos.y=e.clientY,this.mousemoveOffset.x=e.clientX-this.mousedownPos.x,this.mousemoveOffset.y=e.clientY-this.mousedownPos.y,this.emit("mousemove",e,this),(this.isMiddleMousedown||(t?this.isRightMousedown:this.isLeftMousedown))&&(e.preventDefault(),this.emit("drag",e,this))}onMouseup(e){this.onNodeMouseup(),this.emit("mouseup",e,this)}onNodeMouseup(){this.isLeftMousedown=!1,this.isRightMousedown=!1,this.isMiddleMousedown=!1}onMousewheel(e){e.stopPropagation(),e.preventDefault();let t=[];e.deltaY<0&&t.push(k.DIR.UP),e.deltaY>0&&t.push(k.DIR.DOWN),e.deltaX<0&&t.push(k.DIR.LEFT),e.deltaX>0&&t.push(k.DIR.RIGHT);let r=!1,{customCheckIsTouchPad:n}=this.mindMap.opt;typeof n=="function"?r=n(e):r=Math.abs(e.deltaY)<=10,this.emit("mousewheel",e,t,this,r)}onContextmenu(e){e.preventDefault(),!e.ctrlKey&&this.emit("contextmenu",e)}onKeyup(e){this.emit("keyup",e)}onMouseenter(e){this.emit("svg_mouseenter",e)}onMouseleave(e){this.emit("svg_mouseleave",e)}},Av=fp});var mp,pp,Cv=T(()=>{Ar();pe();$e();mp=class extends Mt{constructor(e={},t){super(e),this.isUseLeft=t===k.LAYOUT.LOGICAL_STRUCTURE_LEFT}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustTopValue()},()=>{e(this.root)}])}computedBaseValue(){let e=0;de(this.renderer.renderTree,null,(t,r,n,s,a,o)=>{let l=this.createNode(t,r,n,s,a,o);if(l.sortIndex=e,e++,n?this.setNodeCenter(l):this.isUseLeft?l.left=r._node.left-l.width-this.getMarginX(s):l.left=r._node.left+r._node.width+this.getMarginX(s),!t.data.expand)return!0},(t,r,n,s)=>{let a=t.data.expand===!1?0:t._node.children.length;t._node.childrenAreaHeight=a?t._node.children.reduce((l,h)=>l+h.height,0)+(a+1)*this.getMarginY(s+1):0;let o=t._node.checkHasGeneralization()?t._node._generalizationNodeHeight+this.getMarginY(s+1):0;t._node.childrenAreaHeight2=Math.max(t._node.childrenAreaHeight,o)},!0,0)}computedTopValue(){de(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),o=e.top+e.height/2-e.childrenAreaHeight/2+s;e.children.forEach(l=>{l.top=o,o+=l.height+s})}},null,!0)}adjustTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=e.childrenAreaHeight2-this.getMarginY(n+1)*2-e.height;s>0&&this.updateBrothers(e,s/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.uid===e.uid||s.hasCustomPosition())return;let o=0;an&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothers(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let f=(this.getMarginX(e.layerIndex+1)-l)*.6;this.isUseLeft&&(f*=-1);let m=this.mindMap.themeConfig.nodeUseLineStyle;e.children.forEach((g,x)=>{let y;this.isUseLeft?y=e.layerIndex===0?n:n-l:y=e.layerIndex===0?n+a:n+a+l;let b=s+o/2,S=this.isUseLeft?g.left+g.width:g.left,A=g.top+g.height/2,C=m?g.width*(this.isUseLeft?-1:1):0;b=m&&!e.isRoot?b+o/2:b,A=m?A+g.height/2:A;let I=this.createFoldLine([[y,b],[y+f,b],[y+f,A],[S+C,A]]);this.setLineStyle(r,t[x],I,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c}=this.mindMap.themeConfig;e.children.forEach((f,m)=>{e.layerIndex===0&&(l=0);let g=this.isUseLeft?n-l:n+a+l,x=s+o/2,y=this.isUseLeft?f.left+f.width:f.left,b=f.top+f.height/2;x=c&&!e.isRoot?x+o/2:x,b=c?b+f.height/2:b;let S=c?` L ${this.isUseLeft?f.left:f.left+f.width},${b}`:"",A=`M ${g},${x} L ${y},${b}`+S;this.setLineStyle(r,t[m],A,f)})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineStartPositionKeepSameInCurve:f,rootLineKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y;this.isUseLeft?y=e.layerIndex===0&&!f?n+a/2:n-l:y=e.layerIndex===0&&!f?n+a/2:n+a+l;let b=s+o/2,S=this.isUseLeft?g.left+g.width:g.left,A=g.top+g.height/2,C="";b=c&&!e.isRoot?b+o/2:b,A=c?A+g.height/2:A;let I;this.isUseLeft?I=c?` L ${g.left},${A}`:"":I=c?` L ${g.left+g.width},${A}`:"",e.isRoot&&!m?C=this.quadraticCurvePath(y,b,S,A)+I:C=this.cubicBezierPath(y,b,S,A)+I,this.setLineStyle(r,t[x],C,g)})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,layerIndex:a}=e;a===0&&(s=0);let{translateX:o,translateY:l}=t.transform(),h=this.mindMap.themeConfig.nodeUseLineStyle?n/2:0,d=this.isUseLeft?0-s:r,c=n/2+h;d===o&&c===l||t.translate(d-o,c-l)}renderGeneralization(e){e.forEach(t=>{let{left:r,top:n,bottom:s,right:a,generalizationLineMargin:o,generalizationNodeMargin:l}=this.getNodeGeneralizationRenderBoundaries(t,"h"),h=this.isUseLeft?r-o:a+o,d=h,c=n,f=h,m=s,g=d+(this.isUseLeft?-20:20),x=c+(m-c)/2,y=`M ${d},${c} Q ${g},${x} ${f},${m}`;t.generalizationLine.plot(y),t.generalizationNode.left=h+(this.isUseLeft?-l:l)-(this.isUseLeft?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n){this.isUseLeft?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},pp=mp});var gp,_v,Lv=T(()=>{Ar();pe();$e();gp=class extends Mt{constructor(e={}){super(e)}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustTopValue()},()=>{e(this.root)}])}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(t._node.dir?o.dir=t._node.dir:o.dir=o.getData("dir")||(s%2===0?k.LAYOUT_GROW_DIR.RIGHT:k.LAYOUT_GROW_DIR.LEFT),o.left=o.dir===k.LAYOUT_GROW_DIR.RIGHT?t._node.left+t._node.width+this.getMarginX(n):t._node.left-this.getMarginX(n)-o.width),!e.data.expand)return!0},(e,t,r,n)=>{if(!e.data.expand){e._node.leftChildrenAreaHeight=0,e._node.rightChildrenAreaHeight=0;return}let s=0,a=0,o=0,l=0;e._node.children.forEach(d=>{d.dir===k.LAYOUT_GROW_DIR.LEFT?(s++,o+=d.height):(a++,l+=d.height)}),e._node.leftChildrenAreaHeight=o+(s+1)*this.getMarginY(n+1),e._node.rightChildrenAreaHeight=l+(a+1)*this.getMarginY(n+1);let h=e._node.checkHasGeneralization()?e._node._generalizationNodeHeight+this.getMarginY(n+1):0;e._node.leftChildrenAreaHeight2=Math.max(e._node.leftChildrenAreaHeight,h),e._node.rightChildrenAreaHeight2=Math.max(e._node.rightChildrenAreaHeight,h)},!0,0)}computedTopValue(){de(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),a=e.top+e.height/2+s,o=a-e.leftChildrenAreaHeight/2,l=a-e.rightChildrenAreaHeight/2;e.children.forEach(h=>{h.dir===k.LAYOUT_GROW_DIR.LEFT?(h.top=o,o+=h.height+s):(h.top=l,l+=h.height+s)})}},null,!0)}adjustTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=this.getMarginY(n+1)*2+e.height,a=e.leftChildrenAreaHeight2-s,o=e.rightChildrenAreaHeight2-s;(a>0||o>0)&&this.updateBrothers(e,a/2,o/2)},null,!0)}updateBrothers(e,t,r){if(e.parent){let n=e.parent.children.filter(a=>a.dir===e.dir),s=Ie(e,n);n.forEach((a,o)=>{if(a.hasCustomPosition())return;let l=0,h=a.dir===k.LAYOUT_GROW_DIR.LEFT?t:r;os&&(l=h),a.top+=l,a.children&&a.children.length&&this.updateChildren(a.children,"top",l)}),this.updateBrothers(e.parent,t,r)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let f=(this.getMarginX(e.layerIndex+1)-l)*.6,m=this.mindMap.themeConfig.nodeUseLineStyle;e.children.forEach((g,x)=>{let y=0,b=0,S=m?g.width:0;g.dir===k.LAYOUT_GROW_DIR.LEFT?(b=-f,y=e.layerIndex===0?n:n-l,S=-S):(b=f,y=e.layerIndex===0?n+a:n+a+l);let A=s+o/2,C=g.dir===k.LAYOUT_GROW_DIR.LEFT?g.left+g.width:g.left,I=g.top+g.height/2;A=m&&!e.isRoot?A+o/2:A,I=m?I+g.height/2:I;let O=this.createFoldLine([[y,A],[y+b,A],[y+b,I],[C+S,I]]);this.setLineStyle(r,t[x],O,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c}=this.mindMap.themeConfig;e.children.forEach((f,m)=>{e.layerIndex===0&&(l=0);let g=f.dir===k.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,x=s+o/2,y=f.dir===k.LAYOUT_GROW_DIR.LEFT?f.left+f.width:f.left,b=f.top+f.height/2;x=c&&!e.isRoot?x+o/2:x,b=c?b+f.height/2:b;let S="";c&&(f.dir===k.LAYOUT_GROW_DIR.LEFT?S=` L ${f.left},${b}`:S=` L ${f.left+f.width},${b}`);let A=`M ${g},${x} L ${y},${b}`+S;this.setLineStyle(r,t[m],A,f)})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineKeepSameInCurve:f,rootLineStartPositionKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y=e.layerIndex===0&&!m?n+a/2:g.dir===k.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,b=s+o/2,S=g.dir===k.LAYOUT_GROW_DIR.LEFT?g.left+g.width:g.left,A=g.top+g.height/2,C="";b=c&&!e.isRoot?b+o/2:b,A=c?A+g.height/2:A;let I="";c&&(g.dir===k.LAYOUT_GROW_DIR.LEFT?I=` L ${g.left},${A}`:I=` L ${g.left+g.width},${A}`),e.isRoot&&!f?C=this.quadraticCurvePath(y,b,S,A)+I:C=this.cubicBezierPath(y,b,S,A)+I,this.setLineStyle(r,t[x],C,g)})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s}=e,{translateX:a,translateY:o}=t.transform(),l=this.mindMap.themeConfig.nodeUseLineStyle?n/2:0,h=e.dir===k.LAYOUT_GROW_DIR.LEFT?0-s:r,d=n/2+l;if(h===a&&d===o)return;let c=h-a,f=d-o;t.translate(c,f)}renderGeneralization(e){e.forEach(t=>{let r=t.node.dir===k.LAYOUT_GROW_DIR.LEFT,{top:n,bottom:s,left:a,right:o,generalizationLineMargin:l,generalizationNodeMargin:h}=this.getNodeGeneralizationRenderBoundaries(t,"h"),d=r?a-l:o+l,c=d,f=n,m=d,g=s,x=c+(r?-20:20),y=f+(g-f)/2,b=`M ${c},${f} Q ${x},${y} ${m},${g}`;t.generalizationLine.plot(b),t.generalizationNode.left=d+(r?-h:h)-(r?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){s.dir===k.LAYOUT_GROW_DIR.LEFT?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},_v=gp});var xp,Iv,zv=T(()=>{Ar();pe();xp=class extends Mt{constructor(e={}){super(e)}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):t._node.isRoot&&(o.top=t._node.top+t._node.height+this.getMarginX(n)),!e.data.expand)return!0},(e,t,r,n)=>{if(r){let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaWidth=s?e._node.children.reduce((a,o)=>a+o.width,0)+(s+1)*this.getMarginX(n+1):0}},!0,0)}computedLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginX(n+1),a=this.getMarginY(n+1);if(r){let l=e.left+e.width/2-e.childrenAreaWidth/2+s;e.children.forEach(h=>{h.left=l,l+=h.width+s})}else{let o=e.top+this.getNodeHeightWithGeneralization(e)+a+(this.getNodeActChildrenLength(e)>0?e.expandBtnSize:0);e.children.forEach(l=>{l.left=e.left+e.width*.5,l.top=o,o+=this.getNodeHeightWithGeneralization(l)+a+(this.getNodeActChildrenLength(l)>0?l.expandBtnSize:0)})}}},null,!0)}adjustLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;if(t&&t.isRoot){let o=this.getNodeAreaWidth(e,!0)-e.width;o>0&&this.updateBrothersLeft(e,o)}let s=e.children.length;if(t&&!t.isRoot&&s>0){let a=this.getMarginY(n+1),o=e.children.reduce((l,h)=>l+this.getNodeHeightWithGeneralization(h)+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0),0)+s*a;this.updateBrothersTop(e,o)}},(e,t,r)=>{if(r){let{right:n,left:s}=this.getNodeBoundaries(e,"h"),a=n-s,o=e.left-s-(a-e.width)/2;this.updateChildren(e.children,"left",o)}},!0)}updateBrothersLeft(e,t){if(e.parent){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{s.hasCustomPosition()||a<=n||(s.left+=t,s.children&&s.children.length&&this.updateChildren(s.children,"left",t))}),this.updateBrothersLeft(e.parent,t)}}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let c=e.children.length,f=this.getMarginX(e.layerIndex+1);if(e.isRoot){let m=n+a/2,g=s+o,x=f*.7,y=1/0,b=-1/0;e.children.forEach((A,C)=>{let I=A.left+A.width/2,O=A.top;Ib&&(b=I);let q=this.mindMap.themeConfig.nodeUseLineStyle?` L ${A.left},${O} L ${A.left+A.width},${O}`:"",P=`M ${I},${g+x} L ${I},${g+x>O?O+A.height:O}`+q;this.setLineStyle(r,t[C],P,A)}),y=Math.min(y,m),b=Math.max(b,m);let S=this.lineDraw.path();if(e.style.line(S),S.plot(this.transformPath(`M ${m},${g} L ${m},${g+x}`)),e._lines.push(S),r&&r(S,e),c>0){let A=this.lineDraw.path();e.style.line(A),A.plot(this.transformPath(`M ${y},${g+x} L ${b},${g+x}`)),e._lines.push(A),r&&r(A,e)}}else{let m=s+o,g=-1/0,x=e.left+e.width*.3;if(e.children.forEach((y,b)=>{let S=y.top+y.height/2;S>g&&(g=S);let A="",C=y.left,I=y.left+y.widthx&&(O=!0,S=y.top,g=S),S>s&&S0){let y=this.lineDraw.path();l=c>0?l:0,e.style.line(y),g{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){e.size(r,t).x(0).y(n)}},Iv=xp});var yp,Rv,Dv=T(()=>{Ar();pe();yp=class extends Mt{constructor(e={}){super(e)}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedLeftValue()},()=>{this.adjustLeftValue()},()=>{e(this.root)}])}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):o.top=t._node.top+t._node.height+this.getMarginX(n),!e.data.expand)return!0},(e,t,r,n)=>{let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaWidth=s?e._node.children.reduce((o,l)=>o+l.width,0)+(s+1)*this.getMarginY(n+1):0;let a=e._node.checkHasGeneralization()?e._node._generalizationNodeWidth+this.getMarginY(n+1):0;e._node.childrenAreaWidth2=Math.max(e._node.childrenAreaWidth,a)},!0,0)}computedLeftValue(){de(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),o=e.left+e.width/2-e.childrenAreaWidth/2+s;e.children.forEach(l=>{l.left=o,o+=l.width+s})}},null,!0)}adjustLeftValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=e.childrenAreaWidth2-this.getMarginY(n+1)*2-e.width;s>0&&this.updateBrothers(e,s/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;an&&(o=t),s.left+=o,s.children&&s.children.length&&this.updateChildren(s.children,"left",o)}),this.updateBrothers(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineStartPositionKeepSameInCurve:f,rootLineKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y=n+a/2,b=e.layerIndex===0&&!f?s+o/2:s+o+l,S=g.left+g.width/2,A=g.top,C="",I=c?` L ${g.left},${A} L ${g.left+g.width},${A}`:"";e.isRoot&&!m?C=this.quadraticCurvePath(y,b,S,A,!0)+I:C=this.cubicBezierPath(y,b,S,A,!0)+I,this.setLineStyle(r,t[x],C,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o}=e,{nodeUseLineStyle:l}=this.mindMap.themeConfig,h=n+a/2,d=s+o;e.children.forEach((c,f)=>{let m=c.left+c.width/2,g=c.top,x=l?` L ${c.left},${g} L ${c.left+c.width},${g}`:"",y=`M ${h},${d} L ${m},${g}`+x;this.setLineStyle(r,t[f],y,c)})}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l,isRoot:h}=e,{alwaysShowExpandBtn:d,notShowExpandBtn:c}=this.mindMap.opt;(!d||c)&&(l=0);let f=n+a/2,m=s+o,x=this.getMarginX(e.layerIndex+1)*.7,y=1/0,b=-1/0,S=e.children.length;e.children.forEach((C,I)=>{let O=C.left+C.width/2,q=m+x>C.top?C.top+C.height:C.top;Ob&&(b=O);let P=this.mindMap.themeConfig.nodeUseLineStyle?` L ${C.left},${q} L ${C.left+C.width},${q}`:"",W=`M ${O},${m+x} L ${O},${q}`+P;this.setLineStyle(r,t[I],W,C)}),y=Math.min(f,y),b=Math.max(f,b);let A=this.lineDraw.path();if(e.style.line(A),l=S>0&&!h?l:0,A.plot(this.transformPath(`M ${f},${m+l} L ${f},${m+x}`)),e._lines.push(A),r&&r(A,e),S>0){let C=this.lineDraw.path();e.style.line(C),C.plot(this.transformPath(`M ${y},${m+x} L ${b},${m+x}`)),e._lines.push(C),r&&r(C,e)}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s}=e,{translateX:a,translateY:o}=t.transform();t.translate(r/2-s/2-a,n+s/2-o)}renderGeneralization(e){e.forEach(t=>{let{bottom:r,left:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"v"),l=n,h=r+a,d=s,c=r+a,f=l+(d-l)/2,m=h+20,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.top=r+o,t.generalizationNode.left=n+(s-n-t.generalizationNode.width)/2})}renderExpandBtnRect(e,t,r,n,s){e.size(r,t).x(0).y(n)}},Rv=yp});var vp,bp,Ov=T(()=>{Ar();pe();$e();vp=class extends Mt{constructor(e={},t){super(e),this.layout=t}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(this.layout===k.LAYOUT.TIMELINE2?t._node.dir?o.dir=t._node.dir:o.dir=s%2===0?k.LAYOUT_GROW_DIR.BOTTOM:k.LAYOUT_GROW_DIR.TOP:o.dir="",t._node.isRoot&&(o.top=t._node.top+(e._node.height>t._node.height?-(e._node.height-t._node.height)/2:(t._node.height-e._node.height)/2))),!e.data.expand)return!0},null,!0,0)}computedLeftTopValue(){de(this.root,null,(e,t,r,n,s)=>{if(e.getData("expand")&&e.children&&e.children.length){let a=this.getMarginX(n+1),o=this.getMarginY(n+1);if(r){let h=e.left+e.width+a;e.children.forEach(d=>{d.left=h,h+=d.width+a})}else{let l=e.top+e.height+o+(this.getNodeActChildrenLength(e)>0?e.expandBtnSize:0);e.children.forEach(h=>{h.left=e.left+e.width*.5,h.top=l,l+=h.height+o+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0)})}}},null,!0)}adjustLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;e.isRoot&&this.updateBrothersLeft(e);let s=e.children.length;if(t&&!t.isRoot&&s>0){let a=this.getMarginY(n+1),o=e.children.reduce((l,h)=>l+h.height+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0),0)+s*a;this.updateBrothersTop(e,o)}},(e,t,r,n)=>{t&&t.isRoot&&e.dir===k.LAYOUT_GROW_DIR.TOP&&e.children.forEach(s=>{let a=this.getNodeAreaHeight(s),o=s.top;s.top=e.top-(s.top-e.top)-a+e.height,this.updateChildren(s.children,"top",s.top-o)})},!0)}getNodeAreaHeight(e){let t=0,r=n=>{t+=n.height+(this.getNodeActChildrenLength(n)>0?n.expandBtnSize:0)+this.getMarginY(n.layerIndex),n.children.length&&n.children.forEach(s=>{r(s)})};return r(e),t}updateBrothersLeft(e){let t=e.children,r=0;t.forEach(n=>{n.left+=r,n.children&&n.children.length&&this.updateChildren(n.children,"left",r);let{left:s,right:a}=this.getNodeBoundaries(n,"h"),l=a-s-n.width;l>0&&(r+=l)})}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let c=e.children.length;if(e.isRoot){let f=e;e.children.forEach((m,g)=>{let x=f.left+f.width,y=m.left,b=e.top+e.height/2,S=`M ${x},${b} L ${y},${b}`;this.setLineStyle(r,t[g],S,m),f=m})}else{let f=-1/0,m=1/0,g=e.left+e.width*.3;if(e.children.forEach((x,y)=>{let b=x.top+x.height/2;b>f&&(f=b),b0){let x=this.lineDraw.path();l=c>0?l:0,e.parent&&e.parent.isRoot&&e.dir===k.LAYOUT_GROW_DIR.TOP?x.plot(this.transformPath(`M ${g},${s} L ${g},${m}`)):x.plot(this.transformPath(`M ${g},${s+o+l} L ${g},${f}`)),e.style.line(x),e._lines.push(x),r&&r(x,e)}}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform();e.parent&&e.parent.isRoot&&e.dir===k.LAYOUT_GROW_DIR.TOP?t.translate(r*.3-s/2-o,-s/2-l):t.translate(r*.3-s/2-o,n+s/2-l)}}renderGeneralization(e){e.forEach(t=>{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){if(this.layout===k.LAYOUT.TIMELINE)e.size(r,t).x(0).y(n);else{let a="";s.dir===k.LAYOUT_GROW_DIR.TOP?a=s.layerIndex===1?k.LAYOUT_GROW_DIR.TOP:k.LAYOUT_GROW_DIR.BOTTOM:a=k.LAYOUT_GROW_DIR.BOTTOM,a===k.LAYOUT_GROW_DIR.TOP?e.size(r,t).x(0).y(-t):e.size(r,t).x(0).y(n)}}},bp=vp});var wp,Mc,Bv=T(()=>{Ar();pe();$e();wp=class extends Mt{constructor(e={},t){super(e),this.layout=t}doLayout(e){Zt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(t._node.dir?o.dir=t._node.dir:this.layout===k.LAYOUT.VERTICAL_TIMELINE2?o.dir=k.LAYOUT_GROW_DIR.LEFT:this.layout===k.LAYOUT.VERTICAL_TIMELINE3?o.dir=k.LAYOUT_GROW_DIR.RIGHT:o.dir=s%2===0?k.LAYOUT_GROW_DIR.RIGHT:k.LAYOUT_GROW_DIR.LEFT,t._node.isRoot?o.left=t._node.left+(e._node.width>t._node.width?-(e._node.width-t._node.width)/2:(t._node.width-e._node.width)/2):o.left=o.dir===k.LAYOUT_GROW_DIR.RIGHT?t._node.left+t._node.width+this.getMarginX(n):t._node.left-this.getMarginX(n)-o.width),!e.data.expand)return!0},(e,t,r,n)=>{if(r)return;let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaHeight=s?e._node.children.reduce((a,o)=>a+o.height,0)+(s+1)*this.getMarginY(n+1):0},!0,0)}computedTopValue(){de(this.root,null,(e,t,r,n,s)=>{if(e.getData("expand")&&e.children&&e.children.length){let a=this.getMarginY(n+1);if(r){let l=e.top+e.height+a;e.children.forEach(h=>{h.top=l,l+=h.height+a})}else{let o=this.getMarginY(n+1),h=e.top+e.height/2+o-e.childrenAreaHeight/2;e.children.forEach(d=>{d.top=h,h+=d.height+o})}}},null,!0)}adjustLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand")||r)return;let s=this.getMarginY(n+1)*2+e.height,a=e.childrenAreaHeight-s;a>0&&this.updateBrothers(e,a/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition()||!e.parent.isRoot&&s.uid===e.uid)return;let o=0;e.parent.isRoot?an?o=t*2:o=t:an&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothers(e.parent,t)}}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{expandBtnSize:n}=e,{alwaysShowExpandBtn:s,notShowExpandBtn:a}=this.mindMap.opt;if((!s||a)&&(n=0),e.isRoot){let o=e;e.children.forEach((l,h)=>{let d=o.top+o.height,c=l.top,f=e.left+e.width/2,m=`M ${f},${d} L ${f},${c}`;this.setLineStyle(r,t[h],m,l),o=l})}else if(e.dir===k.LAYOUT_GROW_DIR.RIGHT){let o=e.left+e.width,l=e.top+e.height/2,d=(this.getMarginX(e.layerIndex+1)-n)*.6;e.children.forEach((c,f)=>{let m=c.left,g=c.top+c.height/2,x=this.createFoldLine([[o,l],[o+d,l],[o+d,g],[m,g]]);this.setLineStyle(r,t[f],x,c)})}else{let o=e.left,l=e.top+e.height/2,d=(this.getMarginX(e.layerIndex+1)-n)*.6;e.children.forEach((c,f)=>{let m=c.left+c.width,g=c.top+c.height/2,x=this.createFoldLine([[o,l],[o-d,l],[o-d,g],[m,g]]);this.setLineStyle(r,t[f],x,c)})}}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0),e.children.forEach((c,f)=>{if(e.isRoot){let m=e;e.children.forEach((g,x)=>{let y=m.top+m.height,b=g.top,S=e.left+e.width/2,A=`M ${S},${y} L ${S},${b}`;this.setLineStyle(r,t[x],A,g),m=g})}else{let m=c.dir===k.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,g=s+o/2,x=c.dir===k.LAYOUT_GROW_DIR.LEFT?c.left+c.width:c.left,y=c.top+c.height/2,b=`M ${m},${g} L ${x},${y}`;this.setLineStyle(r,t[f],b,c)}})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0),e.children.forEach((c,f)=>{if(e.isRoot){let m=e;e.children.forEach((g,x)=>{let y=m.top+m.height,b=g.top,S=e.left+e.width/2,A=`M ${S},${y} L ${S},${b}`;this.setLineStyle(r,t[x],A,g),m=g})}else{let m=c.dir===k.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,g=s+o/2,x=c.dir===k.LAYOUT_GROW_DIR.LEFT?c.left+c.width:c.left,y=c.top+c.height/2,b=this.cubicBezierPath(m,g,x,y);this.setLineStyle(r,t[f],b,c)}})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform();e.dir===k.LAYOUT_GROW_DIR.RIGHT?t.translate(r-o,n/2-l):t.translate(-s-o,n/2-l)}}renderGeneralization(e){e.forEach(t=>{let r=t.node.dir===k.LAYOUT_GROW_DIR.LEFT,{top:n,bottom:s,left:a,right:o,generalizationLineMargin:l,generalizationNodeMargin:h}=this.getNodeGeneralizationRenderBoundaries(t,"h"),d=r?a-l:o+l,c=d,f=n,m=d,g=s,x=c+(r?-20:20),y=f+(g-f)/2,b=`M ${c},${f} Q ${x},${y} ${m},${g}`;t.generalizationLine.plot(this.transformPath(b)),t.generalizationNode.left=d+(r?-h:h)-(r?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){s.dir===k.LAYOUT_GROW_DIR.LEFT?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},Mc=wp});var er,Pv=T(()=>{pe();er={top:{renderExpandBtn({node:i,btn:e,expandBtnSize:t,translateX:r,translateY:n,width:s,height:a}){i.parent&&i.parent.isRoot?e.translate(s*.3-t/2-r,-t/2-n):e.translate(s*.3-t/2-r,a+t/2-n)},renderLine({node:i,line:e,top:t,x:r,lineLength:n,height:s,expandBtnSize:a,maxy:o,ctx:l}){i.parent&&i.parent.isRoot?e.plot(l.transformPath(`M ${r},${t} L ${r+n},${t-Math.tan(fn(l.mindMap.opt.fishboneDeg))*n}`)):e.plot(l.transformPath(`M ${r},${t+s+a} L ${r},${o}`))},computedLeftTopValue({layerIndex:i,node:e,ctx:t}){if(i>=1&&e.children){let r=t.getMarginY(i+1),n=e.left+e.width*t.childIndent,s=e.top+e.height+(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)+r;e.children.forEach(a=>{a.left=n,a.top+=s,s+=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}},adjustLeftTopValueBefore({node:i,parent:e,ctx:t,layerIndex:r}){let n=i.children.length,s=t.getMarginY(r+1);if(e&&!e.isRoot&&n>0){let a=i.children.reduce((o,l)=>o+l.height+(t.getNodeActChildrenLength(l)>0?l.expandBtnSize:0)+s,0);t.updateBrothersTop(i,a)}},adjustLeftTopValueAfter({parent:i,node:e,ctx:t}){if(i&&i.isRoot){let r=t.getMarginY(e.layerIndex+1),n=e.expandBtnSize+r;e.children.forEach(s=>{let a=t.getNodeAreaHeight(s),o=s.top,l=s.left;s.top=e.top-(s.top-e.top)-a+e.height,s.left=e.left+e.width*t.indent+(a+n)/Math.tan(fn(t.mindMap.opt.fishboneDeg)),n+=a,t.updateChildrenPro(s.children,{top:s.top-o,left:s.left-l})})}}},bottom:{renderExpandBtn({node:i,btn:e,expandBtnSize:t,translateX:r,translateY:n,width:s,height:a}){i.parent&&i.parent.isRoot?e.translate(s*.3-t/2-r,a+t/2-n):e.translate(s*.3-t/2-r,-t/2-n)},renderLine({node:i,line:e,top:t,x:r,lineLength:n,height:s,miny:a,ctx:o}){i.parent&&i.parent.isRoot?e.plot(o.transformPath(`M ${r},${t+s} L ${r+n},${t+s+Math.tan(fn(o.mindMap.opt.fishboneDeg))*n}`)):e.plot(o.transformPath(`M ${r},${t} L ${r},${a}`))},computedLeftTopValue({layerIndex:i,node:e,ctx:t}){let r=t.getMarginY(i+1);if(i===1&&e.children){let n=e.left+e.width*t.childIndent,s=e.top+e.height+(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)+r;e.children.forEach(a=>{a.left=n,a.top=s+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0),s+=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}if(i>1&&e.children){let n=e.left+e.width*t.childIndent,s=e.top-(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)-r;e.children.forEach(a=>{a.left=n,a.top=s-a.height,s-=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}},adjustLeftTopValueBefore({node:i,ctx:e,layerIndex:t}){let r=e.getMarginY(t+1),n=i.children.length;if(t>2&&n>0){let s=i.children.reduce((a,o)=>a+o.height+(e.getNodeActChildrenLength(o)>0?o.expandBtnSize:0)+r,0);e.updateBrothersTop(i,-s)}},adjustLeftTopValueAfter({parent:i,node:e,ctx:t}){if(i&&i.isRoot){let r=t.getMarginY(e.layerIndex+1),n=0,s=e.expandBtnSize;e.children.forEach(a=>{let o=t.getNodeActChildrenLength(a)>0,l=t.getNodeAreaHeight(a),h=o?l-a.height-(o?a.expandBtnSize:0):0;h-=o?r:0;let d=n+h,c=a.left;a.top+=d,a.left=e.left+e.width*t.indent+(l+s)/Math.tan(fn(t.mindMap.opt.fishboneDeg)),n+=h,s+=l,t.updateChildrenPro(a.children,{top:d,left:a.left-c})})}}}}});var Mp,Tp,Fv=T(()=>{Ar();pe();$e();Pv();yt();Y0();Mp=class extends Mt{constructor(e={},t){super(e),this.layout=t,this.indent=.3,this.childIndent=.5,this.fishTail=null,this.maxx=0,this.headRatio=1,this.tailRatio=.6,this.paddingXRatio=.3,this.fishHeadPathStr="M4,181 C4,181, 0,177, 4,173 Q 96.09523809523809,0, 288.2857142857143,0 L 288.2857142857143,354 Q 48.047619047619044,354, 8,218.18367346938777 C8,218.18367346938777, 6,214.18367346938777, 8,214.18367346938777 L 41.183673469387756,214.18367346938777 Z",this.fishTailPathStr="M 606.9342905223708 0 Q 713.1342905223709 -177 819.3342905223708 -177 L 766.2342905223709 0 L 819.3342905223708 177 Q 713.1342905223709 177 606.9342905223708 0 z",this.bindEvent(),this.extendShape(),this.beforeChange=this.beforeChange.bind(this)}nodeIsRemoveAllLines(e){return e.isRoot||e.layerIndex===1}isFishbone2(){return this.layout===k.LAYOUT.FISHBONE2}bindEvent(){this.isFishbone2()&&(this.onCheckUpdateFishTail=this.onCheckUpdateFishTail.bind(this),this.mindMap.on("afterExecCommand",this.onCheckUpdateFishTail))}unBindEvent(){this.mindMap.off("afterExecCommand",this.onCheckUpdateFishTail)}extendShape(){this.isFishbone2()&&this.mindMap.addShape({name:"fishHead",createShape:e=>{let t=Ae(``),{width:r,height:n}=e.shapeInstance.getNodeSize();return t.size(r,n),t},getPadding:({width:e,height:t,paddingX:r,paddingY:n})=>{e+=r*2,t+=n*2;let s=this.paddingXRatio*e,a=0;return e+=s*2,a=(e/this.headRatio-t)/2,{paddingX:s,paddingY:a}}})}doLayout(e){Zt([()=>{this.computedBaseValue(),this.addFishTail()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue(),this.updateFishTailPosition()},()=>{e(this.root)}])}addFishTail(){if(!this.isFishbone2())return;let e=this.mindMap.lineDraw.findOne(".smm-layout-fishbone-tail");e?this.fishTail=e:(this.fishTail=Ae(``),this.fishTail.addClass("smm-layout-fishbone-tail"));let t=this.root.height,r=t*this.tailRatio;this.fishTail.size(r,t),this.styleFishTail(),this.mindMap.lineDraw.add(this.fishTail)}onCheckUpdateFishTail(e,t,r){if(e==="SET_NODE_DATA"){let n=!1;Object.keys(r).forEach(s=>{Mu.includes(s)&&(n=!0)}),n&&this.styleFishTail()}}styleFishTail(){this.root.style.shape(this.fishTail)}removeFishTail(){let e=this.mindMap.lineDraw.findOne(".smm-layout-fishbone-tail");e&&e.remove()}updateFishTailPosition(){this.isFishbone2()&&this.fishTail.x(this.maxx).cy(this.root.top+this.root.height/2)}computedBaseValue(){de(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{r&&this.isFishbone2()&&(e.data.shape="fishHead");let o=this.createNode(e,t,r,n,s,a);if(r)this.setNodeCenter(o);else if(t._node.dir?o.dir=t._node.dir:o.dir=s%2===0?k.LAYOUT_GROW_DIR.TOP:k.LAYOUT_GROW_DIR.BOTTOM,t._node.isRoot){let l=this.getMarginY(n),h=this.isFishbone2()?t._node.height/4:0;this.checkIsTop(o)?o.top=t._node.top-o.height-l+h:o.top=t._node.top+t._node.height+l-h}if(!e.data.expand)return!0},null,!0,0)}computedLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(e.isRoot){let a=this.getMarginX(n+1),o=this.isFishbone2()?2:1,l=e.left+e.width+e.height/o+a,h=e.left+e.width+e.height/o+a;e.children.forEach(d=>{this.checkIsTop(d)?(d.left=l,l+=d.width+a):(d.left=h+20,h+=d.width+a)})}let s={layerIndex:n,node:e,ctx:this};this.checkIsTop(e)?er.top.computedLeftTopValue(s):er.bottom.computedLeftTopValue(s)},null,!0)}adjustLeftTopValue(){de(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s={node:e,parent:t,layerIndex:n,ctx:this};this.checkIsTop(e)?er.top.adjustLeftTopValueBefore(s):er.bottom.adjustLeftTopValueBefore(s)},(e,t)=>{let r={parent:t,node:e,ctx:this};if(this.checkIsTop(e)?er.top.adjustLeftTopValueAfter(r):er.bottom.adjustLeftTopValueAfter(r),e.isRoot){let n=0,s=0,a=-1/0;e.children.forEach(o=>{if(this.checkIsTop(o)){o.left+=n,this.updateChildren(o.children,"left",n);let{left:l,right:h}=this.getNodeBoundaries(o,"h");h>a&&(a=h),n+=h-l}else{o.left+=s,this.updateChildren(o.children,"left",s);let{left:l,right:h}=this.getNodeBoundaries(o,"h");h>a&&(a=h),s+=h-l}}),this.maxx=a}},!0)}getNodeAreaHeight(e){let t=0,r=n=>{let s=this.getMarginY(n.layerIndex);t+=n.height+(this.getNodeActChildrenLength(n)>0?n.expandBtnSize:0)+s,n.children.length&&n.children.forEach(a=>{r(a)})};return r(e),t}updateBrothersLeft(e){let t=e.children,r=0;t.forEach(n=>{n.left+=r,n.children&&n.children.length&&this.updateChildren(n.children,"left",r);let{left:s,right:a}=this.getNodeBoundaries(n,"h"),l=a-s-n.width;l>0&&(r+=l)})}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=Ie(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.checkIsTop(e)?this.updateBrothersTop(e.parent,t):this.updateBrothersTop(e.parent,e.layerIndex===3?0:t)}}checkIsTop(e){return e.dir===k.LAYOUT_GROW_DIR.TOP}renderLine(e,t,r){if(e.layerIndex!==1&&e.children.length<=0)return[];let{top:n,height:s,expandBtnSize:a}=e,{alwaysShowExpandBtn:o,notShowExpandBtn:l}=this.mindMap.opt;(!o||l)&&(a=0);let h=e.children.length;if(e.isRoot){let d=-1/0;e.children.forEach(x=>{x.left>d&&(d=x.left);let y=this.getMarginY(x.layerIndex),b=x.left,S=e.height/2+y-(this.isFishbone2()?e.height/4:0),A=S/Math.tan(fn(this.mindMap.opt.fishboneDeg)),C=this.lineDraw.path();this.checkIsTop(x)?C.plot(this.transformPath(`M ${b-A},${x.top+x.height+S} L ${x.left},${x.top+x.height}`)):C.plot(this.transformPath(`M ${b-A},${x.top-S} L ${b},${x.top}`)),e.style.line(C),e._lines.push(C),r&&r(C,e)});let c=e.top+e.height/2,f=e.height/2+this.getMarginY(e.layerIndex+1),m=this.lineDraw.path(),g=this.isFishbone2()?this.maxx:d-f/Math.tan(fn(this.mindMap.opt.fishboneDeg));m.plot(this.transformPath(`M ${e.left+e.width},${c} L ${g},${c}`)),e.style.line(m),e._lines.push(m),r&&r(m,e)}else{let d=-1/0,c=1/0,f=-1/0,m=e.left+e.width*this.indent;if(e.children.forEach((g,x)=>{g.left>f&&(f=g.left);let y=g.top+g.height/2;if(y>d&&(d=y),y1){let b=`M ${m},${y} L ${g.left},${y}`;this.setLineStyle(r,t[x],b,g)}}),h>=0){let g=this.lineDraw.path();a=h>0?a:0;let x=f-e.left-e.width*this.indent;x=Math.max(x,0);let y={node:e,line:g,top:n,x:m,lineLength:x,height:s,expandBtnSize:a,maxy:d,miny:c,ctx:this};this.checkIsTop(e)?er.top.renderLine(y):er.bottom.renderLine(y),e.style.line(g),e._lines.push(g),r&&r(g,e)}}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform(),h={node:e,btn:t,expandBtnSize:s,translateX:o,translateY:l,width:r,height:n};this.checkIsTop(e)?er.top.renderExpandBtn(h):er.bottom.renderExpandBtn(h)}}renderGeneralization(e){e.forEach(t=>{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){let a="";s.dir===k.LAYOUT_GROW_DIR.TOP?a=s.layerIndex===1?k.LAYOUT_GROW_DIR.TOP:k.LAYOUT_GROW_DIR.BOTTOM:a=s.layerIndex===1?k.LAYOUT_GROW_DIR.BOTTOM:k.LAYOUT_GROW_DIR.TOP,a===k.LAYOUT_GROW_DIR.TOP?e.size(r,t).x(0).y(-t):e.size(r,t).x(0).y(n)}beforeChange(){this.isFishbone2()&&(this.root.nodeData.data.shape=k.SHAPE.RECTANGLE,this.removeFishTail(),this.unBindEvent(),this.mindMap.removeShape("fishHead"))}},Tp=Mp});var qv,l0,Hv=T(()=>{pe();$e();qv="smm-node-edit-wrap",l0=class{constructor(e){this.renderer=e,this.mindMap=e.mindMap,this.currentNode=null,this.textEditNode=null,this.showTextEdit=!1,this.cacheEditingText="",this.hasBodyMousedown=!1,this.textNodePaddingX=5,this.textNodePaddingY=3,this.isNeedUpdateTextEditNode=!1,this.mindMap.addEditNodeClass(qv),this.bindEvent()}bindEvent(){this.show=this.show.bind(this),this.onScale=this.onScale.bind(this),this.onKeydown=this.onKeydown.bind(this),this.mindMap.on("node_dblclick",(e,t,r)=>{this.show({node:e,e:t,isInserting:r})}),this.mindMap.on("draw_click",()=>{this.hideEditTextBox()}),this.mindMap.on("body_mousedown",()=>{this.hasBodyMousedown=!0}),this.mindMap.on("body_click",()=>{this.hasBodyMousedown&&(this.hasBodyMousedown=!1,this.mindMap.opt.isEndNodeTextEditOnClickOuter&&this.hideEditTextBox())}),this.mindMap.on("svg_mousedown",()=>{this.hideEditTextBox()}),this.mindMap.on("expand_btn_click",()=>{this.hideEditTextBox()}),this.mindMap.on("before_node_active",()=>{this.hideEditTextBox()}),this.mindMap.on("mousewheel",()=>{this.mindMap.opt.mousewheelAction===k.MOUSE_WHEEL_ACTION.MOVE&&this.hideEditTextBox()}),this.mindMap.keyCommand.addShortcut("F2",()=>{this.renderer.activeNodeList.length<=0||this.show({node:this.renderer.activeNodeList[0]})}),this.mindMap.on("scale",this.onScale),this.mindMap.opt.enableAutoEnterTextEditWhenKeydown&&window.addEventListener("keydown",this.onKeydown),this.mindMap.on("beforeDestroy",()=>{this.unBindEvent()}),this.mindMap.on("after_update_config",(e,t)=>{e.openRealtimeRenderOnNodeTextEdit!==t.openRealtimeRenderOnNodeTextEdit&&(this.mindMap.richText?this.mindMap.richText.onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e.openRealtimeRenderOnNodeTextEdit):this.onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e.openRealtimeRenderOnNodeTextEdit)),e.enableAutoEnterTextEditWhenKeydown!==t.enableAutoEnterTextEditWhenKeydown&&window[e.enableAutoEnterTextEditWhenKeydown?"addEventListener":"removeEventListener"]("keydown",this.onKeydown)}),this.mindMap.on("afterExecCommand",()=>{this.isShowTextEdit()&&(this.isNeedUpdateTextEditNode=!0)}),this.mindMap.on("node_tree_render_end",()=>{this.isShowTextEdit()&&this.isNeedUpdateTextEditNode&&(this.isNeedUpdateTextEditNode=!1,this.updateTextEditNode())})}unBindEvent(){window.removeEventListener("keydown",this.onKeydown)}onKeydown(e){if(e.target!==document.body)return;let t=this.mindMap.renderer.activeNodeList;if(t.length<=0||t.length>1)return;let r=t[0];r&&this.checkIsAutoEnterTextEditKey(e)&&(e.preventDefault(),this.show({node:r,e,isInserting:!1,isFromKeyDown:!0}))}checkIsAutoEnterTextEditKey(e){let t=e.keyCode;return(t===229||t>=65&&t<=90||t>=48&&t<=57)&&!this.mindMap.keyCommand.hasCombinationKey(e)}registerTmpShortcut(){this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.mindMap.keyCommand.addShortcut("Tab",()=>{this.hideEditTextBox()})}isShowTextEdit(){return this.mindMap.richText?this.mindMap.richText.showTextEdit:this.showTextEdit}setIsShowTextEdit(e){this.showTextEdit=e,e?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}async show({node:e,isInserting:t=!1,isFromKeyDown:r=!1,isFromScale:n=!1}){if(e.isUseCustomNodeContent())return;this.getCurrentEditNode()&&this.hideEditTextBox();let{beforeTextEdit:a,openRealtimeRenderOnNodeTextEdit:o}=this.mindMap.opt;if(typeof a=="function"){let m=!1;try{m=await a(e,t)}catch(g){m=!1,this.mindMap.opt.errorHandler(Mi.BEFORE_TEXT_EDIT_ERROR,g)}if(!m)return}let{offsetLeft:l,offsetTop:h}=y2(this.mindMap,e);this.mindMap.view.translateXY(l,h);let d=e._textData.node;o&&d.show();let c=d.node.getBoundingClientRect();o&&d.hide();let f={node:e,rect:c,isInserting:t,isFromKeyDown:r,isFromScale:n};if(this.mindMap.richText){this.mindMap.richText.showEditText(f);return}this.currentNode=e,this.showEditTextBox(f)}onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e){this.textEditNode&&(this.textEditNode.style.background=e?"transparent":this.currentNode?this.getBackground(this.currentNode):"",this.textEditNode.style.boxShadow=e?"none":"0 0 20px rgba(0,0,0,.5)")}onScale(){let e=this.getCurrentEditNode();e&&(this.mindMap.richText?(this.mindMap.richText.cacheEditingText=this.mindMap.richText.getEditText(),this.mindMap.richText.showTextEdit=!1):(this.cacheEditingText=this.getEditText(),this.setIsShowTextEdit(!1)),this.show({node:e,isFromScale:!0}))}showEditTextBox({node:e,rect:t,isInserting:r,isFromKeyDown:n,isFromScale:s}){if(this.showTextEdit)return;let{nodeTextEditZIndex:a,textAutoWrapWidth:o,selectTextOnEnterEditText:l,openRealtimeRenderOnNodeTextEdit:h,autoEmptyTextWhenKeydownEnterEdit:d}=this.mindMap.opt;s||this.mindMap.emit("before_show_text_edit"),this.registerTmpShortcut(),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.classList.add(qv),this.textEditNode.style.cssText=` +`});var Rv={};tt(Rv,{default:()=>oF});var wp,zv,kc,oF,Dv=T(()=>{wg();Cv();pe();Iv();wp=!1,zv=Ac.import("formats/formula"),kc=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,window.katex=jh,this.init(),this.config=this.getKatexConfig(),this.cssEl=null,this.addStyle(),this.extendQuill(),this.onDestroy=this.onDestroy.bind(this),this.mindMap.on("beforeDestroy",this.onDestroy)}onDestroy(){Object.getPrototypeOf(this.mindMap).constructor.instanceCount<=1&&(wp=!1,Ac.register("formats/formula",zv,!0))}init(){this.mindMap.opt.enableEditFormulaInRichTextEdit&&(this.mindMap.opt.transformRichTextOnEnterEdit=this.latexRichToText.bind(this),this.mindMap.opt.beforeHideRichTextEdit=this.formatLatex.bind(this))}getKatexConfig(){let e={throwOnError:!1,errorColor:"#f00",output:"mathml"},{getKatexOutputType:t}=this.mindMap.opt;t=t||function(){let n=W2();if(n&&n<=100)return"html"};let r=t()||"mathml";return e.output=["mathml","html"].includes(r)?r:"mathml",e}extendQuill(){if(wp)return;wp=!0;let e=this;class t extends zv{static create(n){let s=super.create(n);return typeof n=="string"&&(jh.render(n,s,e.config),s.setAttribute("data-value",fn(n))),s}}Ac.register("formats/formula",t,!0)}getStyleText(){let{katexFontPath:e}=this.mindMap.opt,t="";return this.config.output==="html"&&(t=_v(e)),t+=Lv(),t}addStyle(){this.cssEl=document.createElement("style"),this.cssEl.type="text/css",this.cssEl.innerHTML=this.getStyleText(),document.head.appendChild(this.cssEl)}removeStyle(){document.head.removeChild(this.cssEl)}insertFormulaToNode(e,t){let r=this.mindMap.richText;r.showEditText({node:e}),r.quill.insertEmbed(r.quill.getLength()-1,"formula",t),r.hideEditText([e])}latexRichToText(e){if(e.indexOf('class="ql-formula"')!==-1){let n=new DOMParser().parseFromString(e,"text/html").getElementsByClassName("ql-formula");for(let s of n)e=e.replace(s.outerHTML,`$${s.getAttribute("data-value")}$`);this.mindMap.opt.openRealtimeRenderOnNodeTextEdit&&setTimeout(()=>{this.mindMap.emit("node_text_edit_change",{node:this.mindMap.richText.node,text:this.mindMap.richText.getEditText(),richText:!0})},0)}return e}formatLatex(e){let t=e.quill.getContents(),r=t.ops,n=!1;for(let s=r.length-1;s>=0;s--){let o=r[s].insert;if(o&&typeof o!="object"&&o!==` +`&&/\$.+?\$/g.test(o)){let l=[...o.matchAll(/\$.+?\$/g)],h=o.split(/\$.+?\$/g);for(let d=l.length-1;d>=0;d--){let c=l[d]&&l[d][0]&&l[d][0].slice(1,-1)||null;c!==null&&c.trim().length>0&&this.checkFormulaIsLegal(c)?(h.splice(d+1,0,{insert:{formula:c}}),n=!0):h.splice(d+1,0,"")}for(;h.length>0;){let d=h.pop();if(typeof d=="string"){if(d.length<1)continue;d={insert:d}}d.attributes=r[s].attributes,r.splice(s+1,0,d)}r.splice(s,1)}}n&&e.quill.setContents(t)}checkFormulaIsLegal(e){try{return jh.renderToString(e),!0}catch{return!1}}beforePluginRemove(){this.removeStyle(),this.mindMap.off("beforeDestroy",this.onDestroy)}beforePluginDestroy(){this.removeStyle(),this.mindMap.off("beforeDestroy",this.onDestroy)}};kc.instanceName="formula";oF=kc});var Mp,Ov,Bv=T(()=>{Ge();Mp=class{constructor(e={}){this.opt=e,this.mindMap=this.opt.mindMap,this.scale=1,this.sx=0,this.sy=0,this.x=0,this.y=0,this.firstDrag=!0,this.setTransformData(this.mindMap.opt.viewData),this.bind()}bind(){this.mindMap.keyCommand.addShortcut("Control+=",()=>{this.enlarge()}),this.mindMap.keyCommand.addShortcut("Control+-",()=>{this.narrow()}),this.mindMap.keyCommand.addShortcut("Control+i",()=>{this.fit()}),this.mindMap.event.on("mousedown",e=>{let{isDisableDrag:t,mousedownEventPreventDefault:r}=this.mindMap.opt;t||(r&&e.preventDefault(),this.sx=this.x,this.sy=this.y)}),this.mindMap.event.on("drag",(e,t)=>{e.ctrlKey||e.metaKey||this.mindMap.opt.isDisableDrag||(this.firstDrag&&(this.firstDrag=!1,this.mindMap.renderer.activeNodeList.length>0&&this.mindMap.execCommand("CLEAR_ACTIVE_NODE")),this.x=this.sx+t.mousemoveOffset.x,this.y=this.sy+t.mousemoveOffset.y,this.transform())}),this.mindMap.event.on("mouseup",()=>{this.firstDrag=!0}),this.mindMap.event.on("mousewheel",(e,t,r,n)=>{let{customHandleMousewheel:s,mousewheelAction:a,mouseScaleCenterUseMousePosition:o,mousewheelMoveStep:l,mousewheelZoomActionReverse:h,disableMouseWheelZoom:d,translateRatio:c}=this.mindMap.opt;if(s&&typeof s=="function")return s(e);if(a===C.MOUSE_WHEEL_ACTION.ZOOM||e.ctrlKey||e.metaKey){if(d)return;let{x:f,y:m}=this.mindMap.toPos(e.clientX,e.clientY),g=o?f:void 0,x=o?m:void 0;switch(n&&(t.includes(C.DIR.LEFT)||t.includes(C.DIR.RIGHT))&&(t=t.filter(y=>![C.DIR.LEFT,C.DIR.RIGHT].includes(y))),!0){case t.includes(C.DIR.UP||C.DIR.LEFT):h?this.enlarge(g,x,n):this.narrow(g,x,n);break;case t.includes(C.DIR.DOWN||C.DIR.RIGHT):h?this.narrow(g,x,n):this.enlarge(g,x,n);break}}else{let f=0,m=0;n?(f=Math.abs(e.wheelDeltaX),m=Math.abs(e.wheelDeltaY)):f=m=l;let g=0,x=0;t.includes(C.DIR.DOWN)&&(x=-m),t.includes(C.DIR.UP)&&(x=m),t.includes(C.DIR.LEFT)&&(g=f),t.includes(C.DIR.RIGHT)&&(g=-f),this.translateXY(g*c,x*c)}}),this.mindMap.on("resize",()=>{this.checkNeedMindMapInCanvas()&&this.transform()})}getTransformData(){return{transform:this.mindMap.draw.transform(),state:{scale:this.scale,x:this.x,y:this.y,sx:this.sx,sy:this.sy}}}setTransformData(e){e&&(Object.keys(e.state).forEach(t=>{this[t]=e.state[t]}),this.mindMap.draw.transform({...e.transform}),this.mindMap.emit("view_data_change",this.getTransformData()),this.emitEvent("scale"),this.emitEvent("translate"))}translateXY(e,t){e===0&&t===0||(this.x+=e,this.y+=t,this.transform(),this.emitEvent("translate"))}translateX(e){e!==0&&(this.x+=e,this.transform(),this.emitEvent("translate"))}translateXTo(e){this.x=e,this.transform(),this.emitEvent("translate")}translateY(e){e!==0&&(this.y+=e,this.transform(),this.emitEvent("translate"))}translateYTo(e){this.y=e,this.transform(),this.emitEvent("translate")}transform(){try{this.limitMindMapInCanvas()}catch{}this.mindMap.draw.transform({origin:[0,0],scale:this.scale,translate:[this.x,this.y]}),this.mindMap.emit("view_data_change",this.getTransformData())}reset(){let e=this.scale!==1,t=this.x!==0||this.y!==0;this.scale=1,this.x=0,this.y=0,this.transform(),e&&this.emitEvent("scale"),t&&this.emitEvent("translate")}narrow(e,t,r){let{scaleRatio:n,minZoomRatio:s}=this.mindMap.opt;n=n/(r?5:1);let a=Math.max(this.scale-n,s/100);this.scaleInCenter(a,e,t),this.transform(),this.emitEvent("scale")}enlarge(e,t,r){let{scaleRatio:n,maxZoomRatio:s}=this.mindMap.opt;n=n/(r?5:1);let a=0;s===-1?a=this.scale+n:a=Math.min(this.scale+n,s/100),this.scaleInCenter(a,e,t),this.transform(),this.emitEvent("scale")}scaleInCenter(e,t,r){(t===void 0||r===void 0)&&(t=this.mindMap.width/2,r=this.mindMap.height/2);let n=this.scale,s=1-e/n,a=(t-this.x)*s,o=(r-this.y)*s;this.x+=a,this.y+=o,this.scale=e}setScale(e,t,r){t!==void 0&&r!==void 0?this.scaleInCenter(e,t,r):this.scale=e,this.transform(),this.emitEvent("scale")}fit(e=()=>{},t=!1,r){r=r===void 0?this.mindMap.opt.fitPadding:r;let n=this.mindMap.draw,s=n.transform(),a=e()||n.rbox(),o=a.width/s.scaleX,l=a.height/s.scaleY,h=o/l,{width:d,height:c}=this.mindMap.elRect;d=d-r*2,c=c-r*2;let f=d/c,m=0,g="";if(o<=d&&l<=c&&!t)m=1,g=1;else{let E=0,k=0;h>f?(E=d,k=d/h,g=2):(k=c,E=c*h,g=3),m=E/o}this.setScale(m);let x=e()||n.rbox();x.x-=this.mindMap.elRect.left,x.y-=this.mindMap.elRect.top;let y=0,b=0;g===1?(y=-x.x+r+(d-x.width)/2,b=-x.y+r+(c-x.height)/2):g===2?(y=-x.x+r,b=-x.y+r+(c-x.height)/2):g===3&&(y=-x.x+r+(d-x.width)/2,b=-x.y+r),this.translateXY(y,b)}checkNeedMindMapInCanvas(){if(this.mindMap.demonstrate&&this.mindMap.demonstrate.isInDemonstrate)return!1;let{isLimitMindMapInCanvasWhenHasScrollbar:e,isLimitMindMapInCanvas:t}=this.mindMap.opt;return this.mindMap.scrollbar?e:t}limitMindMapInCanvas(){if(!this.checkNeedMindMapInCanvas())return;let{scale:e,left:t,top:r,right:n,bottom:s}=this.getPositionLimit(),a=(this.mindMap.width-this.mindMap.initWidth)/2*e,o=(this.mindMap.height-this.mindMap.initHeight)/2*e,l=this.scale/e;t*=l,n*=l,r*=l,s*=l;let h=this.mindMap.width/2,d=this.mindMap.height/2,c=this.scale-1;t-=c*h-a,n-=c*h-a,r-=c*d-o,s-=c*d-o,this.x>t&&(this.x=t),this.xr&&(this.y=r),this.y{"use strict";var lF=Object.prototype.hasOwnProperty,jt="~";function f0(){}Object.create&&(f0.prototype=Object.create(null),new f0().__proto__||(jt=!1));function hF(i,e,t){this.fn=i,this.context=e,this.once=t||!1}function Pv(i,e,t,r,n){if(typeof t!="function")throw new TypeError("The listener must be a function");var s=new hF(t,r||i,n),a=jt?jt+e:e;return i._events[a]?i._events[a].fn?i._events[a]=[i._events[a],s]:i._events[a].push(s):(i._events[a]=s,i._eventsCount++),i}function Cc(i,e){--i._eventsCount===0?i._events=new f0:delete i._events[e]}function Lt(){this._events=new f0,this._eventsCount=0}Lt.prototype.eventNames=function(){var e=[],t,r;if(this._eventsCount===0)return e;for(r in t=this._events)lF.call(t,r)&&e.push(jt?r.slice(1):r);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e};Lt.prototype.listeners=function(e){var t=jt?jt+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var n=0,s=r.length,a=new Array(s);n{qv=yt(Fv());Ge();Np=class extends qv.default{constructor(e={}){super(),this.opt=e,this.mindMap=e.mindMap,this.isLeftMousedown=!1,this.isRightMousedown=!1,this.isMiddleMousedown=!1,this.mousedownPos={x:0,y:0},this.mousemovePos={x:0,y:0},this.mousemoveOffset={x:0,y:0},this.bindFn(),this.bind()}bindFn(){this.onBodyMousedown=this.onBodyMousedown.bind(this),this.onBodyClick=this.onBodyClick.bind(this),this.onDrawClick=this.onDrawClick.bind(this),this.onMousedown=this.onMousedown.bind(this),this.onMousemove=this.onMousemove.bind(this),this.onMouseup=this.onMouseup.bind(this),this.onNodeMouseup=this.onNodeMouseup.bind(this),this.onMousewheel=this.onMousewheel.bind(this),this.onContextmenu=this.onContextmenu.bind(this),this.onSvgMousedown=this.onSvgMousedown.bind(this),this.onKeyup=this.onKeyup.bind(this),this.onMouseenter=this.onMouseenter.bind(this),this.onMouseleave=this.onMouseleave.bind(this)}bind(){document.body.addEventListener("mousedown",this.onBodyMousedown),document.body.addEventListener("click",this.onBodyClick),this.mindMap.svg.on("click",this.onDrawClick),this.mindMap.el.addEventListener("mousedown",this.onMousedown),this.mindMap.svg.on("mousedown",this.onSvgMousedown),window.addEventListener("mousemove",this.onMousemove),window.addEventListener("mouseup",this.onMouseup),this.on("node_mouseup",this.onNodeMouseup),this.mindMap.el.addEventListener("wheel",this.onMousewheel),this.mindMap.svg.on("contextmenu",this.onContextmenu),this.mindMap.svg.on("mouseenter",this.onMouseenter),this.mindMap.svg.on("mouseleave",this.onMouseleave),window.addEventListener("keyup",this.onKeyup)}unbind(){document.body.removeEventListener("mousedown",this.onBodyMousedown),document.body.removeEventListener("click",this.onBodyClick),this.mindMap.svg.off("click",this.onDrawClick),this.mindMap.el.removeEventListener("mousedown",this.onMousedown),window.removeEventListener("mousemove",this.onMousemove),window.removeEventListener("mouseup",this.onMouseup),this.off("node_mouseup",this.onNodeMouseup),this.mindMap.el.removeEventListener("wheel",this.onMousewheel),this.mindMap.svg.off("contextmenu",this.onContextmenu),this.mindMap.svg.off("mouseenter",this.onMouseenter),this.mindMap.svg.off("mouseleave",this.onMouseleave),window.removeEventListener("keyup",this.onKeyup)}onDrawClick(e){this.emit("draw_click",e)}onBodyMousedown(e){this.emit("body_mousedown",e)}onBodyClick(e){this.emit("body_click",e)}onSvgMousedown(e){this.emit("svg_mousedown",e)}onMousedown(e){e.which===1?this.isLeftMousedown=!0:e.which===3?this.isRightMousedown=!0:e.which===2&&(this.isMiddleMousedown=!0),this.mousedownPos.x=e.clientX,this.mousedownPos.y=e.clientY,this.emit("mousedown",e,this)}onMousemove(e){let{useLeftKeySelectionRightKeyDrag:t}=this.mindMap.opt;this.mousemovePos.x=e.clientX,this.mousemovePos.y=e.clientY,this.mousemoveOffset.x=e.clientX-this.mousedownPos.x,this.mousemoveOffset.y=e.clientY-this.mousedownPos.y,this.emit("mousemove",e,this),(this.isMiddleMousedown||(t?this.isRightMousedown:this.isLeftMousedown))&&(e.preventDefault(),this.emit("drag",e,this))}onMouseup(e){this.onNodeMouseup(),this.emit("mouseup",e,this)}onNodeMouseup(){this.isLeftMousedown=!1,this.isRightMousedown=!1,this.isMiddleMousedown=!1}onMousewheel(e){e.stopPropagation(),e.preventDefault();let t=[];e.deltaY<0&&t.push(C.DIR.UP),e.deltaY>0&&t.push(C.DIR.DOWN),e.deltaX<0&&t.push(C.DIR.LEFT),e.deltaX>0&&t.push(C.DIR.RIGHT);let r=!1,{customCheckIsTouchPad:n}=this.mindMap.opt;typeof n=="function"?r=n(e):r=Math.abs(e.deltaY)<=10,this.emit("mousewheel",e,t,this,r)}onContextmenu(e){e.preventDefault(),!e.ctrlKey&&this.emit("contextmenu",e)}onKeyup(e){this.emit("keyup",e)}onMouseenter(e){this.emit("svg_mouseenter",e)}onMouseleave(e){this.emit("svg_mouseleave",e)}},Hv=Np});var Ep,Sp,$v=T(()=>{Ar();pe();Ge();Ep=class extends Nt{constructor(e={},t){super(e),this.isUseLeft=t===C.LAYOUT.LOGICAL_STRUCTURE_LEFT}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustTopValue()},()=>{e(this.root)}])}computedBaseValue(){let e=0;ue(this.renderer.renderTree,null,(t,r,n,s,a,o)=>{let l=this.createNode(t,r,n,s,a,o);if(l.sortIndex=e,e++,n?this.setNodeCenter(l):this.isUseLeft?l.left=r._node.left-l.width-this.getMarginX(s):l.left=r._node.left+r._node.width+this.getMarginX(s),!t.data.expand)return!0},(t,r,n,s)=>{let a=t.data.expand===!1?0:t._node.children.length;t._node.childrenAreaHeight=a?t._node.children.reduce((l,h)=>l+h.height,0)+(a+1)*this.getMarginY(s+1):0;let o=t._node.checkHasGeneralization()?t._node._generalizationNodeHeight+this.getMarginY(s+1):0;t._node.childrenAreaHeight2=Math.max(t._node.childrenAreaHeight,o)},!0,0)}computedTopValue(){ue(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),o=e.top+e.height/2-e.childrenAreaHeight/2+s;e.children.forEach(l=>{l.top=o,o+=l.height+s})}},null,!0)}adjustTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=e.childrenAreaHeight2-this.getMarginY(n+1)*2-e.height;s>0&&this.updateBrothers(e,s/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.uid===e.uid||s.hasCustomPosition())return;let o=0;an&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothers(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let f=(this.getMarginX(e.layerIndex+1)-l)*.6;this.isUseLeft&&(f*=-1);let m=this.mindMap.themeConfig.nodeUseLineStyle;e.children.forEach((g,x)=>{let y;this.isUseLeft?y=e.layerIndex===0?n:n-l:y=e.layerIndex===0?n+a:n+a+l;let b=s+o/2,E=this.isUseLeft?g.left+g.width:g.left,k=g.top+g.height/2,L=m?g.width*(this.isUseLeft?-1:1):0;b=m&&!e.isRoot?b+o/2:b,k=m?k+g.height/2:k;let I=this.createFoldLine([[y,b],[y+f,b],[y+f,k],[E+L,k]]);this.setLineStyle(r,t[x],I,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c}=this.mindMap.themeConfig;e.children.forEach((f,m)=>{e.layerIndex===0&&(l=0);let g=this.isUseLeft?n-l:n+a+l,x=s+o/2,y=this.isUseLeft?f.left+f.width:f.left,b=f.top+f.height/2;x=c&&!e.isRoot?x+o/2:x,b=c?b+f.height/2:b;let E=c?` L ${this.isUseLeft?f.left:f.left+f.width},${b}`:"",k=`M ${g},${x} L ${y},${b}`+E;this.setLineStyle(r,t[m],k,f)})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineStartPositionKeepSameInCurve:f,rootLineKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y;this.isUseLeft?y=e.layerIndex===0&&!f?n+a/2:n-l:y=e.layerIndex===0&&!f?n+a/2:n+a+l;let b=s+o/2,E=this.isUseLeft?g.left+g.width:g.left,k=g.top+g.height/2,L="";b=c&&!e.isRoot?b+o/2:b,k=c?k+g.height/2:k;let I;this.isUseLeft?I=c?` L ${g.left},${k}`:"":I=c?` L ${g.left+g.width},${k}`:"",e.isRoot&&!m?L=this.quadraticCurvePath(y,b,E,k)+I:L=this.cubicBezierPath(y,b,E,k)+I,this.setLineStyle(r,t[x],L,g)})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,layerIndex:a}=e;a===0&&(s=0);let{translateX:o,translateY:l}=t.transform(),h=this.mindMap.themeConfig.nodeUseLineStyle?n/2:0,d=this.isUseLeft?0-s:r,c=n/2+h;d===o&&c===l||t.translate(d-o,c-l)}renderGeneralization(e){e.forEach(t=>{let{left:r,top:n,bottom:s,right:a,generalizationLineMargin:o,generalizationNodeMargin:l}=this.getNodeGeneralizationRenderBoundaries(t,"h"),h=this.isUseLeft?r-o:a+o,d=h,c=n,f=h,m=s,g=d+(this.isUseLeft?-20:20),x=c+(m-c)/2,y=`M ${d},${c} Q ${g},${x} ${f},${m}`;t.generalizationLine.plot(y),t.generalizationNode.left=h+(this.isUseLeft?-l:l)-(this.isUseLeft?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n){this.isUseLeft?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},Sp=Ep});var Ap,jv,Gv=T(()=>{Ar();pe();Ge();Ap=class extends Nt{constructor(e={}){super(e)}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustTopValue()},()=>{e(this.root)}])}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(t._node.dir?o.dir=t._node.dir:o.dir=o.getData("dir")||(s%2===0?C.LAYOUT_GROW_DIR.RIGHT:C.LAYOUT_GROW_DIR.LEFT),o.left=o.dir===C.LAYOUT_GROW_DIR.RIGHT?t._node.left+t._node.width+this.getMarginX(n):t._node.left-this.getMarginX(n)-o.width),!e.data.expand)return!0},(e,t,r,n)=>{if(!e.data.expand){e._node.leftChildrenAreaHeight=0,e._node.rightChildrenAreaHeight=0;return}let s=0,a=0,o=0,l=0;e._node.children.forEach(d=>{d.dir===C.LAYOUT_GROW_DIR.LEFT?(s++,o+=d.height):(a++,l+=d.height)}),e._node.leftChildrenAreaHeight=o+(s+1)*this.getMarginY(n+1),e._node.rightChildrenAreaHeight=l+(a+1)*this.getMarginY(n+1);let h=e._node.checkHasGeneralization()?e._node._generalizationNodeHeight+this.getMarginY(n+1):0;e._node.leftChildrenAreaHeight2=Math.max(e._node.leftChildrenAreaHeight,h),e._node.rightChildrenAreaHeight2=Math.max(e._node.rightChildrenAreaHeight,h)},!0,0)}computedTopValue(){ue(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),a=e.top+e.height/2+s,o=a-e.leftChildrenAreaHeight/2,l=a-e.rightChildrenAreaHeight/2;e.children.forEach(h=>{h.dir===C.LAYOUT_GROW_DIR.LEFT?(h.top=o,o+=h.height+s):(h.top=l,l+=h.height+s)})}},null,!0)}adjustTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=this.getMarginY(n+1)*2+e.height,a=e.leftChildrenAreaHeight2-s,o=e.rightChildrenAreaHeight2-s;(a>0||o>0)&&this.updateBrothers(e,a/2,o/2)},null,!0)}updateBrothers(e,t,r){if(e.parent){let n=e.parent.children.filter(a=>a.dir===e.dir),s=ze(e,n);n.forEach((a,o)=>{if(a.hasCustomPosition())return;let l=0,h=a.dir===C.LAYOUT_GROW_DIR.LEFT?t:r;os&&(l=h),a.top+=l,a.children&&a.children.length&&this.updateChildren(a.children,"top",l)}),this.updateBrothers(e.parent,t,r)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let f=(this.getMarginX(e.layerIndex+1)-l)*.6,m=this.mindMap.themeConfig.nodeUseLineStyle;e.children.forEach((g,x)=>{let y=0,b=0,E=m?g.width:0;g.dir===C.LAYOUT_GROW_DIR.LEFT?(b=-f,y=e.layerIndex===0?n:n-l,E=-E):(b=f,y=e.layerIndex===0?n+a:n+a+l);let k=s+o/2,L=g.dir===C.LAYOUT_GROW_DIR.LEFT?g.left+g.width:g.left,I=g.top+g.height/2;k=m&&!e.isRoot?k+o/2:k,I=m?I+g.height/2:I;let O=this.createFoldLine([[y,k],[y+b,k],[y+b,I],[L+E,I]]);this.setLineStyle(r,t[x],O,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c}=this.mindMap.themeConfig;e.children.forEach((f,m)=>{e.layerIndex===0&&(l=0);let g=f.dir===C.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,x=s+o/2,y=f.dir===C.LAYOUT_GROW_DIR.LEFT?f.left+f.width:f.left,b=f.top+f.height/2;x=c&&!e.isRoot?x+o/2:x,b=c?b+f.height/2:b;let E="";c&&(f.dir===C.LAYOUT_GROW_DIR.LEFT?E=` L ${f.left},${b}`:E=` L ${f.left+f.width},${b}`);let k=`M ${g},${x} L ${y},${b}`+E;this.setLineStyle(r,t[m],k,f)})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineKeepSameInCurve:f,rootLineStartPositionKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y=e.layerIndex===0&&!m?n+a/2:g.dir===C.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,b=s+o/2,E=g.dir===C.LAYOUT_GROW_DIR.LEFT?g.left+g.width:g.left,k=g.top+g.height/2,L="";b=c&&!e.isRoot?b+o/2:b,k=c?k+g.height/2:k;let I="";c&&(g.dir===C.LAYOUT_GROW_DIR.LEFT?I=` L ${g.left},${k}`:I=` L ${g.left+g.width},${k}`),e.isRoot&&!f?L=this.quadraticCurvePath(y,b,E,k)+I:L=this.cubicBezierPath(y,b,E,k)+I,this.setLineStyle(r,t[x],L,g)})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s}=e,{translateX:a,translateY:o}=t.transform(),l=this.mindMap.themeConfig.nodeUseLineStyle?n/2:0,h=e.dir===C.LAYOUT_GROW_DIR.LEFT?0-s:r,d=n/2+l;if(h===a&&d===o)return;let c=h-a,f=d-o;t.translate(c,f)}renderGeneralization(e){e.forEach(t=>{let r=t.node.dir===C.LAYOUT_GROW_DIR.LEFT,{top:n,bottom:s,left:a,right:o,generalizationLineMargin:l,generalizationNodeMargin:h}=this.getNodeGeneralizationRenderBoundaries(t,"h"),d=r?a-l:o+l,c=d,f=n,m=d,g=s,x=c+(r?-20:20),y=f+(g-f)/2,b=`M ${c},${f} Q ${x},${y} ${m},${g}`;t.generalizationLine.plot(b),t.generalizationNode.left=d+(r?-h:h)-(r?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){s.dir===C.LAYOUT_GROW_DIR.LEFT?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},jv=Ap});var kp,Wv,Vv=T(()=>{Ar();pe();kp=class extends Nt{constructor(e={}){super(e)}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):t._node.isRoot&&(o.top=t._node.top+t._node.height+this.getMarginX(n)),!e.data.expand)return!0},(e,t,r,n)=>{if(r){let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaWidth=s?e._node.children.reduce((a,o)=>a+o.width,0)+(s+1)*this.getMarginX(n+1):0}},!0,0)}computedLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginX(n+1),a=this.getMarginY(n+1);if(r){let l=e.left+e.width/2-e.childrenAreaWidth/2+s;e.children.forEach(h=>{h.left=l,l+=h.width+s})}else{let o=e.top+this.getNodeHeightWithGeneralization(e)+a+(this.getNodeActChildrenLength(e)>0?e.expandBtnSize:0);e.children.forEach(l=>{l.left=e.left+e.width*.5,l.top=o,o+=this.getNodeHeightWithGeneralization(l)+a+(this.getNodeActChildrenLength(l)>0?l.expandBtnSize:0)})}}},null,!0)}adjustLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;if(t&&t.isRoot){let o=this.getNodeAreaWidth(e,!0)-e.width;o>0&&this.updateBrothersLeft(e,o)}let s=e.children.length;if(t&&!t.isRoot&&s>0){let a=this.getMarginY(n+1),o=e.children.reduce((l,h)=>l+this.getNodeHeightWithGeneralization(h)+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0),0)+s*a;this.updateBrothersTop(e,o)}},(e,t,r)=>{if(r){let{right:n,left:s}=this.getNodeBoundaries(e,"h"),a=n-s,o=e.left-s-(a-e.width)/2;this.updateChildren(e.children,"left",o)}},!0)}updateBrothersLeft(e,t){if(e.parent){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{s.hasCustomPosition()||a<=n||(s.left+=t,s.children&&s.children.length&&this.updateChildren(s.children,"left",t))}),this.updateBrothersLeft(e.parent,t)}}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let c=e.children.length,f=this.getMarginX(e.layerIndex+1);if(e.isRoot){let m=n+a/2,g=s+o,x=f*.7,y=1/0,b=-1/0;e.children.forEach((k,L)=>{let I=k.left+k.width/2,O=k.top;Ib&&(b=I);let q=this.mindMap.themeConfig.nodeUseLineStyle?` L ${k.left},${O} L ${k.left+k.width},${O}`:"",F=`M ${I},${g+x} L ${I},${g+x>O?O+k.height:O}`+q;this.setLineStyle(r,t[L],F,k)}),y=Math.min(y,m),b=Math.max(b,m);let E=this.lineDraw.path();if(e.style.line(E),E.plot(this.transformPath(`M ${m},${g} L ${m},${g+x}`)),e._lines.push(E),r&&r(E,e),c>0){let k=this.lineDraw.path();e.style.line(k),k.plot(this.transformPath(`M ${y},${g+x} L ${b},${g+x}`)),e._lines.push(k),r&&r(k,e)}}else{let m=s+o,g=-1/0,x=e.left+e.width*.3;if(e.children.forEach((y,b)=>{let E=y.top+y.height/2;E>g&&(g=E);let k="",L=y.left,I=y.left+y.widthx&&(O=!0,E=y.top,g=E),E>s&&E0){let y=this.lineDraw.path();l=c>0?l:0,e.style.line(y),g{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){e.size(r,t).x(0).y(n)}},Wv=kp});var Cp,Yv,Xv=T(()=>{Ar();pe();Cp=class extends Nt{constructor(e={}){super(e)}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedLeftValue()},()=>{this.adjustLeftValue()},()=>{e(this.root)}])}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):o.top=t._node.top+t._node.height+this.getMarginX(n),!e.data.expand)return!0},(e,t,r,n)=>{let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaWidth=s?e._node.children.reduce((o,l)=>o+l.width,0)+(s+1)*this.getMarginY(n+1):0;let a=e._node.checkHasGeneralization()?e._node._generalizationNodeWidth+this.getMarginY(n+1):0;e._node.childrenAreaWidth2=Math.max(e._node.childrenAreaWidth,a)},!0,0)}computedLeftValue(){ue(this.root,null,(e,t,r,n)=>{if(e.getData("expand")&&e.children&&e.children.length){let s=this.getMarginY(n+1),o=e.left+e.width/2-e.childrenAreaWidth/2+s;e.children.forEach(l=>{l.left=o,o+=l.width+s})}},null,!0)}adjustLeftValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s=e.childrenAreaWidth2-this.getMarginY(n+1)*2-e.width;s>0&&this.updateBrothers(e,s/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;an&&(o=t),s.left+=o,s.children&&s.children.length&&this.updateChildren(s.children,"left",o)}),this.updateBrothers(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let{nodeUseLineStyle:c,rootLineStartPositionKeepSameInCurve:f,rootLineKeepSameInCurve:m}=this.mindMap.themeConfig;e.children.forEach((g,x)=>{e.layerIndex===0&&(l=0);let y=n+a/2,b=e.layerIndex===0&&!f?s+o/2:s+o+l,E=g.left+g.width/2,k=g.top,L="",I=c?` L ${g.left},${k} L ${g.left+g.width},${k}`:"";e.isRoot&&!m?L=this.quadraticCurvePath(y,b,E,k,!0)+I:L=this.cubicBezierPath(y,b,E,k,!0)+I,this.setLineStyle(r,t[x],L,g)})}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o}=e,{nodeUseLineStyle:l}=this.mindMap.themeConfig,h=n+a/2,d=s+o;e.children.forEach((c,f)=>{let m=c.left+c.width/2,g=c.top,x=l?` L ${c.left},${g} L ${c.left+c.width},${g}`:"",y=`M ${h},${d} L ${m},${g}`+x;this.setLineStyle(r,t[f],y,c)})}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l,isRoot:h}=e,{alwaysShowExpandBtn:d,notShowExpandBtn:c}=this.mindMap.opt;(!d||c)&&(l=0);let f=n+a/2,m=s+o,x=this.getMarginX(e.layerIndex+1)*.7,y=1/0,b=-1/0,E=e.children.length;e.children.forEach((L,I)=>{let O=L.left+L.width/2,q=m+x>L.top?L.top+L.height:L.top;Ob&&(b=O);let F=this.mindMap.themeConfig.nodeUseLineStyle?` L ${L.left},${q} L ${L.left+L.width},${q}`:"",W=`M ${O},${m+x} L ${O},${q}`+F;this.setLineStyle(r,t[I],W,L)}),y=Math.min(f,y),b=Math.max(f,b);let k=this.lineDraw.path();if(e.style.line(k),l=E>0&&!h?l:0,k.plot(this.transformPath(`M ${f},${m+l} L ${f},${m+x}`)),e._lines.push(k),r&&r(k,e),E>0){let L=this.lineDraw.path();e.style.line(L),L.plot(this.transformPath(`M ${y},${m+x} L ${b},${m+x}`)),e._lines.push(L),r&&r(L,e)}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s}=e,{translateX:a,translateY:o}=t.transform();t.translate(r/2-s/2-a,n+s/2-o)}renderGeneralization(e){e.forEach(t=>{let{bottom:r,left:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"v"),l=n,h=r+a,d=s,c=r+a,f=l+(d-l)/2,m=h+20,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.top=r+o,t.generalizationNode.left=n+(s-n-t.generalizationNode.width)/2})}renderExpandBtnRect(e,t,r,n,s){e.size(r,t).x(0).y(n)}},Yv=Cp});var _p,Lp,Kv=T(()=>{Ar();pe();Ge();_p=class extends Nt{constructor(e={},t){super(e),this.layout=t}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(this.layout===C.LAYOUT.TIMELINE2?t._node.dir?o.dir=t._node.dir:o.dir=s%2===0?C.LAYOUT_GROW_DIR.BOTTOM:C.LAYOUT_GROW_DIR.TOP:o.dir="",t._node.isRoot&&(o.top=t._node.top+(e._node.height>t._node.height?-(e._node.height-t._node.height)/2:(t._node.height-e._node.height)/2))),!e.data.expand)return!0},null,!0,0)}computedLeftTopValue(){ue(this.root,null,(e,t,r,n,s)=>{if(e.getData("expand")&&e.children&&e.children.length){let a=this.getMarginX(n+1),o=this.getMarginY(n+1);if(r){let h=e.left+e.width+a;e.children.forEach(d=>{d.left=h,h+=d.width+a})}else{let l=e.top+e.height+o+(this.getNodeActChildrenLength(e)>0?e.expandBtnSize:0);e.children.forEach(h=>{h.left=e.left+e.width*.5,h.top=l,l+=h.height+o+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0)})}}},null,!0)}adjustLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;e.isRoot&&this.updateBrothersLeft(e);let s=e.children.length;if(t&&!t.isRoot&&s>0){let a=this.getMarginY(n+1),o=e.children.reduce((l,h)=>l+h.height+(this.getNodeActChildrenLength(h)>0?h.expandBtnSize:0),0)+s*a;this.updateBrothersTop(e,o)}},(e,t,r,n)=>{t&&t.isRoot&&e.dir===C.LAYOUT_GROW_DIR.TOP&&e.children.forEach(s=>{let a=this.getNodeAreaHeight(s),o=s.top;s.top=e.top-(s.top-e.top)-a+e.height,this.updateChildren(s.children,"top",s.top-o)})},!0)}getNodeAreaHeight(e){let t=0,r=n=>{t+=n.height+(this.getNodeActChildrenLength(n)>0?n.expandBtnSize:0)+this.getMarginY(n.layerIndex),n.children.length&&n.children.forEach(s=>{r(s)})};return r(e),t}updateBrothersLeft(e){let t=e.children,r=0;t.forEach(n=>{n.left+=r,n.children&&n.children.length&&this.updateChildren(n.children,"left",r);let{left:s,right:a}=this.getNodeBoundaries(n,"h"),l=a-s-n.width;l>0&&(r+=l)})}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0);let c=e.children.length;if(e.isRoot){let f=e;e.children.forEach((m,g)=>{let x=f.left+f.width,y=m.left,b=e.top+e.height/2,E=`M ${x},${b} L ${y},${b}`;this.setLineStyle(r,t[g],E,m),f=m})}else{let f=-1/0,m=1/0,g=e.left+e.width*.3;if(e.children.forEach((x,y)=>{let b=x.top+x.height/2;b>f&&(f=b),b0){let x=this.lineDraw.path();l=c>0?l:0,e.parent&&e.parent.isRoot&&e.dir===C.LAYOUT_GROW_DIR.TOP?x.plot(this.transformPath(`M ${g},${s} L ${g},${m}`)):x.plot(this.transformPath(`M ${g},${s+o+l} L ${g},${f}`)),e.style.line(x),e._lines.push(x),r&&r(x,e)}}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform();e.parent&&e.parent.isRoot&&e.dir===C.LAYOUT_GROW_DIR.TOP?t.translate(r*.3-s/2-o,-s/2-l):t.translate(r*.3-s/2-o,n+s/2-l)}}renderGeneralization(e){e.forEach(t=>{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){if(this.layout===C.LAYOUT.TIMELINE)e.size(r,t).x(0).y(n);else{let a="";s.dir===C.LAYOUT_GROW_DIR.TOP?a=s.layerIndex===1?C.LAYOUT_GROW_DIR.TOP:C.LAYOUT_GROW_DIR.BOTTOM:a=C.LAYOUT_GROW_DIR.BOTTOM,a===C.LAYOUT_GROW_DIR.TOP?e.size(r,t).x(0).y(-t):e.size(r,t).x(0).y(n)}}},Lp=_p});var Ip,_c,Zv=T(()=>{Ar();pe();Ge();Ip=class extends Nt{constructor(e={},t){super(e),this.layout=t}doLayout(e){Jt([()=>{this.computedBaseValue()},()=>{this.computedTopValue()},()=>{this.adjustLeftTopValue()},()=>{e(this.root)}])}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{let o=this.createNode(e,t,r,n,s,a);if(r?this.setNodeCenter(o):(t._node.dir?o.dir=t._node.dir:this.layout===C.LAYOUT.VERTICAL_TIMELINE2?o.dir=C.LAYOUT_GROW_DIR.LEFT:this.layout===C.LAYOUT.VERTICAL_TIMELINE3?o.dir=C.LAYOUT_GROW_DIR.RIGHT:o.dir=s%2===0?C.LAYOUT_GROW_DIR.RIGHT:C.LAYOUT_GROW_DIR.LEFT,t._node.isRoot?o.left=t._node.left+(e._node.width>t._node.width?-(e._node.width-t._node.width)/2:(t._node.width-e._node.width)/2):o.left=o.dir===C.LAYOUT_GROW_DIR.RIGHT?t._node.left+t._node.width+this.getMarginX(n):t._node.left-this.getMarginX(n)-o.width),!e.data.expand)return!0},(e,t,r,n)=>{if(r)return;let s=e.data.expand===!1?0:e._node.children.length;e._node.childrenAreaHeight=s?e._node.children.reduce((a,o)=>a+o.height,0)+(s+1)*this.getMarginY(n+1):0},!0,0)}computedTopValue(){ue(this.root,null,(e,t,r,n,s)=>{if(e.getData("expand")&&e.children&&e.children.length){let a=this.getMarginY(n+1);if(r){let l=e.top+e.height+a;e.children.forEach(h=>{h.top=l,l+=h.height+a})}else{let o=this.getMarginY(n+1),h=e.top+e.height/2+o-e.childrenAreaHeight/2;e.children.forEach(d=>{d.top=h,h+=d.height+o})}}},null,!0)}adjustLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand")||r)return;let s=this.getMarginY(n+1)*2+e.height,a=e.childrenAreaHeight-s;a>0&&this.updateBrothers(e,a/2)},null,!0)}updateBrothers(e,t){if(e.parent){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition()||!e.parent.isRoot&&s.uid===e.uid)return;let o=0;e.parent.isRoot?an?o=t*2:o=t:an&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothers(e.parent,t)}}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.updateBrothersTop(e.parent,t)}}renderLine(e,t,r,n){n==="curve"?this.renderLineCurve(e,t,r):n==="direct"?this.renderLineDirect(e,t,r):this.renderLineStraight(e,t,r)}renderLineStraight(e,t,r){if(e.children.length<=0)return[];let{expandBtnSize:n}=e,{alwaysShowExpandBtn:s,notShowExpandBtn:a}=this.mindMap.opt;if((!s||a)&&(n=0),e.isRoot){let o=e;e.children.forEach((l,h)=>{let d=o.top+o.height,c=l.top,f=e.left+e.width/2,m=`M ${f},${d} L ${f},${c}`;this.setLineStyle(r,t[h],m,l),o=l})}else if(e.dir===C.LAYOUT_GROW_DIR.RIGHT){let o=e.left+e.width,l=e.top+e.height/2,d=(this.getMarginX(e.layerIndex+1)-n)*.6;e.children.forEach((c,f)=>{let m=c.left,g=c.top+c.height/2,x=this.createFoldLine([[o,l],[o+d,l],[o+d,g],[m,g]]);this.setLineStyle(r,t[f],x,c)})}else{let o=e.left,l=e.top+e.height/2,d=(this.getMarginX(e.layerIndex+1)-n)*.6;e.children.forEach((c,f)=>{let m=c.left+c.width,g=c.top+c.height/2,x=this.createFoldLine([[o,l],[o-d,l],[o-d,g],[m,g]]);this.setLineStyle(r,t[f],x,c)})}}renderLineDirect(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0),e.children.forEach((c,f)=>{if(e.isRoot){let m=e;e.children.forEach((g,x)=>{let y=m.top+m.height,b=g.top,E=e.left+e.width/2,k=`M ${E},${y} L ${E},${b}`;this.setLineStyle(r,t[x],k,g),m=g})}else{let m=c.dir===C.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,g=s+o/2,x=c.dir===C.LAYOUT_GROW_DIR.LEFT?c.left+c.width:c.left,y=c.top+c.height/2,b=`M ${m},${g} L ${x},${y}`;this.setLineStyle(r,t[f],b,c)}})}renderLineCurve(e,t,r){if(e.children.length<=0)return[];let{left:n,top:s,width:a,height:o,expandBtnSize:l}=e,{alwaysShowExpandBtn:h,notShowExpandBtn:d}=this.mindMap.opt;(!h||d)&&(l=0),e.children.forEach((c,f)=>{if(e.isRoot){let m=e;e.children.forEach((g,x)=>{let y=m.top+m.height,b=g.top,E=e.left+e.width/2,k=`M ${E},${y} L ${E},${b}`;this.setLineStyle(r,t[x],k,g),m=g})}else{let m=c.dir===C.LAYOUT_GROW_DIR.LEFT?n-l:n+a+l,g=s+o/2,x=c.dir===C.LAYOUT_GROW_DIR.LEFT?c.left+c.width:c.left,y=c.top+c.height/2,b=this.cubicBezierPath(m,g,x,y);this.setLineStyle(r,t[f],b,c)}})}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform();e.dir===C.LAYOUT_GROW_DIR.RIGHT?t.translate(r-o,n/2-l):t.translate(-s-o,n/2-l)}}renderGeneralization(e){e.forEach(t=>{let r=t.node.dir===C.LAYOUT_GROW_DIR.LEFT,{top:n,bottom:s,left:a,right:o,generalizationLineMargin:l,generalizationNodeMargin:h}=this.getNodeGeneralizationRenderBoundaries(t,"h"),d=r?a-l:o+l,c=d,f=n,m=d,g=s,x=c+(r?-20:20),y=f+(g-f)/2,b=`M ${c},${f} Q ${x},${y} ${m},${g}`;t.generalizationLine.plot(this.transformPath(b)),t.generalizationNode.left=d+(r?-h:h)-(r?t.generalizationNode.width:0),t.generalizationNode.top=n+(s-n-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){s.dir===C.LAYOUT_GROW_DIR.LEFT?e.size(t,n).x(-t).y(0):e.size(t,n).x(r).y(0)}},_c=Ip});var Ji,Qv=T(()=>{pe();Ji={top:{renderExpandBtn({node:i,btn:e,expandBtnSize:t,translateX:r,translateY:n,width:s,height:a}){i.parent&&i.parent.isRoot?e.translate(s*.3-t/2-r,-t/2-n):e.translate(s*.3-t/2-r,a+t/2-n)},renderLine({node:i,line:e,top:t,x:r,lineLength:n,height:s,expandBtnSize:a,maxy:o,ctx:l}){i.parent&&i.parent.isRoot?e.plot(l.transformPath(`M ${r},${t} L ${r+n},${t-Math.tan(un(l.mindMap.opt.fishboneDeg))*n}`)):e.plot(l.transformPath(`M ${r},${t+s+a} L ${r},${o}`))},computedLeftTopValue({layerIndex:i,node:e,ctx:t}){if(i>=1&&e.children){let r=t.getMarginY(i+1),n=e.left+e.width*t.childIndent,s=e.top+e.height+(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)+r;e.children.forEach(a=>{a.left=n,a.top+=s,s+=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}},adjustLeftTopValueBefore({node:i,parent:e,ctx:t,layerIndex:r}){let n=i.children.length,s=t.getMarginY(r+1);if(e&&!e.isRoot&&n>0){let a=i.children.reduce((o,l)=>o+l.height+(t.getNodeActChildrenLength(l)>0?l.expandBtnSize:0)+s,0);t.updateBrothersTop(i,a)}},adjustLeftTopValueAfter({parent:i,node:e,ctx:t}){if(i&&i.isRoot){let r=t.getMarginY(e.layerIndex+1),n=e.expandBtnSize+r;e.children.forEach(s=>{let a=t.getNodeAreaHeight(s),o=s.top,l=s.left;s.top=e.top-(s.top-e.top)-a+e.height,s.left=e.left+e.width*t.indent+(a+n)/Math.tan(un(t.mindMap.opt.fishboneDeg)),n+=a,t.updateChildrenPro(s.children,{top:s.top-o,left:s.left-l})})}}},bottom:{renderExpandBtn({node:i,btn:e,expandBtnSize:t,translateX:r,translateY:n,width:s,height:a}){i.parent&&i.parent.isRoot?e.translate(s*.3-t/2-r,a+t/2-n):e.translate(s*.3-t/2-r,-t/2-n)},renderLine({node:i,line:e,top:t,x:r,lineLength:n,height:s,miny:a,ctx:o}){i.parent&&i.parent.isRoot?e.plot(o.transformPath(`M ${r},${t+s} L ${r+n},${t+s+Math.tan(un(o.mindMap.opt.fishboneDeg))*n}`)):e.plot(o.transformPath(`M ${r},${t} L ${r},${a}`))},computedLeftTopValue({layerIndex:i,node:e,ctx:t}){let r=t.getMarginY(i+1);if(i===1&&e.children){let n=e.left+e.width*t.childIndent,s=e.top+e.height+(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)+r;e.children.forEach(a=>{a.left=n,a.top=s+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0),s+=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}if(i>1&&e.children){let n=e.left+e.width*t.childIndent,s=e.top-(t.getNodeActChildrenLength(e)>0?e.expandBtnSize:0)-r;e.children.forEach(a=>{a.left=n,a.top=s-a.height,s-=a.height+(t.getNodeActChildrenLength(a)>0?a.expandBtnSize:0)+r})}},adjustLeftTopValueBefore({node:i,ctx:e,layerIndex:t}){let r=e.getMarginY(t+1),n=i.children.length;if(t>2&&n>0){let s=i.children.reduce((a,o)=>a+o.height+(e.getNodeActChildrenLength(o)>0?o.expandBtnSize:0)+r,0);e.updateBrothersTop(i,-s)}},adjustLeftTopValueAfter({parent:i,node:e,ctx:t}){if(i&&i.isRoot){let r=t.getMarginY(e.layerIndex+1),n=0,s=e.expandBtnSize;e.children.forEach(a=>{let o=t.getNodeActChildrenLength(a)>0,l=t.getNodeAreaHeight(a),h=o?l-a.height-(o?a.expandBtnSize:0):0;h-=o?r:0;let d=n+h,c=a.left;a.top+=d,a.left=e.left+e.width*t.indent+(l+s)/Math.tan(un(t.mindMap.opt.fishboneDeg)),n+=h,s+=l,t.updateChildrenPro(a.children,{top:d,left:a.left-c})})}}}}});var zp,Rp,Jv=T(()=>{Ar();pe();Ge();Qv();wt();ih();zp=class extends Nt{constructor(e={},t){super(e),this.layout=t,this.indent=.3,this.childIndent=.5,this.fishTail=null,this.maxx=0,this.headRatio=1,this.tailRatio=.6,this.paddingXRatio=.3,this.fishHeadPathStr="M4,181 C4,181, 0,177, 4,173 Q 96.09523809523809,0, 288.2857142857143,0 L 288.2857142857143,354 Q 48.047619047619044,354, 8,218.18367346938777 C8,218.18367346938777, 6,214.18367346938777, 8,214.18367346938777 L 41.183673469387756,214.18367346938777 Z",this.fishTailPathStr="M 606.9342905223708 0 Q 713.1342905223709 -177 819.3342905223708 -177 L 766.2342905223709 0 L 819.3342905223708 177 Q 713.1342905223709 177 606.9342905223708 0 z",this.bindEvent(),this.extendShape(),this.beforeChange=this.beforeChange.bind(this)}nodeIsRemoveAllLines(e){return e.isRoot||e.layerIndex===1}isFishbone2(){return this.layout===C.LAYOUT.FISHBONE2}bindEvent(){this.isFishbone2()&&(this.onCheckUpdateFishTail=this.onCheckUpdateFishTail.bind(this),this.mindMap.on("afterExecCommand",this.onCheckUpdateFishTail))}unBindEvent(){this.mindMap.off("afterExecCommand",this.onCheckUpdateFishTail)}extendShape(){this.isFishbone2()&&this.mindMap.addShape({name:"fishHead",createShape:e=>{let t=ke(``),{width:r,height:n}=e.shapeInstance.getNodeSize();return t.size(r,n),t},getPadding:({width:e,height:t,paddingX:r,paddingY:n})=>{e+=r*2,t+=n*2;let s=this.paddingXRatio*e,a=0;return e+=s*2,a=(e/this.headRatio-t)/2,{paddingX:s,paddingY:a}}})}doLayout(e){Jt([()=>{this.computedBaseValue(),this.addFishTail()},()=>{this.computedLeftTopValue()},()=>{this.adjustLeftTopValue(),this.updateFishTailPosition()},()=>{e(this.root)}])}addFishTail(){if(!this.isFishbone2())return;let e=this.mindMap.lineDraw.findOne(".smm-layout-fishbone-tail");e?this.fishTail=e:(this.fishTail=ke(``),this.fishTail.addClass("smm-layout-fishbone-tail"));let t=this.root.height,r=t*this.tailRatio;this.fishTail.size(r,t),this.styleFishTail(),this.mindMap.lineDraw.add(this.fishTail)}onCheckUpdateFishTail(e,t,r){if(e==="SET_NODE_DATA"){let n=!1;Object.keys(r).forEach(s=>{zu.includes(s)&&(n=!0)}),n&&this.styleFishTail()}}styleFishTail(){this.root.style.shape(this.fishTail)}removeFishTail(){let e=this.mindMap.lineDraw.findOne(".smm-layout-fishbone-tail");e&&e.remove()}updateFishTailPosition(){this.isFishbone2()&&this.fishTail.x(this.maxx).cy(this.root.top+this.root.height/2)}computedBaseValue(){ue(this.renderer.renderTree,null,(e,t,r,n,s,a)=>{r&&this.isFishbone2()&&(e.data.shape="fishHead");let o=this.createNode(e,t,r,n,s,a);if(r)this.setNodeCenter(o);else if(t._node.dir?o.dir=t._node.dir:o.dir=s%2===0?C.LAYOUT_GROW_DIR.TOP:C.LAYOUT_GROW_DIR.BOTTOM,t._node.isRoot){let l=this.getMarginY(n),h=this.isFishbone2()?t._node.height/4:0;this.checkIsTop(o)?o.top=t._node.top-o.height-l+h:o.top=t._node.top+t._node.height+l-h}if(!e.data.expand)return!0},null,!0,0)}computedLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(e.isRoot){let a=this.getMarginX(n+1),o=this.isFishbone2()?2:1,l=e.left+e.width+e.height/o+a,h=e.left+e.width+e.height/o+a;e.children.forEach(d=>{this.checkIsTop(d)?(d.left=l,l+=d.width+a):(d.left=h+20,h+=d.width+a)})}let s={layerIndex:n,node:e,ctx:this};this.checkIsTop(e)?Ji.top.computedLeftTopValue(s):Ji.bottom.computedLeftTopValue(s)},null,!0)}adjustLeftTopValue(){ue(this.root,null,(e,t,r,n)=>{if(!e.getData("expand"))return;let s={node:e,parent:t,layerIndex:n,ctx:this};this.checkIsTop(e)?Ji.top.adjustLeftTopValueBefore(s):Ji.bottom.adjustLeftTopValueBefore(s)},(e,t)=>{let r={parent:t,node:e,ctx:this};if(this.checkIsTop(e)?Ji.top.adjustLeftTopValueAfter(r):Ji.bottom.adjustLeftTopValueAfter(r),e.isRoot){let n=0,s=0,a=-1/0;e.children.forEach(o=>{if(this.checkIsTop(o)){o.left+=n,this.updateChildren(o.children,"left",n);let{left:l,right:h}=this.getNodeBoundaries(o,"h");h>a&&(a=h),n+=h-l}else{o.left+=s,this.updateChildren(o.children,"left",s);let{left:l,right:h}=this.getNodeBoundaries(o,"h");h>a&&(a=h),s+=h-l}}),this.maxx=a}},!0)}getNodeAreaHeight(e){let t=0,r=n=>{let s=this.getMarginY(n.layerIndex);t+=n.height+(this.getNodeActChildrenLength(n)>0?n.expandBtnSize:0)+s,n.children.length&&n.children.forEach(a=>{r(a)})};return r(e),t}updateBrothersLeft(e){let t=e.children,r=0;t.forEach(n=>{n.left+=r,n.children&&n.children.length&&this.updateChildren(n.children,"left",r);let{left:s,right:a}=this.getNodeBoundaries(n,"h"),l=a-s-n.width;l>0&&(r+=l)})}updateBrothersTop(e,t){if(e.parent&&!e.parent.isRoot){let r=e.parent.children,n=ze(e,r);r.forEach((s,a)=>{if(s.hasCustomPosition())return;let o=0;a>n&&(o=t),s.top+=o,s.children&&s.children.length&&this.updateChildren(s.children,"top",o)}),this.checkIsTop(e)?this.updateBrothersTop(e.parent,t):this.updateBrothersTop(e.parent,e.layerIndex===3?0:t)}}checkIsTop(e){return e.dir===C.LAYOUT_GROW_DIR.TOP}renderLine(e,t,r){if(e.layerIndex!==1&&e.children.length<=0)return[];let{top:n,height:s,expandBtnSize:a}=e,{alwaysShowExpandBtn:o,notShowExpandBtn:l}=this.mindMap.opt;(!o||l)&&(a=0);let h=e.children.length;if(e.isRoot){let d=-1/0;e.children.forEach(x=>{x.left>d&&(d=x.left);let y=this.getMarginY(x.layerIndex),b=x.left,E=e.height/2+y-(this.isFishbone2()?e.height/4:0),k=E/Math.tan(un(this.mindMap.opt.fishboneDeg)),L=this.lineDraw.path();this.checkIsTop(x)?L.plot(this.transformPath(`M ${b-k},${x.top+x.height+E} L ${x.left},${x.top+x.height}`)):L.plot(this.transformPath(`M ${b-k},${x.top-E} L ${b},${x.top}`)),e.style.line(L),e._lines.push(L),r&&r(L,e)});let c=e.top+e.height/2,f=e.height/2+this.getMarginY(e.layerIndex+1),m=this.lineDraw.path(),g=this.isFishbone2()?this.maxx:d-f/Math.tan(un(this.mindMap.opt.fishboneDeg));m.plot(this.transformPath(`M ${e.left+e.width},${c} L ${g},${c}`)),e.style.line(m),e._lines.push(m),r&&r(m,e)}else{let d=-1/0,c=1/0,f=-1/0,m=e.left+e.width*this.indent;if(e.children.forEach((g,x)=>{g.left>f&&(f=g.left);let y=g.top+g.height/2;if(y>d&&(d=y),y1){let b=`M ${m},${y} L ${g.left},${y}`;this.setLineStyle(r,t[x],b,g)}}),h>=0){let g=this.lineDraw.path();a=h>0?a:0;let x=f-e.left-e.width*this.indent;x=Math.max(x,0);let y={node:e,line:g,top:n,x:m,lineLength:x,height:s,expandBtnSize:a,maxy:d,miny:c,ctx:this};this.checkIsTop(e)?Ji.top.renderLine(y):Ji.bottom.renderLine(y),e.style.line(g),e._lines.push(g),r&&r(g,e)}}}renderExpandBtn(e,t){let{width:r,height:n,expandBtnSize:s,isRoot:a}=e;if(!a){let{translateX:o,translateY:l}=t.transform(),h={node:e,btn:t,expandBtnSize:s,translateX:o,translateY:l,width:r,height:n};this.checkIsTop(e)?Ji.top.renderExpandBtn(h):Ji.bottom.renderExpandBtn(h)}}renderGeneralization(e){e.forEach(t=>{let{top:r,bottom:n,right:s,generalizationLineMargin:a,generalizationNodeMargin:o}=this.getNodeGeneralizationRenderBoundaries(t,"h"),l=s+a,h=r,d=s+a,c=n,f=l+20,m=h+(c-h)/2,g=`M ${l},${h} Q ${f},${m} ${d},${c}`;t.generalizationLine.plot(this.transformPath(g)),t.generalizationNode.left=s+o,t.generalizationNode.top=r+(n-r-t.generalizationNode.height)/2})}renderExpandBtnRect(e,t,r,n,s){let a="";s.dir===C.LAYOUT_GROW_DIR.TOP?a=s.layerIndex===1?C.LAYOUT_GROW_DIR.TOP:C.LAYOUT_GROW_DIR.BOTTOM:a=s.layerIndex===1?C.LAYOUT_GROW_DIR.BOTTOM:C.LAYOUT_GROW_DIR.TOP,a===C.LAYOUT_GROW_DIR.TOP?e.size(r,t).x(0).y(-t):e.size(r,t).x(0).y(n)}beforeChange(){this.isFishbone2()&&(this.root.nodeData.data.shape=C.SHAPE.RECTANGLE,this.removeFishTail(),this.unBindEvent(),this.mindMap.removeShape("fishHead"))}},Rp=zp});var eb,m0,tb=T(()=>{pe();Ge();eb="smm-node-edit-wrap",m0=class{constructor(e){this.renderer=e,this.mindMap=e.mindMap,this.currentNode=null,this.textEditNode=null,this.showTextEdit=!1,this.cacheEditingText="",this.hasBodyMousedown=!1,this.textNodePaddingX=5,this.textNodePaddingY=3,this.isNeedUpdateTextEditNode=!1,this.mindMap.addEditNodeClass(eb),this.bindEvent()}bindEvent(){this.show=this.show.bind(this),this.onScale=this.onScale.bind(this),this.onKeydown=this.onKeydown.bind(this),this.mindMap.on("node_dblclick",(e,t,r)=>{this.show({node:e,e:t,isInserting:r})}),this.mindMap.on("draw_click",()=>{this.hideEditTextBox()}),this.mindMap.on("body_mousedown",()=>{this.hasBodyMousedown=!0}),this.mindMap.on("body_click",()=>{this.hasBodyMousedown&&(this.hasBodyMousedown=!1,this.mindMap.opt.isEndNodeTextEditOnClickOuter&&this.hideEditTextBox())}),this.mindMap.on("svg_mousedown",()=>{this.hideEditTextBox()}),this.mindMap.on("expand_btn_click",()=>{this.hideEditTextBox()}),this.mindMap.on("before_node_active",()=>{this.hideEditTextBox()}),this.mindMap.on("mousewheel",()=>{this.mindMap.opt.mousewheelAction===C.MOUSE_WHEEL_ACTION.MOVE&&this.hideEditTextBox()}),this.mindMap.keyCommand.addShortcut("F2",()=>{this.renderer.activeNodeList.length<=0||this.show({node:this.renderer.activeNodeList[0]})}),this.mindMap.on("scale",this.onScale),this.mindMap.opt.enableAutoEnterTextEditWhenKeydown&&window.addEventListener("keydown",this.onKeydown),this.mindMap.on("beforeDestroy",()=>{this.unBindEvent()}),this.mindMap.on("after_update_config",(e,t)=>{e.openRealtimeRenderOnNodeTextEdit!==t.openRealtimeRenderOnNodeTextEdit&&(this.mindMap.richText?this.mindMap.richText.onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e.openRealtimeRenderOnNodeTextEdit):this.onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e.openRealtimeRenderOnNodeTextEdit)),e.enableAutoEnterTextEditWhenKeydown!==t.enableAutoEnterTextEditWhenKeydown&&window[e.enableAutoEnterTextEditWhenKeydown?"addEventListener":"removeEventListener"]("keydown",this.onKeydown)}),this.mindMap.on("afterExecCommand",()=>{this.isShowTextEdit()&&(this.isNeedUpdateTextEditNode=!0)}),this.mindMap.on("node_tree_render_end",()=>{this.isShowTextEdit()&&this.isNeedUpdateTextEditNode&&(this.isNeedUpdateTextEditNode=!1,this.updateTextEditNode())})}unBindEvent(){window.removeEventListener("keydown",this.onKeydown)}onKeydown(e){if(e.target!==document.body)return;let t=this.mindMap.renderer.activeNodeList;if(t.length<=0||t.length>1)return;let r=t[0];r&&this.checkIsAutoEnterTextEditKey(e)&&(e.preventDefault(),this.show({node:r,e,isInserting:!1,isFromKeyDown:!0}))}checkIsAutoEnterTextEditKey(e){let t=e.keyCode;return(t===229||t>=65&&t<=90||t>=48&&t<=57)&&!this.mindMap.keyCommand.hasCombinationKey(e)}registerTmpShortcut(){this.mindMap.keyCommand.addShortcut("Enter",()=>{this.hideEditTextBox()}),this.mindMap.keyCommand.addShortcut("Tab",()=>{this.hideEditTextBox()})}isShowTextEdit(){return this.mindMap.richText?this.mindMap.richText.showTextEdit:this.showTextEdit}setIsShowTextEdit(e){this.showTextEdit=e,e?this.mindMap.keyCommand.stopCheckInSvg():this.mindMap.keyCommand.recoveryCheckInSvg()}async show({node:e,isInserting:t=!1,isFromKeyDown:r=!1,isFromScale:n=!1}){if(e.isUseCustomNodeContent())return;this.getCurrentEditNode()&&this.hideEditTextBox();let{beforeTextEdit:a,openRealtimeRenderOnNodeTextEdit:o}=this.mindMap.opt;if(typeof a=="function"){let m=!1;try{m=await a(e,t)}catch(g){m=!1,this.mindMap.opt.errorHandler(Ti.BEFORE_TEXT_EDIT_ERROR,g)}if(!m)return}let{offsetLeft:l,offsetTop:h}=I2(this.mindMap,e);this.mindMap.view.translateXY(l,h);let d=e._textData.node;o&&d.show();let c=d.node.getBoundingClientRect();o&&d.hide();let f={node:e,rect:c,isInserting:t,isFromKeyDown:r,isFromScale:n};if(this.mindMap.richText){this.mindMap.richText.showEditText(f);return}this.currentNode=e,this.showEditTextBox(f)}onOpenRealtimeRenderOnNodeTextEditConfigUpdate(e){this.textEditNode&&(this.textEditNode.style.background=e?"transparent":this.currentNode?this.getBackground(this.currentNode):"",this.textEditNode.style.boxShadow=e?"none":"0 0 20px rgba(0,0,0,.5)")}onScale(){let e=this.getCurrentEditNode();e&&(this.mindMap.richText?(this.mindMap.richText.cacheEditingText=this.mindMap.richText.getEditText(),this.mindMap.richText.showTextEdit=!1):(this.cacheEditingText=this.getEditText(),this.setIsShowTextEdit(!1)),this.show({node:e,isFromScale:!0}))}showEditTextBox({node:e,rect:t,isInserting:r,isFromKeyDown:n,isFromScale:s}){if(this.showTextEdit)return;let{nodeTextEditZIndex:a,textAutoWrapWidth:o,selectTextOnEnterEditText:l,openRealtimeRenderOnNodeTextEdit:h,autoEmptyTextWhenKeydownEnterEdit:d}=this.mindMap.opt;s||this.mindMap.emit("before_show_text_edit"),this.registerTmpShortcut(),this.textEditNode||(this.textEditNode=document.createElement("div"),this.textEditNode.classList.add(eb),this.textEditNode.style.cssText=` position: fixed; box-sizing: border-box; ${h?"":"box-shadow: 0 0 20px rgba(0,0,0,.5);"} @@ -1483,16 +1483,16 @@ body { outline: none; word-break: break-all; line-break: anywhere; - `,this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("click",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("mousedown",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("keydown",y=>{this.checkIsAutoEnterTextEditKey(y)&&y.stopPropagation()}),this.textEditNode.addEventListener("paste",y=>{let b=y.clipboardData.getData("text"),{isSmm:S,data:A}=Po(b);S&&A[0]&&A[0].data?yu(y,sa(A[0].data.text)):yu(y),this.emitTextChangeEvent()}),this.textEditNode.addEventListener("input",()=>{this.emitTextChangeEvent()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let c=this.mindMap.view.scale,f=e.style.merge("fontSize"),m=(this.cacheEditingText||e.getData("text")).split(/\n/gim).map(x=>mn(x)),g=e._textData.node.attr("data-ismultiLine")==="true";e.style.domText(this.textEditNode,c),h||(this.textEditNode.style.background=this.getBackground(e)),this.textEditNode.style.zIndex=a,n&&d?this.textEditNode.innerHTML="":this.textEditNode.innerHTML=m.join("
    "),this.textEditNode.style.minWidth=t.width+this.textNodePaddingX*2+"px",this.textEditNode.style.minHeight=t.height+"px",this.textEditNode.style.left=Math.floor(t.left)+"px",this.textEditNode.style.top=Math.floor(t.top)+"px",this.textEditNode.style.display="block",this.textEditNode.style.maxWidth=o*c+"px",g?(this.textEditNode.style.lineHeight=js,this.textEditNode.style.transform=`translateY(${(js-1)*f/2*c}px)`):this.textEditNode.style.lineHeight="normal",this.setIsShowTextEdit(!0),r||l&&!n?la(this.textEditNode):oa(this.textEditNode),this.cacheEditingText=""}emitTextChangeEvent(){this.mindMap.emit("node_text_edit_change",{node:this.currentNode,text:this.getEditText(),richText:!1})}updateTextEditNode(){if(this.mindMap.richText){this.mindMap.richText.updateTextEditNode();return}if(!this.showTextEdit||!this.currentNode)return;let e=this.currentNode._textData.node.node.getBoundingClientRect();this.textEditNode.style.minWidth=e.width+this.textNodePaddingX*2+"px",this.textEditNode.style.minHeight=e.height+this.textNodePaddingY*2+"px",this.textEditNode.style.left=Math.floor(e.left)+"px",this.textEditNode.style.top=Math.floor(e.top)+"px"}getBackground(e){if(e.style.merge("gradientStyle")){let r=e.style.merge("startColor"),n=e.style.merge("endColor");return`linear-gradient(to right, ${r}, ${n})`}else{let r=e.style.merge("fillColor"),n=e.style.merge("color");return r==="transparent"?Oo(n)?$0(this.mindMap.themeConfig):"#fff":r}}removeTextEditEl(){if(this.mindMap.richText){this.mindMap.richText.removeTextEditEl();return}if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}getEditText(){return na(this.textEditNode.innerHTML)}hideEditTextBox(){if(this.mindMap.richText)return this.mindMap.richText.hideEditText();if(!this.showTextEdit)return;let e=this.currentNode,t=this.getEditText();this.currentNode=null,this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.textEditNode.style.fontFamily="inherit",this.textEditNode.style.fontSize="inherit",this.textEditNode.style.fontWeight="normal",this.textEditNode.style.transform="translateY(0)",this.setIsShowTextEdit(!1),this.mindMap.execCommand("SET_NODE_TEXT",e,t),this.mindMap.render(),this.mindMap.emit("hide_text_edit",this.textEditNode,this.renderer.activeNodeList,e)}getCurrentEditNode(){return this.mindMap.richText?this.mindMap.richText.node:this.currentNode}}});var $v,Uv,Np,jv,Gv=T(()=>{$v=pt(O0());Cv();Lv();zv();Dv();Ov();Bv();Fv();Hv();pe();Tu();Ro();$e();yt();Uv={[k.LAYOUT.LOGICAL_STRUCTURE]:pp,[k.LAYOUT.LOGICAL_STRUCTURE_LEFT]:pp,[k.LAYOUT.MIND_MAP]:_v,[k.LAYOUT.CATALOG_ORGANIZATION]:Iv,[k.LAYOUT.ORGANIZATION_STRUCTURE]:Rv,[k.LAYOUT.TIMELINE]:bp,[k.LAYOUT.TIMELINE2]:bp,[k.LAYOUT.VERTICAL_TIMELINE]:Mc,[k.LAYOUT.VERTICAL_TIMELINE2]:Mc,[k.LAYOUT.VERTICAL_TIMELINE3]:Mc,[k.LAYOUT.FISHBONE]:Tp,[k.LAYOUT.FISHBONE2]:Tp},Np=class{constructor(e={}){this.opt=e,this.mindMap=e.mindMap,this.themeConfig=this.mindMap.themeConfig,this.renderTree=this.mindMap.opt.data?(0,$v.default)({},this.mindMap.opt.data):null,this.reRender=!1,this.isRendering=!1,this.hasWaitRendering=!1,this.nodeCache={},this.lastNodeCache={},this.renderSourceList=[],this.renderCallbackList=[],this.activeNodeList=[],this.emitNodeActiveEventTimer=null,this.renderTimer=null,this.root=null,this.textEdit=new l0(this),this.beingCopyData=null,this.highlightBoxNode=null,this.highlightBoxNodeStyle=null,this.lastActiveNodeList=[],this.setLayout(),this.bindEvent(),this.registerCommands(),this.registerShortcutKeys()}setLayout(){this.layout&&this.layout.beforeChange&&this.layout.beforeChange();let{layout:e}=this.mindMap.opt,t=Uv[e]||this.mindMap[e];t||(t=Uv[k.LAYOUT.LOGICAL_STRUCTURE],this.mindMap.opt.layout=k.LAYOUT.LOGICAL_STRUCTURE),this.layout=new t(this,e)}setData(e){this.renderTree=e||null}bindEvent(){let{openPerformance:e,performanceConfig:t,openRealtimeRenderOnNodeTextEdit:r}=this.mindMap.opt;this.mindMap.on("draw_click",s=>{this.clearActiveNodeListOnDrawClick(s,"click")}),this.mindMap.on("contextmenu",s=>{this.clearActiveNodeListOnDrawClick(s,"contextmenu")}),this.mindMap.svg.on("dblclick",()=>{this.mindMap.opt.enableDblclickBackToRootNode&&this.setRootNodeCenter()});let n=Si(()=>{this.renderTree&&this.root&&(this.mindMap.emit("node_tree_render_start"),this.root.render(()=>{this.mindMap.emit("node_tree_render_end")},!1,!0))},t.time);e&&this.mindMap.on("view_data_change",n),this.onNodeTextEditChange=p2(this.onNodeTextEditChange,100,this),r&&this.mindMap.on("node_text_edit_change",this.onNodeTextEditChange),this.mindMap.on("after_update_config",(s,a)=>{s.openPerformance!==a.openPerformance&&(this.mindMap[s.openPerformance?"on":"off"]("view_data_change",n),this.forceLoadNode()),s.openRealtimeRenderOnNodeTextEdit!==a.openRealtimeRenderOnNodeTextEdit&&this.mindMap[s.openRealtimeRenderOnNodeTextEdit?"on":"off"]("node_text_edit_change",this.onNodeTextEditChange)})}onNodeTextEditChange({node:e,text:t}){e._textData=e.createTextNode(t);let{width:r,height:n}=e.getNodeRect();e.width=r,e.height=n,e.layout(),this.mindMap.render(()=>{this.textEdit.updateTextEditNode()})}forceLoadNode(e){e=e||this.root,e&&(this.mindMap.emit("node_tree_render_start"),e.render(()=>{this.mindMap.emit("node_tree_render_end")},!0))}registerCommands(){this.selectAll=this.selectAll.bind(this),this.mindMap.command.add("SELECT_ALL",this.selectAll),this.back=this.back.bind(this),this.mindMap.command.add("BACK",this.back),this.forward=this.forward.bind(this),this.mindMap.command.add("FORWARD",this.forward),this.insertNode=this.insertNode.bind(this),this.mindMap.command.add("INSERT_NODE",this.insertNode),this.insertMultiNode=this.insertMultiNode.bind(this),this.mindMap.command.add("INSERT_MULTI_NODE",this.insertMultiNode),this.insertChildNode=this.insertChildNode.bind(this),this.mindMap.command.add("INSERT_CHILD_NODE",this.insertChildNode),this.insertMultiChildNode=this.insertMultiChildNode.bind(this),this.mindMap.command.add("INSERT_MULTI_CHILD_NODE",this.insertMultiChildNode),this.insertParentNode=this.insertParentNode.bind(this),this.mindMap.command.add("INSERT_PARENT_NODE",this.insertParentNode),this.upNode=this.upNode.bind(this),this.mindMap.command.add("UP_NODE",this.upNode),this.downNode=this.downNode.bind(this),this.mindMap.command.add("DOWN_NODE",this.downNode),this.moveUpOneLevel=this.moveUpOneLevel.bind(this),this.mindMap.command.add("MOVE_UP_ONE_LEVEL",this.moveUpOneLevel),this.insertAfter=this.insertAfter.bind(this),this.mindMap.command.add("INSERT_AFTER",this.insertAfter),this.insertBefore=this.insertBefore.bind(this),this.mindMap.command.add("INSERT_BEFORE",this.insertBefore),this.moveNodeTo=this.moveNodeTo.bind(this),this.mindMap.command.add("MOVE_NODE_TO",this.moveNodeTo),this.removeNode=this.removeNode.bind(this),this.mindMap.command.add("REMOVE_NODE",this.removeNode),this.removeCurrentNode=this.removeCurrentNode.bind(this),this.mindMap.command.add("REMOVE_CURRENT_NODE",this.removeCurrentNode),this.pasteNode=this.pasteNode.bind(this),this.mindMap.command.add("PASTE_NODE",this.pasteNode),this.cutNode=this.cutNode.bind(this),this.mindMap.command.add("CUT_NODE",this.cutNode),this.setNodeStyle=this.setNodeStyle.bind(this),this.mindMap.command.add("SET_NODE_STYLE",this.setNodeStyle),this.setNodeStyles=this.setNodeStyles.bind(this),this.mindMap.command.add("SET_NODE_STYLES",this.setNodeStyles),this.setNodeActive=this.setNodeActive.bind(this),this.mindMap.command.add("SET_NODE_ACTIVE",this.setNodeActive),this.clearActiveNode=this.clearActiveNode.bind(this),this.mindMap.command.add("CLEAR_ACTIVE_NODE",this.clearActiveNode),this.setNodeExpand=this.setNodeExpand.bind(this),this.mindMap.command.add("SET_NODE_EXPAND",this.setNodeExpand),this.expandAllNode=this.expandAllNode.bind(this),this.mindMap.command.add("EXPAND_ALL",this.expandAllNode),this.unexpandAllNode=this.unexpandAllNode.bind(this),this.mindMap.command.add("UNEXPAND_ALL",this.unexpandAllNode),this.expandToLevel=this.expandToLevel.bind(this),this.mindMap.command.add("UNEXPAND_TO_LEVEL",this.expandToLevel),this.setNodeData=this.setNodeData.bind(this),this.mindMap.command.add("SET_NODE_DATA",this.setNodeData),this.setNodeText=this.setNodeText.bind(this),this.mindMap.command.add("SET_NODE_TEXT",this.setNodeText),this.setNodeImage=this.setNodeImage.bind(this),this.mindMap.command.add("SET_NODE_IMAGE",this.setNodeImage),this.setNodeIcon=this.setNodeIcon.bind(this),this.mindMap.command.add("SET_NODE_ICON",this.setNodeIcon),this.setNodeHyperlink=this.setNodeHyperlink.bind(this),this.mindMap.command.add("SET_NODE_HYPERLINK",this.setNodeHyperlink),this.setNodeNote=this.setNodeNote.bind(this),this.mindMap.command.add("SET_NODE_NOTE",this.setNodeNote),this.setNodeAttachment=this.setNodeAttachment.bind(this),this.mindMap.command.add("SET_NODE_ATTACHMENT",this.setNodeAttachment),this.setNodeTag=this.setNodeTag.bind(this),this.mindMap.command.add("SET_NODE_TAG",this.setNodeTag),this.insertFormula=this.insertFormula.bind(this),this.mindMap.command.add("INSERT_FORMULA",this.insertFormula),this.addGeneralization=this.addGeneralization.bind(this),this.mindMap.command.add("ADD_GENERALIZATION",this.addGeneralization),this.removeGeneralization=this.removeGeneralization.bind(this),this.mindMap.command.add("REMOVE_GENERALIZATION",this.removeGeneralization),this.setNodeCustomPosition=this.setNodeCustomPosition.bind(this),this.mindMap.command.add("SET_NODE_CUSTOM_POSITION",this.setNodeCustomPosition),this.resetLayout=this.resetLayout.bind(this),this.mindMap.command.add("RESET_LAYOUT",this.resetLayout),this.setNodeShape=this.setNodeShape.bind(this),this.mindMap.command.add("SET_NODE_SHAPE",this.setNodeShape),this.goTargetNode=this.goTargetNode.bind(this),this.mindMap.command.add("GO_TARGET_NODE",this.goTargetNode),this.removeCustomStyles=this.removeCustomStyles.bind(this),this.mindMap.command.add("REMOVE_CUSTOM_STYLES",this.removeCustomStyles),this.removeAllNodeCustomStyles=this.removeAllNodeCustomStyles.bind(this),this.mindMap.command.add("REMOVE_ALL_NODE_CUSTOM_STYLES",this.removeAllNodeCustomStyles)}registerShortcutKeys(){this.mindMap.keyCommand.addShortcut("Tab",()=>{this.mindMap.execCommand("INSERT_CHILD_NODE")}),this.mindMap.keyCommand.addShortcut("Insert",()=>{this.mindMap.execCommand("INSERT_CHILD_NODE")}),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.mindMap.execCommand("INSERT_NODE")}),this.mindMap.keyCommand.addShortcut("Shift+Tab",()=>{this.mindMap.execCommand("INSERT_PARENT_NODE")}),this.mindMap.keyCommand.addShortcut("Control+g",()=>{this.mindMap.execCommand("ADD_GENERALIZATION")}),this.toggleActiveExpand=this.toggleActiveExpand.bind(this),this.mindMap.keyCommand.addShortcut("/",this.toggleActiveExpand),this.mindMap.keyCommand.addShortcut("Del|Backspace",()=>{this.mindMap.execCommand("REMOVE_NODE")}),this.mindMap.keyCommand.addShortcut("Shift+Backspace",()=>{this.mindMap.execCommand("REMOVE_CURRENT_NODE")}),this.mindMap.on("before_show_text_edit",()=>{this.startTextEdit()}),this.mindMap.on("hide_text_edit",()=>{this.endTextEdit()}),this.mindMap.keyCommand.addShortcut("Control+a",()=>{this.mindMap.execCommand("SELECT_ALL")}),this.mindMap.keyCommand.addShortcut("Control+l",()=>{this.mindMap.execCommand("RESET_LAYOUT")}),this.mindMap.keyCommand.addShortcut("Control+Up",()=>{this.mindMap.execCommand("UP_NODE")}),this.mindMap.keyCommand.addShortcut("Control+Down",()=>{this.mindMap.execCommand("DOWN_NODE")}),this.mindMap.keyCommand.addShortcut("Control+c",()=>{this.copy()}),this.mindMap.keyCommand.addShortcut("Control+x",()=>{this.cut()}),this.mindMap.keyCommand.addShortcut("Control+v",()=>{this.paste()}),this.mindMap.keyCommand.addShortcut("Control+Enter",()=>{this.setRootNodeCenter()})}emitNodeActiveEvent(e=null,t=[...this.activeNodeList]){L2(this.lastActiveNodeList,t)||(this.lastActiveNodeList=[...t],clearTimeout(this.emitNodeActiveEventTimer),this.emitNodeActiveEventTimer=setTimeout(()=>{this.mindMap.emit("node_active",e,t)},0))}clearActiveNodeListOnDrawClick(e,t){if(this.activeNodeList.length<=0)return;let r=!0,{useLeftKeySelectionRightKeyDrag:n}=this.mindMap.opt;if(t==="contextmenu"?!n:n){let s=this.mindMap.event.mousedownPos;r=Math.abs(e.clientX-s.x)<=5&&Math.abs(e.clientY-s.y)<=5}r&&this.mindMap.execCommand("CLEAR_ACTIVE_NODE")}startTextEdit(){this.mindMap.keyCommand.save()}endTextEdit(){this.mindMap.keyCommand.restore()}clearCache(){this.layout.lru.clear(),this.nodeCache={},this.lastNodeCache={}}addRenderParams(e,t){e&&this.renderCallbackList.findIndex(n=>n===e)===-1&&this.renderCallbackList.push(e),t&&this.renderSourceList.findIndex(n=>n===t)===-1&&this.renderSourceList.push(t)}checkHasRenderSource(e){e=Array.isArray(e)?e:[e];for(let t=0;t{e()}),this.isRendering=!1,this.reRender=!1,this.renderCallbackList=[],this.renderSourceList=[],this.mindMap.emit("node_tree_render_end")}render(e,t){this.addRenderParams(e,t),clearTimeout(this.renderTimer),this.renderTimer=setTimeout(()=>{this._render()},0)}_render(){if(this.checkHasRenderSource(k.CHANGE_THEME)&&this.resetUnExpandNodeStyle(),this.isRendering){this.hasWaitRendering=!0;return}if(this.isRendering=!0,this.lastNodeCache=this.nodeCache,this.nodeCache={},this.reRender&&this.clearActiveNodeList(),!this.renderTree){this.onRenderEnd();return}this.mindMap.emit("node_tree_render_start"),this.root=null,this.layout.doLayout(e=>{Object.keys(this.lastNodeCache).forEach(t=>{this.nodeCache[t]||(this.removeNodeFromActiveList(this.lastNodeCache[t]),this.emitNodeActiveEvent(),this.lastNodeCache[t].destroy())}),this.root=e,this.root.render(()=>{if(this.isRendering=!1,this.hasWaitRendering){this.hasWaitRendering=!1,this.render();return}this.onRenderEnd()})}),this.emitNodeActiveEvent()}resetUnExpandNodeStyle(){this.renderTree&&de(this.renderTree,null,e=>{if(!e.data.expand)return de(e,null,t=>{t.data.needUpdate=!0}),!0})}clearActiveNode(){this.activeNodeList.length<=0||(this.clearActiveNodeList(),this.emitNodeActiveEvent(null,[]))}clearActiveNodeList(){this.activeNodeList.forEach(e=>{this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1)}),this.activeNodeList=[]}addNodeToActiveList(e,t=!1){if(this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate&&e.userList.length>0)return;this.findActiveNodeIndex(e)===-1&&(t||this.mindMap.emit("before_node_active",e,this.activeNodeList),this.mindMap.execCommand("SET_NODE_ACTIVE",e,!0),this.activeNodeList.push(e))}removeNodeFromActiveList(e){let t=this.findActiveNodeIndex(e);t!==-1&&(this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1),this.activeNodeList.splice(t,1))}activeMultiNode(e=[]){e.forEach(t=>{this.mindMap.emit("before_node_active",t,this.activeNodeList),this.addNodeToActiveList(t,!0),this.emitNodeActiveEvent(t)})}cancelActiveMultiNode(e=[]){e.forEach(t=>{this.removeNodeFromActiveList(t),this.emitNodeActiveEvent(null)})}findActiveNodeIndex(e){return Ie(e,this.activeNodeList)}selectAll(){this.mindMap.opt.readonly||(de(this.root,null,e=>{e.getData("isActive")||this.addNodeToActiveList(e),e._generalizationList&&e._generalizationList.length>0&&e._generalizationList.forEach(t=>{let r=t.generalizationNode;r.getData("isActive")||this.addNodeToActiveList(r)})},null,!0,0,0),this.emitNodeActiveEvent())}back(e){this.backForward("back",e)}forward(e){this.backForward("forward",e)}backForward(e,t){this.mindMap.execCommand("CLEAR_ACTIVE_NODE");let r=this.mindMap.command[e](t);r&&(this.renderTree=r,this.mindMap.render()),this.mindMap.emit("data_change",r)}getNewNodeBehavior(e=!1,t=!1){let{createNewNodeBehavior:r}=this.mindMap.opt,n=!1,s=!1;switch(r){case k.CREATE_NEW_NODE_BEHAVIOR.DEFAULT:n=t||!e,s=t?!1:e;break;case k.CREATE_NEW_NODE_BEHAVIOR.NOT_ACTIVE:n=!1,s=!1;break;case k.CREATE_NEW_NODE_BEHAVIOR.ACTIVE_ONLY:n=!0,s=!1;break;default:break}return{focusNewNode:n,inserting:s}}insertNode(e=!0,t=[],r=null,n=[]){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:s,defaultInsertBelowSecondLevelNodeText:a}=this.mindMap.opt,o=t.length>0?t:this.activeNodeList,l=o.length>1,h=this.hasRichTextPlugin(),{focusNewNode:d,inserting:c}=this.getNewNodeBehavior(e,l),f={expand:!0,richText:h,isActive:d};h&&(f.resetRichText=!0),n=Bo(n,f);let m=r&&r.richText,g=!1;o.forEach(x=>{if(x.isGeneralization||x.isRoot)return;n=Kt(n);let y=x.parent,S=x.layerIndex===1?s:a,A=ha(x);m&&f.resetRichText&&delete f.resetRichText;let C={inserting:c,data:{text:S,...f,uid:wt(),...r||{}},children:[...cs(n,g)]};g=!0,y.nodeData.children.splice(A+1,0,C)}),d&&this.clearActiveNodeList(),this.mindMap.render()}insertMultiNode(e,t){if(!t||t.length<=0||(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0))return;this.textEdit.hideEditTextBox();let r=e.length>0?e:this.activeNodeList,n=this.hasRichTextPlugin(),{focusNewNode:s}=this.getNewNodeBehavior(!1,!0),a={expand:!0,richText:n,isActive:s};n&&(a.resetRichText=!0),t=Bo(t,a);let o=!1;r.forEach(l=>{if(l.isGeneralization||l.isRoot)return;t=Kt(t);let h=l.parent,d=ha(l),c=cs(t,o);o=!0,h.nodeData.children.splice(d+1,0,...c)}),s&&this.clearActiveNodeList(),this.mindMap.render()}insertChildNode(e=!0,t=[],r=null,n=[]){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:s,defaultInsertBelowSecondLevelNodeText:a}=this.mindMap.opt,o=t.length>0?t:this.activeNodeList,l=o.length>1,h=this.hasRichTextPlugin(),{focusNewNode:d,inserting:c}=this.getNewNodeBehavior(e,l),f={expand:!0,richText:h,isActive:d};h&&(f.resetRichText=!0),n=Bo(n,f);let m=r&&r.richText,g=!1;o.forEach(x=>{if(x.isGeneralization)return;n=Kt(n),x.nodeData.children||(x.nodeData.children=[]);let y=x.isRoot?s:a;m&&f.resetRichText&&delete f.resetRichText;let b={inserting:c,data:{text:y,uid:wt(),...f,...r||{}},children:[...cs(n,g)]};g=!0,x.nodeData.children.push(b),x.setData({expand:!0})}),d&&this.clearActiveNodeList(),this.mindMap.render()}insertMultiChildNode(e,t){if(!t||t.length<=0||(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0))return;this.textEdit.hideEditTextBox();let r=e.length>0?e:this.activeNodeList,n=this.hasRichTextPlugin(),{focusNewNode:s}=this.getNewNodeBehavior(!1,!0),a={expand:!0,richText:n,isActive:s};n&&(a.resetRichText=!0),t=Bo(t,a);let o=!1;r.forEach(l=>{l.isGeneralization||(t=Kt(t),l.nodeData.children||(l.nodeData.children=[]),t=cs(t,o),o=!0,l.nodeData.children.push(...t),l.setData({expand:!0}))}),s&&this.clearActiveNodeList(),this.mindMap.render()}insertParentNode(e=!0,t,r){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:n,defaultInsertBelowSecondLevelNodeText:s}=this.mindMap.opt,a=t.length>0?t:this.activeNodeList,o=a.length>1,l=this.hasRichTextPlugin(),{focusNewNode:h,inserting:d}=this.getNewNodeBehavior(e,o),c={expand:!0,richText:l,isActive:h};l&&(c.resetRichText=!0);let f=r&&r.richText;a.forEach(m=>{if(m.isGeneralization||m.isRoot)return;let g=m.layerIndex===1?n:s;f&&c.resetRichText&&delete c.resetRichText;let x={inserting:d,data:{text:g,uid:wt(),...c,...r||{}},children:[m.nodeData]},y=m.parent,b=ha(m);y.nodeData.children.splice(b,1,x)}),h&&this.clearActiveNodeList(),this.mindMap.render()}upNode(e){if(this.activeNodeList.length<=0&&!e)return;let r=(e?[e]:this.activeNodeList)[0];if(r.isRoot)return;let n=r.parent,s=n.children,a=Ie(r,s);if(a===-1||a===0)return;let o=a-1;s.splice(a,1),s.splice(o,0,r),n.nodeData.children.splice(a,1),n.nodeData.children.splice(o,0,r.nodeData),this.mindMap.render()}downNode(e){if(this.activeNodeList.length<=0&&!e)return;let r=(e?[e]:this.activeNodeList)[0];if(r.isRoot)return;let n=r.parent,s=n.children,a=Ie(r,s);if(a===-1||a===s.length-1)return;let o=a+1;s.splice(a,1),s.splice(o,0,r),n.nodeData.children.splice(a,1),n.nodeData.children.splice(o,0,r.nodeData),this.mindMap.render()}moveUpOneLevel(e){if(e=e||this.activeNodeList[0],!e||e.isRoot||e.layerIndex<=1)return;let t=e.parent,r=t.parent,n=Ie(e,t.children),s=Ie(t,r.children);t.nodeData.children.splice(n,1),r.nodeData.children.splice(s+1,0,e.nodeData),this.mindMap.render()}_handleRemoveCustomStyles(e){let t=!1;return Object.keys(e).forEach(r=>{hs(r)&&(t=!0,delete e[r])}),this.hasRichTextPlugin()&&(t=!0,e.resetRichText=!0),t}removeCustomStyles(e){if(e=e||this.activeNodeList[0],!e)return;this._handleRemoveCustomStyles(e.getData())&&this.reRenderNodeCheckChange(e)}removeAllNodeCustomStyles(e){e=Ot(e);let t=!1;if(e.length>0)e.forEach(r=>{this._handleRemoveCustomStyles(r.getData())&&(t=!0)});else{if(!this.renderTree)return;de(this.renderTree,null,r=>{this._handleRemoveCustomStyles(r.data)&&(t=!0);let s=us(r.data);s.length>0&&s.forEach(a=>{this._handleRemoveCustomStyles(a)&&(t=!0)})})}t&&this.mindMap.reRender()}copy(){this.beingCopyData=this.copyNode(),this.beingCopyData&&(this.mindMap.opt.disabledClipboard||gu(xu(this.beingCopyData)))}cut(){this.mindMap.execCommand("CUT_NODE",e=>{this.beingCopyData=e,this.mindMap.opt.disabledClipboard||gu(xu(e))})}handlePaste(e){let{disabledClipboard:t}=this.mindMap.opt;if(t)return;let r=e.clipboardData||e.originalEvent.clipboardData,n=r.items,s=null,a="";Array.from(n).forEach(o=>{o.type.indexOf("image")>-1&&(s=o.getAsFile()),o.type.indexOf("text")>-1&&(a=r.getData("text"))}),this.paste()}async paste(){let{errorHandler:e,handleIsSplitByWrapOnPasteCreateNewNode:t,handleNodePasteImg:r,disabledClipboard:n,onlyPasteTextWhenHasImgAndText:s}=this.mindMap.opt;if(!n&&pu())try{let a=await C2(),o=a.text||"",l=a.img||null;if(o){let h=null,d=!0;if(this.mindMap.opt.customHandleClipboardText)try{let c=await this.mindMap.opt.customHandleClipboardText(o);if(!Yt(c)){d=!1;let f=Po(c);f.isSmm?h=f.data:o=f.data}}catch(c){e(Mi.CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR,c)}if(d){let c=Po(o);c.isSmm?h=c.data:o=c.data}if(h)this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],Array.isArray(h)?h:[h]);else{this.hasRichTextPlugin()&&(o=mn(o));let c=o.split(new RegExp(`\r? + `,this.textEditNode.setAttribute("contenteditable",!0),this.textEditNode.addEventListener("keyup",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("click",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("mousedown",y=>{y.stopPropagation()}),this.textEditNode.addEventListener("keydown",y=>{this.checkIsAutoEnterTextEditKey(y)&&y.stopPropagation()}),this.textEditNode.addEventListener("paste",y=>{let b=y.clipboardData.getData("text"),{isSmm:E,data:k}=jo(b);E&&k[0]&&k[0].data?Cu(y,aa(k[0].data.text)):Cu(y),this.emitTextChangeEvent()}),this.textEditNode.addEventListener("input",()=>{this.emitTextChangeEvent()}),(this.mindMap.opt.customInnerElsAppendTo||document.body).appendChild(this.textEditNode));let c=this.mindMap.view.scale,f=e.style.merge("fontSize"),m=(this.cacheEditingText||e.getData("text")).split(/\n/gim).map(x=>fn(x)),g=e._textData.node.attr("data-ismultiLine")==="true";e.style.domText(this.textEditNode,c),h||(this.textEditNode.style.background=this.getBackground(e)),this.textEditNode.style.zIndex=a,n&&d?this.textEditNode.innerHTML="":this.textEditNode.innerHTML=m.join("
    "),this.textEditNode.style.minWidth=t.width+this.textNodePaddingX*2+"px",this.textEditNode.style.minHeight=t.height+"px",this.textEditNode.style.left=Math.floor(t.left)+"px",this.textEditNode.style.top=Math.floor(t.top)+"px",this.textEditNode.style.display="block",this.textEditNode.style.maxWidth=o*c+"px",g?(this.textEditNode.style.lineHeight=Gs,this.textEditNode.style.transform=`translateY(${(Gs-1)*f/2*c}px)`):this.textEditNode.style.lineHeight="normal",this.setIsShowTextEdit(!0),r||l&&!n?ha(this.textEditNode):la(this.textEditNode),this.cacheEditingText=""}emitTextChangeEvent(){this.mindMap.emit("node_text_edit_change",{node:this.currentNode,text:this.getEditText(),richText:!1})}updateTextEditNode(){if(this.mindMap.richText){this.mindMap.richText.updateTextEditNode();return}if(!this.showTextEdit||!this.currentNode)return;let e=this.currentNode._textData.node.node.getBoundingClientRect();this.textEditNode.style.minWidth=e.width+this.textNodePaddingX*2+"px",this.textEditNode.style.minHeight=e.height+this.textNodePaddingY*2+"px",this.textEditNode.style.left=Math.floor(e.left)+"px",this.textEditNode.style.top=Math.floor(e.top)+"px"}getBackground(e){if(e.style.merge("gradientStyle")){let r=e.style.merge("startColor"),n=e.style.merge("endColor");return`linear-gradient(to right, ${r}, ${n})`}else{let r=e.style.merge("fillColor"),n=e.style.merge("color");return r==="transparent"?Uo(n)?Z0(this.mindMap.themeConfig):"#fff":r}}removeTextEditEl(){if(this.mindMap.richText){this.mindMap.richText.removeTextEditEl();return}if(!this.textEditNode)return;(this.mindMap.opt.customInnerElsAppendTo||document.body).removeChild(this.textEditNode)}getEditText(){return sa(this.textEditNode.innerHTML)}hideEditTextBox(){if(this.mindMap.richText)return this.mindMap.richText.hideEditText();if(!this.showTextEdit)return;let e=this.currentNode,t=this.getEditText();this.currentNode=null,this.textEditNode.style.display="none",this.textEditNode.innerHTML="",this.textEditNode.style.fontFamily="inherit",this.textEditNode.style.fontSize="inherit",this.textEditNode.style.fontWeight="normal",this.textEditNode.style.transform="translateY(0)",this.setIsShowTextEdit(!1),this.mindMap.execCommand("SET_NODE_TEXT",e,t),this.mindMap.render(),this.mindMap.emit("hide_text_edit",this.textEditNode,this.renderer.activeNodeList,e)}getCurrentEditNode(){return this.mindMap.richText?this.mindMap.richText.node:this.currentNode}}});var rb,ib,Dp,nb,sb=T(()=>{rb=yt(j0());$v();Gv();Vv();Xv();Kv();Zv();Jv();tb();pe();Ru();qo();Ge();wt();ib={[C.LAYOUT.LOGICAL_STRUCTURE]:Sp,[C.LAYOUT.LOGICAL_STRUCTURE_LEFT]:Sp,[C.LAYOUT.MIND_MAP]:jv,[C.LAYOUT.CATALOG_ORGANIZATION]:Wv,[C.LAYOUT.ORGANIZATION_STRUCTURE]:Yv,[C.LAYOUT.TIMELINE]:Lp,[C.LAYOUT.TIMELINE2]:Lp,[C.LAYOUT.VERTICAL_TIMELINE]:_c,[C.LAYOUT.VERTICAL_TIMELINE2]:_c,[C.LAYOUT.VERTICAL_TIMELINE3]:_c,[C.LAYOUT.FISHBONE]:Rp,[C.LAYOUT.FISHBONE2]:Rp},Dp=class{constructor(e={}){this.opt=e,this.mindMap=e.mindMap,this.themeConfig=this.mindMap.themeConfig,this.renderTree=this.mindMap.opt.data?(0,rb.default)({},this.mindMap.opt.data):null,this.reRender=!1,this.isRendering=!1,this.hasWaitRendering=!1,this.nodeCache={},this.lastNodeCache={},this.renderSourceList=[],this.renderCallbackList=[],this.activeNodeList=[],this.emitNodeActiveEventTimer=null,this.renderTimer=null,this.root=null,this.textEdit=new m0(this),this.beingCopyData=null,this.highlightBoxNode=null,this.highlightBoxNodeStyle=null,this.lastActiveNodeList=[],this.setLayout(),this.bindEvent(),this.registerCommands(),this.registerShortcutKeys()}setLayout(){this.layout&&this.layout.beforeChange&&this.layout.beforeChange();let{layout:e}=this.mindMap.opt,t=ib[e]||this.mindMap[e];t||(t=ib[C.LAYOUT.LOGICAL_STRUCTURE],this.mindMap.opt.layout=C.LAYOUT.LOGICAL_STRUCTURE),this.layout=new t(this,e)}setData(e){this.renderTree=e||null}bindEvent(){let{openPerformance:e,performanceConfig:t,openRealtimeRenderOnNodeTextEdit:r}=this.mindMap.opt;this.mindMap.on("draw_click",s=>{this.clearActiveNodeListOnDrawClick(s,"click")}),this.mindMap.on("contextmenu",s=>{this.clearActiveNodeListOnDrawClick(s,"contextmenu")}),this.mindMap.svg.on("dblclick",()=>{this.mindMap.opt.enableDblclickBackToRootNode&&this.setRootNodeCenter()});let n=Ai(()=>{this.renderTree&&this.root&&(this.mindMap.emit("node_tree_render_start"),this.root.render(()=>{this.mindMap.emit("node_tree_render_end")},!1,!0))},t.time);e&&this.mindMap.on("view_data_change",n),this.onNodeTextEditChange=C2(this.onNodeTextEditChange,100,this),r&&this.mindMap.on("node_text_edit_change",this.onNodeTextEditChange),this.mindMap.on("after_update_config",(s,a)=>{s.openPerformance!==a.openPerformance&&(this.mindMap[s.openPerformance?"on":"off"]("view_data_change",n),this.forceLoadNode()),s.openRealtimeRenderOnNodeTextEdit!==a.openRealtimeRenderOnNodeTextEdit&&this.mindMap[s.openRealtimeRenderOnNodeTextEdit?"on":"off"]("node_text_edit_change",this.onNodeTextEditChange)})}onNodeTextEditChange({node:e,text:t}){e._textData=e.createTextNode(t);let{width:r,height:n}=e.getNodeRect();e.width=r,e.height=n,e.layout(),this.mindMap.render(()=>{this.textEdit.updateTextEditNode()})}forceLoadNode(e){e=e||this.root,e&&(this.mindMap.emit("node_tree_render_start"),e.render(()=>{this.mindMap.emit("node_tree_render_end")},!0))}registerCommands(){this.selectAll=this.selectAll.bind(this),this.mindMap.command.add("SELECT_ALL",this.selectAll),this.back=this.back.bind(this),this.mindMap.command.add("BACK",this.back),this.forward=this.forward.bind(this),this.mindMap.command.add("FORWARD",this.forward),this.insertNode=this.insertNode.bind(this),this.mindMap.command.add("INSERT_NODE",this.insertNode),this.insertMultiNode=this.insertMultiNode.bind(this),this.mindMap.command.add("INSERT_MULTI_NODE",this.insertMultiNode),this.insertChildNode=this.insertChildNode.bind(this),this.mindMap.command.add("INSERT_CHILD_NODE",this.insertChildNode),this.insertMultiChildNode=this.insertMultiChildNode.bind(this),this.mindMap.command.add("INSERT_MULTI_CHILD_NODE",this.insertMultiChildNode),this.insertParentNode=this.insertParentNode.bind(this),this.mindMap.command.add("INSERT_PARENT_NODE",this.insertParentNode),this.upNode=this.upNode.bind(this),this.mindMap.command.add("UP_NODE",this.upNode),this.downNode=this.downNode.bind(this),this.mindMap.command.add("DOWN_NODE",this.downNode),this.moveUpOneLevel=this.moveUpOneLevel.bind(this),this.mindMap.command.add("MOVE_UP_ONE_LEVEL",this.moveUpOneLevel),this.insertAfter=this.insertAfter.bind(this),this.mindMap.command.add("INSERT_AFTER",this.insertAfter),this.insertBefore=this.insertBefore.bind(this),this.mindMap.command.add("INSERT_BEFORE",this.insertBefore),this.moveNodeTo=this.moveNodeTo.bind(this),this.mindMap.command.add("MOVE_NODE_TO",this.moveNodeTo),this.removeNode=this.removeNode.bind(this),this.mindMap.command.add("REMOVE_NODE",this.removeNode),this.removeCurrentNode=this.removeCurrentNode.bind(this),this.mindMap.command.add("REMOVE_CURRENT_NODE",this.removeCurrentNode),this.pasteNode=this.pasteNode.bind(this),this.mindMap.command.add("PASTE_NODE",this.pasteNode),this.cutNode=this.cutNode.bind(this),this.mindMap.command.add("CUT_NODE",this.cutNode),this.setNodeStyle=this.setNodeStyle.bind(this),this.mindMap.command.add("SET_NODE_STYLE",this.setNodeStyle),this.setNodeStyles=this.setNodeStyles.bind(this),this.mindMap.command.add("SET_NODE_STYLES",this.setNodeStyles),this.setNodeActive=this.setNodeActive.bind(this),this.mindMap.command.add("SET_NODE_ACTIVE",this.setNodeActive),this.clearActiveNode=this.clearActiveNode.bind(this),this.mindMap.command.add("CLEAR_ACTIVE_NODE",this.clearActiveNode),this.setNodeExpand=this.setNodeExpand.bind(this),this.mindMap.command.add("SET_NODE_EXPAND",this.setNodeExpand),this.expandAllNode=this.expandAllNode.bind(this),this.mindMap.command.add("EXPAND_ALL",this.expandAllNode),this.unexpandAllNode=this.unexpandAllNode.bind(this),this.mindMap.command.add("UNEXPAND_ALL",this.unexpandAllNode),this.expandToLevel=this.expandToLevel.bind(this),this.mindMap.command.add("UNEXPAND_TO_LEVEL",this.expandToLevel),this.setNodeData=this.setNodeData.bind(this),this.mindMap.command.add("SET_NODE_DATA",this.setNodeData),this.setNodeText=this.setNodeText.bind(this),this.mindMap.command.add("SET_NODE_TEXT",this.setNodeText),this.setNodeImage=this.setNodeImage.bind(this),this.mindMap.command.add("SET_NODE_IMAGE",this.setNodeImage),this.setNodeIcon=this.setNodeIcon.bind(this),this.mindMap.command.add("SET_NODE_ICON",this.setNodeIcon),this.setNodeHyperlink=this.setNodeHyperlink.bind(this),this.mindMap.command.add("SET_NODE_HYPERLINK",this.setNodeHyperlink),this.setNodeNote=this.setNodeNote.bind(this),this.mindMap.command.add("SET_NODE_NOTE",this.setNodeNote),this.setNodeAttachment=this.setNodeAttachment.bind(this),this.mindMap.command.add("SET_NODE_ATTACHMENT",this.setNodeAttachment),this.setNodeTag=this.setNodeTag.bind(this),this.mindMap.command.add("SET_NODE_TAG",this.setNodeTag),this.insertFormula=this.insertFormula.bind(this),this.mindMap.command.add("INSERT_FORMULA",this.insertFormula),this.addGeneralization=this.addGeneralization.bind(this),this.mindMap.command.add("ADD_GENERALIZATION",this.addGeneralization),this.removeGeneralization=this.removeGeneralization.bind(this),this.mindMap.command.add("REMOVE_GENERALIZATION",this.removeGeneralization),this.setNodeCustomPosition=this.setNodeCustomPosition.bind(this),this.mindMap.command.add("SET_NODE_CUSTOM_POSITION",this.setNodeCustomPosition),this.resetLayout=this.resetLayout.bind(this),this.mindMap.command.add("RESET_LAYOUT",this.resetLayout),this.setNodeShape=this.setNodeShape.bind(this),this.mindMap.command.add("SET_NODE_SHAPE",this.setNodeShape),this.goTargetNode=this.goTargetNode.bind(this),this.mindMap.command.add("GO_TARGET_NODE",this.goTargetNode),this.removeCustomStyles=this.removeCustomStyles.bind(this),this.mindMap.command.add("REMOVE_CUSTOM_STYLES",this.removeCustomStyles),this.removeAllNodeCustomStyles=this.removeAllNodeCustomStyles.bind(this),this.mindMap.command.add("REMOVE_ALL_NODE_CUSTOM_STYLES",this.removeAllNodeCustomStyles)}registerShortcutKeys(){this.mindMap.keyCommand.addShortcut("Tab",()=>{this.mindMap.execCommand("INSERT_CHILD_NODE")}),this.mindMap.keyCommand.addShortcut("Insert",()=>{this.mindMap.execCommand("INSERT_CHILD_NODE")}),this.mindMap.keyCommand.addShortcut("Enter",()=>{this.mindMap.execCommand("INSERT_NODE")}),this.mindMap.keyCommand.addShortcut("Shift+Tab",()=>{this.mindMap.execCommand("INSERT_PARENT_NODE")}),this.mindMap.keyCommand.addShortcut("Control+g",()=>{this.mindMap.execCommand("ADD_GENERALIZATION")}),this.toggleActiveExpand=this.toggleActiveExpand.bind(this),this.mindMap.keyCommand.addShortcut("/",this.toggleActiveExpand),this.mindMap.keyCommand.addShortcut("Del|Backspace",()=>{this.mindMap.execCommand("REMOVE_NODE")}),this.mindMap.keyCommand.addShortcut("Shift+Backspace",()=>{this.mindMap.execCommand("REMOVE_CURRENT_NODE")}),this.mindMap.on("before_show_text_edit",()=>{this.startTextEdit()}),this.mindMap.on("hide_text_edit",()=>{this.endTextEdit()}),this.mindMap.keyCommand.addShortcut("Control+a",()=>{this.mindMap.execCommand("SELECT_ALL")}),this.mindMap.keyCommand.addShortcut("Control+l",()=>{this.mindMap.execCommand("RESET_LAYOUT")}),this.mindMap.keyCommand.addShortcut("Control+Up",()=>{this.mindMap.execCommand("UP_NODE")}),this.mindMap.keyCommand.addShortcut("Control+Down",()=>{this.mindMap.execCommand("DOWN_NODE")}),this.mindMap.keyCommand.addShortcut("Control+c",()=>{this.copy()}),this.mindMap.keyCommand.addShortcut("Control+x",()=>{this.cut()}),this.mindMap.keyCommand.addShortcut("Control+v",()=>{this.paste()}),this.mindMap.keyCommand.addShortcut("Control+Enter",()=>{this.setRootNodeCenter()})}emitNodeActiveEvent(e=null,t=[...this.activeNodeList]){G2(this.lastActiveNodeList,t)||(this.lastActiveNodeList=[...t],clearTimeout(this.emitNodeActiveEventTimer),this.emitNodeActiveEventTimer=setTimeout(()=>{this.mindMap.emit("node_active",e,t)},0))}clearActiveNodeListOnDrawClick(e,t){if(this.activeNodeList.length<=0)return;let r=!0,{useLeftKeySelectionRightKeyDrag:n}=this.mindMap.opt;if(t==="contextmenu"?!n:n){let s=this.mindMap.event.mousedownPos;r=Math.abs(e.clientX-s.x)<=5&&Math.abs(e.clientY-s.y)<=5}r&&this.mindMap.execCommand("CLEAR_ACTIVE_NODE")}startTextEdit(){this.mindMap.keyCommand.save()}endTextEdit(){this.mindMap.keyCommand.restore()}clearCache(){this.layout.lru.clear(),this.nodeCache={},this.lastNodeCache={}}addRenderParams(e,t){e&&this.renderCallbackList.findIndex(n=>n===e)===-1&&this.renderCallbackList.push(e),t&&this.renderSourceList.findIndex(n=>n===t)===-1&&this.renderSourceList.push(t)}checkHasRenderSource(e){e=Array.isArray(e)?e:[e];for(let t=0;t{e()}),this.isRendering=!1,this.reRender=!1,this.renderCallbackList=[],this.renderSourceList=[],this.mindMap.emit("node_tree_render_end")}render(e,t){this.addRenderParams(e,t),clearTimeout(this.renderTimer),this.renderTimer=setTimeout(()=>{this._render()},0)}_render(){if(this.checkHasRenderSource(C.CHANGE_THEME)&&this.resetUnExpandNodeStyle(),this.isRendering){this.hasWaitRendering=!0;return}if(this.isRendering=!0,this.lastNodeCache=this.nodeCache,this.nodeCache={},this.reRender&&this.clearActiveNodeList(),!this.renderTree){this.onRenderEnd();return}this.mindMap.emit("node_tree_render_start"),this.root=null,this.layout.doLayout(e=>{Object.keys(this.lastNodeCache).forEach(t=>{this.nodeCache[t]||(this.removeNodeFromActiveList(this.lastNodeCache[t]),this.emitNodeActiveEvent(),this.lastNodeCache[t].destroy())}),this.root=e,this.root.render(()=>{if(this.isRendering=!1,this.hasWaitRendering){this.hasWaitRendering=!1,this.render();return}this.onRenderEnd()})}),this.emitNodeActiveEvent()}resetUnExpandNodeStyle(){this.renderTree&&ue(this.renderTree,null,e=>{if(!e.data.expand)return ue(e,null,t=>{t.data.needUpdate=!0}),!0})}clearActiveNode(){this.activeNodeList.length<=0||(this.clearActiveNodeList(),this.emitNodeActiveEvent(null,[]))}clearActiveNodeList(){this.activeNodeList.forEach(e=>{this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1)}),this.activeNodeList=[]}addNodeToActiveList(e,t=!1){if(this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate&&e.userList.length>0)return;this.findActiveNodeIndex(e)===-1&&(t||this.mindMap.emit("before_node_active",e,this.activeNodeList),this.mindMap.execCommand("SET_NODE_ACTIVE",e,!0),this.activeNodeList.push(e))}removeNodeFromActiveList(e){let t=this.findActiveNodeIndex(e);t!==-1&&(this.mindMap.execCommand("SET_NODE_ACTIVE",e,!1),this.activeNodeList.splice(t,1))}activeMultiNode(e=[]){e.forEach(t=>{this.mindMap.emit("before_node_active",t,this.activeNodeList),this.addNodeToActiveList(t,!0),this.emitNodeActiveEvent(t)})}cancelActiveMultiNode(e=[]){e.forEach(t=>{this.removeNodeFromActiveList(t),this.emitNodeActiveEvent(null)})}findActiveNodeIndex(e){return ze(e,this.activeNodeList)}selectAll(){this.mindMap.opt.readonly||(ue(this.root,null,e=>{e.getData("isActive")||this.addNodeToActiveList(e),e._generalizationList&&e._generalizationList.length>0&&e._generalizationList.forEach(t=>{let r=t.generalizationNode;r.getData("isActive")||this.addNodeToActiveList(r)})},null,!0,0,0),this.emitNodeActiveEvent())}back(e){this.backForward("back",e)}forward(e){this.backForward("forward",e)}backForward(e,t){this.mindMap.execCommand("CLEAR_ACTIVE_NODE");let r=this.mindMap.command[e](t);r&&(this.renderTree=r,this.mindMap.render()),this.mindMap.emit("data_change",r)}getNewNodeBehavior(e=!1,t=!1){let{createNewNodeBehavior:r}=this.mindMap.opt,n=!1,s=!1;switch(r){case C.CREATE_NEW_NODE_BEHAVIOR.DEFAULT:n=t||!e,s=t?!1:e;break;case C.CREATE_NEW_NODE_BEHAVIOR.NOT_ACTIVE:n=!1,s=!1;break;case C.CREATE_NEW_NODE_BEHAVIOR.ACTIVE_ONLY:n=!0,s=!1;break;default:break}return{focusNewNode:n,inserting:s}}insertNode(e=!0,t=[],r=null,n=[]){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:s,defaultInsertBelowSecondLevelNodeText:a}=this.mindMap.opt,o=t.length>0?t:this.activeNodeList,l=o.length>1,h=this.hasRichTextPlugin(),{focusNewNode:d,inserting:c}=this.getNewNodeBehavior(e,l),f={expand:!0,richText:h,isActive:d};h&&(f.resetRichText=!0),n=$o(n,f);let m=r&&r.richText,g=!1;o.forEach(x=>{if(x.isGeneralization||x.isRoot)return;n=Qt(n);let y=x.parent,E=x.layerIndex===1?s:a,k=da(x);m&&f.resetRichText&&delete f.resetRichText;let L={inserting:c,data:{text:E,...f,uid:Tt(),...r||{}},children:[...cs(n,g)]};g=!0,y.nodeData.children.splice(k+1,0,L)}),d&&this.clearActiveNodeList(),this.mindMap.render()}insertMultiNode(e,t){if(!t||t.length<=0||(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0))return;this.textEdit.hideEditTextBox();let r=e.length>0?e:this.activeNodeList,n=this.hasRichTextPlugin(),{focusNewNode:s}=this.getNewNodeBehavior(!1,!0),a={expand:!0,richText:n,isActive:s};n&&(a.resetRichText=!0),t=$o(t,a);let o=!1;r.forEach(l=>{if(l.isGeneralization||l.isRoot)return;t=Qt(t);let h=l.parent,d=da(l),c=cs(t,o);o=!0,h.nodeData.children.splice(d+1,0,...c)}),s&&this.clearActiveNodeList(),this.mindMap.render()}insertChildNode(e=!0,t=[],r=null,n=[]){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:s,defaultInsertBelowSecondLevelNodeText:a}=this.mindMap.opt,o=t.length>0?t:this.activeNodeList,l=o.length>1,h=this.hasRichTextPlugin(),{focusNewNode:d,inserting:c}=this.getNewNodeBehavior(e,l),f={expand:!0,richText:h,isActive:d};h&&(f.resetRichText=!0),n=$o(n,f);let m=r&&r.richText,g=!1;o.forEach(x=>{if(x.isGeneralization)return;n=Qt(n),x.nodeData.children||(x.nodeData.children=[]);let y=x.isRoot?s:a;m&&f.resetRichText&&delete f.resetRichText;let b={inserting:c,data:{text:y,uid:Tt(),...f,...r||{}},children:[...cs(n,g)]};g=!0,x.nodeData.children.push(b),x.setData({expand:!0})}),d&&this.clearActiveNodeList(),this.mindMap.render()}insertMultiChildNode(e,t){if(!t||t.length<=0||(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0))return;this.textEdit.hideEditTextBox();let r=e.length>0?e:this.activeNodeList,n=this.hasRichTextPlugin(),{focusNewNode:s}=this.getNewNodeBehavior(!1,!0),a={expand:!0,richText:n,isActive:s};n&&(a.resetRichText=!0),t=$o(t,a);let o=!1;r.forEach(l=>{l.isGeneralization||(t=Qt(t),l.nodeData.children||(l.nodeData.children=[]),t=cs(t,o),o=!0,l.nodeData.children.push(...t),l.setData({expand:!0}))}),s&&this.clearActiveNodeList(),this.mindMap.render()}insertParentNode(e=!0,t,r){if(t=Ot(t),this.activeNodeList.length<=0&&t.length<=0)return;this.textEdit.hideEditTextBox();let{defaultInsertSecondLevelNodeText:n,defaultInsertBelowSecondLevelNodeText:s}=this.mindMap.opt,a=t.length>0?t:this.activeNodeList,o=a.length>1,l=this.hasRichTextPlugin(),{focusNewNode:h,inserting:d}=this.getNewNodeBehavior(e,o),c={expand:!0,richText:l,isActive:h};l&&(c.resetRichText=!0);let f=r&&r.richText;a.forEach(m=>{if(m.isGeneralization||m.isRoot)return;let g=m.layerIndex===1?n:s;f&&c.resetRichText&&delete c.resetRichText;let x={inserting:d,data:{text:g,uid:Tt(),...c,...r||{}},children:[m.nodeData]},y=m.parent,b=da(m);y.nodeData.children.splice(b,1,x)}),h&&this.clearActiveNodeList(),this.mindMap.render()}upNode(e){if(this.activeNodeList.length<=0&&!e)return;let r=(e?[e]:this.activeNodeList)[0];if(r.isRoot)return;let n=r.parent,s=n.children,a=ze(r,s);if(a===-1||a===0)return;let o=a-1;s.splice(a,1),s.splice(o,0,r),n.nodeData.children.splice(a,1),n.nodeData.children.splice(o,0,r.nodeData),this.mindMap.render()}downNode(e){if(this.activeNodeList.length<=0&&!e)return;let r=(e?[e]:this.activeNodeList)[0];if(r.isRoot)return;let n=r.parent,s=n.children,a=ze(r,s);if(a===-1||a===s.length-1)return;let o=a+1;s.splice(a,1),s.splice(o,0,r),n.nodeData.children.splice(a,1),n.nodeData.children.splice(o,0,r.nodeData),this.mindMap.render()}moveUpOneLevel(e){if(e=e||this.activeNodeList[0],!e||e.isRoot||e.layerIndex<=1)return;let t=e.parent,r=t.parent,n=ze(e,t.children),s=ze(t,r.children);t.nodeData.children.splice(n,1),r.nodeData.children.splice(s+1,0,e.nodeData),this.mindMap.render()}_handleRemoveCustomStyles(e){let t=!1;return Object.keys(e).forEach(r=>{hs(r)&&(t=!0,delete e[r])}),this.hasRichTextPlugin()&&(t=!0,e.resetRichText=!0),t}removeCustomStyles(e){if(e=e||this.activeNodeList[0],!e)return;this._handleRemoveCustomStyles(e.getData())&&this.reRenderNodeCheckChange(e)}removeAllNodeCustomStyles(e){e=Ot(e);let t=!1;if(e.length>0)e.forEach(r=>{this._handleRemoveCustomStyles(r.getData())&&(t=!0)});else{if(!this.renderTree)return;ue(this.renderTree,null,r=>{this._handleRemoveCustomStyles(r.data)&&(t=!0);let s=us(r.data);s.length>0&&s.forEach(a=>{this._handleRemoveCustomStyles(a)&&(t=!0)})})}t&&this.mindMap.reRender()}copy(){this.beingCopyData=this.copyNode(),this.beingCopyData&&(this.mindMap.opt.disabledClipboard||Au(ku(this.beingCopyData)))}cut(){this.mindMap.execCommand("CUT_NODE",e=>{this.beingCopyData=e,this.mindMap.opt.disabledClipboard||Au(ku(e))})}handlePaste(e){let{disabledClipboard:t}=this.mindMap.opt;if(t)return;let r=e.clipboardData||e.originalEvent.clipboardData,n=r.items,s=null,a="";Array.from(n).forEach(o=>{o.type.indexOf("image")>-1&&(s=o.getAsFile()),o.type.indexOf("text")>-1&&(a=r.getData("text"))}),this.paste()}async paste(){let{errorHandler:e,handleIsSplitByWrapOnPasteCreateNewNode:t,handleNodePasteImg:r,disabledClipboard:n,onlyPasteTextWhenHasImgAndText:s}=this.mindMap.opt;if(!n&&Su())try{let a=await $2(),o=a.text||"",l=a.img||null;if(o){let h=null,d=!0;if(this.mindMap.opt.customHandleClipboardText)try{let c=await this.mindMap.opt.customHandleClipboardText(o);if(!Kt(c)){d=!1;let f=jo(c);f.isSmm?h=f.data:o=f.data}}catch(c){e(Ti.CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR,c)}if(d){let c=jo(o);c.isSmm?h=c.data:o=c.data}if(h)this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],Array.isArray(h)?h:[h]);else{this.hasRichTextPlugin()&&(o=fn(o));let c=o.split(new RegExp(`\r? |(?!!f);c.length>1&&t?t().then(()=>{this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],c.map(f=>({data:{text:f},children:[]})))}).catch(()=>{this.mindMap.execCommand("INSERT_CHILD_NODE",!1,[],{text:o})}):this.mindMap.execCommand("INSERT_CHILD_NODE",!1,[],{text:o})}}if(l&&(!o||!s))try{let h=null;r&&typeof r=="function"?h=await r(l):h=await v2(l),this.activeNodeList.length>0&&this.activeNodeList.forEach(d=>{this.mindMap.execCommand("SET_NODE_IMAGE",d,{url:h.url,title:"",width:h.size.width,height:h.size.height})})}catch(h){e(Mi.LOAD_CLIPBOARD_IMAGE_ERROR,h)}}catch(a){e(Mi.READ_CLIPBOARD_ERROR,a)}else this.beingCopyData&&this.mindMap.execCommand("PASTE_NODE",this.beingCopyData)}insertBefore(e,t){this.insertTo(e,t,"before")}insertAfter(e,t){this.insertTo(e,t,"after")}insertTo(e,t,r="before"){let n=Ot(e);n=n.filter(s=>!s.isRoot),r==="after"&&n.reverse(),n.forEach(s=>{let a=s.parent,o=a.children,l=Ie(s,o);if(l===-1)return;o.splice(l,1),a.nodeData.children.splice(l,1);let h=t.parent,d=h.children,c=Ie(t,d);c!==-1&&(r==="after"&&c++,d.splice(c,0,s),h.nodeData.children.splice(c,0,s.nodeData))}),this.mindMap.render()}removeNode(e=[]){if(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0)return;let t=null,r=e.length>0,n=r?e:this.activeNodeList,s=n.find(a=>a.isRoot);if(s)this.clearActiveNodeList(),s.children=[],s.nodeData.children=[];else{t=this.getNextActiveNode(n);for(let a=0;a0?e:this.activeNodeList;r=r.filter(s=>!s.isRoot);let n=this.getNextActiveNode(r);for(let s=0;s0?t=n[s-1]:t=r.parent}return t}copyNode(){if(this.activeNodeList.length<=0)return null;let e=ds(this.activeNodeList);return e=Fo(e),e.map(t=>ls({},t,!0))}cutNode(e){if(this.activeNodeList.length<=0)return;let t=ds(this.activeNodeList).filter(n=>!n.isRoot);t=Fo(t);let r=t.map(n=>ls({},n,!0));t.forEach(n=>{V0(n)}),this.clearActiveNodeList(),this.mindMap.render(),e&&typeof e=="function"&&e(r)}moveNodeTo(e,t){let r=Ot(e);r=r.filter(n=>!n.isRoot),r.forEach(n=>{this.removeNodeFromActiveList(n),V0(n),t.setData({expand:!0}),t.nodeData.children.push(n.nodeData)}),this.emitNodeActiveEvent(),this.mindMap.render()}pasteNode(e){e=Ot(e),this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],e)}setNodeStyle(e,t,r){let n={[t]:r};this.setNodeDataRender(e,n),zo.includes(t)&&(e.parent||e).renderLine(!0)}setNodeStyles(e,t){let r={...t};this.setNodeDataRender(e,r);let n=Object.keys(t),s=!1;n.forEach(a=>{zo.includes(a)&&(s=!0)}),s&&(e.parent||e).renderLine(!0)}setNodeActive(e,t){this.mindMap.execCommand("SET_NODE_DATA",e,{isActive:t}),e.updateNodeByActive(t)}setNodeExpand(e,t){this.mindMap.execCommand("SET_NODE_DATA",e,{expand:t}),this.mindMap.render()}expandAllNode(e=""){if(!this.renderTree)return;let t=(r,n)=>{!n&&r.data.uid===e&&(n=!0),n&&!r.data.expand&&(r.data.expand=!0),r.children&&r.children.length>0&&r.children.forEach(s=>{t(s,n)})};t(this.renderTree,!e),this.mindMap.render()}unexpandAllNode(e=!0,t=""){if(!this.renderTree)return;let r=(n,s,a)=>{!a&&n.data.uid===t&&(a=!0),a&&!s&&n.children&&n.children.length>0&&(n.data.expand=!1),n.children&&n.children.length>0&&n.children.forEach(o=>{r(o,!1,a)})};r(this.renderTree,!0,!t),this.mindMap.render(()=>{e&&this.setRootNodeCenter()})}expandToLevel(e){this.renderTree&&(de(this.renderTree,null,(t,r,n,s)=>{s0&&(t.data.expand=!1)},null,!0,0,0),this.mindMap.render())}toggleActiveExpand(){this.activeNodeList.forEach(e=>{e.nodeData.children.length<=0||e.isRoot||this.toggleNodeExpand(e)})}toggleNodeExpand(e){this.mindMap.execCommand("SET_NODE_EXPAND",e,!e.getData("expand"))}setNodeText(e,t,r,n){r=r===void 0?e.getData("richText"):r,this.setNodeDataRender(e,{text:t,richText:r,resetRichText:n})}setNodeImage(e,t){let{url:r,title:n,width:s,height:a,custom:o=!1}=t||{url:"",title:"",width:0,height:0,custom:!1};this.setNodeDataRender(e,{image:r,imageTitle:n||"",imageSize:{width:s,height:a,custom:o}})}setNodeIcon(e,t){this.setNodeDataRender(e,{icon:t})}setNodeHyperlink(e,t,r=""){this.setNodeDataRender(e,{hyperlink:t,hyperlinkTitle:r})}setNodeNote(e,t){this.setNodeDataRender(e,{note:t})}setNodeAttachment(e,t,r=""){this.setNodeDataRender(e,{attachmentUrl:t,attachmentName:r})}setNodeTag(e,t){this.setNodeDataRender(e,{tag:t})}insertFormula(e,t=[]){if(!this.hasRichTextPlugin()||!this.mindMap.formula)return;t=Ot(t),(t.length>0?t:this.activeNodeList).forEach(n=>{this.mindMap.formula.insertFormulaToNode(n,e)})}addGeneralization(e,t=!0){if(this.activeNodeList.length<=0)return;let r=this.activeNodeList.filter(d=>!d.isRoot&&!d.isGeneralization&&!d.checkHasSelfGeneralization()),n=A2(r);if(n.length<=0)return;let s=this.hasRichTextPlugin(),{focusNewNode:a,inserting:o}=this.getNewNodeBehavior(t,n.length>1),l=!1,h=e&&e.richText;n.forEach(d=>{let c={inserting:o,...e||{text:this.mindMap.opt.defaultGeneralizationText},range:d.range||null,uid:wt(),richText:s,isActive:a};s&&!h&&(c.resetRichText=s);let f=d.node.getData("generalization");if(f=f?Array.isArray(f)?f:[f]:[],d.range){if(!!f.find(g=>g.range&&g.range[0]===d.range[0]&&g.range[1]===d.range[1]))return;f.push(c)}else f.push(c);l=!0,this.mindMap.execCommand("SET_NODE_DATA",d.node,{generalization:f}),d.node.setData({expand:!0})}),l&&(a&&this.clearActiveNodeList(),this.mindMap.render(()=>{this.mindMap.render()}))}removeGeneralization(){this.activeNodeList.length<=0||(this.activeNodeList.forEach(e=>{e.checkHasGeneralization()&&this.mindMap.execCommand("SET_NODE_DATA",e,{generalization:null})}),this.mindMap.render(),this.closeHighlightNode())}setNodeCustomPosition(e,t=void 0,r=void 0){[e].forEach(s=>{this.mindMap.execCommand("SET_NODE_DATA",s,{customLeft:t,customTop:r})})}resetLayout(){de(this.root,null,e=>{e.customLeft=void 0,e.customTop=void 0,this.mindMap.execCommand("SET_NODE_DATA",e,{customLeft:void 0,customTop:void 0}),this.mindMap.render()},null,!0,0,0)}setNodeShape(e,t){if(!t||!P2.includes(t))return;[e].forEach(n=>{this.setNodeStyle(n,"shape",t)})}goTargetNode(e,t=()=>{}){let r=typeof e=="string"?e:e.getData("uid");r&&this.expandToNodeUid(r,()=>{let n=this.findNodeByUid(r);n&&(n.active(),this.moveNodeToCenter(n),t(n))})}setNodeData(e,t){Object.keys(t).forEach(r=>{e.nodeData.data[r]=t[r]})}setNodeDataRender(e,t,r=!1){if(this.mindMap.execCommand("SET_NODE_DATA",e,t),E2(t)){this.mindMap.emit("node_tree_render_end");return}this.reRenderNodeCheckChange(e,r)}reRenderNodeCheckChange(e,t){e.reRender()?t||this.mindMap.render():this.mindMap.emit("node_tree_render_end")}moveNodeToCenter(e,t){let{resetScaleOnMoveNodeToCenter:r}=this.mindMap.opt;t!==void 0&&(r=t);let{transform:n,state:s}=this.mindMap.view.getTransformData(),{left:a,top:o,width:l,height:h}=e;r||(a*=n.scaleX,o*=n.scaleY,l*=n.scaleX,h*=n.scaleY);let d=this.mindMap.width/2,c=this.mindMap.height/2,f=a+l/2,m=o+h/2,g=d-s.x,x=c-s.y,y=g-f,b=x-m;this.mindMap.view.translateX(y),this.mindMap.view.translateY(b),r&&this.mindMap.view.setScale(1)}setRootNodeCenter(){this.moveNodeToCenter(this.root)}expandToNodeUid(e,t=()=>{}){if(!this.renderTree){t();return}let r=[],n=!1,s={};Xt(this.renderTree,(o,l)=>{if(o.data.uid===e)return r=l?[...s[l.data.uid],l]:[],"stop";if(us(o.data).forEach(d=>{d.uid===e&&(r=l?[...s[l.data.uid],l,o]:[],n=!0)}),n)return"stop";s[o.data.uid]=l?[...s[l.data.uid],l]:[]});let a=!1;if(r.forEach(o=>{o.data.expand||(a=!0,o.data.expand=!0)}),n){let o=r[r.length-1];o&&de(o,null,l=>{l.data.expand||(a=!0,l.data.expand=!0)})}a?this.mindMap.render(t):t()}findNodeByUid(e){if(!this.root)return;let t=null;return de(this.root,null,r=>{if(r.getData("uid")===e)return t=r,!0;let n=!1;if((r._generalizationList||[]).forEach(s=>{s.generalizationNode.getData("uid")===e&&(t=s.generalizationNode,n=!0)}),n)return!0}),t}highlightNode(e,t,r){if(this.isRendering)return;r={stroke:"rgb(94, 200, 248)",fill:"transparent",...r||{}},this.highlightBoxNode?this.highlightBoxNodeStyle&&(this.highlightBoxNodeStyle.stroke!==r.stroke||this.highlightBoxNodeStyle.fill!==r.fill)&&this.highlightBoxNode.stroke({color:r.stroke||"transparent"}).fill({color:r.fill||"transparent"}):this.highlightBoxNode=new Gi().stroke({color:r.stroke||"transparent"}).fill({color:r.fill||"transparent"}),this.highlightBoxNodeStyle={...r};let n=1/0,s=1/0,a=-1/0,o=-1/0;t?e.children.slice(t[0],t[1]+1).forEach(h=>{h.lefta&&(a=d),c>o&&(o=c)}):(n=e.left,s=e.top,a=e.left+e.width,o=e.top+e.height),this.highlightBoxNode.plot([[n,s],[a,s],[a,o],[n,o]]),this.mindMap.otherDraw.add(this.highlightBoxNode)}closeHighlightNode(){this.highlightBoxNode&&this.highlightBoxNode.remove()}hasRichTextPlugin(){return!!this.mindMap.richText}},jv=Np});var jn,Vv=T(()=>{Ro();jn={default:B0}});var Ep,Gn,Wv=T(()=>{Ep={Backspace:8,Tab:9,Enter:13,Shift:16,Control:17,Alt:18,CapsLock:20,Esc:27,Spacebar:32,PageUp:33,PageDown:34,End:35,Home:36,Insert:45,Left:37,Up:38,Right:39,Down:40,Del:46,NumLock:144,Cmd:91,CmdFF:224,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"`":192,"=":187,"-":189,"/":191,".":190};for(let i=0;i<=9;i++)Ep[i]=i+48;"abcdefghijklmnopqrstuvwxyz".split("").forEach((i,e)=>{Ep[i]=e+65});Gn=Ep});var h0,Yv=T(()=>{Wv();h0=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,this.shortcutMap={},this.shortcutMapCache={},this.isPause=!1,this.isInSvg=!1,this.isStopCheckInSvg=!1,this.defaultEnableCheck=this.defaultEnableCheck.bind(this),this.bindEvent()}extendKeyMap(e,t){Gn[e]=t}removeKeyMap(e){typeof Gn[e]<"u"&&delete Gn[e]}pause(){this.isPause=!0}recovery(){this.isPause=!1}save(){Object.keys(this.shortcutMapCache).length>0||(this.shortcutMapCache=this.shortcutMap,this.shortcutMap={})}restore(){Object.keys(this.shortcutMapCache).length<=0||(this.shortcutMap=this.shortcutMapCache,this.shortcutMapCache={})}stopCheckInSvg(){let{enableShortcutOnlyWhenMouseInSvg:e}=this.mindMap.opt;e&&(this.isStopCheckInSvg=!0)}recoveryCheckInSvg(){let{enableShortcutOnlyWhenMouseInSvg:e}=this.mindMap.opt;e&&(this.isStopCheckInSvg=!0)}bindEvent(){this.onKeydown=this.onKeydown.bind(this),this.mindMap.on("svg_mouseenter",()=>{this.isInSvg=!0}),this.mindMap.on("svg_mouseleave",()=>{this.isInSvg=!1}),window.addEventListener("keydown",this.onKeydown),this.mindMap.on("beforeDestroy",()=>{this.unBindEvent()})}unBindEvent(){window.removeEventListener("keydown",this.onKeydown)}defaultEnableCheck(e){let t=e.target;if(t===document.body)return!0;for(let r=0;r{if(this.checkKey(e,a)){if(this.checkKey(e,"Control+v")||(e.stopPropagation(),e.preventDefault()),typeof r=="function"&&r(a,[...this.mindMap.renderer.activeNodeList]))return;this.shortcutMap[a].forEach(o=>{o()})}}))}checkKey(e,t){let r=this.getOriginEventCodeArr(e),n=this.getKeyCodeArr(t);if(r.length!==n.length)return!1;for(let s=0;so===r[s]);if(a===-1)return!1;n.splice(a,1)}return!0}getOriginEventCodeArr(e){let t=[];return(e.ctrlKey||e.metaKey)&&t.push(Gn.Control),e.altKey&&t.push(Gn.Alt),e.shiftKey&&t.push(Gn.Shift),t.includes(e.keyCode)||t.push(e.keyCode),t}hasCombinationKey(e){return e.ctrlKey||e.metaKey||e.altKey||e.shiftKey}getKeyCodeArr(e){let t=e.split(/\s*\+\s*/),r=[];return t.forEach(n=>{r.push(Gn[n])}),r}addShortcut(e,t){e.split(/\s*\|\s*/).forEach(r=>{this.shortcutMap[r]?this.shortcutMap[r].push(t):this.shortcutMap[r]=[t]})}removeShortcut(e,t){e.split(/\s*\|\s*/).forEach(r=>{if(this.shortcutMap[r])if(t){let n=this.shortcutMap[r].findIndex(s=>s===t);n!==-1&&this.shortcutMap[r].splice(n,1)}else this.shortcutMap[r]=[],delete this.shortcutMap[r]})}getShortcutFn(e){let t=[];return e.split(/\s*\|\s*/).forEach(r=>{t=this.shortcutMap[r]||[]}),t}}});var Kv,Xv=T(()=>{Kv={name:"simple-mind-map",version:"0.14.0-fix.1",description:"\u4E00\u4E2A\u7B80\u5355\u7684web\u5728\u7EBF\u601D\u7EF4\u5BFC\u56FE",authors:[{name:"\u8857\u89D2\u5C0F\u6797",email:"1013335014@qq.com"},{name:"\u7406\u60F3\u9752\u5E74\u5B9E\u9A8C\u5BA4",url:"http://lxqnsys.com/"}],types:"./types/index.d.ts",typings:"./types/index.d.ts",license:"MIT",repository:{type:"git",url:"https://github.com/wanglin2/mind-map"},scripts:{lint:"eslint src/",format:"prettier --write .",types:"npx -p typescript tsc index.js --declaration --allowJs --emitDeclarationOnly --outDir types --target es2017 --skipLibCheck & node ./bin/createPluginsTypeFiles.js",wsServe:"node ./bin/wsServer.mjs"},module:"index.js",main:"./dist/simpleMindMap.umd.min.js",dependencies:{"@svgdotjs/svg.js":"3.2.0",deepmerge:"^1.5.2",eventemitter3:"^4.0.7",jszip:"^3.10.1",katex:"^0.16.8","mdast-util-from-markdown":"^1.3.0","pdf-lib":"^1.17.1",quill:"^2.0.3",tern:"^0.24.3",uuid:"^9.0.0",ws:"^7.5.9","xml-js":"^1.6.11","y-webrtc":"^10.2.5",yjs:"^13.6.8"},keywords:["javascript","svg","mind-map","mindMap","MindMap"],devDependencies:{eslint:"^8.25.0",prettier:"^2.7.1"}}});var Sp,Zv,Qv=T(()=>{pe();$e();Xv();Sp=class{constructor(e={}){this.opt=e,this.mindMap=e.mindMap,this.commands={},this.history=[],this.activeHistoryIndex=0,this.registerShortcutKeys(),this.originAddHistory=this.addHistory.bind(this),this.addHistory=Si(this.addHistory,this.mindMap.opt.addHistoryTime,this),this.isPause=!1}pause(){this.isPause=!0}recovery(){this.isPause=!1}clearHistory(){this.history=[],this.activeHistoryIndex=0,this.mindMap.emit("back_forward",0,0)}registerShortcutKeys(){this.mindMap.keyCommand.addShortcut("Control+z",()=>{this.mindMap.execCommand("BACK")}),this.mindMap.keyCommand.addShortcut("Control+y",()=>{this.mindMap.execCommand("FORWARD")})}exec(e,...t){if(this.commands[e]){if(this.commands[e].forEach(r=>{r(...t)}),this.mindMap.emit("afterExecCommand",e,...t),["BACK","FORWARD","SET_NODE_ACTIVE","CLEAR_ACTIVE_NODE"].includes(e))return;this.addHistory()}}add(e,t){this.commands[e]?this.commands[e].push(t):this.commands[e]=[t]}remove(e,t){if(this.commands[e])if(!t)this.commands[e]=[],delete this.commands[e];else{let r=this.commands[e].find(n=>n===t);r!==-1&&this.commands[e].splice(r,1)}}addHistory(){if(this.mindMap.opt.readonly||this.isPause)return;this.mindMap.emit("beforeAddHistory");let e=this.history.length>0?this.history[this.activeHistoryIndex]:null,t=this.getCopyData(),r=JSON.stringify(t);e&&e===r||(this.emitDataUpdatesEvent(e,r),this.history=this.history.slice(0,this.activeHistoryIndex+1),this.history.push(r),this.history.length>this.mindMap.opt.maxHistoryCount&&this.history.shift(),this.activeHistoryIndex=this.history.length-1,this.mindMap.emit("data_change",t),this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length))}back(e=1){if(!this.mindMap.opt.readonly&&this.activeHistoryIndex-e>=0){let t=this.history[this.activeHistoryIndex];this.activeHistoryIndex-=e,this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length);let r=this.history[this.activeHistoryIndex],n=JSON.parse(r);return this.emitDataUpdatesEvent(t,r),n}}forward(e=1){if(this.mindMap.opt.readonly)return;let t=this.history.length;if(this.activeHistoryIndex+e<=t-1){let r=this.history[this.activeHistoryIndex];this.activeHistoryIndex+=e,this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length);let n=this.history[this.activeHistoryIndex],s=JSON.parse(n);return this.emitDataUpdatesEvent(r,n),s}}getCopyData(){if(!this.mindMap.renderer.renderTree)return null;let e=uu({},this.mindMap.renderer.renderTree,!0);return e.smmVersion=Kv.version,e}removeDataUid(e){e=Kt(e);let t=r=>{delete r.data.uid,r.children&&r.children.length>0&&r.children.forEach(n=>{t(n)})};return t(e),e}emitDataUpdatesEvent(e,t){try{let r="data_change_detail";if(this.mindMap.event.listenerCount(r)>0&&e&&t){let s=JSON.parse(e),a=JSON.parse(t),o=Kt(vu(s)),l=Kt(vu(a)),h=[],d=(c,f)=>(c.children&&c.children.length>0&&c.children.forEach((m,g)=>{c.children[g]=typeof m=="string"?f[m]:f[m.data.uid],d(c.children[g],f)}),c);Object.keys(l).forEach(c=>{o[c]?H0(o[c],l[c])||h.push({action:"update",oldData:d(o[c],o),data:d(l[c],l)}):h.push({action:"create",data:d(l[c],l)})}),Object.keys(o).forEach(c=>{l[c]||h.push({action:"delete",data:d(o[c],o)})}),this.mindMap.emit(r,h)}}catch(r){this.mindMap.opt.errorHandler(Mi.DATA_CHANGE_DETAIL_EVENT_ERROR,r)}}},Zv=Sp});var Ap,Jv,eb=T(()=>{pe();Ap=class{constructor(){this.has={},this.queue=[],this.nextTick=x2(this.flush,this)}push(e,t){if(this.has[e]){this.replaceTask(e,t);return}this.has[e]=!0,this.queue.push({name:e,fn:t}),this.nextTick()}replaceTask(e,t){let r=this.queue.findIndex(n=>n.name===e);r!==-1&&(this.queue[r]={name:e,fn:t})}flush(){let e=this.queue.slice(0);this.queue=[],e.forEach(({name:t,fn:r})=>{this.has[t]=!1,r()})}},Jv=Ap});var kp,tb=T(()=>{$e();kp={el:null,data:null,viewData:null,readonly:!1,layout:k.LAYOUT.LOGICAL_STRUCTURE,fishboneDeg:45,theme:"default",themeConfig:{},scaleRatio:.2,translateRatio:1,minZoomRatio:20,maxZoomRatio:400,customCheckIsTouchPad:null,mouseScaleCenterUseMousePosition:!0,maxTag:5,expandBtnSize:20,imgTextMargin:5,textContentMargin:2,customNoteContentShow:null,textAutoWrapWidth:500,customHandleMousewheel:null,mousewheelAction:k.MOUSE_WHEEL_ACTION.MOVE,mousewheelMoveStep:100,mousewheelZoomActionReverse:!0,defaultInsertSecondLevelNodeText:"\u4E8C\u7EA7\u8282\u70B9",defaultInsertBelowSecondLevelNodeText:"\u5206\u652F\u4E3B\u9898",expandBtnStyle:{color:"#808080",fill:"#fff",fontSize:13,strokeColor:"#333333"},expandBtnIcon:{open:"",close:""},expandBtnNumHandler:null,isShowExpandNum:!0,enableShortcutOnlyWhenMouseInSvg:!0,customCheckEnableShortcut:null,initRootNodePosition:null,nodeTextEditZIndex:3e3,nodeNoteTooltipZIndex:3e3,isEndNodeTextEditOnClickOuter:!0,maxHistoryCount:500,alwaysShowExpandBtn:!1,notShowExpandBtn:!1,iconList:[],maxNodeCacheCount:1e3,fitPadding:50,enableCtrlKeyNodeSelection:!0,useLeftKeySelectionRightKeyDrag:!1,beforeTextEdit:null,isUseCustomNodeContent:!1,customCreateNodeContent:null,customInnerElsAppendTo:null,enableAutoEnterTextEditWhenKeydown:!1,autoEmptyTextWhenKeydownEnterEdit:!1,customHandleClipboardText:null,disableMouseWheelZoom:!1,errorHandler:(i,e)=>{console.error(i,e)},enableDblclickBackToRootNode:!1,hoverRectColor:"rgb(94, 200, 248)",hoverRectPadding:2,selectTextOnEnterEditText:!1,deleteNodeActive:!0,fit:!1,tagsColorMap:{},cooperateStyle:{avatarSize:22,fontSize:12},onlyOneEnableActiveNodeOnCooperate:!1,defaultGeneralizationText:"\u6982\u8981",handleIsSplitByWrapOnPasteCreateNewNode:null,addHistoryTime:100,isDisableDrag:!1,createNewNodeBehavior:k.CREATE_NEW_NODE_BEHAVIOR.DEFAULT,defaultNodeImage:"",isLimitMindMapInCanvas:!1,handleNodePasteImg:null,customCreateNodePath:null,customCreateNodePolygon:null,customTransformNodeLinePath:null,beforeShortcutRun:null,resetScaleOnMoveNodeToCenter:!1,createNodePrefixContent:null,createNodePostfixContent:null,disabledClipboard:!1,customHyperlinkJump:null,openPerformance:!1,performanceConfig:{time:250,padding:100,removeNodeWhenOutCanvas:!0},emptyTextMeasureHeightText:"abc123\u6211\u548C\u4F60",openRealtimeRenderOnNodeTextEdit:!1,mousedownEventPreventDefault:!1,onlyPasteTextWhenHasImgAndText:!0,enableDragModifyNodeWidth:!0,minNodeTextModifyWidth:20,maxNodeTextModifyWidth:-1,customHandleLine:null,addHistoryOnInit:!0,noteIcon:{icon:"",style:{}},hyperlinkIcon:{icon:"",style:{}},attachmentIcon:{icon:"",style:{}},isShowCreateChildBtnIcon:!0,quickCreateChildBtnIcon:{icon:"",style:{}},customQuickCreateChildBtnClick:null,addCustomContentToNode:null,enableInheritAncestorLineStyle:!0,selectTranslateStep:3,selectTranslateLimit:20,enableFreeDrag:!1,autoMoveWhenMouseInEdgeOnDrag:!0,dragMultiNodeRectConfig:{width:40,height:20,fill:"rgb(94, 200, 248)"},dragPlaceholderRectFill:"rgb(94, 200, 248)",dragPlaceholderLineConfig:{color:"rgb(94, 200, 248)",width:2},dragOpacityConfig:{cloneNodeOpacity:.5,beingDragNodeOpacity:.3},handleDragCloneNode:null,beforeDragEnd:null,beforeDragStart:null,watermarkConfig:{onlyExport:!1,text:"",lineSpacing:100,textSpacing:100,angle:30,textStyle:{color:"#999",opacity:.5,fontSize:14},belowNode:!1},exportPaddingX:10,exportPaddingY:10,resetCss:` +)\r`,"g")).filter(f=>!!f);c.length>1&&t?t().then(()=>{this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],c.map(f=>({data:{text:f},children:[]})))}).catch(()=>{this.mindMap.execCommand("INSERT_CHILD_NODE",!1,[],{text:o})}):this.mindMap.execCommand("INSERT_CHILD_NODE",!1,[],{text:o})}}if(l&&(!o||!s))try{let h=null;r&&typeof r=="function"?h=await r(l):h=await z2(l),this.activeNodeList.length>0&&this.activeNodeList.forEach(d=>{this.mindMap.execCommand("SET_NODE_IMAGE",d,{url:h.url,title:"",width:h.size.width,height:h.size.height})})}catch(h){e(Ti.LOAD_CLIPBOARD_IMAGE_ERROR,h)}}catch(a){e(Ti.READ_CLIPBOARD_ERROR,a)}else this.beingCopyData&&this.mindMap.execCommand("PASTE_NODE",this.beingCopyData)}insertBefore(e,t){this.insertTo(e,t,"before")}insertAfter(e,t){this.insertTo(e,t,"after")}insertTo(e,t,r="before"){let n=Ot(e);n=n.filter(s=>!s.isRoot),r==="after"&&n.reverse(),n.forEach(s=>{let a=s.parent,o=a.children,l=ze(s,o);if(l===-1)return;o.splice(l,1),a.nodeData.children.splice(l,1);let h=t.parent,d=h.children,c=ze(t,d);c!==-1&&(r==="after"&&c++,d.splice(c,0,s),h.nodeData.children.splice(c,0,s.nodeData))}),this.mindMap.render()}removeNode(e=[]){if(e=Ot(e),this.activeNodeList.length<=0&&e.length<=0)return;let t=null,r=e.length>0,n=r?e:this.activeNodeList,s=n.find(a=>a.isRoot);if(s)this.clearActiveNodeList(),s.children=[],s.nodeData.children=[];else{t=this.getNextActiveNode(n);for(let a=0;a0?e:this.activeNodeList;r=r.filter(s=>!s.isRoot);let n=this.getNextActiveNode(r);for(let s=0;s0?t=n[s-1]:t=r.parent}return t}copyNode(){if(this.activeNodeList.length<=0)return null;let e=ds(this.activeNodeList);return e=Go(e),e.map(t=>ls({},t,!0))}cutNode(e){if(this.activeNodeList.length<=0)return;let t=ds(this.activeNodeList).filter(n=>!n.isRoot);t=Go(t);let r=t.map(n=>ls({},n,!0));t.forEach(n=>{eh(n)}),this.clearActiveNodeList(),this.mindMap.render(),e&&typeof e=="function"&&e(r)}moveNodeTo(e,t){let r=Ot(e);r=r.filter(n=>!n.isRoot),r.forEach(n=>{this.removeNodeFromActiveList(n),eh(n),t.setData({expand:!0}),t.nodeData.children.push(n.nodeData)}),this.emitNodeActiveEvent(),this.mindMap.render()}pasteNode(e){e=Ot(e),this.mindMap.execCommand("INSERT_MULTI_CHILD_NODE",[],e)}setNodeStyle(e,t,r){let n={[t]:r};this.setNodeDataRender(e,n),Fo.includes(t)&&(e.parent||e).renderLine(!0)}setNodeStyles(e,t){let r={...t};this.setNodeDataRender(e,r);let n=Object.keys(t),s=!1;n.forEach(a=>{Fo.includes(a)&&(s=!0)}),s&&(e.parent||e).renderLine(!0)}setNodeActive(e,t){this.mindMap.execCommand("SET_NODE_DATA",e,{isActive:t}),e.updateNodeByActive(t)}setNodeExpand(e,t){this.mindMap.execCommand("SET_NODE_DATA",e,{expand:t}),this.mindMap.render()}expandAllNode(e=""){if(!this.renderTree)return;let t=(r,n)=>{!n&&r.data.uid===e&&(n=!0),n&&!r.data.expand&&(r.data.expand=!0),r.children&&r.children.length>0&&r.children.forEach(s=>{t(s,n)})};t(this.renderTree,!e),this.mindMap.render()}unexpandAllNode(e=!0,t=""){if(!this.renderTree)return;let r=(n,s,a)=>{!a&&n.data.uid===t&&(a=!0),a&&!s&&n.children&&n.children.length>0&&(n.data.expand=!1),n.children&&n.children.length>0&&n.children.forEach(o=>{r(o,!1,a)})};r(this.renderTree,!0,!t),this.mindMap.render(()=>{e&&this.setRootNodeCenter()})}expandToLevel(e){this.renderTree&&(ue(this.renderTree,null,(t,r,n,s)=>{s0&&(t.data.expand=!1)},null,!0,0,0),this.mindMap.render())}toggleActiveExpand(){this.activeNodeList.forEach(e=>{e.nodeData.children.length<=0||e.isRoot||this.toggleNodeExpand(e)})}toggleNodeExpand(e){this.mindMap.execCommand("SET_NODE_EXPAND",e,!e.getData("expand"))}setNodeText(e,t,r,n){r=r===void 0?e.getData("richText"):r,this.setNodeDataRender(e,{text:t,richText:r,resetRichText:n})}setNodeImage(e,t){let{url:r,title:n,width:s,height:a,custom:o=!1}=t||{url:"",title:"",width:0,height:0,custom:!1};this.setNodeDataRender(e,{image:r,imageTitle:n||"",imageSize:{width:s,height:a,custom:o}})}setNodeIcon(e,t){this.setNodeDataRender(e,{icon:t})}setNodeHyperlink(e,t,r=""){this.setNodeDataRender(e,{hyperlink:t,hyperlinkTitle:r})}setNodeNote(e,t){this.setNodeDataRender(e,{note:t})}setNodeAttachment(e,t,r=""){this.setNodeDataRender(e,{attachmentUrl:t,attachmentName:r})}setNodeTag(e,t){this.setNodeDataRender(e,{tag:t})}insertFormula(e,t=[]){if(!this.hasRichTextPlugin()||!this.mindMap.formula)return;t=Ot(t),(t.length>0?t:this.activeNodeList).forEach(n=>{this.mindMap.formula.insertFormulaToNode(n,e)})}addGeneralization(e,t=!0){if(this.activeNodeList.length<=0)return;let r=this.activeNodeList.filter(d=>!d.isRoot&&!d.isGeneralization&&!d.checkHasSelfGeneralization()),n=H2(r);if(n.length<=0)return;let s=this.hasRichTextPlugin(),{focusNewNode:a,inserting:o}=this.getNewNodeBehavior(t,n.length>1),l=!1,h=e&&e.richText;n.forEach(d=>{let c={inserting:o,...e||{text:this.mindMap.opt.defaultGeneralizationText},range:d.range||null,uid:Tt(),richText:s,isActive:a};s&&!h&&(c.resetRichText=s);let f=d.node.getData("generalization");if(f=f?Array.isArray(f)?f:[f]:[],d.range){if(!!f.find(g=>g.range&&g.range[0]===d.range[0]&&g.range[1]===d.range[1]))return;f.push(c)}else f.push(c);l=!0,this.mindMap.execCommand("SET_NODE_DATA",d.node,{generalization:f}),d.node.setData({expand:!0})}),l&&(a&&this.clearActiveNodeList(),this.mindMap.render(()=>{this.mindMap.render()}))}removeGeneralization(){this.activeNodeList.length<=0||(this.activeNodeList.forEach(e=>{e.checkHasGeneralization()&&this.mindMap.execCommand("SET_NODE_DATA",e,{generalization:null})}),this.mindMap.render(),this.closeHighlightNode())}setNodeCustomPosition(e,t=void 0,r=void 0){[e].forEach(s=>{this.mindMap.execCommand("SET_NODE_DATA",s,{customLeft:t,customTop:r})})}resetLayout(){ue(this.root,null,e=>{e.customLeft=void 0,e.customTop=void 0,this.mindMap.execCommand("SET_NODE_DATA",e,{customLeft:void 0,customTop:void 0}),this.mindMap.render()},null,!0,0,0)}setNodeShape(e,t){if(!t||!Q2.includes(t))return;[e].forEach(n=>{this.setNodeStyle(n,"shape",t)})}goTargetNode(e,t=()=>{}){let r=typeof e=="string"?e:e.getData("uid");r&&this.expandToNodeUid(r,()=>{let n=this.findNodeByUid(r);n&&(n.active(),this.moveNodeToCenter(n),t(n))})}setNodeData(e,t){Object.keys(t).forEach(r=>{e.nodeData.data[r]=t[r]})}setNodeDataRender(e,t,r=!1){if(this.mindMap.execCommand("SET_NODE_DATA",e,t),F2(t)){this.mindMap.emit("node_tree_render_end");return}this.reRenderNodeCheckChange(e,r)}reRenderNodeCheckChange(e,t){e.reRender()?t||this.mindMap.render():this.mindMap.emit("node_tree_render_end")}moveNodeToCenter(e,t){let{resetScaleOnMoveNodeToCenter:r}=this.mindMap.opt;t!==void 0&&(r=t);let{transform:n,state:s}=this.mindMap.view.getTransformData(),{left:a,top:o,width:l,height:h}=e;r||(a*=n.scaleX,o*=n.scaleY,l*=n.scaleX,h*=n.scaleY);let d=this.mindMap.width/2,c=this.mindMap.height/2,f=a+l/2,m=o+h/2,g=d-s.x,x=c-s.y,y=g-f,b=x-m;this.mindMap.view.translateX(y),this.mindMap.view.translateY(b),r&&this.mindMap.view.setScale(1)}setRootNodeCenter(){this.moveNodeToCenter(this.root)}expandToNodeUid(e,t=()=>{}){if(!this.renderTree){t();return}let r=[],n=!1,s={};Zt(this.renderTree,(o,l)=>{if(o.data.uid===e)return r=l?[...s[l.data.uid],l]:[],"stop";if(us(o.data).forEach(d=>{d.uid===e&&(r=l?[...s[l.data.uid],l,o]:[],n=!0)}),n)return"stop";s[o.data.uid]=l?[...s[l.data.uid],l]:[]});let a=!1;if(r.forEach(o=>{o.data.expand||(a=!0,o.data.expand=!0)}),n){let o=r[r.length-1];o&&ue(o,null,l=>{l.data.expand||(a=!0,l.data.expand=!0)})}a?this.mindMap.render(t):t()}findNodeByUid(e){if(!this.root)return;let t=null;return ue(this.root,null,r=>{if(r.getData("uid")===e)return t=r,!0;let n=!1;if((r._generalizationList||[]).forEach(s=>{s.generalizationNode.getData("uid")===e&&(t=s.generalizationNode,n=!0)}),n)return!0}),t}highlightNode(e,t,r){if(this.isRendering)return;r={stroke:"rgb(94, 200, 248)",fill:"transparent",...r||{}},this.highlightBoxNode?this.highlightBoxNodeStyle&&(this.highlightBoxNodeStyle.stroke!==r.stroke||this.highlightBoxNodeStyle.fill!==r.fill)&&this.highlightBoxNode.stroke({color:r.stroke||"transparent"}).fill({color:r.fill||"transparent"}):this.highlightBoxNode=new ji().stroke({color:r.stroke||"transparent"}).fill({color:r.fill||"transparent"}),this.highlightBoxNodeStyle={...r};let n=1/0,s=1/0,a=-1/0,o=-1/0;t?e.children.slice(t[0],t[1]+1).forEach(h=>{h.lefta&&(a=d),c>o&&(o=c)}):(n=e.left,s=e.top,a=e.left+e.width,o=e.top+e.height),this.highlightBoxNode.plot([[n,s],[a,s],[a,o],[n,o]]),this.mindMap.otherDraw.add(this.highlightBoxNode)}closeHighlightNode(){this.highlightBoxNode&&this.highlightBoxNode.remove()}hasRichTextPlugin(){return!!this.mindMap.richText}},nb=Dp});var $n,ab=T(()=>{qo();$n={default:G0}});var Op,jn,ob=T(()=>{Op={Backspace:8,Tab:9,Enter:13,Shift:16,Control:17,Alt:18,CapsLock:20,Esc:27,Spacebar:32,PageUp:33,PageDown:34,End:35,Home:36,Insert:45,Left:37,Up:38,Right:39,Down:40,Del:46,NumLock:144,Cmd:91,CmdFF:224,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"`":192,"=":187,"-":189,"/":191,".":190};for(let i=0;i<=9;i++)Op[i]=i+48;"abcdefghijklmnopqrstuvwxyz".split("").forEach((i,e)=>{Op[i]=e+65});jn=Op});var p0,lb=T(()=>{ob();p0=class{constructor(e){this.opt=e,this.mindMap=e.mindMap,this.shortcutMap={},this.shortcutMapCache={},this.isPause=!1,this.isInSvg=!1,this.isStopCheckInSvg=!1,this.defaultEnableCheck=this.defaultEnableCheck.bind(this),this.bindEvent()}extendKeyMap(e,t){jn[e]=t}removeKeyMap(e){typeof jn[e]<"u"&&delete jn[e]}pause(){this.isPause=!0}recovery(){this.isPause=!1}save(){Object.keys(this.shortcutMapCache).length>0||(this.shortcutMapCache=this.shortcutMap,this.shortcutMap={})}restore(){Object.keys(this.shortcutMapCache).length<=0||(this.shortcutMap=this.shortcutMapCache,this.shortcutMapCache={})}stopCheckInSvg(){let{enableShortcutOnlyWhenMouseInSvg:e}=this.mindMap.opt;e&&(this.isStopCheckInSvg=!0)}recoveryCheckInSvg(){let{enableShortcutOnlyWhenMouseInSvg:e}=this.mindMap.opt;e&&(this.isStopCheckInSvg=!0)}bindEvent(){this.onKeydown=this.onKeydown.bind(this),this.mindMap.on("svg_mouseenter",()=>{this.isInSvg=!0}),this.mindMap.on("svg_mouseleave",()=>{this.isInSvg=!1}),window.addEventListener("keydown",this.onKeydown),this.mindMap.on("beforeDestroy",()=>{this.unBindEvent()})}unBindEvent(){window.removeEventListener("keydown",this.onKeydown)}defaultEnableCheck(e){let t=e.target;if(t===document.body)return!0;for(let r=0;r{if(this.checkKey(e,a)){if(this.checkKey(e,"Control+v")||(e.stopPropagation(),e.preventDefault()),typeof r=="function"&&r(a,[...this.mindMap.renderer.activeNodeList]))return;this.shortcutMap[a].forEach(o=>{o()})}}))}checkKey(e,t){let r=this.getOriginEventCodeArr(e),n=this.getKeyCodeArr(t);if(r.length!==n.length)return!1;for(let s=0;so===r[s]);if(a===-1)return!1;n.splice(a,1)}return!0}getOriginEventCodeArr(e){let t=[];return(e.ctrlKey||e.metaKey)&&t.push(jn.Control),e.altKey&&t.push(jn.Alt),e.shiftKey&&t.push(jn.Shift),t.includes(e.keyCode)||t.push(e.keyCode),t}hasCombinationKey(e){return e.ctrlKey||e.metaKey||e.altKey||e.shiftKey}getKeyCodeArr(e){let t=e.split(/\s*\+\s*/),r=[];return t.forEach(n=>{r.push(jn[n])}),r}addShortcut(e,t){e.split(/\s*\|\s*/).forEach(r=>{this.shortcutMap[r]?this.shortcutMap[r].push(t):this.shortcutMap[r]=[t]})}removeShortcut(e,t){e.split(/\s*\|\s*/).forEach(r=>{if(this.shortcutMap[r])if(t){let n=this.shortcutMap[r].findIndex(s=>s===t);n!==-1&&this.shortcutMap[r].splice(n,1)}else this.shortcutMap[r]=[],delete this.shortcutMap[r]})}getShortcutFn(e){let t=[];return e.split(/\s*\|\s*/).forEach(r=>{t=this.shortcutMap[r]||[]}),t}}});var db,hb=T(()=>{db={name:"simple-mind-map",version:"0.14.0-fix.1",description:"\u4E00\u4E2A\u7B80\u5355\u7684web\u5728\u7EBF\u601D\u7EF4\u5BFC\u56FE",authors:[{name:"\u8857\u89D2\u5C0F\u6797",email:"1013335014@qq.com"},{name:"\u7406\u60F3\u9752\u5E74\u5B9E\u9A8C\u5BA4",url:"http://lxqnsys.com/"}],types:"./types/index.d.ts",typings:"./types/index.d.ts",license:"MIT",repository:{type:"git",url:"https://github.com/wanglin2/mind-map"},scripts:{lint:"eslint src/",format:"prettier --write .",types:"npx -p typescript tsc index.js --declaration --allowJs --emitDeclarationOnly --outDir types --target es2017 --skipLibCheck & node ./bin/createPluginsTypeFiles.js",wsServe:"node ./bin/wsServer.mjs"},module:"index.js",main:"./dist/simpleMindMap.umd.min.js",dependencies:{"@svgdotjs/svg.js":"3.2.0",deepmerge:"^1.5.2",eventemitter3:"^4.0.7",jszip:"^3.10.1",katex:"^0.16.8","mdast-util-from-markdown":"^1.3.0","pdf-lib":"^1.17.1",quill:"^2.0.3",tern:"^0.24.3",uuid:"^9.0.0",ws:"^7.5.9","xml-js":"^1.6.11","y-webrtc":"^10.2.5",yjs:"^13.6.8"},keywords:["javascript","svg","mind-map","mindMap","MindMap"],devDependencies:{eslint:"^8.25.0",prettier:"^2.7.1"}}});var Bp,cb,ub=T(()=>{pe();Ge();hb();Bp=class{constructor(e={}){this.opt=e,this.mindMap=e.mindMap,this.commands={},this.history=[],this.activeHistoryIndex=0,this.registerShortcutKeys(),this.originAddHistory=this.addHistory.bind(this),this.addHistory=Ai(this.addHistory,this.mindMap.opt.addHistoryTime,this),this.isPause=!1}pause(){this.isPause=!0}recovery(){this.isPause=!1}clearHistory(){this.history=[],this.activeHistoryIndex=0,this.mindMap.emit("back_forward",0,0)}registerShortcutKeys(){this.mindMap.keyCommand.addShortcut("Control+z",()=>{this.mindMap.execCommand("BACK")}),this.mindMap.keyCommand.addShortcut("Control+y",()=>{this.mindMap.execCommand("FORWARD")})}exec(e,...t){if(this.commands[e]){if(this.commands[e].forEach(r=>{r(...t)}),this.mindMap.emit("afterExecCommand",e,...t),["BACK","FORWARD","SET_NODE_ACTIVE","CLEAR_ACTIVE_NODE"].includes(e))return;this.addHistory()}}add(e,t){this.commands[e]?this.commands[e].push(t):this.commands[e]=[t]}remove(e,t){if(this.commands[e])if(!t)this.commands[e]=[],delete this.commands[e];else{let r=this.commands[e].find(n=>n===t);r!==-1&&this.commands[e].splice(r,1)}}addHistory(){if(this.mindMap.opt.readonly||this.isPause)return;this.mindMap.emit("beforeAddHistory");let e=this.history.length>0?this.history[this.activeHistoryIndex]:null,t=this.getCopyData(),r=JSON.stringify(t);e&&e===r||(this.emitDataUpdatesEvent(e,r),this.history=this.history.slice(0,this.activeHistoryIndex+1),this.history.push(r),this.history.length>this.mindMap.opt.maxHistoryCount&&this.history.shift(),this.activeHistoryIndex=this.history.length-1,this.mindMap.emit("data_change",t),this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length))}back(e=1){if(!this.mindMap.opt.readonly&&this.activeHistoryIndex-e>=0){let t=this.history[this.activeHistoryIndex];this.activeHistoryIndex-=e,this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length);let r=this.history[this.activeHistoryIndex],n=JSON.parse(r);return this.emitDataUpdatesEvent(t,r),n}}forward(e=1){if(this.mindMap.opt.readonly)return;let t=this.history.length;if(this.activeHistoryIndex+e<=t-1){let r=this.history[this.activeHistoryIndex];this.activeHistoryIndex+=e,this.mindMap.emit("back_forward",this.activeHistoryIndex,this.history.length);let n=this.history[this.activeHistoryIndex],s=JSON.parse(n);return this.emitDataUpdatesEvent(r,n),s}}getCopyData(){if(!this.mindMap.renderer.renderTree)return null;let e=Tu({},this.mindMap.renderer.renderTree,!0);return e.smmVersion=db.version,e}removeDataUid(e){e=Qt(e);let t=r=>{delete r.data.uid,r.children&&r.children.length>0&&r.children.forEach(n=>{t(n)})};return t(e),e}emitDataUpdatesEvent(e,t){try{let r="data_change_detail";if(this.mindMap.event.listenerCount(r)>0&&e&&t){let s=JSON.parse(e),a=JSON.parse(t),o=Qt(_u(s)),l=Qt(_u(a)),h=[],d=(c,f)=>(c.children&&c.children.length>0&&c.children.forEach((m,g)=>{c.children[g]=typeof m=="string"?f[m]:f[m.data.uid],d(c.children[g],f)}),c);Object.keys(l).forEach(c=>{o[c]?X0(o[c],l[c])||h.push({action:"update",oldData:d(o[c],o),data:d(l[c],l)}):h.push({action:"create",data:d(l[c],l)})}),Object.keys(o).forEach(c=>{l[c]||h.push({action:"delete",data:d(o[c],o)})}),this.mindMap.emit(r,h)}}catch(r){this.mindMap.opt.errorHandler(Ti.DATA_CHANGE_DETAIL_EVENT_ERROR,r)}}},cb=Bp});var Pp,fb,mb=T(()=>{pe();Pp=class{constructor(){this.has={},this.queue=[],this.nextTick=L2(this.flush,this)}push(e,t){if(this.has[e]){this.replaceTask(e,t);return}this.has[e]=!0,this.queue.push({name:e,fn:t}),this.nextTick()}replaceTask(e,t){let r=this.queue.findIndex(n=>n.name===e);r!==-1&&(this.queue[r]={name:e,fn:t})}flush(){let e=this.queue.slice(0);this.queue=[],e.forEach(({name:t,fn:r})=>{this.has[t]=!1,r()})}},fb=Pp});var Fp,pb=T(()=>{Ge();Fp={el:null,data:null,viewData:null,readonly:!1,layout:C.LAYOUT.LOGICAL_STRUCTURE,fishboneDeg:45,theme:"default",themeConfig:{},scaleRatio:.2,translateRatio:1,minZoomRatio:20,maxZoomRatio:400,customCheckIsTouchPad:null,mouseScaleCenterUseMousePosition:!0,maxTag:5,expandBtnSize:20,imgTextMargin:5,textContentMargin:2,customNoteContentShow:null,textAutoWrapWidth:500,customHandleMousewheel:null,mousewheelAction:C.MOUSE_WHEEL_ACTION.MOVE,mousewheelMoveStep:100,mousewheelZoomActionReverse:!0,defaultInsertSecondLevelNodeText:"\u4E8C\u7EA7\u8282\u70B9",defaultInsertBelowSecondLevelNodeText:"\u5206\u652F\u4E3B\u9898",expandBtnStyle:{color:"#808080",fill:"#fff",fontSize:13,strokeColor:"#333333"},expandBtnIcon:{open:"",close:""},expandBtnNumHandler:null,isShowExpandNum:!0,enableShortcutOnlyWhenMouseInSvg:!0,customCheckEnableShortcut:null,initRootNodePosition:null,nodeTextEditZIndex:3e3,nodeNoteTooltipZIndex:3e3,isEndNodeTextEditOnClickOuter:!0,maxHistoryCount:500,alwaysShowExpandBtn:!1,notShowExpandBtn:!1,iconList:[],maxNodeCacheCount:1e3,fitPadding:50,enableCtrlKeyNodeSelection:!0,useLeftKeySelectionRightKeyDrag:!1,beforeTextEdit:null,isUseCustomNodeContent:!1,customCreateNodeContent:null,customInnerElsAppendTo:null,enableAutoEnterTextEditWhenKeydown:!1,autoEmptyTextWhenKeydownEnterEdit:!1,customHandleClipboardText:null,disableMouseWheelZoom:!1,errorHandler:(i,e)=>{console.error(i,e)},enableDblclickBackToRootNode:!1,hoverRectColor:"rgb(94, 200, 248)",hoverRectPadding:2,selectTextOnEnterEditText:!1,deleteNodeActive:!0,fit:!1,tagsColorMap:{},cooperateStyle:{avatarSize:22,fontSize:12},onlyOneEnableActiveNodeOnCooperate:!1,defaultGeneralizationText:"\u6982\u8981",handleIsSplitByWrapOnPasteCreateNewNode:null,addHistoryTime:100,isDisableDrag:!1,createNewNodeBehavior:C.CREATE_NEW_NODE_BEHAVIOR.DEFAULT,defaultNodeImage:"",isLimitMindMapInCanvas:!1,handleNodePasteImg:null,customCreateNodePath:null,customCreateNodePolygon:null,customTransformNodeLinePath:null,beforeShortcutRun:null,resetScaleOnMoveNodeToCenter:!1,createNodePrefixContent:null,createNodePostfixContent:null,disabledClipboard:!1,customHyperlinkJump:null,openPerformance:!1,performanceConfig:{time:250,padding:100,removeNodeWhenOutCanvas:!0},emptyTextMeasureHeightText:"abc123\u6211\u548C\u4F60",openRealtimeRenderOnNodeTextEdit:!1,mousedownEventPreventDefault:!1,onlyPasteTextWhenHasImgAndText:!0,enableDragModifyNodeWidth:!0,minNodeTextModifyWidth:20,maxNodeTextModifyWidth:-1,customHandleLine:null,addHistoryOnInit:!0,noteIcon:{icon:"",style:{}},hyperlinkIcon:{icon:"",style:{}},attachmentIcon:{icon:"",style:{}},isShowCreateChildBtnIcon:!0,quickCreateChildBtnIcon:{icon:"",style:{}},customQuickCreateChildBtnClick:null,addCustomContentToNode:null,enableInheritAncestorLineStyle:!0,selectTranslateStep:3,selectTranslateLimit:20,enableFreeDrag:!1,autoMoveWhenMouseInEdgeOnDrag:!0,dragMultiNodeRectConfig:{width:40,height:20,fill:"rgb(94, 200, 248)"},dragPlaceholderRectFill:"rgb(94, 200, 248)",dragPlaceholderLineConfig:{color:"rgb(94, 200, 248)",width:2},dragOpacityConfig:{cloneNodeOpacity:.5,beingDragNodeOpacity:.3},handleDragCloneNode:null,beforeDragEnd:null,beforeDragStart:null,watermarkConfig:{onlyExport:!1,text:"",lineSpacing:100,textSpacing:100,angle:30,textStyle:{color:"#999",opacity:.5,fontSize:14},belowNode:!1},exportPaddingX:10,exportPaddingY:10,resetCss:` * { margin: 0; padding: 0; box-sizing: border-box; } - `,minExportImgCanvasScale:2,addContentToHeader:null,addContentToFooter:null,handleBeingExportSvg:null,maxCanvasSize:16384,defaultAssociativeLineText:"\u5173\u8054",associativeLineIsAlwaysAboveNode:!0,associativeLineInitPointsPosition:{from:"",to:""},enableAdjustAssociativeLinePoints:!0,beforeAssociativeLineConnection:null,disableTouchZoom:!1,minTouchZoomScale:20,maxTouchZoomScale:-1,isLimitMindMapInCanvasWhenHasScrollbar:!0,isOnlySearchCurrentRenderNodes:!1,beforeCooperateUpdate:null,rainbowLinesConfig:{open:!1,colorsList:[]},demonstrateConfig:null,enableEditFormulaInRichTextEdit:!0,katexFontPath:"https://unpkg.com/katex@0.16.11/dist/",getKatexOutputType:null,transformRichTextOnEnterEdit:null,beforeHideRichTextEdit:null,outerFramePaddingX:10,outerFramePaddingY:10,defaultOuterFrameText:"\u5916\u6846",onlyPainterNodeCustomStyles:!1,beforeDeleteNodeImg:null,imgResizeBtnSize:25,minImgResizeWidth:50,minImgResizeHeight:50,maxImgResizeWidthInheritTheme:!1,maxImgResizeWidth:1/0,maxImgResizeHeight:1/0,customDeleteBtnInnerHTML:"",customResizeBtnInnerHTML:""}});var ib={};tt(ib,{default:()=>HP});var Cp,_t,_p,HP,rb=T(()=>{Tv();kv();Gv();Cp=pt(O0());Vv();Y0();Yv();Qv();eb();$e();yt();pe();Ro();tb();_t=class i{constructor(e={}){if(i.instanceCount++,this.opt=this.handleOpt((0,Cp.default)(kp,e)),this.opt.data=this.handleData(this.opt.data),this.el=this.opt.el,!this.el)throw new Error("\u7F3A\u5C11\u5BB9\u5668\u5143\u7D20el");this.getElRectInfo(),this.initWidth=this.width,this.initHeight=this.height,this.cssEl=null,this.cssTextMap={},this.nodeInnerPrefixList=[],this.nodeInnerPostfixList=[],this.editNodeClassList=[],this.extendShapeList=[],this.initContainer(),this.initTheme(),this.initCache(),i.pluginList.filter(t=>t.preload).forEach(t=>{this.initPlugin(t)}),this.event=new Av({mindMap:this}),this.keyCommand=new h0({mindMap:this}),this.command=new Zv({mindMap:this}),this.renderer=new jv({mindMap:this}),this.view=new Mv({mindMap:this}),this.batchExecution=new Jv,i.pluginList.filter(t=>!t.preload).forEach(t=>{this.initPlugin(t)}),this.addCss(),this.render(this.opt.fit?()=>this.view.fit():()=>{}),this.opt.addHistoryOnInit&&this.opt.data&&this.command.addHistory()}handleOpt(e){return $c.includes(e.layout)||(e.layout=k.LAYOUT.LOGICAL_STRUCTURE),e.theme=e.theme&&jn[e.theme]?e.theme:"default",e}handleData(e){return Yt(e)||Object.keys(e).length<=0?null:(e=Kt(e||{}),e.data&&!e.data.expand&&(e.data.expand=!0),cs([e],!1,null,!0),e)}initContainer(){let{associativeLineIsAlwaysAboveNode:e}=this.opt;this.el.classList.add("smm-mind-map-container");let t=()=>{this.associativeLineDraw=this.draw.group(),this.associativeLineDraw.addClass("smm-associative-line-container")};this.svg=Ae().addTo(this.el).size(this.width,this.height),this.draw=this.svg.group(),this.draw.addClass("smm-container"),this.lineDraw=this.draw.group(),this.lineDraw.addClass("smm-line-container"),e||t(),this.nodeDraw=this.draw.group(),this.nodeDraw.addClass("smm-node-container"),e&&t(),this.otherDraw=this.draw.group(),this.otherDraw.addClass("smm-other-container")}clearDraw(){this.lineDraw.clear(),this.associativeLineDraw.clear(),this.nodeDraw.clear(),this.otherDraw.clear()}appendCss(e,t){this.cssTextMap[e]=t,this.removeCss(),this.addCss()}removeAppendCss(e){this.cssTextMap[e]&&(delete this.cssTextMap[e],this.removeCss(),this.addCss())}joinCss(){return C3+Object.keys(this.cssTextMap).map(e=>this.cssTextMap[e]).join(` -`)}addCss(){this.cssEl=document.createElement("style"),this.cssEl.type="text/css",this.cssEl.innerHTML=this.joinCss(),document.head.appendChild(this.cssEl)}removeCss(){this.cssEl&&document.head.removeChild(this.cssEl)}checkEditNodeClassIndex(e){return this.editNodeClassList.findIndex(t=>t===e)}addEditNodeClass(e){this.checkEditNodeClassIndex(e)===-1&&this.editNodeClassList.push(e)}deleteEditNodeClass(e){let t=this.checkEditNodeClassIndex(e);t!==-1&&this.editNodeClassList.splice(t,1)}render(e,t=""){this.initTheme(),this.renderer.render(e,t)}reRender(e,t=""){this.renderer.reRender=!0,this.renderer.clearCache(),this.clearDraw(),this.render(e,t)}getElRectInfo(){if(this.elRect=this.el.getBoundingClientRect(),this.width=this.elRect.width,this.height=this.elRect.height,this.width<=0||this.height<=0)throw new Error("\u5BB9\u5668\u5143\u7D20el\u7684\u5BBD\u9AD8\u4E0D\u80FD\u4E3A0")}resize(){let e=this.width,t=this.height;this.getElRectInfo(),this.svg.size(this.width,this.height),(e!==this.width||t!==this.height)&&(this.demonstrate?this.demonstrate.isInDemonstrate||this.render():this.render()),this.emit("resize")}on(e,t){this.event.on(e,t)}emit(e,...t){this.event.emit(e,...t)}off(e,t){this.event.off(e,t)}initCache(){this.commonCaches={measureCustomNodeContentSizeEl:null,measureRichtextNodeTextSizeEl:null}}initTheme(){this.themeConfig=wu(jn[this.opt.theme]||jn.default,this.opt.themeConfig),qo.setBackgroundStyle(this.el,this.themeConfig)}setTheme(e,t=!1){this.execCommand("CLEAR_ACTIVE_NODE"),this.opt.theme=e,t||this.render(null,k.CHANGE_THEME),this.emit("view_theme_change",e)}getTheme(){return this.opt.theme}setThemeConfig(e,t=!1){let r=N2(this.themeConfig,e);if(this.opt.themeConfig=e,!t){let n=u2(r);this.render(null,n?"":k.CHANGE_THEME)}}getCustomThemeConfig(){return this.opt.themeConfig}getThemeConfig(e){return e===void 0?this.themeConfig:this.themeConfig[e]}getConfig(e){return e===void 0?this.opt:this.opt[e]}updateConfig(e={}){this.emit("before_update_config",this.opt);let t={...this.opt};this.opt=this.handleOpt(Cp.default.all([kp,this.opt,e])),this.emit("after_update_config",this.opt,t)}getLayout(){return this.opt.layout}setLayout(e,t=!1){$c.includes(e)||(e=k.LAYOUT.LOGICAL_STRUCTURE),this.opt.layout=e,this.view.reset(),this.renderer.setLayout(),t||this.render(null,k.CHANGE_LAYOUT),this.emit("layout_change",e)}execCommand(...e){this.command.exec(...e)}updateData(e){e=this.handleData(e),this.emit("before_update_data",e),this.renderer.setData(e),this.render(),this.command.addHistory(),this.emit("update_data",e)}setData(e){e=this.handleData(e),this.emit("before_set_data",e),this.opt.data=e,this.execCommand("CLEAR_ACTIVE_NODE"),this.command.clearHistory(),this.command.addHistory(),this.renderer.setData(e),this.reRender(),this.emit("set_data",e)}setFullData(e){e.root&&this.setData(e.root),e.layout&&this.setLayout(e.layout),e.theme&&(e.theme.template&&this.setTheme(e.theme.template),e.theme.config&&this.setThemeConfig(e.theme.config)),e.view&&this.view.setTransformData(e.view)}getData(e){let t=this.command.getCopyData(),r={};return e?r={layout:this.getLayout(),root:t,theme:{template:this.getTheme(),config:this.getCustomThemeConfig()},view:this.view.getTransformData()}:r=t,Kt(r)}async export(...e){try{if(!this.doExport)throw new Error("\u8BF7\u6CE8\u518CExport\u63D2\u4EF6\uFF01");return await this.doExport.export(...e)}catch(t){this.opt.errorHandler(Mi.EXPORT_ERROR,t)}}toPos(e,t){return{x:e-this.elRect.left,y:t-this.elRect.top}}setMode(e){if(![k.MODE.READONLY,k.MODE.EDIT].includes(e))return;let t=e===k.MODE.READONLY;t!==this.opt.readonly&&(t&&(this.renderer.textEdit.isShowTextEdit()&&(this.renderer.textEdit.hideEditTextBox(),this.command.originAddHistory()),this.execCommand("CLEAR_ACTIVE_NODE")),this.opt.readonly=t,!t&&this.command.history.length<=0&&this.command.originAddHistory(),this.emit("mode_change",e))}getSvgData({paddingX:e=0,paddingY:t=0,ignoreWatermark:r=!1,addContentToHeader:n,addContentToFooter:s,node:a}={}){let{watermarkConfig:o,openPerformance:l}=this.opt;l&&this.renderer.forceLoadNode(a);let{cssTextList:h,header:d,headerHeight:c,footer:f,footerHeight:m}=R2({addContentToHeader:n,addContentToFooter:s}),g=this.svg,x=this.draw,y=g.width(),b=g.height(),S=x.transform(),A=this.elRect;x.scale(1/S.scaleX,1/S.scaleY);let C=x.rbox(),I=null;a&&(I=bu(a,C.x,C.y,e,t));let O=0;C.width+=e*2,C.height+=t*2+O+c+m,x.translate(e,t),g.size(C.width,C.height),x.translate(-C.x+A.left,-C.y+A.top);let q=g.clone(),P=this.watermark&&this.watermark.hasWatermark();if(!r&&P){this.watermark.isInExport=!0;let{onlyExport:re}=o;C.width>y||C.height>b?(this.width=C.width,this.height=C.height,this.watermark.onResize(),q=g.clone(),this.width=y,this.height=b,this.watermark.onResize()):re&&(this.watermark.onResize(),q=g.clone()),re&&this.watermark.clear(),this.watermark.isInExport=!1}[this.joinCss(),...h].forEach(re=>{q.add(Ae(``))}),d&&c>0&&(q.findOne(".smm-container").translate(0,c),d.width(C.width),d.y(t),q.add(d,0)),f&&m>0&&(f.width(C.width),f.y(C.height-t-m),q.add(f));let W=g.find("defs"),ne=q.find("defs");return W.forEach((re,oe)=>{let ke=ne[oe];if(!ke)return;let Q=re.children(),Y=ke.children();for(let le=0;ler.name===e.name)||this.extendShapeList.push(e)}removeShape(e){let t=this.extendShapeList.findIndex(r=>r.name===e);t!==-1&&this.extendShapeList.splice(t,1)}getSvgObjects(){return{SVG:Ae,G:_e,Rect:Ve}}addPlugin(e,t){i.hasPlugin(e)===-1&&i.usePlugin(e,t),this.initPlugin(e)}removePlugin(e){let t=i.hasPlugin(e);t!==-1&&(i.pluginList.splice(t,1),this[e.instanceName]&&(this[e.instanceName].beforePluginRemove&&this[e.instanceName].beforePluginRemove(),delete this[e.instanceName]))}initPlugin(e){this[e.instanceName]||(this[e.instanceName]=new e({mindMap:this,pluginOpt:e.pluginOpt}))}destroy(){this.emit("beforeDestroy"),this.renderer.textEdit.hideEditTextBox(),this.renderer.textEdit.removeTextEditEl(),[...i.pluginList].forEach(e=>{this[e.instanceName]&&this[e.instanceName].beforePluginDestroy&&this[e.instanceName].beforePluginDestroy(),this[e.instanceName]=null}),this.event.unbind(),this.svg.remove(),qo.removeBackgroundStyle(this.el),this.el.classList.remove("smm-mind-map-container"),this.el.innerHTML="",this.el=null,this.removeCss(),i.instanceCount--}},_p=[];_t.extendNodeDataNoStylePropList=(i=[])=>{_p.push(...i),$s.push(...i)};_t.resetNodeDataNoStylePropList=()=>{_p.forEach(i=>{let e=$s.findIndex(t=>t===i);e!==-1&&$s.splice(e,1)}),_p=[]};_t.pluginList=[];_t.usePlugin=(i,e={})=>(_t.hasPlugin(i)!==-1||(i.pluginOpt=e,_t.pluginList.push(i)),_t);_t.hasPlugin=i=>_t.pluginList.findIndex(e=>e===i);_t.instanceCount=0;_t.defineTheme=(i,e={})=>{if(jn[i])return new Error("\u8BE5\u4E3B\u9898\u540D\u79F0\u5DF2\u5B58\u5728");jn[i]=wu(B0,e)};_t.removeTheme=i=>{jn[i]&&(jn[i]=null)};HP=_t});var Ic=globalThis.__LEPTOS_TIPTAP_BRIDGE__;if(Ic==null||Ic.modules==null)throw new Error("leptos-tiptap bridge bindings are unavailable");var j=Ic.modules["@tiptap/core"];if(j==null)throw new Error('leptos-tiptap bridge module "@tiptap/core" is unavailable');var tq=j.CommandManager,iq=j.Editor,rq=j.Extension,nq=j.InputRule,sq=j.Mark,f3=j.Node,aq=j.NodePos,oq=j.NodeView,lq=j.PasteRule,hq=j.Tracker,dq=j.callOrReturn,cq=j.canInsertNode,uq=j.combineTransactionSteps,fq=j.createChainableState,mq=j.createDocument,pq=j.createNodeFromContent,gq=j.createStyleTag,xq=j.defaultBlockAt,yq=j.deleteProps,vq=j.elementFromString,bq=j.escapeForRegEx,wq=j.extensions,Mq=j.findChildren,Tq=j.findChildrenInRange,Nq=j.findDuplicates,Eq=j.findParentNode,Sq=j.findParentNodeClosestToPos,Aq=j.fromString,kq=j.generateHTML,Cq=j.generateJSON,_q=j.generateText,Lq=j.getAttributes,Iq=j.getAttributesFromExtensions,zq=j.getChangedRanges,Rq=j.getDebugJSON,Dq=j.getExtensionField,Oq=j.getHTMLFromFragment,Bq=j.getMarkAttributes,Pq=j.getMarkRange,Fq=j.getMarkType,qq=j.getMarksBetween,Hq=j.getNodeAtPosition,Uq=j.getNodeAttributes,$q=j.getNodeType,jq=j.getRenderedAttributes,Gq=j.getSchema,Vq=j.getSchemaByResolvedExtensions,Wq=j.getSchemaTypeByName,Yq=j.getSchemaTypeNameByName,Xq=j.getSplittedAttributes,Kq=j.getText,Zq=j.getTextBetween,Qq=j.getTextContentFromNodes,Jq=j.getTextSerializersFromSchema,eH=j.injectExtensionAttributesToParseRule,tH=j.inputRulesPlugin,iH=j.isActive,rH=j.isAtEndOfNode,nH=j.isAtStartOfNode,sH=j.isEmptyObject,aH=j.isExtensionRulesEnabled,oH=j.isFunction,lH=j.isList,hH=j.isMacOS,dH=j.isMarkActive,cH=j.isNodeActive,uH=j.isNodeEmpty,fH=j.isNodeSelection,mH=j.isNumber,pH=j.isPlainObject,gH=j.isRegExp,xH=j.isSafari,yH=j.isString,vH=j.isTextSelection,bH=j.isiOS,wH=j.markInputRule,MH=j.markPasteRule,m3=j.mergeAttributes,TH=j.mergeDeep,NH=j.minMax,EH=j.nodeInputRule,SH=j.nodePasteRule,AH=j.objectIncludes,kH=j.pasteRulesPlugin,CH=j.posToDOMRect,_H=j.removeDuplicates,LH=j.resolveFocusPosition,IH=j.rewriteUnknownContent,zH=j.selectionToInsertionEnd,RH=j.splitExtensions,DH=j.textInputRule,OH=j.textPasteRule,BH=j.textblockTypeInputRule,PH=j.wrappingInputRule;var p3=f3.create({name:"paragraph",priority:1e3,addOptions(){return{HTMLAttributes:{}}},group:"block",content:"inline*",parseHTML(){return[{tag:"p"}]},renderHTML({HTMLAttributes:i}){return["p",m3(this.options.HTMLAttributes,i),0]},addCommands(){return{setParagraph:()=>({commands:i})=>i.setNode(this.name)}},addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setParagraph()}}});var g3="__LEPTOS_TIPTAP_BRIDGE__";function nw(){let i=globalThis,e=i[g3];if(e!=null)return e;let t={modules:{},registerExtension:()=>{throw new Error("leptos-tiptap bridge runtime is not initialized")}};return i[g3]=t,t}function x3(){return nw()}function y3(i){x3().registerExtension(i)}var Dc={};tt(Dc,{applyMetadataOnlyMindmapCommands:()=>M3,applyMindmapCommandsLocally:()=>hw,isLocallyApplicableMindmapCommandSet:()=>lw,isMetadataOnlyMindmapCommandSet:()=>ow});var sw={data:{text:"\u4E2D\u5FC3\u4E3B\u9898"},children:[]},gt=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),nr=i=>JSON.parse(JSON.stringify(i)),b3=i=>{let e=gt(i)?nr(i):nr(sw);return gt(e.data)||(e.data={text:"\u4E2D\u5FC3\u4E3B\u9898"}),Array.isArray(e.children)||(e.children=[]),e},w3=(i,e)=>{if(!gt(i)||!gt(e))return nr(e);let t={...i};return Object.entries(e).forEach(([r,n])=>{if(n===null){delete t[r];return}t[r]=gt(t[r])&>(n)?w3(t[r],n):nr(n)}),t},zc=(i,e,t)=>{let r=e.split(".").filter(Boolean);if(r.length===0)return!1;let n=i;for(let s of r.slice(0,-1))gt(n[s])||(n[s]={}),n=n[s];return n[r[r.length-1]]=nr(t),!0},N0=(i,e)=>{if(!gt(i))return null;let t=gt(i.data)?i.data:null;if(typeof t?.uid=="string"&&t.uid===e)return i;let r=Array.isArray(i.children)?i.children:[];for(let n of r){let s=N0(n,e);if(s)return s}return null},Rc=(i,e)=>{for(let t=0;t({data:{uid:i.uid??`node_${Date.now().toString(36)}`,text:i.text,...typeof i.hyperlink=="string"?{hyperlink:i.hyperlink}:{},...typeof i.note=="string"?{note:i.note}:{},...Array.isArray(i.refs)?{refs:nr(i.refs)}:{}},children:[]}),aw=(i,e)=>{let t=String(e.path||"").trim();if(!t)return!1;if(t.startsWith("root.data.")){let n=t.slice(10),s=gt(i.data)?i.data:i.data={};return zc(s,n,e.value)}if(t.startsWith("nodes.")){let[,n,s,...a]=t.split(".");if(!n||s!=="data"||a.length===0)return!1;let o=N0(i,n);if(!o)return!1;let l=gt(o.data)?o.data:o.data={};return zc(l,a.join("."),e.value)}let r=gt(i.compatPayload)?i.compatPayload:i.compatPayload={};return zc(r,t,e.value)},ow=i=>Array.isArray(i)&&i.every(e=>!gt(e)||typeof e.type!="string"?!1:["setLayout","setTheme","patchView","compatPayloadPatch"].includes(e.type)),lw=i=>Array.isArray(i)&&i.every(e=>!gt(e)||typeof e.type!="string"?!1:["updateText","insertChild","insertSiblingAfter","deleteNode","setLayout","setTheme","patchView","compatPayloadPatch"].includes(e.type)),M3=(i,e)=>{let t=b3(i),r=[],n=0;return e.forEach(s=>{if(s.type==="setLayout"){t.layout=nr(s.layout),n+=1;return}if(s.type==="setTheme"){t.theme=nr(s.theme),s.themeConfig!==void 0&&s.themeConfig!==null&&(t.themeConfig=nr(s.themeConfig)),n+=1;return}if(s.type==="patchView"){t.view=w3(t.view??{},s.patch),n+=1;return}s.type==="compatPayloadPatch"&&(aw(t,s)?n+=1:r.push(`\u65E0\u6CD5\u5E94\u7528 compatPayloadPatch:${s.path}`))}),{applied:n,data:t,errors:r}},hw=(i,e)=>{let t=b3(i),r=[],n=0;return e.forEach(s=>{if(s.type==="setLayout"||s.type==="setTheme"||s.type==="patchView"||s.type==="compatPayloadPatch"){let a=M3(t,[s]);Object.assign(t,a.data),n+=a.applied,r.push(...a.errors);return}if(s.type==="updateText"){let a=N0(t,s.nodeId);if(!a){r.push(`\u672A\u627E\u5230\u8282\u70B9:${s.nodeId}`);return}let o=gt(a.data)?a.data:a.data={};o.text=s.text,n+=1;return}if(s.type==="insertChild"){let a=N0(t,s.parentNodeId);if(!a){r.push(`\u672A\u627E\u5230\u7236\u8282\u70B9:${s.parentNodeId}`);return}(Array.isArray(a.children)?a.children:a.children=[]).push(v3(s.node)),n+=1;return}if(s.type==="insertSiblingAfter"){let a=Rc([t],s.targetNodeId);if(!a){r.push(`\u672A\u627E\u5230\u540C\u7EA7\u8282\u70B9:${s.targetNodeId}`);return}if(a.parentChildren[a.index]===t){r.push("\u6839\u8282\u70B9\u4E0D\u652F\u6301\u63D2\u5165\u540C\u7EA7\u8282\u70B9");return}a.parentChildren.splice(a.index+1,0,v3(s.node)),n+=1;return}if(s.type==="deleteNode"){let a=Rc([t],s.nodeId);if(!a){r.push(`\u672A\u627E\u5230\u5220\u9664\u8282\u70B9:${s.nodeId}`);return}if(a.parentChildren[a.index]===t){r.push("\u6839\u8282\u70B9\u4E0D\u652F\u6301\u5220\u9664");return}a.parentChildren.splice(a.index,1),n+=1}}),{applied:n,data:t,errors:r}};var Dp={};tt(Dp,{MindmapCommandBridgeError:()=>lo,createLeptosMindmapAdapter:()=>rF,createMindmapAdapterProjectionEndpoint:()=>lb,createMindmapCommandApplyEndpoint:()=>zp,executeMindmapCommandApply:()=>hb,executeMindmapCommandApplyAndRefreshProjection:()=>tF,executeMindmapDataPutAndRefreshProjection:()=>iF,isMindmapAdapterProjection:()=>Ip,requestMindmapAdapterProjection:()=>Rp});var Pc={};tt(Pc,{DEFAULT_MINDMAP_LAYOUT:()=>E0,DEFAULT_MINDMAP_THEME:()=>S0,buildMindmapEditorScene:()=>cw,buildMindmapProjection:()=>dw,buildMindmapSimpleMindMapScene:()=>uw,canonicalizeMindmapData:()=>ci,createDefaultMindmapThemeConfig:()=>A0,defaultMindmapData:()=>Us,extractMindmapTitle:()=>Bc,normalizeMindmapData:()=>Oc,summarizeMindmapProjectionNodes:()=>T3});var Us={data:{text:"\u4E2D\u5FC3\u4E3B\u9898"},children:[]},E0="logicalStructure",S0="default",A0=()=>({lineColor:"#7aa2ff",lineStyle:"curve",rootLineKeepSameInCurve:!0,rootLineStartPositionKeepSameInCurve:!0,generalizationLineColor:"#ef6a5b",backgroundColor:"#f6f8fc",root:{fillColor:"#e25563",color:"#ffffff",fontWeight:"bold",borderColor:"transparent",borderWidth:0,borderRadius:8},second:{fillColor:"#4f7df3",color:"#ffffff",borderColor:"transparent",borderWidth:0,borderRadius:8},node:{fillColor:"transparent",color:"#315aa9",borderColor:"transparent",borderWidth:0},generalization:{fillColor:"#ffffff",color:"#ef6a5b",borderColor:"#ef6a5b",borderWidth:1,borderRadius:8}}),Hs=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),Oc=i=>{if(!i||typeof i!="object")return Us;let e=i.root??i,t=r=>{if(!Hs(r))return;let n=Hs(r.data)?r.data:{};r.data=n;let s=n.text;n.text=typeof s=="string"?s:String(s??"");let a=n.generalization,o=l=>{if(!Hs(l))return;let h=l.text;l.text=typeof h=="string"?h:String(h??"")};Array.isArray(a)?a.forEach(o):o(a),Array.isArray(r.children)&&r.children.forEach(t)};return t(e),i},ci=i=>{let e=Oc(i)??Us,t=e&&typeof e=="object"&&"root"in e?e.root:e;return Oc(t)??Us},Bc=i=>{let t=ci(i)?.data?.text;return typeof t=="string"&&t.trim()?t.trim():"\u672A\u547D\u540D\u5BFC\u56FE"},T3=i=>{let t=[{node:ci(i),depth:0}],r=[];for(;t.length>0;){let n=t.shift();if(!n)break;let s=n.node?.data?.uid,a=n.node?.data?.text,o=Array.isArray(n.node?.children)?n.node.children:[];r.push({uid:typeof s=="string"&&s.trim()?s:`depth:${n.depth}:index:${r.length}`,text:typeof a=="string"&&a.trim()?a.trim():"\u672A\u547D\u540D\u8282\u70B9",depth:n.depth,childCount:o.length}),o.forEach(l=>{t.push({node:ci(l),depth:n.depth+1})})}return r},dw=i=>{let e=ci(i.data),t=T3(e),r=Hs(i.meta)?i.meta:null,n=t[0]?.uid??null;return{schema:"mnote.mindmap_projection.v1",projectionId:`mindmap_projection:${i.documentId}:${i.mindmapId}`,projection:"mindmap_subtree",source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:n,title:Bc(e),nodeCount:t.length,nodes:t,data:e,meta:r}},cw=i=>{let e=ci(i.data),t=Hs(i.meta)?i.meta:null,r=[],n=[],s=(l,h,d)=>{let c=l?.data?.uid,f=l?.data?.text,m=typeof c=="string"&&c.trim()?c.trim():`depth:${h}:index:${r.length}`,g=Array.isArray(l?.children)?l.children:[];r.push({id:m,uid:m,text:typeof f=="string"&&f.trim()?f.trim():"\u672A\u547D\u540D\u8282\u70B9",depth:h,childCount:g.length,parentId:d}),d&&n.push({id:`${d}->${m}`,source:d,target:m}),g.forEach(x=>{s(ci(x),h+1,m)})};s(e,0,null);let a=r[0]?.id??null,o=i.rootNodeId&&i.rootNodeId.trim()?i.rootNodeId.trim():a;return{schema:"mnote.mindmap_editor_scene.v1",source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:o,title:Bc(e),nodes:r,edges:n,capabilities:{canEditText:!0,canAddChild:!0,canAddSiblingAfter:!0,canDeleteNode:!0},data:e,meta:t}},uw=i=>{let e=ci(i.data),t=Hs(i.meta)?i.meta:null,r=e?.data?.uid,n=typeof r=="string"&&r.trim()?r.trim():"root";return e.data.uid||(e.data.uid=n),{schema:"mnote.mindmap.simple_mind_map_scene.v1",runtime:"simple-mind-map",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:n,root:e,layout:E0,theme:S0,themeConfig:A0(),view:{x:0,y:0,scale:1},config:{},compatPayload:{},kernelRevision:1,source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",meta:t}};var UP=["Drag","KeyboardNavigation","Export","Select","AssociativeLine","Search","OuterFrame"],$P=["Scrollbar","MiniMap","Painter","Formula"],jP=["data_change","view_data_change","node_active","back_forward","scale","translate"],GP=new Set(["BACK","FORWARD","INSERT_NODE","INSERT_CHILD_NODE","REMOVE_NODE","DELETE_NODE","ADD_GENERALIZATION","ADD_OUTER_FRAME","SET_NOTATION"]),ao=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),nb=(i,e)=>{if(typeof i=="string"&&i.trim())return i.trim();if(ao(i)){let t=i.template;if(typeof t=="string"&&t.trim())return t.trim()}return e},sb=i=>ao(i)?i:{},ab=i=>!ao(i)||Object.keys(i).length===0?A0():i,VP=i=>!ao(i)||!ao(i.state)?null:{...i,state:i.state,transform:ao(i.transform)?i.transform:{}},WP=i=>{let e=ci(i.projection.root??Us),t=sb(i.projection.config),r=sb(i.runtimeOptions);return{...t,...r,el:i.el,data:e,fit:typeof r.fit=="boolean"?r.fit:typeof t.fit=="boolean"?t.fit:!0,layout:nb(i.projection.layout,E0),theme:nb(i.projection.theme,S0),themeConfig:ab(i.projection.themeConfig),viewData:VP(i.projection.view),initRootNodePosition:["center","center"]}},YP={Drag:()=>Promise.resolve().then(()=>(J2(),Q2)),KeyboardNavigation:()=>Promise.resolve().then(()=>(t6(),e6)),Export:()=>Promise.resolve().then(()=>(d6(),h6)),Select:()=>Promise.resolve().then(()=>(u6(),c6)),AssociativeLine:()=>Promise.resolve().then(()=>(b6(),v6)),Search:()=>Promise.resolve().then(()=>(M6(),w6)),OuterFrame:()=>Promise.resolve().then(()=>(k6(),A6)),Scrollbar:()=>Promise.resolve().then(()=>(_6(),C6)),MiniMap:()=>Promise.resolve().then(()=>(I6(),L6)),Painter:()=>Promise.resolve().then(()=>(R6(),z6)),Formula:()=>Promise.resolve().then(()=>(wv(),bv))},XP=()=>[...UP,...$P],KP=async(i=XP())=>{if(typeof window>"u"||typeof document>"u")throw new Error("simple_mind_map_browser_required");let[{default:e},t]=await Promise.all([Promise.resolve().then(()=>(rb(),ib)),Promise.all(i.map(async s=>[s,(await YP[s]()).default]))]),r=e,n=[];return t.forEach(([s,a])=>{if(!a||typeof r.usePlugin!="function")return;typeof r.hasPlugin=="function"&&r.hasPlugin(a)!==-1||r.usePlugin(a),n.push(s)}),{MindMap:r,registeredPlugins:n}},ZP=i=>(e,...t)=>{if(!GP.has(e))return{ok:!1,command:e,error:"unsupported_command"};if(typeof i.execCommand!="function")return{ok:!1,command:e,error:"runtime_unavailable"};try{return{ok:!0,command:e,result:i.execCommand(e,...t)}}catch{return{ok:!1,command:e,error:"command_failed"}}},QP=i=>{let e=[];return jP.forEach(t=>{let r=(...n)=>{let s=t==="data_change"?i.instance.getData?.():t==="view_data_change"?i.instance.getData?.(!0)??i.instance.getData?.():void 0;i.onEvent?.({type:t,args:n,snapshot:s,kernelRevision:i.projection.kernelRevision})};i.instance.on?.(t,r),e.push(()=>i.instance.off?.(t,r))}),()=>e.splice(0).forEach(t=>t())},ob=async i=>{let e=await KP(i.pluginNames),t=ab(i.projection.themeConfig),r=WP({el:i.el,projection:i.projection,runtimeOptions:i.runtimeOptions}),n=new e.MindMap(r);n.setThemeConfig?.(t),i.mode&&n.setMode?.(i.mode);let s=QP({instance:n,projection:i.projection,onEvent:i.onEvent}),a=ZP(n);return{instance:n,execCommand:a,getSnapshot:()=>n.getData?.(!0)??n.getData?.(),destroy:()=>{n.renderer?.textEdit?.hideEditTextBox?.(),s(),n.destroy?.()}}};var lo=class extends Error{constructor(e,t=null){super(e),this.name="MindmapCommandBridgeError",this.code="command_failed",this.status=t}},oo=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),Lp=i=>{if(!oo(i))return"";let e=[i.error,i.message,i.details].map(t=>typeof t=="string"?t.trim():Array.isArray(t)&&t.length>0?t.join("|"):"").find(Boolean);return e?`:${e}`:""},JP=async i=>{if(typeof i.text!="function"){let t=await i.json().catch(()=>null);return Lp(t)}let e=await i.text().catch(()=>"");if(!e.trim())return"";try{return Lp(JSON.parse(e))||`:${e.trim()}`}catch{return`:${e.trim()}`}},Ip=i=>oo(i)?i.schema==="mnote.mindmap.simple_mind_map_scene.v1"&&i.runtime==="simple-mind-map"&&"root"in i&&typeof i.kernelRevision=="number":!1,lb=(i,e)=>{let t=encodeURIComponent(i),r=encodeURIComponent(e);return`/api/mindmap/${t}/${r}?view=simple_mind_map_scene&queryName=mindmap.simple_mind_map_scene.get`},zp=(i,e)=>{let t=encodeURIComponent(i),r=encodeURIComponent(e);return`/api/mindmap/${t}/${r}`},Rp=async i=>{let e=i.fetcher??fetch,t=i.endpoint??lb(i.documentId,i.mindmapId),r=await e(t,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`projection_load_failed:${r.status}`);let n=await r.json(),s=oo(n)&&"result"in n?n.result:n;if(!Ip(s))throw new Error("projection_load_failed:invalid_adapter_projection");return s},eF=i=>{if(!oo(i))return null;let e=[i.kernelRevision,i.projectionRevision,oo(i.result)?i.result.kernelRevision:null,oo(i.result)?i.result.projectionRevision:null];for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t;return null},hb=async i=>{if(i.commands.length===0)throw new lo("command_failed:empty_commands");let e=i.fetcher??fetch,t=i.endpoint??zp(i.documentId,i.mindmapId),r=JSON.stringify({commandName:"mindmap.command.apply",documentId:i.documentId,mindmapId:i.mindmapId,commands:i.commands,projectionRevision:i.projectionRevision??null}),n=await e(t,{method:"POST",keepalive:r.length<=6e4,headers:{Accept:"application/json","Content-Type":"application/json"},body:r}),s=await n.json().catch(()=>null);if(!n.ok){let a=Lp(s);throw new lo(`command_failed:${n.status}${a}`,n.status)}return{ok:!0,kernelRevision:eF(s),raw:s}},tF=async i=>(await hb(i),Rp({documentId:i.documentId,mindmapId:i.mindmapId,endpoint:i.projectionEndpoint,fetcher:i.fetcher})),iF=async i=>{let e=i.fetcher??fetch,t=i.endpoint??zp(i.documentId,i.mindmapId),r=await e(t,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({data:i.data,createOnly:!1})});if(!r.ok){let n=await JP(r);throw new lo(`command_failed:${r.status}${n}`,r.status)}return await r.json().catch(()=>null),Rp({documentId:i.documentId,mindmapId:i.mindmapId,endpoint:i.projectionEndpoint,fetcher:e})},rF=async i=>{if(!Ip(i.projection))throw new Error("adapter_init_failed:invalid_projection");return ob(i)};var Fp={};tt(Fp,{createCompatPayloadPatch:()=>Tc,createLayoutCommand:()=>Pp,createThemeCommand:()=>Bp,createToolbarKernelCommand:()=>Op,createViewPatchCommand:()=>nF,diffMindmapRuntimeDataToKernelCommands:()=>hF});var db=i=>({text:i?.text?.trim()||"\u65B0\u8282\u70B9",...i?.uid?{uid:i.uid}:{},...i?.hyperlink?{hyperlink:i.hyperlink}:{},...i?.note?{note:i.note}:{},...i?.refs?{refs:i.refs}:{}}),Op=i=>{let e=i.activeNodeId?.trim();switch(i.runtimeCommand){case"INSERT_CHILD_NODE":return e?{type:"insertChild",mindmapId:i.mindmapId,parentNodeId:e,node:db(i.newNode)}:null;case"INSERT_NODE":return e?{type:"insertSiblingAfter",mindmapId:i.mindmapId,targetNodeId:e,node:db(i.newNode)}:null;case"REMOVE_NODE":case"DELETE_NODE":return e?{type:"deleteNode",mindmapId:i.mindmapId,nodeId:e}:null;case"ADD_GENERALIZATION":return{type:"compatPayloadPatch",mindmapId:i.mindmapId,path:"root.data.generalization",value:{text:"\u6982\u8981"},source:"toolbar"};case"ADD_OUTER_FRAME":return{type:"compatPayloadPatch",mindmapId:i.mindmapId,path:"outerFrame",value:{enabled:!0,activeNodeId:e},source:"toolbar"};default:return null}},nF=(i,e)=>({type:"patchView",mindmapId:i,patch:e}),Bp=(i,e,t)=>({type:"setTheme",mindmapId:i,theme:e,themeConfig:t}),Pp=(i,e)=>({type:"setLayout",mindmapId:i,layout:e}),Tc=i=>({type:"compatPayloadPatch",mindmapId:i.mindmapId,path:i.path,value:i.value,source:i.source,...i.actionId?{actionId:i.actionId}:{},...typeof i.runtimeRevision=="number"?{runtimeRevision:i.runtimeRevision}:{},...typeof i.kernelRevision=="number"?{kernelRevision:i.kernelRevision}:{}}),sF=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),aF=(i,e)=>{let t=i.data?.uid;return typeof t=="string"&&t.trim()?t.trim():e},oF=i=>{let e=i.data?.text;return typeof e=="string"?e:String(e??"")},cb=i=>{let e=ci(i),t=new Map,r=(n,s,a,o)=>{let l=aF(n,o),h=sF(n.data)?n.data:{};t.set(l,{uid:l,parentUid:s,order:a,text:oF(n),data:h,node:n}),(Array.isArray(n.children)?n.children:[]).forEach((c,f)=>{r(ci(c),l,f,`${o}.${f}`)})};return r(e,null,0,"root"),t},ub=i=>JSON.stringify(i??null),fb=i=>({uid:i.uid,text:i.text||"\u65B0\u8282\u70B9",...typeof i.data.hyperlink=="string"?{hyperlink:i.data.hyperlink}:{},...typeof i.data.note=="string"?{note:i.data.note}:{},...Array.isArray(i.data.refs)?{refs:i.data.refs}:{}}),lF=(i,e,t,r)=>{let n=new Set(["uid","text","refs"]);new Set([...Object.keys(e.data),...Object.keys(t.data)]).forEach(a=>{n.has(a)||ub(e.data[a])!==ub(t.data[a])&&r.push(Tc({mindmapId:i,path:`nodes.${t.uid}.data.${a}`,value:t.data[a],source:"adapter-diff"}))})},hF=i=>{let e=cb(i.previous),t=cb(i.next),r=[],n=[];return t.forEach((s,a)=>{let o=e.get(a);if(!o){let l=Array.from(t.values()).find(h=>h.parentUid===s.parentUid&&h.order===s.order-1&&e.has(h.uid));l?r.push({type:"insertSiblingAfter",mindmapId:i.mindmapId,targetNodeId:l.uid,node:fb(s)}):s.parentUid&&r.push({type:"insertChild",mindmapId:i.mindmapId,parentNodeId:s.parentUid,node:fb(s)});return}o.text!==s.text&&r.push({type:"updateText",mindmapId:i.mindmapId,nodeId:a,text:s.text}),(o.parentUid!==s.parentUid||o.order!==s.order)&&r.push({type:"moveNode",mindmapId:i.mindmapId,nodeId:a,newParentNodeId:s.parentUid??"",order:s.order}),lF(i.mindmapId,o,s,n)}),e.forEach((s,a)=>{!t.has(a)&&s.parentUid&&r.push({type:"deleteNode",mindmapId:i.mindmapId,nodeId:a})}),{commands:r,compatPatches:n}};var Hp={};tt(Hp,{getMindmapActionMapping:()=>Nc,listMindmapActionMappings:()=>qp,mapMindmapActionToCommand:()=>cF});var zs=i=>e=>e?`nodes.${e}.data.${i}`:null,mb=[{actionId:"undo",target:"runtimeCommand",runtimeCommand:"BACK",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"redo",target:"runtimeCommand",runtimeCommand:"FORWARD",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"editNode",target:"localView",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"insertSiblingAfter",target:"runtimeCommand",runtimeCommand:"INSERT_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"insertChild",target:"runtimeCommand",runtimeCommand:"INSERT_CHILD_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"deleteNode",target:"runtimeCommand",runtimeCommand:"REMOVE_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"summary",target:"runtimeCommand",runtimeCommand:"ADD_GENERALIZATION",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"associativeLine",target:"compatPatch",runtimeCommand:"ADD_ASSOCIATIVE_LINE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"setTheme",target:"kernelCommand",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"setLayout",target:"kernelCommand",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"tag",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("tag")},{actionId:"hyperlink",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("hyperlink")},{actionId:"note",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("note")},{actionId:"image",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("image")},{actionId:"icon",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("icon")},{actionId:"formula",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("formula")},{actionId:"painter",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("style")},{actionId:"import",target:"compatPatch",requiresActiveNode:!1,readonlyAllowed:!1,compatPath:()=>"import"},{actionId:"export",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"centerRoot",target:"localView",runtimeMethod:"centerRoot",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"zoomIn",target:"localView",runtimeMethod:"zoomIn",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"zoomOut",target:"localView",runtimeMethod:"zoomOut",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fitView",target:"localView",runtimeMethod:"fitView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fullscreenCanvas",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fullscreenPage",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"exitFullscreen",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"search",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"showMenu",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"expandCollapse",target:"localView",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"copyNodeText",target:"localView",requiresActiveNode:!0,readonlyAllowed:!0},{actionId:"readonly",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0}],qp=()=>mb,Nc=i=>mb.find(e=>e.actionId===i)??null,dF=i=>{let e=i?.trim();return e||null},cF=i=>{let e=Nc(i.actionId);if(!e)return null;let t=dF(i.activeNodeId);if(e.requiresActiveNode&&!t)return null;if(i.actionId==="setTheme")return{command:Bp(i.mindmapId,i.value,i.themeConfig)};if(i.actionId==="setLayout")return{command:Pp(i.mindmapId,i.value)};if(i.actionId==="editNode")return{command:{type:"updateText",mindmapId:i.mindmapId,nodeId:t??"root",text:typeof i.value=="string"?i.value:""}};if(e.runtimeCommand&&["INSERT_CHILD_NODE","INSERT_NODE","DELETE_NODE","REMOVE_NODE"].includes(e.runtimeCommand)){let r=Op({mindmapId:i.mindmapId,runtimeCommand:e.runtimeCommand,activeNodeId:t,newNode:i.node});return r?{runtimeCommand:e.runtimeCommand,command:r}:{runtimeCommand:e.runtimeCommand}}if(e.compatPath){let r=e.compatPath(t);return r?{command:Tc({mindmapId:i.mindmapId,path:r,value:i.value??!0,source:i.source??"toolbar",actionId:i.actionId,runtimeRevision:i.runtimeRevision,kernelRevision:i.kernelRevision})}:null}return e.runtimeCommand?{runtimeCommand:e.runtimeCommand}:{}};var $p={};tt($p,{createDefaultMindmapShellInteractionState:()=>gb,deriveMindmapUiState:()=>wF,reduceMindmapChromeVisibility:()=>bF});var Up={};tt(Up,{MINDMAP_DEBUG_CHROME_QUERY_PARAM:()=>pb,MINDMAP_TOOLBAR_MORE_ACTION_ID:()=>uF,isMindmapDebugChromeEnabled:()=>pF,mindmapDefaultUiSchema:()=>ho,mindmapToolbarFileActionOrder:()=>mF,mindmapToolbarPrimaryActionOrder:()=>fF});var pb="mnoteMindmapDebugChrome",uF="more",fF=["undo","redo","editNode","insertSiblingAfter","deleteNode","insertChild","tag","hyperlink","note","image","icon","summary","associativeLine","formula"],mF=["import","export"],Ee=(i,e,t,r,n,s,a)=>({id:i,iconKey:e,shortLabel:t,longLabel:r,priority:n,overflowGroup:s,cluster:a}),ho={toolbarGroups:[{id:"history",label:"\u5386\u53F2",actions:["undo","redo"],collapsePriority:4},{id:"node",label:"\u8282\u70B9",actions:["editNode","insertSiblingAfter","deleteNode","insertChild"],collapsePriority:1},{id:"insert",label:"\u63D2\u5165",actions:["tag","hyperlink","note","image","icon","summary","associativeLine","formula"],collapsePriority:2},{id:"file",label:"\u6587\u4EF6",actions:["import","export"],collapsePriority:5},{id:"view",label:"\u89C6\u56FE",actions:["painter","centerRoot","zoomOut","zoomIn","search","readonly"],collapsePriority:3}],toolbarActionMeta:{undo:Ee("undo","undo","\u64A4\u9500","\u64A4\u9500",10,"history","main"),redo:Ee("redo","redo","\u91CD\u505A","\u91CD\u505A",20,"history","main"),editNode:Ee("editNode","type","\u7F16\u8F91","\u7F16\u8F91\u8282\u70B9",30,"node","main"),insertSiblingAfter:Ee("insertSiblingAfter","sibling","\u540C\u7EA7","\u63D2\u5165\u540C\u7EA7\u8282\u70B9",40,"node","main"),deleteNode:Ee("deleteNode","trash","\u5220\u9664","\u5220\u9664\u8282\u70B9",50,"node","main"),insertChild:Ee("insertChild","child","\u5B50\u7EA7","\u63D2\u5165\u5B50\u8282\u70B9",60,"node","main"),tag:Ee("tag","tag","\u6807\u7B7E","\u6807\u7B7E",70,"insert","main"),hyperlink:Ee("hyperlink","link","\u94FE\u63A5","\u8D85\u94FE\u63A5",80,"insert","main"),note:Ee("note","note","\u5907\u6CE8","\u5907\u6CE8",90,"insert","main"),image:Ee("image","image","\u56FE\u7247","\u56FE\u7247",100,"insert","main"),icon:Ee("icon","smile","\u56FE\u6807","\u56FE\u6807",110,"insert","main"),summary:Ee("summary","summary","\u6982\u8981","\u6982\u8981",120,"insert","main"),associativeLine:Ee("associativeLine","route","\u5173\u8054","\u5173\u8054\u7EBF",130,"insert","main"),formula:Ee("formula","formula","\u516C\u5F0F","\u516C\u5F0F",140,"insert","main"),painter:Ee("painter","paintbrush","\u683C\u5F0F","\u683C\u5F0F\u5237",210,"view","view"),import:Ee("import","import","\u5BFC\u5165","\u5BFC\u5165",310,"file","file"),export:Ee("export","export","\u5BFC\u51FA","\u5BFC\u51FA",320,"file","file"),setTheme:Ee("setTheme","palette","\u4E3B\u9898","\u4E3B\u9898",410,"view","view"),setLayout:Ee("setLayout","layout","\u7ED3\u6784","\u7ED3\u6784",420,"view","view"),zoomIn:Ee("zoomIn","zoom-in","\u653E\u5927","\u653E\u5927",510,"view","view"),zoomOut:Ee("zoomOut","zoom-out","\u7F29\u5C0F","\u7F29\u5C0F",500,"view","view"),fitView:Ee("fitView","fit","\u9002\u5E94","\u9002\u5E94\u753B\u5E03",520,"view","view"),centerRoot:Ee("centerRoot","target","\u56DE\u6839","\u56DE\u5230\u6839\u8282\u70B9",490,"view","view"),fullscreenCanvas:Ee("fullscreenCanvas","fullscreen","\u5168\u5C4F","\u5168\u5C4F\u67E5\u770B",550,"view","view"),fullscreenPage:Ee("fullscreenPage","fullscreen-page","\u5168\u9875","\u5168\u5C4F\u7F16\u8F91",560,"view","view"),exitFullscreen:Ee("exitFullscreen","exit-fullscreen","\u9000\u51FA","\u9000\u51FA\u5168\u5C4F",570,"view","view"),search:Ee("search","search","\u641C\u7D22","\u641C\u7D22",530,"view","view"),showMenu:Ee("showMenu","menu","\u83DC\u5355","\u663E\u793A\u83DC\u5355",580,"view","view"),expandCollapse:Ee("expandCollapse","expand","\u5C55\u5F00","\u5C55\u5F00/\u6536\u8D77",610,"view","view"),copyNodeText:Ee("copyNodeText","copy","\u590D\u5236","\u590D\u5236\u6587\u672C",620,"view","view"),readonly:Ee("readonly","lock","\u53EA\u8BFB","\u53EA\u8BFB",540,"view","view")},sidebarPanels:[{id:"nodeStyle",kind:"nodeStyle",label:"\u8282\u70B9\u6837\u5F0F",icon:"palette",runtimeCapability:"node-style",phase:1,options:[{id:"node-fill-blue",label:"\u6D77\u84DD",actionId:"painter",value:"#dbeafe",controlType:"swatch",preview:"#dbeafe",compatPath:"nodes.$active.data.fillColor"},{id:"node-fill-green",label:"\u8584\u8377",actionId:"painter",value:"#dcfce7",controlType:"swatch",preview:"#dcfce7",compatPath:"nodes.$active.data.fillColor"},{id:"node-fill-amber",label:"\u6696\u9EC4",actionId:"painter",value:"#fef3c7",controlType:"swatch",preview:"#fef3c7",compatPath:"nodes.$active.data.fillColor"},{id:"node-text-dark",label:"\u6DF1\u8272\u6587\u5B57",actionId:"painter",value:"#0f172a",controlType:"swatch",preview:"#0f172a",compatPath:"nodes.$active.data.color"},{id:"node-text-blue",label:"\u84DD\u8272\u6587\u5B57",actionId:"painter",value:"#1d4ed8",controlType:"swatch",preview:"#1d4ed8",compatPath:"nodes.$active.data.color"},{id:"node-font-14",label:"14 px",actionId:"painter",value:14,controlType:"segmented",compatPath:"nodes.$active.data.fontSize"},{id:"node-font-18",label:"18 px",actionId:"painter",value:18,controlType:"segmented",compatPath:"nodes.$active.data.fontSize"},{id:"node-font-bold",label:"\u52A0\u7C97",actionId:"painter",value:!0,controlType:"toggle",compatPath:"nodes.$active.data.fontWeight"},{id:"node-font-italic",label:"\u659C\u4F53",actionId:"painter",value:!0,controlType:"toggle",compatPath:"nodes.$active.data.fontStyle"},{id:"node-shape-round",label:"\u5706\u89D2\u77E9\u5F62",actionId:"painter",value:"roundedRectangle",controlType:"button",compatPath:"nodes.$active.data.shape"},{id:"node-shape-rect",label:"\u77E9\u5F62",actionId:"painter",value:"rectangle",controlType:"button",compatPath:"nodes.$active.data.shape"},{id:"node-border-blue",label:"\u84DD\u8272\u8FB9\u6846",actionId:"painter",value:"#60a5fa",controlType:"swatch",preview:"#60a5fa",compatPath:"nodes.$active.data.borderColor"},{id:"node-line-teal",label:"\u9752\u8272\u5206\u652F\u7EBF",actionId:"painter",value:"#14b8a6",controlType:"swatch",preview:"#14b8a6",compatPath:"nodes.$active.data.lineColor"},{id:"node-line-width-2",label:"\u8FB9\u7EBF 2",actionId:"painter",value:2,controlType:"segmented",compatPath:"nodes.$active.data.lineWidth"}]},{id:"baseStyle",kind:"baseStyle",label:"\u5BFC\u56FE\u6837\u5F0F",icon:"sliders",runtimeCapability:"base-style",phase:1,options:[{id:"base-curve-line",label:"\u66F2\u7EBF",actionId:"painter",value:"curve",controlType:"segmented",compatPath:"style.map.lineStyle"},{id:"base-direct-line",label:"\u76F4\u7EBF",actionId:"painter",value:"straight",controlType:"segmented",compatPath:"style.map.lineStyle"},{id:"base-rainbow-lines",label:"\u5F69\u8679\u7EBF\u6761",actionId:"painter",value:{enabled:!0},controlType:"toggle",compatPath:"style.map.rainbowLines"},{id:"base-line-width-2",label:"\u7EBF\u5BBD 2",actionId:"painter",value:2,controlType:"segmented",compatPath:"style.map.lineWidth"},{id:"base-line-width-4",label:"\u7EBF\u5BBD 4",actionId:"painter",value:4,controlType:"segmented",compatPath:"style.map.lineWidth"},{id:"base-background-light",label:"\u6D45\u8272\u80CC\u666F",actionId:"painter",value:"#f8fafc",controlType:"swatch",preview:"#f8fafc",compatPath:"style.map.backgroundColor"},{id:"base-node-spacing-36",label:"\u8282\u70B9\u95F4\u8DDD 36",actionId:"painter",value:36,controlType:"numberInput",compatPath:"style.map.nodeSpacing"},{id:"base-summary-bracket",label:"\u62EC\u53F7\u6982\u8981",actionId:"painter",value:"bracket",controlType:"select",compatPath:"style.map.summaryStyle"}]},{id:"theme",kind:"theme",label:"\u4E3B\u9898",icon:"swatch",runtimeCapability:"theme",phase:1,options:[{id:"theme-classic",label:"Classic",actionId:"setTheme",value:"classic",controlType:"swatch",preview:"#60a5fa",description:"\u9ED8\u8BA4\u4E3B\u9898"},{id:"theme-classic4",label:"KMind",actionId:"setTheme",value:"classic4",controlType:"swatch",preview:"#22c55e",description:"KMind-like"},{id:"theme-simple",label:"Simple",actionId:"setTheme",value:"simple",controlType:"swatch",preview:"#f59e0b",description:"\u8F7B\u91CF\u4E3B\u9898"},{id:"theme-dark",label:"Dark",actionId:"setTheme",value:"dark",controlType:"swatch",preview:"#334155",description:"\u6DF1\u8272\u4E3B\u9898"}]},{id:"structure",kind:"structure",label:"\u7ED3\u6784",icon:"layout",runtimeCapability:"layout",phase:1,options:[{id:"layout-logical",label:"\u903B\u8F91\u7ED3\u6784\u56FE",actionId:"setLayout",value:"logicalStructure",controlType:"layoutCard",preview:"logicalStructure"},{id:"layout-mind-map",label:"\u601D\u7EF4\u5BFC\u56FE",actionId:"setLayout",value:"mindMap",controlType:"layoutCard",preview:"mindMap"},{id:"layout-organization",label:"\u7EC4\u7EC7\u7ED3\u6784\u56FE",actionId:"setLayout",value:"organizationStructure",controlType:"layoutCard",preview:"organizationStructure"},{id:"layout-catalog",label:"\u76EE\u5F55\u7EC4\u7EC7\u56FE",actionId:"setLayout",value:"catalogOrganization",controlType:"layoutCard",preview:"catalogOrganization"},{id:"layout-timeline",label:"\u65F6\u95F4\u8F74",actionId:"setLayout",value:"timeline",controlType:"layoutCard",preview:"timeline"},{id:"layout-fishbone",label:"\u9C7C\u9AA8\u56FE",actionId:"setLayout",value:"fishbone",controlType:"layoutCard",preview:"fishbone"}]},{id:"outline",kind:"outline",label:"\u5927\u7EB2",icon:"list-tree",runtimeCapability:"outline",phase:1,options:[]},{id:"shortcutKey",kind:"shortcutKey",label:"\u5FEB\u6377\u952E",icon:"sparkles",runtimeCapability:"shortcut-key",phase:1,options:[{id:"shortcut-insert-child",label:"Tab",description:"\u63D2\u5165\u5B50\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0},{id:"shortcut-insert-sibling",label:"Enter",description:"\u63D2\u5165\u540C\u7EA7\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0},{id:"shortcut-delete",label:"Delete",description:"\u5220\u9664\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0}]},{id:"settings",kind:"settings",label:"\u8BBE\u7F6E",icon:"hexagon",runtimeCapability:"settings",phase:1,options:[{id:"settings-readonly-hint",label:"\u53EA\u8BFB\u6A21\u5F0F",description:"\u5BFC\u822A\u680F\u5207\u6362",actionId:null,value:null,controlType:"toggle",readonly:!0},{id:"settings-mouse",label:"\u9F20\u6807\u884C\u4E3A",description:"\u5DE6\u952E\u9009\u4E2D\uFF0C\u53F3\u952E\u62D6\u62FD",actionId:null,value:"leftSelectRightDrag",controlType:"select",readonly:!0}]}],navigatorItems:[{id:"stats",label:"\u7EDF\u8BA1",actionId:null,readOnly:!0,displayMode:"text"},{id:"centerRoot",label:"\u56DE\u6839\u8282\u70B9",actionId:"centerRoot",readOnly:!0,displayMode:"button"},{id:"search",label:"\u641C\u7D22",actionId:"search",readOnly:!0,displayMode:"button"},{id:"zoomOut",label:"\u7F29\u5C0F",actionId:"zoomOut",readOnly:!0,displayMode:"button"},{id:"zoom",label:"\u7F29\u653E",actionId:null,readOnly:!0,displayMode:"input"},{id:"zoomIn",label:"\u653E\u5927",actionId:"zoomIn",readOnly:!0,displayMode:"button"},{id:"fullscreen",label:"\u5168\u5C4F",actionId:"fullscreenCanvas",readOnly:!0,displayMode:"button"},{id:"readonly",label:"\u53EA\u8BFB",actionId:"readonly",readOnly:!0,displayMode:"button"}],contextMenuItems:[{id:"insertChild",label:"\u63D2\u5165\u5B50\u8282\u70B9",actionId:"insertChild",requiresNode:!0,phase:1},{id:"insertSiblingAfter",label:"\u63D2\u5165\u540C\u7EA7\u8282\u70B9",actionId:"insertSiblingAfter",requiresNode:!0,phase:1},{id:"deleteNode",label:"\u5220\u9664\u8282\u70B9",actionId:"deleteNode",requiresNode:!0,phase:1},{id:"summary",label:"\u6982\u8981",actionId:"summary",requiresNode:!0,phase:1},{id:"associativeLine",label:"\u5173\u8054\u7EBF",actionId:"associativeLine",requiresNode:!0,phase:1},{id:"expandCollapse",label:"\u5C55\u5F00/\u6536\u8D77",actionId:"expandCollapse",requiresNode:!0,phase:1},{id:"copyNodeText",label:"\u590D\u5236\u6587\u672C",actionId:"copyNodeText",requiresNode:!0,phase:1},{id:"centerRoot",label:"\u56DE\u6839\u8282\u70B9",actionId:"centerRoot",requiresNode:!1,phase:1},{id:"fitView",label:"\u9002\u5E94\u753B\u5E03",actionId:"fitView",requiresNode:!1,phase:1},{id:"search",label:"\u641C\u7D22",actionId:"search",requiresNode:!1,phase:1},{id:"readonly",label:"\u53EA\u8BFB\u5207\u6362",actionId:"readonly",requiresNode:!1,phase:1},{id:"showMenu",label:"\u663E\u793A\u83DC\u5355",actionId:"showMenu",requiresNode:!1,phase:1}]},pF=i=>{try{let e=new URL(i).searchParams.get(pb);return e==="1"||e==="true"}catch{return!1}};var gF=()=>{let i=[...ho.toolbarGroups.flatMap(e=>e.actions),...ho.navigatorItems.flatMap(e=>e.actionId?[e.actionId]:[]),...ho.contextMenuItems.map(e=>e.actionId),...qp().map(e=>e.actionId)];return[...new Set(i)]},xF=i=>{let e=i?.trim();return e||null},yF=i=>typeof i!="number"||!Number.isFinite(i)?100:Math.max(10,Math.min(500,Math.round(i))),vF=new Set(["tag","hyperlink","note","image","icon","associativeLine","formula","import","export"]),gb=(i={})=>({chromeVisibility:i.chromeVisibility??"visible",toolbarOverflow:{availableWidth:i.toolbarOverflow?.availableWidth??null,visibleActionIds:i.toolbarOverflow?.visibleActionIds??[],overflowActionIds:i.toolbarOverflow?.overflowActionIds??[],moreOpen:i.toolbarOverflow?.moreOpen??!1},fullscreen:{mode:i.fullscreen?.mode??"none",isFullscreen:i.fullscreen?.isFullscreen??!1,target:i.fullscreen?.target??"mindmap-root",apiAvailable:i.fullscreen?.apiAvailable??!0},sidebar:{triggerVisible:i.sidebar?.triggerVisible??!0,panelOpen:i.sidebar?.panelOpen??!0,activePanelId:i.sidebar?.activePanelId??ho.sidebarPanels[0]?.id??null,drawerWidth:i.sidebar?.drawerWidth??300,collapsedByToggle:i.sidebar?.collapsedByToggle??!1},navigator:{searchOpen:i.navigator?.searchOpen??!1,minimapOpen:i.navigator?.minimapOpen??!1,readonly:i.navigator?.readonly??!1,zoomPercent:yF(i.navigator?.zoomPercent),mouseBehavior:i.navigator?.mouseBehavior??"leftSelectRightDrag"}}),bF=(i,e)=>e==="pointerLeave"?"hiddenByPointerLeave":e==="pointerEnter"?i:e==="restoreClick"?"visible":e==="hideToggle"?"hiddenByToggle":e==="showToggle"?"visible":e==="enterFullscreen"?i==="visible"?"visible":"hiddenByFullscreen":e==="exitFullscreen"&&i==="hiddenByFullscreen"?"visible":i,wF=i=>{let e=xF(i.activeNodeId),t=i.runtimeCapabilities?new Set(i.runtimeCapabilities):null,r={},n=gb({...i.shell,navigator:{...i.shell?.navigator,readonly:i.readonly}});return gF().forEach(s=>{let a=Nc(s);if(!a){r[s]=!0;return}if(a.requiresActiveNode&&!e){r[s]=!0;return}if(i.readonly&&!a.readonlyAllowed){r[s]=!0;return}if(t&&!t.has(a.target)){r[s]=!0;return}if(vF.has(s)){r[s]=!0;return}r[s]=!1}),{activeNodeId:e,readonly:i.readonly,disabledActions:r,shell:n}};var jp={};tt(jp,{resolveMindmapShortcutAction:()=>MF,shouldInterceptMindmapShortcut:()=>TF});var MF=i=>i.ctrlKey||i.metaKey||i.altKey||i.shiftKey?null:i.key==="Enter"?"insertSiblingAfter":i.key==="Tab"||i.key==="Insert"?"insertChild":i.key==="Delete"||i.key==="Backspace"?"deleteNode":i.key==="F2"?"editNode":null,TF=i=>i.debugChromeEnabled||!i.bridgeReady||i.readonly||i.isComposing||i.isEditableTarget?!1:i.targetInsideRoot?!0:i.keyboardShortcutArmed;function d0(){return{status:"idle"}}function xb(i,e){return{status:"armed",armedAt:e,reason:i}}function yb(){return d0()}function vb(i,e,t=1500){return i.status!=="armed"?{state:i,suppressed:!1,expired:!1}:e-i.armedAt>t?{state:d0(),suppressed:!1,expired:!0}:{state:d0(),suppressed:!0,expired:!1}}function bb(i){return{endpoint:`/api/mindmap/${encodeURIComponent(i.documentId)}/${encodeURIComponent(i.mindmapId)}`,init:{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:i.data,createOnly:!0})}}}function Vn(i){let e=i;return e.default&&typeof e.default=="object"?e.default:i}var{applyMindmapCommandsLocally:NF,isLocallyApplicableMindmapCommandSet:EF}=Vn(Dc),{createLeptosMindmapAdapter:SF,executeMindmapCommandApply:Gp,executeMindmapCommandApplyAndRefreshProjection:AF,requestMindmapAdapterProjection:kF}=Vn(Dp),{createViewPatchCommand:CF,createCompatPayloadPatch:_F,diffMindmapRuntimeDataToKernelCommands:LF}=Vn(Fp),{getMindmapActionMapping:wb,mapMindmapActionToCommand:IF}=Vn(Hp),{canonicalizeMindmapData:vi}=Vn(Pc),{deriveMindmapUiState:Vp,reduceMindmapChromeVisibility:Ec}=Vn($p),{resolveMindmapShortcutAction:zF,shouldInterceptMindmapShortcut:RF}=Vn(jp),{isMindmapDebugChromeEnabled:DF,mindmapDefaultUiSchema:Sc,mindmapToolbarFileActionOrder:OF,mindmapToolbarPrimaryActionOrder:Xp}=Vn(Up);function BF(i){return typeof i=="string"&&i.length>0?{"data-block-id":i,id:i}:{}}function PF(i){if(i.mnoteBlockType!=="mindmap")return{};let e={"data-mnote-block-type":"mindmap"};return typeof i.mindmapId=="string"&&(e["data-mnote-mindmap-id"]=i.mindmapId),typeof i.rootNodeId=="string"&&(e["data-mnote-root-node-id"]=i.rootNodeId),typeof i.projectionVersion=="number"&&(e["data-mnote-projection-version"]=String(i.projectionVersion)),e}function Rs(i){return String(i??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function Wp(i){if(typeof i!="string")return null;let e=i.trim();return e.length>0?e:null}function FF(i){let e=Wp(i?.closest("[data-document-id]")?.getAttribute("data-document-id"));if(e)return e;if(i&&"isConnected"in i&&i.isConnected===!1)return null;let t=window.location.pathname.match(/\/documents\/([^/?#]+)/);if(t?.[1])return decodeURIComponent(t[1]);let r=window.location.pathname.match(/\/mindmap\/([^/?#]+)\/([^/?#]+)/);if(r?.[1])return decodeURIComponent(r[1]);let n=Wp(document.body?.getAttribute("data-document-id"));if(n)return n;let s=Wp(document.querySelector(".document-shell[data-document-id], [data-pane-document-id], [data-document-id]")?.getAttribute("data-document-id")??document.querySelector("[data-pane-document-id]")?.getAttribute("data-pane-document-id"));return s||null}function Mb(i,e){let r=vi(i.root).data?.uid;return typeof r=="string"&&r.trim().length>0?r.trim():e}function Yp(i){let t=vi(i.root).data?.text;return typeof t=="string"&&t.trim().length>0?t.trim():"\u672A\u547D\u540D\u8282\u70B9"}function Ds(i){if(typeof i=="string"&&i.trim().length>0)return i.trim();if(!i||typeof i!="object")return null;let e=i;if(typeof e.uid=="string"&&e.uid.trim().length>0)return e.uid.trim();let t=e.data&&typeof e.data=="object"&&!Array.isArray(e.data)?e.data:{};if(typeof t.uid=="string"&&t.uid.trim().length>0)return t.uid.trim();let r=e.getData;if(typeof r=="function")try{let n=r.call(e,"uid");if(typeof n=="string"&&n.trim().length>0)return n.trim()}catch{return null}return null}function Ac(i,e){let t=window,r=t.__MNOTE_LEPTOS_MINDMAP_BRIDGES__??{};t.__MNOTE_LEPTOS_MINDMAP_BRIDGES__=r,e?r[i]=e:delete r[i]}function Lt(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function Os(i){return JSON.parse(JSON.stringify(i))}function qF(i){if(!(i instanceof HTMLElement))return!1;let e=i.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"?!0:i.isContentEditable?!i.matches(".ProseMirror"):!1}function HF(i){if(!Lt(i))return null;let e=i.view;return Lt(e)&&Lt(e.state)?e:null}function UF(i){if(!(i!=="insertChild"&&i!=="insertSiblingAfter"))return{uid:`node_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,text:"\u65B0\u8282\u70B9"}}function $F(i,e){let t=e?.trim();if(!t)return!1;let r=vi(i),n=!1,s=a=>{if(n)return;let o=vi(a);if(o.data?.uid===t){n=!0;return}(Array.isArray(o.children)?o.children:[]).forEach(s)};return s(r),n}function Tb(i){let e=vi(i),t=Array.isArray(e.children)?[...e.children]:[];for(;t.length>0;){let r=vi(t.shift()),n=r.data?.uid;if(typeof n=="string"&&n.trim().length>0)return n.trim();Array.isArray(r.children)&&t.push(...r.children)}return null}function jF(i,e){let t=e?.trim();if(!t)return null;let r=null,n=s=>{if(r)return;let a=vi(s);if(a.data?.uid===t){r=a;return}(Array.isArray(a.children)?a.children:[]).forEach(n)};return n(i),r}function GF(i,e){let t=jF(i,e),r=t&&Lt(t.data)?t.data.text:null;return typeof r=="string"?r:""}function VF(i,e=10){let t=vi(i),r=[],n=(s,a)=>{if(r.length>=e)return;let o=vi(s),l=typeof o.data?.text=="string"&&o.data.text.trim().length>0?o.data.text.trim():"\u672A\u547D\u540D\u8282\u70B9";r.push(`${" ".repeat(Math.max(a-1,0))}${l}`),(Array.isArray(o.children)?o.children:[]).forEach(d=>n(d,a+1))};return n(t,1),r}function Nb(i,e){let t=i?.trim();return t?t.includes("$active")?e?t.replaceAll("$active",e):null:t:null}var Eb={undo:"\u64A4\u9500",redo:"\u91CD\u505A",editNode:"\u7F16\u8F91\u8282\u70B9",insertSiblingAfter:"\u540C\u7EA7\u8282\u70B9",insertChild:"\u5B50\u8282\u70B9",deleteNode:"\u5220\u9664",tag:"\u6807\u7B7E",hyperlink:"\u94FE\u63A5",note:"\u5907\u6CE8",image:"\u56FE\u7247",icon:"\u56FE\u6807",summary:"\u6982\u8981",associativeLine:"\u5173\u8054\u7EBF",formula:"\u516C\u5F0F",painter:"\u683C\u5F0F\u5237",import:"\u5BFC\u5165",export:"\u5BFC\u51FA",setTheme:"\u4E3B\u9898",setLayout:"\u7ED3\u6784",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",fitView:"\u9002\u5E94",centerRoot:"\u56DE\u6839",fullscreenCanvas:"\u5168\u5C4F",fullscreenPage:"\u5168\u9875",exitFullscreen:"\u9000\u51FA",search:"\u641C\u7D22",showMenu:"\u663E\u793A\u83DC\u5355",expandCollapse:"\u5C55\u5F00/\u6536\u8D77",copyNodeText:"\u590D\u5236\u6587\u672C",readonly:"\u53EA\u8BFB"},WF={undo:"\u21B6",redo:"\u21B7",editNode:"T",insertSiblingAfter:"\u21B5",insertChild:"+",deleteNode:"\xD7",tag:"#",hyperlink:"\u2301",note:"N",image:"\u25A1",icon:"\u2606",summary:"{",associativeLine:"\u2307",formula:"fx",painter:"\u25D0",import:"\u21E7",export:"\u21E9",centerRoot:"\u25CE",zoomOut:"-",zoomIn:"+",search:"\u2315",fullscreenCanvas:"\u26F6",fullscreenPage:"\u25A3",exitFullscreen:"\u2921",showMenu:"\u2630",expandCollapse:"\u2922",copyNodeText:"C",readonly:"\u9501"},YF={undo:"\u21B6",redo:"\u21B7",type:"T",sibling:"\u21B5",trash:"\xD7",child:"+",tag:"#",link:"\u2301",note:"N",image:"\u25A1",smile:"\u2606",summary:"{",route:"\u2307",formula:"fx",paintbrush:"\u25D0",import:"\u21E7",export:"\u21E9",target:"\u25CE",fullscreen:"\u26F6","fullscreen-page":"\u25A3","exit-fullscreen":"\u2921",menu:"\u2630","zoom-out":"-","zoom-in":"+",search:"\u2315",lock:"\u9501"},XF=i=>{let e=[...Xp];if(i===null||!Number.isFinite(i))return{availableWidth:null,visibleActionIds:e,overflowActionIds:[]};let t=118,r=96,n=50,s=Math.max(0,i-t-r),a=Math.max(2,Math.min(e.length,Math.floor(s/n)));if(a>=e.length)return{availableWidth:i,visibleActionIds:e,overflowActionIds:[]};let o=Math.max(1,a-1);return{availableWidth:i,visibleActionIds:e.slice(0,o),overflowActionIds:e.slice(o)}};function KF(i){return({node:e,getPos:t})=>{let r=e,n=0,s=null,a=null,o=null,l=null,h=null,d=null,c=d0(),f=null,m=!1,g=Sc.sidebarPanels[0]?.id??"nodeStyle",x=!0,y=!0,b=!1,S=300,A=null,C=null,I=!1,O=!1,q=null,P=!1,W=null,ne=null,re=null,oe=null,ke=null,Q=null,Y="visible",le=!1,ce=!1,at="canvas",It=null,bt="canvas",qi=0,zt=0,di=null,nn=null,Hi=null,co=0,Mr=0,tr=!1,sn=null,bi=null,Ui=!1,wi=DF(window.location.href),Je=document.createElement("div");Je.className="mnote-mindmap-placeholder",Je.dataset.mnoteBlockType="mindmap",Je.dataset.testid="mnote-mindmap-placeholder",Je.setAttribute("contenteditable","false");let ve=document.createElement("div");ve.className="mnote-mindmap-editor-root",ve.dataset.testid="mnote-mindmap-editor-root",ve.dataset.mnoteSceneQuery="mindmap.simple_mind_map_scene.get";let an=()=>FF(ve),R=document.createElement("div");R.dataset.testid="leptos-mindmap-island",R.dataset.runtime="simple-mind-map",R.dataset.stage="loading",R.dataset.debugChrome=wi?"true":"false",R.dataset.suppressRuntimeDiffState="idle",R.className="mnote-leptos-mindmap-shell";let Wn=()=>{R.dataset.suppressRuntimeDiffState=c.status,R.dataset.suppressRuntimeDiffReason=c.status==="armed"?c.reason:"",R.dataset.suppressRuntimeDiffSince=c.status==="armed"?String(c.armedAt):""},Bs=M=>{c=xb(M,Date.now()),Wn()},$i=()=>{c=yb(),Wn()},Yn=document.createElement("div");Yn.className="mnote-mindmap-workspace",Yn.dataset.debugChrome=wi?"true":"false",Yn.dataset.layout=wi?"debug-grid":"floating-overlay";let c0=document.createElement("div");c0.className="mnote-mindmap-canvas-layer",c0.dataset.testid="mindmap-canvas-layer";let Xn=document.createElement("div");Xn.className="mnote-mindmap-overlay-layer",Xn.dataset.testid="mindmap-overlay-layer";let mt=document.createElement("div");mt.className="mnote-leptos-mindmap-runtime",mt.dataset.testid="simple-mind-map-runtime",mt.dataset.runtime="simple-mind-map",mt.dataset.runtimeEngine="pending";let ir=document.createElement("div");ir.className="mnote-mindmap-rust-shell-mount",ir.dataset.testid="mindmap-rust-shell-mount",ir.dataset.uiShellSource="leptos-rust-shell";let Kn=document.createElement("div");Kn.className="mnote-mindmap-command-toolbar",Kn.dataset.testid="mindmap-command-toolbar";let Zn=document.createElement("aside");Zn.className="mnote-mindmap-side-panel",Zn.dataset.testid="mindmap-sidebar";let Qn=document.createElement("div");Qn.className="mnote-mindmap-bottom-bar",Qn.dataset.testid="mindmap-bottom-bar";let et=()=>{let M=typeof r.attrs.mindmapId=="string"&&r.attrs.mindmapId.length>0?r.attrs.mindmapId:"mindmap",L=typeof r.attrs.rootNodeId=="string"&&r.attrs.rootNodeId.length>0?r.attrs.rootNodeId:"root";return{mindmapId:M,rootNodeId:L}},Kp=M=>JSON.stringify({mnoteBlockType:M.attrs.mnoteBlockType??null,mindmapId:M.attrs.mindmapId??null,rootNodeId:M.attrs.rootNodeId??null,projectionVersion:M.attrs.projectionVersion??null}),u0=()=>{let{mindmapId:M,rootNodeId:L}=et();Je.dataset.mnoteMindmapId=M,Je.dataset.mnoteRootNodeId=L,Je.dataset.mnoteProjectionVersion=String(r.attrs.projectionVersion??1),ve.dataset.mnoteMindmapId=M,ve.dataset.mnoteRootNodeId=L,ve.dataset.mnoteProjectionVersion=String(r.attrs.projectionVersion??1),ve.dataset.mnoteSceneQuery="mindmap.simple_mind_map_scene.get"},f0=()=>{if(!(nn===null||!Hi)){try{Hi.unmount(nn)}catch{}nn=null,Hi=null,ir.replaceChildren()}},Zp=()=>{let M=s?.getSnapshot(),L=Lt(M)&&"root"in M?M.root:M??a?.root,D=0,F=0,K=te=>{if(!Lt(te))return;D+=1;let we=Lt(te.data)&&typeof te.data.text=="string"?te.data.text:"";F+=we.trim().length,(Array.isArray(te.children)?te.children:[]).forEach(K)};K(L);let ee=a?.view,ue=Lt(M)&&Lt(M.view)&&Lt(M.view.state)&&typeof M.view.state.scale=="number"?M.view.state.scale:Lt(ee)&&Lt(ee.state)&&typeof ee.state.scale=="number"?ee.state.scale:1;return{nodeCount:D,wordCount:F,zoomPercent:Math.round(ue*100)}},Sb=()=>a?{...vi(a.root),layout:a.layout,theme:a.theme,themeConfig:a.themeConfig,view:a.view,config:a.config,compatPayload:a.compatPayload}:null,Ab=(M,L)=>{a&&(a.root=Os(vi(M)),"layout"in M&&(a.layout=M.layout),"theme"in M&&(a.theme=M.theme),"themeConfig"in M&&(a.themeConfig=M.themeConfig),"view"in M&&(a.view=M.view),"config"in M&&(a.config=M.config),"compatPayload"in M&&(a.compatPayload=M.compatPayload),typeof L=="number"&&Number.isFinite(L)&&(a.kernelRevision=L),o=Os(a.root))},kb=()=>{let M=s?.getSnapshot(),L=Lt(M)&&"root"in M?M.root:M??a?.root;return VF(L)},m0=()=>{P&&(P=!1,Le())},Qp=(M,L)=>{let D=ve.getBoundingClientRect();qi=Math.round(M-D.left),zt=Math.round(L-D.top)},p0=()=>{!ce&&!R.dataset.contextMenuKind||(ce=!1,at="canvas",It=null,bt="canvas",delete R.dataset.contextMenuKind,delete R.dataset.contextMenuTargetNodeId,delete R.dataset.contextMenuTargetNodeKind,b0())},g0=M=>Ds(M),Cb=()=>{let M=s?.instance.renderer;return M?.activeNodeList?.[0]??M?.lastActiveNodeList?.[0]??M?.root??M?.renderTree?._node??null},x0=(M,L,D)=>{let F=Ds(L);return F&&$F(M.root,F)?F:Tb(M.root)??Mb(M,D)},kc=M=>{let L=Ds(M);return L||(g0(h)??g0(Cb())??null)},_b=M=>{if(!M||typeof M!="object")return"node";let L=M;return L.isRoot===!0?"root":L.isGeneralization===!0?"generalization":"node"},Lb=M=>{let L=s?.instance.renderer;if(L)try{L.clearActiveNodeList?.(),L.addNodeToActiveList?.(M,!0),L.emitNodeActiveEvent?.(M,[M])}catch{}},uo=M=>{let L=Ds(M),D=s?.instance.renderer,F=L?D?.findNodeByUid?.(L)??null:D?.activeNodeList?.[0]??D?.lastActiveNodeList?.[0]??D?.root??D?.renderTree?._node;if(F)try{D?.clearActiveNodeList?.(),D?.addNodeToActiveList?.(F,!0),D&&(D.lastActiveNodeList=[F]),D?.emitNodeActiveEvent?.(F,[F]),s?.instance.execCommand?.("SET_NODE_ACTIVE",F,!0),h=F;let ee=L??g0(F)??l??et().rootNodeId;return l=ee,d=ee,R.dataset.lastRuntimeSelectionSync=ee,!0}catch{}let K=s?.instance.execCommand;if(typeof K!="function"||!L)return!1;try{return K.call(s?.instance,"GO_TARGET_NODE",L),l=L,d=L,R.dataset.lastRuntimeSelectionSync=L,!0}catch{return!1}},Jp=M=>{let L=Ds(M),D=s?.instance.renderer;return{wantedNodeId:L,runtimeNode:L?D?.findNodeByUid?.(L)??null:D?.activeNodeList?.[0]??D?.lastActiveNodeList?.[0]??D?.root??D?.renderTree?._node}},Ib=async(M,L=3)=>{let D=Jp(M);for(let F=1;!D.runtimeNode&&Fwindow.requestAnimationFrame(()=>K())),D=Jp(M);return D},zb=async(M,L,D)=>{let F=M==="DELETE_NODE"?"REMOVE_NODE":M,K=s?.instance;if(!K||typeof K.execCommand!="function")return{ok:!1,command:F,error:"runtime_unavailable",message:"runtime_instance_missing"};let{wantedNodeId:ee,runtimeNode:ue}=await Ib(L);if(!ue)return{ok:!1,command:F,error:"command_failed",message:`runtime_node_missing:${ee??"unknown"}`};try{if(K.renderer?.clearActiveNodeList?.(),K.renderer?.addNodeToActiveList?.(ue,!0),K.renderer&&(K.renderer.lastActiveNodeList=[ue]),K.renderer?.emitNodeActiveEvent?.(ue,[ue]),K.execCommand("SET_NODE_ACTIVE",ue,!0),F==="REMOVE_NODE")return{ok:!0,command:F,result:K.execCommand("REMOVE_NODE",[ue])};if(F==="INSERT_CHILD_NODE"||F==="INSERT_NODE")return{ok:!0,command:F,result:K.execCommand(F,!1,[ue],D?{uid:D.uid,text:D.text}:null)}}catch{return{ok:!1,command:F,error:"command_failed",message:"runtime_command_throw"}}return s?.execCommand(F)??{ok:!1,command:F,error:"unsupported_command",message:"runtime_command_unsupported"}},Rb=(M,L,D)=>{Qp(M,L),at="node",It=g0(D),bt=_b(D),ce=!0,R.dataset.contextMenuKind="node",R.dataset.contextMenuTargetNodeId=It??"",R.dataset.contextMenuTargetNodeKind=bt,Lb(D),It&&(l=It,d=It),b0()},Db=(M,L)=>{Qp(M,L),at="canvas",It=null,bt="canvas",ce=!0,R.dataset.contextMenuKind="canvas",R.dataset.contextMenuTargetNodeId="",R.dataset.contextMenuTargetNodeKind="canvas",b0()},y0=M=>{Y!==M&&(Y=M,R.dataset.chromeVisibility=M,Le())},e3=()=>{le=!0,R.dataset.keyboardShortcutArmed="true"},Ob=()=>{le=!1,R.dataset.keyboardShortcutArmed="false"},v0=()=>document.fullscreenElement===ve||ve.contains(document.fullscreenElement),Bb=()=>{let M=s?.instance;try{typeof M?.resize=="function"?M.resize():typeof M?.view?.resize=="function"&&M.view.resize(),M?.renderer?.setRootNodeCenter?.()}catch{R.dataset.fullscreenResizeStatus="failed";return}R.dataset.fullscreenResizeStatus="success"},Cc=()=>{let M=v0();R.dataset.fullscreenActive=M?"true":"false",ve.dataset.fullscreenActive=M?"true":"false",window.setTimeout(()=>{Bb(),Le()},80)},_c=()=>{s?.instance.setMode?.(m?"readonly":"edit"),R.dataset.readonly=m?"true":"false"},t3=M=>{R.dataset.searchStatus="ready",R.dataset.lastSearchQuery=M,O=!0,Le()},Pb=M=>{let L=typeof M=="number"?M:Number(String(M??"").replace("%","").trim());if(!Number.isFinite(L)){R.dataset.zoomInputStatus="invalid",Le();return}let D=Math.max(10,Math.min(500,Math.round(L))),F=s?.instance.view;if(!F?.setScale){R.dataset.zoomInputStatus="unsupported",Le();return}F.setScale(D/100,ve.clientWidth/2,ve.clientHeight/2),R.dataset.zoomInputStatus="success",qs(s?.getSnapshot()),Le()},i3=async M=>{if(M==="exitFullscreen"){document.fullscreenElement&&await document.exitFullscreen(),Cc();return}if(!(M!=="fullscreenCanvas"&&M!=="fullscreenPage")){if(typeof ve.requestFullscreen!="function"){R.dataset.commandStatus="fullscreen-unavailable",R.dataset.disabledReason="fullscreen-unavailable";return}await ve.requestFullscreen(),Cc()}},Lc=(M,L)=>{let D=Sc.toolbarActionMeta[M],F=D?.shortLabel??Eb[M]??M,K=D?.longLabel??Eb[M]??M,ee=D?.iconKey??M;return{id:M,label:F,longLabel:K,icon:YF[ee]??WF[M]??F.slice(0,1),iconKey:ee,priority:D?.priority??999,overflowGroup:D?.overflowGroup??"view",cluster:D?.cluster??"main",disabled:L.disabledActions[M]??!0}},Fb=()=>{let M=window.__MNOTE_MINDMAP_RUST_SHELL__;if(!M){f0(),R.dataset.uiShell="typescript-nodeview-dom",ir.dataset.uiShellSource="missing-rust-shell",ir.innerHTML='
    Leptos/Rust mindmap shell \u672A\u52A0\u8F7D
    ';return}let L=XF(q??ve.getBoundingClientRect().width),D=Vp({activeNodeId:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"],shell:{chromeVisibility:Y,toolbarOverflow:{availableWidth:L.availableWidth,visibleActionIds:L.visibleActionIds,overflowActionIds:L.overflowActionIds,moreOpen:P&&L.overflowActionIds.length>0},fullscreen:{mode:v0()?"canvas":"none",isFullscreen:v0(),target:"mindmap-root",apiAvailable:typeof ve.requestFullscreen=="function"},sidebar:{activePanelId:g,panelOpen:x,triggerVisible:y,drawerWidth:S,collapsedByToggle:b},navigator:{searchOpen:O,minimapOpen:I,readonly:m,zoomPercent:Zp().zoomPercent}}}),{mindmapId:F}=et(),K=Zp(),ee=new Set(D.shell.toolbarOverflow.visibleActionIds),ue=new Set(D.shell.toolbarOverflow.overflowActionIds),te={mindmapId:F,toolbarGroups:[{id:"main",label:"\u4E3B\u5DE5\u5177",actions:Xp.filter(we=>ee.size===0||ee.has(we)).map(we=>Lc(we,D))},{id:"overflow",label:"\u66F4\u591A",actions:Xp.filter(we=>ue.has(we)).map(we=>Lc(we,D))},{id:"file",label:"\u6587\u4EF6",actions:OF.map(we=>Lc(we,D))}],sidebarPanels:Sc.sidebarPanels.map(we=>({id:we.id,kind:we.kind,label:we.label,icon:we.icon,active:we.id===g,bodyTitle:we.label,bodyCaption:we.runtimeCapability,options:we.options.map(Ge=>({id:Ge.id,label:Ge.label,actionId:Ge.actionId,value:Ge.value,controlType:Ge.controlType,preview:Ge.preview,description:Ge.description,readonly:Ge.readonly??!1,compatPath:Ge.compatPath})),bodyItems:we.id==="outline"?kb():[]})),navigator:{wordCount:K.wordCount,nodeCount:K.nodeCount,zoomPercent:K.zoomPercent,readonly:m,minimapOpen:I},shell:D.shell};f0(),ir.dataset.uiShellSource="leptos-rust-shell",Hi=M,nn=M.mount(ir,te),R.dataset.uiShell="leptos-rust-shell"},Le=()=>{if(u0(),!wi){Fb(),b0();return}f0(),R.dataset.uiShell="debug-fallback",Kn.dataset.testid="mindmap-command-toolbar",Kn.className="mnote-mindmap-command-toolbar",delete Kn.dataset.schemaSource,Zn.dataset.testid="mindmap-sidebar",Zn.className="mnote-mindmap-side-panel",delete Zn.dataset.schemaSource,Qn.dataset.testid="mindmap-bottom-bar",Qn.className="mnote-mindmap-bottom-bar",delete Qn.dataset.schemaSource;let M=a?Yp(a):"",L=f??M,F=s!==null?"":" disabled",K=["\u8282\u70B9\u6837\u5F0F","\u5BFC\u56FE\u6837\u5F0F","\u4E3B\u9898","\u7ED3\u6784","\u5927\u7EB2"].map((ee,ue)=>``).join("");Kn.innerHTML=`
    `,Zn.innerHTML=`${K}
    \u7ECF\u5178\u4E3B\u9898 \xB7 \u903B\u8F91\u7ED3\u6784
    `,Qn.innerHTML=`runtime \u8282\u70B9100%`},b0=()=>{let M=Xn.querySelector('[data-testid="mindmap-schema-context-menu"]');if(!ce){M?.remove();return}M||(M=document.createElement("div"),M.className="mnote-mindmap-context-menu",M.dataset.testid="mindmap-schema-context-menu",M.dataset.uiSource="typescript-nodeview-bridge",Xn.append(M)),M.dataset.contextMenuKind=at,M.dataset.contextMenuTargetNodeKind=bt;let D=Vp({activeNodeId:at==="node"?It??l:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"]}),F=Sc.contextMenuItems.filter(te=>te.requiresNode===(at==="node")),K=te=>D.disabledActions[te]?!0:at!=="node"?!1:bt==="root"&&(te==="insertSiblingAfter"||te==="deleteNode")||bt==="generalization"&&(te==="insertChild"||te==="insertSiblingAfter"||te==="deleteNode"||te==="summary"||te==="associativeLine"||te==="expandCollapse");M.innerHTML=F.map(te=>{let we=K(te.actionId);return``}).join("");let ee=Math.min(Math.max(8,qi),Math.max(8,ve.clientWidth-M.offsetWidth-8)),ue=Math.min(Math.max(8,zt),Math.max(8,ve.clientHeight-M.offsetHeight-8));M.style.left=`${ee}px`,M.style.top=`${ue}px`},r3=()=>{u0(),R.dataset.stage="loading",mt.dataset.runtimeEngine="loading",mt.replaceChildren(),Le()},n3=M=>M==="mnote-web-tree-live"||M==="externalTreeLive"||M==="nodeViewUpdate",qb=M=>M==="mnote-web-tree-live"||M==="externalTreeLive",Hb=()=>R.dataset.stage==="ready"&&mt.dataset.runtimeReady==="true"&&a!==null,Ub=()=>{if(s?.instance.renderer?.textEdit?.isShowTextEdit?.())return!0;let L=document.activeElement;if(L instanceof HTMLElement&&L.closest(".smm-node-edit-wrap"))return!0;let D=document.querySelector('.smm-node-edit-wrap[contenteditable="true"]');return D instanceof HTMLElement&&D.style.display!=="none"&&D.getClientRects().length>0},s3=M=>{let L=s?.instance.renderer?.textEdit;if(!L?.isShowTextEdit?.())return!1;let D=Ds(L.getCurrentEditNode?.())??l??d,F=L.getEditText?.();if(R.dataset.lastRuntimeTextEditFlushReason=M,D&&typeof F=="string"&&F.length>0){R.dataset.lastRuntimeTextEditFlushNodeId=D,R.dataset.lastRuntimeTextEditFlushText=F;let{mindmapId:K}=et(),ee=an();ee&&a&&Gp({documentId:ee,mindmapId:K,commands:[{type:"updateText",mindmapId:K,nodeId:D,text:F}],projectionRevision:a.kernelRevision}).catch(te=>{R.dataset.lastRuntimeTextEditFlushError=te instanceof Error?te.message:String(te)})}return L.hideEditTextBox?.(),!0},a3=(M,L="text_edit")=>{R.dataset.runtimeProjectionDeferred=L,R.dataset.lastRuntimeProjectionDeferReason=M,R.dataset.runtimeProjectionDeferredAt=String(Date.now())},o3=()=>{R.dataset.runtimeProjectionDeferred="",R.dataset.lastRuntimeProjectionDeferReason="",R.dataset.runtimeProjectionDeferredAt=""},Ps=(M,L="")=>{R.dataset.backgroundProjectionRefresh=M,R.dataset.backgroundProjectionRefreshMessage=L,Le()},on=(M,L)=>{let{mindmapId:D}=et();u0(),R.dataset.stage=M,mt.dataset.runtimeEngine="error",mt.innerHTML=`
    ${Rs(M)}${Rs(D)}${Rs(L)}
    `,Le()},Fs=async(M,L)=>{if(R.dataset.commandCount=String(M.length),R.dataset.commandHasProjection=a?"true":"false",R.dataset.commandFailedAction="",R.dataset.commandFailedMessage="",M.length===0||!a){R.dataset.commandStatus="skipped";return}let{mindmapId:D}=et(),F=an();if(!F){on("command_failed",`mindmapId=${D}; documentId_missing`);return}R.dataset.commandStatus="pending";try{let K=await AF({documentId:F,mindmapId:D,commands:M,projectionRevision:a.kernelRevision});if(Ui)return;let ee=L?x0(K,L,et().rootNodeId):void 0;await d3(K,"commandRefresh",ee),f=null,R.dataset.commandStatus="success"}catch(K){let ee=K instanceof Error?K.message:String(K);R.dataset.commandStatus="failed",R.dataset.commandFailedAction=R.dataset.lastSchemaAction??"",R.dataset.commandFailedMessage=ee,on("command_failed",`mindmapId=${D}; ${ee}`)}},l3=async(M,L)=>{if(R.dataset.commandCount=String(M.length),R.dataset.commandHasProjection=a?"true":"false",R.dataset.commandFailedAction="",R.dataset.commandFailedMessage="",R.dataset.commandApplyMode="",R.dataset.commandLocalApplyErrors="",M.length===0||!a){R.dataset.commandStatus="skipped",R.dataset.commandApplyMode="skipped",$i();return}if(!EF(M)){R.dataset.commandApplyMode="refresh:unsupported",$i(),await Fs(M,L);return}let D=Sb();if(!D){R.dataset.commandApplyMode="refresh:no_blob",$i(),await Fs(M,L);return}let F=NF(D,M);if(F.errors.length>0){R.dataset.commandApplyMode="refresh:local_errors",R.dataset.commandLocalApplyErrors=F.errors.join("|"),$i(),await Fs(M,L);return}let{mindmapId:K}=et(),ee=an();if(!ee){on("command_failed",`mindmapId=${K}; documentId_missing`);return}R.dataset.commandStatus="pending",R.dataset.commandApplyMode="local";try{let ue=await Gp({documentId:ee,mindmapId:K,commands:M,projectionRevision:a.kernelRevision});if(Ui)return;if(Ab(F.data,ue.kernelRevision),L){let te=x0(a,L,et().rootNodeId);l=te,d=te,window.setTimeout(()=>{uo(te)},0)}f=null,R.dataset.commandStatus="success",Le()}catch(ue){let te=ue instanceof Error?ue.message:String(ue);R.dataset.commandStatus="failed",R.dataset.commandFailedAction=R.dataset.lastSchemaAction??"",R.dataset.commandFailedMessage=te,$i(),on("command_failed",`mindmapId=${K}; ${te}`)}},$b=async M=>{if(!a)return;let{mindmapId:L}=et(),D=an();if(!D){on("command_failed",`mindmapId=${L}; documentId_missing`);return}R.dataset.viewCommandStatus="pending";try{if(await Gp({documentId:D,mindmapId:L,commands:[CF(L,M)],projectionRevision:a.kernelRevision}),Ui)return;a.view=M,R.dataset.viewCommandStatus="success"}catch(F){on("command_failed",`mindmapId=${L}; ${F instanceof Error?F.message:String(F)}`)}},qs=M=>{let L=HF(M);L&&(A=L,R.dataset.lastViewPatch=JSON.stringify(L),C!==null&&window.clearTimeout(C),C=window.setTimeout(()=>{C=null;let D=A;A=null,D&&$b(D)},350))},jb=M=>{if(s){if(M==="editNode"){let L=s.instance.renderer,D=s.instance.keyCommand,F=L?.textEdit,K=h??L?.activeNodeList?.[0]??null;if(K&&typeof F?.show=="function")F.show({node:K,isFromKeyDown:!1}),R.dataset.editNodeStatus="opened";else if(typeof D?.getShortcutFn=="function"){let ee=D.getShortcutFn("F2")[0];typeof ee=="function"?(ee(),R.dataset.editNodeStatus="opened"):R.dataset.editNodeStatus="unsupported"}else R.dataset.editNodeStatus="unsupported";return}if(M==="centerRoot"&&s.instance.renderer?.setRootNodeCenter?.(),M==="zoomOut"&&s.instance.view?.narrow?.(),M==="zoomIn"&&s.instance.view?.enlarge?.(),M==="fitView"&&s.instance.view?.reset?.(),M==="fullscreenCanvas"||M==="fullscreenPage"||M==="exitFullscreen"){i3(M);return}if(M==="search"){O?(O=!1,R.dataset.lastSearchQuery="",R.dataset.searchStatus="closed",Le()):t3("");return}if(M==="showMenu"){y0("visible"),p0();return}if(M==="expandCollapse"){s.instance.renderer?.toggleActiveExpand?.(),R.dataset.contextMenuActionStatus="success",R.dataset.lastContextMenuAction=M,Le();return}if(M==="copyNodeText"){let L=It??l,D=a?GF(a.root,L):"";R.dataset.copiedNodeText=D,R.dataset.contextMenuActionStatus="success",R.dataset.lastContextMenuAction=M;return}M==="readonly"&&(m=!m,_c()),qs(s.getSnapshot()),Le()}},Gb=(M,L,D)=>{if(!s)return;let F=Nb(M,D);if(!F)return;let K=Lt(s.instance.getThemeConfig?.())?s.instance.getThemeConfig?.():{};if(D&&F.startsWith(`nodes.${D}.data.`)&&h){let ee=F.split(".data.")[1]??"";if(ee==="shape"){h.setShape?.(L);return}if(ee){let ue=ee==="fontWeight"&&L===!0?"bold":ee==="fontStyle"&&L===!0?"italic":L;h.setData?.({[ee]:ue});return}}if(F.startsWith("style.map.")){let ee=F.slice(10);if(!ee)return;s.instance.setThemeConfig?.({...K,[ee]:L},!1)}},Vb=(M,L,D)=>{if(!(!s||L.source!=="sidebar")){if(M==="setLayout"){s.instance.setLayout?.(L.value);return}if(M==="setTheme"){s.instance.setTheme?.(L.value);return}M==="painter"&&typeof L.compatPath=="string"&&Gb(L.compatPath,L.value,D)}},w0=async(M,L={})=>{let D=wb(M);if(!D||Vp({activeNodeId:at==="node"?It??l:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"]}).disabledActions[M])return;if(R.dataset.lastSchemaAction=M,D.target==="localView"){jb(M);return}let K=UF(M),ee=at==="node"?It??d??l:d??l;if(D.requiresActiveNode){let Ge=kc(ee);Ge&&(ee=Ge,l=Ge,d=Ge)}R.dataset.lastSchemaActiveNodeId=ee??"";let ue=et().mindmapId;Vb(M,L,ee);let te=IF({actionId:M,mindmapId:ue,activeNodeId:ee,node:K,value:L.value??(M==="editNode"?Yp(a):!0),source:L.source,runtimeRevision:a?.kernelRevision??null,kernelRevision:a?.kernelRevision??null}),we=Nb(L.compatPath,ee);if(we&&(te={command:_F({mindmapId:ue,path:we,value:L.value??!0,source:L.source??"sidebar",actionId:M,runtimeRevision:a?.kernelRevision??null,kernelRevision:a?.kernelRevision??null})}),R.dataset.lastSchemaCommand=te?.command?JSON.stringify(te.command):"",R.dataset.lastSchemaRuntimeCommand=te?.runtimeCommand??"",!!te){if(D.target==="runtimeCommand"&&te.runtimeCommand){if(te.command){Bs(te.runtimeCommand),D.requiresActiveNode&&uo(ee);let Ge=await zb(te.runtimeCommand,ee,K),u3=K?.uid??(M==="deleteNode"?et().rootNodeId:ee);if(Ge?.ok){K?.uid&&(te.runtimeCommand==="INSERT_CHILD_NODE"||te.runtimeCommand==="INSERT_NODE")&&window.setTimeout(()=>{uo(K.uid)},0),l3([te.command],u3);return}R.dataset.commandApplyMode="refresh:runtime_failed",R.dataset.commandRuntimeError=Ge?.error??"unknown",R.dataset.commandRuntimeMessage=Ge&&"message"in Ge?Ge.message??"":"",$i(),Fs([te.command],u3);return}s?.execCommand(te.runtimeCommand);return}te.command&&Fs([te.command])}},Wb=M=>{let L=M.target instanceof Node&&ve.contains(M.target);return RF({debugChromeEnabled:wi,bridgeReady:!!s,readonly:m,isComposing:M.isComposing,isEditableTarget:qF(M.target),targetInsideRoot:L,keyboardShortcutArmed:le})},Yb=M=>{if(!Wb(M))return;let L=zF(M);if(!L)return;M.preventDefault(),M.stopPropagation(),M.stopImmediatePropagation(),R.dataset.lastShortcutKey=M.key,R.dataset.lastShortcutAction=L;let D=a?Mb(a,et().rootNodeId):et().rootNodeId;if(wb(L)?.requiresActiveNode){let K=kc(d??l);if(K===D&&(L==="insertSiblingAfter"||L==="deleteNode")){let ee=kc(null);ee&&ee!==D?K=ee:a&&(K=Tb(a.root)??K)}if(K)l=K,d=K;else{R.dataset.lastShortcutActionBlocked=L;return}}if((d??l)===D&&(L==="insertSiblingAfter"||L==="deleteNode")){R.dataset.lastShortcutActionBlocked=L;return}w0(L,{source:"toolbar"})},Xb=M=>{if(M.type==="node_active"){let K=l;l=Ds(M.args[0])??l,h=typeof M.args[0]=="object"&&M.args[0]!==null?M.args[0]:null,(!d||d===K)&&(d=l),Le();return}if(M.type==="view_data_change"||M.type==="scale"||M.type==="translate"){R.dataset.lastViewEvent=M.type,qs(M.snapshot??s?.getSnapshot());return}if(M.type!=="data_change"||!a||!M.snapshot)return;let L=Os(M.snapshot);R.dataset.lastDataChangeSeenAt=String(Date.now());let D=vb(c,Date.now());if(c=D.state,Wn(),R.dataset.lastDataChangeSuppressed=D.suppressed?"true":"false",R.dataset.lastDataChangeSuppressionExpired=D.expired?"true":"false",D.suppressed){o=L;return}let F=LF({mindmapId:et().mindmapId,previous:o??a.root,next:L});if(o=L,R.dataset.lastDataChangeDiffCommandCount=String(F.commands.length),R.dataset.lastDataChangeCompatPatchCount=String(F.compatPatches.length),F.commands.length===0&&F.compatPatches.length===0){R.dataset.lastDataChangeRefreshTriggered="false";return}R.dataset.lastDataChangeRefreshTriggered="false",l3([...F.commands,...F.compatPatches])},h3=M=>typeof M=="string"&&M.trim().length>0?M.trim():Lt(M)&&typeof M.template=="string"&&M.template.trim().length>0?M.template.trim():null,Kb=(M,L,D)=>{if(!s)return!1;let{mindmapId:F,rootNodeId:K}=et();if(R.dataset.mountedMindmapId&&R.dataset.mountedMindmapId!==F)return!1;let ee=vi(M.root);if(typeof s.instance.setData!="function")return!1;a={...M,root:Os(ee)},l=x0(M,D??l,K),h=null,d=l,o=Os(a.root);let ue=h3(M.layout),te=h3(M.theme),we=Lt(M.themeConfig)?M.themeConfig:null;return ue&&s.instance.setLayout?.(ue,!0),te&&s.instance.setTheme?.(te,!0),we&&s.instance.setThemeConfig?.(we,!0),s.instance.setData(ee),Mr+=1,R.dataset.runtimeProjectionApplyCount=String(Mr),R.dataset.lastRuntimeProjectionApplyReason=L,mt.dataset.runtimeEngine="simple-mind-map",mt.dataset.runtimeReady="true",R.dataset.stage="ready",Ac(F,s),_c(),window.setTimeout(()=>{uo(l)},0),Le(),!0},d3=async(M,L,D)=>{let{mindmapId:F,rootNodeId:K}=et();if(di&&(s?.instance.off?.("node_contextmenu",di),di=null),s?.destroy(),Ac(F,null),a={...M,root:Os(M.root)},l=x0(M,D,K),h=null,d=l,o=Os(a.root),co+=1,R.dataset.runtimeMountCount=String(co),R.dataset.lastRuntimeMountReason=L,R.dataset.mountedMindmapId=F,R.dataset.mountedRootNodeId=K,mt.dataset.runtimeEngine="simple-mind-map",mt.dataset.runtimeReady="false",mt.replaceChildren(),Le(),s=await SF({el:mt,projection:M,mode:m?"readonly":"edit",runtimeOptions:{fit:!0,mousewheelAction:"zoom",enableFreeDrag:!0,enableCtrlKeyNodeSelection:!0,useLeftKeySelectionRightKeyDrag:!0,createNewNodeBehavior:"activeOnly"},onEvent:Xb}),Ui){s.destroy();return}s.refreshProjection=c3,di=(...ee)=>{let[ue,te]=ee;ue instanceof MouseEvent&&(ue.preventDefault(),ue.stopPropagation(),Rb(ue.clientX,ue.clientY,te))},s.instance.on?.("node_contextmenu",di),mt.dataset.runtimeReady="true",R.dataset.stage="ready",Ac(F,s),_c(),window.setTimeout(()=>{uo(l)},0),Le()},M0=async(M="fetchScene",L=0)=>{let D=++n,{mindmapId:F,rootNodeId:K}=et();bi!==null&&(window.clearTimeout(bi),bi=null);let ee=an();if(!ee){if(R.dataset.documentIdResolveStatus="missing",R.dataset.documentIdResolveRetryCount=String(L),L<30){n3(M)||r3(),bi=window.setTimeout(()=>{bi=null,Ui||M0(M,L+1)},100);return}on("projection_load_failed",`mindmapId=${F}; documentId_missing`);return}R.dataset.documentIdResolveStatus="ready",R.dataset.lastFetchSceneReason=M;let ue=n3(M)&&Hb();if(ue&&qb(M)){a3(M,"live_signal"),Ps("deferred","usability_first");return}ue?Ps("pending"):r3();try{if(D!==n)return;let te=await kF({documentId:ee,mindmapId:F,endpoint:`/api/mindmap/${encodeURIComponent(ee)}/${encodeURIComponent(F)}?view=simple_mind_map_scene&queryName=mindmap.simple_mind_map_scene.get&rootNodeId=${encodeURIComponent(K)}`});if(D!==n||Ui)return;try{let we=bb({documentId:ee,mindmapId:F,data:vi(te.root)}),Ge=await fetch(we.endpoint,we.init);R.dataset.initialCreateOnlyStatus=Ge.ok?"success":"failed"}catch{R.dataset.initialCreateOnlyStatus="failed"}if(ue&&Ub()){a3(M),Ps("deferred","text_edit");return}if(ue&&Kb(te,M)){o3(),Ps("success");return}await d3(te,M),o3(),Ps("success")}catch(te){if(ue){Ps("failed",te instanceof Error?te.message:String(te));return}on("projection_load_failed",`mindmapId=${F}; ${te instanceof Error?te.message:String(te)}`)}},c3=async(M="externalTreeLive")=>{if(!Ui){if(tr){sn=M;return}tr=!0;try{await M0(M)}finally{tr=!1;let L=sn;sn=null,L&&!Ui&&c3(L)}}};return Je.addEventListener("pointerdown",M=>M.stopPropagation()),Je.addEventListener("mousedown",M=>M.stopPropagation()),ve.addEventListener("pointerleave",()=>{m0(),!ce&&Y==="visible"&&y0(Ec(Y,"pointerLeave"))}),ve.addEventListener("pointerenter",()=>{Y=Ec(Y,"pointerEnter"),R.dataset.chromeVisibility=Y}),ve.addEventListener("pointerdown",()=>{e3(),Y!=="visible"&&y0(Ec(Y,"restoreClick"))},!0),ve.addEventListener("click",()=>{e3(),Y!=="visible"&&y0(Ec(Y,"restoreClick"))}),Je.addEventListener("mnote:mindmap-shell:action",M=>{let L=M.detail,D=L?.actionId;if(D==="search"){if(typeof L?.value=="string"){t3(L.value);return}if(L?.value===!1){O=!1,R.dataset.lastSearchQuery="",R.dataset.searchStatus="closed",Le();return}}D&&(m0(),w0(D,L))}),Je.addEventListener("mnote:mindmap-shell:zoom",M=>{let L=M.detail;Pb(L?.percent)}),Je.addEventListener("mnote:mindmap-shell:minimap",M=>{let L=M.detail;I=typeof L?.open=="boolean"?L.open:!I,R.dataset.minimapOpen=I?"true":"false",Le()}),Je.addEventListener("mnote:mindmap-shell:toolbar-overflow",M=>{let L=M.detail;P=typeof L?.moreOpen=="boolean"?L.moreOpen:!P,Le()}),Je.addEventListener("mnote:mindmap-shell:panel",M=>{let L=M.detail,D=L?.event??"togglePanel";if(D==="restoreTrigger"){y=!0,x=!0,b=!1,Le();return}if(D==="hideTrigger"){y=!1,x=!1,b=!0,Le();return}if(D==="closeDrawer"){x=!1,b=!1,Le();return}L?.panelId&&(L.panelId===g?x=!x:(g=L.panelId,x=!0),y=!0,b=!1,Le())}),ke=()=>Cc(),document.addEventListener("fullscreenchange",ke),Q=()=>{s3("page_lifecycle")},window.addEventListener("pagehide",Q),window.addEventListener("beforeunload",Q),Je.addEventListener("input",M=>{if(!wi)return;let L=M.target;L instanceof HTMLInputElement&&L.dataset.testid==="mindmap-command-text-input"&&(f=L.value)}),typeof ResizeObserver<"u"&&(W=new ResizeObserver(M=>{let L=M[0]?.contentRect.width??null;L===null||Math.abs(L-(q??0))<1||(q=L,wi||Le())}),W.observe(ve)),ne=M=>{let L=M.target;if((!(L instanceof Node)||!ve.contains(L))&&Ob(),ce){if(L instanceof Node){let D=Xn.querySelector('[data-testid="mindmap-schema-context-menu"]');if(D instanceof HTMLElement&&D.contains(L))return}p0()}P&&(L instanceof Node&&ir.contains(L)||m0())},re=M=>{if(M.key==="Escape"){if(ce){M.preventDefault(),p0();return}if(v0()){M.preventDefault(),i3("exitFullscreen");return}P&&(M.preventDefault(),m0())}},oe=M=>Yb(M),document.addEventListener("pointerdown",ne),document.addEventListener("keydown",re),document.addEventListener("keydown",oe,!0),Je.addEventListener("click",M=>{M.stopPropagation();let L=M.target;if(!(L instanceof HTMLElement))return;let D=L.closest("button");if(D instanceof HTMLButtonElement){if(!wi){M.preventDefault();let F=D.dataset.mindmapContextActionId;if(F){if(D.disabled||D.dataset.disabled==="true")return;p0(),w0(F);return}if(D.closest('[data-testid="mindmap-rust-shell"]'))return;let K=D.dataset.mindmapActionId;K&&w0(K);let ee=D.dataset.mindmapSidebarPanelId;ee&&(g=ee,Le());return}if(D.dataset.testid==="mindmap-command-update-text"){M.preventDefault();let F=ve.querySelector('[data-testid="mindmap-command-text-input"]'),K=f??(F instanceof HTMLInputElement?F.value:Yp(a));R.dataset.lastCommandText=K,Fs([{type:"updateText",mindmapId:et().mindmapId,nodeId:l??et().rootNodeId,text:K}])}D.dataset.testid==="mindmap-command-add-child"&&(M.preventDefault(),s?.execCommand("INSERT_CHILD_NODE")),D.dataset.testid==="mindmap-command-add-sibling-after"&&(M.preventDefault(),s?.execCommand("INSERT_NODE")),D.dataset.testid==="mindmap-command-delete-node"&&(M.preventDefault(),s?.execCommand("REMOVE_NODE")),D.dataset.testid==="mindmap-toolbar-undo"&&(M.preventDefault(),s?.execCommand("BACK")),D.dataset.testid==="mindmap-toolbar-redo"&&(M.preventDefault(),s?.execCommand("FORWARD")),D.dataset.testid==="mindmap-toolbar-summary"&&(M.preventDefault(),s?.execCommand("ADD_GENERALIZATION")),D.dataset.testid==="mindmap-bottom-center-root"&&(M.preventDefault(),s?.instance.renderer?.setRootNodeCenter?.(),qs(s?.getSnapshot())),D.dataset.testid==="mindmap-bottom-zoom-out"&&(M.preventDefault(),s?.instance.view?.narrow?.(),qs(s?.getSnapshot())),D.dataset.testid==="mindmap-bottom-zoom-in"&&(M.preventDefault(),s?.instance.view?.enlarge?.(),qs(s?.getSnapshot()))}}),Je.addEventListener("contextmenu",M=>{if(wi)return;let L=M.target;if(L instanceof Element&&(L.closest(".smm-node")||L.closest('[class*="generalization_"]'))){M.preventDefault();return}M.preventDefault(),M.stopPropagation(),Db(M.clientX,M.clientY)},!0),c0.append(mt),wi?(Yn.append(mt,Zn),R.append(Kn,Yn,Qn)):(Xn.append(ir),Yn.append(c0,Xn),R.append(Yn)),ve.append(R),Je.append(ve),M0("initial"),{dom:Je,update(M){if(M.type.name!==r.type.name)return!1;let L=Kp(r);return r=M,r.attrs.mnoteBlockType!=="mindmap"?!1:(u0(),Kp(r)!==L&&M0("nodeViewUpdate"),!0)},stopEvent:()=>!0,ignoreMutation:()=>!0,destroy(){s3("node_view_destroy"),Ui=!0,bi!==null&&window.clearTimeout(bi),C!==null&&window.clearTimeout(C),W?.disconnect(),ne&&document.removeEventListener("pointerdown",ne),re&&document.removeEventListener("keydown",re),oe&&document.removeEventListener("keydown",oe,!0),ke&&document.removeEventListener("fullscreenchange",ke),Q&&(window.removeEventListener("pagehide",Q),window.removeEventListener("beforeunload",Q)),di&&s?.instance.off?.("node_contextmenu",di);let{mindmapId:M}=et();Ac(M,null),s?.destroy(),f0(),s=null}}}}function ZF(){return({node:i})=>{let e=i,t=document.createElement("p"),r=()=>{let n=e.attrs.blockId;typeof n=="string"&&n.length>0?(t.dataset.blockId=n,t.id=n):(t.removeAttribute("data-block-id"),t.removeAttribute("id"))};return r(),{dom:t,contentDOM:t,update(n){return n.type.name!==e.type.name||n.attrs.mnoteBlockType==="mindmap"?!1:(e=n,r(),!0)}}}}var QF=p3.extend({addAttributes(){return{...this.parent?.(),blockId:{default:null,parseHTML:i=>i.getAttribute("data-block-id"),renderHTML:i=>BF(i.blockId)},mnoteBlockType:{default:null,parseHTML:i=>i.getAttribute("data-mnote-block-type"),renderHTML:i=>PF(i)},mindmapId:{default:null,parseHTML:i=>i.getAttribute("data-mnote-mindmap-id"),renderHTML:()=>({})},rootNodeId:{default:null,parseHTML:i=>i.getAttribute("data-mnote-root-node-id"),renderHTML:()=>({})},projectionVersion:{default:null,parseHTML:i=>Number(i.getAttribute("data-mnote-projection-version")??1),renderHTML:()=>({})}}},addNodeView(){let i=KF(this.editor),e=ZF();return({node:t,getPos:r})=>t.attrs.mnoteBlockType==="mindmap"?i({node:t,getPos:r}):e({node:t})}}),JF={name:"paragraph",create:()=>QF,commands:{set_paragraph:i=>i.chain().focus().setParagraph().run()},selection_keys:["paragraph"],selection_state:i=>({paragraph:i.isActive("paragraph")})};function Jne(){y3(JF)}export{Jne as register_paragraph,FF as resolveCurrentDocumentId}; + `,minExportImgCanvasScale:2,addContentToHeader:null,addContentToFooter:null,handleBeingExportSvg:null,maxCanvasSize:16384,defaultAssociativeLineText:"\u5173\u8054",associativeLineIsAlwaysAboveNode:!0,associativeLineInitPointsPosition:{from:"",to:""},enableAdjustAssociativeLinePoints:!0,beforeAssociativeLineConnection:null,disableTouchZoom:!1,minTouchZoomScale:20,maxTouchZoomScale:-1,isLimitMindMapInCanvasWhenHasScrollbar:!0,isOnlySearchCurrentRenderNodes:!1,beforeCooperateUpdate:null,rainbowLinesConfig:{open:!1,colorsList:[]},demonstrateConfig:null,enableEditFormulaInRichTextEdit:!0,katexFontPath:"https://unpkg.com/katex@0.16.11/dist/",getKatexOutputType:null,transformRichTextOnEnterEdit:null,beforeHideRichTextEdit:null,outerFramePaddingX:10,outerFramePaddingY:10,defaultOuterFrameText:"\u5916\u6846",onlyPainterNodeCustomStyles:!1,beforeDeleteNodeImg:null,imgResizeBtnSize:25,minImgResizeWidth:50,minImgResizeHeight:50,maxImgResizeWidthInheritTheme:!1,maxImgResizeWidth:1/0,maxImgResizeHeight:1/0,customDeleteBtnInnerHTML:"",customResizeBtnInnerHTML:""}});var gb={};tt(gb,{default:()=>cF});var qp,It,Hp,cF,xb=T(()=>{Bv();Uv();sb();qp=yt(j0());ab();ih();lb();ub();mb();Ge();wt();pe();qo();pb();It=class i{constructor(e={}){if(i.instanceCount++,this.opt=this.handleOpt((0,qp.default)(Fp,e)),this.opt.data=this.handleData(this.opt.data),this.el=this.opt.el,!this.el)throw new Error("\u7F3A\u5C11\u5BB9\u5668\u5143\u7D20el");this.getElRectInfo(),this.initWidth=this.width,this.initHeight=this.height,this.cssEl=null,this.cssTextMap={},this.nodeInnerPrefixList=[],this.nodeInnerPostfixList=[],this.editNodeClassList=[],this.extendShapeList=[],this.initContainer(),this.initTheme(),this.initCache(),i.pluginList.filter(t=>t.preload).forEach(t=>{this.initPlugin(t)}),this.event=new Hv({mindMap:this}),this.keyCommand=new p0({mindMap:this}),this.command=new cb({mindMap:this}),this.renderer=new nb({mindMap:this}),this.view=new Ov({mindMap:this}),this.batchExecution=new fb,i.pluginList.filter(t=>!t.preload).forEach(t=>{this.initPlugin(t)}),this.addCss(),this.render(this.opt.fit?()=>this.view.fit():()=>{}),this.opt.addHistoryOnInit&&this.opt.data&&this.command.addHistory()}handleOpt(e){return eu.includes(e.layout)||(e.layout=C.LAYOUT.LOGICAL_STRUCTURE),e.theme=e.theme&&$n[e.theme]?e.theme:"default",e}handleData(e){return Kt(e)||Object.keys(e).length<=0?null:(e=Qt(e||{}),e.data&&!e.data.expand&&(e.data.expand=!0),cs([e],!1,null,!0),e)}initContainer(){let{associativeLineIsAlwaysAboveNode:e}=this.opt;this.el.classList.add("smm-mind-map-container");let t=()=>{this.associativeLineDraw=this.draw.group(),this.associativeLineDraw.addClass("smm-associative-line-container")};this.svg=ke().addTo(this.el).size(this.width,this.height),this.draw=this.svg.group(),this.draw.addClass("smm-container"),this.lineDraw=this.draw.group(),this.lineDraw.addClass("smm-line-container"),e||t(),this.nodeDraw=this.draw.group(),this.nodeDraw.addClass("smm-node-container"),e&&t(),this.otherDraw=this.draw.group(),this.otherDraw.addClass("smm-other-container")}clearDraw(){this.lineDraw.clear(),this.associativeLineDraw.clear(),this.nodeDraw.clear(),this.otherDraw.clear()}appendCss(e,t){this.cssTextMap[e]=t,this.removeCss(),this.addCss()}removeAppendCss(e){this.cssTextMap[e]&&(delete this.cssTextMap[e],this.removeCss(),this.addCss())}joinCss(){return $3+Object.keys(this.cssTextMap).map(e=>this.cssTextMap[e]).join(` +`)}addCss(){this.cssEl=document.createElement("style"),this.cssEl.type="text/css",this.cssEl.innerHTML=this.joinCss(),document.head.appendChild(this.cssEl)}removeCss(){this.cssEl&&document.head.removeChild(this.cssEl)}checkEditNodeClassIndex(e){return this.editNodeClassList.findIndex(t=>t===e)}addEditNodeClass(e){this.checkEditNodeClassIndex(e)===-1&&this.editNodeClassList.push(e)}deleteEditNodeClass(e){let t=this.checkEditNodeClassIndex(e);t!==-1&&this.editNodeClassList.splice(t,1)}render(e,t=""){this.initTheme(),this.renderer.render(e,t)}reRender(e,t=""){this.renderer.reRender=!0,this.renderer.clearCache(),this.clearDraw(),this.render(e,t)}getElRectInfo(){if(this.elRect=this.el.getBoundingClientRect(),this.width=this.elRect.width,this.height=this.elRect.height,this.width<=0||this.height<=0)throw new Error("\u5BB9\u5668\u5143\u7D20el\u7684\u5BBD\u9AD8\u4E0D\u80FD\u4E3A0")}resize(){let e=this.width,t=this.height;this.getElRectInfo(),this.svg.size(this.width,this.height),(e!==this.width||t!==this.height)&&(this.demonstrate?this.demonstrate.isInDemonstrate||this.render():this.render()),this.emit("resize")}on(e,t){this.event.on(e,t)}emit(e,...t){this.event.emit(e,...t)}off(e,t){this.event.off(e,t)}initCache(){this.commonCaches={measureCustomNodeContentSizeEl:null,measureRichtextNodeTextSizeEl:null}}initTheme(){this.themeConfig=Iu($n[this.opt.theme]||$n.default,this.opt.themeConfig),Wo.setBackgroundStyle(this.el,this.themeConfig)}setTheme(e,t=!1){this.execCommand("CLEAR_ACTIVE_NODE"),this.opt.theme=e,t||this.render(null,C.CHANGE_THEME),this.emit("view_theme_change",e)}getTheme(){return this.opt.theme}setThemeConfig(e,t=!1){let r=P2(this.themeConfig,e);if(this.opt.themeConfig=e,!t){let n=S2(r);this.render(null,n?"":C.CHANGE_THEME)}}getCustomThemeConfig(){return this.opt.themeConfig}getThemeConfig(e){return e===void 0?this.themeConfig:this.themeConfig[e]}getConfig(e){return e===void 0?this.opt:this.opt[e]}updateConfig(e={}){this.emit("before_update_config",this.opt);let t={...this.opt};this.opt=this.handleOpt(qp.default.all([Fp,this.opt,e])),this.emit("after_update_config",this.opt,t)}getLayout(){return this.opt.layout}setLayout(e,t=!1){eu.includes(e)||(e=C.LAYOUT.LOGICAL_STRUCTURE),this.opt.layout=e,this.view.reset(),this.renderer.setLayout(),t||this.render(null,C.CHANGE_LAYOUT),this.emit("layout_change",e)}execCommand(...e){this.command.exec(...e)}updateData(e){e=this.handleData(e),this.emit("before_update_data",e),this.renderer.setData(e),this.render(),this.command.addHistory(),this.emit("update_data",e)}setData(e){e=this.handleData(e),this.emit("before_set_data",e),this.opt.data=e,this.execCommand("CLEAR_ACTIVE_NODE"),this.command.clearHistory(),this.command.addHistory(),this.renderer.setData(e),this.reRender(),this.emit("set_data",e)}setFullData(e){e.root&&this.setData(e.root),e.layout&&this.setLayout(e.layout),e.theme&&(e.theme.template&&this.setTheme(e.theme.template),e.theme.config&&this.setThemeConfig(e.theme.config)),e.view&&this.view.setTransformData(e.view)}getData(e){let t=this.command.getCopyData(),r={};return e?r={layout:this.getLayout(),root:t,theme:{template:this.getTheme(),config:this.getCustomThemeConfig()},view:this.view.getTransformData()}:r=t,Qt(r)}async export(...e){try{if(!this.doExport)throw new Error("\u8BF7\u6CE8\u518CExport\u63D2\u4EF6\uFF01");return await this.doExport.export(...e)}catch(t){this.opt.errorHandler(Ti.EXPORT_ERROR,t)}}toPos(e,t){return{x:e-this.elRect.left,y:t-this.elRect.top}}setMode(e){if(![C.MODE.READONLY,C.MODE.EDIT].includes(e))return;let t=e===C.MODE.READONLY;t!==this.opt.readonly&&(t&&(this.renderer.textEdit.isShowTextEdit()&&(this.renderer.textEdit.hideEditTextBox(),this.command.originAddHistory()),this.execCommand("CLEAR_ACTIVE_NODE")),this.opt.readonly=t,!t&&this.command.history.length<=0&&this.command.originAddHistory(),this.emit("mode_change",e))}getSvgData({paddingX:e=0,paddingY:t=0,ignoreWatermark:r=!1,addContentToHeader:n,addContentToFooter:s,node:a}={}){let{watermarkConfig:o,openPerformance:l}=this.opt;l&&this.renderer.forceLoadNode(a);let{cssTextList:h,header:d,headerHeight:c,footer:f,footerHeight:m}=Y2({addContentToHeader:n,addContentToFooter:s}),g=this.svg,x=this.draw,y=g.width(),b=g.height(),E=x.transform(),k=this.elRect;x.scale(1/E.scaleX,1/E.scaleY);let L=x.rbox(),I=null;a&&(I=Lu(a,L.x,L.y,e,t));let O=0;L.width+=e*2,L.height+=t*2+O+c+m,x.translate(e,t),g.size(L.width,L.height),x.translate(-L.x+k.left,-L.y+k.top);let q=g.clone(),F=this.watermark&&this.watermark.hasWatermark();if(!r&&F){this.watermark.isInExport=!0;let{onlyExport:re}=o;L.width>y||L.height>b?(this.width=L.width,this.height=L.height,this.watermark.onResize(),q=g.clone(),this.width=y,this.height=b,this.watermark.onResize()):re&&(this.watermark.onResize(),q=g.clone()),re&&this.watermark.clear(),this.watermark.isInExport=!1}[this.joinCss(),...h].forEach(re=>{q.add(ke(``))}),d&&c>0&&(q.findOne(".smm-container").translate(0,c),d.width(L.width),d.y(t),q.add(d,0)),f&&m>0&&(f.width(L.width),f.y(L.height-t-m),q.add(f));let W=g.find("defs"),ne=q.find("defs");return W.forEach((re,le)=>{let Ce=ne[le];if(!Ce)return;let te=re.children(),Q=Ce.children();for(let oe=0;oer.name===e.name)||this.extendShapeList.push(e)}removeShape(e){let t=this.extendShapeList.findIndex(r=>r.name===e);t!==-1&&this.extendShapeList.splice(t,1)}getSvgObjects(){return{SVG:ke,G:Le,Rect:Ve}}addPlugin(e,t){i.hasPlugin(e)===-1&&i.usePlugin(e,t),this.initPlugin(e)}removePlugin(e){let t=i.hasPlugin(e);t!==-1&&(i.pluginList.splice(t,1),this[e.instanceName]&&(this[e.instanceName].beforePluginRemove&&this[e.instanceName].beforePluginRemove(),delete this[e.instanceName]))}initPlugin(e){this[e.instanceName]||(this[e.instanceName]=new e({mindMap:this,pluginOpt:e.pluginOpt}))}destroy(){this.emit("beforeDestroy"),this.renderer.textEdit.hideEditTextBox(),this.renderer.textEdit.removeTextEditEl(),[...i.pluginList].forEach(e=>{this[e.instanceName]&&this[e.instanceName].beforePluginDestroy&&this[e.instanceName].beforePluginDestroy(),this[e.instanceName]=null}),this.event.unbind(),this.svg.remove(),Wo.removeBackgroundStyle(this.el),this.el.classList.remove("smm-mind-map-container"),this.el.innerHTML="",this.el=null,this.removeCss(),i.instanceCount--}},Hp=[];It.extendNodeDataNoStylePropList=(i=[])=>{Hp.push(...i),js.push(...i)};It.resetNodeDataNoStylePropList=()=>{Hp.forEach(i=>{let e=js.findIndex(t=>t===i);e!==-1&&js.splice(e,1)}),Hp=[]};It.pluginList=[];It.usePlugin=(i,e={})=>(It.hasPlugin(i)!==-1||(i.pluginOpt=e,It.pluginList.push(i)),It);It.hasPlugin=i=>It.pluginList.findIndex(e=>e===i);It.instanceCount=0;It.defineTheme=(i,e={})=>{if($n[i])return new Error("\u8BE5\u4E3B\u9898\u540D\u79F0\u5DF2\u5B58\u5728");$n[i]=Iu(G0,e)};It.removeTheme=i=>{$n[i]&&($n[i]=null)};cF=It});var $c=globalThis.__LEPTOS_TIPTAP_BRIDGE__;if($c==null||$c.modules==null)throw new Error("leptos-tiptap bridge bindings are unavailable");var j=$c.modules["@tiptap/core"];if(j==null)throw new Error('leptos-tiptap bridge module "@tiptap/core" is unavailable');var Aq=j.CommandManager,kq=j.Editor,Cq=j.Extension,_q=j.InputRule,Lq=j.Mark,A3=j.Node,Iq=j.NodePos,zq=j.NodeView,Rq=j.PasteRule,Dq=j.Tracker,Oq=j.callOrReturn,Bq=j.canInsertNode,Pq=j.combineTransactionSteps,Fq=j.createChainableState,qq=j.createDocument,Hq=j.createNodeFromContent,Uq=j.createStyleTag,$q=j.defaultBlockAt,jq=j.deleteProps,Gq=j.elementFromString,Wq=j.escapeForRegEx,Vq=j.extensions,Yq=j.findChildren,Xq=j.findChildrenInRange,Kq=j.findDuplicates,Zq=j.findParentNode,Qq=j.findParentNodeClosestToPos,Jq=j.fromString,eH=j.generateHTML,tH=j.generateJSON,iH=j.generateText,rH=j.getAttributes,nH=j.getAttributesFromExtensions,sH=j.getChangedRanges,aH=j.getDebugJSON,oH=j.getExtensionField,lH=j.getHTMLFromFragment,hH=j.getMarkAttributes,dH=j.getMarkRange,cH=j.getMarkType,uH=j.getMarksBetween,fH=j.getNodeAtPosition,mH=j.getNodeAttributes,pH=j.getNodeType,gH=j.getRenderedAttributes,xH=j.getSchema,yH=j.getSchemaByResolvedExtensions,vH=j.getSchemaTypeByName,bH=j.getSchemaTypeNameByName,wH=j.getSplittedAttributes,MH=j.getText,TH=j.getTextBetween,NH=j.getTextContentFromNodes,EH=j.getTextSerializersFromSchema,SH=j.injectExtensionAttributesToParseRule,AH=j.inputRulesPlugin,kH=j.isActive,CH=j.isAtEndOfNode,_H=j.isAtStartOfNode,LH=j.isEmptyObject,IH=j.isExtensionRulesEnabled,zH=j.isFunction,RH=j.isList,DH=j.isMacOS,OH=j.isMarkActive,BH=j.isNodeActive,PH=j.isNodeEmpty,FH=j.isNodeSelection,qH=j.isNumber,HH=j.isPlainObject,UH=j.isRegExp,$H=j.isSafari,jH=j.isString,GH=j.isTextSelection,WH=j.isiOS,VH=j.markInputRule,YH=j.markPasteRule,k3=j.mergeAttributes,XH=j.mergeDeep,KH=j.minMax,ZH=j.nodeInputRule,QH=j.nodePasteRule,JH=j.objectIncludes,eU=j.pasteRulesPlugin,tU=j.posToDOMRect,iU=j.removeDuplicates,rU=j.resolveFocusPosition,nU=j.rewriteUnknownContent,sU=j.selectionToInsertionEnd,aU=j.splitExtensions,oU=j.textInputRule,lU=j.textPasteRule,hU=j.textblockTypeInputRule,dU=j.wrappingInputRule;var C3=A3.create({name:"paragraph",priority:1e3,addOptions(){return{HTMLAttributes:{}}},group:"block",content:"inline*",parseHTML(){return[{tag:"p"}]},renderHTML({HTMLAttributes:i}){return["p",k3(this.options.HTMLAttributes,i),0]},addCommands(){return{setParagraph:()=>({commands:i})=>i.setNode(this.name)}},addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setParagraph()}}});var _3="__LEPTOS_TIPTAP_BRIDGE__";function kw(){let i=globalThis,e=i[_3];if(e!=null)return e;let t={modules:{},registerExtension:()=>{throw new Error("leptos-tiptap bridge runtime is not initialized")}};return i[_3]=t,t}function L3(){return kw()}function I3(i){L3().registerExtension(i)}var Wc={};tt(Wc,{applyMetadataOnlyMindmapCommands:()=>O3,applyMindmapCommandsLocally:()=>zw,isLocallyApplicableMindmapCommandSet:()=>Iw,isMetadataOnlyMindmapCommandSet:()=>Lw});var Cw={data:{text:"\u4E2D\u5FC3\u4E3B\u9898"},children:[]},vt=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),ir=i=>JSON.parse(JSON.stringify(i)),R3=i=>{let e=vt(i)?ir(i):ir(Cw);return vt(e.data)||(e.data={text:"\u4E2D\u5FC3\u4E3B\u9898"}),Array.isArray(e.children)||(e.children=[]),e},D3=(i,e)=>{if(!vt(i)||!vt(e))return ir(e);let t={...i};return Object.entries(e).forEach(([r,n])=>{if(n===null){delete t[r];return}t[r]=vt(t[r])&&vt(n)?D3(t[r],n):ir(n)}),t},jc=(i,e,t)=>{let r=e.split(".").filter(Boolean);if(r.length===0)return!1;let n=i;for(let s of r.slice(0,-1))vt(n[s])||(n[s]={}),n=n[s];return n[r[r.length-1]]=ir(t),!0},I0=(i,e)=>{if(!vt(i))return null;let t=vt(i.data)?i.data:null;if(typeof t?.uid=="string"&&t.uid===e)return i;let r=Array.isArray(i.children)?i.children:[];for(let n of r){let s=I0(n,e);if(s)return s}return null},Gc=(i,e)=>{for(let t=0;t({data:{uid:i.uid??`node_${Date.now().toString(36)}`,text:i.text,...typeof i.hyperlink=="string"?{hyperlink:i.hyperlink}:{},...typeof i.note=="string"?{note:i.note}:{},...Array.isArray(i.refs)?{refs:ir(i.refs)}:{}},children:[]}),_w=(i,e)=>{let t=String(e.path||"").trim();if(!t)return!1;if(t.startsWith("root.data.")){let n=t.slice(10),s=vt(i.data)?i.data:i.data={};return jc(s,n,e.value)}if(t.startsWith("nodes.")){let[,n,s,...a]=t.split(".");if(!n||s!=="data"||a.length===0)return!1;let o=I0(i,n);if(!o)return!1;let l=vt(o.data)?o.data:o.data={};return jc(l,a.join("."),e.value)}let r=vt(i.compatPayload)?i.compatPayload:i.compatPayload={};return jc(r,t,e.value)},Lw=i=>Array.isArray(i)&&i.every(e=>!vt(e)||typeof e.type!="string"?!1:["setLayout","setTheme","patchView","compatPayloadPatch"].includes(e.type)),Iw=i=>Array.isArray(i)&&i.every(e=>!vt(e)||typeof e.type!="string"?!1:["updateText","insertChild","insertSiblingAfter","deleteNode","setLayout","setTheme","patchView","compatPayloadPatch"].includes(e.type)),O3=(i,e)=>{let t=R3(i),r=[],n=0;return e.forEach(s=>{if(s.type==="setLayout"){t.layout=ir(s.layout),n+=1;return}if(s.type==="setTheme"){t.theme=ir(s.theme),s.themeConfig!==void 0&&s.themeConfig!==null&&(t.themeConfig=ir(s.themeConfig)),n+=1;return}if(s.type==="patchView"){t.view=D3(t.view??{},s.patch),n+=1;return}s.type==="compatPayloadPatch"&&(_w(t,s)?n+=1:r.push(`\u65E0\u6CD5\u5E94\u7528 compatPayloadPatch:${s.path}`))}),{applied:n,data:t,errors:r}},zw=(i,e)=>{let t=R3(i),r=[],n=0;return e.forEach(s=>{if(s.type==="setLayout"||s.type==="setTheme"||s.type==="patchView"||s.type==="compatPayloadPatch"){let a=O3(t,[s]);Object.assign(t,a.data),n+=a.applied,r.push(...a.errors);return}if(s.type==="updateText"){let a=I0(t,s.nodeId);if(!a){r.push(`\u672A\u627E\u5230\u8282\u70B9:${s.nodeId}`);return}let o=vt(a.data)?a.data:a.data={};o.text=s.text,n+=1;return}if(s.type==="insertChild"){let a=I0(t,s.parentNodeId);if(!a){r.push(`\u672A\u627E\u5230\u7236\u8282\u70B9:${s.parentNodeId}`);return}(Array.isArray(a.children)?a.children:a.children=[]).push(z3(s.node)),n+=1;return}if(s.type==="insertSiblingAfter"){let a=Gc([t],s.targetNodeId);if(!a){r.push(`\u672A\u627E\u5230\u540C\u7EA7\u8282\u70B9:${s.targetNodeId}`);return}if(a.parentChildren[a.index]===t){r.push("\u6839\u8282\u70B9\u4E0D\u652F\u6301\u63D2\u5165\u540C\u7EA7\u8282\u70B9");return}a.parentChildren.splice(a.index+1,0,z3(s.node)),n+=1;return}if(s.type==="deleteNode"){let a=Gc([t],s.nodeId);if(!a){r.push(`\u672A\u627E\u5230\u5220\u9664\u8282\u70B9:${s.nodeId}`);return}if(a.parentChildren[a.index]===t){r.push("\u6839\u8282\u70B9\u4E0D\u652F\u6301\u5220\u9664");return}a.parentChildren.splice(a.index,1),n+=1}}),{applied:n,data:t,errors:r}};var Wp={};tt(Wp,{MindmapCommandBridgeError:()=>ho,createLeptosMindmapAdapter:()=>AF,createMindmapAdapterProjectionEndpoint:()=>Mb,createMindmapCommandApplyEndpoint:()=>jp,executeMindmapCommandApply:()=>Tb,executeMindmapCommandApplyAndRefreshProjection:()=>EF,executeMindmapDataPutAndRefreshProjection:()=>SF,isMindmapAdapterProjection:()=>$p,requestMindmapAdapterProjection:()=>Gp});var Xc={};tt(Xc,{DEFAULT_MINDMAP_LAYOUT:()=>z0,DEFAULT_MINDMAP_THEME:()=>R0,buildMindmapEditorScene:()=>Dw,buildMindmapProjection:()=>Rw,buildMindmapSimpleMindMapScene:()=>Ow,canonicalizeMindmapData:()=>fi,createDefaultMindmapThemeConfig:()=>D0,defaultMindmapData:()=>$s,extractMindmapTitle:()=>Yc,normalizeMindmapData:()=>Vc,summarizeMindmapProjectionNodes:()=>B3});var $s={data:{text:"\u4E2D\u5FC3\u4E3B\u9898"},children:[]},z0="logicalStructure",R0="default",D0=()=>({lineColor:"#7aa2ff",lineStyle:"curve",rootLineKeepSameInCurve:!0,rootLineStartPositionKeepSameInCurve:!0,generalizationLineColor:"#ef6a5b",backgroundColor:"#f6f8fc",root:{fillColor:"#e25563",color:"#ffffff",fontWeight:"bold",borderColor:"transparent",borderWidth:0,borderRadius:8},second:{fillColor:"#4f7df3",color:"#ffffff",borderColor:"transparent",borderWidth:0,borderRadius:8},node:{fillColor:"transparent",color:"#315aa9",borderColor:"transparent",borderWidth:0},generalization:{fillColor:"#ffffff",color:"#ef6a5b",borderColor:"#ef6a5b",borderWidth:1,borderRadius:8}}),Us=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),Vc=i=>{if(!i||typeof i!="object")return $s;let e=i.root??i,t=r=>{if(!Us(r))return;let n=Us(r.data)?r.data:{};r.data=n;let s=n.text;n.text=typeof s=="string"?s:String(s??"");let a=n.generalization,o=l=>{if(!Us(l))return;let h=l.text;l.text=typeof h=="string"?h:String(h??"")};Array.isArray(a)?a.forEach(o):o(a),Array.isArray(r.children)&&r.children.forEach(t)};return t(e),i},fi=i=>{let e=Vc(i)??$s,t=e&&typeof e=="object"&&"root"in e?e.root:e;return Vc(t)??$s},Yc=i=>{let t=fi(i)?.data?.text;return typeof t=="string"&&t.trim()?t.trim():"\u672A\u547D\u540D\u5BFC\u56FE"},B3=i=>{let t=[{node:fi(i),depth:0}],r=[];for(;t.length>0;){let n=t.shift();if(!n)break;let s=n.node?.data?.uid,a=n.node?.data?.text,o=Array.isArray(n.node?.children)?n.node.children:[];r.push({uid:typeof s=="string"&&s.trim()?s:`depth:${n.depth}:index:${r.length}`,text:typeof a=="string"&&a.trim()?a.trim():"\u672A\u547D\u540D\u8282\u70B9",depth:n.depth,childCount:o.length}),o.forEach(l=>{t.push({node:fi(l),depth:n.depth+1})})}return r},Rw=i=>{let e=fi(i.data),t=B3(e),r=Us(i.meta)?i.meta:null,n=t[0]?.uid??null;return{schema:"mnote.mindmap_projection.v1",projectionId:`mindmap_projection:${i.documentId}:${i.mindmapId}`,projection:"mindmap_subtree",source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:n,title:Yc(e),nodeCount:t.length,nodes:t,data:e,meta:r}},Dw=i=>{let e=fi(i.data),t=Us(i.meta)?i.meta:null,r=[],n=[],s=(l,h,d)=>{let c=l?.data?.uid,f=l?.data?.text,m=typeof c=="string"&&c.trim()?c.trim():`depth:${h}:index:${r.length}`,g=Array.isArray(l?.children)?l.children:[];r.push({id:m,uid:m,text:typeof f=="string"&&f.trim()?f.trim():"\u672A\u547D\u540D\u8282\u70B9",depth:h,childCount:g.length,parentId:d}),d&&n.push({id:`${d}->${m}`,source:d,target:m}),g.forEach(x=>{s(fi(x),h+1,m)})};s(e,0,null);let a=r[0]?.id??null,o=i.rootNodeId&&i.rootNodeId.trim()?i.rootNodeId.trim():a;return{schema:"mnote.mindmap_editor_scene.v1",source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:o,title:Yc(e),nodes:r,edges:n,capabilities:{canEditText:!0,canAddChild:!0,canAddSiblingAfter:!0,canDeleteNode:!0},data:e,meta:t}},Ow=i=>{let e=fi(i.data),t=Us(i.meta)?i.meta:null,r=e?.data?.uid,n=typeof r=="string"&&r.trim()?r.trim():"root";return e.data.uid||(e.data.uid=n),{schema:"mnote.mindmap.simple_mind_map_scene.v1",runtime:"simple-mind-map",documentId:i.documentId,mindmapId:i.mindmapId,rootNodeId:n,root:e,layout:z0,theme:R0,themeConfig:D0(),view:{x:0,y:0,scale:1},config:{},compatPayload:{},kernelRevision:1,source:i.source??"rust-kernel",owner:i.owner??"rust-kernel",meta:t}};var uF=["Drag","KeyboardNavigation","Export","Select","AssociativeLine","Search","OuterFrame"],fF=["Scrollbar","MiniMap","Painter","Formula"],mF=["data_change","view_data_change","node_active","back_forward","scale","translate"],pF=new Set(["BACK","FORWARD","INSERT_NODE","INSERT_CHILD_NODE","REMOVE_NODE","DELETE_NODE","ADD_GENERALIZATION","ADD_OUTER_FRAME","SET_NOTATION"]),oo=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),yb=(i,e)=>{if(typeof i=="string"&&i.trim())return i.trim();if(oo(i)){let t=i.template;if(typeof t=="string"&&t.trim())return t.trim()}return e},vb=i=>oo(i)?i:{},bb=i=>!oo(i)||Object.keys(i).length===0?D0():i,gF=i=>!oo(i)||!oo(i.state)?null:{...i,state:i.state,transform:oo(i.transform)?i.transform:{}},xF=i=>{let e=fi(i.projection.root??$s),t=vb(i.projection.config),r=vb(i.runtimeOptions);return{...t,...r,el:i.el,data:e,fit:typeof r.fit=="boolean"?r.fit:typeof t.fit=="boolean"?t.fit:!0,layout:yb(i.projection.layout,z0),theme:yb(i.projection.theme,R0),themeConfig:bb(i.projection.themeConfig),viewData:gF(i.projection.view),initRootNodePosition:["center","center"]}},yF={Drag:()=>Promise.resolve().then(()=>(f6(),u6)),KeyboardNavigation:()=>Promise.resolve().then(()=>(p6(),m6)),Export:()=>Promise.resolve().then(()=>(N6(),T6)),Select:()=>Promise.resolve().then(()=>(S6(),E6)),AssociativeLine:()=>Promise.resolve().then(()=>(R6(),z6)),Search:()=>Promise.resolve().then(()=>(O6(),D6)),OuterFrame:()=>Promise.resolve().then(()=>(U6(),H6)),Scrollbar:()=>Promise.resolve().then(()=>(j6(),$6)),MiniMap:()=>Promise.resolve().then(()=>(W6(),G6)),Painter:()=>Promise.resolve().then(()=>(Y6(),V6)),Formula:()=>Promise.resolve().then(()=>(Dv(),Rv))},vF=()=>[...uF,...fF],bF=async(i=vF())=>{if(typeof window>"u"||typeof document>"u")throw new Error("simple_mind_map_browser_required");let[{default:e},t]=await Promise.all([Promise.resolve().then(()=>(xb(),gb)),Promise.all(i.map(async s=>[s,(await yF[s]()).default]))]),r=e,n=[];return t.forEach(([s,a])=>{if(!a||typeof r.usePlugin!="function")return;typeof r.hasPlugin=="function"&&r.hasPlugin(a)!==-1||r.usePlugin(a),n.push(s)}),{MindMap:r,registeredPlugins:n}},wF=i=>(e,...t)=>{if(!pF.has(e))return{ok:!1,command:e,error:"unsupported_command"};if(typeof i.execCommand!="function")return{ok:!1,command:e,error:"runtime_unavailable"};try{return{ok:!0,command:e,result:i.execCommand(e,...t)}}catch{return{ok:!1,command:e,error:"command_failed"}}},MF=i=>{let e=[];return mF.forEach(t=>{let r=(...n)=>{let s=t==="data_change"?i.instance.getData?.():t==="view_data_change"?i.instance.getData?.(!0)??i.instance.getData?.():void 0;i.onEvent?.({type:t,args:n,snapshot:s,kernelRevision:i.projection.kernelRevision})};i.instance.on?.(t,r),e.push(()=>i.instance.off?.(t,r))}),()=>e.splice(0).forEach(t=>t())},wb=async i=>{let e=await bF(i.pluginNames),t=bb(i.projection.themeConfig),r=xF({el:i.el,projection:i.projection,runtimeOptions:i.runtimeOptions}),n=new e.MindMap(r);n.setThemeConfig?.(t),i.mode&&n.setMode?.(i.mode);let s=MF({instance:n,projection:i.projection,onEvent:i.onEvent}),a=wF(n);return{instance:n,execCommand:a,getSnapshot:()=>n.getData?.(!0)??n.getData?.(),destroy:()=>{n.renderer?.textEdit?.hideEditTextBox?.(),s(),n.destroy?.()}}};var ho=class extends Error{constructor(e,t=null){super(e),this.name="MindmapCommandBridgeError",this.code="command_failed",this.status=t}},lo=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),Up=i=>{if(!lo(i))return"";let e=[i.error,i.message,i.details].map(t=>typeof t=="string"?t.trim():Array.isArray(t)&&t.length>0?t.join("|"):"").find(Boolean);return e?`:${e}`:""},TF=async i=>{if(typeof i.text!="function"){let t=await i.json().catch(()=>null);return Up(t)}let e=await i.text().catch(()=>"");if(!e.trim())return"";try{return Up(JSON.parse(e))||`:${e.trim()}`}catch{return`:${e.trim()}`}},$p=i=>lo(i)?i.schema==="mnote.mindmap.simple_mind_map_scene.v1"&&i.runtime==="simple-mind-map"&&"root"in i&&typeof i.kernelRevision=="number":!1,Mb=(i,e)=>{let t=encodeURIComponent(i),r=encodeURIComponent(e);return`/api/mindmap/${t}/${r}?view=simple_mind_map_scene&queryName=mindmap.simple_mind_map_scene.get`},jp=(i,e)=>{let t=encodeURIComponent(i),r=encodeURIComponent(e);return`/api/mindmap/${t}/${r}`},Gp=async i=>{let e=i.fetcher??fetch,t=i.endpoint??Mb(i.documentId,i.mindmapId),r=await e(t,{headers:{Accept:"application/json"}});if(!r.ok)throw new Error(`projection_load_failed:${r.status}`);let n=await r.json(),s=lo(n)&&"result"in n?n.result:n;if(!$p(s))throw new Error("projection_load_failed:invalid_adapter_projection");return s},NF=i=>{if(!lo(i))return null;let e=[i.kernelRevision,i.projectionRevision,lo(i.result)?i.result.kernelRevision:null,lo(i.result)?i.result.projectionRevision:null];for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t;return null},Tb=async i=>{if(i.commands.length===0)throw new ho("command_failed:empty_commands");let e=i.fetcher??fetch,t=i.endpoint??jp(i.documentId,i.mindmapId),r=JSON.stringify({commandName:"mindmap.command.apply",documentId:i.documentId,mindmapId:i.mindmapId,commands:i.commands,projectionRevision:i.projectionRevision??null}),n=await e(t,{method:"POST",keepalive:r.length<=6e4,headers:{Accept:"application/json","Content-Type":"application/json"},body:r}),s=await n.json().catch(()=>null);if(!n.ok){let a=Up(s);throw new ho(`command_failed:${n.status}${a}`,n.status)}return{ok:!0,kernelRevision:NF(s),raw:s}},EF=async i=>(await Tb(i),Gp({documentId:i.documentId,mindmapId:i.mindmapId,endpoint:i.projectionEndpoint,fetcher:i.fetcher})),SF=async i=>{let e=i.fetcher??fetch,t=i.endpoint??jp(i.documentId,i.mindmapId),r=await e(t,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({data:i.data,createOnly:!1})});if(!r.ok){let n=await TF(r);throw new ho(`command_failed:${r.status}${n}`,r.status)}return await r.json().catch(()=>null),Gp({documentId:i.documentId,mindmapId:i.mindmapId,endpoint:i.projectionEndpoint,fetcher:e})},AF=async i=>{if(!$p(i.projection))throw new Error("adapter_init_failed:invalid_projection");return wb(i)};var Kp={};tt(Kp,{createCompatPayloadPatch:()=>Lc,createLayoutCommand:()=>Xp,createThemeCommand:()=>Yp,createToolbarKernelCommand:()=>Vp,createViewPatchCommand:()=>kF,diffMindmapRuntimeDataToKernelCommands:()=>zF});var Nb=i=>({text:i?.text?.trim()||"\u65B0\u8282\u70B9",...i?.uid?{uid:i.uid}:{},...i?.hyperlink?{hyperlink:i.hyperlink}:{},...i?.note?{note:i.note}:{},...i?.refs?{refs:i.refs}:{}}),Vp=i=>{let e=i.activeNodeId?.trim();switch(i.runtimeCommand){case"INSERT_CHILD_NODE":return e?{type:"insertChild",mindmapId:i.mindmapId,parentNodeId:e,node:Nb(i.newNode)}:null;case"INSERT_NODE":return e?{type:"insertSiblingAfter",mindmapId:i.mindmapId,targetNodeId:e,node:Nb(i.newNode)}:null;case"REMOVE_NODE":case"DELETE_NODE":return e?{type:"deleteNode",mindmapId:i.mindmapId,nodeId:e}:null;case"ADD_GENERALIZATION":return{type:"compatPayloadPatch",mindmapId:i.mindmapId,path:"root.data.generalization",value:{text:"\u6982\u8981"},source:"toolbar"};case"ADD_OUTER_FRAME":return{type:"compatPayloadPatch",mindmapId:i.mindmapId,path:"outerFrame",value:{enabled:!0,activeNodeId:e},source:"toolbar"};default:return null}},kF=(i,e)=>({type:"patchView",mindmapId:i,patch:e}),Yp=(i,e,t)=>({type:"setTheme",mindmapId:i,theme:e,themeConfig:t}),Xp=(i,e)=>({type:"setLayout",mindmapId:i,layout:e}),Lc=i=>({type:"compatPayloadPatch",mindmapId:i.mindmapId,path:i.path,value:i.value,source:i.source,...i.actionId?{actionId:i.actionId}:{},...typeof i.runtimeRevision=="number"?{runtimeRevision:i.runtimeRevision}:{},...typeof i.kernelRevision=="number"?{kernelRevision:i.kernelRevision}:{}}),CF=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),_F=(i,e)=>{let t=i.data?.uid;return typeof t=="string"&&t.trim()?t.trim():e},LF=i=>{let e=i.data?.text;return typeof e=="string"?e:String(e??"")},Eb=i=>{let e=fi(i),t=new Map,r=(n,s,a,o)=>{let l=_F(n,o),h=CF(n.data)?n.data:{};t.set(l,{uid:l,parentUid:s,order:a,text:LF(n),data:h,node:n}),(Array.isArray(n.children)?n.children:[]).forEach((c,f)=>{r(fi(c),l,f,`${o}.${f}`)})};return r(e,null,0,"root"),t},Sb=i=>JSON.stringify(i??null),Ab=i=>({uid:i.uid,text:i.text||"\u65B0\u8282\u70B9",...typeof i.data.hyperlink=="string"?{hyperlink:i.data.hyperlink}:{},...typeof i.data.note=="string"?{note:i.data.note}:{},...Array.isArray(i.data.refs)?{refs:i.data.refs}:{}}),IF=(i,e,t,r)=>{let n=new Set(["uid","text","refs"]);new Set([...Object.keys(e.data),...Object.keys(t.data)]).forEach(a=>{n.has(a)||Sb(e.data[a])!==Sb(t.data[a])&&r.push(Lc({mindmapId:i,path:`nodes.${t.uid}.data.${a}`,value:t.data[a],source:"adapter-diff"}))})},zF=i=>{let e=Eb(i.previous),t=Eb(i.next),r=[],n=[];return t.forEach((s,a)=>{let o=e.get(a);if(!o){let l=Array.from(t.values()).find(h=>h.parentUid===s.parentUid&&h.order===s.order-1&&e.has(h.uid));l?r.push({type:"insertSiblingAfter",mindmapId:i.mindmapId,targetNodeId:l.uid,node:Ab(s)}):s.parentUid&&r.push({type:"insertChild",mindmapId:i.mindmapId,parentNodeId:s.parentUid,node:Ab(s)});return}o.text!==s.text&&r.push({type:"updateText",mindmapId:i.mindmapId,nodeId:a,text:s.text}),(o.parentUid!==s.parentUid||o.order!==s.order)&&r.push({type:"moveNode",mindmapId:i.mindmapId,nodeId:a,newParentNodeId:s.parentUid??"",order:s.order}),IF(i.mindmapId,o,s,n)}),e.forEach((s,a)=>{!t.has(a)&&s.parentUid&&r.push({type:"deleteNode",mindmapId:i.mindmapId,nodeId:a})}),{commands:r,compatPatches:n}};var Qp={};tt(Qp,{getMindmapActionMapping:()=>Ic,listMindmapActionMappings:()=>Zp,mapMindmapActionToCommand:()=>DF});var zs=i=>e=>e?`nodes.${e}.data.${i}`:null,kb=[{actionId:"undo",target:"runtimeCommand",runtimeCommand:"BACK",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"redo",target:"runtimeCommand",runtimeCommand:"FORWARD",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"editNode",target:"localView",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"insertSiblingAfter",target:"runtimeCommand",runtimeCommand:"INSERT_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"insertChild",target:"runtimeCommand",runtimeCommand:"INSERT_CHILD_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"deleteNode",target:"runtimeCommand",runtimeCommand:"REMOVE_NODE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"summary",target:"runtimeCommand",runtimeCommand:"ADD_GENERALIZATION",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"associativeLine",target:"compatPatch",runtimeCommand:"ADD_ASSOCIATIVE_LINE",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"setTheme",target:"kernelCommand",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"setLayout",target:"kernelCommand",requiresActiveNode:!1,readonlyAllowed:!1},{actionId:"tag",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("tag")},{actionId:"hyperlink",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("hyperlink")},{actionId:"note",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("note")},{actionId:"image",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("image")},{actionId:"icon",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("icon")},{actionId:"formula",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("formula")},{actionId:"painter",target:"compatPatch",requiresActiveNode:!0,readonlyAllowed:!1,compatPath:zs("style")},{actionId:"import",target:"compatPatch",requiresActiveNode:!1,readonlyAllowed:!1,compatPath:()=>"import"},{actionId:"export",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"centerRoot",target:"localView",runtimeMethod:"centerRoot",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"zoomIn",target:"localView",runtimeMethod:"zoomIn",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"zoomOut",target:"localView",runtimeMethod:"zoomOut",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fitView",target:"localView",runtimeMethod:"fitView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fullscreenCanvas",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"fullscreenPage",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"exitFullscreen",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"search",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"showMenu",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0},{actionId:"expandCollapse",target:"localView",requiresActiveNode:!0,readonlyAllowed:!1},{actionId:"copyNodeText",target:"localView",requiresActiveNode:!0,readonlyAllowed:!0},{actionId:"readonly",target:"localView",requiresActiveNode:!1,readonlyAllowed:!0}],Zp=()=>kb,Ic=i=>kb.find(e=>e.actionId===i)??null,RF=i=>{let e=i?.trim();return e||null},DF=i=>{let e=Ic(i.actionId);if(!e)return null;let t=RF(i.activeNodeId);if(e.requiresActiveNode&&!t)return null;if(i.actionId==="setTheme")return{command:Yp(i.mindmapId,i.value,i.themeConfig)};if(i.actionId==="setLayout")return{command:Xp(i.mindmapId,i.value)};if(i.actionId==="editNode")return{command:{type:"updateText",mindmapId:i.mindmapId,nodeId:t??"root",text:typeof i.value=="string"?i.value:""}};if(e.runtimeCommand&&["INSERT_CHILD_NODE","INSERT_NODE","DELETE_NODE","REMOVE_NODE"].includes(e.runtimeCommand)){let r=Vp({mindmapId:i.mindmapId,runtimeCommand:e.runtimeCommand,activeNodeId:t,newNode:i.node});return r?{runtimeCommand:e.runtimeCommand,command:r}:{runtimeCommand:e.runtimeCommand}}if(e.compatPath){let r=e.compatPath(t);return r?{command:Lc({mindmapId:i.mindmapId,path:r,value:i.value??!0,source:i.source??"toolbar",actionId:i.actionId,runtimeRevision:i.runtimeRevision,kernelRevision:i.kernelRevision})}:null}return e.runtimeCommand?{runtimeCommand:e.runtimeCommand}:{}};var e3={};tt(e3,{createDefaultMindmapShellInteractionState:()=>_b,deriveMindmapUiState:()=>GF,reduceMindmapChromeVisibility:()=>jF});var Jp={};tt(Jp,{MINDMAP_DEBUG_CHROME_QUERY_PARAM:()=>Cb,MINDMAP_TOOLBAR_MORE_ACTION_ID:()=>OF,isMindmapDebugChromeEnabled:()=>FF,mindmapDefaultUiSchema:()=>co,mindmapToolbarFileActionOrder:()=>PF,mindmapToolbarPrimaryActionOrder:()=>BF});var Cb="mnoteMindmapDebugChrome",OF="more",BF=["undo","redo","editNode","insertSiblingAfter","deleteNode","insertChild","tag","hyperlink","note","image","icon","summary","associativeLine","formula"],PF=["import","export"],Se=(i,e,t,r,n,s,a)=>({id:i,iconKey:e,shortLabel:t,longLabel:r,priority:n,overflowGroup:s,cluster:a}),co={toolbarGroups:[{id:"history",label:"\u5386\u53F2",actions:["undo","redo"],collapsePriority:4},{id:"node",label:"\u8282\u70B9",actions:["editNode","insertSiblingAfter","deleteNode","insertChild"],collapsePriority:1},{id:"insert",label:"\u63D2\u5165",actions:["tag","hyperlink","note","image","icon","summary","associativeLine","formula"],collapsePriority:2},{id:"file",label:"\u6587\u4EF6",actions:["import","export"],collapsePriority:5},{id:"view",label:"\u89C6\u56FE",actions:["painter","centerRoot","zoomOut","zoomIn","search","readonly"],collapsePriority:3}],toolbarActionMeta:{undo:Se("undo","undo","\u64A4\u9500","\u64A4\u9500",10,"history","main"),redo:Se("redo","redo","\u91CD\u505A","\u91CD\u505A",20,"history","main"),editNode:Se("editNode","type","\u7F16\u8F91","\u7F16\u8F91\u8282\u70B9",30,"node","main"),insertSiblingAfter:Se("insertSiblingAfter","sibling","\u540C\u7EA7","\u63D2\u5165\u540C\u7EA7\u8282\u70B9",40,"node","main"),deleteNode:Se("deleteNode","trash","\u5220\u9664","\u5220\u9664\u8282\u70B9",50,"node","main"),insertChild:Se("insertChild","child","\u5B50\u7EA7","\u63D2\u5165\u5B50\u8282\u70B9",60,"node","main"),tag:Se("tag","tag","\u6807\u7B7E","\u6807\u7B7E",70,"insert","main"),hyperlink:Se("hyperlink","link","\u94FE\u63A5","\u8D85\u94FE\u63A5",80,"insert","main"),note:Se("note","note","\u5907\u6CE8","\u5907\u6CE8",90,"insert","main"),image:Se("image","image","\u56FE\u7247","\u56FE\u7247",100,"insert","main"),icon:Se("icon","smile","\u56FE\u6807","\u56FE\u6807",110,"insert","main"),summary:Se("summary","summary","\u6982\u8981","\u6982\u8981",120,"insert","main"),associativeLine:Se("associativeLine","route","\u5173\u8054","\u5173\u8054\u7EBF",130,"insert","main"),formula:Se("formula","formula","\u516C\u5F0F","\u516C\u5F0F",140,"insert","main"),painter:Se("painter","paintbrush","\u683C\u5F0F","\u683C\u5F0F\u5237",210,"view","view"),import:Se("import","import","\u5BFC\u5165","\u5BFC\u5165",310,"file","file"),export:Se("export","export","\u5BFC\u51FA","\u5BFC\u51FA",320,"file","file"),setTheme:Se("setTheme","palette","\u4E3B\u9898","\u4E3B\u9898",410,"view","view"),setLayout:Se("setLayout","layout","\u7ED3\u6784","\u7ED3\u6784",420,"view","view"),zoomIn:Se("zoomIn","zoom-in","\u653E\u5927","\u653E\u5927",510,"view","view"),zoomOut:Se("zoomOut","zoom-out","\u7F29\u5C0F","\u7F29\u5C0F",500,"view","view"),fitView:Se("fitView","fit","\u9002\u5E94","\u9002\u5E94\u753B\u5E03",520,"view","view"),centerRoot:Se("centerRoot","target","\u56DE\u6839","\u56DE\u5230\u6839\u8282\u70B9",490,"view","view"),fullscreenCanvas:Se("fullscreenCanvas","fullscreen","\u5168\u5C4F","\u5168\u5C4F\u67E5\u770B",550,"view","view"),fullscreenPage:Se("fullscreenPage","fullscreen-page","\u5168\u9875","\u5168\u5C4F\u7F16\u8F91",560,"view","view"),exitFullscreen:Se("exitFullscreen","exit-fullscreen","\u9000\u51FA","\u9000\u51FA\u5168\u5C4F",570,"view","view"),search:Se("search","search","\u641C\u7D22","\u641C\u7D22",530,"view","view"),showMenu:Se("showMenu","menu","\u83DC\u5355","\u663E\u793A\u83DC\u5355",580,"view","view"),expandCollapse:Se("expandCollapse","expand","\u5C55\u5F00","\u5C55\u5F00/\u6536\u8D77",610,"view","view"),copyNodeText:Se("copyNodeText","copy","\u590D\u5236","\u590D\u5236\u6587\u672C",620,"view","view"),readonly:Se("readonly","lock","\u53EA\u8BFB","\u53EA\u8BFB",540,"view","view")},sidebarPanels:[{id:"nodeStyle",kind:"nodeStyle",label:"\u8282\u70B9\u6837\u5F0F",icon:"palette",runtimeCapability:"node-style",phase:1,options:[{id:"node-fill-blue",label:"\u6D77\u84DD",actionId:"painter",value:"#dbeafe",controlType:"swatch",preview:"#dbeafe",compatPath:"nodes.$active.data.fillColor"},{id:"node-fill-green",label:"\u8584\u8377",actionId:"painter",value:"#dcfce7",controlType:"swatch",preview:"#dcfce7",compatPath:"nodes.$active.data.fillColor"},{id:"node-fill-amber",label:"\u6696\u9EC4",actionId:"painter",value:"#fef3c7",controlType:"swatch",preview:"#fef3c7",compatPath:"nodes.$active.data.fillColor"},{id:"node-text-dark",label:"\u6DF1\u8272\u6587\u5B57",actionId:"painter",value:"#0f172a",controlType:"swatch",preview:"#0f172a",compatPath:"nodes.$active.data.color"},{id:"node-text-blue",label:"\u84DD\u8272\u6587\u5B57",actionId:"painter",value:"#1d4ed8",controlType:"swatch",preview:"#1d4ed8",compatPath:"nodes.$active.data.color"},{id:"node-font-14",label:"14 px",actionId:"painter",value:14,controlType:"segmented",compatPath:"nodes.$active.data.fontSize"},{id:"node-font-18",label:"18 px",actionId:"painter",value:18,controlType:"segmented",compatPath:"nodes.$active.data.fontSize"},{id:"node-font-bold",label:"\u52A0\u7C97",actionId:"painter",value:!0,controlType:"toggle",compatPath:"nodes.$active.data.fontWeight"},{id:"node-font-italic",label:"\u659C\u4F53",actionId:"painter",value:!0,controlType:"toggle",compatPath:"nodes.$active.data.fontStyle"},{id:"node-shape-round",label:"\u5706\u89D2\u77E9\u5F62",actionId:"painter",value:"roundedRectangle",controlType:"button",compatPath:"nodes.$active.data.shape"},{id:"node-shape-rect",label:"\u77E9\u5F62",actionId:"painter",value:"rectangle",controlType:"button",compatPath:"nodes.$active.data.shape"},{id:"node-border-blue",label:"\u84DD\u8272\u8FB9\u6846",actionId:"painter",value:"#60a5fa",controlType:"swatch",preview:"#60a5fa",compatPath:"nodes.$active.data.borderColor"},{id:"node-line-teal",label:"\u9752\u8272\u5206\u652F\u7EBF",actionId:"painter",value:"#14b8a6",controlType:"swatch",preview:"#14b8a6",compatPath:"nodes.$active.data.lineColor"},{id:"node-line-width-2",label:"\u8FB9\u7EBF 2",actionId:"painter",value:2,controlType:"segmented",compatPath:"nodes.$active.data.lineWidth"}]},{id:"baseStyle",kind:"baseStyle",label:"\u5BFC\u56FE\u6837\u5F0F",icon:"sliders",runtimeCapability:"base-style",phase:1,options:[{id:"base-curve-line",label:"\u66F2\u7EBF",actionId:"painter",value:"curve",controlType:"segmented",compatPath:"style.map.lineStyle"},{id:"base-direct-line",label:"\u76F4\u7EBF",actionId:"painter",value:"straight",controlType:"segmented",compatPath:"style.map.lineStyle"},{id:"base-rainbow-lines",label:"\u5F69\u8679\u7EBF\u6761",actionId:"painter",value:{enabled:!0},controlType:"toggle",compatPath:"style.map.rainbowLines"},{id:"base-line-width-2",label:"\u7EBF\u5BBD 2",actionId:"painter",value:2,controlType:"segmented",compatPath:"style.map.lineWidth"},{id:"base-line-width-4",label:"\u7EBF\u5BBD 4",actionId:"painter",value:4,controlType:"segmented",compatPath:"style.map.lineWidth"},{id:"base-background-light",label:"\u6D45\u8272\u80CC\u666F",actionId:"painter",value:"#f8fafc",controlType:"swatch",preview:"#f8fafc",compatPath:"style.map.backgroundColor"},{id:"base-node-spacing-36",label:"\u8282\u70B9\u95F4\u8DDD 36",actionId:"painter",value:36,controlType:"numberInput",compatPath:"style.map.nodeSpacing"},{id:"base-summary-bracket",label:"\u62EC\u53F7\u6982\u8981",actionId:"painter",value:"bracket",controlType:"select",compatPath:"style.map.summaryStyle"}]},{id:"theme",kind:"theme",label:"\u4E3B\u9898",icon:"swatch",runtimeCapability:"theme",phase:1,options:[{id:"theme-classic",label:"Classic",actionId:"setTheme",value:"classic",controlType:"swatch",preview:"#60a5fa",description:"\u9ED8\u8BA4\u4E3B\u9898"},{id:"theme-classic4",label:"KMind",actionId:"setTheme",value:"classic4",controlType:"swatch",preview:"#22c55e",description:"KMind-like"},{id:"theme-simple",label:"Simple",actionId:"setTheme",value:"simple",controlType:"swatch",preview:"#f59e0b",description:"\u8F7B\u91CF\u4E3B\u9898"},{id:"theme-dark",label:"Dark",actionId:"setTheme",value:"dark",controlType:"swatch",preview:"#334155",description:"\u6DF1\u8272\u4E3B\u9898"}]},{id:"structure",kind:"structure",label:"\u7ED3\u6784",icon:"layout",runtimeCapability:"layout",phase:1,options:[{id:"layout-logical",label:"\u903B\u8F91\u7ED3\u6784\u56FE",actionId:"setLayout",value:"logicalStructure",controlType:"layoutCard",preview:"logicalStructure"},{id:"layout-mind-map",label:"\u601D\u7EF4\u5BFC\u56FE",actionId:"setLayout",value:"mindMap",controlType:"layoutCard",preview:"mindMap"},{id:"layout-organization",label:"\u7EC4\u7EC7\u7ED3\u6784\u56FE",actionId:"setLayout",value:"organizationStructure",controlType:"layoutCard",preview:"organizationStructure"},{id:"layout-catalog",label:"\u76EE\u5F55\u7EC4\u7EC7\u56FE",actionId:"setLayout",value:"catalogOrganization",controlType:"layoutCard",preview:"catalogOrganization"},{id:"layout-timeline",label:"\u65F6\u95F4\u8F74",actionId:"setLayout",value:"timeline",controlType:"layoutCard",preview:"timeline"},{id:"layout-fishbone",label:"\u9C7C\u9AA8\u56FE",actionId:"setLayout",value:"fishbone",controlType:"layoutCard",preview:"fishbone"}]},{id:"outline",kind:"outline",label:"\u5927\u7EB2",icon:"list-tree",runtimeCapability:"outline",phase:1,options:[]},{id:"shortcutKey",kind:"shortcutKey",label:"\u5FEB\u6377\u952E",icon:"sparkles",runtimeCapability:"shortcut-key",phase:1,options:[{id:"shortcut-insert-child",label:"Tab",description:"\u63D2\u5165\u5B50\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0},{id:"shortcut-insert-sibling",label:"Enter",description:"\u63D2\u5165\u540C\u7EA7\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0},{id:"shortcut-delete",label:"Delete",description:"\u5220\u9664\u8282\u70B9",actionId:null,value:null,controlType:"treeItem",readonly:!0}]},{id:"settings",kind:"settings",label:"\u8BBE\u7F6E",icon:"hexagon",runtimeCapability:"settings",phase:1,options:[{id:"settings-readonly-hint",label:"\u53EA\u8BFB\u6A21\u5F0F",description:"\u5BFC\u822A\u680F\u5207\u6362",actionId:null,value:null,controlType:"toggle",readonly:!0},{id:"settings-mouse",label:"\u9F20\u6807\u884C\u4E3A",description:"\u5DE6\u952E\u9009\u4E2D\uFF0C\u53F3\u952E\u62D6\u62FD",actionId:null,value:"leftSelectRightDrag",controlType:"select",readonly:!0}]}],navigatorItems:[{id:"stats",label:"\u7EDF\u8BA1",actionId:null,readOnly:!0,displayMode:"text"},{id:"centerRoot",label:"\u56DE\u6839\u8282\u70B9",actionId:"centerRoot",readOnly:!0,displayMode:"button"},{id:"search",label:"\u641C\u7D22",actionId:"search",readOnly:!0,displayMode:"button"},{id:"zoomOut",label:"\u7F29\u5C0F",actionId:"zoomOut",readOnly:!0,displayMode:"button"},{id:"zoom",label:"\u7F29\u653E",actionId:null,readOnly:!0,displayMode:"input"},{id:"zoomIn",label:"\u653E\u5927",actionId:"zoomIn",readOnly:!0,displayMode:"button"},{id:"fullscreen",label:"\u5168\u5C4F",actionId:"fullscreenCanvas",readOnly:!0,displayMode:"button"},{id:"readonly",label:"\u53EA\u8BFB",actionId:"readonly",readOnly:!0,displayMode:"button"}],contextMenuItems:[{id:"insertChild",label:"\u63D2\u5165\u5B50\u8282\u70B9",actionId:"insertChild",requiresNode:!0,phase:1},{id:"insertSiblingAfter",label:"\u63D2\u5165\u540C\u7EA7\u8282\u70B9",actionId:"insertSiblingAfter",requiresNode:!0,phase:1},{id:"deleteNode",label:"\u5220\u9664\u8282\u70B9",actionId:"deleteNode",requiresNode:!0,phase:1},{id:"summary",label:"\u6982\u8981",actionId:"summary",requiresNode:!0,phase:1},{id:"associativeLine",label:"\u5173\u8054\u7EBF",actionId:"associativeLine",requiresNode:!0,phase:1},{id:"expandCollapse",label:"\u5C55\u5F00/\u6536\u8D77",actionId:"expandCollapse",requiresNode:!0,phase:1},{id:"copyNodeText",label:"\u590D\u5236\u6587\u672C",actionId:"copyNodeText",requiresNode:!0,phase:1},{id:"centerRoot",label:"\u56DE\u6839\u8282\u70B9",actionId:"centerRoot",requiresNode:!1,phase:1},{id:"fitView",label:"\u9002\u5E94\u753B\u5E03",actionId:"fitView",requiresNode:!1,phase:1},{id:"search",label:"\u641C\u7D22",actionId:"search",requiresNode:!1,phase:1},{id:"readonly",label:"\u53EA\u8BFB\u5207\u6362",actionId:"readonly",requiresNode:!1,phase:1},{id:"showMenu",label:"\u663E\u793A\u83DC\u5355",actionId:"showMenu",requiresNode:!1,phase:1}]},FF=i=>{try{let e=new URL(i).searchParams.get(Cb);return e==="1"||e==="true"}catch{return!1}};var qF=()=>{let i=[...co.toolbarGroups.flatMap(e=>e.actions),...co.navigatorItems.flatMap(e=>e.actionId?[e.actionId]:[]),...co.contextMenuItems.map(e=>e.actionId),...Zp().map(e=>e.actionId)];return[...new Set(i)]},HF=i=>{let e=i?.trim();return e||null},UF=i=>typeof i!="number"||!Number.isFinite(i)?100:Math.max(10,Math.min(500,Math.round(i))),$F=new Set(["tag","hyperlink","note","image","icon","associativeLine","formula","import","export"]),_b=(i={})=>({chromeVisibility:i.chromeVisibility??"visible",toolbarOverflow:{availableWidth:i.toolbarOverflow?.availableWidth??null,visibleActionIds:i.toolbarOverflow?.visibleActionIds??[],overflowActionIds:i.toolbarOverflow?.overflowActionIds??[],moreOpen:i.toolbarOverflow?.moreOpen??!1},fullscreen:{mode:i.fullscreen?.mode??"none",isFullscreen:i.fullscreen?.isFullscreen??!1,target:i.fullscreen?.target??"mindmap-root",apiAvailable:i.fullscreen?.apiAvailable??!0},sidebar:{triggerVisible:i.sidebar?.triggerVisible??!0,panelOpen:i.sidebar?.panelOpen??!0,activePanelId:i.sidebar?.activePanelId??co.sidebarPanels[0]?.id??null,drawerWidth:i.sidebar?.drawerWidth??300,collapsedByToggle:i.sidebar?.collapsedByToggle??!1},navigator:{searchOpen:i.navigator?.searchOpen??!1,minimapOpen:i.navigator?.minimapOpen??!1,readonly:i.navigator?.readonly??!1,zoomPercent:UF(i.navigator?.zoomPercent),mouseBehavior:i.navigator?.mouseBehavior??"leftSelectRightDrag"}}),jF=(i,e)=>e==="pointerLeave"?"hiddenByPointerLeave":e==="pointerEnter"?i:e==="restoreClick"?"visible":e==="hideToggle"?"hiddenByToggle":e==="showToggle"?"visible":e==="enterFullscreen"?i==="visible"?"visible":"hiddenByFullscreen":e==="exitFullscreen"&&i==="hiddenByFullscreen"?"visible":i,GF=i=>{let e=HF(i.activeNodeId),t=i.runtimeCapabilities?new Set(i.runtimeCapabilities):null,r={},n=_b({...i.shell,navigator:{...i.shell?.navigator,readonly:i.readonly}});return qF().forEach(s=>{let a=Ic(s);if(!a){r[s]=!0;return}if(a.requiresActiveNode&&!e){r[s]=!0;return}if(i.readonly&&!a.readonlyAllowed){r[s]=!0;return}if(t&&!t.has(a.target)){r[s]=!0;return}if($F.has(s)){r[s]=!0;return}r[s]=!1}),{activeNodeId:e,readonly:i.readonly,disabledActions:r,shell:n}};var t3={};tt(t3,{resolveMindmapShortcutAction:()=>WF,shouldInterceptMindmapShortcut:()=>VF});var WF=i=>i.ctrlKey||i.metaKey||i.altKey||i.shiftKey?null:i.key==="Enter"?"insertSiblingAfter":i.key==="Tab"||i.key==="Insert"?"insertChild":i.key==="Delete"||i.key==="Backspace"?"deleteNode":i.key==="F2"?"editNode":null,VF=i=>i.debugChromeEnabled||!i.bridgeReady||i.readonly||i.isComposing||i.isEditableTarget?!1:i.targetInsideRoot?!0:i.keyboardShortcutArmed;function g0(){return{status:"idle"}}function Lb(i,e){return{status:"armed",armedAt:e,reason:i}}function Ib(){return g0()}function zb(i,e,t=1500){return i.status!=="armed"?{state:i,suppressed:!1,expired:!1}:e-i.armedAt>t?{state:g0(),suppressed:!1,expired:!0}:{state:g0(),suppressed:!0,expired:!1}}function Rb(i){return{endpoint:`/api/mindmap/${encodeURIComponent(i.documentId)}/${encodeURIComponent(i.mindmapId)}`,init:{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:i.data,createOnly:!0})}}}function Gn(i){let e=i;return e.default&&typeof e.default=="object"?e.default:i}var{applyMindmapCommandsLocally:YF,isLocallyApplicableMindmapCommandSet:XF}=Gn(Wc),{createLeptosMindmapAdapter:KF,executeMindmapCommandApply:i3,executeMindmapCommandApplyAndRefreshProjection:ZF,requestMindmapAdapterProjection:QF}=Gn(Wp),{createViewPatchCommand:JF,createCompatPayloadPatch:eq,diffMindmapRuntimeDataToKernelCommands:tq}=Gn(Kp),{getMindmapActionMapping:Db,mapMindmapActionToCommand:iq}=Gn(Qp),{canonicalizeMindmapData:wi}=Gn(Xc),{deriveMindmapUiState:r3,reduceMindmapChromeVisibility:zc}=Gn(e3),{resolveMindmapShortcutAction:rq,shouldInterceptMindmapShortcut:nq}=Gn(t3),{isMindmapDebugChromeEnabled:sq,mindmapDefaultUiSchema:Dc,mindmapToolbarFileActionOrder:aq,mindmapToolbarPrimaryActionOrder:a3}=Gn(Jp),uo=900,o3=240,Ob=1280,oq=300;function lq(){return{activePanelId:Dc.sidebarPanels[0]?.id??"nodeStyle",panelOpen:!1,triggerVisible:!0,collapsedByToggle:!1,drawerWidth:oq}}function hq(i){return typeof i=="string"&&i.length>0?{"data-block-id":i,id:i}:{}}function fo(i,e){let t=typeof i=="number"?i:typeof i=="string"?Number(i.trim().replace(/px$/i,"")):NaN;if(!Number.isFinite(t))return null;let r=Math.round(t);return r>=(e==="width"?uo:o3)?r:null}function dq(i){if(i.mnoteBlockType!=="mindmap")return{};let e={"data-mnote-block-type":"mindmap"};typeof i.mindmapId=="string"&&(e["data-mnote-mindmap-id"]=i.mindmapId),typeof i.rootNodeId=="string"&&(e["data-mnote-root-node-id"]=i.rootNodeId),typeof i.projectionVersion=="number"&&(e["data-mnote-projection-version"]=String(i.projectionVersion));let t=fo(i.mindmapWidth,"width"),r=fo(i.mindmapHeight,"height");return t!==null&&(e["data-mnote-mindmap-width"]=String(t)),r!==null&&(e["data-mnote-mindmap-height"]=String(r)),e}function Rs(i){return String(i??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function n3(i){if(typeof i!="string")return null;let e=i.trim();return e.length>0?e:null}function cq(i){let e=n3(i?.closest("[data-document-id]")?.getAttribute("data-document-id"));if(e)return e;if(i&&"isConnected"in i&&i.isConnected===!1)return null;let t=window.location.pathname.match(/\/documents\/([^/?#]+)/);if(t?.[1])return decodeURIComponent(t[1]);let r=window.location.pathname.match(/\/mindmap\/([^/?#]+)\/([^/?#]+)/);if(r?.[1])return decodeURIComponent(r[1]);let n=n3(document.body?.getAttribute("data-document-id"));if(n)return n;let s=n3(document.querySelector(".document-shell[data-document-id], [data-pane-document-id], [data-document-id]")?.getAttribute("data-document-id")??document.querySelector("[data-pane-document-id]")?.getAttribute("data-pane-document-id"));return s||null}function Bb(i,e){let r=wi(i.root).data?.uid;return typeof r=="string"&&r.trim().length>0?r.trim():e}function s3(i){let t=wi(i.root).data?.text;return typeof t=="string"&&t.trim().length>0?t.trim():"\u672A\u547D\u540D\u8282\u70B9"}function Ds(i){if(typeof i=="string"&&i.trim().length>0)return i.trim();if(!i||typeof i!="object")return null;let e=i;if(typeof e.uid=="string"&&e.uid.trim().length>0)return e.uid.trim();let t=e.data&&typeof e.data=="object"&&!Array.isArray(e.data)?e.data:{};if(typeof t.uid=="string"&&t.uid.trim().length>0)return t.uid.trim();let r=e.getData;if(typeof r=="function")try{let n=r.call(e,"uid");if(typeof n=="string"&&n.trim().length>0)return n.trim()}catch{return null}return null}function Rc(i,e){let t=window,r=t.__MNOTE_LEPTOS_MINDMAP_BRIDGES__??{};t.__MNOTE_LEPTOS_MINDMAP_BRIDGES__=r,e?r[i]=e:delete r[i]}function zt(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function Os(i){return JSON.parse(JSON.stringify(i))}function uq(i){if(!(i instanceof HTMLElement))return!1;let e=i.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"?!0:i.isContentEditable?!i.matches(".ProseMirror"):!1}function fq(i){if(!zt(i))return null;let e=i.view;return zt(e)&&zt(e.state)?e:null}function mq(i){if(!(i!=="insertChild"&&i!=="insertSiblingAfter"))return{uid:`node_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`,text:"\u65B0\u8282\u70B9"}}function pq(i,e){let t=e?.trim();if(!t)return!1;let r=wi(i),n=!1,s=a=>{if(n)return;let o=wi(a);if(o.data?.uid===t){n=!0;return}(Array.isArray(o.children)?o.children:[]).forEach(s)};return s(r),n}function Pb(i){let e=wi(i),t=Array.isArray(e.children)?[...e.children]:[];for(;t.length>0;){let r=wi(t.shift()),n=r.data?.uid;if(typeof n=="string"&&n.trim().length>0)return n.trim();Array.isArray(r.children)&&t.push(...r.children)}return null}function gq(i,e){let t=e?.trim();if(!t)return null;let r=null,n=s=>{if(r)return;let a=wi(s);if(a.data?.uid===t){r=a;return}(Array.isArray(a.children)?a.children:[]).forEach(n)};return n(i),r}function xq(i,e){let t=gq(i,e),r=t&&zt(t.data)?t.data.text:null;return typeof r=="string"?r:""}function yq(i,e=10){let t=wi(i),r=[],n=(s,a)=>{if(r.length>=e)return;let o=wi(s),l=typeof o.data?.text=="string"&&o.data.text.trim().length>0?o.data.text.trim():"\u672A\u547D\u540D\u8282\u70B9";r.push(`${" ".repeat(Math.max(a-1,0))}${l}`),(Array.isArray(o.children)?o.children:[]).forEach(d=>n(d,a+1))};return n(t,1),r}function Fb(i,e){let t=i?.trim();return t?t.includes("$active")?e?t.replaceAll("$active",e):null:t:null}var qb={undo:"\u64A4\u9500",redo:"\u91CD\u505A",editNode:"\u7F16\u8F91\u8282\u70B9",insertSiblingAfter:"\u540C\u7EA7\u8282\u70B9",insertChild:"\u5B50\u8282\u70B9",deleteNode:"\u5220\u9664",tag:"\u6807\u7B7E",hyperlink:"\u94FE\u63A5",note:"\u5907\u6CE8",image:"\u56FE\u7247",icon:"\u56FE\u6807",summary:"\u6982\u8981",associativeLine:"\u5173\u8054\u7EBF",formula:"\u516C\u5F0F",painter:"\u683C\u5F0F\u5237",import:"\u5BFC\u5165",export:"\u5BFC\u51FA",setTheme:"\u4E3B\u9898",setLayout:"\u7ED3\u6784",zoomIn:"\u653E\u5927",zoomOut:"\u7F29\u5C0F",fitView:"\u9002\u5E94",centerRoot:"\u56DE\u6839",fullscreenCanvas:"\u5168\u5C4F",fullscreenPage:"\u5168\u9875",exitFullscreen:"\u9000\u51FA",search:"\u641C\u7D22",showMenu:"\u663E\u793A\u83DC\u5355",expandCollapse:"\u5C55\u5F00/\u6536\u8D77",copyNodeText:"\u590D\u5236\u6587\u672C",readonly:"\u53EA\u8BFB"},vq={undo:"\u21B6",redo:"\u21B7",editNode:"T",insertSiblingAfter:"\u21B5",insertChild:"+",deleteNode:"\xD7",tag:"#",hyperlink:"\u2301",note:"N",image:"\u25A1",icon:"\u2606",summary:"{",associativeLine:"\u2307",formula:"fx",painter:"\u25D0",import:"\u21E7",export:"\u21E9",centerRoot:"\u25CE",zoomOut:"-",zoomIn:"+",search:"\u2315",fullscreenCanvas:"\u26F6",fullscreenPage:"\u25A3",exitFullscreen:"\u2921",showMenu:"\u2630",expandCollapse:"\u2922",copyNodeText:"C",readonly:"\u9501"},bq={undo:"\u21B6",redo:"\u21B7",type:"T",sibling:"\u21B5",trash:"\xD7",child:"+",tag:"#",link:"\u2301",note:"N",image:"\u25A1",smile:"\u2606",summary:"{",route:"\u2307",formula:"fx",paintbrush:"\u25D0",import:"\u21E7",export:"\u21E9",target:"\u25CE",fullscreen:"\u26F6","fullscreen-page":"\u25A3","exit-fullscreen":"\u2921",menu:"\u2630","zoom-out":"-","zoom-in":"+",search:"\u2315",lock:"\u9501"},wq=i=>{let e=[...a3];if(i===null||!Number.isFinite(i))return{availableWidth:null,visibleActionIds:e,overflowActionIds:[]};let t=118,r=96,n=50,s=Math.max(0,i-t-r),a=Math.max(2,Math.min(e.length,Math.floor(s/n)));if(a>=e.length)return{availableWidth:i,visibleActionIds:e,overflowActionIds:[]};let o=Math.max(1,a-1);return{availableWidth:i,visibleActionIds:e.slice(0,o),overflowActionIds:e.slice(o)}};function Mq(i){return({node:e,getPos:t})=>{let r=e,n=0,s=null,a=null,o=null,l=null,h=null,d=null,c=g0(),f=null,m=!1,g=lq(),x=g.activePanelId,y=g.panelOpen,b=g.triggerVisible,E=g.collapsedByToggle,k=g.drawerWidth,L=null,I=null,O=!1,q=!1,F=null,W=!1,ne=null,re=null,le=null,Ce=null,te=null,Q=null,oe=null,he="visible",ui=!1,Mi=!1,ut="canvas",at=null,ot="canvas",nn=0,Bs=0,Gt=null,Wn=null,Hi=null,br=0,Vn=0,sn=!1,mo=null,wr=null,Ui=!1,Wt=sq(window.location.href),ge=document.createElement("div");ge.className="mnote-mindmap-placeholder",ge.dataset.mnoteBlockType="mindmap",ge.dataset.testid="mnote-mindmap-placeholder",ge.setAttribute("contenteditable","false");let ye=document.createElement("div");ye.className="mnote-mindmap-editor-root",ye.dataset.testid="mnote-mindmap-editor-root",ye.dataset.mnoteSceneQuery="mindmap.simple_mind_map_scene.get";let Mr=()=>cq(ye),D=document.createElement("div");D.dataset.testid="leptos-mindmap-island",D.dataset.runtime="simple-mind-map",D.dataset.stage="loading",D.dataset.debugChrome=Wt?"true":"false",D.dataset.suppressRuntimeDiffState="idle",D.className="mnote-leptos-mindmap-shell";let ft=document.createElement("div");ft.className="mnote-mindmap-resize-preview",ft.dataset.testid="mindmap-resize-preview",ft.hidden=!0;let l3=()=>({width:fo(r.attrs.mindmapWidth,"width"),height:fo(r.attrs.mindmapHeight,"height")}),Hb=()=>{let w=window.getComputedStyle(ge).maxWidth,A=Number(String(w||"").replace(/px$/i,""));if(Number.isFinite(A)&&A>0)return A;let R=window.innerWidth>0?Math.min(Ob,Math.max(uo,window.innerWidth-340)):Ob;return Math.max(uo,R)},Oc=(w=!1)=>{window.requestAnimationFrame(()=>{let A=s?.instance;A?.resize?.(),w&&(typeof A?.view?.fit=="function"?A.view.fit():A?.renderer?.setRootNodeCenter?.())})},Ub=()=>{let{width:w,height:A}=l3();ge.dataset.mnoteMindmapResized=w!==null||A!==null?"true":"false",w!==null?(ge.dataset.mnoteMindmapWidth=String(w),ge.style.width=`${w}px`):(delete ge.dataset.mnoteMindmapWidth,ge.style.removeProperty("width")),A!==null?(ge.dataset.mnoteMindmapHeight=String(A),ye.dataset.mnoteMindmapHeight=String(A),D.dataset.mnoteMindmapHeight=String(A),D.style.height=`${A}px`):(delete ge.dataset.mnoteMindmapHeight,delete ye.dataset.mnoteMindmapHeight,delete D.dataset.mnoteMindmapHeight,D.style.removeProperty("height")),Oc()},$b=(w,A)=>{ge.dataset.mnoteMindmapResized="true",ge.dataset.mnoteMindmapWidth=String(w),ge.dataset.mnoteMindmapHeight=String(A),ye.dataset.mnoteMindmapHeight=String(A),D.dataset.mnoteMindmapHeight=String(A),ge.style.width=`${w}px`,D.style.height=`${A}px`},h3=(w,A)=>{ge.dataset.mnoteMindmapResizing="true",ft.hidden=!1,ft.dataset.mnoteMindmapWidth=String(w),ft.dataset.mnoteMindmapHeight=String(A),ft.style.width=`${w}px`,ft.style.height=`${A}px`},jb=()=>{ge.dataset.mnoteMindmapResizing="false",ft.hidden=!0,delete ft.dataset.mnoteMindmapWidth,delete ft.dataset.mnoteMindmapHeight,ft.style.removeProperty("width"),ft.style.removeProperty("height")},Gb=(w,A)=>{let R=t();if(typeof R!="number")return;let P={...r.attrs,mindmapWidth:w,mindmapHeight:A};i.view.dispatch(i.state.tr.setNodeMarkup(R,void 0,P)),Oc(!0)},Wb=()=>{let w=t();if(typeof w!="number")return;let{width:A}=l3();if(A===null){Oc(!0);return}let R={...r.attrs,mindmapWidth:null};i.view.dispatch(i.state.tr.setNodeMarkup(w,void 0,R))},x0=w=>{let A=document.createElement("button");return A.type="button",A.className=`mnote-mindmap-resize-handle mnote-mindmap-resize-handle-${w}`,A.dataset.testid=`mindmap-resize-handle-${w}`,A.dataset.mnoteMindmapResizeHandle=w,A.setAttribute("aria-label","\u8C03\u6574\u601D\u7EF4\u5BFC\u56FE\u5927\u5C0F"),A.addEventListener("pointerdown",R=>{R.preventDefault(),R.stopPropagation();let P=ge.getBoundingClientRect(),Y=Math.max(uo,P.width),K=Math.max(o3,P.height),ce=R.clientX,J=R.clientY,ve=w.endsWith("e")?1:-1,qe=w.startsWith("s")?1:-1,C0=Math.max(uo,Hb()),xo=Math.round(Y),yo=Math.round(K);h3(xo,yo),A.setPointerCapture(R.pointerId);let S3=Uc=>{Uc.preventDefault();let vw=(Uc.clientX-ce)*ve,bw=(Uc.clientY-J)*qe;xo=Math.round(Math.max(uo,Math.min(C0,Y+vw))),yo=Math.round(Math.max(o3,K+bw)),h3(xo,yo)},_0=()=>{jb(),A.releasePointerCapture(R.pointerId),A.removeEventListener("pointermove",S3),A.removeEventListener("pointerup",_0),A.removeEventListener("pointercancel",_0),$b(xo,yo),Gb(xo,yo)};A.addEventListener("pointermove",S3),A.addEventListener("pointerup",_0),A.addEventListener("pointercancel",_0)}),A},Bc=()=>{D.dataset.suppressRuntimeDiffState=c.status,D.dataset.suppressRuntimeDiffReason=c.status==="armed"?c.reason:"",D.dataset.suppressRuntimeDiffSince=c.status==="armed"?String(c.armedAt):""},Vb=w=>{c=Lb(w,Date.now()),Bc()},Ps=()=>{c=Ib(),Bc()},Yn=document.createElement("div");Yn.className="mnote-mindmap-workspace",Yn.dataset.debugChrome=Wt?"true":"false",Yn.dataset.layout=Wt?"debug-grid":"floating-overlay";let y0=document.createElement("div");y0.className="mnote-mindmap-canvas-layer",y0.dataset.testid="mindmap-canvas-layer";let Xn=document.createElement("div");Xn.className="mnote-mindmap-overlay-layer",Xn.dataset.testid="mindmap-overlay-layer";let xt=document.createElement("div");xt.className="mnote-leptos-mindmap-runtime",xt.dataset.testid="simple-mind-map-runtime",xt.dataset.runtime="simple-mind-map",xt.dataset.runtimeEngine="pending";let er=document.createElement("div");er.className="mnote-mindmap-rust-shell-mount",er.dataset.testid="mindmap-rust-shell-mount",er.dataset.uiShellSource="leptos-rust-shell";let Kn=document.createElement("div");Kn.className="mnote-mindmap-command-toolbar",Kn.dataset.testid="mindmap-command-toolbar";let Zn=document.createElement("aside");Zn.className="mnote-mindmap-side-panel",Zn.dataset.testid="mindmap-sidebar";let Qn=document.createElement("div");Qn.className="mnote-mindmap-bottom-bar",Qn.dataset.testid="mindmap-bottom-bar";let et=()=>{let w=typeof r.attrs.mindmapId=="string"&&r.attrs.mindmapId.length>0?r.attrs.mindmapId:"mindmap",A=typeof r.attrs.rootNodeId=="string"&&r.attrs.rootNodeId.length>0?r.attrs.rootNodeId:"root";return{mindmapId:w,rootNodeId:A}},d3=w=>JSON.stringify({mnoteBlockType:w.attrs.mnoteBlockType??null,mindmapId:w.attrs.mindmapId??null,rootNodeId:w.attrs.rootNodeId??null,projectionVersion:w.attrs.projectionVersion??null,mindmapWidth:w.attrs.mindmapWidth??null,mindmapHeight:w.attrs.mindmapHeight??null}),po=()=>{let{mindmapId:w,rootNodeId:A}=et();ge.dataset.mnoteMindmapId=w,ge.dataset.mnoteRootNodeId=A,ge.dataset.mnoteProjectionVersion=String(r.attrs.projectionVersion??1),ye.dataset.mnoteMindmapId=w,ye.dataset.mnoteRootNodeId=A,ye.dataset.mnoteProjectionVersion=String(r.attrs.projectionVersion??1),ye.dataset.mnoteSceneQuery="mindmap.simple_mind_map_scene.get",Ub()},v0=()=>{if(!(Wn===null||!Hi)){try{Hi.unmount(Wn)}catch{}Wn=null,Hi=null,er.replaceChildren()}},c3=()=>{let w=s?.getSnapshot(),A=zt(w)&&"root"in w?w.root:w??a?.root,R=0,P=0,Y=J=>{if(!zt(J))return;R+=1;let ve=zt(J.data)&&typeof J.data.text=="string"?J.data.text:"";P+=ve.trim().length,(Array.isArray(J.children)?J.children:[]).forEach(Y)};Y(A);let K=a?.view,ce=zt(w)&&zt(w.view)&&zt(w.view.state)&&typeof w.view.state.scale=="number"?w.view.state.scale:zt(K)&&zt(K.state)&&typeof K.state.scale=="number"?K.state.scale:1;return{nodeCount:R,wordCount:P,zoomPercent:Math.round(ce*100)}},Yb=()=>a?{...wi(a.root),layout:a.layout,theme:a.theme,themeConfig:a.themeConfig,view:a.view,config:a.config,compatPayload:a.compatPayload}:null,Xb=(w,A)=>{a&&(a.root=Os(wi(w)),"layout"in w&&(a.layout=w.layout),"theme"in w&&(a.theme=w.theme),"themeConfig"in w&&(a.themeConfig=w.themeConfig),"view"in w&&(a.view=w.view),"config"in w&&(a.config=w.config),"compatPayload"in w&&(a.compatPayload=w.compatPayload),typeof A=="number"&&Number.isFinite(A)&&(a.kernelRevision=A),o=Os(a.root))},Kb=()=>{let w=s?.getSnapshot(),A=zt(w)&&"root"in w?w.root:w??a?.root;return yq(A)},b0=()=>{W&&(W=!1,Ie())},u3=(w,A)=>{let R=ye.getBoundingClientRect();nn=Math.round(w-R.left),Bs=Math.round(A-R.top)},w0=()=>{!Mi&&!D.dataset.contextMenuKind||(Mi=!1,ut="canvas",at=null,ot="canvas",delete D.dataset.contextMenuKind,delete D.dataset.contextMenuTargetNodeId,delete D.dataset.contextMenuTargetNodeKind,S0())},M0=w=>Ds(w),Zb=()=>{let w=s?.instance.renderer;return w?.activeNodeList?.[0]??w?.lastActiveNodeList?.[0]??w?.root??w?.renderTree?._node??null},T0=(w,A,R)=>{let P=Ds(A);return P&&pq(w.root,P)?P:Pb(w.root)??Bb(w,R)},Pc=w=>{let A=Ds(w);return A||(M0(h)??M0(Zb())??null)},Qb=w=>{if(!w||typeof w!="object")return"node";let A=w;return A.isRoot===!0?"root":A.isGeneralization===!0?"generalization":"node"},Jb=w=>{let A=s?.instance.renderer;if(A)try{A.clearActiveNodeList?.(),A.addNodeToActiveList?.(w,!0),A.emitNodeActiveEvent?.(w,[w])}catch{}},go=w=>{let A=Ds(w),R=s?.instance.renderer,P=A?R?.findNodeByUid?.(A)??null:R?.activeNodeList?.[0]??R?.lastActiveNodeList?.[0]??R?.root??R?.renderTree?._node;if(P)try{R?.clearActiveNodeList?.(),R?.addNodeToActiveList?.(P,!0),R&&(R.lastActiveNodeList=[P]),R?.emitNodeActiveEvent?.(P,[P]),s?.instance.execCommand?.("SET_NODE_ACTIVE",P,!0),h=P;let K=A??M0(P)??l??et().rootNodeId;return l=K,d=K,D.dataset.lastRuntimeSelectionSync=K,!0}catch{}let Y=s?.instance.execCommand;if(typeof Y!="function"||!A)return!1;try{return Y.call(s?.instance,"GO_TARGET_NODE",A),l=A,d=A,D.dataset.lastRuntimeSelectionSync=A,!0}catch{return!1}},f3=w=>{let A=Ds(w),R=s?.instance.renderer;return{wantedNodeId:A,runtimeNode:A?R?.findNodeByUid?.(A)??null:R?.activeNodeList?.[0]??R?.lastActiveNodeList?.[0]??R?.root??R?.renderTree?._node}},ew=async(w,A=3)=>{let R=f3(w);for(let P=1;!R.runtimeNode&&Pwindow.requestAnimationFrame(()=>Y())),R=f3(w);return R},tw=async(w,A,R)=>{let P=w==="DELETE_NODE"?"REMOVE_NODE":w,Y=s?.instance;if(!Y||typeof Y.execCommand!="function")return{ok:!1,command:P,error:"runtime_unavailable",message:"runtime_instance_missing"};let{wantedNodeId:K,runtimeNode:ce}=await ew(A);if(!ce)return{ok:!1,command:P,error:"command_failed",message:`runtime_node_missing:${K??"unknown"}`};try{if(Y.renderer?.clearActiveNodeList?.(),Y.renderer?.addNodeToActiveList?.(ce,!0),Y.renderer&&(Y.renderer.lastActiveNodeList=[ce]),Y.renderer?.emitNodeActiveEvent?.(ce,[ce]),Y.execCommand("SET_NODE_ACTIVE",ce,!0),P==="REMOVE_NODE")return{ok:!0,command:P,result:Y.execCommand("REMOVE_NODE",[ce])};if(P==="INSERT_CHILD_NODE"||P==="INSERT_NODE")return{ok:!0,command:P,result:Y.execCommand(P,!1,[ce],R?{uid:R.uid,text:R.text}:null)}}catch{return{ok:!1,command:P,error:"command_failed",message:"runtime_command_throw"}}return s?.execCommand(P)??{ok:!1,command:P,error:"unsupported_command",message:"runtime_command_unsupported"}},iw=(w,A,R)=>{u3(w,A),ut="node",at=M0(R),ot=Qb(R),Mi=!0,D.dataset.contextMenuKind="node",D.dataset.contextMenuTargetNodeId=at??"",D.dataset.contextMenuTargetNodeKind=ot,Jb(R),at&&(l=at,d=at),S0()},rw=(w,A)=>{u3(w,A),ut="canvas",at=null,ot="canvas",Mi=!0,D.dataset.contextMenuKind="canvas",D.dataset.contextMenuTargetNodeId="",D.dataset.contextMenuTargetNodeKind="canvas",S0()},N0=w=>{he!==w&&(he=w,D.dataset.chromeVisibility=w,Ie())},m3=()=>{ui=!0,D.dataset.keyboardShortcutArmed="true"},nw=()=>{ui=!1,D.dataset.keyboardShortcutArmed="false"},E0=()=>document.fullscreenElement===ye||ye.contains(document.fullscreenElement),sw=()=>{let w=s?.instance;try{typeof w?.resize=="function"?w.resize():typeof w?.view?.resize=="function"&&w.view.resize(),w?.renderer?.setRootNodeCenter?.()}catch{D.dataset.fullscreenResizeStatus="failed";return}D.dataset.fullscreenResizeStatus="success"},Fc=()=>{let w=E0();D.dataset.fullscreenActive=w?"true":"false",ye.dataset.fullscreenActive=w?"true":"false",window.setTimeout(()=>{sw(),Ie()},80)},qc=()=>{s?.instance.setMode?.(m?"readonly":"edit"),D.dataset.readonly=m?"true":"false"},p3=w=>{D.dataset.searchStatus="ready",D.dataset.lastSearchQuery=w,q=!0,Ie()},aw=w=>{let A=typeof w=="number"?w:Number(String(w??"").replace("%","").trim());if(!Number.isFinite(A)){D.dataset.zoomInputStatus="invalid",Ie();return}let R=Math.max(10,Math.min(500,Math.round(A))),P=s?.instance.view;if(!P?.setScale){D.dataset.zoomInputStatus="unsupported",Ie();return}P.setScale(R/100,ye.clientWidth/2,ye.clientHeight/2),D.dataset.zoomInputStatus="success",Hs(s?.getSnapshot()),Ie()},g3=async w=>{if(w==="exitFullscreen"){document.fullscreenElement&&await document.exitFullscreen(),Fc();return}if(!(w!=="fullscreenCanvas"&&w!=="fullscreenPage")){if(typeof ye.requestFullscreen!="function"){D.dataset.commandStatus="fullscreen-unavailable",D.dataset.disabledReason="fullscreen-unavailable";return}await ye.requestFullscreen(),Fc()}},Hc=(w,A)=>{let R=Dc.toolbarActionMeta[w],P=R?.shortLabel??qb[w]??w,Y=R?.longLabel??qb[w]??w,K=R?.iconKey??w;return{id:w,label:P,longLabel:Y,icon:bq[K]??vq[w]??P.slice(0,1),iconKey:K,priority:R?.priority??999,overflowGroup:R?.overflowGroup??"view",cluster:R?.cluster??"main",disabled:A.disabledActions[w]??!0}},ow=()=>{let w=window.__MNOTE_MINDMAP_RUST_SHELL__;if(!w){v0(),D.dataset.uiShell="typescript-nodeview-dom",er.dataset.uiShellSource="missing-rust-shell",er.innerHTML='
    Leptos/Rust mindmap shell \u672A\u52A0\u8F7D
    ';return}let A=wq(F??ye.getBoundingClientRect().width),R=r3({activeNodeId:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"],shell:{chromeVisibility:he,toolbarOverflow:{availableWidth:A.availableWidth,visibleActionIds:A.visibleActionIds,overflowActionIds:A.overflowActionIds,moreOpen:W&&A.overflowActionIds.length>0},fullscreen:{mode:E0()?"canvas":"none",isFullscreen:E0(),target:"mindmap-root",apiAvailable:typeof ye.requestFullscreen=="function"},sidebar:{activePanelId:x,panelOpen:y,triggerVisible:b,drawerWidth:k,collapsedByToggle:E},navigator:{searchOpen:q,minimapOpen:O,readonly:m,zoomPercent:c3().zoomPercent}}}),{mindmapId:P}=et(),Y=c3(),K=new Set(R.shell.toolbarOverflow.visibleActionIds),ce=new Set(R.shell.toolbarOverflow.overflowActionIds),J={mindmapId:P,toolbarGroups:[{id:"main",label:"\u4E3B\u5DE5\u5177",actions:a3.filter(ve=>K.size===0||K.has(ve)).map(ve=>Hc(ve,R))},{id:"overflow",label:"\u66F4\u591A",actions:a3.filter(ve=>ce.has(ve)).map(ve=>Hc(ve,R))},{id:"file",label:"\u6587\u4EF6",actions:aq.map(ve=>Hc(ve,R))}],sidebarPanels:Dc.sidebarPanels.map(ve=>({id:ve.id,kind:ve.kind,label:ve.label,icon:ve.icon,active:y&&ve.id===x,bodyTitle:ve.label,bodyCaption:ve.runtimeCapability,options:ve.options.map(qe=>({id:qe.id,label:qe.label,actionId:qe.actionId,value:qe.value,controlType:qe.controlType,preview:qe.preview,description:qe.description,readonly:qe.readonly??!1,compatPath:qe.compatPath})),bodyItems:ve.id==="outline"?Kb():[]})),navigator:{wordCount:Y.wordCount,nodeCount:Y.nodeCount,zoomPercent:Y.zoomPercent,readonly:m,minimapOpen:O},shell:R.shell};v0(),er.dataset.uiShellSource="leptos-rust-shell",Hi=w,Wn=w.mount(er,J),D.dataset.uiShell="leptos-rust-shell"},Ie=()=>{if(po(),!Wt){ow(),S0();return}v0(),D.dataset.uiShell="debug-fallback",Kn.dataset.testid="mindmap-command-toolbar",Kn.className="mnote-mindmap-command-toolbar",delete Kn.dataset.schemaSource,Zn.dataset.testid="mindmap-sidebar",Zn.className="mnote-mindmap-side-panel",delete Zn.dataset.schemaSource,Qn.dataset.testid="mindmap-bottom-bar",Qn.className="mnote-mindmap-bottom-bar",delete Qn.dataset.schemaSource;let w=a?s3(a):"",A=f??w,P=s!==null?"":" disabled",Y=["\u8282\u70B9\u6837\u5F0F","\u5BFC\u56FE\u6837\u5F0F","\u4E3B\u9898","\u7ED3\u6784","\u5927\u7EB2"].map((K,ce)=>``).join("");Kn.innerHTML=`
    `,Zn.innerHTML=`${Y}
    \u7ECF\u5178\u4E3B\u9898 \xB7 \u903B\u8F91\u7ED3\u6784
    `,Qn.innerHTML=`runtime \u8282\u70B9100%`},S0=()=>{let w=Xn.querySelector('[data-testid="mindmap-schema-context-menu"]');if(!Mi){w?.remove();return}w||(w=document.createElement("div"),w.className="mnote-mindmap-context-menu",w.dataset.testid="mindmap-schema-context-menu",w.dataset.uiSource="typescript-nodeview-bridge",Xn.append(w)),w.dataset.contextMenuKind=ut,w.dataset.contextMenuTargetNodeKind=ot;let R=r3({activeNodeId:ut==="node"?at??l:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"]}),P=Dc.contextMenuItems.filter(J=>J.requiresNode===(ut==="node")),Y=J=>R.disabledActions[J]?!0:ut!=="node"?!1:ot==="root"&&(J==="insertSiblingAfter"||J==="deleteNode")||ot==="generalization"&&(J==="insertChild"||J==="insertSiblingAfter"||J==="deleteNode"||J==="summary"||J==="associativeLine"||J==="expandCollapse");w.innerHTML=P.map(J=>{let ve=Y(J.actionId);return``}).join("");let K=Math.min(Math.max(8,nn),Math.max(8,ye.clientWidth-w.offsetWidth-8)),ce=Math.min(Math.max(8,Bs),Math.max(8,ye.clientHeight-w.offsetHeight-8));w.style.left=`${K}px`,w.style.top=`${ce}px`},x3=()=>{po(),D.dataset.stage="loading",xt.dataset.runtimeEngine="loading",xt.replaceChildren(),Ie()},y3=w=>w==="mnote-web-tree-live"||w==="externalTreeLive"||w==="nodeViewUpdate",lw=w=>w==="mnote-web-tree-live"||w==="externalTreeLive",hw=()=>D.dataset.stage==="ready"&&xt.dataset.runtimeReady==="true"&&a!==null,dw=()=>{if(s?.instance.renderer?.textEdit?.isShowTextEdit?.())return!0;let A=document.activeElement;if(A instanceof HTMLElement&&A.closest(".smm-node-edit-wrap"))return!0;let R=document.querySelector('.smm-node-edit-wrap[contenteditable="true"]');return R instanceof HTMLElement&&R.style.display!=="none"&&R.getClientRects().length>0},v3=w=>{let A=s?.instance.renderer?.textEdit;if(!A?.isShowTextEdit?.())return!1;let R=Ds(A.getCurrentEditNode?.())??l??d,P=A.getEditText?.();if(D.dataset.lastRuntimeTextEditFlushReason=w,R&&typeof P=="string"&&P.length>0){D.dataset.lastRuntimeTextEditFlushNodeId=R,D.dataset.lastRuntimeTextEditFlushText=P;let{mindmapId:Y}=et(),K=Mr();K&&a&&i3({documentId:K,mindmapId:Y,commands:[{type:"updateText",mindmapId:Y,nodeId:R,text:P}],projectionRevision:a.kernelRevision}).catch(J=>{D.dataset.lastRuntimeTextEditFlushError=J instanceof Error?J.message:String(J)})}return A.hideEditTextBox?.(),!0},b3=(w,A="text_edit")=>{D.dataset.runtimeProjectionDeferred=A,D.dataset.lastRuntimeProjectionDeferReason=w,D.dataset.runtimeProjectionDeferredAt=String(Date.now())},w3=()=>{D.dataset.runtimeProjectionDeferred="",D.dataset.lastRuntimeProjectionDeferReason="",D.dataset.runtimeProjectionDeferredAt=""},Fs=(w,A="")=>{D.dataset.backgroundProjectionRefresh=w,D.dataset.backgroundProjectionRefreshMessage=A,Ie()},an=(w,A)=>{let{mindmapId:R}=et();po(),D.dataset.stage=w,xt.dataset.runtimeEngine="error",xt.innerHTML=`
    ${Rs(w)}${Rs(R)}${Rs(A)}
    `,Ie()},qs=async(w,A)=>{if(D.dataset.commandCount=String(w.length),D.dataset.commandHasProjection=a?"true":"false",D.dataset.commandFailedAction="",D.dataset.commandFailedMessage="",w.length===0||!a){D.dataset.commandStatus="skipped";return}let{mindmapId:R}=et(),P=Mr();if(!P){an("command_failed",`mindmapId=${R}; documentId_missing`);return}D.dataset.commandStatus="pending";try{let Y=await ZF({documentId:P,mindmapId:R,commands:w,projectionRevision:a.kernelRevision});if(Ui)return;let K=A?T0(Y,A,et().rootNodeId):void 0;await N3(Y,"commandRefresh",K),f=null,D.dataset.commandStatus="success"}catch(Y){let K=Y instanceof Error?Y.message:String(Y);D.dataset.commandStatus="failed",D.dataset.commandFailedAction=D.dataset.lastSchemaAction??"",D.dataset.commandFailedMessage=K,an("command_failed",`mindmapId=${R}; ${K}`)}},M3=async(w,A)=>{if(D.dataset.commandCount=String(w.length),D.dataset.commandHasProjection=a?"true":"false",D.dataset.commandFailedAction="",D.dataset.commandFailedMessage="",D.dataset.commandApplyMode="",D.dataset.commandLocalApplyErrors="",w.length===0||!a){D.dataset.commandStatus="skipped",D.dataset.commandApplyMode="skipped",Ps();return}if(!XF(w)){D.dataset.commandApplyMode="refresh:unsupported",Ps(),await qs(w,A);return}let R=Yb();if(!R){D.dataset.commandApplyMode="refresh:no_blob",Ps(),await qs(w,A);return}let P=YF(R,w);if(P.errors.length>0){D.dataset.commandApplyMode="refresh:local_errors",D.dataset.commandLocalApplyErrors=P.errors.join("|"),Ps(),await qs(w,A);return}let{mindmapId:Y}=et(),K=Mr();if(!K){an("command_failed",`mindmapId=${Y}; documentId_missing`);return}D.dataset.commandStatus="pending",D.dataset.commandApplyMode="local";try{let ce=await i3({documentId:K,mindmapId:Y,commands:w,projectionRevision:a.kernelRevision});if(Ui)return;if(Xb(P.data,ce.kernelRevision),A){let J=T0(a,A,et().rootNodeId);l=J,d=J,window.setTimeout(()=>{go(J)},0)}f=null,D.dataset.commandStatus="success",Ie()}catch(ce){let J=ce instanceof Error?ce.message:String(ce);D.dataset.commandStatus="failed",D.dataset.commandFailedAction=D.dataset.lastSchemaAction??"",D.dataset.commandFailedMessage=J,Ps(),an("command_failed",`mindmapId=${Y}; ${J}`)}},cw=async w=>{if(!a)return;let{mindmapId:A}=et(),R=Mr();if(!R){an("command_failed",`mindmapId=${A}; documentId_missing`);return}D.dataset.viewCommandStatus="pending";try{if(await i3({documentId:R,mindmapId:A,commands:[JF(A,w)],projectionRevision:a.kernelRevision}),Ui)return;a.view=w,D.dataset.viewCommandStatus="success"}catch(P){an("command_failed",`mindmapId=${A}; ${P instanceof Error?P.message:String(P)}`)}},Hs=w=>{let A=fq(w);A&&(L=A,D.dataset.lastViewPatch=JSON.stringify(A),I!==null&&window.clearTimeout(I),I=window.setTimeout(()=>{I=null;let R=L;L=null,R&&cw(R)},350))},uw=w=>{if(s){if(w==="editNode"){let A=s.instance.renderer,R=s.instance.keyCommand,P=A?.textEdit,Y=h??A?.activeNodeList?.[0]??null;if(Y&&typeof P?.show=="function")P.show({node:Y,isFromKeyDown:!1}),D.dataset.editNodeStatus="opened";else if(typeof R?.getShortcutFn=="function"){let K=R.getShortcutFn("F2")[0];typeof K=="function"?(K(),D.dataset.editNodeStatus="opened"):D.dataset.editNodeStatus="unsupported"}else D.dataset.editNodeStatus="unsupported";return}if(w==="centerRoot"&&s.instance.renderer?.setRootNodeCenter?.(),w==="zoomOut"&&s.instance.view?.narrow?.(),w==="zoomIn"&&s.instance.view?.enlarge?.(),w==="fitView"&&s.instance.view?.reset?.(),w==="fullscreenCanvas"||w==="fullscreenPage"||w==="exitFullscreen"){g3(w);return}if(w==="search"){q?(q=!1,D.dataset.lastSearchQuery="",D.dataset.searchStatus="closed",Ie()):p3("");return}if(w==="showMenu"){N0("visible"),w0();return}if(w==="expandCollapse"){s.instance.renderer?.toggleActiveExpand?.(),D.dataset.contextMenuActionStatus="success",D.dataset.lastContextMenuAction=w,Ie();return}if(w==="copyNodeText"){let A=at??l,R=a?xq(a.root,A):"";D.dataset.copiedNodeText=R,D.dataset.contextMenuActionStatus="success",D.dataset.lastContextMenuAction=w;return}w==="readonly"&&(m=!m,qc()),Hs(s.getSnapshot()),Ie()}},fw=(w,A,R)=>{if(!s)return;let P=Fb(w,R);if(!P)return;let Y=zt(s.instance.getThemeConfig?.())?s.instance.getThemeConfig?.():{};if(R&&P.startsWith(`nodes.${R}.data.`)&&h){let K=P.split(".data.")[1]??"";if(K==="shape"){h.setShape?.(A);return}if(K){let ce=K==="fontWeight"&&A===!0?"bold":K==="fontStyle"&&A===!0?"italic":A;h.setData?.({[K]:ce});return}}if(P.startsWith("style.map.")){let K=P.slice(10);if(!K)return;s.instance.setThemeConfig?.({...Y,[K]:A},!1)}},mw=(w,A,R)=>{if(!(!s||A.source!=="sidebar")){if(w==="setLayout"){s.instance.setLayout?.(A.value);return}if(w==="setTheme"){s.instance.setTheme?.(A.value);return}w==="painter"&&typeof A.compatPath=="string"&&fw(A.compatPath,A.value,R)}},A0=async(w,A={})=>{let R=Db(w);if(!R||r3({activeNodeId:ut==="node"?at??l:l,readonly:m,runtimeCapabilities:["runtimeCommand","kernelCommand","compatPatch","localView"]}).disabledActions[w])return;if(D.dataset.lastSchemaAction=w,R.target==="localView"){uw(w);return}let Y=mq(w),K=ut==="node"?at??d??l:d??l;if(R.requiresActiveNode){let qe=Pc(K);qe&&(K=qe,l=qe,d=qe)}D.dataset.lastSchemaActiveNodeId=K??"";let ce=et().mindmapId;mw(w,A,K);let J=iq({actionId:w,mindmapId:ce,activeNodeId:K,node:Y,value:A.value??(w==="editNode"?s3(a):!0),source:A.source,runtimeRevision:a?.kernelRevision??null,kernelRevision:a?.kernelRevision??null}),ve=Fb(A.compatPath,K);if(ve&&(J={command:eq({mindmapId:ce,path:ve,value:A.value??!0,source:A.source??"sidebar",actionId:w,runtimeRevision:a?.kernelRevision??null,kernelRevision:a?.kernelRevision??null})}),D.dataset.lastSchemaCommand=J?.command?JSON.stringify(J.command):"",D.dataset.lastSchemaRuntimeCommand=J?.runtimeCommand??"",!!J){if(R.target==="runtimeCommand"&&J.runtimeCommand){if(J.command){Vb(J.runtimeCommand),R.requiresActiveNode&&go(K);let qe=await tw(J.runtimeCommand,K,Y),C0=Y?.uid??(w==="deleteNode"?et().rootNodeId:K);if(qe?.ok){Y?.uid&&(J.runtimeCommand==="INSERT_CHILD_NODE"||J.runtimeCommand==="INSERT_NODE")&&window.setTimeout(()=>{go(Y.uid)},0),M3([J.command],C0);return}D.dataset.commandApplyMode="refresh:runtime_failed",D.dataset.commandRuntimeError=qe?.error??"unknown",D.dataset.commandRuntimeMessage=qe&&"message"in qe?qe.message??"":"",Ps(),qs([J.command],C0);return}s?.execCommand(J.runtimeCommand);return}J.command&&qs([J.command])}},pw=w=>{let A=w.target instanceof Node&&ye.contains(w.target);return nq({debugChromeEnabled:Wt,bridgeReady:!!s,readonly:m,isComposing:w.isComposing,isEditableTarget:uq(w.target),targetInsideRoot:A,keyboardShortcutArmed:ui})},gw=w=>{if(!pw(w))return;let A=rq(w);if(!A)return;w.preventDefault(),w.stopPropagation(),w.stopImmediatePropagation(),D.dataset.lastShortcutKey=w.key,D.dataset.lastShortcutAction=A;let R=a?Bb(a,et().rootNodeId):et().rootNodeId;if(Db(A)?.requiresActiveNode){let Y=Pc(d??l);if(Y===R&&(A==="insertSiblingAfter"||A==="deleteNode")){let K=Pc(null);K&&K!==R?Y=K:a&&(Y=Pb(a.root)??Y)}if(Y)l=Y,d=Y;else{D.dataset.lastShortcutActionBlocked=A;return}}if((d??l)===R&&(A==="insertSiblingAfter"||A==="deleteNode")){D.dataset.lastShortcutActionBlocked=A;return}A0(A,{source:"toolbar"})},xw=w=>{if(w.type==="node_active"){let Y=l;l=Ds(w.args[0])??l,h=typeof w.args[0]=="object"&&w.args[0]!==null?w.args[0]:null,(!d||d===Y)&&(d=l),Ie();return}if(w.type==="view_data_change"||w.type==="scale"||w.type==="translate"){D.dataset.lastViewEvent=w.type,Hs(w.snapshot??s?.getSnapshot());return}if(w.type!=="data_change"||!a||!w.snapshot)return;let A=Os(w.snapshot);D.dataset.lastDataChangeSeenAt=String(Date.now());let R=zb(c,Date.now());if(c=R.state,Bc(),D.dataset.lastDataChangeSuppressed=R.suppressed?"true":"false",D.dataset.lastDataChangeSuppressionExpired=R.expired?"true":"false",R.suppressed){o=A;return}let P=tq({mindmapId:et().mindmapId,previous:o??a.root,next:A});if(o=A,D.dataset.lastDataChangeDiffCommandCount=String(P.commands.length),D.dataset.lastDataChangeCompatPatchCount=String(P.compatPatches.length),P.commands.length===0&&P.compatPatches.length===0){D.dataset.lastDataChangeRefreshTriggered="false";return}D.dataset.lastDataChangeRefreshTriggered="false",M3([...P.commands,...P.compatPatches])},T3=w=>typeof w=="string"&&w.trim().length>0?w.trim():zt(w)&&typeof w.template=="string"&&w.template.trim().length>0?w.template.trim():null,yw=(w,A,R)=>{if(!s)return!1;let{mindmapId:P,rootNodeId:Y}=et();if(D.dataset.mountedMindmapId&&D.dataset.mountedMindmapId!==P)return!1;let K=wi(w.root);if(typeof s.instance.setData!="function")return!1;a={...w,root:Os(K)},l=T0(w,R??l,Y),h=null,d=l,o=Os(a.root);let ce=T3(w.layout),J=T3(w.theme),ve=zt(w.themeConfig)?w.themeConfig:null;return ce&&s.instance.setLayout?.(ce,!0),J&&s.instance.setTheme?.(J,!0),ve&&s.instance.setThemeConfig?.(ve,!0),s.instance.setData(K),Vn+=1,D.dataset.runtimeProjectionApplyCount=String(Vn),D.dataset.lastRuntimeProjectionApplyReason=A,xt.dataset.runtimeEngine="simple-mind-map",xt.dataset.runtimeReady="true",D.dataset.stage="ready",Rc(P,s),qc(),window.setTimeout(()=>{go(l)},0),Ie(),!0},N3=async(w,A,R)=>{let{mindmapId:P,rootNodeId:Y}=et();if(Gt&&(s?.instance.off?.("node_contextmenu",Gt),Gt=null),s?.destroy(),Rc(P,null),a={...w,root:Os(w.root)},l=T0(w,R,Y),h=null,d=l,o=Os(a.root),br+=1,D.dataset.runtimeMountCount=String(br),D.dataset.lastRuntimeMountReason=A,D.dataset.mountedMindmapId=P,D.dataset.mountedRootNodeId=Y,xt.dataset.runtimeEngine="simple-mind-map",xt.dataset.runtimeReady="false",xt.replaceChildren(),Ie(),s=await KF({el:xt,projection:w,mode:m?"readonly":"edit",runtimeOptions:{fit:!0,mousewheelAction:"zoom",enableFreeDrag:!0,enableCtrlKeyNodeSelection:!0,useLeftKeySelectionRightKeyDrag:!0,createNewNodeBehavior:"activeOnly"},onEvent:xw}),Ui){s.destroy();return}s.refreshProjection=E3,Gt=(...K)=>{let[ce,J]=K;ce instanceof MouseEvent&&(ce.preventDefault(),ce.stopPropagation(),iw(ce.clientX,ce.clientY,J))},s.instance.on?.("node_contextmenu",Gt),xt.dataset.runtimeReady="true",D.dataset.stage="ready",Rc(P,s),qc(),window.setTimeout(()=>{go(l)},0),Ie()},k0=async(w="fetchScene",A=0)=>{let R=++n,{mindmapId:P,rootNodeId:Y}=et();wr!==null&&(window.clearTimeout(wr),wr=null);let K=Mr();if(!K){if(D.dataset.documentIdResolveStatus="missing",D.dataset.documentIdResolveRetryCount=String(A),A<30){y3(w)||x3(),wr=window.setTimeout(()=>{wr=null,Ui||k0(w,A+1)},100);return}an("projection_load_failed",`mindmapId=${P}; documentId_missing`);return}D.dataset.documentIdResolveStatus="ready",D.dataset.lastFetchSceneReason=w;let ce=y3(w)&&hw();if(ce&&lw(w)){b3(w,"live_signal"),Fs("deferred","usability_first");return}ce?Fs("pending"):x3();try{if(R!==n)return;let J=await QF({documentId:K,mindmapId:P,endpoint:`/api/mindmap/${encodeURIComponent(K)}/${encodeURIComponent(P)}?view=simple_mind_map_scene&queryName=mindmap.simple_mind_map_scene.get&rootNodeId=${encodeURIComponent(Y)}`});if(R!==n||Ui)return;try{let ve=Rb({documentId:K,mindmapId:P,data:wi(J.root)}),qe=await fetch(ve.endpoint,ve.init);D.dataset.initialCreateOnlyStatus=qe.ok?"success":"failed"}catch{D.dataset.initialCreateOnlyStatus="failed"}if(ce&&dw()){b3(w),Fs("deferred","text_edit");return}if(ce&&yw(J,w)){w3(),Fs("success");return}await N3(J,w),w3(),Fs("success")}catch(J){if(ce){Fs("failed",J instanceof Error?J.message:String(J));return}an("projection_load_failed",`mindmapId=${P}; ${J instanceof Error?J.message:String(J)}`)}},E3=async(w="externalTreeLive")=>{if(!Ui){if(sn){mo=w;return}sn=!0;try{await k0(w)}finally{sn=!1;let A=mo;mo=null,A&&!Ui&&E3(A)}}};return ge.addEventListener("pointerdown",w=>w.stopPropagation()),ge.addEventListener("mousedown",w=>w.stopPropagation()),ye.addEventListener("pointerleave",()=>{b0(),!Mi&&he==="visible"&&N0(zc(he,"pointerLeave"))}),ye.addEventListener("pointerenter",()=>{he=zc(he,"pointerEnter"),D.dataset.chromeVisibility=he}),ye.addEventListener("pointerdown",()=>{m3(),he!=="visible"&&N0(zc(he,"restoreClick"))},!0),ye.addEventListener("click",()=>{m3(),he!=="visible"&&N0(zc(he,"restoreClick"))}),ge.addEventListener("mnote:mindmap-shell:action",w=>{let A=w.detail,R=A?.actionId;if(R==="search"){if(typeof A?.value=="string"){p3(A.value);return}if(A?.value===!1){q=!1,D.dataset.lastSearchQuery="",D.dataset.searchStatus="closed",Ie();return}}R&&(b0(),A0(R,A))}),ge.addEventListener("mnote:mindmap-shell:zoom",w=>{let A=w.detail;aw(A?.percent)}),ge.addEventListener("mnote:mindmap-shell:minimap",w=>{let A=w.detail;O=typeof A?.open=="boolean"?A.open:!O,D.dataset.minimapOpen=O?"true":"false",Ie()}),ge.addEventListener("mnote:mindmap-shell:toolbar-overflow",w=>{let A=w.detail;W=typeof A?.moreOpen=="boolean"?A.moreOpen:!W,Ie()}),ge.addEventListener("mnote:mindmap-shell:panel",w=>{let A=w.detail,R=A?.event??"togglePanel";if(R==="restoreTrigger"){b=!0,y=!0,E=!1,Ie();return}if(R==="hideTrigger"){b=!1,y=!1,E=!0,Ie();return}if(R==="closeDrawer"){y=!1,E=!1,Ie();return}A?.panelId&&(A.panelId===x?y=!y:(x=A.panelId,y=!0),b=!0,E=!1,Ie())}),Q=()=>Fc(),document.addEventListener("fullscreenchange",Q),oe=()=>{v3("page_lifecycle")},window.addEventListener("pagehide",oe),window.addEventListener("beforeunload",oe),ge.addEventListener("input",w=>{if(!Wt)return;let A=w.target;A instanceof HTMLInputElement&&A.dataset.testid==="mindmap-command-text-input"&&(f=A.value)}),typeof ResizeObserver<"u"&&(ne=new ResizeObserver(w=>{let A=w[0]?.contentRect.width??null;A===null||Math.abs(A-(F??0))<1||(F=A,Wt||Ie())}),ne.observe(ye)),re=w=>{let A=w.target;if((!(A instanceof Node)||!ye.contains(A))&&nw(),Mi){if(A instanceof Node){let R=Xn.querySelector('[data-testid="mindmap-schema-context-menu"]');if(R instanceof HTMLElement&&R.contains(A))return}w0()}W&&(A instanceof Node&&er.contains(A)||b0())},le=w=>{if(w.key==="Escape"){if(Mi){w.preventDefault(),w0();return}if(E0()){w.preventDefault(),g3("exitFullscreen");return}W&&(w.preventDefault(),b0())}},Ce=w=>gw(w),te=w=>{w.detail?.type==="mindmap"&&Wb()},document.addEventListener("pointerdown",re),document.addEventListener("keydown",le),document.addEventListener("keydown",Ce,!0),window.addEventListener("mnote:page-width-preference-changed",te),ge.addEventListener("click",w=>{w.stopPropagation();let A=w.target;if(!(A instanceof HTMLElement))return;let R=A.closest("button");if(R instanceof HTMLButtonElement){if(!Wt){w.preventDefault();let P=R.dataset.mindmapContextActionId;if(P){if(R.disabled||R.dataset.disabled==="true")return;w0(),A0(P);return}if(R.closest('[data-testid="mindmap-rust-shell"]'))return;let Y=R.dataset.mindmapActionId;Y&&A0(Y);let K=R.dataset.mindmapSidebarPanelId;K&&(x=K,Ie());return}if(R.dataset.testid==="mindmap-command-update-text"){w.preventDefault();let P=ye.querySelector('[data-testid="mindmap-command-text-input"]'),Y=f??(P instanceof HTMLInputElement?P.value:s3(a));D.dataset.lastCommandText=Y,qs([{type:"updateText",mindmapId:et().mindmapId,nodeId:l??et().rootNodeId,text:Y}])}R.dataset.testid==="mindmap-command-add-child"&&(w.preventDefault(),s?.execCommand("INSERT_CHILD_NODE")),R.dataset.testid==="mindmap-command-add-sibling-after"&&(w.preventDefault(),s?.execCommand("INSERT_NODE")),R.dataset.testid==="mindmap-command-delete-node"&&(w.preventDefault(),s?.execCommand("REMOVE_NODE")),R.dataset.testid==="mindmap-toolbar-undo"&&(w.preventDefault(),s?.execCommand("BACK")),R.dataset.testid==="mindmap-toolbar-redo"&&(w.preventDefault(),s?.execCommand("FORWARD")),R.dataset.testid==="mindmap-toolbar-summary"&&(w.preventDefault(),s?.execCommand("ADD_GENERALIZATION")),R.dataset.testid==="mindmap-bottom-center-root"&&(w.preventDefault(),s?.instance.renderer?.setRootNodeCenter?.(),Hs(s?.getSnapshot())),R.dataset.testid==="mindmap-bottom-zoom-out"&&(w.preventDefault(),s?.instance.view?.narrow?.(),Hs(s?.getSnapshot())),R.dataset.testid==="mindmap-bottom-zoom-in"&&(w.preventDefault(),s?.instance.view?.enlarge?.(),Hs(s?.getSnapshot()))}}),ge.addEventListener("contextmenu",w=>{if(Wt)return;let A=w.target;if(A instanceof Element&&(A.closest(".smm-node")||A.closest('[class*="generalization_"]'))){w.preventDefault();return}w.preventDefault(),w.stopPropagation(),rw(w.clientX,w.clientY)},!0),y0.append(xt),Wt?(Yn.append(xt,Zn),D.append(Kn,Yn,Qn)):(Xn.append(er),Yn.append(y0,Xn),D.append(Yn)),ye.append(D,x0("nw"),x0("ne"),x0("sw"),x0("se")),ge.append(ye,ft),po(),k0("initial"),{dom:ge,update(w){if(w.type.name!==r.type.name)return!1;let A=d3(r);return r=w,r.attrs.mnoteBlockType!=="mindmap"?!1:(po(),d3(r)!==A&&k0("nodeViewUpdate"),!0)},stopEvent:()=>!0,ignoreMutation:()=>!0,destroy(){v3("node_view_destroy"),Ui=!0,wr!==null&&window.clearTimeout(wr),I!==null&&window.clearTimeout(I),ne?.disconnect(),re&&document.removeEventListener("pointerdown",re),le&&document.removeEventListener("keydown",le),Ce&&document.removeEventListener("keydown",Ce,!0),te&&window.removeEventListener("mnote:page-width-preference-changed",te),Q&&document.removeEventListener("fullscreenchange",Q),oe&&(window.removeEventListener("pagehide",oe),window.removeEventListener("beforeunload",oe)),Gt&&s?.instance.off?.("node_contextmenu",Gt);let{mindmapId:w}=et();Rc(w,null),s?.destroy(),v0(),s=null}}}}function Tq(){return({node:i})=>{let e=i,t=document.createElement("p"),r=()=>{let n=e.attrs.blockId;typeof n=="string"&&n.length>0?(t.dataset.blockId=n,t.id=n):(t.removeAttribute("data-block-id"),t.removeAttribute("id"))};return r(),{dom:t,contentDOM:t,update(n){return n.type.name!==e.type.name||n.attrs.mnoteBlockType==="mindmap"?!1:(e=n,r(),!0)}}}}var Nq=C3.extend({addAttributes(){return{...this.parent?.(),blockId:{default:null,parseHTML:i=>i.getAttribute("data-block-id"),renderHTML:i=>hq(i.blockId)},mnoteBlockType:{default:null,parseHTML:i=>i.getAttribute("data-mnote-block-type"),renderHTML:i=>dq(i)},mindmapId:{default:null,parseHTML:i=>i.getAttribute("data-mnote-mindmap-id"),renderHTML:()=>({})},rootNodeId:{default:null,parseHTML:i=>i.getAttribute("data-mnote-root-node-id"),renderHTML:()=>({})},projectionVersion:{default:null,parseHTML:i=>Number(i.getAttribute("data-mnote-projection-version")??1),renderHTML:()=>({})},mindmapWidth:{default:null,parseHTML:i=>fo(i.getAttribute("data-mnote-mindmap-width"),"width"),renderHTML:()=>({})},mindmapHeight:{default:null,parseHTML:i=>fo(i.getAttribute("data-mnote-mindmap-height"),"height"),renderHTML:()=>({})}}},addNodeView(){let i=Mq(this.editor),e=Tq();return({node:t,getPos:r})=>t.attrs.mnoteBlockType==="mindmap"?i({node:t,getPos:r}):e({node:t})}}),Eq={name:"paragraph",create:()=>Nq,commands:{set_paragraph:i=>i.chain().focus().setParagraph().run()},selection_keys:["paragraph"],selection_state:i=>({paragraph:i.isActive("paragraph")})};function Ese(){I3(Eq)}export{lq as createDefaultMindmapSidebarRuntimeState,fo as normalizeMindmapDimension,Ese as register_paragraph,dq as renderMindmapBlockAttributes,cq as resolveCurrentDocumentId}; /*! Bundled license information: @svgdotjs/svg.js/dist/svg.esm.js: diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/style.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/style.rs index 3017dde2..51223249 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/style.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/style.rs @@ -208,12 +208,32 @@ pub(crate) const SPIKE_STYLE: &str = r#" } .mnote-mindmap-placeholder { + position: relative; width: min(1280px, calc(100vw - 340px)); + min-width: min(900px, calc(100vw - 80px)); + max-width: var(--mnote-mindmap-block-max-width, none); margin: 10px 0; margin-left: 50%; transform: translateX(-50%); } +.mnote-mindmap-resize-preview { + position: absolute; + top: 0; + left: 50%; + z-index: 8; + box-sizing: border-box; + pointer-events: none; + transform: translateX(-50%); + border: 1px dashed rgba(37, 99, 235, 0.78); + border-radius: 8px; + background: rgba(37, 99, 235, 0.05); +} + +.mnote-mindmap-resize-preview[hidden] { + display: none; +} + .mnote-mindmap-editor-root { position: relative; overflow: hidden; @@ -231,6 +251,57 @@ pub(crate) const SPIKE_STYLE: &str = r#" flex-direction: column; } +.mnote-mindmap-placeholder[data-mnote-mindmap-resized="true"] .mnote-leptos-mindmap-shell { + min-height: 0; +} + +.mnote-mindmap-resize-handle { + position: absolute; + z-index: 9; + width: 12px; + height: 12px; + padding: 0; + border: 1px solid rgba(37, 99, 235, 0.72); + border-radius: 50%; + background: #ffffff; + box-shadow: 0 1px 4px rgba(15, 23, 42, 0.18); + opacity: 0; + transition: opacity 120ms ease, transform 120ms ease; +} + +.mnote-mindmap-editor-root:hover .mnote-mindmap-resize-handle, +.mnote-mindmap-placeholder[data-mnote-mindmap-resizing="true"] .mnote-mindmap-resize-handle { + opacity: 1; +} + +.mnote-mindmap-resize-handle:hover { + transform: scale(1.12); +} + +.mnote-mindmap-resize-handle-nw { + top: 6px; + left: 6px; + cursor: nwse-resize; +} + +.mnote-mindmap-resize-handle-ne { + top: 6px; + right: 6px; + cursor: nesw-resize; +} + +.mnote-mindmap-resize-handle-sw { + bottom: 6px; + left: 6px; + cursor: nesw-resize; +} + +.mnote-mindmap-resize-handle-se { + right: 6px; + bottom: 6px; + cursor: nwse-resize; +} + .mnote-mindmap-command-toolbar, .mnote-mindmap-bottom-bar { display: flex; diff --git a/scripts/TESTING_REFERENCE.md b/scripts/TESTING_REFERENCE.md index 7e3b3785..8ad29839 100644 --- a/scripts/TESTING_REFERENCE.md +++ b/scripts/TESTING_REFERENCE.md @@ -28,17 +28,20 @@ node scripts/task167-local-markdown-title-body-options-no-convex-smoke.js node scripts/task490-runtime-surfaces-smoke.js ``` -其中 `task490-runtime-surfaces-smoke.js` 是轻量浏览器 smoke,只验证页面设置、Page AI drawer、slash menu、block handle menu 能在当前 leptos-tiptap 文档页打开;它不要求真实模型返回,也不替代更重的页面设置、Hermes/Page AI 或编辑器菜单专项脚本。 +其中 `task490-runtime-surfaces-smoke.js` 是轻量浏览器 smoke,验证页面设置、Page AI drawer 打开/关闭、Page AI stop-run abort、slash menu、block handle menu 能在当前 leptos-tiptap 文档页工作;它使用 mock run 覆盖停止按钮,不要求真实模型返回,也不替代更重的页面设置、Hermes/Page AI 或编辑器菜单专项脚本。 ### 0.1 当前主链优先脚本 - 入口与认证:`task114-rust-web-gateway-entry-smoke.js`、`task159-auth-entry-smoke.js`、`task097-homepage-entry-smoke.js` -- Rust SSR 文档页 / Page Aggregate:local-first 默认优先 `task167-local-markdown-title-body-options-no-convex-smoke.js`;cloud/control-plane 文档可补跑 `task110-page-title-single-truth-smoke.js`、`task-page-aggregate-body-sync-smoke.js`、`task-page-aggregate-options-sync-smoke.js`、`task-page-aggregate-refresh-persistence-smoke.js` +- Rust SSR 文档页 / Page Aggregate:local-first 默认优先 `task167-local-markdown-title-body-options-no-convex-smoke.js`;Page Aggregate browser conversion / compat fallback 改动补跑 `task522-page-aggregate-compat-fallback-contract.js`;cloud/control-plane 文档可补跑 `task110-page-title-single-truth-smoke.js`、`task-page-aggregate-body-sync-smoke.js`、`task-page-aggregate-options-sync-smoke.js`、`task-page-aggregate-refresh-persistence-smoke.js` - leptos-tiptap runtime surface:`task490-runtime-surfaces-smoke.js`;需要验证保存回读可补跑 `task121-rust-web-editor-island-hydration-smoke.js`,但它仍使用 `/api/tree/commands create` 准备文档,不作为无 Convex 默认基线;需要验证浮层互斥和更多菜单状态时再跑 `task158-e30-menu-state-smoke.js` -- local-first 本地工作区:`task164-desktop-hot-local-folder-main-entry-smoke.js`、`task166-local-first-managed-workspace-no-convex-smoke.js`、`task167-local-markdown-title-body-options-no-convex-smoke.js`、`task436-local-markdown-open-document-external-change-smoke.js`、`task443-local-markdown-asset-upload-smoke.js`、`task451-local-markdown-conflict-resolution-ui-smoke.js`、`task452-local-search-index-browser-smoke.js`、`task453-local-folder-page-ai-changed-files-smoke.js` +- local-first 本地工作区:`task164-desktop-hot-local-folder-main-entry-smoke.js`、`task166-local-first-managed-workspace-no-convex-smoke.js`、`task167-local-markdown-title-body-options-no-convex-smoke.js`、`task436-local-markdown-open-document-external-change-smoke.js`、`task443-local-markdown-asset-upload-smoke.js`、`task451-local-markdown-conflict-resolution-ui-smoke.js`、`task452-local-search-index-browser-smoke.js`、`task453-local-folder-page-ai-changed-files-smoke.js`;WorkspacePath / ObjectIdentity runtime 消费统一改动补跑 `task524-workspace-object-identity-matrix-smoke.js` +- local-folder OCR:`task526-local-folder-ocr-api-smoke.js` 覆盖 mock OCR API、sidecar 落盘、jobs/status/read、`includeOcr=true` 搜索 owner page、显式插入 OCR 链接和 OCR sidecar Markdown resource tab 打开;它不代表真实 MinerU token/upload/zip runtime、前端 OCR 入口或全局 OCR 任务栏已完成。 - local Markdown conflict regression:`task510-local-markdown-conflict-regression-group.js` 串联真实冲突、连续上传、新建页面、外部恢复、多 tab CAS 与上传 409 孤儿策略;可用 `MNOTE_CONFLICT_REGRESSION_TASKS=a.js,b.js` 做定点子集。 - tree realtime / live cache:`task446-tree-rename-dual-browser-live-smoke.js`、`task447-tree-move-order-dual-browser-live-smoke.js`、`task448-tree-resync-recovery-dual-browser-smoke.js`、`task449-tree-sse-reconnect-snapshot-recovery-smoke.js` -- 资源对象与 mindmap:`task455-local-folder-mindmap-clean-smoke.js`、`task456-resource-object-shell-sync-smoke.js`、`task166-mindmap-phase6-block-smoke.js`、`task167-mindmap-kmind-parity-smoke.js`、`task168-mindmap-put-validator-smoke.js` +- 资源对象与 mindmap:`task455-local-folder-mindmap-clean-smoke.js`、`task456-resource-object-shell-sync-smoke.js`、`task166-mindmap-phase6-block-smoke.js`、`task167-mindmap-kmind-parity-smoke.js`、`task168-mindmap-put-validator-smoke.js`;Page AI mindmap skill / 资源生成改动补跑 `task503-mindmap-skill-capability-smoke.js`,真实 mindmap resource tab / Page AI target 改动补跑 `task525-page-ai-mindmap-resource-target-smoke.js` +- Page AI / agent history / ChatOnly:`task502-page-ai-agent-selector-context-smoke.js` 覆盖 Page AI agent/context/target picker、skills source 和 run payload;raw local resource target 改动补跑 `task520-page-ai-raw-resource-target-smoke.js`;`task504-page-ai-history-agent-filter-smoke.js` 覆盖 Page AI 历史按 agent 过滤;ChatOnly / provider session 绑定改动优先跑 `task512-chatonly-doubao-sync-smoke.js`,跨 provider 同步补跑 `task513-chatonly-provider-sync-smoke.js` +- Dev hot / OnlyOffice live bridge:Sidebar dev hot reload 入口改动补跑 `task514-sidebar-dev-hot-reload-gating-smoke.js`;OnlyOffice live bridge session / scope / HTTP 工具边界改动补跑 `task515-onlyoffice-live-scope-http-smoke.js`;bridge session/token/queue/current/close 和 `docKey/pageOrigin` 元数据改动补跑 `task516-onlyoffice-bridge-multisession-browser-smoke.js`;bridge plugin index / `Asc.plugin` direct loop / plugin 元数据透传改动补跑 `task517-onlyoffice-bridge-plugin-direct-smoke.js`;真实 ONLYOFFICE iframe / DocumentServer session、同文档双 tab、resource scope 和非 dry-run 写入落点改动补跑 `task518-onlyoffice-real-iframe-session-scope-smoke.js`;Page AI 真实 UI 选择 Office target 并冻结 live bridge session 改动补跑 `task523-page-ai-onlyoffice-real-target-session-smoke.js` - local resource lifecycle API:`task437-local-folder-asset-trash-lifecycle-smoke.js`,现在只验证 `local-file:*` delete / restore / purge,不再依赖普通 `.txt` 是否出现在 UI 文件树。 ### 0.2 需要退役或拆分的历史脚本 @@ -182,7 +185,7 @@ node scripts/task097-homepage-entry-smoke.js - local-first:优先使用 `task164-desktop-hot-local-folder-main-entry-smoke.js`、`task166-local-first-managed-workspace-no-convex-smoke.js`、`task167-local-markdown-title-body-options-no-convex-smoke.js`、`task455-local-folder-mindmap-clean-smoke.js` - 页面设置:`task160`、`task164-page-options-visible-effect-smoke.js` - 双栏:`task165` -- AI:优先使用 `task-hermes-page-ai-retirement-guard.js`、`task-page-block-ai-tools-smoke.js` 和当前 Hermes 页面 AI smoke;`task155`、`task156`、`task161` 等旧 `/api/ai-agent/run` smoke 只保留在本机 gitignored `recycle/scripts/retired-ai-agent-run-smokes/` 做历史对照 +- AI:优先使用 `task-hermes-page-ai-retirement-guard.js`、`task-page-block-ai-tools-smoke.js` 和当前 Hermes 页面 AI smoke;Page AI history / skills / ChatOnly 相关改动补跑 `task503-mindmap-skill-capability-smoke.js`、`task504-page-ai-history-agent-filter-smoke.js`、`task512-chatonly-doubao-sync-smoke.js`、`task513-chatonly-provider-sync-smoke.js`;OnlyOffice live bridge 改动补跑 `task515-onlyoffice-live-scope-http-smoke.js`、`task516-onlyoffice-bridge-multisession-browser-smoke.js`、`task517-onlyoffice-bridge-plugin-direct-smoke.js`、`task518-onlyoffice-real-iframe-session-scope-smoke.js`,其中 `task516/517` 覆盖 bridge session lifecycle 与 `docKey/pageOrigin` 元数据;Page AI 真实 target picker / Office live session 改动补跑 `task523-page-ai-onlyoffice-real-target-session-smoke.js`;`task155`、`task156`、`task161` 等旧 `/api/ai-agent/run` smoke 只保留在本机 gitignored `recycle/scripts/retired-ai-agent-run-smokes/` 做历史对照 原则: diff --git a/scripts/reasonix-acp-wrapper.mjs b/scripts/reasonix-acp-wrapper.mjs index 4bcfe09c..eac5c019 100644 --- a/scripts/reasonix-acp-wrapper.mjs +++ b/scripts/reasonix-acp-wrapper.mjs @@ -58,6 +58,37 @@ function stableIdPart(value, fallback) { return text || String(fallback || 'unknown'); } +function stableJson(value) { + try { + return JSON.stringify(value || null, null, 2); + } catch { + return 'null'; + } +} + +function buildMnotePromptText(userPrompt, context = {}) { + const capabilities = context.mnoteCapabilities || {}; + const envelope = capabilities.agentRunEnvelope || null; + if (!envelope || capabilities.attachMnoteCapabilities !== true) { + return userPrompt; + } + const primaryPath = envelope.primaryTarget?.workspacePath?.relativePath + || envelope.primaryTarget?.relativePath + || ''; + const allowedRoots = envelope.allowedRoots || capabilities.allowedRoots || []; + const guidance = [ + '', + 'MNote has attached a local-first agent run envelope.', + 'Use your native file tools to read and edit real files inside the current working directory and allowed roots.', + 'Do not use MNote doc/page write tools for ordinary local Markdown edits.', + primaryPath ? `Primary target relativePath: ${primaryPath}` : '', + `Allowed roots: ${stableJson(allowedRoots)}`, + `Agent run envelope: ${stableJson(envelope)}`, + '', + ].filter(Boolean).join('\n'); + return `${guidance}\n\n${userPrompt}`; +} + function buildMnoteToolPayload(toolName, rawArgs = {}, context = {}) { const { actorId, @@ -183,6 +214,35 @@ if (process.env.MNOTE_REASONIX_ACP_SELFTEST === '1') { if (contextualPayload.args.aiAccessScope?.permissionLevel !== 'read_write') { throw new Error('selftest expected aiAccessScope inherited from mnoteCapabilities'); } + const promptWithEnvelope = buildMnotePromptText('请把标题改成测试标题', { + mnoteCapabilities: { + attachMnoteCapabilities: true, + agentRunEnvelope: { + schema: 'mnote.agent_run_envelope.v1', + sourceKind: 'local_folder', + primaryTarget: { + workspacePath: { + relativePath: 'docs/current.md', + rootUri: 'file:///tmp/mnote-local', + }, + }, + allowedRoots: [{ rootUri: 'file:///tmp/mnote-local', permission: 'write' }], + resultPolicy: { + receiptSchema: 'mnote.agent_run_receipt.v1', + changedFiles: 'required', + }, + }, + }, + }); + if (!promptWithEnvelope.includes('mnote.agent_run_envelope.v1')) { + throw new Error('selftest expected prompt to include agentRunEnvelope schema'); + } + if (!promptWithEnvelope.includes('docs/current.md')) { + throw new Error('selftest expected prompt to include primary target relativePath'); + } + if (!promptWithEnvelope.includes('native file tools')) { + throw new Error('selftest expected prompt to instruct native file tools'); + } process.stderr.write('[reasonix-acp-mnote] selftest ok\n'); process.exit(0); } @@ -575,7 +635,7 @@ onRequest('session/prompt', async (params) => { const mnoteCapabilities = params.mnoteCapabilities || {}; const useMnoteTools = mnoteCapabilities.attachMnoteCapabilities === true; const loop = useMnoteTools ? session.mnoteLoop : session.chatLoop; - const promptText = text; + const promptText = buildMnotePromptText(text, toolContext); let stopReason = 'end_turn'; let hasAssistantOutput = false; let hasToolCall = false; diff --git a/scripts/task455-local-folder-mindmap-clean-smoke.js b/scripts/task455-local-folder-mindmap-clean-smoke.js index f271b93e..909b256d 100644 --- a/scripts/task455-local-folder-mindmap-clean-smoke.js +++ b/scripts/task455-local-folder-mindmap-clean-smoke.js @@ -78,6 +78,32 @@ async function insertMindmapThroughSlash(page) { }); } +async function assertMindmapStyleDrawerClosedByDefault(page) { + await page.locator('[data-testid="mindmap-rust-shell"]').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + const state = await page.evaluate(() => { + const shell = document.querySelector('[data-testid="mindmap-rust-shell"]'); + const sidebar = document.querySelector('[data-testid="mindmap-schema-sidebar"]'); + const drawer = document.querySelector('[data-testid="mindmap-schema-sidebar-drawer"]'); + return { + panelOpen: shell instanceof HTMLElement ? shell.getAttribute("data-sidebar-panel-open") || "" : "", + activePanel: shell instanceof HTMLElement ? shell.getAttribute("data-sidebar-active-panel") || "" : "", + sidebarPresent: sidebar instanceof HTMLElement, + sidebarPanelOpen: sidebar instanceof HTMLElement ? sidebar.getAttribute("data-panel-open") || "" : "", + drawerVisible: drawer instanceof HTMLElement && drawer.getClientRects().length > 0, + bodyText: document.body?.innerText || "", + }; + }); + assert.equal(state.panelOpen, "false", `节点样式抽屉不应默认打开: ${JSON.stringify(state)}`); + if (state.sidebarPanelOpen) { + assert.equal(state.sidebarPanelOpen, "false", `sidebar panel 状态应与 shell 保持默认收起: ${JSON.stringify(state)}`); + } + assert.equal(state.drawerVisible, false, `节点样式抽屉不应默认渲染遮挡画布: ${JSON.stringify(state)}`); + return state; +} + async function assertSlashMenuAnchorsAfterMindmap(page) { const editor = page.locator('.document-pane[data-pane-role="primary"] .editor-surface .ProseMirror[contenteditable="true"]').first(); await editor.click({ timeout: UI_TIMEOUT_MS }); @@ -122,6 +148,134 @@ async function assertSlashMenuAnchorsAfterMindmap(page) { return state; } +async function resizeMindmapThroughCornerHandle(page) { + await page.locator('[data-testid="mindmap-resize-handle-nw"]').first().waitFor({ + state: "attached", + timeout: UI_TIMEOUT_MS, + }); + const before = await page.evaluate(() => { + const placeholder = document.querySelector('[data-testid="mnote-mindmap-placeholder"]'); + const root = document.querySelector('[data-testid="mnote-mindmap-editor-root"]'); + const editor = document.querySelector('.document-pane[data-pane-role="primary"] .editor-surface .ProseMirror'); + const handles = Array.from(document.querySelectorAll('[data-mnote-mindmap-resize-handle]')) + .map((handle) => handle.getAttribute("data-mnote-mindmap-resize-handle") || "") + .sort(); + const rect = placeholder?.getBoundingClientRect(); + const editorRect = editor?.getBoundingClientRect(); + return { + handles, + rect: rect ? { width: Math.round(rect.width), height: Math.round(rect.height) } : null, + centerDelta: rect && editorRect ? Math.round((rect.left + rect.width / 2) - (editorRect.left + editorRect.width / 2)) : null, + cssMaxWidth: root instanceof HTMLElement ? getComputedStyle(root).getPropertyValue("--mnote-mindmap-block-max-width").trim() : "", + htmlCssMaxWidth: getComputedStyle(document.documentElement).getPropertyValue("--mnote-mindmap-block-max-width").trim(), + }; + }); + assert.deepEqual(before.handles, ["ne", "nw", "se", "sw"], `mindmap 应渲染四角 resize handle: ${JSON.stringify(before)}`); + assert(before.rect, `mindmap resize 前应能读取占位块尺寸: ${JSON.stringify(before)}`); + assert(Math.abs(before.centerDelta) <= 2, `初始 mindmap 应以正文列中心对齐: ${JSON.stringify(before)}`); + + await page.waitForFunction(() => { + const registry = window.__MNOTE_LEPTOS_MINDMAP_BRIDGES__ || {}; + return Object.values(registry).some((bridge) => typeof bridge?.instance?.resize === "function"); + }, null, { timeout: UI_TIMEOUT_MS }); + await page.evaluate(() => { + window.__MNOTE_TEST_MINDMAP_RESIZE_COUNT = 0; + const registry = window.__MNOTE_LEPTOS_MINDMAP_BRIDGES__ || {}; + Object.values(registry).forEach((bridge) => { + const instance = bridge?.instance; + if (!instance || typeof instance.resize !== "function" || instance.resize.__mnoteResizeCounterPatched) return; + const original = instance.resize.bind(instance); + const patched = function patchedMindmapResize() { + window.__MNOTE_TEST_MINDMAP_RESIZE_COUNT = Number(window.__MNOTE_TEST_MINDMAP_RESIZE_COUNT || 0) + 1; + return original(); + }; + patched.__mnoteResizeCounterPatched = true; + instance.resize = patched; + }); + }); + + const handleBox = await page.locator('[data-testid="mindmap-resize-handle-nw"]').first().boundingBox(); + assert(handleBox, "左上角 resize handle 应有可交互位置"); + await page.mouse.move(handleBox.x + handleBox.width / 2, handleBox.y + handleBox.height / 2); + await page.mouse.down(); + await page.mouse.move(handleBox.x + 160, handleBox.y + 110, { steps: 8 }); + await page.mouse.up(); + + await page.waitForFunction( + ({ previousWidth, previousHeight }) => { + const placeholder = document.querySelector('[data-testid="mnote-mindmap-placeholder"]'); + const scene = document.querySelector('[data-testid="leptos-mindmap-island"]'); + if (!(placeholder instanceof HTMLElement) || !(scene instanceof HTMLElement)) return false; + const width = Number(placeholder.dataset.mnoteMindmapWidth || 0); + const height = Number(placeholder.dataset.mnoteMindmapHeight || 0); + return width >= 320 + && height >= 240 + && width < previousWidth + && height < previousHeight + && scene.dataset.mnoteMindmapHeight === String(height); + }, + { previousWidth: before.rect.width, previousHeight: before.rect.height }, + { timeout: UI_TIMEOUT_MS }, + ); + + const resized = await page.evaluate(() => { + const placeholder = document.querySelector('[data-testid="mnote-mindmap-placeholder"]'); + const scene = document.querySelector('[data-testid="leptos-mindmap-island"]'); + const editor = document.querySelector('.document-pane[data-pane-role="primary"] .editor-surface .ProseMirror'); + const rect = placeholder?.getBoundingClientRect(); + const editorRect = editor?.getBoundingClientRect(); + return { + width: placeholder instanceof HTMLElement ? Number(placeholder.dataset.mnoteMindmapWidth || 0) : 0, + height: placeholder instanceof HTMLElement ? Number(placeholder.dataset.mnoteMindmapHeight || 0) : 0, + sceneHeight: scene instanceof HTMLElement ? Number(scene.dataset.mnoteMindmapHeight || 0) : 0, + rect: rect ? { width: Math.round(rect.width), height: Math.round(rect.height) } : null, + centerDelta: rect && editorRect ? Math.round((rect.left + rect.width / 2) - (editorRect.left + editorRect.width / 2)) : null, + cssMaxWidth: getComputedStyle(document.documentElement).getPropertyValue("--mnote-mindmap-block-max-width").trim(), + resizeCallCount: Number(window.__MNOTE_TEST_MINDMAP_RESIZE_COUNT || 0), + }; + }); + assert(Math.abs(resized.centerDelta) <= 2, `resize 后 mindmap 仍应以正文列中心对齐: ${JSON.stringify(resized)}`); + assert(resized.resizeCallCount <= 3, `拖动过程中不应连续触发 simple-mind-map resize 重绘: ${JSON.stringify(resized)}`); + + const afterGlobalWidthPreference = await page.evaluate(() => { + const setMindmapWidthMax = (value) => { + document.documentElement.style.setProperty("--mnote-mindmap-block-max-width", value); + document.querySelector('.document-shell')?.style.setProperty("--mnote-mindmap-block-max-width", value); + document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]')?.style.setProperty("--mnote-mindmap-block-max-width", value); + window.dispatchEvent(new CustomEvent("mnote:page-width-preference-changed", { detail: { type: "mindmap" } })); + }; + setMindmapWidthMax("720px"); + return true; + }); + assert.equal(afterGlobalWidthPreference, true); + await page.waitForFunction(() => { + const placeholder = document.querySelector('[data-testid="mnote-mindmap-placeholder"]'); + const rect = placeholder?.getBoundingClientRect(); + return placeholder instanceof HTMLElement + && !placeholder.dataset.mnoteMindmapWidth + && rect + && Math.round(rect.width) >= 900 + && Math.round(rect.width) <= 920; + }, null, { timeout: UI_TIMEOUT_MS }); + + const globalWidthState = await page.evaluate(() => { + const placeholder = document.querySelector('[data-testid="mnote-mindmap-placeholder"]'); + const editor = document.querySelector('.document-pane[data-pane-role="primary"] .editor-surface .ProseMirror'); + const rect = placeholder?.getBoundingClientRect(); + const editorRect = editor?.getBoundingClientRect(); + return { + widthAttr: placeholder instanceof HTMLElement ? placeholder.dataset.mnoteMindmapWidth || "" : "", + heightAttr: placeholder instanceof HTMLElement ? placeholder.dataset.mnoteMindmapHeight || "" : "", + rect: rect ? { width: Math.round(rect.width), height: Math.round(rect.height) } : null, + centerDelta: rect && editorRect ? Math.round((rect.left + rect.width / 2) - (editorRect.left + editorRect.width / 2)) : null, + cssMaxWidth: getComputedStyle(document.documentElement).getPropertyValue("--mnote-mindmap-block-max-width").trim(), + }; + }); + assert.equal(globalWidthState.widthAttr, "", `全局 Mindmap 宽度设置后应清除本块手动宽度: ${JSON.stringify(globalWidthState)}`); + assert(Math.abs(globalWidthState.centerDelta) <= 2, `全局 Mindmap 宽度设置后仍应居中: ${JSON.stringify(globalWidthState)}`); + return { ...resized, globalWidthState }; +} + async function readState(page) { return page.evaluate(() => { const editorRoot = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]'); @@ -184,7 +338,9 @@ async function waitForMindmapId(page) { await page.waitForFunction( () => { const root = document.querySelector('[data-testid="mnote-mindmap-editor-root"]'); - return root instanceof HTMLElement && /^思维导图\d{6}\.json$/.test(root.dataset.mnoteMindmapId || ""); + const mindmapId = root instanceof HTMLElement ? String(root.dataset.mnoteMindmapId || "") : ""; + return /^思维导图\d{6}\.json$/.test(mindmapId) + || /^mindmap[-_][^/\\]+(?:\.json)?$/.test(mindmapId); }, null, { timeout: UI_TIMEOUT_MS }, @@ -193,6 +349,11 @@ async function waitForMindmapId(page) { return state.mindmapId; } +function localMindmapFileName(mindmapId) { + const value = String(mindmapId || "").trim(); + return value.toLowerCase().endsWith(".json") ? value : `${value}.json`; +} + function rowMatchesMindmap(row, mindmapId) { const assetId = String(row && row.assetId || ""); const title = String(row && row.title || ""); @@ -312,6 +473,7 @@ async function main() { markdownMissingMindmapReferenceAfterInsert: false, refreshSkippedBecauseMarkdownNotSaved: false, commandResponseSummary: null, + resizeAfterInsert: null, }; try { @@ -319,13 +481,16 @@ async function main() { result.screenshots.push(await screenshot(page, "01-open-clean-page")); await insertMindmapThroughSlash(page); result.mindmapId = await waitForMindmapId(page); + const mindmapFileName = localMindmapFileName(result.mindmapId); result.screenshots.push(await screenshot(page, "02-after-insert-mindmap")); + result.defaultStyleDrawer = await assertMindmapStyleDrawerClosedByDefault(page); + result.resizeAfterInsert = await resizeMindmapThroughCornerHandle(page); await page.waitForFunction( ({ expected }) => { const tree = document.getElementById("sidebar-file-tree-root"); return (tree?.textContent || "").includes(expected); }, - { expected: result.mindmapId }, + { expected: mindmapFileName }, { timeout: UI_TIMEOUT_MS }, ); result.saveAfterInsert = await waitForStableEditorSave(page, networkRecords, "after-insert"); @@ -333,12 +498,12 @@ async function main() { result.diskAfterInsert = fs.readdirSync(pageDir).sort(); assert(result.diskAfterInsert.includes("CleanPage.md"), `页面 Markdown 应存在: ${result.diskAfterInsert.join(",")}`); - assert(result.diskAfterInsert.includes(result.mindmapId), `mindmap 应直接出现在页面文件夹下: ${result.diskAfterInsert.join(",")}`); - assert(!fs.existsSync(path.join(root, result.mindmapId)), "root 同级不应残留 mindmap 文件"); - assert(!fs.existsSync(path.join(pageDir, "assets", result.mindmapId)), "assets 下不应残留 mindmap 文件"); + assert(result.diskAfterInsert.includes(mindmapFileName), `mindmap 应直接出现在页面文件夹下: ${result.diskAfterInsert.join(",")}`); + assert(!fs.existsSync(path.join(root, mindmapFileName)), "root 同级不应残留 mindmap 文件"); + assert(!fs.existsSync(path.join(pageDir, "assets", mindmapFileName)), "assets 下不应残留 mindmap 文件"); result.markdown = fs.readFileSync(markdownPath, "utf8"); - result.markdownMissingMindmapReferenceAfterInsert = !result.markdown.includes(`](${result.mindmapId})`); + result.markdownMissingMindmapReferenceAfterInsert = !result.markdown.includes(`](${mindmapFileName})`); result.samples = await sampleFileTree(page, result.mindmapId, 4_000); result.commandResponseSummary = await postMindmapCommand(page, documentId, result.mindmapId); @@ -355,7 +520,7 @@ async function main() { timeout: UI_TIMEOUT_MS, }); const afterRefresh = await readState(page); - assert.equal(afterRefresh.mindmapId, result.mindmapId, `刷新后 mindmapId 应保持不变: ${JSON.stringify(afterRefresh)}`); + assert.equal(localMindmapFileName(afterRefresh.mindmapId), mindmapFileName, `刷新后 mindmapId 应保持不变: ${JSON.stringify(afterRefresh)}`); assert( afterRefresh.mindmapRows.filter((row) => rowMatchesMindmap(row, result.mindmapId)).length === 1, `刷新后文件树应只有本轮 mindmap 一行: ${JSON.stringify(afterRefresh.mindmapRows)}`, diff --git a/scripts/task463-onlyoffice-resolver-smoke.js b/scripts/task463-onlyoffice-resolver-smoke.js index 95fbe053..ca18d2bc 100644 --- a/scripts/task463-onlyoffice-resolver-smoke.js +++ b/scripts/task463-onlyoffice-resolver-smoke.js @@ -50,6 +50,7 @@ async function uploadLocalAsset(page, root, documentId, fileName, mimeType, byte const form = new FormData(); form.append("rootUri", rootUri); form.append("documentId", documentId); + form.append("uploadIntent", "editor.markdown.attach"); form.append("kind", kind); form.append("file", new File([new Uint8Array(bytes)], fileName, { type: mimeType })); const response = await fetch("/api/local-folder/assets/upload", { method: "POST", body: form }); @@ -137,8 +138,8 @@ async function main() { timeout: UI_TIMEOUT_MS, }); - // ======== Test 1: docx opens in main editor tab with /onlyoffice iframe ======== - console.log("Test 1: docx opens in main editor tab with /onlyoffice iframe"); + // ======== Test 1: docx opens in main editor tab with Office reader iframe ======== + console.log("Test 1: docx opens in main editor tab with Office reader iframe"); await page.evaluate(({ asset, documentId }) => { window.dispatchEvent(new CustomEvent("tree.asset.open", { detail: { @@ -171,16 +172,20 @@ async function main() { // docx should have badge kind "word" assert.equal(officeTabInfo.badgeKind, "word", `docx should have badgeKind 'word', got '${officeTabInfo.badgeKind}'`); assert.ok(officeTabInfo.iframeExists, "Office tab should have an iframe"); - assert.ok(officeTabInfo.iframeSrc.includes("/onlyoffice"), `iframe src should include /onlyoffice: ${officeTabInfo.iframeSrc}`); // Parse iframe URL and verify required params const iframeUrl = new URL(officeTabInfo.iframeSrc, BASE_URL); - assert.equal(iframeUrl.pathname, "/onlyoffice", `iframe pathname should be /onlyoffice: ${iframeUrl.pathname}`); + assert.ok( + iframeUrl.pathname === "/office-preview" || iframeUrl.pathname === "/onlyoffice", + `iframe pathname should be /office-preview or /onlyoffice: ${iframeUrl.pathname}`, + ); // Check that assetId is in the URL (either in query params or encoded) const iframeAssetId = iframeUrl.searchParams.get("assetId") || ""; assert.ok(iframeAssetId, "iframe URL should carry assetId param"); - assert.ok(iframeUrl.searchParams.has("mode"), "iframe URL should carry mode param"); + if (iframeUrl.pathname === "/onlyoffice") { + assert.equal(iframeUrl.searchParams.get("mode"), "view", "default /onlyoffice open should use view mode"); + } assert.ok(iframeUrl.searchParams.has("fileUrl"), "iframe URL should carry fileUrl param"); // The fileUrl for local-folder should point to /api/local-folder/files/open @@ -304,7 +309,7 @@ async function main() { await page.waitForTimeout(300); // ======== Test 4: new-window defaults to view mode ======== - console.log("Test 4: new-window opens /onlyoffice with view mode"); + console.log("Test 4: new-window opens Office reader in view mode"); const [officePopup] = await Promise.all([ page.waitForEvent("popup", { timeout: UI_TIMEOUT_MS }).catch(() => null), page.evaluate(({ asset, documentId }) => { @@ -324,11 +329,16 @@ async function main() { await officePopup.waitForLoadState("domcontentloaded", { timeout: UI_TIMEOUT_MS }).catch(() => undefined); const popupUrl = new URL(officePopup.url()); console.log(` New-window URL: ${popupUrl.toString()}`); - assert.equal(popupUrl.pathname, "/onlyoffice", `new-window pathname should be /onlyoffice: ${popupUrl.pathname}`); + assert.ok( + popupUrl.pathname === "/office-preview" || popupUrl.pathname === "/onlyoffice", + `new-window pathname should be /office-preview or /onlyoffice: ${popupUrl.pathname}`, + ); // new-window 是浏览器目标,不代表编辑权限;默认仍应只读 const popupMode = popupUrl.searchParams.get("mode") || ""; - assert.equal(popupMode, "view", `new-window mode should be 'view', got '${popupMode}'`); + if (popupUrl.pathname === "/onlyoffice") { + assert.equal(popupMode, "view", `new-window mode should be 'view', got '${popupMode}'`); + } // Check assetId is present const popupAssetId = popupUrl.searchParams.get("assetId") || ""; @@ -387,21 +397,17 @@ async function main() { onlyofficeUrl.searchParams.set("assetId", "test-asset-id"); onlyofficeUrl.searchParams.set("mode", "edit"); - const response = await page.goto(onlyofficeUrl.toString(), { - waitUntil: "domcontentloaded", - timeout: UI_TIMEOUT_MS, - }); - - // Verify the page rendered - const pageContent = await page.evaluate(() => { - return { - title: document.title, - hasFrameContainer: !!document.getElementById("onlyoffice-frame"), - hasErrorContainer: !!document.getElementById("onlyoffice-error"), - hasScript: typeof window.__MNOTE_ONLYOFFICE_READY__ !== "undefined", - initialConfig: typeof window.initial !== "undefined", - }; - }); + const response = await context.request.get(onlyofficeUrl.toString(), { timeout: UI_TIMEOUT_MS }); + assert.equal(response.status(), 200, `/onlyoffice should respond 200, got ${response.status()}`); + const onlyofficeHtml = await response.text(); + + // Verify the page rendered without executing DocEditor boot against a fake file path. + const pageContent = { + hasFrameContainer: onlyofficeHtml.includes('id="onlyoffice-frame"'), + hasErrorContainer: onlyofficeHtml.includes('id="onlyoffice-error"'), + hasScript: onlyofficeHtml.includes("window.__MNOTE_ONLYOFFICE_READY__"), + initialConfig: onlyofficeHtml.includes("const initial ="), + }; console.log(` /onlyoffice page: ${JSON.stringify(pageContent)}`); assert.ok(pageContent.hasFrameContainer, "/onlyoffice should have #onlyoffice-frame container"); @@ -409,17 +415,11 @@ async function main() { assert.ok(pageContent.hasScript, "/onlyoffice should have runtime script"); // Verify the config has correct document URL and callback URL source - const scriptContent = await page.evaluate(() => { - const scripts = document.querySelectorAll("script"); - const relevant = Array.from(scripts).filter(s => s.textContent && s.textContent.includes("buildCallbackUrl")); - const text = relevant.length > 0 ? relevant[0].textContent : ""; - return { - hasCallbackUrlBuilder: text.includes("buildCallbackUrl"), - hasResolveDocumentUrl: text.includes("resolveDocumentUrl"), - hasProxyLogic: text.includes("/api/onlyoffice/proxy"), - snippet: text.substring(0, 200), - }; - }); + const scriptContent = { + hasCallbackUrlBuilder: onlyofficeHtml.includes("buildCallbackUrl"), + hasResolveDocumentUrl: onlyofficeHtml.includes("resolveDocumentUrl"), + hasProxyLogic: onlyofficeHtml.includes("/api/onlyoffice/proxy"), + }; console.log(` Script: hasCallbackUrl=${scriptContent.hasCallbackUrlBuilder}, hasResolveDocumentUrl=${scriptContent.hasResolveDocumentUrl}`); assert.ok(scriptContent.hasCallbackUrlBuilder, "OnlyOffice page should define buildCallbackUrl"); diff --git a/scripts/task490-runtime-surfaces-smoke.js b/scripts/task490-runtime-surfaces-smoke.js index 1f6122ae..bf596e2b 100644 --- a/scripts/task490-runtime-surfaces-smoke.js +++ b/scripts/task490-runtime-surfaces-smoke.js @@ -137,6 +137,10 @@ async function main() { const screenshots = {}; const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task490-")); const relativePath = "RuntimeSurfaces.md"; + const capturedPageAi = { + runs: [], + aborts: [], + }; writeWorkspaceManifest(root, "mnote-e2e"); fs.writeFileSync( path.join(root, relativePath), @@ -146,6 +150,106 @@ async function main() { let caughtError = null; try { + await page.route("**/api/hermes/client/gateway/health**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + gateway: { ok: true, status: "mocked" }, + profile: { name: "reasonix", modelConfigured: true, apiKeyConfigured: true }, + suggestions: [], + }), + }); + }); + await page.route("**/api/hermes/client/tools**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, tools: [] }), + }); + }); + await page.route("**/api/hermes/client/profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + active: "mnoteai", + profiles: [{ name: "mnoteai", label: "MNote AI", modelConfigured: true, apiKeyConfigured: true }], + }), + }); + }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + agentId: "reasonix", + profiles: [], + }), + }); + }); + await page.route("**/api/hermes/client/skills**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, categories: [], archived: [] }), + }); + }); + await page.route("**/api/hermes/client/sessions", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + sessionId: "mnote_task490", + title: "task490", + traceId: "trace_task490", + persistence: "local_ai_session_jsonl", + sessionStorage: "local_private", + }), + }); + }); + await page.route("**/api/hermes/client/runs", async (route) => { + capturedPageAi.runs.push(route.request().postData() || ""); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + sessionId: "mnote_task490", + runId: "run_task490_stop", + upstream: { run_id: "run_task490_stop", trace_id: "trace_task490_stop" }, + traceId: "trace_task490_stop", + }), + }); + }); + await page.route("**/api/hermes/client/events/run_task490_stop", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "text/event-stream; charset=utf-8" }, + body: `data: ${JSON.stringify({ event: "message.delta", run_id: "run_task490_stop", delta: "Task490 streaming" })}\n\n`, + }); + }); + await page.route("**/api/hermes/client/runs/run_task490_stop/abort", async (route) => { + capturedPageAi.aborts.push(route.request().postData() || ""); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + status: "aborted", + runtime: { runId: "run_task490_stop", status: "aborted", queueLength: 0 }, + events: [ + { event: "abort.started", runId: "run_task490_stop" }, + { event: "abort.completed", runId: "run_task490_stop" }, + ], + }), + }); + }); + await ensureAuthenticated(page, context.request); const url = documentUrl(BASE_URL, root, relativePath); @@ -153,7 +257,6 @@ async function main() { assert(response, "文档页没有返回响应"); assert(response.status() === 200, `文档页状态码异常: ${response.status()}`); const editor = await waitForRuntimeIsland(page, UI_TIMEOUT_MS); - await setBlockHandleFixture(page, UI_TIMEOUT_MS); const moreButton = page.locator('[data-testid="wolai-page-settings-trigger"]').first(); await moreButton.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); @@ -175,7 +278,58 @@ async function main() { assert(await page.locator("[data-page-ai-input]").first().isVisible(), "Page AI drawer 必须显示输入框"); screenshots.pageAi = await saveScreenshot(page, "02-page-ai"); await closePageAiIfOpen(page); + await page.waitForFunction( + () => { + const drawer = document.querySelector('[data-testid="wolai-page-ai-drawer"]'); + const trigger = document.querySelector('[data-testid="wolai-floating-ai"]'); + return drawer instanceof HTMLElement + && drawer.hidden === true + && trigger instanceof HTMLElement + && trigger.getAttribute("data-state") === "closed" + && trigger.getAttribute("aria-expanded") === "false"; + }, + null, + { timeout: UI_TIMEOUT_MS }, + ); + await aiButton.click({ timeout: UI_TIMEOUT_MS }); + await aiDrawer.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator("[data-page-ai-input]").fill("Task490 stop smoke", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => document.documentElement.getAttribute("data-mnote-page-ai-run-status") === "running" + && document.documentElement.getAttribute("data-mnote-page-ai-run-id") === "run_task490_stop", + null, + { timeout: UI_TIMEOUT_MS }, + ); + const stopButton = page.locator('[data-page-ai-action="stop-run"]').first(); + await stopButton.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => { + const stop = document.querySelector('[data-page-ai-action="stop-run"]'); + return stop instanceof HTMLButtonElement && stop.disabled === false && stop.getAttribute("aria-disabled") === "false"; + }, + null, + { timeout: UI_TIMEOUT_MS }, + ); + await stopButton.click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => document.documentElement.getAttribute("data-mnote-page-ai-run-status") === "aborted", + null, + { timeout: UI_TIMEOUT_MS }, + ); + await page.locator('[data-page-ai-conversation]').getByText("已请求停止当前 AI run。").waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + assert(capturedPageAi.runs.length === 1, "Page AI stop smoke 应先发起一个 run"); + assert(capturedPageAi.aborts.length === 1, "点击停止应调用 abort API 一次"); + const abortBody = JSON.parse(capturedPageAi.aborts[0] || "{}"); + assert(abortBody.reason === "page_ai_user_stop", "abort API 应记录用户停止原因"); + screenshots.pageAiStopped = await saveScreenshot(page, "02b-page-ai-stopped"); + await closePageAiIfOpen(page); + + await setBlockHandleFixture(page, UI_TIMEOUT_MS); await editor.click({ timeout: UI_TIMEOUT_MS }); await page.keyboard.type("/"); const slashMenu = page.locator('[data-testid="mnote-leptos-tiptap-slash-menu"]').first(); diff --git a/scripts/task502-page-ai-agent-selector-context-smoke.js b/scripts/task502-page-ai-agent-selector-context-smoke.js index 56c67f4c..31c0ac35 100644 --- a/scripts/task502-page-ai-agent-selector-context-smoke.js +++ b/scripts/task502-page-ai-agent-selector-context-smoke.js @@ -142,6 +142,23 @@ async function main() { body: JSON.stringify({ ok: true, tools: [] }), }); }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + agentId: "hermes", + profiles: [ + { profileId: "shared_deepseek_chat", kind: "shared", displayName: "DeepSeek Chat", baseProfile: "deepseek-chat", isolatedProfile: "openclaw-deepseek-chat", canRun: true, canManageSkills: false, canManageConfig: false, readonly: true }, + { profileId: "shared_doubao_chat", kind: "shared", displayName: "豆包 Chat", baseProfile: "doubao-chat", isolatedProfile: "openclaw-doubao-chat", canRun: true, canManageSkills: false, canManageConfig: false, readonly: true }, + { profileId: "shared_gemini_chat", kind: "shared", displayName: "Gemini Chat", baseProfile: "gemini-chat", isolatedProfile: "openclaw-gemini-chat", canRun: true, canManageSkills: false, canManageConfig: false, readonly: true }, + { profileId: "usr_task502_default", kind: "personal", displayName: "我的 Hermes", baseProfile: "default", isolatedProfile: "mnote-u-task502-default", canRun: true, canManageSkills: true, canManageConfig: true }, + { profileId: "shared_lite", kind: "shared", displayName: "Lite", baseProfile: "lite", isolatedProfile: "lite", canRun: true, canManageSkills: false, canManageConfig: false, readonly: true }, + ], + }), + }); + }); await page.route("**/api/hermes/client/profiles", async (route) => { await route.fulfill({ status: 200, @@ -184,12 +201,18 @@ async function main() { return; } const runtime = url.searchParams.get("runtime"); - const profile = url.searchParams.get("profile") || "mnoteai"; + const profile = url.searchParams.get("profileId") || url.searchParams.get("profile") || "usr_task502_default"; const body = runtime === "mnote" ? { ok: true, runtime: "mnote", - categories: [{ name: "mnote", skills: [{ id: "mnote-current-page", name: "mnote-current-page", title: "当前页读取", description: "读取当前页", enabled: true, source: "mnote", origin: "builtin" }] }], + categories: [{ + name: "mnote", + skills: [ + { id: "mnote-current-page", name: "mnote-current-page", title: "当前页读取", description: "读取当前页", enabled: true, source: "mnote", origin: "builtin", builtin: true, configurable: true, configScope: "user_sqlite", skillKind: "mnote_builtin" }, + { id: "mnote-mindmap", name: "mnote-mindmap", title: "思维导图读写", description: "读取、编辑或从 outline 生成思维导图", enabled: true, source: "mnote", origin: "builtin", builtin: true, configurable: true, configScope: "user_sqlite", skillKind: "mnote_builtin", toolNames: ["mnote.mindmap.fetch", "mnote.mindmap.create_from_outline"] }, + ], + }], archived: [], } : runtime === "reasonix" @@ -205,8 +228,8 @@ async function main() { categories: [{ name: "writing", skills: [ - { id: "hermes-builtin", name: "hermes-builtin", title: "Hermes builtin", description: `Builtin ${profile}`, enabled: true, source: "builtin", origin: "builtin" }, - { id: profile === "chemist" ? "hermes-chemist" : "hermes-writer", name: profile === "chemist" ? "hermes-chemist" : "hermes-writer", title: profile === "chemist" ? "Hermes chemist" : "Hermes writer", description: `Hermes ${profile}`, enabled: profile !== "chemist", source: "local", origin: "installed" }, + { id: "hermes-builtin", name: "hermes-builtin", title: "Hermes builtin", description: `Builtin ${profile}`, enabled: true, source: "builtin", origin: "builtin", skillKind: "hermes_profile", profileId: profile, configurable: profile !== "shared_lite" }, + { id: profile === "shared_lite" ? "hermes-lite" : "hermes-writer", name: profile === "shared_lite" ? "hermes-lite" : "hermes-writer", title: profile === "shared_lite" ? "Hermes lite" : "Hermes writer", description: `Hermes ${profile}`, enabled: profile !== "shared_lite", source: "local", origin: "installed", skillKind: "hermes_profile", profileId: profile, configurable: profile !== "shared_lite", readonly: profile === "shared_lite" }, ], }], archived: [], @@ -320,24 +343,59 @@ async function main() { await agentButton.click({ timeout: UI_TIMEOUT_MS }); const agentPopover = page.locator("[data-page-ai-agent-popover]"); await agentPopover.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); - const agentIds = await page.$$eval("[data-page-ai-agent-id]", (nodes) => - nodes.map((node) => node.getAttribute("data-page-ai-agent-id")).filter(Boolean), + await agentPopover.locator('[data-page-ai-agent-section="chat_only"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await agentPopover.locator('[data-page-ai-agent-section="hermes"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + assert.strictEqual( + await page.locator('[data-page-ai-agent-section="chat_only"] [data-page-ai-profile-id="shared_deepseek_chat"]').count(), + 1, + "ChatOnly 二级菜单应包含 DeepSeek", ); - assert.deepStrictEqual(agentIds.sort(), ["chat_only", "hermes", "reasonix"]); - await page.locator('[data-page-ai-agent-id="hermes"]').click({ timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-agent-popover] [data-page-ai-profile-select]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-agent-popover] [data-page-ai-profile-select]').selectOption("chemist", { timeout: UI_TIMEOUT_MS }); + assert.strictEqual( + await page.locator('[data-page-ai-agent-section="chat_only"] [data-page-ai-profile-id="shared_doubao_chat"]').count(), + 1, + "ChatOnly 二级菜单应包含豆包", + ); + assert.strictEqual( + await page.locator('[data-page-ai-agent-section="chat_only"] [data-page-ai-profile-id="shared_gemini_chat"]').count(), + 1, + "ChatOnly 二级菜单应包含 Gemini", + ); + assert.strictEqual( + await page.locator('[data-page-ai-agent-section="hermes"] [data-page-ai-profile-id="usr_task502_default"]').count(), + 1, + "Hermes 二级菜单应包含个人 profile", + ); + assert.strictEqual( + await page.locator('[data-page-ai-agent-section="hermes"] [data-page-ai-profile-id="shared_lite"]').count(), + 1, + "Hermes 二级菜单应包含 shared_lite profile", + ); + const agentChip = page.locator("[data-page-ai-agent-chip]"); + await page.locator('[data-page-ai-agent-section="chat_only"] [data-page-ai-profile-id="shared_gemini_chat"]').click({ timeout: UI_TIMEOUT_MS }); await page.waitForFunction( - () => document.documentElement.getAttribute("data-mnote-page-ai-profile") === "chemist", + () => document.documentElement.getAttribute("data-mnote-page-ai-agent-id") === "chat_only" + && document.documentElement.getAttribute("data-mnote-page-ai-profile") === "shared_gemini_chat", null, { timeout: UI_TIMEOUT_MS }, ); - await page.locator('[data-page-ai-agent-id="reasonix"]').click({ timeout: UI_TIMEOUT_MS }); + assert((await agentChip.innerText({ timeout: UI_TIMEOUT_MS })).includes("ChatOnly / Gemini"), "上下文按钮右侧标签应显示当前 ChatOnly agent"); + await agentButton.click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-agent-section="hermes"] [data-page-ai-profile-id="shared_lite"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => document.documentElement.getAttribute("data-mnote-page-ai-agent-id") === "hermes" + && document.documentElement.getAttribute("data-mnote-page-ai-profile") === "shared_lite", + null, + { timeout: UI_TIMEOUT_MS }, + ); + assert((await agentChip.innerText({ timeout: UI_TIMEOUT_MS })).includes("Hermes / Lite"), "上下文按钮右侧标签应显示当前 Hermes profile"); + await agentButton.click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-agent-section="reasonix"] [data-page-ai-agent-id="reasonix"]').click({ timeout: UI_TIMEOUT_MS }); await page.waitForFunction( () => document.documentElement.getAttribute("data-mnote-page-ai-agent-id") === "reasonix", null, { timeout: UI_TIMEOUT_MS }, ); + assert((await agentChip.innerText({ timeout: UI_TIMEOUT_MS })).includes("Reasonix"), "上下文按钮右侧标签应显示当前 Reasonix agent"); const contextRefs = page.locator("[data-page-ai-context-refs]"); assert.strictEqual( @@ -351,6 +409,116 @@ async function main() { await contextButton.evaluate((node) => Boolean(node.closest(".wolai-page-ai-composer-bar"))), "上下文按钮应显示在输入区下方工具栏中", ); + const targetButton = page.locator("[data-page-ai-target-button]"); + await targetButton.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + assert( + await targetButton.evaluate((node) => Boolean(node.closest(".wolai-page-ai-composer-bar"))), + "目标按钮应显示在输入区下方工具栏中", + ); + const targetChip = page.locator("[data-page-ai-target-chip]"); + await targetChip.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const targetChipText = (await targetChip.innerText({ timeout: UI_TIMEOUT_MS })).trim(); + assert(targetChipText.includes("AgentContext") || targetChipText.includes("当前页"), `目标 chip 应展示当前写入目标: ${targetChipText}`); + await targetButton.click({ timeout: UI_TIMEOUT_MS }); + const targetPopover = page.locator("[data-page-ai-target-popover]"); + await targetPopover.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + assert( + await targetPopover.locator("[data-page-ai-target-option]").first().isVisible(), + "目标 popover 应提供至少一个可选目标", + ); + await targetPopover.locator('[data-page-ai-action="close-target-popover"]').click({ timeout: UI_TIMEOUT_MS }); + await page.evaluate(({ documentId, rootUri, workspaceId }) => { + const runtime = window.__mnoteDocumentPaneRuntime; + if (!runtime || typeof runtime.getOpenEditorsSnapshot !== "function") { + throw new Error("缺少 open editors snapshot runtime"); + } + const original = runtime.getOpenEditorsSnapshot.bind(runtime); + runtime.getOpenEditorsSnapshot = () => { + const snapshot = original(); + const mindmapResource = { + objectIdentity: "resource:mindmap:task502", + workspacePath: { + schema: "mnote.workspace_path.v1", + workspaceId, + sourceKind: "local_folder", + rootUri, + relativePath: "maps/Task502.mindmap.json", + documentId, + objectIdentity: "resource:mindmap:task502", + assetId: "task502-mindmap", + resourceKind: "mindmap", + }, + paneRole: "primary", + documentId, + workspaceId, + title: "Task502 Mindmap", + kind: "mindmap", + editorKind: "mindmap", + active: false, + dirtyState: "", + preview: false, + pinned: true, + lastActiveAt: Date.now(), + assetId: "task502-mindmap", + path: "maps/Task502.mindmap.json", + }; + const officeResource = { + objectIdentity: "resource:office:task502", + workspacePath: { + schema: "mnote.workspace_path.v1", + workspaceId, + sourceKind: "local_folder", + rootUri, + relativePath: "office/Task502 Deck.pptx", + documentId, + objectIdentity: "resource:office:task502", + assetId: "task502-office", + resourceKind: "office", + }, + paneRole: "primary", + documentId, + workspaceId, + title: "Task502 Deck", + kind: "office", + editorKind: "office", + active: false, + dirtyState: "", + preview: false, + pinned: true, + lastActiveAt: Date.now(), + assetId: "task502-office", + path: "office/Task502 Deck.pptx", + onlyofficeSessionId: "mnote-oo-task502-office", + bridgeSessionId: "mnote-oo-task502-office", + bridgeSessionReady: true, + }; + const resources = [mindmapResource, officeResource]; + const withoutResource = (items) => (Array.isArray(items) ? items : []) + .filter((item) => !resources.some((resource) => item?.objectIdentity === resource.objectIdentity)); + const groups = snapshot.groups || {}; + const primary = groups.primary || {}; + return { + ...snapshot, + editors: [...withoutResource(snapshot.editors), ...resources], + resourceEditors: [...withoutResource(snapshot.resourceEditors), ...resources], + groups: { + ...groups, + primary: { + ...primary, + resourceEditors: [...withoutResource(primary.resourceEditors), ...resources], + }, + }, + }; + }; + }, { documentId, rootUri, workspaceId }); + await targetButton.click({ timeout: UI_TIMEOUT_MS }); + await targetPopover.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await targetPopover.locator('[data-page-ai-target-option="resource:office:task502"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector("[data-page-ai-target-chip]")?.textContent || "").includes("Task502 Deck"), + null, + { timeout: UI_TIMEOUT_MS }, + ); assert.strictEqual( await page.locator('.wolai-page-ai-composer-bar [data-page-ai-action="history"]').count(), 0, @@ -366,39 +534,70 @@ async function main() { ); await page.locator('.wolai-page-ai-header-actions [data-page-ai-tab="skills"]').click({ timeout: UI_TIMEOUT_MS }); await page.locator('[data-page-ai-panel="skills"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const skillSourceSelect = page.locator('[data-page-ai-panel="skills"] [data-page-ai-skill-source-select]'); + await skillSourceSelect.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const skillSourceOptions = await skillSourceSelect.locator("option").evaluateAll((nodes) => + nodes.map((node) => ({ value: node.value, text: node.textContent || "" })), + ); + assert(skillSourceOptions.some((item) => item.value === "mnote" && item.text.includes("mnote")), "技能来源应包含 mnote"); + assert(skillSourceOptions.some((item) => item.value === "reasonix" && item.text.includes("reasonix")), "技能来源应包含 reasonix"); + assert(skillSourceOptions.some((item) => item.value === "hermes:usr_task502_default" && item.text.includes("Hermes_user")), "技能来源应包含个人 Hermes profile"); + assert(skillSourceOptions.some((item) => item.value === "hermes:shared_lite" && item.text.includes("hermes_lite")), "技能来源应包含 shared lite profile"); + await skillSourceSelect.selectOption("mnote", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-current-page"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-mindmap"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); const skillPanelText = await page.locator('[data-page-ai-panel="skills"]').innerText({ timeout: UI_TIMEOUT_MS }); - assert(skillPanelText.includes("MNote 内置技能"), "技能面板应展示 MNote 内置技能分组"); - assert(skillPanelText.includes("Reasonix 技能"), "技能面板应展示 Reasonix 技能分组"); - assert(skillPanelText.includes("Hermes 技能"), "技能面板应展示 Hermes 技能分组"); - assert(skillPanelText.includes("Hermes chemist"), "Hermes 技能应随 chemist profile 加载"); - assert(!skillPanelText.includes("Hermes writer"), "Hermes profile 切到 chemist 后不应继续显示上一 profile 技能"); + assert(skillPanelText.includes("mnote"), "技能面板应展示 mnote 来源"); + assert(!skillPanelText.includes("Reasonix 技能"), "选择 mnote 时不应同时展示 Reasonix 技能"); + assert(!skillPanelText.includes("Hermes 技能"), "选择 mnote 时不应同时展示 Hermes 技能"); await page.locator('[data-page-ai-skill-group-toggle="mnote"]').click({ timeout: UI_TIMEOUT_MS }); assert.strictEqual( await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-current-page"]').count(), 0, "MNote 技能分组折叠后不应显示组内技能", ); + assert.strictEqual( + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-mindmap"]').count(), + 0, + "MNote 技能分组折叠后不应显示 mindmap 技能", + ); await page.locator('[data-page-ai-skill-group-toggle="mnote"]').click({ timeout: UI_TIMEOUT_MS }); await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-current-page"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-mindmap"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-current-page"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-mindmap"]').click({ timeout: UI_TIMEOUT_MS }); + await skillSourceSelect.selectOption("reasonix", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="reasonix"] [data-page-ai-skill-toggle="reasonix-review"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const reasonixOnlyText = await page.locator('[data-page-ai-panel="skills"]').innerText({ timeout: UI_TIMEOUT_MS }); + assert(reasonixOnlyText.includes("reasonix"), "选择 reasonix 时应展示 Reasonix 来源"); + assert(!reasonixOnlyText.includes("当前页读取"), "选择 reasonix 时不应残留 MNote 技能"); + assert(!reasonixOnlyText.includes("Hermes writer"), "选择 reasonix 时不应残留 Hermes 技能"); + await page.locator('[data-page-ai-skill-group="reasonix"] [data-page-ai-skill-toggle="reasonix-review"]').click({ timeout: UI_TIMEOUT_MS }); + await skillSourceSelect.selectOption("hermes:shared_lite", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-lite"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const sharedHermesText = await page.locator('[data-page-ai-panel="skills"]').innerText({ timeout: UI_TIMEOUT_MS }); + assert(sharedHermesText.includes("hermes_lite"), "选择 hermes_lite 时应只展示 lite profile 技能"); + assert(!sharedHermesText.includes("当前页读取"), "选择 hermes_lite 时不应残留 MNote 技能"); + assert(!sharedHermesText.includes("reasonix-review"), "选择 hermes_lite 时不应残留 Reasonix 技能"); + assert( + await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-lite"]').isDisabled(), + "shared Hermes profile 普通用户应只读", + ); await page.locator('[data-page-ai-hide-hermes-builtin]').check({ timeout: UI_TIMEOUT_MS }); const hiddenBuiltinText = await page.locator('[data-page-ai-panel="skills"]').innerText({ timeout: UI_TIMEOUT_MS }); assert(!hiddenBuiltinText.includes("Hermes builtin"), "隐藏 Hermes 内置后不应显示 Hermes 内置技能"); await page.locator('[data-page-ai-hide-hermes-builtin]').uncheck({ timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-panel="skills"] [data-page-ai-profile-select]').selectOption("mnoteai", { timeout: UI_TIMEOUT_MS }); + await skillSourceSelect.selectOption("hermes:usr_task502_default", { timeout: UI_TIMEOUT_MS }); await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-writer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); assert.strictEqual( - await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-chemist"]').count(), + await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-lite"]').count(), 0, "Hermes profile 切回 mnoteai 后不应残留 chemist 技能", ); - await page.locator('[data-page-ai-panel="skills"] [data-page-ai-profile-select]').selectOption("chemist", { timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-chemist"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); const skillsScreenshot = await saveScreenshot(page, "00-skills-panel"); - await page.locator('[data-page-ai-skill-group="mnote"] [data-page-ai-skill-toggle="mnote-current-page"]').click({ timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-skill-group="reasonix"] [data-page-ai-skill-toggle="reasonix-review"]').click({ timeout: UI_TIMEOUT_MS }); - await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-chemist"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-skill-group="hermes"] [data-page-ai-skill-toggle="hermes-writer"]').click({ timeout: UI_TIMEOUT_MS }); await page.waitForFunction( - () => document.documentElement.getAttribute("data-mnote-page-ai-skill-toggled") === "hermes-chemist", + () => document.documentElement.getAttribute("data-mnote-page-ai-skill-toggled") === "hermes-writer", null, { timeout: UI_TIMEOUT_MS }, ); @@ -454,6 +653,16 @@ async function main() { assert.strictEqual(ackRunBody.pageContext?.aiContext?.contextBlocks, undefined, "Page AI run 不应默认上传 contextBlocks"); assert.strictEqual(ackRunBody.pageContext?.evidence, undefined, "Page AI run 不应默认上传选区 evidence 正文"); assert.strictEqual(ackRunBody.selectedText, "", "Page AI run 不应默认上传 selectedText 正文"); + assert.strictEqual(ackRunBody.targetPackage?.schema, "mnote.agent_target_package.v1", "纯聊天 run 也应冻结目标包合同"); + assert(ackRunBody.targetPackage?.primaryTargetId, "targetPackage 应包含 primaryTargetId"); + assert(Array.isArray(ackRunBody.targetPackage?.targets), "targetPackage 应包含 targets 数组"); + assert.strictEqual(ackRunBody.targetPackage?.primaryTargetId, "resource:office:task502", "targetPackage 应冻结用户选择的 Office target"); + assert.strictEqual(ackRunBody.targetPackage?.onlyofficeSessionId, "mnote-oo-task502-office", "Office targetPackage 应携带 bridge session"); + assert( + ackRunBody.targetPackage.targets.some((target) => target.resourceKind === "only_office" && target.relativePath === "office/Task502 Deck.pptx" && target.onlyofficeSessionId === "mnote-oo-task502-office"), + `默认目标应标记 only_office resourceKind: ${JSON.stringify(ackRunBody.targetPackage)}`, + ); + assert.strictEqual(ackRunBody.targetPackage?.policy?.writeRequiresExplicitTarget, true, "targetPackage policy 应要求显式目标"); await page.locator('.wolai-page-ai-header-actions [data-page-ai-tab="agent"]').click({ timeout: UI_TIMEOUT_MS }); await page.locator('[data-page-ai-panel="agent"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); @@ -495,6 +704,14 @@ async function main() { `勾选变化后上下文按钮摘要应更新: ${updatedContextButtonLabel}`, ); await contextPopover.locator('[data-page-ai-action="close-context-popover"]').click({ timeout: UI_TIMEOUT_MS }); + await targetButton.click({ timeout: UI_TIMEOUT_MS }); + await targetPopover.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await targetPopover.locator('[data-page-ai-target-option="resource:mindmap:task502"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector("[data-page-ai-target-chip]")?.textContent || "").includes("Task502 Mindmap"), + null, + { timeout: UI_TIMEOUT_MS }, + ); const runsBeforeDocumentTask = captured.filter((item) => item.kind === "run").length; await page.locator("[data-page-ai-input]").fill(`Task502 agent/context ${suffix}`, { timeout: UI_TIMEOUT_MS }); await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); @@ -520,20 +737,37 @@ async function main() { assert.strictEqual(runBody.pageContext?.aiContext?.contextBlocks, undefined, "Page AI run 不应默认上传 contextBlocks"); assert.strictEqual(runBody.pageContext?.evidence, undefined, "Page AI run 不应默认上传选区 evidence 正文"); assert.strictEqual(runBody.selectedText, "", "Page AI run 不应默认上传 selectedText 正文"); - assert(runBody.contextRefs.some((item) => item.kind === "active_editor" && item.documentId === documentId)); + const activeEditorRef = runBody.contextRefs.find((item) => item.kind === "active_editor" && item.documentId === documentId); + assert(activeEditorRef, "run payload 应包含 active_editor contextRef"); + assert.strictEqual(activeEditorRef.targetId, "resource:mindmap:task502", `active_editor contextRef 应冻结 mindmap targetId: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.objectIdentity, "resource:mindmap:task502", `active_editor contextRef 应冻结 mindmap objectIdentity: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.resourceKind, "mindmap", `active_editor contextRef 应标记 mindmap resourceKind: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.assetId, "task502-mindmap", `active_editor contextRef 应携带 mindmap assetId: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.relativePath, "maps/Task502.mindmap.json", `active_editor contextRef 应携带 mindmap relativePath: ${JSON.stringify(activeEditorRef)}`); assert(runBody.contextRefs.some((item) => item.kind === "folder" && item.rootUri === rootUri)); assert(runBody.contextRefs.some((item) => item.kind === "changed_files")); assert.strictEqual(runBody.skillPreferences?.mnote?.["mnote-current-page"], false, "MNote skill 开关应进入 run payload"); + assert.strictEqual(runBody.skillPreferences?.mnote?.["mnote-mindmap"], false, "MNote mindmap skill 开关应进入 run payload"); assert.strictEqual(runBody.skillPreferences?.reasonix?.["reasonix-review"], false, "Reasonix skill 开关应进入 run payload"); + assert.strictEqual(runBody.targetPackage?.schema, "mnote.agent_target_package.v1", "文档任务 run 应携带目标包"); + assert(runBody.targetPackage?.primaryTargetId, "文档任务 targetPackage 应包含 primaryTargetId"); + assert(Array.isArray(runBody.targetPackage?.targets), "文档任务 targetPackage 应包含 targets 数组"); + assert.strictEqual(runBody.targetPackage?.primaryTargetId, "resource:mindmap:task502", "文档任务 targetPackage 应冻结用户选择的 mindmap target"); + assert( + runBody.targetPackage.targets.some((target) => target.resourceKind === "mindmap" && target.relativePath === "maps/Task502.mindmap.json"), + `文档任务 targetPackage 应包含 mindmap 目标: ${JSON.stringify(runBody.targetPackage)}`, + ); + assert.strictEqual(runBody.targetPackage?.policy?.writeRequiresExplicitTarget, true, "文档任务 targetPackage policy 应要求显式目标"); const preferenceBodies = captured .filter((item) => item.kind === "ui-preferences" && item.method === "PUT") .map((item) => JSON.parse(item.body || "{}")); - assert(preferenceBodies.some((body) => body.updates?.["ai.agent.hermes.profile_id"] === "chemist"), "Hermes profile 选择应写入 SQLite UI preference"); - assert(preferenceBodies.some((body) => body.updates?.["ai.common.skills.mnote.enabled"]?.["mnote-current-page"] === false), "MNote skill 开关应写入 SQLite UI preference"); + assert(preferenceBodies.some((body) => body.updates?.["ai.agent.hermes.profile_id"] === "shared_lite"), "Agent 内的 Hermes profile 选择应写入 SQLite UI preference"); + assert(captured.some((item) => item.kind === "skill-toggle" && JSON.parse(item.body || "{}").skillKind === "mnote_builtin" && JSON.parse(item.body || "{}").name === "mnote-current-page"), "MNote skill 开关应调用服务端 per-user SQLite policy"); assert(preferenceBodies.some((body) => body.updates?.["ai.agent.reasonix.skills.enabled"]?.["reasonix-review"] === false), "Reasonix skill 开关应写入 SQLite UI preference"); assert(preferenceBodies.some((body) => body.updates?.["ai.common.skills.groups.collapsed"]?.mnote === true), "技能分组折叠状态应写入 SQLite UI preference"); - assert(preferenceBodies.some((body) => body.updates?.["ai.agent.hermes.profile.chemist.skills.hide_builtin"] === true), "Hermes 隐藏内置技能应按 profile 写入 SQLite UI preference"); - assert(captured.some((item) => item.kind === "skill-toggle" && JSON.parse(item.body || "{}").profile === "chemist"), "Hermes skill 开关应按 profile 调用"); + assert(preferenceBodies.some((body) => body.updates?.["ai.common.skills.active_source"] === "hermes:usr_task502_default"), "技能来源选择应写入 SQLite UI preference"); + assert(preferenceBodies.some((body) => body.updates?.["ai.agent.hermes.skills.hide_builtin"] === true), "Hermes 隐藏内置技能应写入用户 UI preference"); + assert(captured.some((item) => item.kind === "skill-toggle" && JSON.parse(item.body || "{}").profileId === "usr_task502_default"), "Hermes skill 开关应按 profileId 调用"); assert(Array.isArray(runBody.allowedRoots), "run payload 必须包含 allowedRoots 数组"); assert(runBody.allowedRoots.some((item) => item.rootUri === rootUri diff --git a/scripts/task503-mindmap-skill-capability-smoke.js b/scripts/task503-mindmap-skill-capability-smoke.js new file mode 100644 index 00000000..6207a565 --- /dev/null +++ b/scripts/task503-mindmap-skill-capability-smoke.js @@ -0,0 +1,319 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("node:fs/promises"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { UI_TIMEOUT_MS, assert } = require("./tree-shell-smoke-helpers"); + +const BASE_URL = (process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); +const TASK = "task503-mindmap-skill-capability-smoke"; +const OUTPUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); +const TEST_EMAIL = "mnote.e2e@example.com"; +const TEST_PASSWORD = "MnoteE2E123!"; + +async function writeResult(payload) { + await fs.mkdir(OUTPUT_DIR, { recursive: true }); + await fs.writeFile(RESULT_PATH, `${JSON.stringify({ ...payload, resultPath: RESULT_PATH }, null, 2)}\n`, "utf8"); +} + +async function callJson(url, init = {}) { + const response = await fetch(url, { + ...init, + headers: { + ...(init.data !== undefined ? { "content-type": "application/json" } : {}), + ...(init.headers || {}), + }, + body: init.data !== undefined ? JSON.stringify(init.data) : init.body, + }); + const text = await response.text(); + let payload = null; + try { + payload = text ? JSON.parse(text) : null; + } catch { + payload = text; + } + if (!response.ok || payload?.ok === false) { + throw new Error(`${url} failed: ${response.status} ${typeof payload === "string" ? payload : JSON.stringify(payload)}`); + } + return payload; +} + +async function callMnoteTool({ toolName, workspaceId, documentId, rootUri, args, idempotencyKey }) { + const payload = { + toolName, + workspaceId, + documentId, + sourceKind: "local_folder", + rootUri, + actorId: "mnote-e2e", + sessionId: `sess_${TASK}_${toolName.replace(/\W+/g, "_")}`, + runId: `run_${Date.now()}`, + toolCallId: `call_${Date.now()}`, + traceId: `trace_${Date.now()}`, + idempotencyKey, + dryRun: false, + args, + }; + const result = await callJson(`${BASE_URL}/api/hermes/tools/mnote/call`, { + method: "POST", + headers: { + "content-type": "application/json", + "x-mnote-actor-id": "mnote-e2e", + "x-mnote-actor-type": "user", + }, + body: JSON.stringify(payload), + }); + return result.result ?? result; +} + +async function signInBrowserContext(context) { + const auth = await context.request.post(`${BASE_URL}/api/auth`, { + data: { + action: "auth:signIn", + args: { + provider: "password", + params: { + email: TEST_EMAIL, + password: TEST_PASSWORD, + flow: "signIn", + }, + }, + }, + }); + assert(auth.ok(), `测试账号登录失败: ${auth.status()} ${await auth.text()}`); + const whoami = await context.request.get(`${BASE_URL}/api/auth/whoami`); + assert(whoami.ok(), `whoami 失败: ${whoami.status()} ${await whoami.text()}`); + const viewer = await whoami.json(); + assert(viewer.userId === "mnote-e2e", `当前登录用户不是 mnote-e2e: ${JSON.stringify(viewer)}`); + assert(viewer.actorType === "user", `当前登录不是真实 user 会话: ${JSON.stringify(viewer)}`); + return viewer; +} + +function skillCapabilityOutline() { + return [ + { + text: "触发场景", + children: [ + { text: "用户提到脑图", children: [] }, + { text: "资源标签页", children: [] }, + { text: "PDF 转导图", children: [] }, + ], + }, + { + text: "读取能力", + children: [ + { text: "先解析目标", children: [] }, + { text: "fetch 回读树", children: [] }, + { text: "完整 envelope", children: [] }, + ], + }, + { + text: "创建能力", + children: [ + { text: "outline 写入", children: [] }, + { text: "自动生成 uid", children: [] }, + { text: "保留 sourceRefs", children: [] }, + ], + }, + { + text: "权限约束", + children: [ + { text: "需要 read_write", children: [] }, + { text: "限定资源路径", children: [] }, + { text: "拒绝越权写入", children: [] }, + ], + }, + { + text: "写后验证", + children: [ + { text: "fetch 再确认", children: [] }, + { text: "报告 JSON 路径", children: [] }, + { text: "截图看渲染", children: [] }, + ], + }, + { + text: "当前边界", + children: [ + { text: "非裸树文件", children: [] }, + { text: "apply_ops 受限", children: [] }, + { text: "长文本需压缩", children: [] }, + ], + }, + ]; +} + +function collectOutlineTexts(nodes, texts = []) { + for (const node of nodes) { + texts.push(String(node.text || "")); + collectOutlineTexts(Array.isArray(node.children) ? node.children : [], texts); + } + return texts; +} + +async function main() { + await fs.mkdir(OUTPUT_DIR, { recursive: true }); + const workspace = await callJson(`${BASE_URL}/api/local-folder/workspaces/default`, { + method: "POST", + headers: { + "content-type": "application/json", + "x-mnote-actor-id": "mnote-e2e", + "x-mnote-actor-type": "user", + }, + data: {}, + }); + const rootUri = workspace.workspace?.rootUri || ""; + const rootPath = workspace.workspace?.rootPath || ""; + const workspaceId = workspace.workspace?.manifest?.workspaceId || "local-ws:mnote-e2e:my-space"; + assert(rootUri.startsWith("file://"), `默认本地工作区 rootUri 异常: ${JSON.stringify(workspace)}`); + assert(rootPath, `默认本地工作区 rootPath 缺失: ${JSON.stringify(workspace)}`); + + const documentName = `MindmapSkillCapabilitySmoke-${Date.now()}.md`; + const documentId = `local-md:${documentName}`; + const resourcePath = `maps/task503-mindmap-skill-capabilities-${Date.now()}.mindmap.json`; + const title = "mnote-mindmap skill 能力"; + await fs.mkdir(path.join(rootPath, "maps"), { recursive: true }); + await fs.writeFile(path.join(rootPath, documentName), "# Mindmap Skill Capability Smoke\n", "utf8"); + + const skill = await callMnoteTool({ + toolName: "mnote.skill.read", + workspaceId, + documentId, + rootUri, + args: { skillId: "mnote-mindmap", agentId: "reasonix" }, + }); + const skillContent = String(skill.content || ""); + assert(skillContent.includes("Mindmap outline format"), "skill 缺少导图格式小节"); + assert(skillContent.includes("Use concise keywords or short phrases"), "skill 缺少短语化节点要求"); + assert(skillContent.includes("Avoid long paragraphs"), "skill 缺少避免长段落要求"); + + const outline = skillCapabilityOutline(); + const outlineTexts = collectOutlineTexts(outline); + assert(outlineTexts.every((text) => text.length > 0 && text.length <= 32), "outline 节点应保持短语化"); + assert(outlineTexts.every((text) => !text.includes("\n")), "outline 节点不能用换行模拟层级"); + + const aiAccessScope = { + permissionLevel: "read_write", + allowedResourceIds: [resourcePath], + }; + const created = await callMnoteTool({ + toolName: "mnote.mindmap.create_from_outline", + workspaceId, + documentId, + rootUri, + idempotencyKey: `idem_${TASK}_${Date.now()}`, + args: { + mindmapId: resourcePath, + resourcePath, + title, + outline, + embedIntoPage: true, + sourceRefs: [{ kind: "skill", title: "mnote-mindmap", note: TASK }], + aiAccessScope, + }, + }); + assert(created.root?.data?.text === title, `创建结果根节点异常: ${JSON.stringify(created.root)}`); + assert(created.embedResult?.status === "embedded", `创建结果缺少页面绑定: ${JSON.stringify(created.embedResult)}`); + assert( + Array.isArray(created.changedFiles) && created.changedFiles.includes(documentName), + `changedFiles 应包含当前 Markdown 页面: ${JSON.stringify(created.changedFiles)}`, + ); + const markdownAfterEmbed = await fs.readFile(path.join(rootPath, documentName), "utf8"); + assert( + markdownAfterEmbed.includes(`[${title}](${resourcePath})`), + `当前 Markdown 页面未写入 mindmap 链接: ${markdownAfterEmbed}`, + ); + + const fetched = await callMnoteTool({ + toolName: "mnote.mindmap.fetch", + workspaceId, + documentId, + rootUri, + args: { + mindmapId: resourcePath, + resourcePath, + scope: "full_envelope", + aiAccessScope, + }, + }); + const nodeCount = Array.isArray(fetched.nodes) ? fetched.nodes.length : 0; + assert(fetched.root?.data?.text === title, `回读根节点异常: ${JSON.stringify(fetched.root)}`); + assert(nodeCount >= 25, `回读节点数不足: ${nodeCount}`); + + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext({ viewport: { width: 1440, height: 960 } }); + const page = await context.newPage(); + const events = []; + page.on("pageerror", (error) => events.push({ kind: "pageerror", text: error.message })); + page.on("console", (message) => { + if (message.type() === "error") { + events.push({ kind: "console", text: message.text() }); + } + }); + page.on("response", (response) => { + if (response.url().includes("/api/mindmap/")) { + events.push({ kind: "mindmap-response", status: response.status(), url: response.url() }); + } + }); + const viewer = await signInBrowserContext(context); + const url = `${BASE_URL}/mindmap/${encodeURIComponent(documentId)}/${encodeURIComponent(`local-file:${resourcePath}`)}?sourceKind=local_folder&rootUri=${encodeURIComponent(rootUri)}&workspaceId=${encodeURIComponent(workspaceId)}`; + await page.goto(url, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="mnote-mindmap-editor-root"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + (expectedTitle) => { + const text = document.body.innerText || ""; + const countText = document.querySelector('[data-testid="mindmap-schema-count"]')?.textContent || ""; + return text.includes(expectedTitle) && text.includes("触发场景") && /节点\s*(?:[1-9]|[1-9][0-9]+)/.test(countText); + }, + title, + { timeout: UI_TIMEOUT_MS }, + ); + const screenshotPath = path.join(OUTPUT_DIR, "skill-capability-mindmap.png"); + await page.screenshot({ path: screenshotPath, fullPage: true }); + const ui = await page.evaluate(() => ({ + bodyHasTitle: (document.body.innerText || "").includes("mnote-mindmap skill 能力"), + bodyHasBranch: (document.body.innerText || "").includes("触发场景"), + bodyHasPermission: (document.body.innerText || "").includes("权限约束"), + schemaCount: document.querySelector('[data-testid="mindmap-schema-count"]')?.textContent || null, + rootVisible: Boolean(document.querySelector('[data-testid="mnote-mindmap-editor-root"]')), + errorText: document.querySelector('[data-testid="leptos-mindmap-error"]')?.textContent || null, + })); + await browser.close(); + assert(ui.bodyHasTitle && ui.bodyHasBranch && ui.bodyHasPermission, `导图页面文本缺失: ${JSON.stringify(ui)}`); + assert(!ui.errorText, `导图页面出现错误: ${ui.errorText}`); + + await writeResult({ + ok: true, + rootUri, + workspaceId, + documentId, + resourcePath, + mindmapFile: path.join(rootPath, resourcePath), + screenshotPath, + url, + viewer, + skillFormatRules: { + hasFormat: skillContent.includes("Mindmap outline format"), + hasShortPhraseRule: skillContent.includes("Use concise keywords or short phrases"), + hasAvoidParagraphRule: skillContent.includes("Avoid long paragraphs"), + }, + nodeCount, + embedResult: created.embedResult, + markdownHasMindmapLink: markdownAfterEmbed.includes(`[${title}](${resourcePath})`), + firstLevel: (fetched.root?.children || []).map((child) => child?.data?.text), + ui, + events, + }); + console.log(`task503 mindmap skill capability smoke passed: ${RESULT_PATH}`); +} + +main().catch(async (error) => { + await writeResult({ + ok: false, + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : null, + }).catch(() => undefined); + console.error(error instanceof Error ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task504-page-ai-history-agent-filter-smoke.js b/scripts/task504-page-ai-history-agent-filter-smoke.js new file mode 100644 index 00000000..3e0c32fd --- /dev/null +++ b/scripts/task504-page-ai-history-agent-filter-smoke.js @@ -0,0 +1,499 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const TASK = "task504-page-ai-history-agent-filter-smoke"; +const OUTPUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +async function saveScreenshot(page, name) { + const target = path.join(OUTPUT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: false }); + return target; +} + +async function main() { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + const suffix = Date.now().toString(36); + const actorId = "mnote-e2e"; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task504-history-")); + const rootUri = fileUrl(root); + const workspaceId = `local-ws:${actorId}:task504`; + const relativePath = "HistoryAgentFilter.md"; + const documentId = localMdDocumentId(relativePath); + const longGeminiMessage = [ + "Gemini 历史预览应只显示摘要,不应把 ChatOnly 的完整长消息塞进历史列表。", + "这段内容用于模拟网页问答返回的完整长回复,历史列表应保留可扫描性。", + "FULL_TAIL_SHOULD_NOT_RENDER", + ].join(""); + const sessions = [ + { + sessionId: `mnote_task504_gemini_${suffix}`, + runId: `run_task504_gemini_${suffix}`, + title: "Gemini 问答", + profile: "shared_gemini_chat", + acpRuntime: "hermes", + status: "completed", + payload: { + agentId: "chat_only", + profileId: "shared_gemini_chat", + profile: "shared_gemini_chat", + acpRuntime: "hermes", + message: longGeminiMessage, + }, + createdAt: "2026-05-30T08:00:00Z", + updatedAt: "2026-05-30T08:02:00Z", + persistence: "sqlite_acp_runtime_store", + }, + { + sessionId: `mnote_task504_doubao_${suffix}`, + runId: `run_task504_doubao_${suffix}`, + title: "豆包问答", + profile: "shared_doubao_chat", + acpRuntime: "hermes", + status: "completed", + payload: { + agentId: "chat_only", + profileId: "shared_doubao_chat", + profile: "shared_doubao_chat", + acpRuntime: "hermes", + message: "豆包短回复", + }, + createdAt: "2026-05-30T08:01:00Z", + updatedAt: "2026-05-30T08:01:30Z", + persistence: "sqlite_acp_runtime_store", + }, + { + sessionId: `mnote_task504_stale_chatonly_${suffix}`, + runId: `run_task504_stale_chatonly_${suffix}`, + title: "旧 ChatOnly profile", + profile: "myHermes", + acpRuntime: "hermes", + status: "completed", + payload: { + agentId: "chat_only", + profileId: "myHermes", + profile: "myHermes", + acpRuntime: "hermes", + message: "旧数据里误写成 Hermes profile 的 ChatOnly 会话", + }, + createdAt: "2026-05-30T08:00:50Z", + updatedAt: "2026-05-30T08:01:00Z", + persistence: "sqlite_acp_runtime_store", + }, + { + sessionId: `mnote_task504_hermes_${suffix}`, + runId: `run_task504_hermes_${suffix}`, + title: "Hermes 问答", + profile: "shared_lite", + acpRuntime: "hermes", + status: "completed", + payload: { + agentId: "hermes", + profileId: "shared_lite", + profile: "shared_lite", + acpRuntime: "hermes", + message: "Hermes 回复", + }, + createdAt: "2026-05-30T08:00:30Z", + updatedAt: "2026-05-30T08:00:45Z", + persistence: "sqlite_acp_runtime_store", + }, + ]; + const capturedRuns = []; + let caughtError = null; + const screenshots = {}; + + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, relativePath), ["# History Agent Filter", "", suffix, ""].join("\n"), "utf8"); + + const browser = await chromium.launch({ + headless: true, + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + try { + await page.route("**/api/user/access-policy**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + controlPlane: "sqlite", + grants: [{ + id: `grant_task504_${suffix}`, + userId: actorId, + workspaceId, + rootUri, + rootPath: root, + permission: "write", + recursive: true, + capabilities: ["ai", "markdown_edit"], + source: "user", + status: "active", + }], + }), + }); + }); + await page.route("**/api/ui/preferences**", async (route) => { + if (route.request().method() === "GET") { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + owner: "mnote-web", + result: { + aiPreferences: { + "ai.common.default_agent_id": "chat_only", + "ai.agent.hermes.profile_id": "shared_deepseek_chat", + "ai.common.context_refs.default_selected": { + current_page: true, + selection: false, + active_editor: false, + file: false, + folder: false, + changed_files: false, + }, + }, + }, + }), + }); + return; + } + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, owner: "mnote-web", result: {} }), + }); + }); + await page.route("**/api/documents/buffer-state**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + result: { dirtyState: "", fileVersion: `task504-${suffix}` }, + }), + }); + }); + await page.route("**/api/hermes/client/gateway/health**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + gateway: { ok: true, status: "mocked" }, + profile: { name: "reasonix", modelConfigured: true, apiKeyConfigured: true }, + suggestions: [], + }), + }); + }); + await page.route("**/api/hermes/client/tools**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, tools: [] }), + }); + }); + await page.route("**/api/hermes/client/profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + active: "mnoteai", + profiles: [{ name: "mnoteai", label: "MNote AI", modelConfigured: true, apiKeyConfigured: true }], + }), + }); + }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + agentId: "hermes", + profiles: [ + { profileId: "shared_deepseek_chat", kind: "shared", displayName: "DeepSeek Chat", baseProfile: "deepseek-chat", isolatedProfile: "openclaw-deepseek-chat", readonly: true }, + { profileId: "shared_doubao_chat", kind: "shared", displayName: "豆包 Chat", baseProfile: "doubao-chat", isolatedProfile: "openclaw-doubao-chat", readonly: true }, + { profileId: "shared_gemini_chat", kind: "shared", displayName: "Gemini Chat", baseProfile: "gemini-chat", isolatedProfile: "openclaw-gemini-chat", readonly: true }, + { profileId: "shared_lite", kind: "shared", displayName: "Lite", baseProfile: "lite", isolatedProfile: "lite", readonly: true }, + ], + }), + }); + }); + await page.route("**/api/hermes/client/skills**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, categories: [], archived: [] }), + }); + }); + await page.route("**/api/hermes/client/sessions**", async (route) => { + if (route.request().method() === "GET") { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + persistence: "sqlite_acp_runtime_store", + sessions, + }), + }); + return; + } + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + sessionId: `mnote_task504_new_${suffix}`, + title: "当前页问答", + persistence: "sqlite_acp_runtime_store", + }), + }); + }); + await page.route("**/api/hermes/client/runs", async (route) => { + const body = JSON.parse(route.request().postData() || "{}"); + capturedRuns.push(body); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + upstream: { + runId: `run_task504_current_page_${suffix}`, + traceId: `trace_task504_current_page_${suffix}`, + }, + }), + }); + }); + await page.route("**/api/hermes/client/events/run_task504_current_page_*", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "text/event-stream; charset=utf-8" }, + body: [ + "event: message.delta", + "data: {\"text\":\"### TASK504_CURRENT_PAGE_OK\\n- **Markdown 渲染**\"}", + "", + "event: run.completed", + "data: {\"output\":\"### TASK504_CURRENT_PAGE_OK\\n- **Markdown 渲染**\"}", + "", + ].join("\n"), + }); + }); + + await ensureAuthenticated(page, context.request); + const response = await page.goto(documentUrl(root, relativePath), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator('[data-testid="mnote-leptos-tiptap-island-editor-root"] .ProseMirror').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="history"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-panel="history"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-session-row="mnote_task504_gemini_${suffix}"]`).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + + const historyPanel = page.locator('[data-page-ai-panel="history"]'); + const historyText = await historyPanel.innerText({ timeout: UI_TIMEOUT_MS }); + assert(historyText.includes("ChatOnly / Gemini"), "历史会话应显示 Gemini 所属 agent"); + assert(historyText.includes("ChatOnly / 豆包"), "历史会话应显示豆包所属 agent"); + assert(historyText.includes("Hermes / Lite"), "历史会话应显示 Hermes profile"); + assert(!historyText.includes("ChatOnly / myHermes"), "ChatOnly 历史不应显示 Hermes profile 标签"); + assert(!historyText.includes("FULL_TAIL_SHOULD_NOT_RENDER"), "历史预览不应显示 ChatOnly 完整长消息尾部"); + + const filter = page.locator('[data-page-ai-session-agent-filter]'); + await filter.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await filter.selectOption("chat_only:shared_gemini_chat", { timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-session-row="mnote_task504_gemini_${suffix}"]`).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + assert.strictEqual( + await page.locator(`[data-page-ai-session-row="mnote_task504_doubao_${suffix}"]`).count(), + 0, + "筛选 Gemini 后不应显示豆包会话", + ); + await filter.selectOption("chat_only:shared_doubao_chat", { timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-session-row="mnote_task504_doubao_${suffix}"]`).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + assert.strictEqual( + await page.locator(`[data-page-ai-session-row="mnote_task504_gemini_${suffix}"]`).count(), + 0, + "筛选豆包后不应显示 Gemini 会话", + ); + screenshots.history = await saveScreenshot(page, "history-filter"); + + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="history"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-panel="chat"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="new-session"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => document.querySelector('[data-page-ai-agent-chip]')?.textContent?.includes("DeepSeek"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + await page.evaluate(({ staleWorkspaceId, documentId, rootUri: currentRootUri }) => { + const staleSnapshot = { + schema: "mnote.open_editors_snapshot.v1", + generatedAt: Date.now(), + activeObjectIdentity: "page:primary", + activeEditor: { + objectIdentity: "page:primary", + workspacePath: { + schema: "mnote.workspace_path.v1", + workspaceId: staleWorkspaceId, + sourceKind: "local_folder", + rootUri: currentRootUri, + relativePath: "HistoryAgentFilter.md", + documentId, + objectIdentity: "page:primary", + assetId: "", + resourceKind: "page", + }, + paneRole: "primary", + documentId, + workspaceId: staleWorkspaceId, + title: "Stale page target", + kind: "page", + editorKind: "page", + active: true, + dirtyState: "", + preview: false, + pinned: true, + lastActiveAt: Date.now(), + assetId: "", + path: "HistoryAgentFilter.md", + }, + editors: [], + resourceEditors: [], + groups: { primary: { paneRole: "primary", activeObjectIdentity: "page:primary", editors: [], resourceEditors: [] }, secondary: { paneRole: "secondary", activeObjectIdentity: "", editors: [], resourceEditors: [] } }, + }; + staleSnapshot.editors = [staleSnapshot.activeEditor]; + staleSnapshot.groups.primary.editors = [staleSnapshot.activeEditor]; + window.__mnoteOpenEditorsSnapshot = staleSnapshot; + const previous = window.__mnoteDocumentPaneRuntime || {}; + window.__mnoteDocumentPaneRuntime = { + ...previous, + getOpenEditorsSnapshot: () => staleSnapshot, + }; + }, { + staleWorkspaceId: `${workspaceId}:stale`, + documentId, + rootUri, + }); + await page.locator("[data-page-ai-input]").fill(`task504 current page target ${suffix}`, { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-panel="chat"] [data-page-ai-conversation]').getByText("TASK504_CURRENT_PAGE_OK").waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + const markdownState = await page.locator('[data-page-ai-panel="chat"] [data-page-ai-conversation]').evaluate((root) => ({ + heading: Boolean(root.querySelector(".wolai-page-ai-message--assistant .wolai-page-ai-message-text h3")), + strong: Boolean(root.querySelector(".wolai-page-ai-message--assistant .wolai-page-ai-message-text strong")), + rawHeadingMarkers: root.textContent?.includes("### TASK504_CURRENT_PAGE_OK") || false, + rawStrongMarkers: root.textContent?.includes("**Markdown 渲染**") || false, + })); + assert.deepStrictEqual(markdownState, { + heading: true, + strong: true, + rawHeadingMarkers: false, + rawStrongMarkers: false, + }, `AI 面板应渲染 Markdown,而不是显示原始标记: ${JSON.stringify(markdownState)}`); + assert.strictEqual(capturedRuns.length, 1, "当前页 ChatOnly 请求应通过前置 target 校验并到达 runs API"); + assert.strictEqual(capturedRuns[0].agentId, "chat_only", "应使用 ChatOnly agent"); + assert.strictEqual(capturedRuns[0].profile, "shared_deepseek_chat", "应使用 DeepSeek ChatOnly profile"); + assert.strictEqual( + capturedRuns[0].runTargetSnapshot?.editorTarget?.workspaceId, + workspaceId, + "只选择当前页时 runTargetSnapshot 应使用当前 workspaceId,而不是 stale active editor workspaceId", + ); + assert( + capturedRuns[0].contextRefs.some((item) => item.kind === "current_page" && item.workspaceId === workspaceId), + "当前页 contextRef 应保留当前 workspaceId", + ); + assert( + !capturedRuns[0].contextRefs.some((item) => item.kind === "active_editor"), + "取消打开资源后不应发送 active_editor contextRef", + ); + screenshots.currentPageTarget = await saveScreenshot(page, "current-page-target"); + } catch (error) { + caughtError = error; + try { + screenshots.failure = await saveScreenshot(page, "failure"); + } catch (_) {} + } finally { + await browser.close(); + const result = { + ok: !caughtError, + error: caughtError ? String(caughtError && caughtError.stack || caughtError) : null, + screenshots, + root, + capturedRuns, + }; + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + if (caughtError) { + console.error(JSON.stringify(result, null, 2)); + process.exit(1); + } + console.log(JSON.stringify(result, null, 2)); + } +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/scripts/task512-chatonly-doubao-sync-smoke.js b/scripts/task512-chatonly-doubao-sync-smoke.js new file mode 100644 index 00000000..c4f607ec --- /dev/null +++ b/scripts/task512-chatonly-doubao-sync-smoke.js @@ -0,0 +1,499 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { execFileSync } = require("node:child_process"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const TASK = "task512-chatonly-doubao-sync-smoke"; +const OUTPUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); +const CONTROL_PLANE_DB = "/mnt/Data1T/Mnote_data/control-plane/control-plane.db"; +const DOUBAO_CDP_URL = process.env.MNOTE_DOUBAO_CDP_URL || "http://127.0.0.1:9233"; +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +function sqliteJson(sql, fallback = null) { + try { + const raw = execFileSync("sqlite3", ["-json", CONTROL_PLANE_DB, sql], { + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + }).trim(); + return raw ? JSON.parse(raw) : fallback; + } catch { + return fallback; + } +} + +function sqlQuote(value) { + return `'${String(value).replaceAll("'", "''")}'`; +} + +function sqliteExec(sql) { + execFileSync("sqlite3", [CONTROL_PLANE_DB, sql], { + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + }); +} + +function grantWorkspaceAccess({ actorId, workspaceId, root, rootUri, grantId }) { + const now = new Date().toISOString(); + sqliteExec(` + INSERT OR IGNORE INTO users (id, email, username, display_name, role, status, created_at, updated_at, revision) + VALUES (${sqlQuote(actorId)}, ${sqlQuote(`${actorId}@example.com`)}, ${sqlQuote(actorId)}, ${sqlQuote(actorId)}, 'user', 'active', ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + INSERT OR REPLACE INTO workspaces (id, owner_user_id, name, kind, root_uri, root_path, source_kind, status, created_at, updated_at, revision) + VALUES (${sqlQuote(workspaceId)}, ${sqlQuote(actorId)}, 'Task512 Doubao Smoke', 'personal', ${sqlQuote(rootUri)}, ${sqlQuote(root)}, 'local_folder', 'active', ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + INSERT OR REPLACE INTO directory_grants (id, user_id, workspace_id, root_uri, root_path, permission, recursive, capabilities_json, source, status, created_by, created_at, updated_at, revision) + VALUES (${sqlQuote(grantId)}, ${sqlQuote(actorId)}, ${sqlQuote(workspaceId)}, ${sqlQuote(rootUri)}, ${sqlQuote(root)}, 'write', 1, '["ai","markdown_edit"]', 'smoke', 'active', ${sqlQuote(actorId)}, ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + `); +} + +async function firstDoubaoPage(cdpBrowser) { + for (const context of cdpBrowser.contexts()) { + const page = context.pages().find((candidate) => candidate.url().includes("doubao.com")); + if (page) return page; + } + const context = cdpBrowser.contexts()[0] || await cdpBrowser.newContext(); + const page = await context.newPage(); + await page.goto("https://www.doubao.com/chat/", { waitUntil: "domcontentloaded" }); + return page; +} + +async function installDoubaoFetchProbe(page) { + await page.evaluate(() => { + const win = window; + const shouldTrack = (url) => url.includes("/samantha/chat/completion") + || url.includes("/im/conversation/batch_del_user_conv"); + if (!win.__mnoteDoubaoOriginalFetch) { + win.__mnoteDoubaoOriginalFetch = win.fetch.bind(win); + } + win.__mnoteDoubaoFetchLog = []; + win.fetch = async function patchedMnoteDoubaoFetch(input, init) { + const url = String((input && input.url) || input || ""); + const method = String((init && init.method) || "GET").toUpperCase(); + if (shouldTrack(url)) { + win.__mnoteDoubaoFetchLog.push({ + transport: "fetch", + url, + method, + body: init && init.body ? String(init.body) : "", + ts: Date.now(), + }); + } + return win.__mnoteDoubaoOriginalFetch(input, init); + }; + if (!win.__mnoteDoubaoOriginalXHROpen && win.XMLHttpRequest) { + win.__mnoteDoubaoOriginalXHROpen = win.XMLHttpRequest.prototype.open; + win.__mnoteDoubaoOriginalXHRSend = win.XMLHttpRequest.prototype.send; + win.XMLHttpRequest.prototype.open = function patchedMnoteDoubaoXHROpen(method, url, ...rest) { + this.__mnoteDoubaoProbeMethod = String(method || "GET").toUpperCase(); + this.__mnoteDoubaoProbeUrl = String(url || ""); + return win.__mnoteDoubaoOriginalXHROpen.call(this, method, url, ...rest); + }; + win.XMLHttpRequest.prototype.send = function patchedMnoteDoubaoXHRSend(body) { + const url = String(this.__mnoteDoubaoProbeUrl || ""); + if (shouldTrack(url)) { + win.__mnoteDoubaoFetchLog.push({ + transport: "xhr", + url, + method: String(this.__mnoteDoubaoProbeMethod || "GET").toUpperCase(), + body: body ? String(body) : "", + ts: Date.now(), + }); + } + return win.__mnoteDoubaoOriginalXHRSend.call(this, body); + }; + } + }); +} + +async function readDoubaoFetchLog(page) { + return await page.evaluate(() => Array.isArray(window.__mnoteDoubaoFetchLog) + ? window.__mnoteDoubaoFetchLog + : []); +} + +async function readDoubaoConversationStats(page, { marker, prompt }) { + return await page.evaluate(({ marker, prompt }) => { + const normalize = (value) => String(value || "").replace(/\s+/g, " ").trim(); + const markerText = String(marker || ""); + const promptText = String(prompt || ""); + const userBubbleTexts = Array.from(document.querySelectorAll(".bg-g-send-msg-bubble-bg")) + .map((node) => normalize(node.textContent)); + const assistantMarkdownTexts = Array.from(document.querySelectorAll(".md-box-root")) + .map((node) => normalize(node.textContent)); + return { + userPromptCount: userBubbleTexts.filter((text) => text === normalize(promptText)).length, + userMarkerCount: userBubbleTexts.filter((text) => text.includes(markerText)).length, + assistantMarkerCount: assistantMarkdownTexts.filter((text) => text.includes(markerText)).length, + userBubbleTexts, + assistantMarkdownTexts, + }; + }, { marker, prompt }); +} + +async function saveScreenshot(page, name) { + const target = path.join(OUTPUT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: false }); + return target; +} + +function doubaoConversationUrl(remoteConversationId) { + return `https://www.doubao.com/chat/${encodeURIComponent(remoteConversationId)}`; +} + +async function captureDoubaoPage(page, { name, url, remoteConversationId = "" }) { + let navigationError = ""; + if (url) { + await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60_000 }).catch((error) => { + navigationError = error instanceof Error ? error.message : String(error); + }); + } + await page.bringToFront().catch(() => {}); + await page.waitForTimeout(2500); + const screenshot = await saveScreenshot(page, name); + const title = await page.title().catch(() => ""); + const pageUrl = page.url(); + const visibleText = await page.locator("body").innerText({ timeout: 5000 }).catch(() => ""); + const conversationRowCount = remoteConversationId + ? await page.locator(`#conversation_${remoteConversationId}`).count().catch(() => -1) + : null; + return { + screenshot, + requestedUrl: url || "", + pageUrl, + title, + navigationError, + conversationRowCount, + visibleText: visibleText.slice(0, 2000), + }; +} + +async function main() { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + const suffix = Date.now().toString(36); + const actorId = "mnote-e2e"; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task512-doubao-")); + const rootUri = fileUrl(root); + const workspaceId = `local-ws:${actorId}:task512-${suffix}`; + const relativePath = "DoubaoChatOnlySync.md"; + const marker = `MNOTE_DOUBAO_SYNC_${suffix.toUpperCase()}`; + const prompt = `请只回复以下字符串,不要添加空格或其他内容:${marker}`; + const screenshots = {}; + const providerCaptures = {}; + const runRequests = []; + const deleteResponses = []; + let caughtError = null; + + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, relativePath), ["# Doubao ChatOnly Sync", "", marker, ""].join("\n"), "utf8"); + grantWorkspaceAccess({ + actorId, + workspaceId, + root, + rootUri, + grantId: `grant_task512_${suffix}`, + }); + + const doubaoBrowser = await chromium.connectOverCDP(DOUBAO_CDP_URL); + const doubaoPage = await firstDoubaoPage(doubaoBrowser); + await doubaoPage.goto("https://www.doubao.com/chat/", { + waitUntil: "domcontentloaded", + timeout: 60_000, + }).catch(() => {}); + await doubaoPage.keyboard.press("Escape").catch(() => {}); + await installDoubaoFetchProbe(doubaoPage); + + const browser = await chromium.launch({ + headless: true, + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + try { + await page.route("**/api/hermes/client/runs", async (route) => { + runRequests.push(JSON.parse(route.request().postData() || "{}")); + await route.continue(); + }); + page.on("response", async (response) => { + const url = response.url(); + const request = response.request(); + if (request.method() === "DELETE" && url.includes("/api/hermes/client/sessions/")) { + deleteResponses.push({ + url, + status: response.status(), + body: await response.text().catch(() => ""), + }); + } + }); + + await ensureAuthenticated(page, context.request); + const response = await page.goto(documentUrl(root, relativePath), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator('[data-testid="mnote-leptos-tiptap-island-editor-root"] .ProseMirror').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="new-session"]').click({ + timeout: UI_TIMEOUT_MS, + }); + await page.locator("[data-page-ai-agent-button]").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-agent-id="chat_only"][data-page-ai-profile-id="shared_doubao_chat"]').click({ + timeout: UI_TIMEOUT_MS, + }); + await page.waitForFunction( + () => document.querySelector("[data-page-ai-agent-chip]")?.textContent?.includes("ChatOnly / 豆包"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + + await page.locator("[data-page-ai-input]").fill(prompt, { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + const replyState = await page.waitForFunction( + (expectedMarker) => { + const assistantText = Array.from(document.querySelectorAll(".wolai-page-ai-message--assistant")) + .map((node) => node.textContent || "") + .join("\n"); + if (assistantText.includes(expectedMarker)) return "marker"; + if (assistantText.includes("豆包暂时无法回复")) return "provider_error"; + return ""; + }, + marker, + { timeout: 180_000 }, + ).then((handle) => handle.jsonValue()); + await page.waitForFunction( + () => (document.querySelector("[data-page-ai-run-status]")?.textContent || "").includes("完成"), + null, + { timeout: 180_000 }, + ).catch(() => {}); + screenshots.afterMessage = await saveScreenshot(page, "after-message"); + + assert.strictEqual(runRequests.length, 1, "MNote 本轮应只创建一个 run"); + const run = runRequests[0]; + assert.strictEqual(run.agentId, "chat_only", "应使用 ChatOnly agent"); + assert.strictEqual(run.profileId, "shared_doubao_chat", "应使用豆包 ChatOnly profile"); + assert.strictEqual(run.acpRuntime, "hermes", "豆包 ChatOnly 应走 Hermes/OpenClaw runtime"); + assert(run.sessionId, "run payload 应包含 MNote sessionId"); + + const logAfterMessage = await readDoubaoFetchLog(doubaoPage); + const completionCalls = logAfterMessage.filter((entry) => entry.url.includes("/samantha/chat/completion")); + assert.strictEqual(completionCalls.length, 0, "豆包 ChatOnly 应走真实 UI 发送,不应再直调 samantha completion"); + assert.notStrictEqual(replyState, "provider_error", "豆包返回限流/风控错误,未产生本轮 marker 回复"); + + const visibleAssistantTexts = await page.locator(".wolai-page-ai-message--assistant").allTextContents(); + const markerAssistantCount = visibleAssistantTexts.filter((text) => text.includes(marker)).length; + assert.strictEqual(markerAssistantCount, 1, "MNote 可见豆包回复应只有一条"); + + const sessionId = String(run.sessionId); + const bindingRows = sqliteJson( + `SELECT mnote_session_id, remote_conversation_id, status FROM ai_external_conversation_bindings WHERE user_id='${actorId}' AND mnote_session_id='${sessionId}' AND provider='doubao-web' ORDER BY updated_at DESC LIMIT 1;`, + [], + ); + assert(bindingRows && bindingRows.length === 1, "SQLite 应保存豆包远端会话绑定"); + assert.strictEqual(bindingRows[0].status, "active", "删除前 binding 应为 active"); + const remoteConversationId = bindingRows[0].remote_conversation_id; + assert(remoteConversationId, "binding 应包含 remote_conversation_id"); + + providerCaptures.afterMessage = await captureDoubaoPage(doubaoPage, { + name: "doubao-after-message", + url: doubaoConversationUrl(remoteConversationId), + remoteConversationId, + }); + const doubaoMessageStats = await readDoubaoConversationStats(doubaoPage, { marker, prompt }); + screenshots.doubaoAfterMessage = providerCaptures.afterMessage.screenshot; + assert( + providerCaptures.afterMessage.pageUrl.includes(remoteConversationId), + "豆包截图应定位到本轮远端 conversation_id", + ); + assert( + providerCaptures.afterMessage.visibleText.includes(marker), + "豆包本轮远端会话页面应显示 marker", + ); + assert.strictEqual( + providerCaptures.afterMessage.conversationRowCount, + 1, + "豆包删除前左侧历史列表应存在本轮 conversation 行", + ); + assert.strictEqual( + doubaoMessageStats.userPromptCount, + 1, + "豆包网页端本轮用户消息应只有一条", + ); + assert.strictEqual( + doubaoMessageStats.userMarkerCount, + 1, + "豆包网页端不应把豆包回复再次作为用户消息发送", + ); + assert.strictEqual( + doubaoMessageStats.assistantMarkerCount, + 1, + "豆包网页端本轮助手回复应只有一条", + ); + + await installDoubaoFetchProbe(doubaoPage); + + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="history"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-panel="history"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-session-row="${sessionId}"]`).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + page.once("dialog", async (dialog) => { + await dialog.accept(); + }); + await page.locator(`[data-page-ai-session-delete="${sessionId}"]`).click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + (id) => !document.querySelector(`[data-page-ai-session-row="${CSS.escape(id)}"]`), + sessionId, + { timeout: UI_TIMEOUT_MS }, + ); + screenshots.afterDelete = await saveScreenshot(page, "after-delete"); + + await page.waitForTimeout(1000); + const logAfterDelete = await readDoubaoFetchLog(doubaoPage); + const deleteCalls = logAfterDelete.filter((entry) => entry.url.includes("/im/conversation/batch_del_user_conv")); + assert.strictEqual(deleteCalls.length, 1, "豆包端本轮只能收到一次会话删除请求"); + assert(deleteCalls[0].body.includes(remoteConversationId), "豆包删除请求应包含绑定的远端 conversation_id"); + assert(deleteResponses.length >= 1, "MNote 应发出历史会话 DELETE 请求"); + assert.strictEqual(deleteResponses.at(-1).status, 200, "MNote 历史会话 DELETE 应成功"); + const deleteBody = JSON.parse(deleteResponses.at(-1).body || "{}"); + assert.strictEqual( + deleteBody?.result?.providerConversationDelete?.response?.result?.providerDeleteMode, + "doubao_sidebar_menu", + "豆包远端删除必须走左侧会话三点菜单 + 确认弹窗路径", + ); + + providerCaptures.afterDelete = await captureDoubaoPage(doubaoPage, { + name: "doubao-after-delete", + url: "https://www.doubao.com/chat/", + remoteConversationId, + }); + screenshots.doubaoAfterDelete = providerCaptures.afterDelete.screenshot; + assert( + !providerCaptures.afterDelete.visibleText.includes(marker), + "豆包删除后聊天入口不应继续显示本轮 marker", + ); + assert.strictEqual( + providerCaptures.afterDelete.conversationRowCount, + 0, + "豆包删除后左侧历史列表不应继续存在本轮 conversation 行", + ); + + const deletedRows = sqliteJson( + `SELECT mnote_session_id, remote_conversation_id, status, metadata_json FROM ai_external_conversation_bindings WHERE user_id='${actorId}' AND mnote_session_id='${sessionId}' AND provider='doubao-web' ORDER BY updated_at DESC LIMIT 1;`, + [], + ); + assert(deletedRows && deletedRows.length === 1, "删除后 binding 仍应可审计"); + assert.strictEqual(deletedRows[0].status, "remote_deleted", "删除后 binding 应标记 remote_deleted"); + + fs.writeFileSync( + RESULT_PATH, + `${JSON.stringify({ + ok: true, + marker, + sessionId, + remoteConversationId, + samanthaCompletionCallCount: completionCalls.length, + doubaoMessageStats, + deleteCallCount: deleteCalls.length, + deleteResponse: deleteResponses.at(-1), + bindingBefore: bindingRows[0], + bindingAfter: deletedRows[0], + screenshots, + providerCaptures, + }, null, 2)}\n`, + "utf8", + ); + } catch (error) { + caughtError = error; + screenshots.failure = await saveScreenshot(page, "failure").catch(() => ""); + providerCaptures.failure = await captureDoubaoPage(doubaoPage, { + name: "doubao-failure", + url: "", + }).catch((captureError) => ({ + screenshot: "", + requestedUrl: "", + pageUrl: "", + title: "", + navigationError: captureError instanceof Error ? captureError.message : String(captureError), + visibleText: "", + })); + if (providerCaptures.failure.screenshot) { + screenshots.doubaoFailure = providerCaptures.failure.screenshot; + } + fs.writeFileSync( + RESULT_PATH, + `${JSON.stringify({ + ok: false, + marker, + error: error instanceof Error ? error.stack || error.message : String(error), + runRequests, + deleteResponses, + doubaoFetchLog: await readDoubaoFetchLog(doubaoPage).catch(() => []), + screenshots, + providerCaptures, + }, null, 2)}\n`, + "utf8", + ); + } finally { + await browser.close().catch(() => {}); + await doubaoBrowser.close().catch(() => {}); + } + + if (caughtError) throw caughtError; + console.log(JSON.stringify(JSON.parse(fs.readFileSync(RESULT_PATH, "utf8")), null, 2)); +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task513-chatonly-provider-sync-smoke.js b/scripts/task513-chatonly-provider-sync-smoke.js new file mode 100644 index 00000000..ea8e4545 --- /dev/null +++ b/scripts/task513-chatonly-provider-sync-smoke.js @@ -0,0 +1,512 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { execFileSync } = require("node:child_process"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const PROVIDERS = { + deepseek: { + taskName: "task513-chatonly-deepseek-sync-smoke", + title: "DeepSeek ChatOnly Sync", + agentProfileId: "shared_deepseek_chat", + chipText: "ChatOnly / DeepSeek", + expectedProvider: "deepseek-web", + gatewayLog: "/home/lix/.openclaw-mnote-deepseek-chat/logs/gateway.out", + sendLogPattern: /\[DeepSeekWebClient\] Sending chat completion request/g, + configPath: "/home/lix/.openclaw-mnote-deepseek-chat/openclaw.json", + }, + gemini: { + taskName: "task513-chatonly-gemini-sync-smoke", + title: "Gemini ChatOnly Sync", + agentProfileId: "shared_gemini_chat", + chipText: "ChatOnly / Gemini", + expectedProvider: "gemini-web", + gatewayLog: "/home/lix/.openclaw-mnote-gemini-chat/logs/gateway.out", + sendLogPattern: /\[Gemini Web Browser\] DOM: typed message and pressed Enter/g, + cdpUrl: process.env.MNOTE_GEMINI_CDP_URL || "http://127.0.0.1:9232", + }, +}; + +const providerKey = process.argv[2] || process.env.MNOTE_CHATONLY_PROVIDER || "deepseek"; +const provider = PROVIDERS[providerKey]; +if (!provider) { + throw new Error(`未知 provider: ${providerKey}`); +} + +const OUTPUT_DIR = path.join(process.cwd(), "tmp", provider.taskName); +const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); +const CONTROL_PLANE_DB = "/mnt/Data1T/Mnote_data/control-plane/control-plane.db"; +const CHROMIUM_EXECUTABLE_PATH = + process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || + [ + "/usr/bin/google-chrome-stable", + "/usr/bin/google-chrome", + "/snap/bin/chromium", + "/usr/bin/chromium", + ].find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +function sqliteJson(sql, fallback = null) { + try { + const raw = execFileSync("sqlite3", ["-json", CONTROL_PLANE_DB, sql], { + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + }).trim(); + return raw ? JSON.parse(raw) : fallback; + } catch { + return fallback; + } +} + +function sqlQuote(value) { + return `'${String(value).replaceAll("'", "''")}'`; +} + +function sqliteExec(sql) { + execFileSync("sqlite3", [CONTROL_PLANE_DB, sql], { + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + }); +} + +function grantWorkspaceAccess({ actorId, workspaceId, root, rootUri, grantId }) { + const now = new Date().toISOString(); + sqliteExec(` + INSERT OR IGNORE INTO users (id, email, username, display_name, role, status, created_at, updated_at, revision) + VALUES (${sqlQuote(actorId)}, ${sqlQuote(`${actorId}@example.com`)}, ${sqlQuote(actorId)}, ${sqlQuote(actorId)}, 'user', 'active', ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + INSERT OR REPLACE INTO workspaces (id, owner_user_id, name, kind, root_uri, root_path, source_kind, status, created_at, updated_at, revision) + VALUES (${sqlQuote(workspaceId)}, ${sqlQuote(actorId)}, ${sqlQuote(actorId)}, 'personal', ${sqlQuote(rootUri)}, ${sqlQuote(root)}, 'local_folder', 'active', ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + INSERT OR REPLACE INTO directory_grants (id, user_id, workspace_id, root_uri, root_path, permission, recursive, capabilities_json, source, status, created_by, created_at, updated_at, revision) + VALUES (${sqlQuote(grantId)}, ${sqlQuote(actorId)}, ${sqlQuote(workspaceId)}, ${sqlQuote(rootUri)}, ${sqlQuote(root)}, 'write', 1, '["ai","markdown_edit"]', 'smoke', 'active', ${sqlQuote(actorId)}, ${sqlQuote(now)}, ${sqlQuote(now)}, 1); + `); +} + +function logSize(logPath) { + try { + return fs.statSync(logPath).size; + } catch { + return 0; + } +} + +function readLogSince(logPath, offset) { + try { + const fd = fs.openSync(logPath, "r"); + const stat = fs.fstatSync(fd); + const start = offset > stat.size ? 0 : offset; + const buffer = Buffer.alloc(stat.size - start); + fs.readSync(fd, buffer, 0, buffer.length, start); + fs.closeSync(fd); + return buffer.toString("utf8"); + } catch { + return ""; + } +} + +function countMatches(text, pattern) { + return Array.from(String(text || "").matchAll(pattern)).length; +} + +function escapeRegExp(value) { + return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +function parseCookieString(cookieString, domain) { + return String(cookieString || "") + .split(";") + .filter((cookie) => cookie.trim().includes("=")) + .map((cookie) => { + const [name, ...valueParts] = cookie.trim().split("="); + return { + name: name.trim(), + value: valueParts.join("=").trim(), + domain, + path: "/", + }; + }) + .filter((cookie) => cookie.name); +} + +function deepseekAuth() { + const config = JSON.parse(fs.readFileSync(provider.configPath, "utf8")); + return JSON.parse(config.models.providers["deepseek-web"].apiKey || "{}"); +} + +async function saveScreenshot(page, name) { + const target = path.join(OUTPUT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: false }); + return target; +} + +async function captureDeepseek(remoteConversationId, name) { + const auth = deepseekAuth(); + const browser = await chromium.launch({ + headless: true, + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + userAgent: auth.userAgent, + }); + await context.addCookies(parseCookieString(auth.cookie, ".deepseek.com")); + if (auth.bearer) { + await context.addInitScript((token) => { + localStorage.setItem("userToken", JSON.stringify({ value: token, __version: "0" })); + }, auth.bearer); + } + const page = await context.newPage(); + if (auth.bearer) { + await page.route("https://chat.deepseek.com/api/**", (route) => { + route.continue({ + headers: { + ...route.request().headers(), + authorization: `Bearer ${auth.bearer}`, + }, + }); + }); + } + const url = `https://chat.deepseek.com/a/chat/s/${remoteConversationId}`; + await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60_000 }).catch(() => {}); + await page.waitForTimeout(2500); + const screenshot = await saveScreenshot(page, name); + const title = await page.title().catch(() => ""); + const visibleText = await page.locator("body").innerText({ timeout: 5000 }).catch(() => ""); + const conversationLinkCount = await page + .locator(`a[href*="/a/chat/s/${remoteConversationId}"]`) + .count() + .catch(() => -1); + await browser.close().catch(() => {}); + return { + screenshot, + url, + title, + conversationLinkCount, + conversationMissingText: visibleText.includes("该对话不存在"), + visibleText: visibleText.slice(0, 1000), + }; +} + +async function firstGeminiPage(cdpBrowser, remoteConversationId) { + const targetUrl = String(remoteConversationId || ""); + for (const context of cdpBrowser.contexts()) { + const exact = context.pages().find((candidate) => candidate.url().split("#")[0] === targetUrl); + if (exact) return exact; + const gemini = context.pages().find((candidate) => candidate.url().includes("gemini.google.com")); + if (gemini) return gemini; + } + const context = cdpBrowser.contexts()[0] || await cdpBrowser.newContext(); + return await context.newPage(); +} + +async function captureGemini(remoteConversationId, name) { + const browser = await chromium.connectOverCDP(provider.cdpUrl); + const page = await firstGeminiPage(browser, remoteConversationId); + const targetUrl = String(remoteConversationId || ""); + if (targetUrl && page.url().split("#")[0] !== targetUrl) { + await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 60_000 }).catch(() => {}); + await page.waitForTimeout(1500); + } + await page.bringToFront().catch(() => {}); + await page.waitForTimeout(1000); + const screenshot = await saveScreenshot(page, name); + const title = await page.title().catch(() => ""); + const visibleText = await page.locator("body").innerText({ timeout: 5000 }).catch(() => ""); + const conversationLinkCount = await page.evaluate((target) => { + let targetPath = ""; + try { + targetPath = new URL(target).pathname; + } catch { + return -1; + } + return Array.from(document.querySelectorAll("a[href]")).filter((anchor) => { + try { + return new URL(anchor.href, location.href).pathname === targetPath; + } catch { + return false; + } + }).length; + }, targetUrl).catch(() => -1); + await browser.close().catch(() => {}); + return { + screenshot, + url: page.url(), + title, + conversationLinkCount, + visibleText: visibleText.slice(0, 1000), + }; +} + +async function captureProvider(remoteConversationId, name) { + if (providerKey === "deepseek") return await captureDeepseek(remoteConversationId, name); + return await captureGemini(remoteConversationId, name); +} + +async function main() { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + const suffix = Date.now().toString(36); + const actorId = "mnote-e2e"; + const root = fs.mkdtempSync(path.join(os.tmpdir(), `mnote-task513-${providerKey}-`)); + const rootUri = fileUrl(root); + const workspaceId = `local-ws:${actorId}:task513-${providerKey}-${suffix}`; + const relativePath = `${providerKey}-ChatOnlySync.md`; + const marker = `MNOTE_CHATONLY_SYNC_${suffix}`; + const screenshots = {}; + const providerCaptures = {}; + const runRequests = []; + const deleteResponses = []; + const gatewayLogOffset = logSize(provider.gatewayLog); + let caughtError = null; + + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, relativePath), [`# ${provider.title}`, "", marker, ""].join("\n"), "utf8"); + grantWorkspaceAccess({ + actorId, + workspaceId, + root, + rootUri, + grantId: `grant_task513_${providerKey}_${suffix}`, + }); + + const browser = await chromium.launch({ + headless: true, + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + try { + await page.route("**/api/hermes/client/runs", async (route) => { + runRequests.push(JSON.parse(route.request().postData() || "{}")); + await route.continue(); + }); + page.on("response", async (response) => { + const url = response.url(); + const request = response.request(); + if (request.method() === "DELETE" && url.includes("/api/hermes/client/sessions/")) { + deleteResponses.push({ + url, + status: response.status(), + body: await response.text().catch(() => ""), + }); + } + }); + + await ensureAuthenticated(page, context.request); + const response = await page.goto(documentUrl(root, relativePath), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator('[data-testid="mnote-leptos-tiptap-island-editor-root"] .ProseMirror').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="new-session"]').click({ + timeout: UI_TIMEOUT_MS, + }); + await page.locator("[data-page-ai-agent-button]").click({ timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-agent-id="chat_only"][data-page-ai-profile-id="${provider.agentProfileId}"]`).click({ + timeout: UI_TIMEOUT_MS, + }); + await page.waitForFunction( + (expected) => document.querySelector("[data-page-ai-agent-chip]")?.textContent?.includes(expected), + provider.chipText, + { timeout: UI_TIMEOUT_MS }, + ); + + await page.locator("[data-page-ai-input]").fill(`请只回复:${marker}`, { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + (expectedMarker) => { + const assistantText = Array.from(document.querySelectorAll(".wolai-page-ai-message--assistant")) + .map((node) => node.textContent || "") + .join("\n"); + return assistantText.includes(expectedMarker); + }, + marker, + { timeout: 180_000 }, + ); + await page.waitForFunction( + () => (document.querySelector("[data-page-ai-run-status]")?.textContent || "").includes("完成"), + null, + { timeout: 180_000 }, + ).catch(() => {}); + screenshots.afterMessage = await saveScreenshot(page, "after-message"); + + assert.strictEqual(runRequests.length, 1, "MNote 本轮应只创建一个 run"); + const run = runRequests[0]; + assert.strictEqual(run.agentId, "chat_only", "应使用 ChatOnly agent"); + assert.strictEqual(run.profileId, provider.agentProfileId, `应使用 ${provider.title} profile`); + assert.strictEqual(run.acpRuntime, "hermes", "ChatOnly 网页 provider 应走 Hermes/OpenClaw runtime"); + assert(run.sessionId, "run payload 应包含 MNote sessionId"); + + const visibleAssistantTexts = await page.locator(".wolai-page-ai-message--assistant").allTextContents(); + const markerAssistantCount = visibleAssistantTexts.filter((text) => text.includes(marker)).length; + assert.strictEqual(markerAssistantCount, 1, "MNote 可见 provider 回复应只有一条"); + + const sessionId = String(run.sessionId); + const bindingRows = sqliteJson( + `SELECT mnote_session_id, remote_conversation_id, status FROM ai_external_conversation_bindings WHERE user_id=${sqlQuote(actorId)} AND mnote_session_id=${sqlQuote(sessionId)} AND provider=${sqlQuote(provider.expectedProvider)} ORDER BY updated_at DESC LIMIT 1;`, + [], + ); + assert(bindingRows && bindingRows.length === 1, "SQLite 应保存远端会话绑定"); + assert.strictEqual(bindingRows[0].status, "active", "删除前 binding 应为 active"); + const remoteConversationId = bindingRows[0].remote_conversation_id; + assert(remoteConversationId, "binding 应包含 remote_conversation_id"); + + providerCaptures.afterMessage = await captureProvider(remoteConversationId, `${providerKey}-after-message`); + + await page.locator('.wolai-page-ai-header-actions [data-page-ai-action="history"]').click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-panel="history"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await page.locator(`[data-page-ai-session-row="${sessionId}"]`).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + page.once("dialog", async (dialog) => { + await dialog.accept(); + }); + await page.locator(`[data-page-ai-session-delete="${sessionId}"]`).click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + (id) => !document.querySelector(`[data-page-ai-session-row="${CSS.escape(id)}"]`), + sessionId, + { timeout: UI_TIMEOUT_MS }, + ); + screenshots.afterDelete = await saveScreenshot(page, "after-delete"); + + assert(deleteResponses.length >= 1, "MNote 应发出历史会话 DELETE 请求"); + assert.strictEqual(deleteResponses.at(-1).status, 200, "MNote 历史会话 DELETE 应成功"); + const deleteBody = JSON.parse(deleteResponses.at(-1).body || "{}"); + assert.strictEqual( + deleteBody?.result?.providerConversationDelete?.status, + "remote_deleted", + "provider 删除应返回 remote_deleted", + ); + const providerDeleteMode = deleteBody?.result?.providerConversationDelete?.response?.result?.providerDeleteMode; + if (providerKey === "deepseek") { + assert.strictEqual( + providerDeleteMode, + "deepseek_chat_session_delete_api", + "DeepSeek 删除应明确走 chat_session_delete_api 并由网页复核", + ); + } else { + assert.strictEqual( + providerDeleteMode, + "gemini_conversation_menu", + "Gemini 删除应走网页对话菜单确认路径", + ); + } + + await page.waitForTimeout(1500); + providerCaptures.afterDelete = await captureProvider(remoteConversationId, `${providerKey}-after-delete`); + assert.strictEqual( + providerCaptures.afterDelete.conversationLinkCount, + 0, + "provider 删除后网页历史中不应继续存在本轮远端会话链接", + ); + + const deletedRows = sqliteJson( + `SELECT mnote_session_id, remote_conversation_id, status, metadata_json FROM ai_external_conversation_bindings WHERE user_id=${sqlQuote(actorId)} AND mnote_session_id=${sqlQuote(sessionId)} AND provider=${sqlQuote(provider.expectedProvider)} ORDER BY updated_at DESC LIMIT 1;`, + [], + ); + assert(deletedRows && deletedRows.length === 1, "删除后 binding 仍应可审计"); + assert.strictEqual(deletedRows[0].status, "remote_deleted", "删除后 binding 应标记 remote_deleted"); + + const providerLog = readLogSince(provider.gatewayLog, gatewayLogOffset); + let providerSendCount = countMatches(providerLog, provider.sendLogPattern); + if (providerKey === "gemini" && providerSendCount === 0) { + const fullProviderLog = readLogSince(provider.gatewayLog, 0); + providerSendCount = countMatches(fullProviderLog, new RegExp(escapeRegExp(marker), "g")); + } + assert.strictEqual(providerSendCount, 1, "provider 本轮只能收到一次发送动作"); + + fs.writeFileSync( + RESULT_PATH, + `${JSON.stringify({ + ok: true, + provider: providerKey, + marker, + sessionId, + remoteConversationId, + providerSendCount, + deleteResponse: deleteResponses.at(-1), + bindingBefore: bindingRows[0], + bindingAfter: deletedRows[0], + screenshots, + providerCaptures, + }, null, 2)}\n`, + "utf8", + ); + } catch (error) { + caughtError = error; + screenshots.failure = await saveScreenshot(page, "failure").catch(() => ""); + fs.writeFileSync( + RESULT_PATH, + `${JSON.stringify({ + ok: false, + provider: providerKey, + marker, + error: error instanceof Error ? error.stack || error.message : String(error), + runRequests, + deleteResponses, + screenshots, + gatewayLog: readLogSince(provider.gatewayLog, gatewayLogOffset).slice(-8000), + }, null, 2)}\n`, + "utf8", + ); + } finally { + await browser.close().catch(() => {}); + } + + if (caughtError) throw caughtError; + console.log(JSON.stringify(JSON.parse(fs.readFileSync(RESULT_PATH, "utf8")), null, 2)); +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task514-sidebar-dev-hot-reload-gating-smoke.js b/scripts/task514-sidebar-dev-hot-reload-gating-smoke.js new file mode 100644 index 00000000..26c87900 --- /dev/null +++ b/scripts/task514-sidebar-dev-hot-reload-gating-smoke.js @@ -0,0 +1,141 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const { spawn } = require("node:child_process"); +const net = require("node:net"); +const { chromium } = require("playwright"); + +const UI_TIMEOUT_MS = Number(process.env.MNOTE_UI_TIMEOUT_MS || 45000); + +function findFreePort() { + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.listen(0, "127.0.0.1", () => { + const port = server.address().port; + server.close(() => resolve(port)); + }); + server.on("error", reject); + }); +} + +async function waitForGateway(baseUrl, timeoutMs = 120000) { + const deadline = Date.now() + timeoutMs; + let lastError = ""; + while (Date.now() < deadline) { + try { + const response = await fetch(`${baseUrl}/`, { + headers: { + "x-mnote-actor-id": "mnote-e2e", + "x-mnote-actor-type": "user", + }, + }); + if (response.status === 200 || response.status === 303) return; + lastError = `${response.status} ${await response.text().catch(() => "")}`; + } catch (error) { + lastError = error && error.message ? error.message : String(error); + } + await new Promise((resolve) => setTimeout(resolve, 500)); + } + throw new Error(`mnote-web 未就绪: ${lastError}`); +} + +function startGateway(port, devHot) { + const env = { + ...process.env, + MNOTE_WEB_BIND: `127.0.0.1:${port}`, + MNOTE_WEB_PUBLIC_BIND: `127.0.0.1:${port}`, + MNOTE_WEB_ALLOW_DEV_FIXTURES: "1", + MNOTE_WEB_LEGACY_NEXT_BASE_URL: "http://127.0.0.1:3100", + MNOTE_WEB_ENABLE_LEGACY_NEXT_COMPAT: "1", + }; + delete env.MNOTE_WEB_DEV_HOT_RELOAD; + if (devHot) env.MNOTE_WEB_DEV_HOT_RELOAD = "1"; + const child = spawn("cargo", ["run", "-q", "-p", "mnote-web", "--bin", "mnote-web"], { + cwd: "/mnt/Data1T/mnote/rust", + env, + stdio: ["ignore", "pipe", "pipe"], + }); + let stderr = ""; + child.stderr.on("data", (chunk) => { + stderr += chunk.toString("utf8"); + }); + child.stdout.on("data", () => {}); + return { + child, + stderr: () => stderr, + }; +} + +async function stopGateway(gateway) { + if (!gateway || gateway.child.killed) return; + gateway.child.kill("SIGTERM"); + await new Promise((resolve) => setTimeout(resolve, 500)); + if (!gateway.child.killed) gateway.child.kill("SIGKILL"); +} + +async function verifyCase(devHot) { + const port = await findFreePort(); + const baseUrl = `http://127.0.0.1:${port}`; + const gateway = startGateway(port, devHot); + try { + await waitForGateway(baseUrl); + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext({ + extraHTTPHeaders: { + "x-mnote-actor-id": "mnote-e2e", + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + const hotReloadRequests = []; + const networkFailures = []; + const consoleErrors = []; + page.on("request", (request) => { + if (request.url().includes("/api/dev/hot-reload")) hotReloadRequests.push(request.url()); + }); + page.on("requestfailed", (request) => { + networkFailures.push({ url: request.url(), failure: request.failure()?.errorText || "" }); + }); + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + await page.goto(`${baseUrl}/`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + await page.locator('body[data-mnote-shell="workspace"]').waitFor({ state: "attached", timeout: UI_TIMEOUT_MS }); + await page.waitForTimeout(1800); + const html = await page.content(); + const shell = await page.locator("body").getAttribute("data-mnote-shell"); + const devHotAttr = await page.locator("html").getAttribute("data-mnote-dev-hot-reload").catch(() => null); + await browser.close(); + return { + devHot, + baseUrl, + shell, + scriptHasDevHot: html.includes("sidebar-tree-runtime.js?devHot="), + hotReloadRequestCount: hotReloadRequests.length, + hotReloadAttr: devHotAttr || "", + networkFailures, + consoleErrors, + }; + } finally { + await stopGateway(gateway); + } +} + +async function main() { + const normal = await verifyCase(false); + const hot = await verifyCase(true); + assert.equal(normal.shell, "workspace", JSON.stringify(normal)); + assert.equal(normal.scriptHasDevHot, false, JSON.stringify(normal)); + assert.equal(normal.hotReloadRequestCount, 0, JSON.stringify(normal)); + assert.equal(hot.shell, "workspace", JSON.stringify(hot)); + assert.equal(hot.scriptHasDevHot, true, JSON.stringify(hot)); + assert(hot.hotReloadRequestCount >= 1, JSON.stringify(hot)); + assert.equal(hot.hotReloadAttr, "enabled", JSON.stringify(hot)); + console.log(JSON.stringify({ ok: true, task: "task514-sidebar-dev-hot-reload-gating-smoke", normal, hot }, null, 2)); +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task515-onlyoffice-live-scope-http-smoke.js b/scripts/task515-onlyoffice-live-scope-http-smoke.js new file mode 100644 index 00000000..7ebfd1f1 --- /dev/null +++ b/scripts/task515-onlyoffice-live-scope-http-smoke.js @@ -0,0 +1,188 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); + +const BASE_URL = (process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); + +async function requestJson(path, init = {}) { + const response = await fetch(`${BASE_URL}${path}`, { + ...init, + headers: { + "content-type": "application/json", + "x-mnote-actor-id": "user_1", + ...(init.headers || {}), + }, + }); + const text = await response.text(); + let payload = null; + try { + payload = text ? JSON.parse(text) : null; + } catch (_) { + payload = { raw: text }; + } + return { + status: response.status, + headers: Object.fromEntries(response.headers.entries()), + payload, + }; +} + +function callPayload(sessionId, args, toolName = "mnote.onlyoffice.sheet.set_value") { + return { + toolName, + workspaceId: "ws_demo", + documentId: "doc_1", + actorId: "user_1", + sessionId, + runId: `${sessionId}-run`, + toolCallId: `${sessionId}-call`, + traceId: `${sessionId}-trace`, + idempotencyKey: `${sessionId}-idem`, + dryRun: true, + capabilityScope: ["office.write"], + args, + }; +} + +async function main() { + const suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`; + const bridgeSessionId = `mnote-oo-http-${suffix}`; + const bridgeToken = `token-${suffix}`; + const register = await requestJson("/api/onlyoffice/bridge/session", { + method: "POST", + body: JSON.stringify({ + sessionId: bridgeSessionId, + token: bridgeToken, + editorType: "cell", + documentId: "doc_http", + assetId: "asset_http_allowed", + fileType: "xlsx", + }), + }); + assert.equal(register.status, 200, JSON.stringify(register)); + assert.equal(register.payload.sessionId, bridgeSessionId); + + const implicit = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_implicit", { + address: "A1", + value: "after", + })), + }); + assert.equal(implicit.status, 400, JSON.stringify(implicit)); + assert.equal(implicit.headers["x-error-code"], "mnote_onlyoffice_session_explicit_required"); + + const forbidden = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_forbidden", { + onlyofficeSessionId: bridgeSessionId, + address: "A1", + value: "after", + aiAccessScope: { + permissionLevel: "read_write", + allowedResourceIds: ["asset_other"], + }, + })), + }); + assert.equal(forbidden.status, 403, JSON.stringify(forbidden)); + assert.equal(forbidden.headers["x-error-code"], "mnote_onlyoffice_resource_scope_forbidden"); + + const missingScope = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_missing_scope", { + onlyofficeSessionId: bridgeSessionId, + address: "A1", + value: "after", + })), + }); + assert.equal(missingScope.status, 403, JSON.stringify(missingScope)); + assert.equal(missingScope.headers["x-error-code"], "mnote_onlyoffice_resource_scope_required"); + + const allowed = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_allowed", { + onlyofficeSessionId: bridgeSessionId, + address: "A1", + value: "after", + aiAccessScope: { + permissionLevel: "read_write", + allowedResourceIds: ["asset_http_allowed"], + }, + })), + }); + assert.equal(allowed.status, 200, JSON.stringify(allowed)); + assert.equal(allowed.payload.result.schema, "mnote.onlyoffice.action_plan.v1"); + assert.equal(allowed.payload.result.sessionId, bridgeSessionId); + assert.equal(allowed.payload.result.action, "sheet.set_value"); + assert.equal(allowed.payload.audit.effect, "dry_run"); + + const currentImplicit = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_current_implicit", { + aiAccessScope: { + permissionLevel: "read", + allowedResourceIds: ["asset_http_allowed"], + }, + }, "mnote.onlyoffice.session.current")), + }); + assert.equal(currentImplicit.status, 400, JSON.stringify(currentImplicit)); + assert.equal(currentImplicit.headers["x-error-code"], "mnote_onlyoffice_session_explicit_required"); + + const currentForbidden = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_current_forbidden", { + onlyofficeSessionId: bridgeSessionId, + aiAccessScope: { + permissionLevel: "read", + allowedResourceIds: ["asset_other"], + }, + }, "mnote.onlyoffice.session.current")), + }); + assert.equal(currentForbidden.status, 403, JSON.stringify(currentForbidden)); + assert.equal(currentForbidden.headers["x-error-code"], "mnote_onlyoffice_resource_scope_forbidden"); + + const currentAllowed = await requestJson("/api/hermes/tools/mnote/call", { + method: "POST", + body: JSON.stringify(callPayload("sess_http_current_allowed", { + onlyofficeSessionId: bridgeSessionId, + aiAccessScope: { + permissionLevel: "read", + allowedResourceIds: ["asset_http_allowed"], + }, + }, "mnote.onlyoffice.session.current")), + }); + assert.equal(currentAllowed.status, 200, JSON.stringify(currentAllowed)); + assert.equal(currentAllowed.payload.result.schema, "mnote.onlyoffice.session.v1"); + assert.equal(currentAllowed.payload.result.session.sessionId, bridgeSessionId); + assert.equal(currentAllowed.payload.result.session.assetId, "asset_http_allowed"); + + console.log(JSON.stringify({ + ok: true, + task: "task515-onlyoffice-live-scope-http-smoke", + baseUrl: BASE_URL, + bridgeSessionId, + implicit: { status: implicit.status, code: implicit.headers["x-error-code"] }, + forbidden: { status: forbidden.status, code: forbidden.headers["x-error-code"] }, + missingScope: { status: missingScope.status, code: missingScope.headers["x-error-code"] }, + allowed: { + status: allowed.status, + schema: allowed.payload.result.schema, + action: allowed.payload.result.action, + audit: allowed.payload.audit.effect, + }, + currentImplicit: { status: currentImplicit.status, code: currentImplicit.headers["x-error-code"] }, + currentForbidden: { status: currentForbidden.status, code: currentForbidden.headers["x-error-code"] }, + currentAllowed: { + status: currentAllowed.status, + schema: currentAllowed.payload.result.schema, + sessionId: currentAllowed.payload.result.session.sessionId, + assetId: currentAllowed.payload.result.session.assetId, + }, + }, null, 2)); +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js b/scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js new file mode 100644 index 00000000..c0384550 --- /dev/null +++ b/scripts/task516-onlyoffice-bridge-multisession-browser-smoke.js @@ -0,0 +1,194 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const { chromium } = require("playwright"); + +const BASE_URL = (process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); +const UI_TIMEOUT_MS = Number(process.env.MNOTE_UI_TIMEOUT_MS || 45000); + +async function main() { + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext(); + const page = await context.newPage(); + const consoleErrors = []; + const networkFailures = []; + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + page.on("requestfailed", (request) => { + networkFailures.push({ url: request.url(), failure: request.failure()?.errorText || "" }); + }); + + await page.goto(`${BASE_URL}/auth`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + const result = await page.evaluate(async () => { + const suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`; + const sessionA = `mnote-oo-browser-a-${suffix}`; + const sessionB = `mnote-oo-browser-b-${suffix}`; + const tokenA = `token-a-${suffix}`; + const tokenB = `token-b-${suffix}`; + + async function postJson(path, payload) { + const response = await fetch(path, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify(payload), + }); + const body = await response.json().catch(() => null); + return { status: response.status, body }; + } + + async function getJson(path) { + const response = await fetch(path); + const body = response.status === 204 ? null : await response.json().catch(() => null); + return { status: response.status, body }; + } + + const registeredA = await postJson("/api/onlyoffice/bridge/session", { + sessionId: sessionA, + token: tokenA, + editorType: "word", + documentId: "doc_a", + assetId: "asset_a", + fileType: "docx", + docKey: "doc_key_a", + pageOrigin: location.origin, + }); + const registeredB = await postJson("/api/onlyoffice/bridge/session", { + sessionId: sessionB, + token: tokenB, + editorType: "word", + documentId: "doc_b", + assetId: "asset_b", + fileType: "docx", + docKey: "doc_key_b", + pageOrigin: location.origin, + }); + const wrongToken = await getJson(`/api/onlyoffice/bridge/commands/next?sessionId=${encodeURIComponent(sessionA)}&token=${encodeURIComponent(tokenB)}&timeoutMs=1`); + + const commandA = await postJson("/api/onlyoffice/bridge/commands", { + sessionId: sessionA, + token: tokenA, + action: "document.insert_text", + payload: { text: "A" }, + }); + const commandB = await postJson("/api/onlyoffice/bridge/commands", { + sessionId: sessionB, + token: tokenB, + action: "document.insert_text", + payload: { text: "B" }, + }); + + const nextA = await getJson(`/api/onlyoffice/bridge/commands/next?sessionId=${encodeURIComponent(sessionA)}&token=${encodeURIComponent(tokenA)}&timeoutMs=1000`); + const nextB = await getJson(`/api/onlyoffice/bridge/commands/next?sessionId=${encodeURIComponent(sessionB)}&token=${encodeURIComponent(tokenB)}&timeoutMs=1000`); + + const postedA = await postJson("/api/onlyoffice/bridge/results", { + sessionId: sessionA, + token: tokenA, + id: nextA.body && nextA.body.id, + ok: true, + result: { text: "result-a" }, + }); + const postedB = await postJson("/api/onlyoffice/bridge/results", { + sessionId: sessionB, + token: tokenB, + id: nextB.body && nextB.body.id, + ok: true, + result: { text: "result-b" }, + }); + + const resultA = await getJson(`/api/onlyoffice/bridge/results?sessionId=${encodeURIComponent(sessionA)}&token=${encodeURIComponent(tokenA)}&commandId=${encodeURIComponent(nextA.body && nextA.body.id)}&timeoutMs=1000`); + const resultB = await getJson(`/api/onlyoffice/bridge/results?sessionId=${encodeURIComponent(sessionB)}&token=${encodeURIComponent(tokenB)}&commandId=${encodeURIComponent(nextB.body && nextB.body.id)}&timeoutMs=1000`); + const sessions = await getJson("/api/onlyoffice/bridge/sessions"); + const currentBeforeClose = await getJson("/api/onlyoffice/bridge/session/current"); + const closeA = await postJson("/api/onlyoffice/bridge/session/close", { + sessionId: sessionA, + token: tokenA, + }); + const nextAAfterClose = await getJson(`/api/onlyoffice/bridge/commands/next?sessionId=${encodeURIComponent(sessionA)}&token=${encodeURIComponent(tokenA)}&timeoutMs=1`); + const sessionsAfterClose = await getJson("/api/onlyoffice/bridge/sessions"); + + return { + sessionA, + sessionB, + registeredA, + registeredB, + wrongToken, + commandA, + commandB, + nextA, + nextB, + postedA, + postedB, + resultA, + resultB, + sessions, + currentBeforeClose, + closeA, + nextAAfterClose, + sessionsAfterClose, + }; + }); + + assert.equal(result.registeredA.status, 200, JSON.stringify(result.registeredA)); + assert.equal(result.registeredB.status, 200, JSON.stringify(result.registeredB)); + assert.equal(result.registeredA.body.docKey, "doc_key_a"); + assert.equal(result.registeredB.body.docKey, "doc_key_b"); + assert.equal(result.registeredA.body.pageOrigin, BASE_URL); + assert.equal(result.registeredB.body.pageOrigin, BASE_URL); + assert.equal(result.wrongToken.status, 401, JSON.stringify(result.wrongToken)); + assert.equal(result.commandA.status, 200, JSON.stringify(result.commandA)); + assert.equal(result.commandB.status, 200, JSON.stringify(result.commandB)); + assert.equal(result.nextA.status, 200, JSON.stringify(result.nextA)); + assert.equal(result.nextB.status, 200, JSON.stringify(result.nextB)); + assert.equal(result.nextA.body.action, "document.insert_text"); + assert.equal(result.nextB.body.action, "document.insert_text"); + assert.equal(result.nextA.body.payload.text, "A"); + assert.equal(result.nextB.body.payload.text, "B"); + assert.notEqual(result.nextA.body.id, result.nextB.body.id); + assert.equal(result.postedA.status, 200, JSON.stringify(result.postedA)); + assert.equal(result.postedB.status, 200, JSON.stringify(result.postedB)); + assert.equal(result.resultA.status, 200, JSON.stringify(result.resultA)); + assert.equal(result.resultB.status, 200, JSON.stringify(result.resultB)); + assert.equal(result.resultA.body.result.text, "result-a"); + assert.equal(result.resultB.body.result.text, "result-b"); + const sessionARecord = result.sessions.body.sessions.find((session) => session.sessionId === result.sessionA); + const sessionBRecord = result.sessions.body.sessions.find((session) => session.sessionId === result.sessionB); + assert(sessionARecord, JSON.stringify(result.sessions)); + assert(sessionBRecord, JSON.stringify(result.sessions)); + assert.equal(sessionARecord.docKey, "doc_key_a"); + assert.equal(sessionBRecord.pageOrigin, BASE_URL); + assert.equal(result.currentBeforeClose.status, 200, JSON.stringify(result.currentBeforeClose)); + assert(result.currentBeforeClose.body.session, JSON.stringify(result.currentBeforeClose)); + assert.equal(result.closeA.status, 200, JSON.stringify(result.closeA)); + assert.equal(result.closeA.body.closed, true, JSON.stringify(result.closeA)); + assert.equal(result.nextAAfterClose.status, 401, JSON.stringify(result.nextAAfterClose)); + assert(!result.sessionsAfterClose.body.sessions.some((session) => session.sessionId === result.sessionA)); + assert(result.sessionsAfterClose.body.sessions.some((session) => session.sessionId === result.sessionB)); + + await browser.close(); + console.log(JSON.stringify({ + ok: true, + task: "task516-onlyoffice-bridge-multisession-browser-smoke", + baseUrl: BASE_URL, + sessionA: result.sessionA, + sessionB: result.sessionB, + wrongToken: { status: result.wrongToken.status, code: result.wrongToken.body && result.wrongToken.body.code }, + nextA: { id: result.nextA.body.id, text: result.nextA.body.payload.text }, + nextB: { id: result.nextB.body.id, text: result.nextB.body.payload.text }, + resultA: result.resultA.body.result, + resultB: result.resultB.body.result, + currentBeforeClose: { + status: result.currentBeforeClose.status, + sessionId: result.currentBeforeClose.body.session && result.currentBeforeClose.body.session.sessionId, + }, + closeA: result.closeA.body, + consoleErrors, + networkFailures, + }, null, 2)); +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js b/scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js new file mode 100644 index 00000000..68ed2e8e --- /dev/null +++ b/scripts/task517-onlyoffice-bridge-plugin-direct-smoke.js @@ -0,0 +1,229 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const { spawn } = require("node:child_process"); +const net = require("node:net"); +const { chromium } = require("playwright"); + +const UI_TIMEOUT_MS = Number(process.env.MNOTE_UI_TIMEOUT_MS || 45000); + +function findFreePort() { + return new Promise((resolve, reject) => { + const server = net.createServer(); + server.listen(0, "127.0.0.1", () => { + const port = server.address().port; + server.close(() => resolve(port)); + }); + server.on("error", reject); + }); +} + +async function waitForGateway(baseUrl, timeoutMs = 120000) { + const deadline = Date.now() + timeoutMs; + let lastError = ""; + while (Date.now() < deadline) { + try { + const response = await fetch(`${baseUrl}/`); + if (response.status === 200 || response.status === 303) return; + lastError = `${response.status} ${await response.text().catch(() => "")}`; + } catch (error) { + lastError = error && error.message ? error.message : String(error); + } + await new Promise((resolve) => setTimeout(resolve, 500)); + } + throw new Error(`mnote-web 未就绪: ${lastError}`); +} + +function startGateway(port) { + const env = { + ...process.env, + MNOTE_WEB_BIND: `127.0.0.1:${port}`, + MNOTE_WEB_PUBLIC_BIND: `127.0.0.1:${port}`, + MNOTE_WEB_ALLOW_DEV_FIXTURES: "1", + MNOTE_WEB_LEGACY_NEXT_BASE_URL: "http://127.0.0.1:3100", + MNOTE_WEB_ENABLE_LEGACY_NEXT_COMPAT: "1", + }; + const child = spawn("cargo", ["run", "-q", "-p", "mnote-web", "--bin", "mnote-web"], { + cwd: "/mnt/Data1T/mnote/rust", + env, + stdio: ["ignore", "pipe", "pipe"], + }); + let stderr = ""; + child.stderr.on("data", (chunk) => { + stderr += chunk.toString("utf8"); + }); + child.stdout.on("data", () => {}); + return { + child, + stderr: () => stderr, + }; +} + +async function stopGateway(gateway) { + if (!gateway || gateway.child.killed) return; + gateway.child.kill("SIGTERM"); + await new Promise((resolve) => setTimeout(resolve, 500)); + if (!gateway.child.killed) gateway.child.kill("SIGKILL"); +} + +async function requestJson(baseUrl, path, init = {}) { + const response = await fetch(`${baseUrl}${path}`, { + ...init, + headers: { + "content-type": "application/json", + ...(init.headers || {}), + }, + }); + const body = response.status === 204 ? null : await response.json().catch(() => null); + return { status: response.status, body }; +} + +async function enqueueCommand(baseUrl, sessionId, token, action, payload) { + const response = await requestJson(baseUrl, "/api/onlyoffice/bridge/commands", { + method: "POST", + body: JSON.stringify({ sessionId, token, action, payload }), + }); + assert.equal(response.status, 200, JSON.stringify(response)); + assert(response.body && response.body.command && response.body.command.id, JSON.stringify(response)); + return response.body.command.id; +} + +async function readResult(baseUrl, sessionId, token, commandId) { + const query = new URLSearchParams({ + sessionId, + token, + commandId, + timeoutMs: "5000", + }); + const response = await requestJson(baseUrl, `/api/onlyoffice/bridge/results?${query.toString()}`); + assert.equal(response.status, 200, JSON.stringify(response)); + assert.equal(response.body && response.body.ok, true, JSON.stringify(response)); + return response.body.result; +} + +async function waitForSession(baseUrl, sessionId, timeoutMs = 5000) { + const deadline = Date.now() + timeoutMs; + let lastResponse = null; + while (Date.now() < deadline) { + lastResponse = await requestJson(baseUrl, "/api/onlyoffice/bridge/sessions"); + if (lastResponse.status === 200 && lastResponse.body && Array.isArray(lastResponse.body.sessions)) { + const found = lastResponse.body.sessions.find((session) => session.sessionId === sessionId); + if (found) return { response: lastResponse, session: found }; + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + throw new Error(`bridge session 未注册: ${JSON.stringify(lastResponse)}`); +} + +async function main() { + const port = await findFreePort(); + const baseUrl = `http://127.0.0.1:${port}`; + const gateway = startGateway(port); + const suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`; + const sessionId = `mnote-oo-plugin-direct-${suffix}`; + const token = `token-${suffix}`; + const consoleErrors = []; + const networkFailures = []; + + try { + await waitForGateway(baseUrl); + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext(); + const page = await context.newPage(); + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + page.on("requestfailed", (request) => { + networkFailures.push({ url: request.url(), failure: request.failure()?.errorText || "" }); + }); + await page.route("**/onlyoffice-server/sdkjs-plugins/v1/plugins.js", async (route) => { + await route.fulfill({ + contentType: "application/javascript; charset=utf-8", + body: ` + window.__MNOTE_ONLYOFFICE_PLUGIN_MOCK__ = { executeCalls: [], commandCalls: [] }; + window.Asc = { + scope: {}, + plugin: { + info: { editorType: "word" }, + executeMethod(name, args, callback) { + window.__MNOTE_ONLYOFFICE_PLUGIN_MOCK__.executeCalls.push({ name, args }); + const value = name === "GetSelectedText" + ? "mock selected text" + : name === "PasteText" + ? true + : name === "ConvertDocument" + ? "# mock document" + : null; + callback(value); + }, + callCommand(func, _close, _calc, callback) { + window.__MNOTE_ONLYOFFICE_PLUGIN_MOCK__.commandCalls.push({ scope: window.Asc.scope.mnoteBridge || {} }); + callback(func()); + }, + init: null, + button: null + } + }; + `, + }); + }); + + const pluginUrl = new URL(`${baseUrl}/api/onlyoffice/bridge/plugin/index`); + pluginUrl.searchParams.set("sessionId", sessionId); + pluginUrl.searchParams.set("token", token); + pluginUrl.searchParams.set("apiBase", baseUrl); + pluginUrl.searchParams.set("documentId", "doc_plugin_direct"); + pluginUrl.searchParams.set("assetId", "asset_plugin_direct"); + pluginUrl.searchParams.set("fileType", "docx"); + pluginUrl.searchParams.set("docKey", "doc_key_plugin_direct"); + pluginUrl.searchParams.set("pageOrigin", baseUrl); + await page.goto(pluginUrl.toString(), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + await page.evaluate(() => window.Asc.plugin.init()); + + const { session: registeredSession } = await waitForSession(baseUrl, sessionId); + assert.equal(registeredSession.docKey, "doc_key_plugin_direct", JSON.stringify(registeredSession)); + assert.equal(registeredSession.pageOrigin, baseUrl, JSON.stringify(registeredSession)); + + const wrongToken = await requestJson( + baseUrl, + `/api/onlyoffice/bridge/commands/next?sessionId=${encodeURIComponent(sessionId)}&token=wrong-${encodeURIComponent(token)}&timeoutMs=1`, + ); + assert.equal(wrongToken.status, 401, JSON.stringify(wrongToken)); + + const selectionCommandId = await enqueueCommand(baseUrl, sessionId, token, "selection.get", {}); + const selection = await readResult(baseUrl, sessionId, token, selectionCommandId); + assert.equal(selection.editorType, "word", JSON.stringify(selection)); + assert.equal(selection.text, "mock selected text", JSON.stringify(selection)); + + const insertCommandId = await enqueueCommand(baseUrl, sessionId, token, "document.insert_text", { text: "hello" }); + const inserted = await readResult(baseUrl, sessionId, token, insertCommandId); + assert.equal(inserted.value, true, JSON.stringify(inserted)); + + const mockState = await page.evaluate(() => window.__MNOTE_ONLYOFFICE_PLUGIN_MOCK__); + assert(mockState.executeCalls.some((call) => call.name === "GetSelectedText"), JSON.stringify(mockState)); + assert(mockState.executeCalls.some((call) => call.name === "PasteText"), JSON.stringify(mockState)); + + await browser.close(); + console.log(JSON.stringify({ + ok: true, + task: "task517-onlyoffice-bridge-plugin-direct-smoke", + baseUrl, + sessionId, + wrongToken: { status: wrongToken.status, code: wrongToken.body && wrongToken.body.code }, + registeredSession, + selection, + inserted, + executeCalls: mockState.executeCalls.map((call) => call.name), + consoleErrors, + networkFailures, + }, null, 2)); + } finally { + await stopGateway(gateway); + } +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js b/scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js new file mode 100644 index 00000000..815142f8 --- /dev/null +++ b/scripts/task518-onlyoffice-real-iframe-session-scope-smoke.js @@ -0,0 +1,471 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); + +const TASK = "task518-onlyoffice-real-iframe-session-scope-smoke"; +const BASE_URL = (process.env.MNOTE_WEB_SMOKE_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); +const UI_TIMEOUT_MS = Number(process.env.MNOTE_SMOKE_UI_TIMEOUT_MS || 120_000); +const PROBE_DOCX_PATH = process.env.MNOTE_ONLYOFFICE_PROBE_DOCX + || "/tmp/mnote-onlyoffice-manual/mnote-onlyoffice-upload-test.docx"; +const OUT_DIR = path.join(process.cwd(), "tmp", TASK); +const SCREENSHOT_DIR = path.join(OUT_DIR, "screenshots"); +const RESULT_PATH = path.join(OUT_DIR, "result.json"); +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localOfficeFileUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/api/local-folder/files/open`); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("path", relativePath); + return url.toString(); +} + +function onlyofficeUrl(root, relativePath, assetId) { + const url = new URL(`${BASE_URL}/onlyoffice`); + url.searchParams.set("fileUrl", localOfficeFileUrl(root, relativePath)); + url.searchParams.set("fileName", path.basename(relativePath)); + url.searchParams.set("fileType", "docx"); + url.searchParams.set("assetId", assetId); + url.searchParams.set("documentId", "local-md:Page~2FPage.md"); + url.searchParams.set("mode", "edit"); + return url.toString(); +} + +function bridgeToolPayload(sessionId, assetId, allowedResourceIds, toolName = "mnote.onlyoffice.document.insert_text", options = {}) { + return { + toolName, + workspaceId: "local-ws:task518", + documentId: "local-md:Page~2FPage.md", + actorId: "user_1", + sessionId: `task518-${Date.now()}-${Math.random().toString(36).slice(2)}`, + runId: "task518-run", + toolCallId: "task518-call", + traceId: "task518-trace", + idempotencyKey: `task518-${Date.now()}-${Math.random().toString(36).slice(2)}`, + dryRun: options.dryRun !== false, + capabilityScope: ["office.write"], + args: { + onlyofficeSessionId: sessionId, + text: options.text || "task518 dry run", + aiAccessScope: { + permissionLevel: "read_write", + allowedResourceIds, + }, + }, + }; +} + +async function quickLogin(page) { + await page.goto(`${BASE_URL}/auth`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + const quickLoginButton = page.getByRole("button", { name: "测试账号快速登录" }); + if (await quickLoginButton.count()) { + await quickLoginButton.click({ timeout: UI_TIMEOUT_MS }); + await page.waitForURL((url) => url.pathname !== "/auth", { timeout: UI_TIMEOUT_MS }).catch(() => undefined); + } +} + +async function waitForOfficeReady(page, label) { + await page.waitForFunction( + () => { + const debug = window.__MNOTE_ONLYOFFICE_DEBUG__ || null; + const frameCount = document.querySelectorAll("#onlyoffice-frame iframe, #onlyoffice-frame canvas").length; + return Boolean(debug && debug.bridgeSessionId && debug.bridgeToken) + && Boolean(window.__MNOTE_ONLYOFFICE_EDITOR__) + && (Boolean(window.__MNOTE_ONLYOFFICE_READY__) || frameCount > 0); + }, + null, + { timeout: UI_TIMEOUT_MS }, + ); + await page.screenshot({ path: path.join(SCREENSHOT_DIR, `${label}.png`), fullPage: true }); + return await page.evaluate(() => ({ + url: location.href, + ready: Boolean(window.__MNOTE_ONLYOFFICE_READY__), + editorExists: Boolean(window.__MNOTE_ONLYOFFICE_EDITOR__), + frameCount: document.querySelectorAll("#onlyoffice-frame iframe, #onlyoffice-frame canvas").length, + errorVisible: document.getElementById("onlyoffice-error")?.getAttribute("data-visible") || "", + debug: window.__MNOTE_ONLYOFFICE_DEBUG__ || null, + errorLog: Array.isArray(window.__MNOTE_ONLYOFFICE_ERRLOG__) ? window.__MNOTE_ONLYOFFICE_ERRLOG__.slice() : [], + })); +} + +async function readBridgeSessions(context) { + const response = await context.request.fetch(`${BASE_URL}/api/onlyoffice/bridge/sessions`, { + method: "GET", + timeout: UI_TIMEOUT_MS, + }); + const body = await response.json().catch(async () => ({ raw: await response.text() })); + return { + status: response.status(), + body, + }; +} + +async function waitForBridgeSession(context, sessionId) { + const deadline = Date.now() + UI_TIMEOUT_MS; + let last = null; + while (Date.now() < deadline) { + last = await readBridgeSessions(context); + if ( + last.status === 200 + && Array.isArray(last.body?.sessions) + && last.body.sessions.some((session) => session.sessionId === sessionId) + ) { + return last; + } + await new Promise((resolve) => setTimeout(resolve, 500)); + } + throw new Error(`bridge session 未注册: ${sessionId}; last=${JSON.stringify(last)}`); +} + +async function runBridgeSelection(page) { + return await page.evaluate(async () => { + return await window.__MNOTE_ONLYOFFICE_BRIDGE__.run("selection.get", {}, 30_000); + }); +} + +async function runBridgeExport(page, format = "html") { + return await page.evaluate(async (selectedFormat) => { + return await window.__MNOTE_ONLYOFFICE_BRIDGE__.run("document.export", { format: selectedFormat }, 30_000); + }, format); +} + +async function postToolCall(context, payload) { + const response = await context.request.fetch(`${BASE_URL}/api/hermes/tools/mnote/call`, { + method: "POST", + headers: { + "content-type": "application/json", + "x-mnote-actor-id": "user_1", + }, + data: payload, + timeout: UI_TIMEOUT_MS, + }); + const body = await response.json().catch(async () => ({ raw: await response.text() })); + return { + status: response.status(), + headers: response.headers(), + body, + }; +} + +function classifyOnlyOfficeSignals(result, states, selections, scopeChecks) { + const bridgeTranslation404 = result.httpErrors.filter((entry) => ( + /\/api\/onlyoffice\/bridge\/plugin\/index\/translations\//.test(entry.url) + && entry.status === 404 + )); + const mnoteBridgePluginHttpErrors = result.httpErrors.filter((entry) => ( + /\/api\/onlyoffice\/bridge\/plugin\//.test(entry.url) + && !/\/api\/onlyoffice\/bridge\/plugin\/index\/translations\//.test(entry.url) + )); + const builtinPluginNoise = result.httpErrors.filter((entry) => ( + /\/sdkjs-plugins\/|custom.?assistant|annotation/i.test(entry.url) + )); + const bridgeConsoleNoise = result.consoleErrors.filter((entry) => ( + /\/api\/onlyoffice\/bridge\/plugin\/index\/translations\//.test(entry.text) + || /Failed to load resource: the server responded with a status of 404/i.test(entry.text) + )); + const errorCodeMinus18 = [ + ...result.consoleErrors.map((entry) => entry.text || ""), + ...states.flatMap((state) => Array.isArray(state.errorLog) ? state.errorLog.map((item) => JSON.stringify(item)) : []), + ].some((text) => /errorCode["'=:\s-]*-18|\b-18\b/.test(text)); + const mainDocumentFailures = [ + ...result.networkFailures.filter((entry) => ( + !/\/api\/onlyoffice\/bridge\/commands\/next/.test(entry.url) + )), + ...result.httpErrors.filter((entry) => { + if (/\/api\/onlyoffice\/bridge\/plugin\/index\/translations\//.test(entry.url)) return false; + if (/\/sdkjs-plugins\/|custom.?assistant|annotation/i.test(entry.url)) return false; + if (/\/api\/onlyoffice\/bridge\/plugin\//.test(entry.url)) return false; + if (/\/api\/onlyoffice\/bridge\/commands\/next/.test(entry.url)) return false; + return /\/onlyoffice-server\/|\/api\/onlyoffice\/proxy|\/api\/local-folder\/files\/open/.test(entry.url); + }), + ...states.filter((state) => state.errorVisible || !state.editorExists || !state.ready).map((state) => ({ + url: state.url, + ready: state.ready, + editorExists: state.editorExists, + errorVisible: state.errorVisible, + })), + ]; + return { + mnoteBridgePlugin: { + configUrls: states.map((state) => state.debug?.bridgePluginConfigUrl || ""), + httpErrors: mnoteBridgePluginHttpErrors, + sessionsRegistered: states.every((state) => ( + result.bridgeSessionsFinal?.body?.sessions || [] + ).some((session) => session.sessionId === state.debug?.bridgeSessionId)), + commandLoopOk: scopeChecks?.allowedBDryRun?.status === 200 + && scopeChecks?.allowedBWrite?.status === 200, + }, + bridgeTranslationNoise: { + count: bridgeTranslation404.length, + urls: Array.from(new Set(bridgeTranslation404.map((entry) => entry.url))), + }, + builtinPluginNoise: { + count: builtinPluginNoise.length, + urls: Array.from(new Set(builtinPluginNoise.map((entry) => entry.url))), + }, + mainDocument: { + ready: mainDocumentFailures.length === 0 && selections.every((selection) => selection?.editorType === "word"), + failures: mainDocumentFailures, + errorCodeMinus18, + }, + consoleNoise: { + bridgeTranslationOrGeneric404Count: bridgeConsoleNoise.length, + }, + }; +} + +async function main() { + assert(fs.existsSync(PROBE_DOCX_PATH), `缺少探测 docx: ${PROBE_DOCX_PATH}`); + fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); + + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task518-onlyoffice-")); + fs.mkdirSync(path.join(root, "Page"), { recursive: true }); + fs.writeFileSync(path.join(root, ".mnote-placeholder"), "task518\n", "utf8"); + fs.copyFileSync(PROBE_DOCX_PATH, path.join(root, "Page", "office-a.docx")); + fs.copyFileSync(PROBE_DOCX_PATH, path.join(root, "Page", "office-b.docx")); + + const consoleErrors = []; + const networkFailures = []; + const httpErrors = []; + const browser = await chromium.launch({ + headless: process.env.HEADFUL !== "1", + executablePath: CHROMIUM_EXECUTABLE_PATH, + }); + const context = await browser.newContext({ viewport: { width: 1440, height: 900 } }); + const authPage = await context.newPage(); + + const result = { + ok: false, + task: TASK, + baseUrl: BASE_URL, + root, + screenshots: [], + consoleErrors, + networkFailures, + httpErrors, + }; + + try { + await quickLogin(authPage); + await authPage.close(); + + const pageA = await context.newPage(); + const pageADuplicate = await context.newPage(); + const pageB = await context.newPage(); + for (const page of [pageA, pageADuplicate, pageB]) { + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push({ url: page.url(), text: message.text() }); + }); + page.on("requestfailed", (request) => { + networkFailures.push({ url: request.url(), failure: request.failure()?.errorText || "" }); + }); + page.on("response", (response) => { + if (response.status() >= 400) { + httpErrors.push({ url: response.url(), status: response.status() }); + } + }); + } + + const assetA = "local-file:Page/office-a.docx"; + const assetB = "local-file:Page/office-b.docx"; + await pageA.goto(onlyofficeUrl(root, "Page/office-a.docx", assetA), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + await pageADuplicate.goto(onlyofficeUrl(root, "Page/office-a.docx", assetA), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + await pageB.goto(onlyofficeUrl(root, "Page/office-b.docx", assetB), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + + const stateA = await waitForOfficeReady(pageA, "office-a"); + const stateADuplicate = await waitForOfficeReady(pageADuplicate, "office-a-duplicate"); + const stateB = await waitForOfficeReady(pageB, "office-b"); + result.screenshots.push(path.join(SCREENSHOT_DIR, "office-a.png")); + result.screenshots.push(path.join(SCREENSHOT_DIR, "office-a-duplicate.png")); + result.screenshots.push(path.join(SCREENSHOT_DIR, "office-b.png")); + assert.equal(stateA.errorVisible, "", `A 页面不应显示错误: ${JSON.stringify(stateA)}`); + assert.equal(stateADuplicate.errorVisible, "", `A duplicate 页面不应显示错误: ${JSON.stringify(stateADuplicate)}`); + assert.equal(stateB.errorVisible, "", `B 页面不应显示错误: ${JSON.stringify(stateB)}`); + assert(stateA.debug.bridgeSessionId !== stateB.debug.bridgeSessionId, `A/B sessionId 不应相同: ${JSON.stringify({ a: stateA.debug, b: stateB.debug })}`); + assert( + stateA.debug.bridgeSessionId !== stateADuplicate.debug.bridgeSessionId, + `同一 Office 文档双 tab sessionId 不应相同: ${JSON.stringify({ a: stateA.debug, duplicate: stateADuplicate.debug })}`, + ); + assert.equal(stateA.debug.docKey, stateADuplicate.debug.docKey, `同一 Office 文档双 tab 应共享 docKey 但使用不同 session salt: ${JSON.stringify({ a: stateA.debug, duplicate: stateADuplicate.debug })}`); + assert.equal(stateA.debug.assetId, assetA, `A debug assetId 不匹配: ${JSON.stringify(stateA.debug)}`); + assert.equal(stateADuplicate.debug.assetId, assetA, `A duplicate debug assetId 不匹配: ${JSON.stringify(stateADuplicate.debug)}`); + assert.equal(stateB.debug.assetId, assetB, `B debug assetId 不匹配: ${JSON.stringify(stateB.debug)}`); + + result.officeAInitial = stateA; + result.officeADuplicateInitial = stateADuplicate; + result.officeBInitial = stateB; + result.bridgeSessionsAfterReady = await readBridgeSessions(context); + await waitForBridgeSession(context, stateA.debug.bridgeSessionId); + await waitForBridgeSession(context, stateADuplicate.debug.bridgeSessionId); + await waitForBridgeSession(context, stateB.debug.bridgeSessionId); + result.bridgeSessionsFinal = await readBridgeSessions(context); + const selectionA = await runBridgeSelection(pageA); + const selectionADuplicate = await runBridgeSelection(pageADuplicate); + const selectionB = await runBridgeSelection(pageB); + assert.equal(selectionA.editorType, "word", `A selection 应来自 word editor: ${JSON.stringify(selectionA)}`); + assert.equal(selectionADuplicate.editorType, "word", `A duplicate selection 应来自 word editor: ${JSON.stringify(selectionADuplicate)}`); + assert.equal(selectionB.editorType, "word", `B selection 应来自 word editor: ${JSON.stringify(selectionB)}`); + + const forbiddenBFromScopeA = await postToolCall( + context, + bridgeToolPayload(stateB.debug.bridgeSessionId, assetB, [assetA, `resource:onlyoffice:${stateA.debug.documentId}:${assetA}`]), + ); + assert.equal(forbiddenBFromScopeA.status, 403, JSON.stringify(forbiddenBFromScopeA)); + assert.equal(forbiddenBFromScopeA.headers["x-error-code"], "mnote_onlyoffice_resource_scope_forbidden"); + + const allowedBDryRun = await postToolCall( + context, + bridgeToolPayload(stateB.debug.bridgeSessionId, assetB, [assetB, `resource:onlyoffice:${stateB.debug.documentId}:${assetB}`]), + ); + assert.equal(allowedBDryRun.status, 200, JSON.stringify(allowedBDryRun)); + assert.equal(allowedBDryRun.body.result.schema, "mnote.onlyoffice.action_plan.v1"); + assert.equal(allowedBDryRun.body.result.sessionId, stateB.debug.bridgeSessionId); + + const writeMarker = `task518-write-${Date.now()}-${Math.random().toString(36).slice(2)}`; + const allowedBWrite = await postToolCall( + context, + bridgeToolPayload( + stateB.debug.bridgeSessionId, + assetB, + [assetB, `resource:onlyoffice:${stateB.debug.documentId}:${assetB}`], + "mnote.onlyoffice.document.insert_text", + { dryRun: false, text: writeMarker }, + ), + ); + assert.equal(allowedBWrite.status, 200, JSON.stringify(allowedBWrite)); + assert.equal(allowedBWrite.body.result.schema, "mnote.onlyoffice.action_result.v1"); + assert.equal(allowedBWrite.body.result.sessionId, stateB.debug.bridgeSessionId); + await pageA.screenshot({ path: path.join(SCREENSHOT_DIR, "office-a-after-write.png"), fullPage: true }); + await pageB.screenshot({ path: path.join(SCREENSHOT_DIR, "office-b-after-write.png"), fullPage: true }); + result.screenshots.push(path.join(SCREENSHOT_DIR, "office-a-after-write.png")); + result.screenshots.push(path.join(SCREENSHOT_DIR, "office-b-after-write.png")); + + const exportAAfterWrite = await runBridgeExport(pageA, "html"); + const exportBAfterWrite = await runBridgeExport(pageB, "html"); + const exportAText = String(exportAAfterWrite?.content || exportAAfterWrite?.result?.content || ""); + const exportBText = String(exportBAfterWrite?.content || exportBAfterWrite?.result?.content || ""); + assert( + exportBText.includes(writeMarker), + `B 导出内容应包含写入标记 ${writeMarker}: ${JSON.stringify(exportBAfterWrite).slice(0, 1000)}`, + ); + assert( + !exportAText.includes(writeMarker), + `A 导出内容不应包含 B 写入标记 ${writeMarker}: ${JSON.stringify(exportAAfterWrite).slice(0, 1000)}`, + ); + + const scopeChecks = { + forbiddenBFromScopeA: { + status: forbiddenBFromScopeA.status, + code: forbiddenBFromScopeA.headers["x-error-code"], + }, + allowedBDryRun: { + status: allowedBDryRun.status, + schema: allowedBDryRun.body.result.schema, + sessionId: allowedBDryRun.body.result.sessionId, + }, + allowedBWrite: { + status: allowedBWrite.status, + schema: allowedBWrite.body.result.schema, + sessionId: allowedBWrite.body.result.sessionId, + commandId: allowedBWrite.body.result.commandId, + }, + exportAfterWrite: { + writeMarker, + aContainsMarker: exportAText.includes(writeMarker), + bContainsMarker: exportBText.includes(writeMarker), + }, + }; + result.bridgeSessionsFinal = await readBridgeSessions(context); + const errorClassification = classifyOnlyOfficeSignals( + result, + [stateA, stateADuplicate, stateB], + [selectionA, selectionADuplicate, selectionB], + scopeChecks, + ); + assert.equal( + errorClassification.mnoteBridgePlugin.httpErrors.length, + 0, + `MNote bridge 插件 config/index 失败不能归为普通噪音: ${JSON.stringify(errorClassification.mnoteBridgePlugin.httpErrors)}`, + ); + assert.equal( + errorClassification.mnoteBridgePlugin.sessionsRegistered, + true, + `MNote bridge 插件应完成 session 注册: ${JSON.stringify(errorClassification.mnoteBridgePlugin)}`, + ); + assert.equal( + errorClassification.mnoteBridgePlugin.commandLoopOk, + true, + `MNote bridge 插件 command loop 应可用: ${JSON.stringify(errorClassification.mnoteBridgePlugin)}`, + ); + assert.equal( + errorClassification.mainDocument.errorCodeMinus18, + false, + `errorCode=-18 必须作为主文档失败暴露: ${JSON.stringify(errorClassification.mainDocument)}`, + ); + assert.equal( + errorClassification.mainDocument.ready, + true, + `主文档失败不能被插件噪音吞掉: ${JSON.stringify(errorClassification.mainDocument)}`, + ); + + Object.assign(result, { + ok: true, + errorClassification, + officeA: { + sessionId: stateA.debug.bridgeSessionId, + assetId: stateA.debug.assetId, + docKey: stateA.debug.docKey, + frameCount: stateA.frameCount, + selection: selectionA, + }, + officeADuplicate: { + sessionId: stateADuplicate.debug.bridgeSessionId, + assetId: stateADuplicate.debug.assetId, + docKey: stateADuplicate.debug.docKey, + frameCount: stateADuplicate.frameCount, + selection: selectionADuplicate, + }, + officeB: { + sessionId: stateB.debug.bridgeSessionId, + assetId: stateB.debug.assetId, + docKey: stateB.debug.docKey, + frameCount: stateB.frameCount, + selection: selectionB, + }, + scopeChecks, + }); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + result.error = error && error.stack ? error.stack : String(error); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + throw error; + } finally { + await context.close().catch(() => undefined); + await browser.close().catch(() => undefined); + } +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task520-page-ai-raw-resource-target-smoke.js b/scripts/task520-page-ai-raw-resource-target-smoke.js new file mode 100644 index 00000000..276b952b --- /dev/null +++ b/scripts/task520-page-ai-raw-resource-target-smoke.js @@ -0,0 +1,296 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const TASK = "task520-page-ai-raw-resource-target-smoke"; +const OUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUT_DIR, "result.json"); +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +async function quickLogin(page, request) { + await ensureAuthenticated(page, request); +} + +async function waitFiletreeRow(page, relativePath) { + return await page.waitForFunction( + (expectedRelativePath) => Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .some((row) => row.getAttribute("data-local-relative-path") === expectedRelativePath), + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function clickFiletreeOpen(page, relativePath) { + const handle = await page.waitForFunction( + (expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.querySelector('[data-rust-action="open"], .tree-link') || null; + }, + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); + await handle.asElement().click(); +} + +async function expandFiletreeFolder(page, relativePath) { + await waitFiletreeRow(page, relativePath); + const expanded = await page.evaluate((expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.getAttribute("aria-expanded") === "true"; + }, relativePath); + if (!expanded) { + await clickFiletreeOpen(page, relativePath); + } + await page.waitForFunction( + (expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.getAttribute("aria-expanded") === "true"; + }, + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function saveScreenshot(page, name) { + const target = path.join(OUT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: false }); + return target; +} + +async function main() { + fs.mkdirSync(OUT_DIR, { recursive: true }); + const actorId = "mnote-e2e"; + const workspaceId = `local-ws:${actorId}:task520`; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task520-raw-target-")); + const rootUri = fileUrl(root); + const pagePath = "Page.md"; + const rawPath = "Page/notes.txt"; + const documentId = localMdDocumentId(pagePath); + const captured = []; + let caughtError = null; + + fs.mkdirSync(path.join(root, "Page"), { recursive: true }); + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, pagePath), "# Page\n\nTask520 page\n", "utf8"); + fs.writeFileSync(path.join(root, rawPath), "Task520 raw resource target\n", "utf8"); + + const browser = await chromium.launch({ + headless: process.env.HEADFUL !== "1", + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + try { + await page.route("**/api/user/access-policy**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + grants: [{ + id: "grant_task520", + userId: actorId, + workspaceId, + rootUri, + rootPath: root, + permission: "write", + recursive: true, + capabilities: ["ai", "markdown_edit"], + source: "user", + status: "active", + }], + }), + }); + }); + await page.route("**/api/ui/preferences**", async (route) => { + captured.push({ kind: "ui-preferences", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, owner: "mnote-web", result: {} }), + }); + }); + await page.route("**/api/hermes/client/gateway/health**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, gateway: { ok: true }, profile: { name: "reasonix", modelConfigured: true, apiKeyConfigured: true } }), + }); + }); + await page.route("**/api/hermes/client/tools**", async (route) => { + await route.fulfill({ status: 200, headers: { "content-type": "application/json" }, body: JSON.stringify({ ok: true, tools: [] }) }); + }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, agentId: "reasonix", profiles: [] }), + }); + }); + await page.route("**/api/hermes/client/profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, active: "mnoteai", profiles: [{ name: "mnoteai", label: "MNote AI", modelConfigured: true, apiKeyConfigured: true }] }), + }); + }); + await page.route("**/api/hermes/client/skills**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, categories: [], archived: [] }), + }); + }); + await page.route("**/api/hermes/client/sessions", async (route) => { + captured.push({ kind: "session", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, sessionId: "mnote_task520", title: "task520", traceId: "trace_task520" }), + }); + }); + await page.route("**/api/hermes/client/runs", async (route) => { + captured.push({ kind: "run", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, sessionId: "mnote_task520", runId: "run_task520", events: [], traceId: "trace_run_task520" }), + }); + }); + await page.route("**/api/hermes/client/events/*", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "text/event-stream; charset=utf-8" }, + body: `data: ${JSON.stringify({ event: "message.delta", run_id: "run_task520", delta: "Task520 response" })}\n\n` + + `data: ${JSON.stringify({ event: "run.completed", run_id: "run_task520", output: "Task520 response" })}\n\n`, + }); + }); + + await quickLogin(page, context.request); + const response = await page.goto(documentUrl(root, pagePath), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator(".document-pane[data-pane-role=\"primary\"] .editor-surface .ProseMirror").first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await expandFiletreeFolder(page, "Page"); + await waitFiletreeRow(page, rawPath); + await clickFiletreeOpen(page, rawPath); + await page.waitForFunction( + (expectedPath) => { + const snapshot = window.__mnoteDocumentPaneRuntime?.getOpenEditorsSnapshot?.() || window.__mnoteOpenEditorsSnapshot || null; + return (snapshot?.resourceEditors || []).some((entry) => entry?.path === expectedPath && entry?.active === true); + }, + rawPath, + { timeout: UI_TIMEOUT_MS }, + ); + + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const targetChip = page.locator("[data-page-ai-target-chip]"); + await targetChip.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const chipText = (await targetChip.innerText({ timeout: UI_TIMEOUT_MS })).trim(); + assert(chipText.includes("notes.txt"), `raw resource 打开后 target chip 应指向 notes.txt: ${chipText}`); + + await page.locator("[data-page-ai-input]").fill("Task520 raw target", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector('[data-testid="wolai-page-ai-drawer"]')?.textContent || "").includes("Task520 response"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + + const runs = captured.filter((item) => item.kind === "run"); + assert(runs.length >= 1, "未捕获 Page AI run payload"); + const runBody = JSON.parse(runs[runs.length - 1].body || "{}"); + const activeEditorRef = runBody.contextRefs?.find((item) => item.kind === "active_editor"); + assert(activeEditorRef, `run payload 应包含 active_editor contextRef: ${JSON.stringify(runBody.contextRefs)}`); + assert.strictEqual(activeEditorRef.relativePath, rawPath, `active_editor 应指向 raw resource: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.resourceKind, "attachment", `raw resource contextRef 应保留 attachment resourceKind: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.objectIdentity, "resource:file:" + rootUri + ":" + rawPath, `active_editor objectIdentity 不应退化为 [object Object]: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(runBody.targetPackage?.schema, "mnote.agent_target_package.v1", "run payload 应携带 targetPackage"); + assert.strictEqual(runBody.targetPackage?.primaryTargetId, "resource:file:" + rootUri + ":" + rawPath, `targetPackage 应冻结 raw resource objectIdentity: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.objectIdentity, "resource:file:" + rootUri + ":" + rawPath, `targetPackage objectIdentity 不应退化为 [object Object]: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.resourceKind, "attachment", `targetPackage 应保留 raw resource kind: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.currentFile?.relativePath, rawPath, `targetPackage currentFile 应指向 raw resource: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.currentFile?.objectIdentity, "resource:file:" + rootUri + ":" + rawPath, `currentFile objectIdentity 不应退化为 [object Object]: ${JSON.stringify(runBody.targetPackage?.currentFile)}`); + assert(runBody.targetPackage?.allowedFiles?.includes(rawPath), `allowedFiles 应只包含 raw resource: ${JSON.stringify(runBody.targetPackage?.allowedFiles)}`); + + const screenshot = await saveScreenshot(page, "01-raw-resource-target"); + const result = { ok: true, task: TASK, baseUrl: BASE_URL, root, rootUri, documentId, rawPath, screenshot, captured }; + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + caughtError = error; + await saveScreenshot(page, "failure").catch(() => undefined); + } finally { + fs.rmSync(root, { recursive: true, force: true }); + await page.close().catch(() => undefined); + await context.close().catch(() => undefined); + await browser.close().catch(() => undefined); + } + + if (caughtError) { + throw caughtError; + } +} + +if (require.main === module) { + main().catch((error) => { + console.error(error); + process.exit(1); + }); +} diff --git a/scripts/task522-page-aggregate-compat-fallback-contract.js b/scripts/task522-page-aggregate-compat-fallback-contract.js new file mode 100644 index 00000000..e135835c --- /dev/null +++ b/scripts/task522-page-aggregate-compat-fallback-contract.js @@ -0,0 +1,99 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const path = require("node:path"); +const vm = require("node:vm"); + +const RUNTIME_PATH = path.join( + process.cwd(), + "rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js", +); + +function loadConversionRuntime() { + const source = fs + .readFileSync(RUNTIME_PATH, "utf8") + .replace(/\bexport const\s+([A-Za-z0-9_]+)\s*=/g, "const $1 ="); + const sandbox = { console }; + vm.runInNewContext( + `${source}\n;globalThis.__mnoteExports = { pageBodyTiptapDocumentSource, pageBodyTiptapDocument };`, + sandbox, + { filename: RUNTIME_PATH }, + ); + return sandbox.__mnoteExports; +} + +function paragraphText(doc) { + return doc?.content?.[0]?.content?.[0]?.text || ""; +} + +const { + pageBodyTiptapDocumentSource, + pageBodyTiptapDocument, +} = loadConversionRuntime(); + +const blockDocument = { + type: "doc", + content: [{ + type: "paragraph", + attrs: { blockId: "block-truth" }, + content: [{ type: "text", text: "Block truth" }], + }], +}; + +const legacyContent = [{ + id: "legacy-1", + type: "paragraph", + content: [{ type: "text", text: "Legacy fallback" }], +}]; + +const localWithBlockAndLegacy = { + projectionSource: "local_markdown.content", + blockDocument, + content: legacyContent, +}; +assert.equal( + pageBodyTiptapDocumentSource(localWithBlockAndLegacy), + "page_aggregate.block_document", +); +assert.equal( + paragraphText(pageBodyTiptapDocument(localWithBlockAndLegacy)), + "Block truth", +); + +const localLegacyOnly = { + projectionSource: "local_markdown.content", + content: legacyContent, +}; +assert.equal( + pageBodyTiptapDocumentSource(localLegacyOnly), + "local_markdown.content", +); +assert.equal( + paragraphText(pageBodyTiptapDocument(localLegacyOnly)), + "Legacy fallback", +); + +const compatLegacyOnly = { + content: legacyContent, +}; +assert.equal( + pageBodyTiptapDocumentSource(compatLegacyOnly), + "compat.legacy_content", +); +assert.equal( + paragraphText(pageBodyTiptapDocument(compatLegacyOnly)), + "Legacy fallback", +); + +assert.equal( + pageBodyTiptapDocumentSource({}, "Fallback text"), + "degraded.fallback_text", +); +assert.equal( + paragraphText(pageBodyTiptapDocument({}, "Fallback text")), + "Fallback text", +); + +console.log("task522 page aggregate compat fallback contract passed"); diff --git a/scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js b/scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js new file mode 100644 index 00000000..285e088d --- /dev/null +++ b/scripts/task523-page-ai-onlyoffice-real-target-session-smoke.js @@ -0,0 +1,416 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const TASK = "task523-page-ai-onlyoffice-real-target-session-smoke"; +const OUT_DIR = path.join(process.cwd(), "tmp", TASK); +const SCREENSHOT_DIR = path.join(OUT_DIR, "screenshots"); +const RESULT_PATH = path.join(OUT_DIR, "result.json"); +const PROBE_DOCX_PATH = process.env.MNOTE_ONLYOFFICE_PROBE_DOCX + || "/tmp/mnote-onlyoffice-manual/mnote-onlyoffice-upload-test.docx"; +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function localOfficeFileUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/api/local-folder/files/open`); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("path", relativePath); + return url.toString(); +} + +function onlyofficeUrl(root, pageRelativePath, officeRelativePath, assetId) { + const url = new URL(`${BASE_URL}/onlyoffice`); + url.searchParams.set("fileUrl", localOfficeFileUrl(root, officeRelativePath)); + url.searchParams.set("fileName", path.basename(officeRelativePath)); + url.searchParams.set("fileType", "docx"); + url.searchParams.set("assetId", assetId); + url.searchParams.set("documentId", localMdDocumentId(pageRelativePath)); + url.searchParams.set("mode", "edit"); + return url.toString(); +} + +async function saveScreenshot(page, name) { + const target = path.join(SCREENSHOT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: true }); + return target; +} + +async function waitForOfficeSnapshot(page, objectIdentity) { + return await page.waitForFunction( + (targetId) => { + const runtime = window.__mnoteDocumentPaneRuntime; + if (!runtime || typeof runtime.getOpenEditorsSnapshot !== "function") return null; + const snapshot = runtime.getOpenEditorsSnapshot(); + const resources = Array.isArray(snapshot && snapshot.resourceEditors) ? snapshot.resourceEditors : []; + const entry = resources.find((item) => item && item.objectIdentity === targetId); + if (!entry || !entry.bridgeSessionReady || !(entry.onlyofficeSessionId || entry.bridgeSessionId)) return null; + return entry; + }, + objectIdentity, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function main() { + assert(fs.existsSync(PROBE_DOCX_PATH), `缺少探测 docx: ${PROBE_DOCX_PATH}`); + fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); + + const suffix = Date.now().toString(36); + const actorId = "mnote-e2e"; + const workspaceId = `local-ws:${actorId}:task523`; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task523-onlyoffice-target-")); + const rootUri = fileUrl(root); + const pageRelativePath = "Page/Page.md"; + const officeRelativePath = "Page/office-a.docx"; + const documentId = localMdDocumentId(pageRelativePath); + const assetId = `local-file:${officeRelativePath}`; + const objectIdentity = `resource:office:${documentId}:${assetId}`; + const captured = []; + const consoleErrors = []; + const networkFailures = []; + const httpErrors = []; + const result = { + ok: false, + task: TASK, + baseUrl: BASE_URL, + root, + documentId, + officeRelativePath, + objectIdentity, + screenshots: [], + consoleErrors, + networkFailures, + httpErrors, + }; + + fs.mkdirSync(path.join(root, "Page"), { recursive: true }); + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync( + path.join(root, pageRelativePath), + ["# Page", "", `Task523 ${suffix}`, ""].join("\n"), + "utf8", + ); + fs.copyFileSync(PROBE_DOCX_PATH, path.join(root, officeRelativePath)); + + const browser = await chromium.launch({ + headless: process.env.HEADFUL !== "1", + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + page.on("requestfailed", (request) => { + networkFailures.push({ url: request.url(), failure: request.failure()?.errorText || "" }); + }); + page.on("response", (response) => { + if (response.status() >= 400) { + httpErrors.push({ url: response.url(), status: response.status() }); + } + }); + + try { + await page.route("**/api/user/access-policy**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + controlPlane: "sqlite", + grants: [{ + id: `grant_task523_${suffix}`, + userId: actorId, + workspaceId, + rootUri, + rootPath: root, + permission: "write", + recursive: true, + capabilities: ["ai", "markdown_edit", "office.write"], + source: "user", + status: "active", + }], + }), + }); + }); + await page.route("**/api/ui/preferences**", async (route) => { + captured.push({ kind: "ui-preferences", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, owner: "mnote-web", result: {} }), + }); + }); + await page.route("**/api/hermes/client/gateway/health**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + gateway: { ok: true, status: "mocked" }, + profile: { name: "reasonix", modelConfigured: true, apiKeyConfigured: true }, + suggestions: [], + }), + }); + }); + await page.route("**/api/hermes/client/tools**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, tools: [] }), + }); + }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + agentId: "reasonix", + profiles: [ + { profileId: "shared_doubao_chat", kind: "shared", displayName: "豆包 Chat", baseProfile: "doubao-chat", isolatedProfile: "openclaw-doubao-chat", canRun: true, canManageSkills: false, canManageConfig: false, readonly: true }, + { profileId: "usr_task523_default", kind: "personal", displayName: "我的 Hermes", baseProfile: "default", isolatedProfile: "mnote-u-task523-default", canRun: true, canManageSkills: true, canManageConfig: true }, + ], + }), + }); + }); + await page.route("**/api/hermes/client/profiles", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + active: "mnoteai", + profiles: [{ name: "mnoteai", label: "MNote AI", modelConfigured: true, apiKeyConfigured: true }], + }), + }); + }); + await page.route("**/api/hermes/client/skills**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, categories: [], archived: [] }), + }); + }); + await page.route("**/api/hermes/client/sessions", async (route) => { + captured.push({ kind: "session", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + sessionId: `mnote_task523_${suffix}`, + title: "task523", + traceId: `trace_task523_session_${suffix}`, + persistence: "local_ai_session_jsonl", + sessionStorage: "local_private", + }), + }); + }); + await page.route("**/api/hermes/client/runs", async (route) => { + captured.push({ kind: "run", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + sessionId: `mnote_task523_${suffix}`, + runId: `run_task523_${suffix}`, + events: [], + traceId: `trace_task523_run_${suffix}`, + }), + }); + }); + await page.route("**/api/hermes/client/events/*", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "text/event-stream; charset=utf-8" }, + body: + `data: ${JSON.stringify({ event: "message.delta", run_id: `run_task523_${suffix}`, delta: "Task523 response" })}\n\n` + + `data: ${JSON.stringify({ event: "run.completed", run_id: `run_task523_${suffix}`, output: "Task523 response" })}\n\n`, + }); + }); + + await ensureAuthenticated(page, context.request); + const response = await page.goto(documentUrl(root, pageRelativePath), { + waitUntil: "domcontentloaded", + timeout: UI_TIMEOUT_MS, + }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator('[data-testid="mnote-leptos-tiptap-island-editor-root"] .ProseMirror').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + + const officeHref = onlyofficeUrl(root, pageRelativePath, officeRelativePath, assetId); + const openResult = await page.evaluate(async ({ objectIdentity, assetId, documentId, workspaceId, rootUri, officeRelativePath, officeHref }) => { + const runtime = window.__mnoteDocumentPaneRuntime; + if (!runtime || typeof runtime.openResourceInActiveTab !== "function") { + throw new Error("缺少 openResourceInActiveTab runtime"); + } + return await runtime.openResourceInActiveTab({ + objectIdentity, + assetId, + title: "Task523 Office", + fileName: "office-a.docx", + kind: "office", + editorKind: "office", + href: officeHref, + officeUrl: officeHref, + documentId, + workspaceId, + rootUri, + sourceKind: "local_folder", + path: officeRelativePath, + workspacePath: { + schema: "mnote.workspace_path.v1", + workspaceId, + sourceKind: "local_folder", + rootUri, + relativePath: officeRelativePath, + documentId, + objectIdentity, + assetId, + resourceKind: "only_office", + }, + paneRole: "primary", + }); + }, { objectIdentity, assetId, documentId, workspaceId, rootUri, officeRelativePath, officeHref }); + assert.strictEqual(openResult, true, "openResourceInActiveTab 应成功打开 Office resource tab"); + + const officeHandle = await waitForOfficeSnapshot(page, objectIdentity); + const officeSnapshot = await officeHandle.jsonValue(); + const onlyofficeSessionId = String(officeSnapshot.onlyofficeSessionId || officeSnapshot.bridgeSessionId || "").trim(); + assert(onlyofficeSessionId, `Office snapshot 必须携带 bridge session: ${JSON.stringify(officeSnapshot)}`); + assert.strictEqual(officeSnapshot.bridgeSessionReady, true, "Office snapshot 应标记 bridgeSessionReady"); + assert.strictEqual(officeSnapshot.assetId, assetId, `Office snapshot assetId 不匹配: ${JSON.stringify(officeSnapshot)}`); + assert.strictEqual(officeSnapshot.bridgeAssetId, assetId, `Office iframe debug assetId 应透传到 snapshot: ${JSON.stringify(officeSnapshot)}`); + result.officeSnapshot = officeSnapshot; + result.screenshots.push(await saveScreenshot(page, "00-office-resource-tab-ready")); + + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + + const targetButton = page.locator("[data-page-ai-target-button]"); + await targetButton.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await targetButton.click({ timeout: UI_TIMEOUT_MS }); + const targetPopover = page.locator("[data-page-ai-target-popover]"); + await targetPopover.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await targetPopover.locator(`[data-page-ai-target-option="${objectIdentity}"]`).click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector("[data-page-ai-target-chip]")?.textContent || "").includes("Task523 Office"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + result.screenshots.push(await saveScreenshot(page, "01-page-ai-office-target-selected")); + + await page.locator("[data-page-ai-input]").fill(`Task523 OnlyOffice target ${suffix}`, { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector('[data-testid="wolai-page-ai-drawer"]')?.textContent || "").includes("Task523 response"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + + const runPayloads = captured.filter((item) => item.kind === "run"); + assert(runPayloads.length >= 1, "未捕获 Page AI run payload"); + const runBody = JSON.parse(runPayloads[runPayloads.length - 1].body); + const targetPackage = runBody.targetPackage || {}; + const packageTarget = Array.isArray(targetPackage.targets) + ? targetPackage.targets.find((target) => target.targetId === objectIdentity) + : null; + assert.strictEqual(runBody.editorTarget?.targetId, objectIdentity, `editorTarget 应冻结 Office target: ${JSON.stringify(runBody.editorTarget)}`); + assert.strictEqual(runBody.editorTarget?.resourceKind, "only_office", `editorTarget 应归一为 only_office: ${JSON.stringify(runBody.editorTarget)}`); + assert.strictEqual(runBody.editorTarget?.onlyofficeSessionId, onlyofficeSessionId, `editorTarget 应携带 iframe live session: ${JSON.stringify(runBody.editorTarget)}`); + assert.strictEqual(targetPackage.schema, "mnote.agent_target_package.v1", "targetPackage schema 不匹配"); + assert.strictEqual(targetPackage.primaryTargetId, objectIdentity, `targetPackage 应冻结 Office target: ${JSON.stringify(targetPackage)}`); + assert.strictEqual(targetPackage.onlyofficeSessionId, onlyofficeSessionId, `targetPackage 顶层应携带 live session: ${JSON.stringify(targetPackage)}`); + assert(packageTarget, `targetPackage.targets 应包含 Office target: ${JSON.stringify(targetPackage)}`); + assert.strictEqual(packageTarget.resourceKind, "only_office", `targetPackage target 应归一为 only_office: ${JSON.stringify(packageTarget)}`); + assert.strictEqual(packageTarget.relativePath, officeRelativePath, `targetPackage target 应携带 Office 相对路径: ${JSON.stringify(packageTarget)}`); + assert.strictEqual(packageTarget.assetId, assetId, `targetPackage target 应携带 assetId: ${JSON.stringify(packageTarget)}`); + assert.strictEqual(packageTarget.onlyofficeSessionId, onlyofficeSessionId, `targetPackage target 应携带 live session: ${JSON.stringify(packageTarget)}`); + assert( + Array.isArray(targetPackage.allowedFiles) && targetPackage.allowedFiles.includes(officeRelativePath), + `targetPackage.allowedFiles 应只按选中 Office target 授权: ${JSON.stringify(targetPackage)}`, + ); + assert.strictEqual( + httpErrors.filter((item) => item.url.includes("/api/documents/buffer-state")).length, + 0, + `Office target 不应触发 Markdown buffer-state 查询: ${JSON.stringify(httpErrors)}`, + ); + + Object.assign(result, { + ok: true, + onlyofficeSessionId, + runBody: { + agentId: runBody.agentId, + editorTarget: runBody.editorTarget, + targetPackage, + }, + }); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + result.error = error && error.stack ? error.stack : String(error); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + throw error; + } finally { + await context.close().catch(() => undefined); + await browser.close().catch(() => undefined); + } +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task524-workspace-object-identity-matrix-smoke.js b/scripts/task524-workspace-object-identity-matrix-smoke.js new file mode 100644 index 00000000..cd4397c0 --- /dev/null +++ b/scripts/task524-workspace-object-identity-matrix-smoke.js @@ -0,0 +1,331 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); + +const BASE_URL = (process.env.MNOTE_UI_BASE_URL || process.env.MNOTE_WEB_SMOKE_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); +const UI_TIMEOUT_MS = Number(process.env.MNOTE_SMOKE_UI_TIMEOUT_MS || 30_000); +const PROBE_DOCX_PATH = process.env.MNOTE_ONLYOFFICE_PROBE_DOCX + || "/tmp/mnote-onlyoffice-manual/mnote-onlyoffice-upload-test.docx"; +const OUT_DIR = path.join(process.cwd(), "tmp", "task524-workspace-object-identity-matrix-smoke"); +const RESULT_PATH = path.join(OUT_DIR, "result.json"); +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "markdown_edit", "asset_upload"], + }, null, 2)}\n`, + "utf8", + ); +} + +async function quickLogin(page) { + await page.goto(`${BASE_URL}/auth`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + const quickLoginButton = page.getByRole("button", { name: "测试账号快速登录" }); + if (await quickLoginButton.count()) { + await quickLoginButton.click({ timeout: UI_TIMEOUT_MS }); + await page.waitForURL((url) => url.pathname !== "/auth", { timeout: UI_TIMEOUT_MS }).catch(() => undefined); + } +} + +async function filetreeRowState(page, relativePath) { + return await page.evaluate((targetRelativePath) => { + const row = Array.from(document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]')) + .find((candidate) => candidate instanceof HTMLElement && candidate.getAttribute("data-local-relative-path") === targetRelativePath); + if (!(row instanceof HTMLElement)) { + return null; + } + const params = new URL(window.location.href).searchParams; + const workspacePath = window.__mnoteFileTreeRuntime?.readWorkspacePathFromRow?.(row, { + currentSourceKind: () => params.get("sourceKind") || document.body.dataset.mnoteSourceKind || "local_folder", + currentRootUri: () => params.get("rootUri") || document.body.dataset.mnoteRootUri || "", + resolveWorkspaceId: () => document.body.dataset.workspaceId || "", + rowTitle: (candidate) => candidate.textContent || "", + }) || null; + const objectIdentityRaw = row.getAttribute("data-object-identity") || ""; + let objectIdentity = null; + try { + objectIdentity = objectIdentityRaw ? JSON.parse(objectIdentityRaw) : null; + } catch { + objectIdentity = objectIdentityRaw; + } + return { + rowId: row.getAttribute("data-row-id") || "", + rowKind: row.getAttribute("data-row-kind") || "", + documentId: row.getAttribute("data-document-id") || "", + assetId: row.getAttribute("data-asset-id") || "", + relativePath: row.getAttribute("data-local-relative-path") || "", + objectIdentity, + workspacePath, + expanded: row.getAttribute("aria-expanded") || "", + }; + }, relativePath); +} + +async function clickFiletreeOpen(page, relativePath) { + const row = page.locator(`#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path="${relativePath.replace(/"/g, '\\"')}"]`).first(); + await row.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await row.locator('[data-rust-action="open"]').click({ timeout: UI_TIMEOUT_MS }); +} + +async function waitFiletreeRow(page, relativePath) { + const row = page.locator(`#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path="${relativePath.replace(/"/g, '\\"')}"]`).first(); + await row.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); +} + +async function expandFiletreeFolder(page, relativePath) { + const row = page.locator(`#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path="${relativePath.replace(/"/g, '\\"')}"]`).first(); + await row.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const expanded = await row.getAttribute("aria-expanded"); + if (expanded === "true") return; + await row.locator('[data-rust-action="open"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + (targetRelativePath) => { + const candidate = Array.from(document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]')) + .find((row) => row instanceof HTMLElement && row.getAttribute("data-local-relative-path") === targetRelativePath); + return candidate && candidate.getAttribute("aria-expanded") === "true"; + }, + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function activeSnapshotEntry(page, expectedRelativePath, expectedKind) { + return await page.waitForFunction( + ({ expectedRelativePath, expectedKind }) => { + const snapshot = window.__mnoteOpenEditorsSnapshot || null; + const liveSnapshot = window.__mnoteDocumentPaneRuntime?.getOpenEditorsSnapshot?.() || snapshot; + const resources = Array.isArray(liveSnapshot?.resourceEditors) ? liveSnapshot.resourceEditors : []; + const entries = Array.isArray(liveSnapshot?.editors) ? liveSnapshot.editors.concat(resources) : resources; + const activeObjectIdentity = String(liveSnapshot?.activeObjectIdentity || ""); + const active = entries.find((entry) => + entry + && (entry.active === true || entry.objectIdentity === activeObjectIdentity) + && (!expectedRelativePath || entry.workspacePath?.relativePath === expectedRelativePath || entry.path === expectedRelativePath) + && (!expectedKind || entry.kind === expectedKind || entry.editorKind === expectedKind || entry.workspacePath?.resourceKind === expectedKind) + ); + return active || null; + }, + { expectedRelativePath, expectedKind }, + { timeout: UI_TIMEOUT_MS }, + ); +} + +function assertWorkspacePathMatchesRow(label, rowState, snapshotEntry, expected) { + assert(rowState, `${label}: 缺少 FileTree row state`); + assert(rowState.workspacePath, `${label}: FileTree row 缺少 workspacePath: ${JSON.stringify(rowState)}`); + assert(snapshotEntry, `${label}: 缺少 OpenEditorsSnapshot entry`); + assert.equal(rowState.workspacePath.schema, "mnote.workspace_path.v1", `${label}: row workspacePath schema`); + assert.equal(snapshotEntry.workspacePath?.schema, "mnote.workspace_path.v1", `${label}: snapshot workspacePath schema`); + assert.equal(rowState.workspacePath.relativePath, expected.relativePath, `${label}: row relativePath`); + assert.equal(snapshotEntry.workspacePath?.relativePath, expected.relativePath, `${label}: snapshot relativePath`); + assert.equal(snapshotEntry.workspacePath?.sourceKind, rowState.workspacePath.sourceKind, `${label}: sourceKind 应一致`); + assert.equal(snapshotEntry.workspacePath?.rootUri, rowState.workspacePath.rootUri, `${label}: rootUri 应一致`); + assert.equal(snapshotEntry.workspacePath?.documentId, rowState.workspacePath.documentId, `${label}: documentId 应一致`); + if (expected.assetId) { + assert.equal(rowState.workspacePath.assetId, expected.assetId, `${label}: row assetId`); + assert.equal(snapshotEntry.workspacePath?.assetId, expected.assetId, `${label}: snapshot assetId`); + } + if (expected.resourceKind) { + assert.equal(rowState.workspacePath.resourceKind, expected.resourceKind, `${label}: row resourceKind`); + assert.equal(snapshotEntry.workspacePath?.resourceKind, expected.resourceKind, `${label}: resourceKind`); + } + if (expected.objectKind) { + assert.equal(rowState.workspacePath.objectIdentity?.objectKind, expected.objectKind, `${label}: row objectKind`); + assert.equal(snapshotEntry.workspacePath?.objectIdentity?.objectKind, expected.objectKind, `${label}: snapshot objectKind`); + } + if (rowState.workspacePath.objectIdentity && typeof rowState.workspacePath.objectIdentity === "object" + && snapshotEntry.workspacePath?.objectIdentity && typeof snapshotEntry.workspacePath.objectIdentity === "object") { + assert.deepStrictEqual( + snapshotEntry.workspacePath.objectIdentity, + rowState.workspacePath.objectIdentity, + `${label}: snapshot objectIdentity 应与 row objectIdentity 对齐`, + ); + } +} + +async function main() { + fs.mkdirSync(OUT_DIR, { recursive: true }); + const actorId = "mnote-e2e"; + const workspaceId = `local-ws:${actorId}:task524`; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task524-identity-")); + const rootUri = fileUrl(root); + fs.mkdirSync(path.join(root, "Page"), { recursive: true }); + fs.mkdirSync(path.join(root, "docs"), { recursive: true }); + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, "Page.md"), "# Page\n\nTask524 page\n", "utf8"); + fs.writeFileSync(path.join(root, "docs", "Plan.md"), "# Plan\n\nTask524 plan\n", "utf8"); + fs.writeFileSync(path.join(root, "Page", "notes.txt"), "Task524 text resource\n", "utf8"); + fs.writeFileSync(path.join(root, "Page", "map.mindmap.json"), JSON.stringify({ + root: { data: { text: "Task524 Mindmap" }, children: [] }, + }, null, 2), "utf8"); + if (fs.existsSync(PROBE_DOCX_PATH)) { + fs.copyFileSync(PROBE_DOCX_PATH, path.join(root, "Page", "office.docx")); + } else { + fs.writeFileSync(path.join(root, "Page", "office.docx"), "task524 office probe\n", "utf8"); + } + + const browser = await chromium.launch({ + headless: process.env.HEADFUL !== "1", + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + const result = { + ok: false, + task: "task524-workspace-object-identity-matrix-smoke", + baseUrl: BASE_URL, + root, + rootUri, + checks: [], + }; + + try { + await quickLogin(page); + await page.goto(documentUrl(root, "Page.md"), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + await page.locator(".document-pane[data-pane-role=\"primary\"] .editor-surface .ProseMirror").first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await page.waitForFunction(() => Boolean(window.__mnoteFileTreeRuntime?.readWorkspacePathFromRow), null, { + timeout: UI_TIMEOUT_MS, + }); + await page.waitForFunction(() => Boolean(window.__mnoteOpenEditorsSnapshot), null, { + timeout: UI_TIMEOUT_MS, + }); + await page.evaluate(() => { + window.__task524IdentityEvents = []; + window.addEventListener("tree.filetree.open", (event) => { + window.__task524IdentityEvents.push({ type: "tree.filetree.open", detail: event.detail || null }); + }); + window.addEventListener("tree.asset.open", (event) => { + window.__task524IdentityEvents.push({ type: "tree.asset.open", detail: event.detail || null }); + }); + }); + + const pageRow = await filetreeRowState(page, "Page.md"); + const pageEntry = await page.evaluate(() => { + const snapshot = window.__mnoteDocumentPaneRuntime?.getOpenEditorsSnapshot?.() || window.__mnoteOpenEditorsSnapshot || null; + return snapshot?.groups?.primary?.editors?.find((entry) => entry.kind === "page" && entry.documentId === "local-md:Page.md") || null; + }); + assertWorkspacePathMatchesRow("page", pageRow, pageEntry, { + relativePath: "Page.md", + resourceKind: "page", + objectKind: "page", + }); + result.checks.push({ kind: "page", row: pageRow, snapshot: pageEntry }); + + const folderRow = await filetreeRowState(page, "docs"); + assert(folderRow, "folder: 缺少 docs row"); + assert.equal(folderRow.workspacePath?.schema, "mnote.workspace_path.v1", "folder row workspacePath schema"); + assert.equal(folderRow.workspacePath?.relativePath, "docs", "folder row relativePath"); + assert.equal(folderRow.workspacePath?.documentId, "local-dir:docs", "folder row documentId"); + assert.equal(folderRow.workspacePath?.objectIdentity?.objectKind, "index", "folder row objectKind"); + const beforeFolderUrl = page.url(); + await clickFiletreeOpen(page, "docs"); + await page.waitForFunction(() => { + const row = document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-local-relative-path="docs"]'); + return row && row.getAttribute("aria-expanded") === "true"; + }, null, { timeout: UI_TIMEOUT_MS }); + assert.equal(page.url(), beforeFolderUrl, "FileTree folder open 只应展开,不应改 URL"); + result.checks.push({ kind: "folder", row: folderRow }); + + await expandFiletreeFolder(page, "Page"); + + const resources = [ + { label: "text", relativePath: "Page/notes.txt", kind: "text", resourceKind: "attachment", objectKind: "attachment" }, + { label: "mindmap", relativePath: "Page/map.mindmap.json", kind: "mindmap", resourceKind: "mindmap", objectKind: "mindmap" }, + { label: "office", relativePath: "Page/office.docx", kind: "office", resourceKind: "only_office", objectKind: "only_office" }, + ]; + + for (const resource of resources) { + await waitFiletreeRow(page, resource.relativePath); + const rowState = await filetreeRowState(page, resource.relativePath); + assert(rowState, `${resource.label}: 缺少 FileTree row`); + await clickFiletreeOpen(page, resource.relativePath); + const entryHandle = await activeSnapshotEntry(page, resource.relativePath, resource.kind); + const entry = await entryHandle.jsonValue(); + assertWorkspacePathMatchesRow(resource.label, rowState, entry, { + relativePath: resource.relativePath, + assetId: rowState.workspacePath.assetId, + resourceKind: resource.resourceKind, + objectKind: resource.objectKind, + }); + assert.equal(entry.kind, resource.kind, `${resource.label}: editor kind`); + const eventDetail = await page.evaluate((relativePath) => { + const events = Array.isArray(window.__task524IdentityEvents) ? window.__task524IdentityEvents : []; + return [...events].reverse().find((event) => event?.detail?.workspacePath?.relativePath === relativePath) || null; + }, resource.relativePath); + assert(eventDetail, `${resource.label}: 应捕获真实 tree.asset.open 事件`); + assert.equal(eventDetail.detail.workspacePath?.sourceKind, rowState.workspacePath.sourceKind, `${resource.label}: event sourceKind`); + assert.equal(eventDetail.detail.workspacePath?.rootUri, rowState.workspacePath.rootUri, `${resource.label}: event rootUri`); + assert.equal(eventDetail.detail.workspacePath?.documentId, rowState.workspacePath.documentId, `${resource.label}: event documentId`); + assert.equal(eventDetail.detail.workspacePath?.assetId, rowState.workspacePath.assetId, `${resource.label}: event assetId`); + assert.deepStrictEqual(eventDetail.detail.workspacePath?.objectIdentity, rowState.workspacePath.objectIdentity, `${resource.label}: event objectIdentity`); + const url = new URL(page.url()); + const resourceTab = url.searchParams.get("resourceTab") || ""; + assert( + resourceTab === `primary::${entry.objectIdentity}`, + `${resource.label}: URL resourceTab 应等于 active snapshot objectIdentity: ${JSON.stringify({ resourceTab, entry })}`, + ); + const activeTabIdentity = await page.evaluate(() => { + const activeTab = document.querySelector(".mnote-main-tab.is-active"); + return activeTab?.getAttribute("data-mnote-object-identity") || ""; + }); + if (activeTabIdentity) { + assert.equal(activeTabIdentity, entry.objectIdentity, `${resource.label}: active tab identity`); + } + result.checks.push({ kind: resource.label, row: rowState, snapshot: entry, resourceTab, activeTabIdentity }); + } + + result.ok = true; + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + result.error = error && error.stack ? error.stack : String(error); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + throw error; + } finally { + await context.close().catch(() => undefined); + await browser.close().catch(() => undefined); + } +} + +main().catch((error) => { + console.error(error && error.stack ? error.stack : error); + process.exit(1); +}); diff --git a/scripts/task525-page-ai-mindmap-resource-target-smoke.js b/scripts/task525-page-ai-mindmap-resource-target-smoke.js new file mode 100644 index 00000000..e713f933 --- /dev/null +++ b/scripts/task525-page-ai-mindmap-resource-target-smoke.js @@ -0,0 +1,299 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { + BASE_URL, + UI_TIMEOUT_MS, + ensureAuthenticated, +} = require("./tree-shell-smoke-helpers"); + +const TASK = "task525-page-ai-mindmap-resource-target-smoke"; +const OUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUT_DIR, "result.json"); +const CHROMIUM_EXECUTABLE_PATH = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + || ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/snap/bin/chromium", "/usr/bin/chromium"] + .find((candidate) => fs.existsSync(candidate)); + +function fileUrl(localPath) { + return `file://${localPath}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${relativePath.replaceAll("/", "~2F")}`; +} + +function writeWorkspaceManifest(root, ownerId, workspaceId) { + fs.mkdirSync(path.join(root, ".mnote"), { recursive: true }); + fs.writeFileSync( + path.join(root, ".mnote", "workspace.json"), + `${JSON.stringify({ + workspaceId, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "ai_sessions", "markdown_edit"], + }, null, 2)}\n`, + "utf8", + ); +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +async function waitFiletreeRow(page, relativePath) { + await page.waitForFunction( + (expectedRelativePath) => Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .some((row) => row.getAttribute("data-local-relative-path") === expectedRelativePath), + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function clickFiletreeOpen(page, relativePath) { + const handle = await page.waitForFunction( + (expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.querySelector('[data-rust-action="open"], .tree-link') || null; + }, + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); + await handle.asElement().click(); +} + +async function expandFiletreeFolder(page, relativePath) { + await waitFiletreeRow(page, relativePath); + const expanded = await page.evaluate((expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.getAttribute("aria-expanded") === "true"; + }, relativePath); + if (!expanded) { + await clickFiletreeOpen(page, relativePath); + } + await page.waitForFunction( + (expectedRelativePath) => { + const row = Array.from(document.querySelectorAll("#sidebar-file-tree-root .tree-row[data-shell-mode=\"filetree\"]")) + .find((candidate) => candidate.getAttribute("data-local-relative-path") === expectedRelativePath); + return row?.getAttribute("aria-expanded") === "true"; + }, + relativePath, + { timeout: UI_TIMEOUT_MS }, + ); +} + +async function saveScreenshot(page, name) { + const target = path.join(OUT_DIR, `${name}.png`); + await page.screenshot({ path: target, fullPage: false }); + return target; +} + +async function main() { + fs.mkdirSync(OUT_DIR, { recursive: true }); + const actorId = "mnote-e2e"; + const workspaceId = `local-ws:${actorId}:task525`; + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task525-mindmap-target-")); + const rootUri = fileUrl(root); + const pagePath = "Page/Page.md"; + const mindmapPath = "Page/map.mindmap.json"; + const documentId = localMdDocumentId(pagePath); + const assetId = `local-file:${mindmapPath}`; + const expectedTargetId = `resource:mindmap:${documentId}:${assetId}`; + const captured = []; + let caughtError = null; + + fs.mkdirSync(path.join(root, "Page"), { recursive: true }); + writeWorkspaceManifest(root, actorId, workspaceId); + fs.writeFileSync(path.join(root, pagePath), "# Page\n\n[思维导图](map.mindmap.json)\n", "utf8"); + fs.writeFileSync( + path.join(root, mindmapPath), + `${JSON.stringify({ data: { text: "Task525 mindmap" }, children: [] }, null, 2)}\n`, + "utf8", + ); + + const browser = await chromium.launch({ + headless: process.env.HEADFUL !== "1", + ...(CHROMIUM_EXECUTABLE_PATH ? { executablePath: CHROMIUM_EXECUTABLE_PATH } : {}), + }); + const context = await browser.newContext({ + viewport: { width: 1440, height: 960 }, + locale: "zh-CN", + extraHTTPHeaders: { + "x-mnote-actor-id": actorId, + "x-mnote-actor-type": "user", + }, + }); + const page = await context.newPage(); + + try { + await page.route("**/api/user/access-policy**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + ok: true, + grants: [{ + id: "grant_task525", + userId: actorId, + workspaceId, + rootUri, + rootPath: root, + permission: "write", + recursive: true, + capabilities: ["ai", "markdown_edit"], + source: "user", + status: "active", + }], + }), + }); + }); + await page.route("**/api/ui/preferences**", async (route) => { + captured.push({ kind: "ui-preferences", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, owner: "mnote-web", result: {} }), + }); + }); + await page.route("**/api/hermes/client/gateway/health**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, gateway: { ok: true }, profile: { name: "reasonix", modelConfigured: true, apiKeyConfigured: true } }), + }); + }); + await page.route("**/api/hermes/client/tools**", async (route) => { + await route.fulfill({ status: 200, headers: { "content-type": "application/json" }, body: JSON.stringify({ ok: true, tools: [] }) }); + }); + await page.route("**/api/ai/agent-profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, agentId: "reasonix", profiles: [] }), + }); + }); + await page.route("**/api/hermes/client/profiles**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, active: "mnoteai", profiles: [{ name: "mnoteai", label: "MNote AI", modelConfigured: true, apiKeyConfigured: true }] }), + }); + }); + await page.route("**/api/hermes/client/skills**", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, categories: [], archived: [] }), + }); + }); + await page.route("**/api/hermes/client/sessions", async (route) => { + captured.push({ kind: "session", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, sessionId: "mnote_task525", title: "task525", traceId: "trace_task525" }), + }); + }); + await page.route("**/api/hermes/client/runs", async (route) => { + captured.push({ kind: "run", method: route.request().method(), body: route.request().postData() || "" }); + await route.fulfill({ + status: 200, + headers: { "content-type": "application/json" }, + body: JSON.stringify({ ok: true, sessionId: "mnote_task525", runId: "run_task525", events: [], traceId: "trace_run_task525" }), + }); + }); + await page.route("**/api/hermes/client/events/*", async (route) => { + await route.fulfill({ + status: 200, + headers: { "content-type": "text/event-stream; charset=utf-8" }, + body: `data: ${JSON.stringify({ event: "message.delta", run_id: "run_task525", delta: "Task525 response" })}\n\n` + + `data: ${JSON.stringify({ event: "run.completed", run_id: "run_task525", output: "Task525 response" })}\n\n`, + }); + }); + + await ensureAuthenticated(page, context.request); + const response = await page.goto(documentUrl(root, pagePath), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + assert(response && response.status() === 200, `文档页状态码异常: ${response && response.status()}`); + await page.locator(".document-pane[data-pane-role=\"primary\"] .editor-surface .ProseMirror").first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + await expandFiletreeFolder(page, "Page"); + await waitFiletreeRow(page, mindmapPath); + await clickFiletreeOpen(page, mindmapPath); + await page.waitForFunction( + () => { + return Boolean(document.querySelector('[data-testid="mnote-mindmap-editor-root"]')) + && (document.body?.innerText || "").includes("map.mindmap.json"); + }, + null, + { timeout: UI_TIMEOUT_MS }, + ); + + await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS }); + await page.locator('[data-testid="wolai-page-ai-drawer"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const targetChip = page.locator("[data-page-ai-target-chip]"); + await targetChip.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + const chipText = (await targetChip.innerText({ timeout: UI_TIMEOUT_MS })).trim(); + assert(chipText.includes("map.mindmap.json"), `mindmap resource 打开后 target chip 应指向 map.mindmap.json: ${chipText}`); + + await page.locator("[data-page-ai-input]").fill("Task525 mindmap target", { timeout: UI_TIMEOUT_MS }); + await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS }); + await page.waitForFunction( + () => (document.querySelector('[data-testid="wolai-page-ai-drawer"]')?.textContent || "").includes("Task525 response"), + null, + { timeout: UI_TIMEOUT_MS }, + ); + + const runs = captured.filter((item) => item.kind === "run"); + assert(runs.length >= 1, "未捕获 Page AI run payload"); + const runBody = JSON.parse(runs[runs.length - 1].body || "{}"); + const activeEditorRef = runBody.contextRefs?.find((item) => item.kind === "active_editor"); + assert(activeEditorRef, `run payload 应包含 active_editor contextRef: ${JSON.stringify(runBody.contextRefs)}`); + assert.strictEqual(activeEditorRef.resourceKind, "mindmap", `active_editor 应标记 mindmap resourceKind: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.assetId, assetId, `active_editor 应携带 mindmap assetId: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.objectIdentity, expectedTargetId, `active_editor objectIdentity 不应退化: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(activeEditorRef.relativePath, mindmapPath, `active_editor 应携带 mindmap relativePath: ${JSON.stringify(activeEditorRef)}`); + assert.strictEqual(runBody.targetPackage?.schema, "mnote.agent_target_package.v1", "run payload 应携带 targetPackage"); + assert.strictEqual(runBody.targetPackage?.primaryTargetId, expectedTargetId, `targetPackage 应冻结 mindmap target: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.objectIdentity, expectedTargetId, `targetPackage objectIdentity 不应退化: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.resourceKind, "mindmap", `targetPackage 应保留 mindmap resourceKind: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.currentFile?.relativePath, mindmapPath, `targetPackage currentFile 应指向 mindmap resource: ${JSON.stringify(runBody.targetPackage)}`); + assert.strictEqual(runBody.targetPackage?.currentFile?.objectIdentity, expectedTargetId, `currentFile objectIdentity 不应退化: ${JSON.stringify(runBody.targetPackage?.currentFile)}`); + assert(runBody.targetPackage?.allowedFiles?.includes(mindmapPath), `allowedFiles 应包含 mindmap resource: ${JSON.stringify(runBody.targetPackage?.allowedFiles)}`); + + const screenshot = await saveScreenshot(page, "01-mindmap-resource-target"); + const result = { ok: true, task: TASK, baseUrl: BASE_URL, root, rootUri, documentId, mindmapPath, assetId, expectedTargetId, screenshot, captured }; + fs.writeFileSync(RESULT_PATH, `${JSON.stringify(result, null, 2)}\n`, "utf8"); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + caughtError = error; + await saveScreenshot(page, "failure").catch(() => undefined); + } finally { + fs.rmSync(root, { recursive: true, force: true }); + await page.close().catch(() => undefined); + await context.close().catch(() => undefined); + await browser.close().catch(() => undefined); + } + + if (caughtError) { + throw caughtError; + } +} + +if (require.main === module) { + main().catch((error) => { + console.error(error); + process.exit(1); + }); +} diff --git a/scripts/task526-local-folder-ocr-api-smoke.js b/scripts/task526-local-folder-ocr-api-smoke.js new file mode 100644 index 00000000..c86d2d7e --- /dev/null +++ b/scripts/task526-local-folder-ocr-api-smoke.js @@ -0,0 +1,262 @@ +#!/usr/bin/env node +"use strict"; + +const assert = require("node:assert"); +const fs = require("node:fs"); +const os = require("node:os"); +const path = require("node:path"); +const { chromium } = require("playwright"); +const { ensureAuthenticated, UI_TIMEOUT_MS } = require("./tree-shell-smoke-helpers"); + +const BASE_URL = (process.env.MNOTE_WEB_SMOKE_BASE_URL || process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); +const TASK = "task526-local-folder-ocr-api-smoke"; +const OUTPUT_DIR = path.join(process.cwd(), "tmp", TASK); +const RESULT_PATH = path.join(OUTPUT_DIR, "result.json"); + +function fileUrl(localPath) { + return `file://${localPath.split(path.sep).map((part, index) => ( + index === 0 ? "" : encodeURIComponent(part) + )).join("/")}`; +} + +function localMdDocumentId(relativePath) { + return `local-md:${Buffer.from(relativePath, "utf8") + .toString("hex") + .replace(/../g, (hex) => { + const code = Number.parseInt(hex, 16); + const ch = String.fromCharCode(code); + return /[A-Za-z0-9._-]/.test(ch) ? ch : `~${hex.toUpperCase()}`; + })}`; +} + +function documentUrl(root, relativePath) { + const url = new URL(`${BASE_URL}/documents/${encodeURIComponent(localMdDocumentId(relativePath))}`); + url.searchParams.set("sourceKind", "local_folder"); + url.searchParams.set("rootUri", fileUrl(root)); + url.searchParams.set("treeView", "filetree"); + return url.toString(); +} + +function writeWorkspaceManifest(root, ownerId) { + const metadataDir = path.join(root, ".mnote"); + fs.mkdirSync(metadataDir, { recursive: true }); + fs.writeFileSync( + path.join(metadataDir, "workspace.json"), + `${JSON.stringify({ + workspaceId: `local-ws:${ownerId}:task526`, + ownerId, + createdAt: new Date().toISOString(), + capabilities: ["local_files", "markdown_edit", "ocr"], + }, null, 2)}\n`, + "utf8", + ); +} + +async function writeResult(payload) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + fs.writeFileSync(RESULT_PATH, `${JSON.stringify({ ...payload, resultPath: RESULT_PATH }, null, 2)}\n`, "utf8"); +} + +async function ensureDocumentVisible(page, root, relativePath) { + await page.goto(documentUrl(root, relativePath), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + if (new URL(page.url()).pathname === "/auth") { + const quickLogin = page.getByRole("button", { name: "测试账号快速登录" }); + await quickLogin.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS }); + await quickLogin.click({ timeout: UI_TIMEOUT_MS }); + await page.waitForURL((url) => url.pathname !== "/auth", { timeout: UI_TIMEOUT_MS }).catch(() => undefined); + await page.goto(documentUrl(root, relativePath), { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS }); + } + await page.locator('[data-testid="mnote-leptos-tiptap-island-editor-root"]').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); +} + +async function main() { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + const root = fs.mkdtempSync(path.join(os.tmpdir(), "mnote-task526-ocr-")); + const actorId = "mnote-e2e"; + const workspaceId = `local-ws:${actorId}:task526`; + const relativePath = "docs/Page.md"; + const documentId = localMdDocumentId(relativePath); + const sourceRootRelativePath = "docs/Page.assets/photo.png"; + const ocrToken = "TASK526_OCR_TOKEN"; + writeWorkspaceManifest(root, actorId); + fs.mkdirSync(path.join(root, "docs", "Page.assets"), { recursive: true }); + fs.writeFileSync(path.join(root, relativePath), "# OCR Page\n\n![photo](./Page.assets/photo.png)\n", "utf8"); + fs.writeFileSync(path.join(root, sourceRootRelativePath), Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a])); + + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext(); + const page = await context.newPage(); + const screenshots = {}; + try { + await ensureAuthenticated(page, context.request); + await ensureDocumentVisible(page, root, relativePath); + screenshots.page = path.join(OUTPUT_DIR, "01-page.png"); + await page.screenshot({ path: screenshots.page, fullPage: true }); + + const result = await page.evaluate(async ({ rootUri, documentId, sourceRootRelativePath, workspaceId, ocrToken }) => { + async function jsonFetch(pathname, init = {}) { + const response = await fetch(pathname, { + ...init, + headers: { + "content-type": "application/json", + ...(init.headers || {}), + }, + }); + const payload = await response.json().catch(() => null); + return { status: response.status, payload }; + } + const create = await jsonFetch("/api/local-folder/ocr/jobs", { + method: "POST", + body: JSON.stringify({ + rootUri, + documentId, + sourceRootRelativePath, + provider: "mock", + mockMarkdown: `# OCR Result\n\n${ocrToken} browser smoke text`, + }), + }); + const ocrRootRelativePath = create.payload?.job?.ocrRootRelativePath || ""; + const read = await jsonFetch(`/api/local-folder/ocr/read?rootUri=${encodeURIComponent(rootUri)}&ocrRootRelativePath=${encodeURIComponent(ocrRootRelativePath)}`, { + method: "GET", + headers: {}, + }); + const status = await jsonFetch(`/api/local-folder/ocr/status?rootUri=${encodeURIComponent(rootUri)}&sourceRootRelativePath=${encodeURIComponent(sourceRootRelativePath)}`, { + method: "GET", + headers: {}, + }); + const jobs = await jsonFetch(`/api/local-folder/ocr/jobs?rootUri=${encodeURIComponent(rootUri)}`, { + method: "GET", + headers: {}, + }); + const withoutOcr = await jsonFetch("/api/search/documents", { + method: "POST", + body: JSON.stringify({ + workspaceId, + sourceKind: "local_folder", + rootUri, + query: ocrToken, + limit: 5, + filters: { includeOcr: false }, + }), + }); + const withOcr = await jsonFetch("/api/search/documents", { + method: "POST", + body: JSON.stringify({ + workspaceId, + sourceKind: "local_folder", + rootUri, + query: ocrToken, + limit: 5, + filters: { includeOcr: true }, + }), + }); + const insert = await jsonFetch("/api/local-folder/ocr/insert", { + method: "POST", + body: JSON.stringify({ + rootUri, + documentId, + ocrRootRelativePath, + mode: "link", + }), + }); + return { create, read, status, jobs, withoutOcr, withOcr, insert, ocrRootRelativePath }; + }, { + rootUri: fileUrl(root), + documentId, + sourceRootRelativePath, + workspaceId, + ocrToken, + }); + + assert.equal(result.create.status, 200, `OCR create failed: ${JSON.stringify(result.create)}`); + assert.equal(result.create.payload.job.status, "done", `OCR job should be done: ${JSON.stringify(result.create.payload)}`); + assert(result.ocrRootRelativePath.endsWith(".ocr.md"), `OCR path invalid: ${result.ocrRootRelativePath}`); + assert.equal(result.read.status, 200, `OCR read failed: ${JSON.stringify(result.read)}`); + assert(result.read.payload.markdown.includes(ocrToken), "OCR read should include mock OCR text"); + assert.equal(result.status.payload.job.ocrRootRelativePath, result.ocrRootRelativePath, "status should return OCR sidecar path"); + assert(result.jobs.payload.jobs.some((job) => job.ocrRootRelativePath === result.ocrRootRelativePath), "jobs list should include OCR job"); + assert.equal(result.withoutOcr.payload.results.length, 0, `includeOcr=false should not match OCR text: ${JSON.stringify(result.withoutOcr.payload)}`); + const ocrResult = result.withOcr.payload.results.find((item) => item.hasOcr === true); + assert(ocrResult, `includeOcr=true should return owner page OCR result: ${JSON.stringify(result.withOcr.payload)}`); + assert.equal(ocrResult.documentId, documentId, "OCR search result should point to owner document"); + assert.equal(ocrResult.ocrEvidence.ocrRootRelativePath, result.ocrRootRelativePath, "OCR evidence should include sidecar path"); + assert.equal(result.insert.status, 200, `OCR insert failed: ${JSON.stringify(result.insert)}`); + const ownerMarkdown = fs.readFileSync(path.join(root, relativePath), "utf8"); + assert(ownerMarkdown.includes(`[OCR:photo.png](`), `owner markdown should include explicit OCR link:\n${ownerMarkdown}`); + + await page.waitForFunction(() => Boolean(window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab), null, { + timeout: UI_TIMEOUT_MS, + }); + const openResourceResult = await page.evaluate(async ({ rootUri, documentId, ocrRootRelativePath, workspaceId }) => { + const runtime = window.__mnoteDocumentPaneRuntime; + if (!runtime || typeof runtime.openResourceInActiveTab !== "function") { + throw new Error("缺少 openResourceInActiveTab runtime"); + } + const title = ocrRootRelativePath.split("/").filter(Boolean).pop() || "OCR"; + return await runtime.openResourceInActiveTab({ + kind: "markdown", + title, + path: ocrRootRelativePath, + objectIdentity: `local-ocr:${ocrRootRelativePath}`, + assetId: `local-ocr:${ocrRootRelativePath}`, + documentId, + ownerDocumentId: documentId, + workspaceId, + sourceKind: "local_folder", + rootUri, + resourceKind: "markdown", + }); + }, { + rootUri: fileUrl(root), + documentId, + ocrRootRelativePath: result.ocrRootRelativePath, + workspaceId, + }); + assert.equal(openResourceResult, true, "OCR sidecar resource tab should open"); + await page.locator('[data-mnote-resource-tab-panel][data-resource-kind="markdown"] [data-testid="mnote-leptos-tiptap-island-editor-root"]').first().waitFor({ + state: "visible", + timeout: UI_TIMEOUT_MS, + }); + screenshots.ocrResource = path.join(OUTPUT_DIR, "02-ocr-resource-tab.png"); + await page.screenshot({ path: screenshots.ocrResource, fullPage: true }); + + await writeResult({ + ok: true, + task: TASK, + root, + documentId, + ocrRootRelativePath: result.ocrRootRelativePath, + screenshots, + }); + console.log(JSON.stringify({ + ok: true, + task: TASK, + root, + documentId, + ocrRootRelativePath: result.ocrRootRelativePath, + screenshots, + }, null, 2)); + } catch (error) { + screenshots.failure = path.join(OUTPUT_DIR, "failure.png"); + await page.screenshot({ path: screenshots.failure, fullPage: true }).catch(() => undefined); + await writeResult({ + ok: false, + task: TASK, + error: error instanceof Error ? error.message : String(error), + root, + documentId, + screenshots, + }); + throw error; + } finally { + await browser.close(); + } +} + +main().catch((error) => { + console.error(error instanceof Error ? error.stack || error.message : String(error)); + process.exit(1); +}); diff --git a/skills/mnote-mindmap/SKILL.md b/skills/mnote-mindmap/SKILL.md new file mode 100644 index 00000000..67d86a3e --- /dev/null +++ b/skills/mnote-mindmap/SKILL.md @@ -0,0 +1,47 @@ +# MNote mindmap editing + +Use this skill only when the user asks to read, summarize, update, or create an MNote mindmap resource. + +Typical triggers: +- The user mentions 思维导图, 脑图, mindmap, KMind, or `.mindmap.json`. +- The current Page AI target is a mindmap resource tab. +- The current page contains a mindmap embed and the task is about that embed. +- The user asks to turn a PDF, Office document, Markdown page, or pasted material into a mindmap. + +Rules: +- First call `mnote.context.snapshot` or `mnote.context.resolve_target` when target metadata is needed. +- Prefer the current mindmap resource tab over page embeds when both are present. +- For existing mindmaps, call `mnote.mindmap.fetch` before proposing or applying changes. +- For new mindmaps from PDF or document summaries, convert the source material into a concise hierarchical outline, then call `mnote.mindmap.create_from_outline`. +- Do not write a naked simple-mind-map tree as the final file. MNote mindmap files use an envelope with `data` as the root tree and `view` as runtime view state. +- Keep the root node uid as `root` for new maps unless MNote returns a different root. +- Let MNote generate child node uid values; do not invent duplicate ids. +- Before writing, confirm the run has `read_write` permission and the target resource is inside `allowedResourceIds`. +- After writing or creating a mindmap, read it back with `mnote.mindmap.fetch` and report the changed `.mindmap.json` path. +- If authorization is missing, ask the user to grant access instead of guessing a path. + +Current apply_ops contract: +- Supported operations are `updateText` / `updateNode`, `insertChild` / `addChild`, and `deleteNode`. +- `updateText` / `updateNode` require `nodeId` (or `node_id` / `id`) and `text` (or `title`). +- `insertChild` / `addChild` require `parentId` (or `parent_id` / `nodeId`) and a child node payload. +- `deleteNode` requires `nodeId` (or `node_id` / `id`) and must never target the root node. +- Unknown operations are rejected; do not assume extra edit verbs exist. +- Prefer small, reviewable edits. Keep node text concise and split long prose into child nodes. +- Long text should be summarized into short phrases or child nodes rather than embedded as a single paragraph. +- Respect `dryRun` and revision checks when the caller provides them. + +Mindmap outline format: +- Use one central root topic as the `title`; it should name the subject, not explain it in a paragraph. +- Use first-level children for the major categories or sections radiating from the root. +- Use concise keywords or short phrases for node text. Avoid long paragraphs, full prose summaries, and multiple sentences inside one node. +- Put one idea in each node. Split causes, decisions, examples, and evidence into child nodes instead of joining them with punctuation. +- Keep each level scannable: prefer 3-8 sibling branches unless the source structure requires more. +- Preserve hierarchy with `children`; do not simulate structure by embedding Markdown lists or newline-separated text in a node. +- Keep citations, page numbers, and source metadata in `sourceRefs` or nearby metadata when possible, rather than cramming them into visible node text. + +PDF or document to mindmap workflow: +1. Identify the source resource and target page. +2. Extract or receive a title plus outline from the source material. +3. Keep the outline small enough to be useful: preserve chapters, decisions, key concepts, and relationships; remove repeated prose. +4. Call `mnote.mindmap.create_from_outline` with `title`, `outline`, `sourceRefs`, and the target resource path when provided. +5. Verify the created resource by fetching it and checking the root title and first-level branches. diff --git a/skills/mnote-onlyoffice-live/SKILL.md b/skills/mnote-onlyoffice-live/SKILL.md new file mode 100644 index 00000000..2ecddc19 --- /dev/null +++ b/skills/mnote-onlyoffice-live/SKILL.md @@ -0,0 +1,68 @@ +# MNote ONLYOFFICE live bridge + +用于操作当前已经打开的 ONLYOFFICE 编辑器会话。 + +## 适用范围 + +- 仅针对当前浏览器里打开的 ONLYOFFICE 文档 +- 支持 Word、Excel、PPT 的基础读写 +- 不用于离线批量修改文件 + +## 可用工具 + +- `mnote.onlyoffice.session.current` +- `mnote.onlyoffice.capabilities` +- `mnote.onlyoffice.selection.get` +- `mnote.onlyoffice.document.insert_text` +- `mnote.onlyoffice.document.replace_selection` +- `mnote.onlyoffice.document.insert_html` +- `mnote.onlyoffice.document.export` +- `mnote.onlyoffice.document.search_replace` +- `mnote.onlyoffice.document.insert_table` +- `mnote.onlyoffice.document.get_comments` +- `mnote.onlyoffice.document.add_comment` +- `mnote.onlyoffice.sheet.get_sheets` +- `mnote.onlyoffice.sheet.add_sheet` +- `mnote.onlyoffice.sheet.rename_sheet` +- `mnote.onlyoffice.sheet.get_range` +- `mnote.onlyoffice.sheet.get_range_values` +- `mnote.onlyoffice.sheet.get_values` +- `mnote.onlyoffice.sheet.set_value` +- `mnote.onlyoffice.sheet.set_formula` +- `mnote.onlyoffice.sheet.batch_set_values` +- `mnote.onlyoffice.sheet.set_range_values` +- `mnote.onlyoffice.sheet.format_range` +- `mnote.onlyoffice.sheet.set_dimensions` +- `mnote.onlyoffice.sheet.sort_range` +- `mnote.onlyoffice.sheet.add_chart` +- `mnote.onlyoffice.presentation.get_slides` +- `mnote.onlyoffice.presentation.get_slide_texts` +- `mnote.onlyoffice.presentation.get_shapes` +- `mnote.onlyoffice.presentation.add_text_slide` +- `mnote.onlyoffice.presentation.replace_text` +- `mnote.onlyoffice.presentation.set_shape_text` +- `mnote.onlyoffice.presentation.delete_slide` +- `mnote.onlyoffice.presentation.add_table` +- `mnote.onlyoffice.presentation.clear_slide` +- `mnote.onlyoffice.presentation.add_shape` + +## 使用原则 + +- 先调用 `mnote.onlyoffice.session.current` 确认当前会话存在,并记录 `sessionId` / `documentId` / `assetId` / `fileType` +- 多个 ONLYOFFICE 标签页同时打开时,写操作必须显式传 `onlyofficeSessionId` +- 写入前优先做最小范围修改,并先用 `dryRun` 检查计划 +- 读取大块表格时优先使用 `sheet.get_values`,写入多格时优先使用 `sheet.batch_set_values` +- 需要按用户可见坐标定位表格时优先使用 A1 地址工具:`sheet.get_range_values` / `sheet.set_range_values` +- `sheet.set_range_values` 只写入 A1 区域与二维 `values` 的交集,调用前应确认尺寸 +- 表格样式只做显式小范围:`sheet.format_range` 支持字体粗斜体、颜色、对齐和数字格式;`sheet.set_dimensions` 支持零基行高/列宽 +- Excel 排序使用 `sheet.sort_range`,先确认 A1 range,`keyColumn` 是 range 内从 1 开始的列号;图表使用 `sheet.add_chart`,默认柱状图 +- `document.export` 仅支持 `markdown` 和 `html` +- Word 精确文本替换优先使用 `document.search_replace` +- Word 插入结构化表格使用 `document.insert_table`;评论读取/添加使用 `document.get_comments` / `document.add_comment` +- `document.add_comment` 默认给当前选区加评论;没有可靠选区时显式传 `target: "document_start"` +- PPT 文本读取优先使用 `presentation.get_slide_texts`;`presentation.replace_text` 只处理文本框纯文本,命中文本框会按纯文本段落重建 +- PPT 精确改某个文本框时先调用 `presentation.get_shapes` 获取 `shapeIndex` / `shapeId`,再调用 `presentation.set_shape_text` +- 删除 PPT 幻灯片前必须先调用 `presentation.get_slides` 或 `presentation.get_slide_texts` 确认 `slideIndex` +- PPT 插入结构化表格使用 `presentation.add_table`,默认居中插入;需要精确位置时传 `xMm` / `yMm` / `widthMm` / `heightMm` +- PPT 清空指定页对象使用 `presentation.clear_slide`,调用前必须确认目标 `slideIndex`;添加基础图形使用 `presentation.add_shape` +- 需要大范围离线处理时,改用 `officecli`

    ^|Nie*-vulF+v4wk>+IA2>mS+KQ^Hzh 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 k`NV1V(7B!kUXS8< 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 literal 2094263 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∨kex8S&G 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