dsh-tiddlywiki 0.22.4 → 0.22.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +5 -1
- package/cordis.patch.yml +13 -13
- package/lib/client.js +1 -1
- package/lib/index.js +249 -31
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client/markdown-editor.ts +128 -128
- package/src/client/settings-page.ts +4 -0
- package/src/client/state.ts +39 -39
- package/src/client/theme-sync.ts +327 -327
- package/src/client/toast.ts +22 -22
- package/src/host/config.ts +9 -0
- package/src/host/ready-policy.ts +108 -0
- package/src/host/wiki.ts +164 -35
- package/src/index.ts +35 -2
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 dsh-tiddlywiki contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-tiddlywiki contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -193,6 +193,8 @@ seed 是把「wiki 里预置内容」随插件分发的机制:**ONE-SHOT(只
|
|
|
193
193
|
branch: "main"
|
|
194
194
|
note:
|
|
195
195
|
tag: "inbox" # 快速笔记默认 tag
|
|
196
|
+
startup:
|
|
197
|
+
readyTimeoutMs: 60000 # TW 启动就绪窗口(v0.22.5,5s–600s;超出只警告并继续等,硬上限 = 3×,仍未就绪才判失败)
|
|
196
198
|
prompt:
|
|
197
199
|
enabled: true # false = 本插件不注入任何提示词
|
|
198
200
|
mode: "slim" # slim(默认:只留约定)/ full(+ 由工具注册表实时生成的参数索引)
|
|
@@ -222,7 +224,7 @@ seed 是把「wiki 里预置内容」随插件分发的机制:**ONE-SHOT(只
|
|
|
222
224
|
password: "" # 非空时插件内置客户端/就绪探测/浏览器代理都带 Basic 认证(v0.18.0 起真正可用)
|
|
223
225
|
```
|
|
224
226
|
|
|
225
|
-
> **运行时配置**:设置页写入的 `$:/plugins/dsh-tiddlywiki/config` tiddler 是 `config:` 块之上的覆盖层(tiddler 优先、随 wiki git 同步),改 note tag / git / ui 开关 / **注入提示词(`prompt.*`)** 都无需动 cordis;**提示词改动保存后立即生效**(section 即时重注册,当前会话下一步生效),剪藏桥端口改动仍需重启 dsh web
|
|
227
|
+
> **运行时配置**:设置页写入的 `$:/plugins/dsh-tiddlywiki/config` tiddler 是 `config:` 块之上的覆盖层(tiddler 优先、随 wiki git 同步),改 note tag / git / ui 开关 / **注入提示词(`prompt.*`)** 都无需动 cordis;**提示词改动保存后立即生效**(section 即时重注册,当前会话下一步生效),剪藏桥端口改动仍需重启 dsh web 重新绑定监听;**`startup.readyTimeoutMs` 对下一次 TW 启动/重启生效**(v0.22.5)。
|
|
226
228
|
>
|
|
227
229
|
> **知识库位置是三层**(v0.22.0):指针文件 `$DSH_HOME/dsh-tiddlywiki/location.json` > `config:` 块的 `wikiRoot`/`wiki` > 内置默认(`$DSH_HOME/tiddlywiki` + `main`)。`wikiRoot`/`wiki` 因此是「默认位置」而不是「唯一位置」——设置页切过的位置存在指针文件里(一个在 wiki 之外的文件),所以要换回配置值就点「恢复为配置默认」。
|
|
228
230
|
|
|
@@ -343,6 +345,8 @@ lib/ # 预构建产物(发布含 lib/**,提交入库;
|
|
|
343
345
|
|
|
344
346
|
> 最近几个主要版本的一句话记录(完整变更见 [Releases](https://github.com/bbqisbbq/dsh-tiddlywiki/releases) / git log)。
|
|
345
347
|
|
|
348
|
+
- **v0.22.5**(2026-09-14):**修「大知识库冷启动被误判为启动失败」**(用户实测报障:dsh 启动时 `[dsh-tiddlywiki] startup issue (self-healing is armed): Error: wiki server did not become ready in time`)。根因不是 TW 没起来,而是**就绪判定太急 + 判失败后再也没人复探**。证据来自 `/status` 的环形日志:`01:43:51 spawn … tiddlywiki.js … --listen` → `01:44:11 wiki server did not become ready in time` → `01:44:35 [out] Processing background action …` + `[out] Serving on http://127.0.0.1:52323`。也就是说这个 5099 个 tiddler / 26MB 的知识库在**冷文件缓存**下真的需要约 44 秒才打印 `Serving on`,而旧代码只有**一个 20 秒硬超时**,于是:① 抛错中断整条启动管线——配置 tiddler 没加载、核心 seed(发送给 Agent / 渲染路由 / 同源代理 / markdown 插件)没写、剪藏桥没起,全都会拖到下一次重启;② 写死 `health='failed'` + 一条粘性 error,而**超时后没有任何东西会再探测**,所以 TW 明明在正常服务,`/status`(面板 / FAB / 悬浮提示)却一直报故障。现在把「就绪」变成一条明确的三段策略(新的 `src/host/ready-policy.ts`,纯函数 + 注入时钟,可单测):**软窗口**(默认 60s,可用 `startup.readyTimeoutMs` 在设置页调,夹在 5s–600s)之内安静等待;超过它只写一条 `slow start: /status not ready after Ns — still loading` 并**继续等**(状态保持 `starting`,不再粘住 error);**硬上限 = 3× 软窗口**仍无响应才判失败——并且失败时**不杀子进程**,而是挂一个**有界(10 分钟)、`unref` 的「迟到就绪」后台探测**,TW 真起来的那一刻立刻把状态改回 `running` 并清掉那条旧错误(`ready (late): /status 200`),`stop()` 与新一次 `start()` 都会取消它。`startup.readyTimeoutMs` 走「cordis 配置 < 配置 tiddler」双层,设置页保存后对**下一次启动/重启**生效,无需重启 dsh web。守门:新增 `scripts/verify-ready-policy.mjs`(进 `verify:unit`,tsx 直跑源码 + 虚拟时钟)——归一化/夹取、**44s 冷启动必须判成功**(本次事故形状的回归断言)、慢启动只警告一次、子进程退出 → 立即 `exited`、始终不就绪 → 到硬上限才 `timeout`、轮询节奏有界(慢窗口降到 2s,不空转),外加源码级接线断言(`wiki.ts` 不得再出现 20s 硬编码、必须有 `awaitReady` / `armLateReadyWatch` / `clearLateReadyWatch`,config/index/client 三处链路都在);`verify-resilience.mjs` 增加一条真实 TW 的重启断言(窗口热改 + 夹取 + 仍判就绪)。
|
|
349
|
+
|
|
346
350
|
- **v0.22.4**(2026-09-13):**重构:把 TW frame 的生命周期收敛成唯一一份实现**(无功能变更,纯去重)。v0.22.3 那个「空 `src` 把 DSH 载进 iframe」的 P0 之所以发生,根因不是谁写错了某个判断,而是 `panel.ts`(中央列面板)与 `tw-frame.ts`(右侧栏 tab)**各自抄了一份** `showError` / `showStarting` / `showFrame` / `applyPendingHash` / `fallbackLoad` / `doRefresh`——修 bug 时守卫只补到 panel,tw-frame 那份照旧,同一个坑于是踩了两次(`panel.ts` 靠「`!hidden` ⇒ 已载入真实 twProxy」这个不成文不变量侥幸安全,tw-frame 连这个都没有)。现在这六个函数只在 `tw-frame.ts` 新增的 **`createTwFrameSurface(skin)`** 里各有一份,`createTwFrameController()` 退化成它的 rightbar 薄包装;一个 surface 只提供三样东西:**皮肤**(类名 + 可选内联样式)、**惰性构建点**(`build()` 返回 view,由调用方决定挂到哪里)、**可见性**(`setVisible()`)。`panel.ts` 因此从 469 行降到 280 行,只剩 rect 钉住 / 惰性构建 / 共存 chrome / 面板互斥。顺带三处行为改进(都是去重后的自然结果):① 面板打开链接改为**先 `state.openPanel()` 再 `surface.openTiddler()`**(内核以 `visible=false` 拒绝隐藏 surface,顺序反了链接会静默丢失,脚本里有守门断言);② `setVisible(false)` 现在会**隐藏 frame 并停掉有界轮询**(下次显示重新给满预算);FAB「重载面板」刻意**不受可见性限制**(唯一判据是 `dataset.loaded`)——显式重载请求要能覆盖**关掉的**面板,否则「关掉面板 → 点重载 → 再打开」会看到旧资源,而展示陈旧内容比多一次重载更糟;③ 内核的 `build()` 会记住「DOM 还没建就被要求显示」的情况并在建好后补一次 `/status` —— 此前中心列若在面板挂载之后才出现,面板会停在空壳上直到用户再切一次。守门:`verify-frame-guards.mjs` 加了**计数去重断言**(panel 里出现任何一个生命周期函数就直接判红,反向验证过:植入回来必失败),并新增 **`scripts/verify-frame-surface.mjs`** —— 用 tsx 直跑源码 + 最小 DOM 打桩,真正执行 `createTwFrameSurface()` 跑 16 条行为断言(空 `src` 的两条重载路径、只显示真的载入过 TW 的 frame、同一 URL 不重复赋 `src`、启动/错误/重试恢复、同源 hash 导航与跨源兜底、共享 chip 标签、dispose 摘监听且幂等),已进 `verify:unit`。测试环境提示:本机沙箱里 node 再 spawn 孙进程会崩,`npm run` 偶发段错误,`verify-package-contents` 与 `verify-git-resolve` 的失败属环境问题(手动复核过断言全过),与本版无关。
|
|
347
351
|
|
|
348
352
|
- **v0.22.3**(2026-09-12):**第五轮代码审计的客户端修复版**(host 侧零缺陷:CSRF 门禁 / 片段净化 / SSRF 守卫 / 密钥打码 / 写策略 type 保留 / 乐观并发 / git 互斥 / seed 内容哈希 / 切换回滚逐条对照都成立;`tsc` 与 8 个 `verify-*` 全绿)。① **P0:iframe 空 `src` 被当成合法地址使用**。`tw-frame.ts` 的 FAB「重载面板」处理是 `frame.src = frame.src`、hash 兜底加载是 `frame.src.split('#')[0]` 拼 hash——而 `iframe` 从未赋过 `src` 时,**读 `iframe.src` 得到的是宿主 DSH 页面自己的 URL**。`setVisible(true)` 会在首个 `/status` 回来之前就取消 `hidden`(切走再切回即可命中),于是这两种写法会把 **DSH 页面载进 iframe**:iframe 里再起一份 DSH(重复 FAB、重复全局监听、白屏)。现在两处「整页重载」路径都只认 `dataset.loaded`(只有 `showFrame` 写它)并抽出共享的 `loadableFrameUrl()`,`panel.ts` 原本靠「`!hidden` ⇒ 已载入真实 twProxy」这个不成文不变量侥幸安全,现也改成显式判据。② **P1:主题「活动」单选预选错误,且会影响写入**。`/admin/state` 只回 `info.themes`(**已加载**集合),设置页就拿它的**最后一项**冒充「活动主题」;用户显式激活过非末位主题时,打开设置页显示错误选中项、**不动任何单选直接点「应用主题」也会静默把活动主题改回末位那个**。现在 host 读 `$:/theme` 并在 `/admin/state` 回 `info.themeActive`(去掉 `$:/themes/` 前缀归一),设置页优先用它、猜末位只作兜底,并且只在 catalog 里存在时才认。③ **P1:`applyToFrame` 缺 try/catch**。`setThemeSyncConfig()` 是**同步**遍历调用各 frame 的 applier 的(`doRefresh`/`load` 都在 await 链里),而 `frame.contentWindow.$tw` 这次属性访问在 iframe 导航到跨源页面(TW 里点外链)时**自身**就抛 `SecurityError`(内层各助手的 try/catch 还没轮到),异常直接变成未处理 rejection 并中断那次刷新;现在整段包住。④ **P2 清理**:会话汇总的挂载 effect 补 `mountedRef` 卸载守卫(`genRef` 只认「被更新取代」、覆盖不到卸载,在途请求 resolve 后仍会 setState 并递归再发一轮)、快速笔记按钮的 `fetchUiConfig().then(setMode)` 补 alive 守卫、`note-widget` 卸载不再删除**设置页也在用**的页面级 toast 单例(原来会掐掉别人正在显示的提示);删掉三处无人消费的死标记/死字段(`view.dataset.visible`、`data-dsh-tw-rightbar`、`BuiltUi.recentBtn`、`ConfigField.input`),工具卡标签 key 补下标(同标签重复会撞 key),并把 `panel.ts` 里重复的 `requestRestart` 收敛为复用 `tw-frame.ts` 的那一份。守门:新增 `scripts/verify-frame-guards.mjs`(已进 `verify:unit`)——空 src 陷阱、活动主题优先级、跨源 try/catch、共享 toast、死标记共 13 条断言,其中 `readActiveThemeName()` 走真实函数(前缀 / 裸名 / 缺失 / 读失败),静态断言会剥掉注释行以免匹配到自己的说明文字。
|
package/cordis.patch.yml
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# dsh-tiddlywiki bundle patch: inserts the plugin row into the web profile
|
|
2
|
-
# roster. Applied as a profile bundle layer (the `dsh.bundle.patch` manifest
|
|
3
|
-
# field) over dsh-base; activate with
|
|
4
|
-
# `dsh plugin --profile web add link:<path-to-this-package>` and restart dsh web.
|
|
5
|
-
#
|
|
6
|
-
# The row is a bare plugin by package name: the node half (exports ".") runs
|
|
7
|
-
# in the host process (WikiServer, routes, tiddlywiki_* tools, prompt section,
|
|
8
|
-
# auto-commit), and the `dsh.client` declaration in package.json makes the
|
|
9
|
-
# browser half (exports "./client", served at /plugins/dsh-tiddlywiki/client.js)
|
|
10
|
-
# load in the web GUI.
|
|
11
|
-
- insert:
|
|
12
|
-
- id: dsh-tiddlywiki
|
|
13
|
-
name: dsh-tiddlywiki
|
|
1
|
+
# dsh-tiddlywiki bundle patch: inserts the plugin row into the web profile
|
|
2
|
+
# roster. Applied as a profile bundle layer (the `dsh.bundle.patch` manifest
|
|
3
|
+
# field) over dsh-base; activate with
|
|
4
|
+
# `dsh plugin --profile web add link:<path-to-this-package>` and restart dsh web.
|
|
5
|
+
#
|
|
6
|
+
# The row is a bare plugin by package name: the node half (exports ".") runs
|
|
7
|
+
# in the host process (WikiServer, routes, tiddlywiki_* tools, prompt section,
|
|
8
|
+
# auto-commit), and the `dsh.client` declaration in package.json makes the
|
|
9
|
+
# browser half (exports "./client", served at /plugins/dsh-tiddlywiki/client.js)
|
|
10
|
+
# load in the web GUI.
|
|
11
|
+
- insert:
|
|
12
|
+
- id: dsh-tiddlywiki
|
|
13
|
+
name: dsh-tiddlywiki
|
package/lib/client.js
CHANGED
|
@@ -739,7 +739,7 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
739
739
|
}`,{label:`enum`,detail:`definition`,type:`keyword`})]),Sh=new kl,Ch=new Set([`Script`,`Block`,`FunctionExpression`,`FunctionDeclaration`,`ArrowFunction`,`MethodDeclaration`,`ForStatement`]);function wh(e){return(t,n)=>{let r=t.node.getChild(`VariableDefinition`);return r&&n(r,e),!0}}const Th=[`FunctionDeclaration`],Eh={FunctionDeclaration:wh(`function`),ClassDeclaration:wh(`class`),ClassExpression:()=>!0,EnumDeclaration:wh(`constant`),TypeAliasDeclaration:wh(`type`),NamespaceDeclaration:wh(`namespace`),VariableDefinition(e,t){e.matchContext(Th)||t(e,`variable`)},TypeDefinition(e,t){t(e,`type`)},__proto__:null};function Dh(e,t){let n=Sh.get(t);if(n)return n;let r=[],i=!0;function a(t,n){let i=e.sliceString(t.from,t.to);r.push({label:i,type:n})}return t.cursor(W.IncludeAnonymous).iterate(t=>{if(i)i=!1;else if(t.name){let e=Eh[t.name];if(e&&e(t,a)||Ch.has(t.name))return!1}else if(t.to-t.from>8192){for(let n of Dh(e,t.node))r.push(n);return!1}}),Sh.set(t,r),r}const Oh=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,kh=[`TemplateString`,`String`,`RegExp`,`LineComment`,`BlockComment`,`VariableDefinition`,`TypeDefinition`,`Label`,`PropertyDefinition`,`PropertyName`,`PrivatePropertyDefinition`,`PrivatePropertyName`,`JSXText`,`JSXAttributeValue`,`JSXOpenTag`,`JSXCloseTag`,`JSXSelfClosingTag`,`.`,`?.`];function Ah(e){let t=J(e.state).resolveInner(e.pos,-1);if(kh.indexOf(t.name)>-1)return null;let n=t.name==`VariableName`||t.to-t.from<20&&Oh.test(e.state.sliceDoc(t.from,t.to));if(!n&&!e.explicit)return null;let r=[];for(let n=t;n;n=n.parent)Ch.has(n.name)&&(r=r.concat(Dh(e.state.doc,n)));return{options:r,from:n?t.from:e.pos,validFor:Oh}}const jh=Eu.define({name:`javascript`,parser:yh.configure({props:[Wu.add({IfStatement:nd({except:/^\s*({|else\b)/}),TryStatement:nd({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:td,SwitchBody:e=>{let t=e.textAfter,n=/^\s*\}/.test(t),r=/^\s*(case|default)\b/.test(t);return e.baseIndent+(n?0:r?1:2)*e.unit},Block:$u({closing:`}`}),ArrowFunction:e=>e.baseIndent+e.unit,"TemplateString BlockComment":()=>null,"Statement Property":nd({except:/^\s*{/}),JSXElement(e){let t=/^\s*<\//.test(e.textAfter);return e.lineIndent(e.node.from)+(t?0:e.unit)},JSXEscape(e){let t=/\s*\}/.test(e.textAfter);return e.lineIndent(e.node.from)+(t?0:e.unit)},"JSXOpenTag JSXSelfClosingTag"(e){return e.column(e.node.from)+e.unit}}),id.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":ad,BlockComment(e){return{from:e.from+2,to:e.to-2}},JSXElement(e){let t=e.firstChild;if(!t||t.name==`JSXSelfClosingTag`)return null;let n=e.lastChild;return{from:t.to,to:n.type.isError?e.to:n.from}},"JSXSelfClosingTag JSXOpenTag"(e){let t=e.firstChild?.nextSibling,n=e.lastChild;return!t||t.type.isError?null:{from:t.to,to:n.type.isError?e.to:n.from}}})]}),languageData:{closeBrackets:{brackets:[`(`,`[`,`{`,`'`,`"`,"`"]},commentTokens:{line:`//`,block:{open:`/*`,close:`*/`}},indentOnInput:/^\s*(?:case |default:|\{|\}|<\/)$/,wordChars:`$`}}),Mh={test:e=>/^JSX/.test(e.name),facet:Su({commentTokens:{block:{open:`{/*`,close:`*/}`}}})},Nh=jh.configure({dialect:`ts`},`typescript`),Ph=jh.configure({dialect:`jsx`,props:[Cu.add(e=>e.isTop?[Mh]:void 0)]}),Fh=jh.configure({dialect:`jsx ts`,props:[Cu.add(e=>e.isTop?[Mh]:void 0)]},`typescript`);let Ih=e=>({label:e,type:`keyword`});const Lh=`break case const continue default delete export extends false finally in instanceof let new return static super switch this throw true typeof var yield`.split(` `).map(Ih),Rh=Lh.concat([`declare`,`implements`,`private`,`protected`,`public`].map(Ih));function zh(e={}){let t=e.jsx?e.typescript?Fh:Ph:e.typescript?Nh:jh,n=e.typescript?xh.concat(Rh):bh.concat(Lh);return new Iu(t,[jh.data.of({autocomplete:Ad(kh,kd(n))}),jh.data.of({autocomplete:Ah}),e.jsx?Uh:[]])}function Bh(e){for(;;){if(e.name==`JSXOpenTag`||e.name==`JSXSelfClosingTag`||e.name==`JSXFragmentTag`)return e;if(e.name==`JSXEscape`||!e.parent)return null;e=e.parent}}function Vh(e,t,n=e.length){for(let r=t?.firstChild;r;r=r.nextSibling)if(r.name==`JSXIdentifier`||r.name==`JSXBuiltin`||r.name==`JSXNamespacedName`||r.name==`JSXMemberExpression`)return e.sliceString(r.from,Math.min(r.to,n));return``}const Hh=typeof navigator==`object`&&/Android\b/.test(navigator.userAgent),Uh=V.inputHandler.of((e,t,n,r,i)=>{if((Hh?e.composing:e.compositionStarted)||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!jh.isActiveAt(e.state,t,-1))return!1;let a=i(),{state:o}=a,s=o.changeByRange(e=>{let{head:t}=e,n=J(o).resolveInner(t-1,-1),i;if(n.name==`JSXStartTag`&&(n=n.parent),!(o.doc.sliceString(t-1,t)!=r||n.name==`JSXAttributeValue`&&n.to>t)){if(r==`>`&&n.name==`JSXFragmentTag`)return{range:e,changes:{from:t,insert:`</>`}};if(r==`/`&&n.name==`JSXStartCloseTag`){let e=n.parent,r=e.parent;if(r&&e.from==t-2&&((i=Vh(o.doc,r.firstChild,t))||r.firstChild?.name==`JSXFragmentTag`)){let e=`${i}>`;return{range:A.cursor(t+e.length,-1),changes:{from:t,insert:e}}}}else if(r==`>`){let r=Bh(n);if(r&&r.name==`JSXOpenTag`&&!/^\/?>|^<\//.test(o.doc.sliceString(t,t+2))&&(i=Vh(o.doc,r,t)))return{range:e,changes:{from:t,insert:`</${i}>`}}}}return{range:e}});return s.changes.empty?!1:(e.dispatch([a,o.update(s,{userEvent:`input.complete`,scrollIntoView:!0})]),!0)}),Wh=[`_blank`,`_self`,`_top`,`_parent`],Gh=[`ascii`,`utf-8`,`utf-16`,`latin1`,`latin1`],Kh=[`get`,`post`,`put`,`delete`],qh=[`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`],Jh=[`true`,`false`],Z={},Yh={a:{attrs:{href:null,ping:null,type:null,media:null,target:Wh,hreflang:null}},abbr:Z,address:Z,area:{attrs:{alt:null,coords:null,href:null,target:null,ping:null,media:null,hreflang:null,type:null,shape:[`default`,`rect`,`circle`,`poly`]}},article:Z,aside:Z,audio:{attrs:{src:null,mediagroup:null,crossorigin:[`anonymous`,`use-credentials`],preload:[`none`,`metadata`,`auto`],autoplay:[`autoplay`],loop:[`loop`],controls:[`controls`]}},b:Z,base:{attrs:{href:null,target:Wh}},bdi:Z,bdo:Z,blockquote:{attrs:{cite:null}},body:Z,br:Z,button:{attrs:{form:null,formaction:null,name:null,value:null,autofocus:[`autofocus`],disabled:[`autofocus`],formenctype:qh,formmethod:Kh,formnovalidate:[`novalidate`],formtarget:Wh,type:[`submit`,`reset`,`button`]}},canvas:{attrs:{width:null,height:null}},caption:Z,center:Z,cite:Z,code:Z,col:{attrs:{span:null}},colgroup:{attrs:{span:null}},command:{attrs:{type:[`command`,`checkbox`,`radio`],label:null,icon:null,radiogroup:null,command:null,title:null,disabled:[`disabled`],checked:[`checked`]}},data:{attrs:{value:null}},datagrid:{attrs:{disabled:[`disabled`],multiple:[`multiple`]}},datalist:{attrs:{data:null}},dd:Z,del:{attrs:{cite:null,datetime:null}},details:{attrs:{open:[`open`]}},dfn:Z,div:Z,dl:Z,dt:Z,em:Z,embed:{attrs:{src:null,type:null,width:null,height:null}},eventsource:{attrs:{src:null}},fieldset:{attrs:{disabled:[`disabled`],form:null,name:null}},figcaption:Z,figure:Z,footer:Z,form:{attrs:{action:null,name:null,"accept-charset":Gh,autocomplete:[`on`,`off`],enctype:qh,method:Kh,novalidate:[`novalidate`],target:Wh}},h1:Z,h2:Z,h3:Z,h4:Z,h5:Z,h6:Z,head:{children:[`title`,`base`,`link`,`style`,`meta`,`script`,`noscript`,`command`]},header:Z,hgroup:Z,hr:Z,html:{attrs:{manifest:null}},i:Z,iframe:{attrs:{src:null,srcdoc:null,name:null,width:null,height:null,sandbox:[`allow-top-navigation`,`allow-same-origin`,`allow-forms`,`allow-scripts`],seamless:[`seamless`]}},img:{attrs:{alt:null,src:null,ismap:null,usemap:null,width:null,height:null,crossorigin:[`anonymous`,`use-credentials`]}},input:{attrs:{alt:null,dirname:null,form:null,formaction:null,height:null,list:null,max:null,maxlength:null,min:null,name:null,pattern:null,placeholder:null,size:null,src:null,step:null,value:null,width:null,accept:[`audio/*`,`video/*`,`image/*`],autocomplete:[`on`,`off`],autofocus:[`autofocus`],checked:[`checked`],disabled:[`disabled`],formenctype:qh,formmethod:Kh,formnovalidate:[`novalidate`],formtarget:Wh,multiple:[`multiple`],readonly:[`readonly`],required:[`required`],type:[`hidden`,`text`,`search`,`tel`,`url`,`email`,`password`,`datetime`,`date`,`month`,`week`,`time`,`datetime-local`,`number`,`range`,`color`,`checkbox`,`radio`,`file`,`submit`,`image`,`reset`,`button`]}},ins:{attrs:{cite:null,datetime:null}},kbd:Z,keygen:{attrs:{challenge:null,form:null,name:null,autofocus:[`autofocus`],disabled:[`disabled`],keytype:[`RSA`]}},label:{attrs:{for:null,form:null}},legend:Z,li:{attrs:{value:null}},link:{attrs:{href:null,type:null,hreflang:null,media:null,sizes:[`all`,`16x16`,`16x16 32x32`,`16x16 32x32 64x64`]}},map:{attrs:{name:null}},mark:Z,menu:{attrs:{label:null,type:[`list`,`context`,`toolbar`]}},meta:{attrs:{content:null,charset:Gh,name:[`viewport`,`application-name`,`author`,`description`,`generator`,`keywords`],"http-equiv":[`content-language`,`content-type`,`default-style`,`refresh`]}},meter:{attrs:{value:null,min:null,low:null,high:null,max:null,optimum:null}},nav:Z,noscript:Z,object:{attrs:{data:null,type:null,name:null,usemap:null,form:null,width:null,height:null,typemustmatch:[`typemustmatch`]}},ol:{attrs:{reversed:[`reversed`],start:null,type:[`1`,`a`,`A`,`i`,`I`]},children:[`li`,`script`,`template`,`ul`,`ol`]},optgroup:{attrs:{disabled:[`disabled`],label:null}},option:{attrs:{disabled:[`disabled`],label:null,selected:[`selected`],value:null}},output:{attrs:{for:null,form:null,name:null}},p:Z,param:{attrs:{name:null,value:null}},pre:Z,progress:{attrs:{value:null,max:null}},q:{attrs:{cite:null}},rp:Z,rt:Z,ruby:Z,samp:Z,script:{attrs:{type:[`text/javascript`],src:null,async:[`async`],defer:[`defer`],charset:Gh}},section:Z,select:{attrs:{form:null,name:null,size:null,autofocus:[`autofocus`],disabled:[`disabled`],multiple:[`multiple`]}},slot:{attrs:{name:null}},small:Z,source:{attrs:{src:null,type:null,media:null}},span:Z,strong:Z,style:{attrs:{type:[`text/css`],media:null,scoped:null}},sub:Z,summary:Z,sup:Z,table:Z,tbody:Z,td:{attrs:{colspan:null,rowspan:null,headers:null}},template:Z,textarea:{attrs:{dirname:null,form:null,maxlength:null,name:null,placeholder:null,rows:null,cols:null,autofocus:[`autofocus`],disabled:[`disabled`],readonly:[`readonly`],required:[`required`],wrap:[`soft`,`hard`]}},tfoot:Z,th:{attrs:{colspan:null,rowspan:null,headers:null,scope:[`row`,`col`,`rowgroup`,`colgroup`]}},thead:Z,time:{attrs:{datetime:null}},title:Z,tr:Z,track:{attrs:{src:null,label:null,default:null,kind:[`subtitles`,`captions`,`descriptions`,`chapters`,`metadata`],srclang:null}},ul:{children:[`li`,`script`,`template`,`ul`,`ol`]},var:Z,video:{attrs:{src:null,poster:null,width:null,height:null,crossorigin:[`anonymous`,`use-credentials`],preload:[`auto`,`metadata`,`none`],autoplay:[`autoplay`],mediagroup:[`movie`],muted:[`muted`],controls:[`controls`]}},wbr:Z},Xh={accesskey:null,class:null,contenteditable:Jh,contextmenu:null,dir:[`ltr`,`rtl`,`auto`],draggable:[`true`,`false`,`auto`],dropzone:[`copy`,`move`,`link`,`string:`,`file:`],hidden:[`hidden`],id:null,inert:[`inert`],itemid:null,itemprop:null,itemref:null,itemscope:[`itemscope`],itemtype:null,lang:[`ar`,`bn`,`de`,`en-GB`,`en-US`,`es`,`fr`,`hi`,`id`,`ja`,`pa`,`pt`,`ru`,`tr`,`zh`],spellcheck:Jh,autocorrect:Jh,autocapitalize:Jh,style:null,tabindex:null,title:null,translate:[`yes`,`no`],rel:[`stylesheet`,`alternate`,`author`,`bookmark`,`help`,`license`,`next`,`nofollow`,`noreferrer`,`prefetch`,`prev`,`search`,`tag`],role:`alert application article banner button cell checkbox complementary contentinfo dialog document feed figure form grid gridcell heading img list listbox listitem main navigation region row rowgroup search switch tab table tabpanel textbox timer`.split(` `),"aria-activedescendant":null,"aria-atomic":Jh,"aria-autocomplete":[`inline`,`list`,`both`,`none`],"aria-busy":Jh,"aria-checked":[`true`,`false`,`mixed`,`undefined`],"aria-controls":null,"aria-describedby":null,"aria-disabled":Jh,"aria-dropeffect":null,"aria-expanded":[`true`,`false`,`undefined`],"aria-flowto":null,"aria-grabbed":[`true`,`false`,`undefined`],"aria-haspopup":Jh,"aria-hidden":Jh,"aria-invalid":[`true`,`false`,`grammar`,`spelling`],"aria-label":null,"aria-labelledby":null,"aria-level":null,"aria-live":[`off`,`polite`,`assertive`],"aria-multiline":Jh,"aria-multiselectable":Jh,"aria-owns":null,"aria-posinset":null,"aria-pressed":[`true`,`false`,`mixed`,`undefined`],"aria-readonly":Jh,"aria-relevant":null,"aria-required":Jh,"aria-selected":[`true`,`false`,`undefined`],"aria-setsize":null,"aria-sort":[`ascending`,`descending`,`none`,`other`],"aria-valuemax":null,"aria-valuemin":null,"aria-valuenow":null,"aria-valuetext":null},Zh=`beforeunload copy cut dragstart dragover dragleave dragenter dragend drag paste focus blur change click load mousedown mouseenter mouseleave mouseup keydown keyup resize scroll unload`.split(` `).map(e=>`on`+e);for(let e of Zh)Xh[e]=null;var Qh=class{constructor(e,t){this.tags={...Yh,...e},this.globalAttrs={...Xh,...t},this.allTags=Object.keys(this.tags),this.globalAttrNames=Object.keys(this.globalAttrs)}};Qh.default=new Qh;function $h(e,t,n=e.length){if(!t)return``;let r=t.firstChild,i=r&&r.getChild(`TagName`);return i?e.sliceString(i.from,Math.min(i.to,n)):``}function eg(e,t=!1){for(;e;e=e.parent)if(e.name==`Element`)if(t)t=!1;else return e;return null}function tg(e,t,n){return n.tags[$h(e,eg(t))]?.children||n.allTags}function ng(e,t){let n=[];for(let r=eg(t);r&&!r.type.isTop;r=eg(r.parent)){let i=$h(e,r);if(i&&r.lastChild.name==`CloseTag`)break;i&&n.indexOf(i)<0&&(t.name==`EndTag`||t.from>=r.firstChild.to)&&n.push(i)}return n}const rg=/^[:\-\.\w\u00b7-\uffff]*$/;function ig(e,t,n,r,i){let a=/\s*>/.test(e.sliceDoc(i,i+5))?``:`>`,o=eg(n,n.name==`StartTag`||n.name==`TagName`);return{from:r,to:i,options:tg(e.doc,o,t).map(e=>({label:e,type:`type`})).concat(ng(e.doc,n).map((e,t)=>({label:`/`+e,apply:`/`+e+a,type:`type`,boost:99-t}))),validFor:/^\/?[:\-\.\w\u00b7-\uffff]*$/}}function ag(e,t,n,r){let i=/\s*>/.test(e.sliceDoc(r,r+5))?``:`>`;return{from:n,to:r,options:ng(e.doc,t).map((e,t)=>({label:e,apply:e+i,type:`type`,boost:99-t})),validFor:rg}}function og(e,t,n,r){let i=[],a=0;for(let r of tg(e.doc,n,t))i.push({label:`<`+r,type:`type`});for(let t of ng(e.doc,n))i.push({label:`</`+t+`>`,type:`type`,boost:99-a++});return{from:r,to:r,options:i,validFor:/^<\/?[:\-\.\w\u00b7-\uffff]*$/}}function sg(e,t,n,r,i){let a=eg(n),o=a?t.tags[$h(e.doc,a)]:null,s=o&&o.attrs?Object.keys(o.attrs):[];return{from:r,to:i,options:(o&&o.globalAttrs===!1?s:s.length?s.concat(t.globalAttrNames):t.globalAttrNames).map(e=>({label:e,type:`property`})),validFor:rg}}function cg(e,t,n,r,i){let a=n.parent?.getChild(`AttributeName`),o=[],s;if(a){let c=e.sliceDoc(a.from,a.to),l=t.globalAttrs[c];if(!l){let r=eg(n),i=r?t.tags[$h(e.doc,r)]:null;l=i?.attrs&&i.attrs[c]}if(l){let t=e.sliceDoc(r,i).toLowerCase(),n=`"`,a=`"`;/^['"]/.test(t)?(s=t[0]==`"`?/^[^"]*$/:/^[^']*$/,n=``,a=e.sliceDoc(i,i+1)==t[0]?``:t[0],t=t.slice(1),r++):s=/^[^\s<>='"]*$/;for(let e of l)o.push({label:e,apply:n+e+a,type:`constant`})}}return{from:r,to:i,options:o,validFor:s}}function lg(e,t){let{state:n,pos:r}=t,i=J(n).resolveInner(r,-1),a=i.resolve(r);for(let e=r,t;a==i&&(t=i.childBefore(e));){let n=t.lastChild;if(!n||!n.type.isError||n.from<n.to)break;a=i=t,e=n.from}return i.name==`TagName`?i.parent&&/CloseTag$/.test(i.parent.name)?ag(n,i,i.from,r):ig(n,e,i,i.from,r):i.name==`StartTag`||i.name==`IncompleteTag`?ig(n,e,i,r,r):i.name==`StartCloseTag`||i.name==`IncompleteCloseTag`?ag(n,i,r,r):i.name==`OpenTag`||i.name==`SelfClosingTag`||i.name==`AttributeName`?sg(n,e,i,i.name==`AttributeName`?i.from:r,r):i.name==`Is`||i.name==`AttributeValue`||i.name==`UnquotedAttributeValue`?cg(n,e,i,i.name==`Is`?r:i.from,r):t.explicit&&(a.name==`Element`||a.name==`Text`||a.name==`Document`)?og(n,e,i,r):null}function ug(e){return lg(Qh.default,e)}function dg(e){let{extraTags:t,extraGlobalAttributes:n}=e,r=n||t?new Qh(t,n):Qh.default;return e=>lg(r,e)}const fg=jh.parser.configure({top:`SingleExpression`}),pg=[{tag:`script`,attrs:e=>e.type==`text/typescript`||e.lang==`ts`,parser:Nh.parser},{tag:`script`,attrs:e=>e.type==`text/babel`||e.type==`text/jsx`,parser:Ph.parser},{tag:`script`,attrs:e=>e.type==`text/typescript-jsx`,parser:Fh.parser},{tag:`script`,attrs(e){return/^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(e.type)},parser:fg},{tag:`script`,attrs(e){return!e.type||/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(e.type)},parser:jh.parser},{tag:`style`,attrs(e){return(!e.lang||e.lang==`css`)&&(!e.type||/^(text\/)?(x-)?(stylesheet|css)$/i.test(e.type))},parser:ah.parser}],mg=[{name:`style`,parser:ah.parser.configure({top:`Styles`})}].concat(Zh.map(e=>({name:e,parser:jh.parser}))),hg=Eu.define({name:`html`,parser:wm.configure({props:[Wu.add({Element(e){let t=/^(\s*)(<\/)?/.exec(e.textAfter);return e.node.to<=e.pos+t[0].length?e.continue():e.lineIndent(e.node.from)+(t[2]?0:e.unit)},"OpenTag CloseTag SelfClosingTag"(e){return e.column(e.node.from)+e.unit},Document(e){if(e.pos+/\s*/.exec(e.textAfter)[0].length<e.node.to)return e.continue();let t=null,n;for(let n=e.node;;){let e=n.lastChild;if(!e||e.name!=`Element`||e.to!=n.to)break;t=n=e}return t&&!((n=t.lastChild)&&(n.name==`CloseTag`||n.name==`SelfClosingTag`))?e.lineIndent(t.from)+e.unit:null}}),id.add({Element(e){let t=e.firstChild,n=e.lastChild;return!t||t.name!=`OpenTag`?null:{from:t.to,to:n.name==`CloseTag`?n.from:e.to}}}),pd.add({"OpenTag CloseTag":e=>e.getChild(`TagName`)})]}),languageData:{commentTokens:{block:{open:`<!--`,close:`-->`}},indentOnInput:/^\s*<\/\w+\W$/,wordChars:`-_`}}),gg=hg.configure({wrap:Om(pg,mg)});function _g(e={}){let t=``,n;return e.matchClosingTags===!1&&(t=`noMatch`),e.selfClosingTags===!0&&(t=(t?t+` `:``)+`selfClosing`),(e.nestedLanguages&&e.nestedLanguages.length||e.nestedAttributes&&e.nestedAttributes.length)&&(n=Om((e.nestedLanguages||[]).concat(pg),(e.nestedAttributes||[]).concat(mg))),new Iu(n?hg.configure({wrap:n,dialect:t}):t?gg.configure({dialect:t}):gg,[gg.data.of({autocomplete:dg(e)}),e.autoCloseTags===!1?[]:bg,zh().support,oh().support])}const vg=new Set(`area base br col command embed frame hr img input keygen link meta param source track wbr menuitem`.split(` `));function yg(e,t,n){for(;;){if(t.lastChild?.name!=`CloseTag`)return!1;let r=t.parent;if(!r||$h(e,r)!=n)return!0;t=r}}const bg=V.inputHandler.of((e,t,n,r,i)=>{if(e.composing||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!gg.isActiveAt(e.state,t,-1))return!1;let a=i(),{state:o}=a,s=o.changeByRange(e=>{let t=o.doc.sliceString(e.from-1,e.to)==r,{head:n}=e,i=J(o).resolveInner(n,-1),a;if(t&&r==`>`&&i.name==`EndTag`){let t=i.parent;if((a=$h(o.doc,t.parent,n))&&!vg.has(a)&&!yg(o.doc,t.parent,a))return{range:e,changes:{from:n,to:n+ +(o.doc.sliceString(n,n+1)===`>`),insert:`</${a}>`}}}else if(t&&r==`/`&&i.name==`IncompleteCloseTag`){let e=i.parent;if(i.from==n-2&&e.lastChild?.name!=`CloseTag`&&(a=$h(o.doc,e,n))&&!vg.has(a)){let e=n+ +(o.doc.sliceString(n,n+1)===`>`),t=`${a}>`;return{range:A.cursor(n+t.length,-1),changes:{from:n,to:e,insert:t}}}}return{range:e}});return s.changes.empty?!1:(e.dispatch([a,o.update(s,{userEvent:`input.complete`,scrollIntoView:!0})]),!0)}),xg=Su({commentTokens:{block:{open:`<!--`,close:`-->`}}}),Sg=new H,Cg=rp.configure({props:[id.add(e=>!e.is(`Block`)||e.is(`Document`)||wg(e)!=null||Tg(e)?void 0:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})),Sg.add(wg),Wu.add({Document:()=>null}),xu.add({Document:xg})]});function wg(e){let t=/^(?:ATX|Setext)Heading(\d)$/.exec(e.name);return t?+t[1]:void 0}function Tg(e){return e.name==`OrderedList`||e.name==`BulletList`}function Eg(e,t){let n=e;for(;;){let e=n.nextSibling,r;if(!e||(r=wg(e.type))!=null&&r<=t)break;n=e}return n.to}const Dg=rd.of((e,t,n)=>{for(let r=J(e).resolveInner(n,-1);r&&!(r.from<t);r=r.parent){let e=r.type.prop(Sg);if(e==null)continue;let t=Eg(r,e);if(t>n)return{from:n,to:t}}return null});function Og(e){return new wu(xg,e,[],`markdown`)}const kg=Og(Cg),Ag=Og(Cg.configure([Cp,Ep,Tp,Dp,{props:[id.add({Table:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})})]}]));function jg(e,t){return n=>{if(n&&e){let t=null;if(n=/\S*/.exec(n)[0],t=typeof e==`function`?e(n):Lu.matchLanguageName(e,n,!0),t instanceof Lu)return t.support?t.support.language.parser:ku.getSkippingParser(t.load());if(t)return t.parser}return t?t.parser:null}}var Mg=class{constructor(e,t,n,r,i,a,o){this.node=e,this.from=t,this.to=n,this.spaceBefore=r,this.spaceAfter=i,this.type=a,this.item=o}blank(e,t=!0){let n=this.spaceBefore+(this.node.name==`Blockquote`?`>`:``);if(e!=null){for(;n.length<e;)n+=` `;return n}else{for(let e=this.to-this.from-n.length-this.spaceAfter.length;e>0;e--)n+=` `;return n+(t?this.spaceAfter:``)}}marker(e,t){let n=this.node.name==`OrderedList`?String(+Pg(this.item,e)[2]+t):``;return this.spaceBefore+n+this.type+this.spaceAfter}};function Ng(e,t){let n=[],r=[];for(let t=e;t;t=t.parent){if(t.name==`FencedCode`)return r;(t.name==`ListItem`||t.name==`Blockquote`)&&n.push(t)}for(let e=n.length-1;e>=0;e--){let i=n[e],a,o=t.lineAt(i.from),s=i.from-o.from;if(i.name==`Blockquote`&&(a=/^ *>( ?)/.exec(o.text.slice(s))))r.push(new Mg(i,s,s+a[0].length,``,a[1],`>`,null));else if(i.name==`ListItem`&&i.parent.name==`OrderedList`&&(a=/^( *)\d+([.)])( *)/.exec(o.text.slice(s)))){let e=a[3],t=a[0].length;e.length>=4&&(e=e.slice(0,e.length-4),t-=4),r.push(new Mg(i.parent,s,s+t,a[1],e,a[2],i))}else if(i.name==`ListItem`&&i.parent.name==`BulletList`&&(a=/^( *)([-+*])( {1,4}\[[ xX]\])?( +)/.exec(o.text.slice(s)))){let e=a[4],t=a[0].length;e.length>4&&(e=e.slice(0,e.length-4),t-=4);let n=a[2];a[3]&&(n+=a[3].replace(/[xX]/,` `)),r.push(new Mg(i.parent,s,s+t,a[1],e,n,i))}}return r}function Pg(e,t){return/^(\s*)(\d+)(?=[.)])/.exec(t.sliceString(e.from,e.from+10))}function Fg(e,t,n,r=0){for(let i=-1,a=e;;){if(a.name==`ListItem`){let e=Pg(a,t),o=+e[2];if(i>=0){if(o!=i+1)return;n.push({from:a.from+e[1].length,to:a.from+e[0].length,insert:String(i+2+r)})}i=o}let e=a.nextSibling;if(!e)break;a=e}}function Ig(e,t){let n=/^[ \t]*/.exec(e)[0].length;if(!n||t.facet(zu)!=` `)return e;let r=gr(e,4,n),i=``;for(let e=r;e>0;)e>=4?(i+=` `,e-=4):(i+=` `,e--);return i+e.slice(n)}const Lg=((e={})=>({state:t,dispatch:n})=>{let r=J(t),{doc:i}=t,a=null,o=t.changeByRange(n=>{if(!n.empty||!Ag.isActiveAt(t,n.from,-1)&&!Ag.isActiveAt(t,n.from,1))return a={range:n};let o=n.from,s=i.lineAt(o),c=Ng(r.resolveInner(o,-1),i);for(;c.length&&c[c.length-1].from>o-s.from;)c.pop();if(!c.length)return a={range:n};let l=c[c.length-1];if(l.to-l.spaceAfter.length>o-s.from)return a={range:n};let u=o>=l.to-l.spaceAfter.length&&!/\S/.test(s.text.slice(l.to));if(l.item&&u){if(l.item.from<s.from&&!/^[\s>]*$/.test(s.text.slice(0,l.to)))return a={range:n};let r=l.node.firstChild,u=l.node.getChild(`ListItem`,`ListItem`);if(r.to>=o||u&&u.to<o||s.from>0&&!/[^\s>]/.test(i.lineAt(s.from-1).text)||e.nonTightLists===!1){let e=c.length>1?c[c.length-2]:null,t,n=``;e&&e.item?(t=s.from+e.from,n=e.marker(i,1)):t=s.from+(e?e.to:0);let r=[{from:t,to:o,insert:n}];return l.node.name==`OrderedList`&&Fg(l.item,i,r,-2),e&&e.node.name==`OrderedList`&&Fg(e.item,i,r),{range:A.cursor(t+n.length),changes:r}}else{let e=Bg(c,t,s);return{range:A.cursor(o+e.length+1),changes:{from:s.from,insert:e+t.lineBreak}}}}if(l.node.name==`Blockquote`&&u&&s.from){let e=i.lineAt(s.from-1),r=/>\s*$/.exec(e.text);if(r&&r.index==l.from){let i=t.changes([{from:e.from+r.index,to:e.to},{from:s.from+l.from,to:s.to}]);return{range:n.map(i),changes:i}}}let d=[];l.node.name==`OrderedList`&&Fg(l.item,i,d);let f=l.item&&l.item.from<s.from,p=``;if(!f||/^[\s\d.)\-+*>]*/.exec(s.text)[0].length>=l.to)for(let e=0,t=c.length-1;e<=t;e++)p+=e==t&&!f?c[e].marker(i,1):c[e].blank(e<t?gr(s.text,4,c[e+1].from)-p.length:null);let m=o;for(;m>s.from&&/\s/.test(s.text.charAt(m-s.from-1));)m--;return p=Ig(p,t),zg(l.node,t.doc)&&(p=Bg(c,t,s)+t.lineBreak+p),d.push({from:m,to:o,insert:t.lineBreak+p}),{range:A.cursor(m+p.length+1),changes:d}});return a?!1:(n(t.update(o,{scrollIntoView:!0,userEvent:`input`})),!0)})();function Rg(e){return e.name==`QuoteMark`||e.name==`ListMark`}function zg(e,t){if(e.name!=`OrderedList`&&e.name!=`BulletList`)return!1;let n=e.firstChild,r=e.getChild(`ListItem`,`ListItem`);if(!r)return!1;let i=t.lineAt(n.to),a=t.lineAt(r.from),o=/^[\s>]*$/.test(i.text);return i.number+ +!o<a.number}function Bg(e,t,n){let r=``;for(let t=0,i=e.length-2;t<=i;t++)r+=e[t].blank(t<i?gr(n.text,4,e[t+1].from)-r.length:null,t<i);return Ig(r,t)}function Vg(e,t){let n=e.resolveInner(t,-1),r=t;Rg(n)&&(r=n.from,n=n.parent);for(let e;e=n.childBefore(r);)if(Rg(e))r=e.from;else if(e.name==`OrderedList`||e.name==`BulletList`)n=e.lastChild,r=n.to;else break;return n}const Hg=[{key:`Enter`,run:Lg},{key:`Backspace`,run:({state:e,dispatch:t})=>{let n=J(e),r=null,i=e.changeByRange(t=>{let i=t.from,{doc:a}=e;if(t.empty&&Ag.isActiveAt(e,t.from)){let t=a.lineAt(i),r=Ng(Vg(n,i),a);if(r.length){let n=r[r.length-1],a=n.to-n.spaceAfter.length+ +!!n.spaceAfter;if(i-t.from>a&&!/\S/.test(t.text.slice(a,i-t.from)))return{range:A.cursor(t.from+a),changes:{from:t.from+a,to:i}};if(i-t.from==a&&(n.item&&t.from<=n.item.from||/^[\s>]*$/.test(t.text.slice(0,n.to)))){let r=t.from+n.from;if(n.item&&n.node.from<n.item.from&&/\S/.test(t.text.slice(n.from,n.to))){let i=n.blank(gr(t.text,4,n.to)-gr(t.text,4,n.from));return r==t.from&&(i=Ig(i,e)),{range:A.cursor(r+i.length),changes:{from:r,to:t.from+n.to,insert:i}}}if(r<i)return{range:A.cursor(r),changes:{from:r,to:i}}}}}return r={range:t}});return r?!1:(t(e.update(i,{scrollIntoView:!0,userEvent:`delete`})),!0)}}],Ug=_g({matchClosingTags:!1});function Wg(e={}){let{codeLanguages:t,defaultCodeLanguage:n,addKeymap:r=!0,base:{parser:i}=kg,completeHTMLTags:a=!0,pasteURLAsLink:o=!0,htmlTagLanguage:s=Ug}=e;if(!(i instanceof jf))throw RangeError("Base parser provided to `markdown` should be a Markdown parser");let c=e.extensions?[e.extensions]:[],l=[s.support,Dg],u;o&&l.push(Yg),n instanceof Iu?(l.push(n.support),u=n.language):n&&(u=n);let d=t||u?jg(t,u):void 0;c.push(ap({codeParser:d,htmlParser:s.language.parser})),r&&l.push(yn.high(Ac.of(Hg)));let f=Og(i.configure(c));return a&&l.push(f.data.of({autocomplete:Gg})),new Iu(f,l)}function Gg(e){let{state:t,pos:n}=e,r=/<[:\-\.\w\u00b7-\uffff]*$/.exec(t.sliceDoc(n-25,n));if(!r)return null;let i=J(t).resolveInner(n,-1);for(;i&&!i.type.isTop;){if(i.name==`CodeBlock`||i.name==`FencedCode`||i.name==`ProcessingInstructionBlock`||i.name==`CommentBlock`||i.name==`Link`||i.name==`Image`)return null;i=i.parent}return{from:n-r[0].length,to:n,options:qg(),validFor:/^<[:\-\.\w\u00b7-\uffff]*$/}}let Kg=null;function qg(){if(Kg)return Kg;let e=ug(new Ed(N.create({extensions:Ug}),0,!0));return Kg=e?e.options:[]}const Jg=/code|horizontalrule|html|link|comment|processing|escape|entity|image|mark|url/i,Yg=V.domEventHandlers({paste:(e,t)=>{let{main:n}=t.state.selection;if(n.empty)return!1;let r=e.clipboardData?.getData(`text/plain`);if(!r||!/^(https?:\/\/|mailto:|xmpp:|www\.)/.test(r)||(/^www\./.test(r)&&(r=`https://`+r),!Ag.isActiveAt(t.state,n.from,1)))return!1;let i=J(t.state),a=!1;return i.iterate({from:n.from,to:n.to,enter:e=>{(e.from>n.from||Jg.test(e.name))&&(a=!0)},leave:e=>{e.to<n.to&&(a=!0)}}),a?!1:(t.dispatch({changes:[{from:n.from,insert:`[`},{from:n.to,insert:`](${r})`}],userEvent:`input.paste`,scrollIntoView:!0}),!0)}}),Xg=e=>{let{state:t}=e,n=t.doc.lineAt(t.selection.main.from),r=t_(e.state,n.from);return r.line?Qg(e):r.block?e_(e):!1};function Zg(e,t){return({state:n,dispatch:r})=>{if(n.readOnly)return!1;let i=e(t,n);return i?(r(n.update(i)),!0):!1}}const Qg=Zg(a_,0),$g=Zg(i_,0),e_=Zg((e,t)=>i_(e,t,r_(t)),0);function t_(e,t){let n=e.languageDataAt(`commentTokens`,t,1);return n.length?n[0]:{}}function n_(e,{open:t,close:n},r,i){let a=e.sliceDoc(r-50,r),o=e.sliceDoc(i,i+50),s=/\s*$/.exec(a)[0].length,c=/^\s*/.exec(o)[0].length,l=a.length-s;if(a.slice(l-t.length,l)==t&&o.slice(c,c+n.length)==n)return{open:{pos:r-s,margin:s&&1},close:{pos:i+c,margin:c&&1}};let u,d;i-r<=100?u=d=e.sliceDoc(r,i):(u=e.sliceDoc(r,r+50),d=e.sliceDoc(i-50,i));let f=/^\s*/.exec(u)[0].length,p=/\s*$/.exec(d)[0].length,m=d.length-p-n.length;return u.slice(f,f+t.length)==t&&d.slice(m,m+n.length)==n?{open:{pos:r+f+t.length,margin:+!!/\s/.test(u.charAt(f+t.length))},close:{pos:i-p-n.length,margin:+!!/\s/.test(d.charAt(m-1))}}:null}function r_(e){let t=[];for(let n of e.selection.ranges){let r=e.doc.lineAt(n.from),i=n.to<=r.to?r:e.doc.lineAt(n.to);i.from>r.from&&i.from==n.to&&(i=n.to==r.to+1?r:e.doc.lineAt(n.to-1));let a=t.length-1;a>=0&&t[a].to>r.from?t[a].to=i.to:t.push({from:r.from+/^\s*/.exec(r.text)[0].length,to:i.to})}return t}function i_(e,t,n=t.selection.ranges){let r=n.map(e=>t_(t,e.from).block);if(!r.every(e=>e))return null;let i=n.map((e,n)=>n_(t,r[n],e.from,e.to));if(e!=2&&!i.every(e=>e))return{changes:t.changes(n.map((e,t)=>i[t]?[]:[{from:e.from,insert:r[t].open+` `},{from:e.to,insert:` `+r[t].close}]))};if(e!=1&&i.some(e=>e)){let e=[];for(let t=0,n;t<i.length;t++)if(n=i[t]){let i=r[t],{open:a,close:o}=n;e.push({from:a.pos-i.open.length,to:a.pos+a.margin},{from:o.pos-o.margin,to:o.pos+i.close.length})}return{changes:e}}return null}function a_(e,t,n=t.selection.ranges){let r=[],i=-1;ranges:for(let{from:e,to:a}of n){let n=r.length,o=1e9,s;for(let n=e;n<=a;){let c=t.doc.lineAt(n);if(s==null&&(s=t_(t,c.from).line,!s))continue ranges;if(c.from>i&&(e==a||a>c.from)){i=c.from;let e=/^\s*/.exec(c.text)[0].length,t=e==c.length,n=c.text.slice(e,e+s.length)==s?e:-1;e<c.text.length&&e<o&&(o=e),r.push({line:c,comment:n,token:s,indent:e,empty:t,single:!1})}n=c.to+1}if(o<1e9)for(let e=n;e<r.length;e++)r[e].indent<r[e].line.text.length&&(r[e].indent=o);r.length==n+1&&(r[n].single=!0)}if(e!=2&&r.some(e=>e.comment<0&&(!e.empty||e.single))){let e=[];for(let{line:t,token:n,indent:i,empty:a,single:o}of r)(o||!a)&&e.push({from:t.from+i,insert:n+` `});let n=t.changes(e);return{changes:n,selection:t.selection.map(n,1)}}else if(e!=1&&r.some(e=>e.comment>=0)){let e=[];for(let{line:t,comment:n,token:i}of r)if(n>=0){let r=t.from+n,a=r+i.length;t.text[a-t.from]==` `&&a++,e.push({from:r,to:a})}return{changes:e}}return null}const o_=Pn.define(),s_=Pn.define(),c_=j.define(),l_=j.define({combine(e){return Zn(e,{minDepth:100,newGroupDelay:500,joinToEvent:(e,t)=>t},{minDepth:Math.max,newGroupDelay:Math.min,joinToEvent:(e,t)=>(n,r)=>e(n,r)||t(n,r)})}}),u_=gn.define({create(){return O_.empty},update(e,t){let n=t.state.facet(l_),r=t.annotation(o_);if(r){let i=__.fromTransaction(t,r.selection),a=r.side,o=a==0?e.undone:e.done;return o=i?v_(o,o.length,n.minDepth,i):C_(o,t.startState.selection),new O_(a==0?r.rest:o,a==0?o:r.rest)}let i=t.annotation(s_);if((i==`full`||i==`before`)&&(e=e.isolate()),t.annotation(Ln.addToHistory)===!1)return t.changes.empty?e:e.addMapping(t.changes.desc);let a=__.fromTransaction(t),o=t.annotation(Ln.time),s=t.annotation(Ln.userEvent);return a?e=e.addChanges(a,o,s,n,t):t.selection&&(e=e.addSelection(t.startState.selection,o,s,n.newGroupDelay)),(i==`full`||i==`after`)&&(e=e.isolate()),e},toJSON(e){return{done:e.done.map(e=>e.toJSON()),undone:e.undone.map(e=>e.toJSON())}},fromJSON(e){return new O_(e.done.map(__.fromJSON),e.undone.map(__.fromJSON))}});function d_(e={}){return[u_,l_.of(e),V.domEventHandlers({beforeinput(e,t){let n=e.inputType==`historyUndo`?p_:e.inputType==`historyRedo`?m_:null;return n?(e.preventDefault(),n(t)):!1}})]}function f_(e,t){return function({state:n,dispatch:r}){if(!t&&n.readOnly)return!1;let i=n.field(u_,!1);if(!i)return!1;let a=i.pop(e,n,t);return a?(r(a),!0):!1}}const p_=f_(0,!1),m_=f_(1,!1),h_=f_(0,!0),g_=f_(1,!0);var __=class e{constructor(e,t,n,r,i){this.changes=e,this.effects=t,this.mapped=n,this.startSelection=r,this.selectionsAfter=i}setSelAfter(t){return new e(this.changes,this.effects,this.mapped,this.startSelection,t)}toJSON(){return{changes:this.changes?.toJSON(),mapped:this.mapped?.toJSON(),startSelection:this.startSelection?.toJSON(),selectionsAfter:this.selectionsAfter.map(e=>e.toJSON())}}static fromJSON(t){return new e(t.changes&&en.fromJSON(t.changes),[],t.mapped&&$t.fromJSON(t.mapped),t.startSelection&&A.fromJSON(t.startSelection),t.selectionsAfter.map(A.fromJSON))}static fromTransaction(t,n){let r=S_;for(let e of t.startState.facet(c_)){let n=e(t);n.length&&(r=r.concat(n))}return!r.length&&t.changes.empty?null:new e(t.changes.invert(t.startState.doc),r,void 0,n||t.startState.selection,S_)}static selection(t){return new e(void 0,S_,void 0,void 0,t)}};function v_(e,t,n,r){let i=t+1>n+20?t-n-1:0,a=e.slice(i,t);return a.push(r),a}function y_(e,t){let n=[],r=!1;return e.iterChangedRanges((e,t)=>n.push(e,t)),t.iterChangedRanges((e,t,i,a)=>{for(let e=0;e<n.length;){let t=n[e++],o=n[e++];a>=t&&i<=o&&(r=!0)}}),r}function b_(e,t){return e.ranges.length==t.ranges.length&&e.ranges.filter((e,n)=>e.empty!=t.ranges[n].empty).length===0}function x_(e,t){return e.length?t.length?e.concat(t):e:t}const S_=[];function C_(e,t){if(e.length){let n=e[e.length-1],r=n.selectionsAfter.slice(Math.max(0,n.selectionsAfter.length-200));return r.length&&r[r.length-1].eq(t)?e:(r.push(t),v_(e,e.length-1,1e9,n.setSelAfter(r)))}else return[__.selection([t])]}function w_(e){let t=e[e.length-1],n=e.slice();return n[e.length-1]=t.setSelAfter(t.selectionsAfter.slice(0,t.selectionsAfter.length-1)),n}function T_(e,t){if(!e.length)return e;let n=e.length,r=S_;for(;n;){let i=E_(e[n-1],t,r);if(i.changes&&!i.changes.empty||i.effects.length){let t=e.slice(0,n);return t[n-1]=i,t}else t=i.mapped,n--,r=i.selectionsAfter}return r.length?[__.selection(r)]:S_}function E_(e,t,n){let r=x_(e.selectionsAfter.length?e.selectionsAfter.map(e=>e.map(t)):S_,n);if(!e.changes)return __.selection(r);let i=e.changes.map(t),a=t.mapDesc(e.changes,!0),o=e.mapped?e.mapped.composeDesc(a):a;return new __(i,M.mapEffects(e.effects,t),o,e.startSelection.map(a),r)}const D_=/^(input\.type|delete)($|\.)/;var O_=class e{constructor(e,t,n=0,r=void 0){this.done=e,this.undone=t,this.prevTime=n,this.prevUserEvent=r}isolate(){return this.prevTime?new e(this.done,this.undone):this}addChanges(t,n,r,i,a){let o=this.done,s=o[o.length-1];return o=s&&s.changes&&!s.changes.empty&&t.changes&&(!r||D_.test(r))&&(!s.selectionsAfter.length&&n-this.prevTime<i.newGroupDelay&&i.joinToEvent(a,y_(s.changes,t.changes))||r==`input.type.compose`)?v_(o,o.length-1,i.minDepth,new __(t.changes.compose(s.changes),x_(M.mapEffects(t.effects,s.changes),s.effects),s.mapped,s.startSelection,S_)):v_(o,o.length,i.minDepth,t),new e(o,S_,n,r)}addSelection(t,n,r,i){let a=this.done.length?this.done[this.done.length-1].selectionsAfter:S_;return a.length>0&&n-this.prevTime<i&&r==this.prevUserEvent&&r&&/^select($|\.)/.test(r)&&b_(a[a.length-1],t)?this:new e(C_(this.done,t),this.undone,n,r)}addMapping(t){return new e(T_(this.done,t),T_(this.undone,t),this.prevTime,this.prevUserEvent)}pop(e,t,n){let r=e==0?this.done:this.undone;if(r.length==0)return null;let i=r[r.length-1],a=i.selectionsAfter[0]||(i.startSelection?i.startSelection.map(i.changes.invertedDesc,1):t.selection);if(n&&i.selectionsAfter.length)return t.update({selection:i.selectionsAfter[i.selectionsAfter.length-1],annotations:o_.of({side:e,rest:w_(r),selection:a}),userEvent:e==0?`select.undo`:`select.redo`,scrollIntoView:!0});if(i.changes){let n=r.length==1?S_:r.slice(0,r.length-1);return i.mapped&&(n=T_(n,i.mapped)),t.update({changes:i.changes,selection:i.startSelection,effects:i.effects,annotations:o_.of({side:e,rest:n,selection:a}),filter:!1,userEvent:e==0?`undo`:`redo`,scrollIntoView:!0})}else return null}};O_.empty=new O_(S_,S_);const k_=[{key:`Mod-z`,run:p_,preventDefault:!0},{key:`Mod-y`,mac:`Mod-Shift-z`,run:m_,preventDefault:!0},{linux:`Ctrl-Shift-z`,run:m_,preventDefault:!0},{key:`Mod-u`,run:h_,preventDefault:!0},{key:`Alt-u`,mac:`Mod-Shift-u`,run:g_,preventDefault:!0}];function A_(e,t){return A.create(e.ranges.map(t),e.mainIndex)}function j_(e,t){return e.update({selection:t,scrollIntoView:!0,userEvent:`select`})}function M_({state:e,dispatch:t},n){let r=A_(e.selection,n);return r.eq(e.selection,!0)?!1:(t(j_(e,r)),!0)}function N_(e,t){return A.cursor(t?e.to:e.from)}function P_(e,t){return M_(e,n=>n.empty?e.moveByChar(n,t):N_(n,t))}function Q(e){return e.textDirectionAt(e.state.selection.main.head)==L.LTR}const F_=e=>P_(e,!Q(e)),I_=e=>P_(e,Q(e));function L_(e,t){return M_(e,n=>n.empty?e.moveByGroup(n,t):N_(n,t))}const R_=e=>L_(e,!Q(e)),z_=e=>L_(e,Q(e));typeof Intl<`u`&&Intl.Segmenter;function B_(e,t,n){if(t.type.prop(n))return!0;let r=t.to-t.from;return r&&(r>2||/[^\s,.;:]/.test(e.sliceDoc(t.from,t.to)))||t.firstChild}function V_(e,t,n){let r=J(e).resolveInner(t.head),i=n?H.closedBy:H.openedBy;for(let a=t.head;;){let t=n?r.childAfter(a):r.childBefore(a);if(!t)break;B_(e,t,i)?r=t:a=n?t.to:t.from}let a=r.type.prop(i),o,s;return s=a&&(o=n?gd(e,r.from,1):gd(e,r.to,-1))&&o.matched?n?o.end.to:o.end.from:n?r.to:r.from,A.cursor(s,n?-1:1)}const H_=e=>M_(e,t=>V_(e.state,t,!Q(e))),U_=e=>M_(e,t=>V_(e.state,t,Q(e)));function W_(e,t){return M_(e,n=>{if(!n.empty)return N_(n,t);let r=e.moveVertically(n,t);return r.head==n.head?e.moveToLineBoundary(n,t):r})}const G_=e=>W_(e,!1),K_=e=>W_(e,!0);function q_(e){let t=e.scrollDOM.clientHeight<e.scrollDOM.scrollHeight-2,n=0,r=0,i;if(t){for(let t of e.state.facet(V.scrollMargins)){let i=t(e);i?.top&&(n=Math.max(i?.top,n)),i?.bottom&&(r=Math.max(i?.bottom,r))}i=e.scrollDOM.clientHeight-n-r}else i=(e.dom.ownerDocument.defaultView||window).innerHeight;return{marginTop:n,marginBottom:r,selfScroll:t,height:Math.max(e.defaultLineHeight,i-5)}}function J_(e,t){let n=q_(e),{state:r}=e,i=A_(r.selection,r=>r.empty?e.moveVertically(r,t,n.height):N_(r,t));if(i.eq(r.selection))return!1;let a;if(n.selfScroll){let t=e.coordsAtPos(r.selection.main.head),o=e.scrollDOM.getBoundingClientRect(),s=o.top+n.marginTop,c=o.bottom-n.marginBottom;t&&t.top>s&&t.bottom<c&&(a=V.scrollIntoView(i.main.head,{y:`start`,yMargin:t.top-s}))}return e.dispatch(j_(r,i),{effects:a}),!0}const Y_=e=>J_(e,!1),X_=e=>J_(e,!0);function Z_(e,t,n){let r=e.lineBlockAt(t.head),i=e.moveToLineBoundary(t,n);if(i.head==t.head&&i.head!=(n?r.to:r.from)&&(i=e.moveToLineBoundary(t,n,!1)),!n&&i.head==r.from&&r.length){let n=/^\s*/.exec(e.state.sliceDoc(r.from,Math.min(r.from+100,r.to)))[0].length;n&&t.head!=r.from+n&&(i=A.cursor(r.from+n))}return i}const Q_=e=>M_(e,t=>Z_(e,t,!0)),$_=e=>M_(e,t=>Z_(e,t,!1)),ev=e=>M_(e,t=>Z_(e,t,!Q(e))),tv=e=>M_(e,t=>Z_(e,t,Q(e))),nv=e=>M_(e,t=>A.cursor(e.lineBlockAt(t.head).from,1)),rv=e=>M_(e,t=>A.cursor(e.lineBlockAt(t.head).to,-1));function iv(e,t,n){let r=!1,i=A_(e.selection,t=>{let i=gd(e,t.head,-1)||gd(e,t.head,1)||t.head>0&&gd(e,t.head-1,1)||t.head<e.doc.length&&gd(e,t.head+1,-1);if(!i||!i.end)return t;r=!0;let a=i.start.from==t.head?i.end.to:i.end.from;return n?A.range(t.anchor,a):A.cursor(a)});return r?(t(j_(e,i)),!0):!1}const av=({state:e,dispatch:t})=>iv(e,t,!1);function ov(e,t,n){let r=A_(e.state.selection,e=>{e.undirectional&&e.head>=e.anchor!=t&&(e=A.range(e.head,e.anchor));let r=n(e);return A.range(e.anchor,r.head,r.goalColumn,r.bidiLevel||void 0,r.assoc)});return r.eq(e.state.selection)?!1:(e.dispatch(j_(e.state,r)),!0)}function sv(e,t){return ov(e,t,n=>e.moveByChar(n,t))}const cv=e=>sv(e,!Q(e)),lv=e=>sv(e,Q(e));function uv(e,t){return ov(e,t,n=>e.moveByGroup(n,t))}const dv=e=>uv(e,!Q(e)),fv=e=>uv(e,Q(e)),pv=e=>{let t=!Q(e);return ov(e,t,n=>V_(e.state,n,t))},mv=e=>{let t=Q(e);return ov(e,t,n=>V_(e.state,n,t))};function hv(e,t){return ov(e,t,n=>e.moveVertically(n,t))}const gv=e=>hv(e,!1),_v=e=>hv(e,!0);function vv(e,t){return ov(e,t,n=>e.moveVertically(n,t,q_(e).height))}const yv=e=>vv(e,!1),bv=e=>vv(e,!0),xv=e=>ov(e,!0,t=>Z_(e,t,!0)),Sv=e=>ov(e,!1,t=>Z_(e,t,!1)),Cv=e=>{let t=!Q(e);return ov(e,t,n=>Z_(e,n,t))},wv=e=>{let t=Q(e);return ov(e,t,n=>Z_(e,n,t))},Tv=e=>ov(e,!1,t=>A.cursor(e.lineBlockAt(t.head).from)),Ev=e=>ov(e,!0,t=>A.cursor(e.lineBlockAt(t.head).to)),Dv=({state:e,dispatch:t})=>(t(j_(e,{anchor:0})),!0),Ov=({state:e,dispatch:t})=>(t(j_(e,{anchor:e.doc.length})),!0),kv=({state:e,dispatch:t})=>(t(j_(e,{anchor:e.selection.main.anchor,head:0})),!0),Av=({state:e,dispatch:t})=>(t(j_(e,{anchor:e.selection.main.anchor,head:e.doc.length})),!0),jv=({state:e,dispatch:t})=>(t(e.update({selection:{anchor:0,head:e.doc.length},userEvent:`select`})),!0),Mv=({state:e,dispatch:t})=>{let n=Zv(e).map(({from:t,to:n})=>A.undirectionalRange(t,Math.min(n+1,e.doc.length)));return t(e.update({selection:A.create(n),userEvent:`select`})),!0},Nv=({state:e,dispatch:t})=>{let n=A_(e.selection,t=>{let n=J(e),r=n.resolveStack(t.from,1);if(t.empty){let e=n.resolveStack(t.from,-1);e.node.from>=r.node.from&&e.node.to<=r.node.to&&(r=e)}for(let e=r;e;e=e.next){let{node:n}=e;if((n.from<t.from&&n.to>=t.to||n.to>t.to&&n.from<=t.from)&&e.next)return A.undirectionalRange(n.from,n.to)}return t});return n.eq(e.selection)?!1:(t(j_(e,n)),!0)};function Pv(e,t){let{state:n}=e,r=n.selection,i=n.selection.ranges.slice();for(let r of n.selection.ranges){let a=n.doc.lineAt(r.head);if(t?a.to<e.state.doc.length:a.from>0)for(let n=r;;){let r=e.moveVertically(n,t);if(r.head<a.from||r.head>a.to){i.some(e=>e.head==r.head)||i.push(r);break}else if(r.head==n.head)break;else n=r}}return i.length==r.ranges.length?!1:(e.dispatch(j_(n,A.create(i,i.length-1))),!0)}const Fv=e=>Pv(e,!1),Iv=e=>Pv(e,!0),Lv=({state:e,dispatch:t})=>{let n=e.selection,r=null;return n.ranges.length>1?r=A.create([n.main]):n.main.empty||(r=A.create([A.cursor(n.main.head)])),r?(t(j_(e,r)),!0):!1};function Rv(e,t){if(e.state.readOnly)return!1;let n=`delete.selection`,{state:r}=e,i=r.changeByRange(r=>{let{from:i,to:a}=r;if(i==a){let o=t(r);o<i?(n=`delete.backward`,o=zv(e,o,!1)):o>i&&(n=`delete.forward`,o=zv(e,o,!0)),i=Math.min(i,o),a=Math.max(a,o)}else i=zv(e,i,!1),a=zv(e,a,!0);return i==a?{range:r}:{changes:{from:i,to:a},range:A.cursor(i,i<r.head?-1:1)}});return i.changes.empty?!1:(e.dispatch(r.update(i,{scrollIntoView:!0,userEvent:n,effects:n==`delete.selection`?V.announce.of(r.phrase(`Selection deleted`)):void 0})),!0)}function zv(e,t,n){if(e instanceof V)for(let r of e.state.facet(V.atomicRanges).map(t=>t(e)))r.between(t,t,(e,r)=>{e<t&&r>t&&(t=n?r:e)});return t}const Bv=(e,t,n)=>Rv(e,r=>{let i=r.from,{state:a}=e,o=a.doc.lineAt(i),s,c;if(n&&!t&&i>o.from&&i<o.from+200&&!/[^ \t]/.test(s=o.text.slice(0,i-o.from))){if(s[s.length-1]==` `)return i-1;let e=gr(s,a.tabSize)%Bu(a)||Bu(a);for(let t=0;t<e&&s[s.length-1-t]==` `;t++)i--;c=i}else c=O(o.text,i-o.from,t,t)+o.from,c==i&&o.number!=(t?a.doc.lines:1)?c+=t?1:-1:!t&&/[\ufe00-\ufe0f]/.test(o.text.slice(c-o.from,i-o.from))&&(c=O(o.text,c-o.from,!1,!1)+o.from);return c}),Vv=e=>Bv(e,!1,!0),Hv=e=>Bv(e,!0,!1),Uv=(e,t)=>Rv(e,n=>{let r=n.head,{state:i}=e,a=i.doc.lineAt(r),o=i.charCategorizer(r);for(let e=null;;){if(r==(t?a.to:a.from)){r==n.head&&a.number!=(t?i.doc.lines:1)&&(r+=t?1:-1);break}let s=O(a.text,r-a.from,t)+a.from,c=a.text.slice(Math.min(r,s)-a.from,Math.max(r,s)-a.from),l=o(c);if(e!=null&&l!=e)break;(c!=` `||r!=n.head)&&(e=l),r=s}return r}),Wv=e=>Uv(e,!1),Gv=e=>Uv(e,!0),Kv=e=>Rv(e,t=>{let n=e.lineBlockAt(t.head).to;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),qv=e=>Rv(e,t=>{let n=e.moveToLineBoundary(t,!1).head;return t.head>n?n:Math.max(0,t.head-1)}),Jv=e=>Rv(e,t=>{let n=e.moveToLineBoundary(t,!0).head;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),Yv=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=e.changeByRange(e=>({changes:{from:e.from,to:e.to,insert:D.of([``,``])},range:A.cursor(e.from)}));return t(e.update(n,{scrollIntoView:!0,userEvent:`input`})),!0},Xv=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=e.changeByRange(t=>{if(!t.empty||t.from==0||t.from==e.doc.length)return{range:t};let n=t.from,r=e.doc.lineAt(n),i=n==r.from?n-1:O(r.text,n-r.from,!1)+r.from,a=n==r.to?n+1:O(r.text,n-r.from,!0)+r.from;return{changes:{from:i,to:a,insert:e.doc.slice(n,a).append(e.doc.slice(i,n))},range:A.cursor(a)}});return n.changes.empty?!1:(t(e.update(n,{scrollIntoView:!0,userEvent:`move.character`})),!0)};function Zv(e){let t=[],n=-1;for(let r of e.selection.ranges){let i=e.doc.lineAt(r.from),a=e.doc.lineAt(r.to);if(!r.empty&&r.to==a.from&&(a=e.doc.lineAt(r.to-1)),n>=i.number){let e=t[t.length-1];e.to=a.to,e.ranges.push(r)}else t.push({from:i.from,to:a.to,ranges:[r]});n=a.number+1}return t}function Qv(e,t,n){if(e.readOnly)return!1;let r=[],i=[];for(let t of Zv(e)){if(n?t.to==e.doc.length:t.from==0)continue;let a=e.doc.lineAt(n?t.to+1:t.from-1),o=a.length+1;if(n){r.push({from:t.to,to:a.to},{from:t.from,insert:a.text+e.lineBreak});for(let n of t.ranges)i.push(A.range(Math.min(e.doc.length,n.anchor+o),Math.min(e.doc.length,n.head+o)))}else{r.push({from:a.from,to:t.from},{from:t.to,insert:e.lineBreak+a.text});for(let e of t.ranges)i.push(A.range(e.anchor-o,e.head-o))}}return r.length?(t(e.update({changes:r,scrollIntoView:!0,selection:A.create(i,e.selection.mainIndex),userEvent:`move.line`})),!0):!1}const $v=({state:e,dispatch:t})=>Qv(e,t,!1),ey=({state:e,dispatch:t})=>Qv(e,t,!0);function ty(e,t,n){if(e.readOnly)return!1;let r=[];for(let t of Zv(e))n?r.push({from:t.from,insert:e.doc.slice(t.from,t.to)+e.lineBreak}):r.push({from:t.to,insert:e.lineBreak+e.doc.slice(t.from,t.to)});let i=e.changes(r);return t(e.update({changes:i,selection:e.selection.map(i,n?1:-1),scrollIntoView:!0,userEvent:`input.copyline`})),!0}const ny=({state:e,dispatch:t})=>ty(e,t,!1),ry=({state:e,dispatch:t})=>ty(e,t,!0),iy=e=>{if(e.state.readOnly)return!1;let{state:t}=e,n=t.changes(Zv(t).map(({from:e,to:n})=>(e>0?e--:n<t.doc.length&&n++,{from:e,to:n}))),r=A_(t.selection,t=>{let n;if(e.lineWrapping){let r=e.lineBlockAt(t.head),i=e.coordsAtPos(t.head,t.assoc||1);i&&(n=r.bottom+e.documentTop-i.bottom+e.defaultLineHeight/2)}return e.moveVertically(t,!0,n)}).map(n);return e.dispatch({changes:n,selection:r,scrollIntoView:!0,userEvent:`delete.line`}),!0};function ay(e,t){if(/\(\)|\[\]|\{\}/.test(e.sliceDoc(t-1,t+1)))return{from:t,to:t};let n=J(e).resolveInner(t),r=n.childBefore(t),i=n.childAfter(t),a;return r&&i&&r.to<=t&&i.from>=t&&(a=r.type.prop(H.closedBy))&&a.indexOf(i.name)>-1&&e.doc.lineAt(r.to).from==e.doc.lineAt(i.from).from&&!/\S/.test(e.sliceDoc(r.to,i.from))?{from:r.to,to:i.from}:null}const oy=cy(!1),sy=cy(!0);function cy(e){return({state:t,dispatch:n})=>{if(t.readOnly)return!1;let r=t.changeByRange(n=>{let{from:r,to:i}=n,a=t.doc.lineAt(r),o=!e&&r==i&&ay(t,r);e&&(r=i=(i<=a.to?a:t.doc.lineAt(i)).to);let s=new Uu(t,{simulateBreak:r,simulateDoubleBreak:!!o}),c=Hu(s,r);for(c??=gr(/^\s*/.exec(t.doc.lineAt(r).text)[0],t.tabSize);i<a.to&&/\s/.test(a.text[i-a.from]);)i++;o?{from:r,to:i}=o:r>a.from&&r<a.from+100&&!/\S/.test(a.text.slice(0,r))&&(r=a.from);let l=[``,Vu(t,c)];return o&&l.push(Vu(t,s.lineIndent(a.from,-1))),{changes:{from:r,to:i,insert:D.of(l)},range:A.cursor(r+1+l[1].length)}});return n(t.update(r,{scrollIntoView:!0,userEvent:`input`})),!0}}function ly(e,t){let n=-1;return e.changeByRange(r=>{let i=[];for(let a=r.from;a<=r.to;){let o=e.doc.lineAt(a);o.number>n&&(r.empty||r.to>o.from)&&(t(o,i,r),n=o.number),a=o.to+1}let a=e.changes(i);return{changes:i,range:A.range(a.mapPos(r.anchor,1),a.mapPos(r.head,1))}})}const uy=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=Object.create(null),r=new Uu(e,{overrideIndentation:e=>n[e]??-1}),i=ly(e,(t,i,a)=>{let o=Hu(r,t.from);if(o==null)return;/\S/.test(t.text)||(o=0);let s=/^\s*/.exec(t.text)[0],c=Vu(e,o);(s!=c||a.from<t.from+s.length)&&(n[t.from]=o,i.push({from:t.from,to:t.from+s.length,insert:c}))});return i.changes.empty||t(e.update(i,{userEvent:`indent`})),!0},dy=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(ly(e,(t,n)=>{n.push({from:t.from,insert:e.facet(zu)})}),{userEvent:`input.indent`})),!0),fy=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(ly(e,(t,n)=>{let r=/^\s*/.exec(t.text)[0];if(!r)return;let i=gr(r,e.tabSize),a=0,o=Vu(e,Math.max(0,i-Bu(e)));for(;a<r.length&&a<o.length&&r.charCodeAt(a)==o.charCodeAt(a);)a++;n.push({from:t.from+a,to:t.from+r.length,insert:o.slice(a)})}),{userEvent:`delete.dedent`})),!0),py=e=>(e.setTabFocusMode(),!0),my=[{key:`Ctrl-b`,run:F_,shift:cv,preventDefault:!0},{key:`Ctrl-f`,run:I_,shift:lv},{key:`Ctrl-p`,run:G_,shift:gv},{key:`Ctrl-n`,run:K_,shift:_v},{key:`Ctrl-a`,run:nv,shift:Tv},{key:`Ctrl-e`,run:rv,shift:Ev},{key:`Ctrl-d`,run:Hv},{key:`Ctrl-h`,run:Vv},{key:`Ctrl-k`,run:Kv},{key:`Ctrl-Alt-h`,run:Wv},{key:`Ctrl-o`,run:Yv},{key:`Ctrl-t`,run:Xv},{key:`Ctrl-v`,run:X_}],hy=[{key:`ArrowLeft`,run:F_,shift:cv,preventDefault:!0},{key:`Mod-ArrowLeft`,mac:`Alt-ArrowLeft`,run:R_,shift:dv,preventDefault:!0},{mac:`Cmd-ArrowLeft`,run:ev,shift:Cv,preventDefault:!0},{key:`ArrowRight`,run:I_,shift:lv,preventDefault:!0},{key:`Mod-ArrowRight`,mac:`Alt-ArrowRight`,run:z_,shift:fv,preventDefault:!0},{mac:`Cmd-ArrowRight`,run:tv,shift:wv,preventDefault:!0},{key:`ArrowUp`,run:G_,shift:gv,preventDefault:!0},{mac:`Cmd-ArrowUp`,run:Dv,shift:kv},{mac:`Ctrl-ArrowUp`,run:Y_,shift:yv},{key:`ArrowDown`,run:K_,shift:_v,preventDefault:!0},{mac:`Cmd-ArrowDown`,run:Ov,shift:Av},{mac:`Ctrl-ArrowDown`,run:X_,shift:bv},{key:`PageUp`,run:Y_,shift:yv},{key:`PageDown`,run:X_,shift:bv},{key:`Home`,run:$_,shift:Sv,preventDefault:!0},{key:`Mod-Home`,run:Dv,shift:kv},{key:`End`,run:Q_,shift:xv,preventDefault:!0},{key:`Mod-End`,run:Ov,shift:Av},{key:`Enter`,run:oy,shift:oy},{key:`Mod-a`,run:jv},{key:`Backspace`,run:Vv,shift:Vv,preventDefault:!0},{key:`Delete`,run:Hv,preventDefault:!0},{key:`Mod-Backspace`,mac:`Alt-Backspace`,run:Wv,preventDefault:!0},{key:`Mod-Delete`,mac:`Alt-Delete`,run:Gv,preventDefault:!0},{mac:`Mod-Backspace`,run:qv,preventDefault:!0},{mac:`Mod-Delete`,run:Jv,preventDefault:!0}].concat(my.map(e=>({mac:e.key,run:e.run,shift:e.shift}))),gy=[{key:`Alt-ArrowLeft`,mac:`Ctrl-ArrowLeft`,run:H_,shift:pv},{key:`Alt-ArrowRight`,mac:`Ctrl-ArrowRight`,run:U_,shift:mv},{key:`Alt-ArrowUp`,run:$v},{key:`Shift-Alt-ArrowUp`,run:ny},{key:`Alt-ArrowDown`,run:ey},{key:`Shift-Alt-ArrowDown`,run:ry},{key:`Mod-Alt-ArrowUp`,run:Fv},{key:`Mod-Alt-ArrowDown`,run:Iv},{key:`Escape`,run:Lv},{key:`Mod-Enter`,run:sy},{key:`Alt-l`,mac:`Ctrl-l`,run:Mv},{key:`Mod-i`,run:Nv,preventDefault:!0},{key:`Mod-[`,run:fy},{key:`Mod-]`,run:dy},{key:`Mod-Alt-\\`,run:uy},{key:`Shift-Mod-k`,run:iy},{key:`Shift-Mod-\\`,run:av},{key:`Mod-/`,run:Xg},{key:`Alt-A`,mac:`Ctrl-A`,run:$g},{key:`Ctrl-m`,mac:`Shift-Alt-m`,run:py}].concat(hy),_y=`var(--dsw-alias-brand-primary, #3e63dd)`,vy=`color-mix(in srgb, var(--dsw-alias-brand-primary, #3e63dd) 55%, transparent)`,yy=`var(--dsw-alias-label-dimmed, #999)`,by=`ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace`,xy=od.define([{tag:[q.heading1,q.heading2,q.heading3,q.heading4,q.heading5,q.heading6],color:_y,fontWeight:`700`},{tag:q.processingInstruction,color:vy},{tag:q.monospace,fontFamily:by,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 12%, transparent)`,borderRadius:`4px`,padding:`0 3px`},{tag:q.content,fontFamily:by,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 8%, transparent)`},{tag:q.strong,fontWeight:`700`},{tag:q.emphasis,fontStyle:`italic`},{tag:q.strikethrough,textDecoration:`line-through`,opacity:`.75`},{tag:q.link,color:_y,textDecoration:`underline`},{tag:q.url,color:vy,textDecoration:`underline dotted`},{tag:q.quote,fontStyle:`italic`,color:`var(--dsw-alias-label-secondary, #888)`},{tag:q.contentSeparator,color:yy,textDecoration:`line-through`},{tag:q.comment,color:yy}]);function Sy(e={}){let t=document.createElement(`div`);t.className=`dsh-tw-note-editor`;let n=new V({parent:t,state:N.create({doc:``,extensions:[V.lineWrapping,d_(),Wg({base:Ag}),ud(xy),Kc(),el(e.placeholder??``),Ac.of([...gy,...k_,{key:`Mod-Enter`,run:()=>(e.onSave?.(),!0)}]),V.updateListener.of(t=>{t.docChanged&&e.onChange?.()})]})});return{el:t,view:n,getValue:()=>n.state.doc.toString(),setValue(e){n.dispatch({changes:{from:0,to:n.state.doc.length,insert:e}})},insertAtCaret(e){let{from:t}=n.state.selection.main,r=`${t===n.state.doc.lineAt(t).from?``:`
|
|
740
740
|
`}${e}\n`;n.dispatch({changes:{from:t,insert:r},selection:{anchor:t+r.length},scrollIntoView:!0}),n.focus()},focus:()=>n.focus()}}const Cy=`dsh-tw-note-state`,wy=`dsh-tw-note-draft-v1`,Ty=`dsh-tw-note-window-id`,Ey=(()=>{try{let e=sessionStorage.getItem(Ty);if(e!==null&&e.length>0)return e;let t=Math.random().toString(36).slice(2,10);return sessionStorage.setItem(Ty,t),t}catch{return Math.random().toString(36).slice(2,10)}})();function Dy(){return`dsh-tw-note-draft-v1:${Ey}`}function Oy(e){if(e===null)return null;try{let t=JSON.parse(e);return typeof t.text!=`string`||typeof t.title!=`string`?null:{text:t.text,title:t.title,tags:Array.isArray(t.tags)?t.tags.filter(e=>typeof e==`string`):[],savedAt:typeof t.savedAt==`number`?t.savedAt:0,windowId:typeof t.windowId==`string`?t.windowId:void 0}}catch{return null}}function ky(e){try{return Oy(localStorage.getItem(e))}catch{return null}}function Ay(){let e=ky(Dy());if(e!==null)return{draft:e,foreign:e.windowId!==void 0&&e.windowId!==Ey};let t=ky(wy);if(t===null)return null;let n={...t,windowId:Ey};My(n);try{localStorage.removeItem(wy)}catch{}return{draft:n,foreign:!0}}function jy(e){My({...e,windowId:Ey})}function My(e){try{localStorage.setItem(Dy(),JSON.stringify({...e,windowId:Ey}))}catch{}}function Ny(){try{localStorage.removeItem(Dy())}catch{}}function Py(e,t,n){return`${e}\u0000${t}\u0000${n.join(``)}`}function Fy(e){return e<10?`0${e}`:String(e)}function Iy(e=new Date){return`${e.getFullYear()}-${Fy(e.getMonth()+1)}-${Fy(e.getDate())} ${Fy(e.getHours())}:${Fy(e.getMinutes())}`}function Ly(e){if(e===null)return``;let t=new Date(e).getTime();if(Number.isNaN(t))return``;let n=Date.now()-t,r=Math.floor(n/6e4);if(r<1)return`刚刚`;if(r<60)return`${r}分钟前`;let i=Math.floor(r/60);if(i<24)return`${i}小时前`;let a=Math.floor(i/24);return a<30?`${a}天前`:new Date(t).toLocaleDateString(`zh-CN`)}async function Ry(){let e={showQuickNote:!0,defaultTag:`inbox`},t=await me();return t===null?e:{showQuickNote:t.ui?.showQuickNote!==!1,defaultTag:typeof t.note?.tag==`string`&&t.note.tag.length>0?t.note.tag:`inbox`}}function zy(e={}){let t=document.createElement(`div`);t.className=`dsh-tw-note-tags`;let n=document.createElement(`div`);n.className=`dsh-tw-note-chips`;let r=document.createElement(`input`);r.className=`dsh-tw-note-taginput`,r.placeholder=`tag(可多选,自动补全)`;let i=document.createElement(`div`);i.className=`dsh-tw-note-tagsuggest`,i.hidden=!0,t.append(n,r,i);let a=[],o=()=>{i.hidden=!0},s=()=>{e.onChange?.()},c=()=>{n.replaceChildren();for(let e of a){let t=document.createElement(`span`);t.className=`dsh-tw-note-tagchip`,t.textContent=e;let r=document.createElement(`span`);r.className=`dsh-tw-note-tagchip-x`,r.textContent=`×`,r.title=`移除 tag「${e}」`,r.addEventListener(`click`,t=>{t.stopPropagation();let n=a.indexOf(e);n>=0&&(a.splice(n,1),c(),s())}),t.append(r),n.append(t)}},l=e=>{let t=e.trim();t.length===0||a.includes(t)||(a.push(t),r.value=``,c(),o(),r.focus(),s())},u=()=>{for(let e of r.value.split(/\s+/))l(e)},d=[],f,p=()=>(f??=fetch(b,{signal:AbortSignal.timeout(5e3)}).then(e=>e.ok?e.json():Promise.resolve({})).then(e=>[...e.tags??[]].sort((e,t)=>e.localeCompare(t,`zh`))).catch(()=>[]),f.then(e=>{d=e}),f),m=()=>{let e=r.value.trim().toLowerCase(),t=d.filter(t=>!a.includes(t)&&(e.length===0||t.toLowerCase().includes(e))).slice(0,8);i.replaceChildren();for(let e of t){let t=document.createElement(`div`);t.className=`dsh-tw-note-tagsuggest-item`,t.textContent=e,t.setAttribute(`role`,`button`),t.tabIndex=0,t.setAttribute(`aria-label`,`添加标签「${e}」`),t.addEventListener(`mousedown`,t=>{t.preventDefault(),l(e)}),t.addEventListener(`keydown`,t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),l(e))}),i.append(t)}i.hidden=t.length===0};r.addEventListener(`focus`,()=>{p().then(m)}),r.addEventListener(`input`,()=>{d.length===0?p().then(m):m()}),r.addEventListener(`keydown`,e=>{e.key===`Enter`||e.key===`,`?(e.preventDefault(),u()):e.key===`Backspace`&&r.value.length===0&&a.length>0?(a.pop(),c(),s()):e.key===`Escape`&&o()});let h=e=>{t.contains(e.target)||o()};return document.addEventListener(`click`,h,!0),{el:t,getTags:()=>(u(),[...a]),peekTags:()=>[...a],setDefault:e=>{if(a.length===0){let t=e.trim();t.length>0&&(a.push(t),c())}},setTags:e=>{a.length=0;for(let t of Array.isArray(e)?e:[]){let e=typeof t==`string`?t.trim():``;e.length>0&&!a.includes(e)&&a.push(e)}r.value=``,c(),o()},dispose:()=>document.removeEventListener(`click`,h,!0)}}async function By(e,t){if(e.size>67108864){T(`文件过大(≤ 64MB)`);return}try{let n=await fetch(`${ee}?name=${encodeURIComponent(e.name)}`,{method:`POST`,headers:{"content-type":e.type||`application/octet-stream`},body:e,signal:AbortSignal.timeout(12e4)}),r=await n.json().catch(()=>null);if(!n.ok||r?.ok!==!0){T(`上传失败:${r?.error??`HTTP ${n.status}`}`);return}let i=r.name??e.name,a=e.type.startsWith(`image/`)?``:`[${i}](${r.url})`;t.insertAtCaret(a),T(`已上传「${i}」并插入链接`)}catch(e){T(`上传失败:${e instanceof Error?e.message:String(e)}`)}}function Vy(){let e,t=!1,n=!1,r=!1,i,a=`inbox`,o,s=!1,c=null,l=null,u=e=>{try{window.dispatchEvent(new CustomEvent(Cy,{detail:{open:e}}))}catch{}},d=t=>{if(e===void 0)return;let n=e.root,r=e.card;if(t!==void 0){let e=t.getBoundingClientRect(),i=r.offsetWidth||340,a=r.offsetHeight||260,o=window.innerWidth,s=window.innerHeight,c=Math.min(Math.max(e.left+e.width/2-i/2,8),Math.max(8,o-i-8)),l=s-e.top+10,u=Math.min(Math.max(8,l),Math.max(8,s-a-8));n.style.right=`auto`,n.style.top=`auto`,n.style.left=`${c}px`,n.style.bottom=`${u}px`}else n.style.right=`24px`,n.style.bottom=`88px`,n.style.left=`auto`,n.style.top=`auto`},f=()=>{e!==void 0&&(e.titleInput.value=Iy())},p=()=>{if(e===void 0)return;let t=e.editor.getValue(),n=e.titleInput.value.trim();if(t.trim().length===0&&n.length===0){Ny();return}let r=Py(n,t,e.tagEditor.peekTags());l!==null&&r===l||My({text:t,title:n,tags:e.tagEditor.peekTags(),savedAt:Date.now()})},m=()=>{t||!n||e===void 0||(o!==void 0&&(clearTimeout(o),o=void 0),o=window.setTimeout(()=>{o=void 0,p()},500))},h=()=>{e!==void 0&&(e.draftBanner.hidden=!0)},_=async(e,t,n)=>{try{let r=await fetch(y,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({title:e,tags:n,text:t}),signal:AbortSignal.timeout(1e4)}),i=await r.json().catch(()=>null);return!r.ok||i?.ok!==!0?(T(`打开失败:${i?.error??`HTTP ${r.status}`}`),!1):typeof i.twUrl!=`string`||typeof i.draftTitle!=`string`?(T(`打开失败:服务未返回编辑器地址`),!1):(Ny(),h(),l=Py(e,t,n),c=null,yt(`${new URL(i.twUrl,location.origin).href}#${encodeURIComponent(i.draftTitle)}`,i.title??e),T(`已在弹出窗口打开「${i.title??e}」编辑器`),!0)}catch(e){return T(`打开失败:${e instanceof Error?e.message:String(e)}`),!1}},b=()=>{s=!1,e!==void 0&&(e.recentWrap.hidden=!0)},S=async t=>{try{let n=await fetch(`${g}?title=${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(1e4)}),r=await n.json().catch(()=>null);if(!n.ok||r?.ok!==!0||typeof r.title!=`string`){T(`读取失败:${r?.notFound===!0?`不存在`:r?.error??`HTTP ${n.status}`}`);return}if(e===void 0)return;e.editor.setValue(r.text??``),e.titleInput.value=r.title,e.tagEditor.setTags(r.tags??[]),c={title:r.title,...typeof r.modified==`string`&&r.modified.length>0?{modified:r.modified}:{},...typeof r.revision==`number`?{revision:r.revision}:{}},l=Py(r.title,r.text??``,r.tags??[]),h(),b(),T(`已载入「${r.title}」`),e.editor.focus()}catch(e){T(`读取失败:${e instanceof Error?e.message:String(e)}`)}},ee=()=>{if(e===void 0)return;if(s){b();return}s=!0,e.recentWrap.hidden=!1,e.recentWrap.textContent=``;let t=document.createElement(`div`);t.className=`dsh-tw-note-recent-muted`,t.textContent=`加载中…`,e.recentWrap.append(t),(async()=>{try{let t=await(await fetch(`${x}?limit=15`,{signal:AbortSignal.timeout(1e4)})).json().catch(()=>null);if(!s||e===void 0)return;e.recentWrap.replaceChildren();let n=[];if(t?.ok===!0)for(let e of t.items??[]){if(typeof e!=`object`||!e)continue;let t=e,r=typeof t.title==`string`?t.title:``;r.length!==0&&n.push({title:r,tags:Array.isArray(t.tags)?t.tags.filter(e=>typeof e==`string`):[],modified:typeof t.modified==`string`?t.modified:null,snippet:typeof t.snippet==`string`?t.snippet:``})}if(n.length===0){let n=document.createElement(`div`);n.className=`dsh-tw-note-recent-muted`,n.textContent=t?.ok===!0?`暂无笔记`:`加载失败:${t?.error??`未知`}`,e.recentWrap.append(n);return}for(let t of n){let n=document.createElement(`div`);n.className=`dsh-tw-note-recent-item`,n.title=t.snippet||t.title,n.setAttribute(`role`,`button`),n.tabIndex=0,n.setAttribute(`aria-label`,`载入笔记「${t.title}」`);let r=document.createElement(`span`);r.className=`dsh-tw-note-recent-name`,r.textContent=t.title;let i=document.createElement(`span`);i.className=`dsh-tw-note-recent-meta`;let a=[Ly(t.modified)];t.tags.length>0&&a.unshift(t.tags.slice(0,3).join(`,`)),i.textContent=a.join(` · `),n.append(r,i),n.addEventListener(`click`,()=>{S(t.title)}),n.addEventListener(`keydown`,e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),S(t.title))}),e.recentWrap.append(n)}}catch(t){if(!s||e===void 0)return;e.recentWrap.replaceChildren();let n=document.createElement(`div`);n.className=`dsh-tw-note-recent-muted`,n.textContent=`加载失败:${t instanceof Error?t.message:String(t)}`,e.recentWrap.append(n)}})()},te=()=>{if(e!==void 0)return;let t=document.createElement(`div`);t.className=`dsh-tw-note`,t.hidden=!0;let r=document.createElement(`div`);r.className=`dsh-tw-note-card`;let a=document.createElement(`div`);a.className=`dsh-tw-note-head`;let o=document.createElement(`span`);o.className=`dsh-tw-note-label`,o.textContent=`📝 快速笔记`;let s=document.createElement(`button`);s.type=`button`,s.className=`dsh-tw-note-close`,s.title=`收起`,s.textContent=`✕`,a.append(o,s);let d=document.createElement(`div`);d.className=`dsh-tw-note-draft`,d.hidden=!0;let f=document.createElement(`span`);f.className=`dsh-tw-note-draft-text`,f.textContent=`已恢复未保存草稿`;let g=document.createElement(`button`);g.type=`button`,g.className=`dsh-tw-note-draft-discard`,g.textContent=`丢弃`,d.append(f,g);let y=document.createElement(`div`);y.className=`dsh-tw-note-fields`;let x=document.createElement(`input`);x.className=`dsh-tw-note-title`,x.placeholder=`标题(默认时间戳)`,x.setAttribute(`aria-label`,`笔记标题(默认时间戳)`);let S=zy({onChange:m});y.append(x,S.el),x.addEventListener(`input`,m);let te,C=Sy({placeholder:`写点东西… Markdown 高亮,可 📎/拖入文件
|
|
741
741
|
Ctrl+Enter 保存`,onSave:()=>{te?.()},onChange:m}),w=document.createElement(`button`);w.type=`button`,w.className=`dsh-tw-note-upload`,w.title=`上传文件到 wiki 并插入 Markdown 链接(也可直接拖入编辑器)`,w.textContent=`📎 上传`;let ne=document.createElement(`input`);ne.type=`file`,ne.multiple=!0,ne.hidden=!0,w.addEventListener(`click`,()=>{ne.click()}),ne.addEventListener(`change`,()=>{for(let e of Array.from(ne.files??[]))By(e,C);ne.value=``});let re=0;C.el.addEventListener(`dragenter`,e=>{e.preventDefault(),re++,C.el.classList.add(`dsh-tw-note-drop`)}),C.el.addEventListener(`dragover`,e=>{e.preventDefault()}),C.el.addEventListener(`dragleave`,e=>{e.preventDefault(),re=Math.max(0,re-1),re===0&&C.el.classList.remove(`dsh-tw-note-drop`)}),C.el.addEventListener(`drop`,e=>{e.preventDefault(),re=0,C.el.classList.remove(`dsh-tw-note-drop`);let t=e.dataTransfer?.files;if(!(t===void 0||t.length===0))for(let e of Array.from(t))By(e,C)});let ie=document.createElement(`div`);ie.className=`dsh-tw-note-foot`;let ae=document.createElement(`div`);ae.className=`dsh-tw-note-foot-left`;let oe=document.createElement(`span`);oe.className=`dsh-tw-note-hint`,oe.textContent=`Ctrl+Enter`;let se=document.createElement(`button`);se.type=`button`,se.className=`dsh-tw-note-recent-btn`,se.title=`最近修改的笔记,点击载入继续编辑`,se.textContent=`🕘 最近`,se.addEventListener(`click`,ee),ae.append(w,se,oe);let ce=document.createElement(`div`);ce.className=`dsh-tw-note-foot-right`;let le=document.createElement(`button`);le.type=`button`,le.className=`dsh-tw-note-edit`,le.title=`保存并在 TiddlyWiki 原生编辑器中打开`,le.textContent=`✏️ 在 TW 中编辑`;let ue=document.createElement(`button`);ue.type=`button`,ue.className=`dsh-tw-note-save`,ue.textContent=`保存`,ce.append(le,ue),ie.append(ae,ce);let de=document.createElement(`div`);de.className=`dsh-tw-note-recent`,de.hidden=!0,r.append(a,d,y,C.el,ie),t.append(r,de),document.body.append(t),e={root:t,card:r,editor:C,titleInput:x,tagEditor:S,saveBtn:ue,editBtn:le,draftBanner:d,bannerText:f,recentWrap:de};let fe=()=>{n=!1,t.hidden=!0,b(),u(!1)},pe=()=>{Ny(),h(),l=Py(x.value.trim(),C.getValue(),S.getTags()),c=null,C.setValue(``),x.value=Iy(),S.setTags([]),fe()},me=!1;te=async()=>{if(me)return;let e=C.getValue().trim();if(e.length===0){T(`内容为空,未保存`);return}me=!0,ue.disabled=!0,ue.textContent=`保存中…`;try{let t=x.value.trim(),n={title:t,tags:S.getTags(),text:e};c!==null&&c.title===t&&(c.modified!==void 0&&(n.expectedModified=c.modified),c.revision!==void 0&&(n.expectedRevision=c.revision));let r=await fetch(v,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n),signal:AbortSignal.timeout(1e4)}),i=await r.json().catch(()=>null);if(!r.ok||i?.ok!==!0){if(r.status===409||i?.conflict===!0){T(`保存被拒绝:这篇笔记在你读取之后被改动过。请用「🕘 最近」重新载入后再保存。`);return}T(`保存失败:${i?.error??`HTTP ${r.status}`}`);return}pe(),T(`已保存「${i.title??x.value}」`)}catch(e){T(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{me=!1,ue.disabled=!1,ue.textContent=`保存`}},ue.addEventListener(`click`,()=>{te?.()});let he=async()=>{let e=x.value.trim().length>0?x.value.trim():Iy(),t=C.getValue(),n=S.getTags();le.disabled=!0,le.textContent=`打开中…`;try{await _(e,t,n)}finally{le.disabled=!1,le.textContent=`✏️ 在 TW 中编辑`}};le.addEventListener(`click`,()=>{he()}),s.addEventListener(`click`,fe);let ge=null,_e=(e,n)=>{let i=window.innerWidth,a=window.innerHeight,o=r.offsetWidth||340,s=r.offsetHeight||260,c=Math.min(Math.max(e,8),Math.max(8,i-o-8)),l=Math.min(Math.max(n,8),Math.max(8,a-s-8));t.style.right=`auto`,t.style.bottom=`auto`,t.style.left=`${c}px`,t.style.top=`${l}px`};a.addEventListener(`pointerdown`,e=>{if(s.contains(e.target))return;e.preventDefault();let n=t.getBoundingClientRect();ge={startX:e.clientX,startY:e.clientY,origLeft:n.left,origTop:n.top,moved:!1};try{a.setPointerCapture(e.pointerId)}catch{}a.classList.add(`dsh-tw-note-head-dragging`)}),a.addEventListener(`pointermove`,e=>{if(ge===null)return;let t=e.clientX-ge.startX,n=e.clientY-ge.startY;!ge.moved&&Math.abs(t)<4&&Math.abs(n)<4||(ge.moved=!0,_e(ge.origLeft+t,ge.origTop+n))});let ve=e=>{if(ge!==null){try{a.releasePointerCapture(e.pointerId)}catch{}ge=null,a.classList.remove(`dsh-tw-note-head-dragging`)}};a.addEventListener(`pointerup`,ve),a.addEventListener(`pointercancel`,ve),g.addEventListener(`click`,()=>{Ny(),h(),C.setValue(``),x.value=Iy(),S.setTags([]),T(`已丢弃草稿`)}),i=()=>{p()},window.addEventListener(`pagehide`,i)};return{async open(r){if(t||(te(),e===void 0||n))return;n=!0,e.root.hidden=!1,d(r),u(!0);let i=Ay(),o=i?.draft??null;if(o!==null&&(o.text.trim().length>0||o.title.trim().length>0))e.editor.setValue(o.text),e.titleInput.value=o.title,e.tagEditor.setTags(o.tags),e.bannerText.textContent=i?.foreign===!0?`已恢复未保存草稿(来自其它窗口)`:`已恢复未保存草稿`,e.draftBanner.hidden=!1,i?.foreign===!0&&(T(`已恢复其它窗口的未保存草稿`),jy(o));else{if(f(),a=(await Ry()).defaultTag,t||e===void 0)return;e.tagEditor.setDefault(a)}e!==void 0&&e.editor.focus()},close(){e!==void 0&&(n=!1,e.root.hidden=!0,b(),u(!1))},async openNative(){if(!(t||r||bt())){r=!0;try{let e=Ay(),n=e!==null&&(e.draft.text.trim().length>0||e.draft.title.trim().length>0),r=n&&e.draft.title.trim().length>0?e.draft.title.trim():Iy(),i=n?e.draft.text:``,o=[];if(n)o=e.draft.tags;else{if(a=(await Ry()).defaultTag,t)return;o=[a]}e!==null&&e.foreign&&(e.draft.text.trim().length>0||e.draft.title.trim().length>0)&&(T(`已恢复其它窗口的未保存草稿`),jy(e.draft)),await _(r,i,o)}finally{r=!1}}},isOpen(){return n},dispose(){t=!0,i!==void 0&&(window.removeEventListener(`pagehide`,i),i=void 0),o!==void 0&&(clearTimeout(o),o=void 0),p(),e?.tagEditor.dispose(),e?.editor.view.destroy(),e?.root.remove(),e=void 0}}}function Hy(e){return e<10?`0${e}`:String(e)}function Uy(e){return`${Hy(e.getHours())}:${Hy(e.getMinutes())}`}function Wy(e,t){let n=e?.git,r=[`同步知识库`],i=`offline`,a=`离线`;if(n==null||n.exists!==!0)r.push(`git 仓库不可用`);else{r.push(`分支 ${n.branch??`?`}`),typeof n.lastCommit==`string`&&r.push(n.lastCommit);let e=typeof n.behind==`number`?n.behind:0,t=typeof n.ahead==`number`?n.ahead:0;t>0&&r.push(`领先 ${t}`),e>0&&r.push(`落后 ${e}`),n.dirty===!0?(i=`dirty`,a=`待提交`,r.push(`有 ${n.dirtyFiles?.length??0} 个未提交改动`)):e>0?(i=`behind`,a=`可更新`):(i=`clean`,a=`已同步`)}return t!==void 0&&r.push(`上次同步 ${Uy(t)}`),{state:i,label:a,tooltip:r.join(` · `),...t===void 0?{}:{lastSync:t}}}function Gy(){let e={state:`offline`,label:`离线`,tooltip:`同步知识库`},t,n,r=!1,i=!1,a=new Set,o=()=>{for(let e of[...a])e()},s=n=>{if(r)return;let i=Wy(n,t);(i.state!==e.state||i.tooltip!==e.tooltip)&&(e=i,o())},c=async()=>{if(i)return;let e=await me();i||s(e)};return c(),n=window.setInterval(()=>{c()},3e4),{getState:()=>e,trigger:async()=>{if(i)return e;if(r)return T(`同步进行中…`),e;r=!0,e={...e,state:`syncing`,label:`同步中…`},o();try{let e=await fetch(te,{method:`POST`,signal:AbortSignal.timeout(12e4)}),n=await e.json().catch(()=>null);if(n===null||n.ok!==!0)T(`同步失败:${n?.error??n?.message??`HTTP ${e.status}`}`);else{t=new Date;let e=``;n.push&&n.push!==`nothing to commit`&&(e=`(${n.push})`),n.changed===!0&&(e+=n.restarted===!0?`,TW 已重启`:`,TW 未自动重启`,n.restartError&&(e+=`(${n.restartError})`)),T(`同步完成:${n.message??`OK`}${e}`)}}catch(e){T(`同步失败:${e instanceof Error?e.message:String(e)}`)}finally{r=!1,await c()}return e},subscribe(e){return a.add(e),()=>{a.delete(e)}},dispose(){i=!0,n!==void 0&&(clearInterval(n),n=void 0),a.clear()}}}const Ky={showQuickNoteDock:!0,quickNoteMode:`native`,sidebarLabel:`TiddlyWiki`,tabLabel:`知识库`,showSessionTab:!0,showRightbarTab:!0};let qy;function Jy(){qy=void 0,he()}function Yy(){if(qy!==void 0&&Date.now()-qy.at<15e3)return qy.value;let e=(async()=>{let e=await me(),t=e?.ui;return e===null||t===void 0?Ky:{showQuickNoteDock:t.showQuickNoteDock!==!1,quickNoteMode:t.quickNoteMode===`card`?`card`:`native`,sidebarLabel:typeof t.sidebarLabel==`string`&&t.sidebarLabel.trim().length>0?t.sidebarLabel.trim():`TiddlyWiki`,tabLabel:typeof t.tabLabel==`string`&&t.tabLabel.trim().length>0?t.tabLabel.trim():`知识库`,showSessionTab:t.showSessionTab!==!1,showRightbarTab:t.showRightbarTab!==!1}})();return qy={at:Date.now(),value:e},e}async function Xy(){let e=await me();return{showQuickNote:e?.ui?.showQuickNote!==!1,showPanelStatus:e?.ui?.showPanelStatus!==!1,showSyncButton:e?.ui?.showSyncButton!==!1}}async function Zy(){let e=await me();if(e===null)return{state:`failed`,text:`状态不可达`,logs:[]};let t=Array.isArray(e.logs)?e.logs.filter(e=>typeof e==`string`):[];return e.status===`running`?{state:`running`,text:`TW 在线 · ${e.url??``}`,logs:t}:e.status===`starting`?{state:`starting`,text:`TW 启动中…`,logs:t}:{state:`failed`,text:e.error??`TW 状态:${e.status??`?`}`,logs:t}}function Qy(e,t,n){let r=!1,i,a,o,s,c,l,u,d,f=!1,p={state:`unknown`,text:`TiddlyWiki 服务…`,logs:[]},m=()=>{f=!1,s!==void 0&&(s.hidden=!0),u!==void 0&&(u.hidden=!0)},h=e=>{if(!f)return;let t=e.target;i!==void 0&&i.contains(t)||m()},g=()=>{if(u===void 0)return;let e=[`TiddlyWiki 服务:${p.text}`];e.push(`知识库同步:${n.getState().tooltip}`),p.logs.length>0&&(e.push(`最近日志:`),e.push(...p.logs.slice(-3))),u.textContent=e.join(`
|
|
742
|
-
`)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await Zy(),!r&&(c!==void 0&&(c.textContent=p.text),l!==void 0&&(l.dataset.state=p.state),g())},y=p=>{if(r)return;if(i=document.createElement(`div`),i.className=`dsh-tw-fab-wrap`,s=document.createElement(`div`),s.className=`dsh-tw-fab-menu`,s.hidden=!0,p.showPanelStatus){let e=document.createElement(`div`);e.className=`dsh-tw-fab-status dsh-tw-fab-status-tiprow`,l=document.createElement(`span`),l.className=`dsh-tw-fab-status-dot`,l.dataset.state=`unknown`,c=document.createElement(`span`),c.className=`dsh-tw-fab-status-text`,c.textContent=`TiddlyWiki 服务…`,e.append(l,c),u=document.createElement(`div`),u.className=`dsh-tw-fab-tip`,u.hidden=!0,e.append(u),e.addEventListener(`mouseenter`,()=>{g(),u!==void 0&&(u.hidden=!1)}),e.addEventListener(`mouseleave`,()=>{u!==void 0&&(u.hidden=!0)}),s.append(e)}if(p.showQuickNote){let e=document.createElement(`button`);e.type=`button`,e.className=`dsh-tw-fab-item`,e.textContent=`📝 快速笔记`,e.title=`ui.quickNoteMode=native 时直接打开 TW 原生编辑器;card 时打开 Markdown 卡片`,e.addEventListener(`click`,()=>{m(),Yy().then(e=>{e.quickNoteMode===`native`?t.openNative():t.open()})}),s.append(e)}if(p.showPanelStatus){d=document.createElement(`span`),d.textContent=`打开 TW 面板`;let t=document.createElement(`button`);t.type=`button`,t.className=`dsh-tw-fab-item`,t.append(document.createTextNode(`🖥 `),d),t.addEventListener(`click`,()=>{m(),e.toggle()}),s.append(t);let n=document.createElement(`button`);n.type=`button`,n.className=`dsh-tw-fab-item`,n.textContent=`🔄 重载 TW 面板`,n.addEventListener(`click`,()=>{m(),document.dispatchEvent(new CustomEvent(He)),v()}),s.append(n)}if(p.showSyncButton){let e=document.createElement(`button`);e.type=`button`,e.className=`dsh-tw-fab-item`,e.textContent=`🔁 同步`,e.addEventListener(`click`,()=>{m(),n.trigger()}),s.append(e)}a=document.createElement(`button`),a.type=`button`,a.className=`dsh-tw-fab`,a.setAttribute(`aria-label`,`TiddlyWiki 知识库`);let y=document.createElement(`span`);y.className=`dsh-tw-fab-icon`,y.innerHTML=`<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 2.5h8a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1z"/><path d="M6 6h4M6 8.5h2.5"/></svg>`,o=document.createElement(`span`),o.className=`dsh-tw-fab-dot`,o.dataset.state=n.getState().state,a.append(y,o),a.addEventListener(`click`,()=>{if(s!==void 0){if(f){m();return}f=!0,s.hidden=!1,_(),v()}}),i.append(s,a),document.body.append(i),_(),document.addEventListener(`click`,h,!0)},b=e.subscribe(()=>{d!==void 0&&(d.textContent=e.isOpen()?`收起 TW 面板`:`打开 TW 面板`)}),x=n.subscribe(_);return(async()=>{let e=await Xy();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),b(),x(),i?.remove()}}function $y(e){return function(){let[t,n]=c.useState(!1),[r,i]=c.useState(null),a=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{let e=!0,t=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(Cy,t),Yy().then(t=>{e&&i(t.quickNoteMode)}),()=>{e=!1,window.removeEventListener(Cy,t)}},[]),c.useLayoutEffect(()=>{let e=a.current;if(e===null)return;let t=()=>{let t=null,n=null,r=e;for(;r!==null&&r!==document.documentElement&&(r=r.parentElement,r!==null);){for(let e of r.querySelectorAll(`textarea, [contenteditable]:not([contenteditable="false"]), [role="textbox"]`))if(e.getBoundingClientRect().width>300){t=e,n=r;break}if(n!==null)break}if(t===null||n===null)return null;let i=n.getBoundingClientRect().width,a=t,o=null,s=0;for(;a!==null&&a!==n;){let e=a.getBoundingClientRect().width;e>0&&e<i-8&&e>=s&&(s=e,o=a),a=a.parentElement}return o},n=()=>{let n=e.getBoundingClientRect(),r=t(),i=r===null?n.right:r.getBoundingClientRect().right,a=Math.max(0,n.right-i);return e.style.paddingRight!==`${a}px`&&(e.style.paddingRight=`${a}px`),r!==null};n();let r=new ResizeObserver(n),i=e;for(;i!==null&&i!==document.documentElement&&(r.observe(i),!(i instanceof HTMLElement&&i.hasAttribute(`data-phase`)));)i=i.parentElement;window.addEventListener(`resize`,n),document.addEventListener(`visibilitychange`,n);let o=0,s=0,c=window.setInterval(()=>{if(s++,!n()){s>=20&&window.clearInterval(c);return}o++,o>=3&&window.clearInterval(c)},1500),l=window.setTimeout(n,120),u=window.setTimeout(n,600);return()=>{r.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`visibilitychange`,n),window.clearInterval(c),window.clearTimeout(l),window.clearTimeout(u)}},[]);let s=r===`native`,l=s?`快速笔记`:t?`快速笔记(已打开)`:`快速笔记`,u=s?`快速笔记:直接打开 TiddlyWiki 原生编辑器(再次点击可收起弹窗)`:t?`快速笔记已打开(点此按钮或卡片右上角 ✕ 收起)`:`打开快速笔记(在按钮上方弹出,可拖动标题栏移动)`;return c.createElement(`div`,{ref:a,className:`dsh-tw-dock-note`},c.createElement(`button`,{ref:o,type:`button`,className:t?`dsh-tw-dock-note-btn dsh-tw-dock-note-btn-active`:`dsh-tw-dock-note-btn`,title:u,onClick:()=>{Yy().then(t=>{t.quickNoteMode===`native`?bt()?St():e.openNative():e.isOpen()?e.close():e.open(o.current??void 0)})}},c.createElement(`span`,{className:`dsh-tw-dock-note-icon`,"aria-hidden":`true`},`📝`),c.createElement(`span`,{className:`dsh-tw-dock-note-label`},l)))}}function eb(){return Ge()}async function tb(e){try{let t=await fetch(_,{method:`POST`,headers:{"content-type":`application/json`,"x-requested-with":`TiddlyWiki`},body:JSON.stringify({title:e}),signal:AbortSignal.timeout(15e3)});if(!t.ok)return null;let n=await t.text();return n.length>0?n:null}catch{return null}}async function nb(e){try{let t=await fetch(`${g}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function rb(e){let{sessionId:t,viewRequest:n,completeViewRequest:r}=e,[i,a]=c.useState(`loading`),[o,s]=c.useState(null),[l,u]=c.useState(null),[d,f]=c.useState(``),p=c.useRef(0),m=c.useRef(!0),h=c.useRef(0),_=c.useCallback(async()=>{let e=++p.current;if(m.current){if(a(`loading`),typeof t!=`string`||t.length===0){a(`error`),f(`缺少会话 ID`);return}if(h.current>=3){a(`error`),f(`连续 3 次生成失败,已停止自动重试,请点「🔄 刷新」`);return}try{let n=await fetch(w,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(!m.current||e!==p.current)return;if(!n.ok||r?.ok!==!0){h.current++,a(`error`),f(r?.error??`HTTP ${n.status}`);return}if(typeof r.title!=`string`||r.title.length===0){h.current++,a(`error`),f(`汇总生成失败:缺少标题`);return}u(r.title);let i=await tb(r.title);if(!m.current||e!==p.current)return;if(i===null){let t=await nb(r.title);if(!m.current||e!==p.current)return;if(!t){if(h.current++,h.current<3){_();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(host /render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(!m.current||e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}}},[t]);c.useEffect(()=>(m.current=!0,_(),()=>{m.current=!1}),[_]),c.useEffect(()=>{if(i!==`ready`||l===null)return;let e=!0,t=window.setInterval(()=>{(async()=>{if(!e)return;let t=!1;try{let e=await fetch(`${g}?title=${encodeURIComponent(l)}`,{signal:AbortSignal.timeout(8e3)}),n=await e.json().catch(()=>null);t=e.status!==404&&n?.notFound!==!0}catch{return}if(e)if(t)h.current=0;else{if(h.current++,h.current<3){_();return}a(`error`),f(`汇总条目已失效且自动重建多次失败,请点「🔄 刷新」重试`)}})()},3e4);return()=>{e=!1,window.clearInterval(t)}},[i,l,_]),c.useEffect(()=>{n!=null&&r?.()},[n,r]);let v=()=>{h.current=0,_()},y;return y=i===`loading`?c.createElement(`div`,{className:`dsh-tw-summary-state`},c.createElement(`div`,{className:`dsh-tw-summary-state-spin`},`⏳`),c.createElement(`div`,null,`正在生成会话 wiki 汇总…`)):i===`error`?c.createElement(`div`,{className:`dsh-tw-summary-state`},c.createElement(`div`,{className:`dsh-tw-summary-state-title`},`知识库汇总暂不可用`),c.createElement(`div`,{className:`dsh-tw-summary-state-detail`},d),c.createElement(`button`,{type:`button`,className:`dsh-tw-summary-btn`,onClick:v},`重试`)):c.createElement(`div`,{className:`dsh-tw-summary-native dsh-tw-toolcard-native`,dangerouslySetInnerHTML:{__html:o??``}}),c.createElement(`div`,{className:`dsh-tw-summary`,"data-dsh-tw-summary":`true`},c.createElement(`div`,{className:`dsh-tw-summary-bar`},c.createElement(`span`,{className:`dsh-tw-summary-bar-title`},`📚 本会话知识库`),c.createElement(`span`,{className:`dsh-tw-summary-bar-hint`},`产生 / 读取 / 检索过的笔记(含子代理)`),c.createElement(`span`,{className:`dsh-tw-summary-bar-spacer`}),c.createElement(`button`,{type:`button`,className:`dsh-tw-summary-btn`,onClick:v,disabled:i===`loading`,title:`重新生成并刷新汇总`},`🔄 刷新`)),y)}function ib(e,t){if(!(e===void 0||t.showSessionTab===!1))return We(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:eb},rb))}function $(e,t,n){let r=document.createElement(e);return t!==void 0&&(r.className=t),n!==void 0&&(r.textContent=n),r}async function ab(e,t){let n=await fetch(e,{...t,signal:AbortSignal.timeout(15e3)}),r=await n.json().catch(()=>({}));if(!n.ok){let e=r.error??`HTTP ${n.status}`;throw Error(e)}return r}function ob(e){let t=!1;e.classList.add(`dsh-tw-settings`);let n=$(`div`,`dsh-tw-settings-row dsh-tw-settings-status`),r=$(`div`,`dsh-tw-settings-body`);e.append(n,r);let i=[],a={},o=async()=>{try{let e=await ab(ne);if(t)return;sb(n,e,o),fb(r,e,o,()=>t,a)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),a=$(`button`,`dsh-tw-settings-btn`,`重试`);a.type=`button`,a.addEventListener(`click`,()=>{o()}),r.append(i,a)}};return o(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function sb(e,t,n){e.replaceChildren();let r=t.server??{},i=r.status??`unknown`,a=$(`span`,`dsh-tw-settings-chip`,i);a.dataset.state=i;let o=$(`span`,`dsh-tw-settings-muted`,[r.url===void 0?``:`TW ${r.url}`,t.git?.branch===void 0?``:`git ${t.git.branch}`,t.git?.lastCommit===void 0?``:t.git.lastCommit,t.git?.dirty===!0?`有未提交改动`:``].filter(Boolean).join(` · `)),s=$(`button`,`dsh-tw-settings-btn`,`同步`);s.type=`button`,s.title=`git 同步(pull → commit → push)`,s.addEventListener(`click`,()=>{s.disabled=!0,s.textContent=`同步中…`,(async()=>{try{let e=await fetch(te,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=await e.json().catch(()=>null);if(!e.ok||t?.ok!==!0)T(`同步失败:${t?.error??t?.message??`HTTP ${e.status}`}`);else{let e=``;t.changed===!0&&(e+=t.restarted===!0?`,TW 已重启`:`,TW 未自动重启`,t.restartError&&(e+=`(${t.restartError})`)),T(`同步完成:${t.message??`OK`}${e}`)}}catch(e){T(`同步失败:${e instanceof Error?e.message:String(e)}`)}finally{s.disabled=!1,s.textContent=`同步`,n()}})()});let c=$(`button`,`dsh-tw-settings-btn`,`重启 TW`);c.type=`button`,c.addEventListener(`click`,()=>{c.disabled=!0,c.textContent=`重启中…`,(async()=>{try{await ab(oe,{method:`POST`}),T(`TW 已重启`)}catch(e){T(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function cb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`常规配置`));let i=t.note??{},a=t.git??{},o=t.ui??{},s=[],c=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.value=n;let a=$(`label`,`dsh-tw-settings-field`);a.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:()=>i.value.trim(),changed:()=>i.value.trim()!==n}),r.append(a)},l=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-check`);i.type=`checkbox`,i.checked=n;let a=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-check`);a.append(i,$(`span`,`dsh-tw-settings-label`,t)),s.push({key:e,initial:n,read:()=>i.checked,changed:()=>i.checked!==n}),r.append(a)},u=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.type=`number`,i.value=String(n);let a=()=>{let e=i.value.trim();if(e.length===0)return n;let t=Number(e);return Number.isFinite(t)?t:n},o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:a,changed:()=>a()!==n}),r.append(o)},d=(e,t,n,i)=>{let a=$(`select`,`dsh-tw-settings-input`);for(let e of i){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,e.value===n&&(t.selected=!0),a.append(t)}let o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o)},f=(e,t,n,i)=>{let a=$(`textarea`,`dsh-tw-settings-input dsh-tw-settings-area`);a.rows=i,a.value=n;let o=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-area`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value.trim(),changed:()=>a.value.trim()!==n}),r.append(o),a};c(`note.tag`,`快速笔记默认 tag`,typeof i.tag==`string`?i.tag:`inbox`),l(`git.autoCommit`,`自动 commit(防抖)`,a.autoCommit!==!1),u(`git.debounceMs`,`自动 commit 防抖(ms)`,typeof a.debounceMs==`number`?a.debounceMs:6e4),c(`git.remote`,`git 远端(空=仅本地)`,typeof a.remote==`string`?a.remote:``),c(`git.branch`,`git 分支`,typeof a.branch==`string`?a.branch:`main`),l(`ui.showQuickNote`,`显示「知识库」按钮里的「快速笔记」入口`,o.showQuickNote!==!1),l(`ui.showQuickNoteDock`,`显示聊天输入框上方的「快速笔记」快捷按钮`,o.showQuickNoteDock!==!1),d(`ui.quickNoteMode`,`点击「快速笔记」的打开方式`,typeof o.quickNoteMode==`string`&&o.quickNoteMode===`card`?`card`:`native`,[{value:`native`,label:`原生编辑器:直接弹出 TW 原生编辑页(新建/恢复草稿)`},{value:`card`,label:`Markdown 卡片:弹出现有快速笔记卡片(CodeMirror 编辑器)`}]),c(`ui.sidebarLabel`,`侧边栏 TW 入口显示名称`,typeof o.sidebarLabel==`string`&&o.sidebarLabel.trim().length>0?o.sidebarLabel.trim():`TiddlyWiki`),l(`ui.showPanelStatus`,`显示「知识库」按钮里的 TW 面板/重载入口与状态行`,o.showPanelStatus!==!1),l(`ui.showSyncButton`,`显示「知识库」按钮里的「同步」入口与 git 状态点`,o.showSyncButton!==!1),l(`ui.followDshTheme`,`嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)`,o.followDshTheme!==!1),c(`ui.darkPalette`,`暗色时 TW palette(tiddler 标题)`,typeof o.darkPalette==`string`&&o.darkPalette.trim().length>0?o.darkPalette.trim():`$:/palettes/CupertinoDark`),c(`ui.tabLabel`,`会话顶部「知识库」Tab 名称`,typeof o.tabLabel==`string`&&o.tabLabel.trim().length>0?o.tabLabel.trim():`知识库`),l(`ui.showSessionTab`,`显示会话顶部「知识库」Tab(本会话相关 wiki 笔记汇总)`,o.showSessionTab!==!1),l(`ui.showRightbarTab`,`在 DSH 右侧边栏提供 TiddlyWiki 入口/Tab(与聊天并排)`,o.showRightbarTab!==!1);let p=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,p.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof p.endpoint==`string`?p.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头;已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof p.token==`string`?p.token:``);let m=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof m.pageSize==`number`?m.pageSize:10);let h=t.prompt??{};r.append($(`h3`,`dsh-tw-settings-h`,`系统提示词(注入每个会话)`)),r.append($(`div`,`dsh-tw-settings-muted`,`插件把自己的约定(同步纪律 / 标签约定 / 链接格式等)注入每个会话的系统提示词。保存后**无需重启 dsh web**:section 会即时重新注册,当前会话从下一步起就使用新文本。`)),l(`prompt.enabled`,`注入 TiddlyWiki 提示词(关闭后本插件不再注入任何文本)`,h.enabled!==!1),d(`prompt.mode`,`内置文本形态`,h.mode===`full`?`full`:`slim`,[{value:`slim`,label:`精简(默认):只保留工具 schema 表达不了的约定`},{value:`full`,label:`完整:额外附一份由工具注册表实时生成的参数索引`}]),f(`prompt.extra`,`附加说明(永远追加在末尾,可放团队/个人规范)`,typeof h.extra==`string`?h.extra:``,5),f(`prompt.override`,`整段替换(非空时取代上面的内置文本,附加说明仍会追加)`,typeof h.override==`string`?h.override:``,8);let g=$(`button`,`dsh-tw-settings-btn`,`查看当前注入文本`);g.type=`button`,g.title=`读取 host 端实时生成的提示词全文(保存后即为下一步注入的内容)`;let _=$(`pre`,`dsh-tw-settings-prompt-preview`);_.hidden=!0,g.addEventListener(`click`,()=>{if(!_.hidden){_.hidden=!0,_.textContent=``;return}g.disabled=!0,(async()=>{try{let e=await ab(re);if(e.ok!==!0)throw Error(e.error??`获取失败`);_.textContent=e.enabled===!1?`(已关闭:不会注入任何提示词)`:`# 形态 ${e.mode??``} · ${e.length??0} 字符\n\n${e.text??``}`,_.hidden=!1}catch(e){T(`读取提示词失败:${e instanceof Error?e.message:String(e)}`)}finally{g.disabled=!1}})()}),r.append(g,_);let v=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,v.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof v.port==`number`&&v.port>0?v.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置。已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof v.token==`string`?v.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof v.tag==`string`&&v.tag.trim().length>0?v.tag.trim():`clip`);let y=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);y.type=`button`,y.addEventListener(`click`,()=>{y.disabled=!0,(async()=>{let e={};for(let t of s){if(!t.changed())continue;let n=t.key.split(`.`),r=e;for(let e=0;e<n.length;e++){let i=n[e];if(i===void 0)break;if(e===n.length-1)r[i]=t.read();else{let e=r[i]??{};r[i]=e,r=e}}}try{await ab(ae,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),Jy(),T(`配置已保存`),n()}catch(e){T(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{y.disabled=!1}})()}),r.append(y),e.append(r)}function lb(e,t,n,r){let i=n?.plugins??[],a=n?.themes??[],o=n?.languages??[],s=new Set(t?.plugins??[]),c=new Set(t?.themes??[]),l=new Set(t?.languages??[]),u=$(`section`,`dsh-tw-settings-section`);u.append($(`h3`,`dsh-tw-settings-h`,`插件管理(自带官方插件)`));let d=$(`input`,`dsh-tw-settings-input dsh-tw-settings-search`);d.placeholder=`搜索插件…`;let f=$(`div`,`dsh-tw-settings-list`),p=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用插件(重启 TW)`);p.type=`button`;let m=e=>{f.replaceChildren();let t=e.toLowerCase();for(let e of i){if(t.length>0&&!`${e.label} ${e.name} ${e.description}`.toLowerCase().includes(t))continue;let n=$(`input`,`dsh-tw-settings-check`);n.type=`checkbox`,n.checked=s.has(e.name),n.addEventListener(`change`,()=>{n.checked?s.add(e.name):s.delete(e.name)});let r=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),i=$(`span`,`dsh-tw-settings-name`,e.label);i.title=e.name;let a=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);r.append(n,i,a),f.append(r)}};d.addEventListener(`input`,()=>m(d.value)),p.addEventListener(`click`,()=>{p.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),T(`插件已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),p.disabled=!1}})()}),m(``),u.append(d,f,p),e.append(u);let h=$(`section`,`dsh-tw-settings-section`);h.append($(`h3`,`dsh-tw-settings-h`,`主题管理(自带主题)`));let g=$(`div`,`dsh-tw-settings-muted`,`「加载」= TW 里可用的主题(可多选,依赖链自动带上,如 heavier 会带 snowwhite+vanilla);「活动」= 当前视觉主题(单选,自动加入加载集)。应用后重启 TW。`),_=$(`div`,`dsh-tw-settings-row dsh-tw-settings-head`);_.append($(`span`,`dsh-tw-settings-col`,`加载`),$(`span`,`dsh-tw-settings-col`,`活动`),$(`span`,`dsh-tw-settings-name`,`主题`));let v=t?.themes??[],y=t?.themeActive,b=typeof y==`string`&&a.some(e=>e.name===y)?y:v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,x=$(`div`,`dsh-tw-settings-list`);for(let e of a){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=c.has(e.name),t.title=`加载该主题`,t.addEventListener(`change`,()=>{t.checked?c.add(e.name):c.delete(e.name)});let n=$(`input`,`dsh-tw-settings-check`);n.type=`radio`,n.name=`dsh-tw-active-theme`,n.checked=e.name===b,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(b=e.name)});let r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name),a=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);a.append(t,n,r,i),x.append(a)}let S=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);S.type=`button`,S.addEventListener(`click`,()=>{S.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:b})}),T(`主题已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),S.disabled=!1}})()}),h.append(g,_,x,S),e.append(h);let ee=$(`section`,`dsh-tw-settings-section`);ee.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let te=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),C=$(`div`,`dsh-tw-settings-list`);for(let e of o){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=l.has(e.name),t.addEventListener(`change`,()=>{t.checked?l.add(e.name):l.delete(e.name)});let n=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);n.append(t,r,i),C.append(n)}let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);w.type=`button`,w.addEventListener(`click`,()=>{w.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),T(`语言已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),w.disabled=!1}})()}),ee.append(te,C,w),e.append(ee)}function ub(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`知识库位置(可切换)`));let i=$(`div`,`dsh-tw-settings-muted`,`读取中…`),a=$(`div`,`dsh-tw-settings-muted`),o=$(`div`,`dsh-tw-settings-muted`),s=$(`div`,`dsh-tw-settings-muted`),c=$(`input`,`dsh-tw-settings-input`),l=$(`input`,`dsh-tw-settings-input`);c.placeholder=`绝对路径,如 D:\\notes 或 $DSH_HOME/tiddlywiki`,l.placeholder=`文件夹名(默认 main;填 . 表示直接用上面这个目录)`;let u=$(`label`,`dsh-tw-settings-field`);u.append($(`span`,`dsh-tw-settings-label`,`根目录(wikiRoot)`),c);let d=$(`label`,`dsh-tw-settings-field`);d.append($(`span`,`dsh-tw-settings-label`,`文件夹名(wiki)`),l);let f=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`切换到这个位置`);f.type=`button`;let p=$(`button`,`dsh-tw-settings-btn`,`恢复为配置默认`);p.type=`button`;let m=$(`div`,`dsh-tw-settings-row`);m.append(f,p);let h=$(`div`,`dsh-tw-settings-row dsh-tw-settings-candidates`),g=$(`div`,`dsh-tw-settings-muted`,"切换会停掉并就地重启 TW 子进程(几秒);新目录若还没有 tiddlywiki.info,插件会自动 `--init server` 初始化一个全新知识库。选中的位置会记在 $DSH_HOME 下的指针文件里(不进 wiki),可用「恢复为配置默认」清除。"),_=(e,t)=>{f.disabled=e,p.disabled=e,f.textContent=e?t:`切换到这个位置`},v=async()=>{if(!t())try{let e=await ab(ue);if(t())return;if(e.ok!==!0)throw Error(e.error??`获取失败`);let n=e.current??{};i.textContent=`当前:${n.path??`(未知)`}`;let r=n.source===`state`?`来源:指针文件(在设置页切换过)`:n.source===`config`?`来源:cordis 配置(config.wikiRoot / config.wiki)`:`来源:默认值($DSH_HOME/tiddlywiki + main)`;a.textContent=`${r} · 配置默认:${e.default?.path??`(未知)`}`,o.textContent=e.stateFile===void 0?``:`指针文件:${e.stateFile}(不存在=使用配置默认)`,s.textContent=e.error===void 0?``:`⚠️ ${e.error}`,c.value.length===0&&typeof n.root==`string`&&(c.value=n.root),l.value.length===0&&typeof n.name==`string`&&(l.value=n.name),h.replaceChildren();let u=e.candidates??[];if(u.length>0){h.append($(`span`,`dsh-tw-settings-label`,`同目录下可选的 wiki:`));for(let e of u){let t=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-chipbtn`,e===`.`?`(根目录本身)`:e);t.type=`button`,t.title=`填入文件夹名「${e}」`,t.addEventListener(`click`,()=>{l.value=e}),h.append(t)}}}catch(e){if(t())return;i.textContent=`读取位置失败:${e instanceof Error?e.message:String(e)}`}};f.addEventListener(`click`,()=>{let e=c.value.trim(),t=l.value.trim().length>0?l.value.trim():`main`;if(e.length===0){T(`请先填写根目录(绝对路径)`);return}window.confirm(`切换知识库到:\n${e}\\${t}\n\n会停止并重启 TW 子进程;当前对话/工具随后读写的是新知识库。确定继续?`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let r=await ab(de,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({root:e,name:t}),signal:AbortSignal.timeout(12e4)});r.warning===void 0?T(`已切换到 ${r.path??``}`):T(`已切换到 ${r.path??``}(注意:${r.warning})`),Jy(),await v(),await n()}catch(e){T(`切换失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),p.addEventListener(`click`,()=>{window.confirm(`恢复为配置默认位置?会删除位置指针文件,并(必要时)切回配置里的知识库。`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let e=await ab(fe,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`,signal:AbortSignal.timeout(12e4)});T(e.warning===void 0?`已恢复为配置默认:${e.path??``}`:`已恢复默认(注意:${e.warning})`),Jy(),await v(),await n()}catch(e){T(`恢复失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),r.append(i,a,o,u,d,m,h,s,g),e.append(r),v()}function db(e,t){let n=$(`section`,`dsh-tw-settings-section`);n.append($(`h3`,`dsh-tw-settings-h`,`初始化(一次性预置)`));let r=$(`div`,`dsh-tw-settings-muted`,`这些是插件与 dsh 联动、需要在 wiki 里预置的 tiddler/配置。「发送给 Agent 按钮」和「TW 前端 API 基址」是功能必需项,启动时自动写入(只写缺失,不覆盖你的改动);其余为可选项,默认不自动写入、也不会强绑定——需要时点「重新初始化」写入,不想要了可随时「反初始化」移除。`),i=$(`div`,`dsh-tw-settings-list`),a=$(`div`,`dsh-tw-settings-muted`),o=async()=>{if(!t())try{let e=await ab(se);if(t())return;if(e.ok!==!0||!Array.isArray(e.items))throw Error(e.error??`获取失败`);i.replaceChildren();let n=0,r=0;for(let t of e.items){t.present&&(n+=1),t.removable&&(r+=1);let e=$(`span`,`dsh-tw-settings-chip`,t.present?`✓`:`✗`);e.dataset.state=t.present?`ok`:`missing`,e.title=t.present?`已存在`:`缺失`;let a=$(`span`,`dsh-tw-settings-name`,t.title);a.title=t.id;let s=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),c=t.updateAvailable===!0?$(`span`,`dsh-tw-settings-chip`,`⬆ 有更新`):void 0;c!==void 0&&(c.dataset.state=`update`,c.title=`内置内容在本 wiki 预置之后更新过,可点「重新初始化」取用`);let l=t.userModified===!0?$(`span`,`dsh-tw-settings-chip`,`✏️ 本地已修改`):void 0;l!==void 0&&(l.dataset.state=`missing`,l.title=`这篇是你的内容:重新初始化会覆盖它`);let u=$(`button`,`dsh-tw-settings-btn`,t.updateAvailable===!0?`更新到内置版本`:`重新初始化`);u.type=`button`,u.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,u.addEventListener(`click`,()=>{if(t.updateAvailable===!0){let e=t.userModified===!0?`「${t.title}」有你的本地修改,更新会覆盖它。`:t.userModified===void 0?`无法确认「${t.title}」是否被你编辑过(旧格式标记),更新可能覆盖你的改动。`:``;if(!window.confirm(`${e}${e.length>0?`
|
|
742
|
+
`)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await Zy(),!r&&(c!==void 0&&(c.textContent=p.text),l!==void 0&&(l.dataset.state=p.state),g())},y=p=>{if(r)return;if(i=document.createElement(`div`),i.className=`dsh-tw-fab-wrap`,s=document.createElement(`div`),s.className=`dsh-tw-fab-menu`,s.hidden=!0,p.showPanelStatus){let e=document.createElement(`div`);e.className=`dsh-tw-fab-status dsh-tw-fab-status-tiprow`,l=document.createElement(`span`),l.className=`dsh-tw-fab-status-dot`,l.dataset.state=`unknown`,c=document.createElement(`span`),c.className=`dsh-tw-fab-status-text`,c.textContent=`TiddlyWiki 服务…`,e.append(l,c),u=document.createElement(`div`),u.className=`dsh-tw-fab-tip`,u.hidden=!0,e.append(u),e.addEventListener(`mouseenter`,()=>{g(),u!==void 0&&(u.hidden=!1)}),e.addEventListener(`mouseleave`,()=>{u!==void 0&&(u.hidden=!0)}),s.append(e)}if(p.showQuickNote){let e=document.createElement(`button`);e.type=`button`,e.className=`dsh-tw-fab-item`,e.textContent=`📝 快速笔记`,e.title=`ui.quickNoteMode=native 时直接打开 TW 原生编辑器;card 时打开 Markdown 卡片`,e.addEventListener(`click`,()=>{m(),Yy().then(e=>{e.quickNoteMode===`native`?t.openNative():t.open()})}),s.append(e)}if(p.showPanelStatus){d=document.createElement(`span`),d.textContent=`打开 TW 面板`;let t=document.createElement(`button`);t.type=`button`,t.className=`dsh-tw-fab-item`,t.append(document.createTextNode(`🖥 `),d),t.addEventListener(`click`,()=>{m(),e.toggle()}),s.append(t);let n=document.createElement(`button`);n.type=`button`,n.className=`dsh-tw-fab-item`,n.textContent=`🔄 重载 TW 面板`,n.addEventListener(`click`,()=>{m(),document.dispatchEvent(new CustomEvent(He)),v()}),s.append(n)}if(p.showSyncButton){let e=document.createElement(`button`);e.type=`button`,e.className=`dsh-tw-fab-item`,e.textContent=`🔁 同步`,e.addEventListener(`click`,()=>{m(),n.trigger()}),s.append(e)}a=document.createElement(`button`),a.type=`button`,a.className=`dsh-tw-fab`,a.setAttribute(`aria-label`,`TiddlyWiki 知识库`);let y=document.createElement(`span`);y.className=`dsh-tw-fab-icon`,y.innerHTML=`<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 2.5h8a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1z"/><path d="M6 6h4M6 8.5h2.5"/></svg>`,o=document.createElement(`span`),o.className=`dsh-tw-fab-dot`,o.dataset.state=n.getState().state,a.append(y,o),a.addEventListener(`click`,()=>{if(s!==void 0){if(f){m();return}f=!0,s.hidden=!1,_(),v()}}),i.append(s,a),document.body.append(i),_(),document.addEventListener(`click`,h,!0)},b=e.subscribe(()=>{d!==void 0&&(d.textContent=e.isOpen()?`收起 TW 面板`:`打开 TW 面板`)}),x=n.subscribe(_);return(async()=>{let e=await Xy();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),b(),x(),i?.remove()}}function $y(e){return function(){let[t,n]=c.useState(!1),[r,i]=c.useState(null),a=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{let e=!0,t=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(Cy,t),Yy().then(t=>{e&&i(t.quickNoteMode)}),()=>{e=!1,window.removeEventListener(Cy,t)}},[]),c.useLayoutEffect(()=>{let e=a.current;if(e===null)return;let t=()=>{let t=null,n=null,r=e;for(;r!==null&&r!==document.documentElement&&(r=r.parentElement,r!==null);){for(let e of r.querySelectorAll(`textarea, [contenteditable]:not([contenteditable="false"]), [role="textbox"]`))if(e.getBoundingClientRect().width>300){t=e,n=r;break}if(n!==null)break}if(t===null||n===null)return null;let i=n.getBoundingClientRect().width,a=t,o=null,s=0;for(;a!==null&&a!==n;){let e=a.getBoundingClientRect().width;e>0&&e<i-8&&e>=s&&(s=e,o=a),a=a.parentElement}return o},n=()=>{let n=e.getBoundingClientRect(),r=t(),i=r===null?n.right:r.getBoundingClientRect().right,a=Math.max(0,n.right-i);return e.style.paddingRight!==`${a}px`&&(e.style.paddingRight=`${a}px`),r!==null};n();let r=new ResizeObserver(n),i=e;for(;i!==null&&i!==document.documentElement&&(r.observe(i),!(i instanceof HTMLElement&&i.hasAttribute(`data-phase`)));)i=i.parentElement;window.addEventListener(`resize`,n),document.addEventListener(`visibilitychange`,n);let o=0,s=0,c=window.setInterval(()=>{if(s++,!n()){s>=20&&window.clearInterval(c);return}o++,o>=3&&window.clearInterval(c)},1500),l=window.setTimeout(n,120),u=window.setTimeout(n,600);return()=>{r.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`visibilitychange`,n),window.clearInterval(c),window.clearTimeout(l),window.clearTimeout(u)}},[]);let s=r===`native`,l=s?`快速笔记`:t?`快速笔记(已打开)`:`快速笔记`,u=s?`快速笔记:直接打开 TiddlyWiki 原生编辑器(再次点击可收起弹窗)`:t?`快速笔记已打开(点此按钮或卡片右上角 ✕ 收起)`:`打开快速笔记(在按钮上方弹出,可拖动标题栏移动)`;return c.createElement(`div`,{ref:a,className:`dsh-tw-dock-note`},c.createElement(`button`,{ref:o,type:`button`,className:t?`dsh-tw-dock-note-btn dsh-tw-dock-note-btn-active`:`dsh-tw-dock-note-btn`,title:u,onClick:()=>{Yy().then(t=>{t.quickNoteMode===`native`?bt()?St():e.openNative():e.isOpen()?e.close():e.open(o.current??void 0)})}},c.createElement(`span`,{className:`dsh-tw-dock-note-icon`,"aria-hidden":`true`},`📝`),c.createElement(`span`,{className:`dsh-tw-dock-note-label`},l)))}}function eb(){return Ge()}async function tb(e){try{let t=await fetch(_,{method:`POST`,headers:{"content-type":`application/json`,"x-requested-with":`TiddlyWiki`},body:JSON.stringify({title:e}),signal:AbortSignal.timeout(15e3)});if(!t.ok)return null;let n=await t.text();return n.length>0?n:null}catch{return null}}async function nb(e){try{let t=await fetch(`${g}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function rb(e){let{sessionId:t,viewRequest:n,completeViewRequest:r}=e,[i,a]=c.useState(`loading`),[o,s]=c.useState(null),[l,u]=c.useState(null),[d,f]=c.useState(``),p=c.useRef(0),m=c.useRef(!0),h=c.useRef(0),_=c.useCallback(async()=>{let e=++p.current;if(m.current){if(a(`loading`),typeof t!=`string`||t.length===0){a(`error`),f(`缺少会话 ID`);return}if(h.current>=3){a(`error`),f(`连续 3 次生成失败,已停止自动重试,请点「🔄 刷新」`);return}try{let n=await fetch(w,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(!m.current||e!==p.current)return;if(!n.ok||r?.ok!==!0){h.current++,a(`error`),f(r?.error??`HTTP ${n.status}`);return}if(typeof r.title!=`string`||r.title.length===0){h.current++,a(`error`),f(`汇总生成失败:缺少标题`);return}u(r.title);let i=await tb(r.title);if(!m.current||e!==p.current)return;if(i===null){let t=await nb(r.title);if(!m.current||e!==p.current)return;if(!t){if(h.current++,h.current<3){_();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(host /render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(!m.current||e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}}},[t]);c.useEffect(()=>(m.current=!0,_(),()=>{m.current=!1}),[_]),c.useEffect(()=>{if(i!==`ready`||l===null)return;let e=!0,t=window.setInterval(()=>{(async()=>{if(!e)return;let t=!1;try{let e=await fetch(`${g}?title=${encodeURIComponent(l)}`,{signal:AbortSignal.timeout(8e3)}),n=await e.json().catch(()=>null);t=e.status!==404&&n?.notFound!==!0}catch{return}if(e)if(t)h.current=0;else{if(h.current++,h.current<3){_();return}a(`error`),f(`汇总条目已失效且自动重建多次失败,请点「🔄 刷新」重试`)}})()},3e4);return()=>{e=!1,window.clearInterval(t)}},[i,l,_]),c.useEffect(()=>{n!=null&&r?.()},[n,r]);let v=()=>{h.current=0,_()},y;return y=i===`loading`?c.createElement(`div`,{className:`dsh-tw-summary-state`},c.createElement(`div`,{className:`dsh-tw-summary-state-spin`},`⏳`),c.createElement(`div`,null,`正在生成会话 wiki 汇总…`)):i===`error`?c.createElement(`div`,{className:`dsh-tw-summary-state`},c.createElement(`div`,{className:`dsh-tw-summary-state-title`},`知识库汇总暂不可用`),c.createElement(`div`,{className:`dsh-tw-summary-state-detail`},d),c.createElement(`button`,{type:`button`,className:`dsh-tw-summary-btn`,onClick:v},`重试`)):c.createElement(`div`,{className:`dsh-tw-summary-native dsh-tw-toolcard-native`,dangerouslySetInnerHTML:{__html:o??``}}),c.createElement(`div`,{className:`dsh-tw-summary`,"data-dsh-tw-summary":`true`},c.createElement(`div`,{className:`dsh-tw-summary-bar`},c.createElement(`span`,{className:`dsh-tw-summary-bar-title`},`📚 本会话知识库`),c.createElement(`span`,{className:`dsh-tw-summary-bar-hint`},`产生 / 读取 / 检索过的笔记(含子代理)`),c.createElement(`span`,{className:`dsh-tw-summary-bar-spacer`}),c.createElement(`button`,{type:`button`,className:`dsh-tw-summary-btn`,onClick:v,disabled:i===`loading`,title:`重新生成并刷新汇总`},`🔄 刷新`)),y)}function ib(e,t){if(!(e===void 0||t.showSessionTab===!1))return We(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:eb},rb))}function $(e,t,n){let r=document.createElement(e);return t!==void 0&&(r.className=t),n!==void 0&&(r.textContent=n),r}async function ab(e,t){let n=await fetch(e,{...t,signal:AbortSignal.timeout(15e3)}),r=await n.json().catch(()=>({}));if(!n.ok){let e=r.error??`HTTP ${n.status}`;throw Error(e)}return r}function ob(e){let t=!1;e.classList.add(`dsh-tw-settings`);let n=$(`div`,`dsh-tw-settings-row dsh-tw-settings-status`),r=$(`div`,`dsh-tw-settings-body`);e.append(n,r);let i=[],a={},o=async()=>{try{let e=await ab(ne);if(t)return;sb(n,e,o),fb(r,e,o,()=>t,a)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),a=$(`button`,`dsh-tw-settings-btn`,`重试`);a.type=`button`,a.addEventListener(`click`,()=>{o()}),r.append(i,a)}};return o(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function sb(e,t,n){e.replaceChildren();let r=t.server??{},i=r.status??`unknown`,a=$(`span`,`dsh-tw-settings-chip`,i);a.dataset.state=i;let o=$(`span`,`dsh-tw-settings-muted`,[r.url===void 0?``:`TW ${r.url}`,t.git?.branch===void 0?``:`git ${t.git.branch}`,t.git?.lastCommit===void 0?``:t.git.lastCommit,t.git?.dirty===!0?`有未提交改动`:``].filter(Boolean).join(` · `)),s=$(`button`,`dsh-tw-settings-btn`,`同步`);s.type=`button`,s.title=`git 同步(pull → commit → push)`,s.addEventListener(`click`,()=>{s.disabled=!0,s.textContent=`同步中…`,(async()=>{try{let e=await fetch(te,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=await e.json().catch(()=>null);if(!e.ok||t?.ok!==!0)T(`同步失败:${t?.error??t?.message??`HTTP ${e.status}`}`);else{let e=``;t.changed===!0&&(e+=t.restarted===!0?`,TW 已重启`:`,TW 未自动重启`,t.restartError&&(e+=`(${t.restartError})`)),T(`同步完成:${t.message??`OK`}${e}`)}}catch(e){T(`同步失败:${e instanceof Error?e.message:String(e)}`)}finally{s.disabled=!1,s.textContent=`同步`,n()}})()});let c=$(`button`,`dsh-tw-settings-btn`,`重启 TW`);c.type=`button`,c.addEventListener(`click`,()=>{c.disabled=!0,c.textContent=`重启中…`,(async()=>{try{await ab(oe,{method:`POST`}),T(`TW 已重启`)}catch(e){T(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function cb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`常规配置`));let i=t.note??{},a=t.git??{},o=t.ui??{},s=[],c=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.value=n;let a=$(`label`,`dsh-tw-settings-field`);a.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:()=>i.value.trim(),changed:()=>i.value.trim()!==n}),r.append(a)},l=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-check`);i.type=`checkbox`,i.checked=n;let a=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-check`);a.append(i,$(`span`,`dsh-tw-settings-label`,t)),s.push({key:e,initial:n,read:()=>i.checked,changed:()=>i.checked!==n}),r.append(a)},u=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.type=`number`,i.value=String(n);let a=()=>{let e=i.value.trim();if(e.length===0)return n;let t=Number(e);return Number.isFinite(t)?t:n},o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:a,changed:()=>a()!==n}),r.append(o)},d=(e,t,n,i)=>{let a=$(`select`,`dsh-tw-settings-input`);for(let e of i){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,e.value===n&&(t.selected=!0),a.append(t)}let o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o)},f=(e,t,n,i)=>{let a=$(`textarea`,`dsh-tw-settings-input dsh-tw-settings-area`);a.rows=i,a.value=n;let o=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-area`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value.trim(),changed:()=>a.value.trim()!==n}),r.append(o),a};c(`note.tag`,`快速笔记默认 tag`,typeof i.tag==`string`?i.tag:`inbox`),l(`git.autoCommit`,`自动 commit(防抖)`,a.autoCommit!==!1),u(`git.debounceMs`,`自动 commit 防抖(ms)`,typeof a.debounceMs==`number`?a.debounceMs:6e4),c(`git.remote`,`git 远端(空=仅本地)`,typeof a.remote==`string`?a.remote:``),c(`git.branch`,`git 分支`,typeof a.branch==`string`?a.branch:`main`);let p=t.startup??{};u(`startup.readyTimeoutMs`,`TW 启动就绪等待(ms;默认 60000,范围 5000–600000,超时上限为其 3 倍,对下次启动/重启生效)`,typeof p.readyTimeoutMs==`number`&&p.readyTimeoutMs>0?p.readyTimeoutMs:6e4),l(`ui.showQuickNote`,`显示「知识库」按钮里的「快速笔记」入口`,o.showQuickNote!==!1),l(`ui.showQuickNoteDock`,`显示聊天输入框上方的「快速笔记」快捷按钮`,o.showQuickNoteDock!==!1),d(`ui.quickNoteMode`,`点击「快速笔记」的打开方式`,typeof o.quickNoteMode==`string`&&o.quickNoteMode===`card`?`card`:`native`,[{value:`native`,label:`原生编辑器:直接弹出 TW 原生编辑页(新建/恢复草稿)`},{value:`card`,label:`Markdown 卡片:弹出现有快速笔记卡片(CodeMirror 编辑器)`}]),c(`ui.sidebarLabel`,`侧边栏 TW 入口显示名称`,typeof o.sidebarLabel==`string`&&o.sidebarLabel.trim().length>0?o.sidebarLabel.trim():`TiddlyWiki`),l(`ui.showPanelStatus`,`显示「知识库」按钮里的 TW 面板/重载入口与状态行`,o.showPanelStatus!==!1),l(`ui.showSyncButton`,`显示「知识库」按钮里的「同步」入口与 git 状态点`,o.showSyncButton!==!1),l(`ui.followDshTheme`,`嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)`,o.followDshTheme!==!1),c(`ui.darkPalette`,`暗色时 TW palette(tiddler 标题)`,typeof o.darkPalette==`string`&&o.darkPalette.trim().length>0?o.darkPalette.trim():`$:/palettes/CupertinoDark`),c(`ui.tabLabel`,`会话顶部「知识库」Tab 名称`,typeof o.tabLabel==`string`&&o.tabLabel.trim().length>0?o.tabLabel.trim():`知识库`),l(`ui.showSessionTab`,`显示会话顶部「知识库」Tab(本会话相关 wiki 笔记汇总)`,o.showSessionTab!==!1),l(`ui.showRightbarTab`,`在 DSH 右侧边栏提供 TiddlyWiki 入口/Tab(与聊天并排)`,o.showRightbarTab!==!1);let m=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,m.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof m.endpoint==`string`?m.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头;已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof m.token==`string`?m.token:``);let h=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof h.pageSize==`number`?h.pageSize:10);let g=t.prompt??{};r.append($(`h3`,`dsh-tw-settings-h`,`系统提示词(注入每个会话)`)),r.append($(`div`,`dsh-tw-settings-muted`,`插件把自己的约定(同步纪律 / 标签约定 / 链接格式等)注入每个会话的系统提示词。保存后**无需重启 dsh web**:section 会即时重新注册,当前会话从下一步起就使用新文本。`)),l(`prompt.enabled`,`注入 TiddlyWiki 提示词(关闭后本插件不再注入任何文本)`,g.enabled!==!1),d(`prompt.mode`,`内置文本形态`,g.mode===`full`?`full`:`slim`,[{value:`slim`,label:`精简(默认):只保留工具 schema 表达不了的约定`},{value:`full`,label:`完整:额外附一份由工具注册表实时生成的参数索引`}]),f(`prompt.extra`,`附加说明(永远追加在末尾,可放团队/个人规范)`,typeof g.extra==`string`?g.extra:``,5),f(`prompt.override`,`整段替换(非空时取代上面的内置文本,附加说明仍会追加)`,typeof g.override==`string`?g.override:``,8);let _=$(`button`,`dsh-tw-settings-btn`,`查看当前注入文本`);_.type=`button`,_.title=`读取 host 端实时生成的提示词全文(保存后即为下一步注入的内容)`;let v=$(`pre`,`dsh-tw-settings-prompt-preview`);v.hidden=!0,_.addEventListener(`click`,()=>{if(!v.hidden){v.hidden=!0,v.textContent=``;return}_.disabled=!0,(async()=>{try{let e=await ab(re);if(e.ok!==!0)throw Error(e.error??`获取失败`);v.textContent=e.enabled===!1?`(已关闭:不会注入任何提示词)`:`# 形态 ${e.mode??``} · ${e.length??0} 字符\n\n${e.text??``}`,v.hidden=!1}catch(e){T(`读取提示词失败:${e instanceof Error?e.message:String(e)}`)}finally{_.disabled=!1}})()}),r.append(_,v);let y=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,y.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof y.port==`number`&&y.port>0?y.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置。已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof y.token==`string`?y.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof y.tag==`string`&&y.tag.trim().length>0?y.tag.trim():`clip`);let b=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);b.type=`button`,b.addEventListener(`click`,()=>{b.disabled=!0,(async()=>{let e={};for(let t of s){if(!t.changed())continue;let n=t.key.split(`.`),r=e;for(let e=0;e<n.length;e++){let i=n[e];if(i===void 0)break;if(e===n.length-1)r[i]=t.read();else{let e=r[i]??{};r[i]=e,r=e}}}try{await ab(ae,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),Jy(),T(`配置已保存`),n()}catch(e){T(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{b.disabled=!1}})()}),r.append(b),e.append(r)}function lb(e,t,n,r){let i=n?.plugins??[],a=n?.themes??[],o=n?.languages??[],s=new Set(t?.plugins??[]),c=new Set(t?.themes??[]),l=new Set(t?.languages??[]),u=$(`section`,`dsh-tw-settings-section`);u.append($(`h3`,`dsh-tw-settings-h`,`插件管理(自带官方插件)`));let d=$(`input`,`dsh-tw-settings-input dsh-tw-settings-search`);d.placeholder=`搜索插件…`;let f=$(`div`,`dsh-tw-settings-list`),p=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用插件(重启 TW)`);p.type=`button`;let m=e=>{f.replaceChildren();let t=e.toLowerCase();for(let e of i){if(t.length>0&&!`${e.label} ${e.name} ${e.description}`.toLowerCase().includes(t))continue;let n=$(`input`,`dsh-tw-settings-check`);n.type=`checkbox`,n.checked=s.has(e.name),n.addEventListener(`change`,()=>{n.checked?s.add(e.name):s.delete(e.name)});let r=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),i=$(`span`,`dsh-tw-settings-name`,e.label);i.title=e.name;let a=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);r.append(n,i,a),f.append(r)}};d.addEventListener(`input`,()=>m(d.value)),p.addEventListener(`click`,()=>{p.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),T(`插件已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),p.disabled=!1}})()}),m(``),u.append(d,f,p),e.append(u);let h=$(`section`,`dsh-tw-settings-section`);h.append($(`h3`,`dsh-tw-settings-h`,`主题管理(自带主题)`));let g=$(`div`,`dsh-tw-settings-muted`,`「加载」= TW 里可用的主题(可多选,依赖链自动带上,如 heavier 会带 snowwhite+vanilla);「活动」= 当前视觉主题(单选,自动加入加载集)。应用后重启 TW。`),_=$(`div`,`dsh-tw-settings-row dsh-tw-settings-head`);_.append($(`span`,`dsh-tw-settings-col`,`加载`),$(`span`,`dsh-tw-settings-col`,`活动`),$(`span`,`dsh-tw-settings-name`,`主题`));let v=t?.themes??[],y=t?.themeActive,b=typeof y==`string`&&a.some(e=>e.name===y)?y:v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,x=$(`div`,`dsh-tw-settings-list`);for(let e of a){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=c.has(e.name),t.title=`加载该主题`,t.addEventListener(`change`,()=>{t.checked?c.add(e.name):c.delete(e.name)});let n=$(`input`,`dsh-tw-settings-check`);n.type=`radio`,n.name=`dsh-tw-active-theme`,n.checked=e.name===b,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(b=e.name)});let r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name),a=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);a.append(t,n,r,i),x.append(a)}let S=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);S.type=`button`,S.addEventListener(`click`,()=>{S.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:b})}),T(`主题已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),S.disabled=!1}})()}),h.append(g,_,x,S),e.append(h);let ee=$(`section`,`dsh-tw-settings-section`);ee.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let te=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),C=$(`div`,`dsh-tw-settings-list`);for(let e of o){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=l.has(e.name),t.addEventListener(`change`,()=>{t.checked?l.add(e.name):l.delete(e.name)});let n=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);n.append(t,r,i),C.append(n)}let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);w.type=`button`,w.addEventListener(`click`,()=>{w.disabled=!0,(async()=>{try{await ab(ie,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),T(`语言已应用,TW 已重启`),r()}catch(e){T(`应用失败:${e instanceof Error?e.message:String(e)}`),w.disabled=!1}})()}),ee.append(te,C,w),e.append(ee)}function ub(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`知识库位置(可切换)`));let i=$(`div`,`dsh-tw-settings-muted`,`读取中…`),a=$(`div`,`dsh-tw-settings-muted`),o=$(`div`,`dsh-tw-settings-muted`),s=$(`div`,`dsh-tw-settings-muted`),c=$(`input`,`dsh-tw-settings-input`),l=$(`input`,`dsh-tw-settings-input`);c.placeholder=`绝对路径,如 D:\\notes 或 $DSH_HOME/tiddlywiki`,l.placeholder=`文件夹名(默认 main;填 . 表示直接用上面这个目录)`;let u=$(`label`,`dsh-tw-settings-field`);u.append($(`span`,`dsh-tw-settings-label`,`根目录(wikiRoot)`),c);let d=$(`label`,`dsh-tw-settings-field`);d.append($(`span`,`dsh-tw-settings-label`,`文件夹名(wiki)`),l);let f=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`切换到这个位置`);f.type=`button`;let p=$(`button`,`dsh-tw-settings-btn`,`恢复为配置默认`);p.type=`button`;let m=$(`div`,`dsh-tw-settings-row`);m.append(f,p);let h=$(`div`,`dsh-tw-settings-row dsh-tw-settings-candidates`),g=$(`div`,`dsh-tw-settings-muted`,"切换会停掉并就地重启 TW 子进程(几秒);新目录若还没有 tiddlywiki.info,插件会自动 `--init server` 初始化一个全新知识库。选中的位置会记在 $DSH_HOME 下的指针文件里(不进 wiki),可用「恢复为配置默认」清除。"),_=(e,t)=>{f.disabled=e,p.disabled=e,f.textContent=e?t:`切换到这个位置`},v=async()=>{if(!t())try{let e=await ab(ue);if(t())return;if(e.ok!==!0)throw Error(e.error??`获取失败`);let n=e.current??{};i.textContent=`当前:${n.path??`(未知)`}`;let r=n.source===`state`?`来源:指针文件(在设置页切换过)`:n.source===`config`?`来源:cordis 配置(config.wikiRoot / config.wiki)`:`来源:默认值($DSH_HOME/tiddlywiki + main)`;a.textContent=`${r} · 配置默认:${e.default?.path??`(未知)`}`,o.textContent=e.stateFile===void 0?``:`指针文件:${e.stateFile}(不存在=使用配置默认)`,s.textContent=e.error===void 0?``:`⚠️ ${e.error}`,c.value.length===0&&typeof n.root==`string`&&(c.value=n.root),l.value.length===0&&typeof n.name==`string`&&(l.value=n.name),h.replaceChildren();let u=e.candidates??[];if(u.length>0){h.append($(`span`,`dsh-tw-settings-label`,`同目录下可选的 wiki:`));for(let e of u){let t=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-chipbtn`,e===`.`?`(根目录本身)`:e);t.type=`button`,t.title=`填入文件夹名「${e}」`,t.addEventListener(`click`,()=>{l.value=e}),h.append(t)}}}catch(e){if(t())return;i.textContent=`读取位置失败:${e instanceof Error?e.message:String(e)}`}};f.addEventListener(`click`,()=>{let e=c.value.trim(),t=l.value.trim().length>0?l.value.trim():`main`;if(e.length===0){T(`请先填写根目录(绝对路径)`);return}window.confirm(`切换知识库到:\n${e}\\${t}\n\n会停止并重启 TW 子进程;当前对话/工具随后读写的是新知识库。确定继续?`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let r=await ab(de,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({root:e,name:t}),signal:AbortSignal.timeout(12e4)});r.warning===void 0?T(`已切换到 ${r.path??``}`):T(`已切换到 ${r.path??``}(注意:${r.warning})`),Jy(),await v(),await n()}catch(e){T(`切换失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),p.addEventListener(`click`,()=>{window.confirm(`恢复为配置默认位置?会删除位置指针文件,并(必要时)切回配置里的知识库。`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let e=await ab(fe,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`,signal:AbortSignal.timeout(12e4)});T(e.warning===void 0?`已恢复为配置默认:${e.path??``}`:`已恢复默认(注意:${e.warning})`),Jy(),await v(),await n()}catch(e){T(`恢复失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),r.append(i,a,o,u,d,m,h,s,g),e.append(r),v()}function db(e,t){let n=$(`section`,`dsh-tw-settings-section`);n.append($(`h3`,`dsh-tw-settings-h`,`初始化(一次性预置)`));let r=$(`div`,`dsh-tw-settings-muted`,`这些是插件与 dsh 联动、需要在 wiki 里预置的 tiddler/配置。「发送给 Agent 按钮」和「TW 前端 API 基址」是功能必需项,启动时自动写入(只写缺失,不覆盖你的改动);其余为可选项,默认不自动写入、也不会强绑定——需要时点「重新初始化」写入,不想要了可随时「反初始化」移除。`),i=$(`div`,`dsh-tw-settings-list`),a=$(`div`,`dsh-tw-settings-muted`),o=async()=>{if(!t())try{let e=await ab(se);if(t())return;if(e.ok!==!0||!Array.isArray(e.items))throw Error(e.error??`获取失败`);i.replaceChildren();let n=0,r=0;for(let t of e.items){t.present&&(n+=1),t.removable&&(r+=1);let e=$(`span`,`dsh-tw-settings-chip`,t.present?`✓`:`✗`);e.dataset.state=t.present?`ok`:`missing`,e.title=t.present?`已存在`:`缺失`;let a=$(`span`,`dsh-tw-settings-name`,t.title);a.title=t.id;let s=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),c=t.updateAvailable===!0?$(`span`,`dsh-tw-settings-chip`,`⬆ 有更新`):void 0;c!==void 0&&(c.dataset.state=`update`,c.title=`内置内容在本 wiki 预置之后更新过,可点「重新初始化」取用`);let l=t.userModified===!0?$(`span`,`dsh-tw-settings-chip`,`✏️ 本地已修改`):void 0;l!==void 0&&(l.dataset.state=`missing`,l.title=`这篇是你的内容:重新初始化会覆盖它`);let u=$(`button`,`dsh-tw-settings-btn`,t.updateAvailable===!0?`更新到内置版本`:`重新初始化`);u.type=`button`,u.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,u.addEventListener(`click`,()=>{if(t.updateAvailable===!0){let e=t.userModified===!0?`「${t.title}」有你的本地修改,更新会覆盖它。`:t.userModified===void 0?`无法确认「${t.title}」是否被你编辑过(旧格式标记),更新可能覆盖你的改动。`:``;if(!window.confirm(`${e}${e.length>0?`
|
|
743
743
|
|
|
744
744
|
`:``}用内置版本覆盖?`))return}u.disabled=!0,u.textContent=`执行中…`,(async()=>{try{let e=await fetch(ce,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:t.id,force:!0}),signal:AbortSignal.timeout(3e4)}),n=await e.json().catch(()=>null);!e.ok||n?.ok!==!0?T(`重新初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):T(`已重新初始化「${t.title}」`),o()}catch(e){T(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{u.disabled=!1,u.textContent=t.updateAvailable===!0?`更新到内置版本`:`重新初始化`}})()});let d=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);if(d.append(e,a),c!==void 0&&d.append(c),l!==void 0&&d.append(l),d.append(s,u),t.removable){let e=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`反初始化`);e.type=`button`,e.title=`移除「${t.title}」写入的 tiddler 与 marker(恢复未初始化状态)`,e.addEventListener(`click`,()=>{window.confirm(`确定反初始化「${t.title}」?将删除它写入的 tiddler(含其一次性 marker),需要时可用「重新初始化」恢复。`)&&(e.disabled=!0,e.textContent=`移除中…`,(async()=>{try{let e=await fetch(le,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:t.id}),signal:AbortSignal.timeout(3e4)}),n=await e.json().catch(()=>null);!e.ok||n?.ok!==!0?T(`反初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):T(`已反初始化「${t.title}」`),o()}catch(e){T(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{e.disabled=!1,e.textContent=`反初始化`}})())}),d.append(e)}i.append(d)}a.textContent=`共 ${e.items.length} 项,${n} 项已就绪;可移除 ${r} 项`}catch(e){if(t())return;a.textContent=`加载初始化状态失败:${e instanceof Error?e.message:String(e)}`}},s=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`全部重新初始化`);s.type=`button`,s.title=`强制重写所有一次性预置内容(含可选 seed,会覆盖当前 tiddler/配置)`,s.addEventListener(`click`,()=>{s.disabled=!0,s.textContent=`执行中…`,(async()=>{try{let e=await fetch(ce,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({force:!0}),signal:AbortSignal.timeout(6e4)}),t=await e.json().catch(()=>null);!e.ok||t?.ok!==!0?T(`重新初始化失败:${t?.error??`HTTP ${e.status}`}`):T(`全部已重新初始化`),o()}catch(e){T(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{s.disabled=!1,s.textContent=`全部重新初始化`}})()});let c=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`全部反初始化`);c.type=`button`,c.title=`移除所有可选 seed 写入的 tiddler 与 marker(功能必需项保留)`,c.addEventListener(`click`,()=>{window.confirm(`确定全部反初始化?将删除所有可选 seed 写入的 tiddler(含一次性 marker)。功能必需项(发送给 Agent 按钮 / TW 前端 API 基址)会保留。`)&&(c.disabled=!0,c.textContent=`移除中…`,(async()=>{try{let e=await fetch(le,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({}),signal:AbortSignal.timeout(6e4)}),t=await e.json().catch(()=>null);!e.ok||t?.ok!==!0?T(`反初始化失败:${t?.error??`HTTP ${e.status}`}`):T(`全部可选 seed 已反初始化`),o()}catch(e){T(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`全部反初始化`}})())}),n.append(r,a,i,s,c),e.append(n),o()}function fb(e,t,n,r,i){e.replaceChildren();let a=JSON.stringify(t.config??{});if(i.host===void 0||i.signature!==a){let e=$(`div`,`dsh-tw-settings-confighost`);cb(e,t.config??{},n),i.host=e,i.signature=a}e.append(i.host),ub(e,r,n),lb(e,t.info,t.catalog,n),db(e,r)}function pb(){let e=c.useRef(null);return c.useEffect(()=>{let t=e.current;return t===null?void 0:ob(t)},[]),c.createElement(`div`,{ref:e})}const mb={tiddlywiki_get:`读取笔记`,tiddlywiki_search:`检索笔记`,tiddlywiki_recent:`最近修改`,tiddlywiki_list_tags:`标签列表`,tiddlywiki_put:`写入笔记`,tiddlywiki_batch_put:`批量写入`,tiddlywiki_append:`增量写入`,tiddlywiki_rename:`重命名笔记`,tiddlywiki_delete:`删除笔记`,tiddlywiki_trash:`回收站`,tiddlywiki_backlinks:`反向链接`,tiddlywiki_attach:`保存附件`,tiddlywiki_lint:`知识库体检`,tiddlywiki_git_sync:`git 同步`,tiddlywiki_git_resolve:`git 冲突解决`};function hb(e){return typeof e==`object`&&!!e&&e.kind===`tool-result`}function gb(e){if(typeof e!=`object`||!e)return null;let t=e;if(typeof t.call==`object`&&t.call!==null){let e=t.call;if(typeof e.name==`string`&&typeof e.argsRaw==`string`)return e}let n=e;return typeof n.name==`string`&&typeof n.argsRaw==`string`?{name:n.name,argsRaw:n.argsRaw}:null}function _b(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{}}catch{return{}}}function vb(e){return Array.isArray(e)?e.filter(e=>typeof e?.text==`string`).map(e=>e.text).join(`
|
|
745
745
|
`):``}function yb(e){return typeof e==`string`?e:``}async function bb(e){try{let t=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(t.status===404){let e=await t.json().catch(()=>null);return typeof e==`object`&&e?e:{notFound:!0}}if(!t.ok)return null;let n=await t.json();return typeof n==`object`&&n?n:null}catch{return null}}async function xb(e){try{let t=await fetch(_,{method:`POST`,headers:{"content-type":`application/json`,"x-requested-with":`TiddlyWiki`},body:JSON.stringify({title:e}),signal:AbortSignal.timeout(1e4)});return t.ok?await t.text():null}catch{return null}}function Sb(e,t){let[n,r]=c.useState({loading:!0,data:null});return c.useEffect(()=>{let t=!0;return r({loading:!0,data:null}),Promise.resolve(e()).then(e=>{t&&r({loading:!1,data:e})},()=>{t&&r({loading:!1,data:null})}),()=>{t=!1}},t),n}function Cb(e){return t=>{t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||(t.preventDefault(),t.stopPropagation(),lt(e))}}function wb(e){let t=mb[e.toolName]??e.toolName,n=c.createElement(`div`,{className:`dsh-tw-toolcard-head`},c.createElement(`span`,{className:`dsh-tw-toolcard-badge`},t),e.title!==void 0&&e.title.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-title`,title:e.title},e.title):null,e.onOpen===void 0?null:c.createElement(`button`,{type:`button`,className:`dsh-tw-toolcard-open`,onClick:e.onOpen},`在 TW 打开`)),r=e.subtitle!==void 0||e.tags!==void 0&&e.tags.length>0?c.createElement(`div`,{className:`dsh-tw-toolcard-meta`},e.subtitle===void 0?null:c.createElement(`span`,{className:`dsh-tw-toolcard-sub`},e.subtitle),e.tags!==void 0&&e.tags.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-tags`},...e.tags.map((e,t)=>c.createElement(`span`,{className:`dsh-tw-toolcard-tag`,key:`${t}-${e}`},e))):null):null;return c.createElement(`div`,{className:`dsh-tw-toolcard`},n,r,c.createElement(`div`,{className:`dsh-tw-toolcard-body`},e.children),e.foot!==void 0&&e.foot!==null?c.createElement(`div`,{className:`dsh-tw-toolcard-foot`},e.foot):null)}const Tb=new Map;function Eb(e){let t=Tb.get(e);if(t!==void 0){if(Date.now()-t.at>3e5){Tb.delete(e);return}return Tb.delete(e),Tb.set(e,t),t}}function Db(e,t){for(Tb.delete(e),Tb.set(e,{at:Date.now(),...t});Tb.size>50;){let e=Tb.keys().next().value;if(e===void 0)break;Tb.delete(e)}}function Ob(e){e.length>0&&Tb.delete(e)}function kb(e){let t=e.join(`\0`);c.useEffect(()=>{for(let e of t.split(`\0`))Ob(e)},[t])}function Ab(e){let{title:t,fresh:n}=e,{loading:r,data:i}=Sb(async()=>{n===!0&&Ob(t);let e=Eb(t);if(e!==void 0)return{get:e.get,html:e.html};let[r,i]=await Promise.all([bb(`${g}?title=${encodeURIComponent(t)}`),xb(t)]);return typeof i==`string`&&i.length>0&&Db(t,{get:r,html:i}),{get:r,html:i}},[t,n]),a=i?.get??null,o=i?.html??null,s;s=r?c.createElement(`div`,{className:`dsh-tw-toolcard-loading`},`渲染中…`):a!==null&&a.notFound===!0?c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`tiddler「${t}」不存在`):typeof o==`string`&&o.length>0?c.createElement(`div`,{className:`dsh-tw-toolcard-native`,dangerouslySetInnerHTML:{__html:o}}):a!==null&&typeof a.text==`string`&&a.text.length>0?c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},a.text):c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`wiki 服务不可用`);let l=Array.isArray(a?.tags)?a.tags.filter(e=>typeof e==`string`):[],u=typeof a?.modified==`string`?a.modified:void 0;return c.createElement(wb,{toolName:e.toolName,title:t,subtitle:e.subtitle,tags:l,onOpen:Cb(t),foot:u===void 0?void 0:`修改于 ${u}`},s)}function jb(e){return c.createElement(`a`,{className:`dsh-tw-toolcard-row`,href:`${m}#${encodeURIComponent(e.title)}`,onClick:Cb(e.title),title:e.title},c.createElement(`span`,{className:`dsh-tw-toolcard-row-title`},e.title),e.tags!==void 0&&e.tags.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-row-tags`},e.tags.slice(0,4).join(` · `)):null,typeof e.modified==`string`&&e.modified.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-row-meta`},e.modified):null)}function Mb(e){let t=e.rows.slice(0,60),n;return n=t.length===0?c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},e.fallbackText):c.createElement(`div`,{className:`dsh-tw-toolcard-list`},...t.map((e,t)=>c.createElement(jb,{key:`${e.title}-${t}`,...e}))),c.createElement(wb,{toolName:e.toolName,title:e.title,subtitle:e.subtitle},n)}function Nb(e){let t=yb(e.args.query),n=new URLSearchParams;if(t.length>0&&n.set(`query`,t),Array.isArray(e.args.tags))for(let t of e.args.tags)typeof t==`string`&&t.length>0&&n.append(`tags`,t);typeof e.args.tag==`string`&&e.args.tag.length>0&&n.set(`tag`,e.args.tag),typeof e.args.since==`string`&&e.args.since.length>0&&n.set(`since`,e.args.since),typeof e.args.type==`string`&&e.args.type.length>0&&n.set(`type`,e.args.type),typeof e.args.field==`string`&&e.args.field.length>0&&n.set(`field`,e.args.field),typeof e.args.value==`string`&&e.args.value.length>0&&n.set(`value`,e.args.value),typeof e.args.limit==`number`&&n.set(`limit`,String(e.args.limit));let r=n.toString(),i=Sb(()=>bb(`${S}?${r}`),[r]).data,a=(Array.isArray(i?.items)?i.items:[]).map(e=>({title:yb(e.title),tags:Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`):[],modified:typeof e.modified==`string`?e.modified:null})),o=typeof i?.total==`number`?i.total:void 0,s=`关键词「${t||`(全部)`}」${o===void 0?``:` · 共 ${o} 条`}`;return c.createElement(Mb,{toolName:e.toolName,title:t.length>0?t:`检索`,subtitle:s,rows:a,fallbackText:`没有匹配的笔记`})}function Pb(e){let t=new URLSearchParams;typeof e.args.limit==`number`&&t.set(`limit`,String(e.args.limit)),typeof e.args.since==`string`&&e.args.since.length>0&&t.set(`since`,e.args.since);let n=t.toString(),r=Sb(()=>bb(`${x}?${n}`),[n]).data,i=(Array.isArray(r?.items)?r.items:[]).map(e=>({title:yb(e.title),tags:Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`):[],modified:typeof e.modified==`string`?e.modified:null}));return c.createElement(Mb,{toolName:e.toolName,title:`最近修改`,subtitle:i.length>0?`最近 ${i.length} 条`:``,rows:i,fallbackText:`暂无笔记`})}function Fb(e){let t=(Array.isArray(e.args.items)?e.args.items:[]).map(e=>typeof e==`object`&&e&&typeof e.title==`string`?yb(e.title):null).filter(e=>e!==null&&e.length>0).map(e=>({title:e}));return kb(t.map(e=>e.title)),c.createElement(Mb,{toolName:e.toolName,title:`批量写入`,subtitle:t.length>0?`写入 ${t.length} 篇`:`(参数中没有可解析的 items)`,rows:t,fallbackText:`没有可展示的笔记`})}function Ib(e){let t=Sb(()=>bb(`${b}?limit=60&sort=count`),[]).data,n=(Array.isArray(t?.items)?t.items:[]).map(e=>({tag:yb(e.tag),count:typeof e.count==`number`?e.count:0})),r=n.slice(0,60),i=typeof t?.total==`number`?t.total:n.length,a;return a=n.length===0?c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`暂无标签`):c.createElement(`div`,{className:`dsh-tw-toolcard-tags-wrap`},...r.map(e=>c.createElement(`span`,{className:`dsh-tw-toolcard-tag`,key:e.tag},`${e.tag} · ${e.count}`)),...i>r.length?[c.createElement(`span`,{className:`dsh-tw-toolcard-tag-more`,key:`__more`},`…另有 ${i-r.length} 个`)]:[]),c.createElement(wb,{toolName:e.toolName,title:`标签`,subtitle:`共 ${i} 个`},a)}function Lb(e){let t=e.text.trim().length>0?c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},e.text):c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`(无结果)`);return c.createElement(wb,{toolName:e.toolName},t)}function Rb(e){kb([e.title]);let t=e.title.length>0?c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`已删除 tiddler「${e.title}」`):c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},e.text||`(已删除)`);return c.createElement(wb,{toolName:e.toolName,title:e.title.length>0?e.title:void 0},t)}function zb(e,t){switch(e){case`tiddlywiki_get`:case`tiddlywiki_put`:case`tiddlywiki_append`:case`tiddlywiki_delete`:case`tiddlywiki_attach`:case`tiddlywiki_backlinks`:return yb(t.title);case`tiddlywiki_rename`:return yb(t.newTitle);case`tiddlywiki_search`:return yb(t.query);default:return``}}function Bb(e){let t=e.block,n=e.toolName,r=hb(t),i=gb(t),a=n!==void 0&&n.length>0?n:i?.name??``,o=_b(i?.argsRaw??``),s=r?vb(t.content):``;if(i===null)return c.createElement(wb,{toolName:a},c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},s||`(无调用信息)`));if(!r)return c.createElement(wb,{toolName:a,title:zb(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-pending`},`处理中…`));if(t.isError===!0)return c.createElement(wb,{toolName:a,title:zb(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-error`},s||`工具调用失败`));switch(a){case`tiddlywiki_get`:return c.createElement(Ab,{toolName:a,title:yb(o.title),subtitle:`读取`});case`tiddlywiki_put`:return c.createElement(Ab,{toolName:a,title:yb(o.title),subtitle:`已写入`,fresh:!0});case`tiddlywiki_append`:return c.createElement(Ab,{toolName:a,title:yb(o.title),subtitle:`已增量写入`,fresh:!0});case`tiddlywiki_rename`:return c.createElement(Ab,{toolName:a,title:yb(o.newTitle),subtitle:`已重命名「${yb(o.oldTitle)}」→`,fresh:!0});case`tiddlywiki_delete`:return c.createElement(Rb,{toolName:a,title:yb(o.title),text:s});case`tiddlywiki_batch_put`:return c.createElement(Fb,{toolName:a,args:o});case`tiddlywiki_search`:return c.createElement(Nb,{toolName:a,args:o});case`tiddlywiki_recent`:return c.createElement(Pb,{toolName:a,args:o});case`tiddlywiki_list_tags`:return c.createElement(Ib,{toolName:a});case`tiddlywiki_git_sync`:case`tiddlywiki_git_resolve`:return c.createElement(Lb,{toolName:a,text:s});default:return c.createElement(wb,{toolName:a,title:zb(a,o)},c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},s||`(完成)`))}}const Vb=[`tiddlywiki_get`,`tiddlywiki_search`,`tiddlywiki_recent`,`tiddlywiki_list_tags`,`tiddlywiki_put`,`tiddlywiki_batch_put`,`tiddlywiki_append`,`tiddlywiki_rename`,`tiddlywiki_delete`,`tiddlywiki_trash`,`tiddlywiki_backlinks`,`tiddlywiki_attach`,`tiddlywiki_lint`,`tiddlywiki_git_sync`,`tiddlywiki_git_resolve`];function Hb(e){let t=[];for(let n of Vb)try{let r=e.inject(`tool.call.toolview`,()=>e.register({name:`tool.call.toolview`,id:`dsh-tiddlywiki-toolview-${n}`,key:n,order:20,label:`TiddlyWiki: ${n}`},Bb));r!==void 0&&t.push(r)}catch(e){console.error(`[dsh-tiddlywiki] register toolview ${n} failed:`,e)}return t}function Ub(){let e=RegExp(`^${m.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}#(.+)$`),t=t=>{if(t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;let n=t.target;if(!(n instanceof Element))return;let r=n.closest(`a`);if(r===null)return;let i=(r.getAttribute(`href`)??``).match(e);if(i===null||i[1]===void 0)return;t.preventDefault(),t.stopPropagation();let a=i[1];try{a=decodeURIComponent(a)}catch{}lt(a)};return document.addEventListener(`click`,t,!0),()=>document.removeEventListener(`click`,t,!0)}const Wb=`dsh-tiddlywiki`,Gb=`dsh-tiddlywiki/rightbar`;function Kb(e){let{useTabInfo:t}=e,n=t().tab,r=c.useRef(null),i=c.useRef(null);c.useEffect(()=>{let e=r.current;if(e===null)return;let t=tt(e,n.signal);return i.current=t,()=>{t.dispose(),i.current=null}},[n.id,n.signal]),c.useEffect(()=>{i.current?.setVisible(n.visible)},[n.visible]);let a=n.visible,o=n.actions.close;return c.useEffect(()=>{if(!a)return;document.dispatchEvent(new CustomEvent(Ve,{detail:Gb}));let e=e=>{e.detail!==Gb&&o()};return document.addEventListener(Ve,e),()=>document.removeEventListener(Ve,e)},[a,o]),c.createElement(`div`,{ref:r,className:`dsh-tw-rightbar-tab`})}function qb(){return{id:Wb,kind:`dsh-tiddlywiki`,title:()=>Ge(),guide:[{order:10,title:()=>`TiddlyWiki 知识库`,description:()=>`在右侧边栏打开 TiddlyWiki 编辑器(与聊天并排)`,icon:qe}]}}function Jb(e,t){let n=[];try{n.push(e.register(qb()));let r=t.inject(`sidebar.right.pane.tab`,()=>t.register({name:`sidebar.right.pane.tab`,key:Wb},Kb));r!==void 0&&n.push(r)}catch(e){for(let e of n.splice(0))e();console.error(`[dsh-tiddlywiki] rightbar tab mount failed:`,e);return}return $e(),()=>{for(let e of n.splice(0))e()}}const Yb=[`slots`];function Xb(e){try{let t=[],n=!1,r=()=>{n=!0;for(let e of t.splice(0))e()},i=(e,t)=>{try{t()}catch(t){console.error(`[dsh-tiddlywiki] ${e} failed:`,t)}};i(`styles`,()=>t.push(d()));let a=new f,o,s;if(i(`quick-note widget`,()=>{o=Vy(),t.push(()=>o?.dispose())}),i(`sync controller`,()=>{s=Gy(),t.push(()=>s?.dispose())}),i(`sidebar entry`,()=>t.push(be(a))),i(`center panel`,()=>t.push(ft(a))),o!==void 0&&s!==void 0){let e=o,n=s;i(`knowledge FAB`,()=>t.push(Qy(a,e,n)))}i(`editor popup`,()=>t.push(Ct)),e.slots!==void 0&&Yy().then(r=>{if(n)return;let a=o;r.showQuickNoteDock&&a!==void 0&&i(`quick-note dock`,()=>{let n=e.slots?.inject(`conversation.input.dock`,()=>e.slots?.register({name:`conversation.input.dock`,id:`quick-note`,order:8,label:`快速笔记`},$y(a)));n!==void 0&&t.push(n)}),i(`session summary tab`,()=>{let n=ib(e.slots,r);n!==void 0&&t.push(n)})}).catch(e=>{console.error(`[dsh-tiddlywiki] ui config load failed:`,e)}),i(`rightbar mount`,()=>{let r,i=a=>{let o=e.get?.(`sidebarRightTabs`);if(o===void 0){a<6&&!n&&(r=window.setTimeout(()=>i(a+1),500*(a+1)));return}Yy().then(r=>{if(n||!r.showRightbarTab)return;let i=Jb(o,e.slots);i!==void 0&&t.push(i)}).catch(e=>{console.error(`[dsh-tiddlywiki] rightbar config load failed:`,e)})};t.push(()=>{r!==void 0&&window.clearTimeout(r)}),i(0)}),i(`tool views`,()=>{e.slots!==void 0&&t.push(...Hb(e.slots))}),i(`wiki link interceptor`,()=>t.push(Ub())),i(`settings section`,()=>{let n=e.slots?.inject(`settings.section`,()=>e.slots?.register({name:`settings.section`,id:`dsh-tiddlywiki`,order:50,label:`TiddlyWiki 知识库`},pb));n!==void 0&&t.push(n)}),e.effect===void 0?window.addEventListener(`pagehide`,r,{once:!0}):e.effect(()=>r,`dsh-tiddlywiki: client mount`)}catch(e){console.error(`[dsh-tiddlywiki] client half failed to start:`,e)}}exports.apply=Xb,exports.inject=Yb,exports.name=`dsh-tiddlywiki/client`;
|