dsh-tiddlywiki 0.19.2 → 0.19.3
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/README.md +4 -0
- package/lib/client.js +1 -1
- package/lib/index.js +333 -141
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client/settings-page.ts +2 -2
- package/src/host/admin.ts +153 -52
- package/src/host/clip-bridge.ts +29 -2
- package/src/host/http.ts +35 -0
- package/src/host/routes.ts +141 -44
- package/src/host/session-summary.ts +30 -8
- package/src/index.ts +2 -1
package/README.md
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
| 🛡️ **不会被覆盖的写入** | 所有写入路径(agent 工具 **与** 快速笔记/编辑器路由)都**先读后写**:不传 tags 就保留原有标签与自定义字段;`tiddlywiki_put(..., expectedModified/expectedRevision)` 乐观并发——读取后若有人(在 TW 编辑器里)改过,写入被拒绝(HTTP 409)而不是静默覆盖;`tiddlywiki_delete` 默认**软删除进回收站**,`tiddlywiki_trash` 可恢复(v0.19.0 / v0.19.1) |
|
|
30
30
|
| 🧼 **渲染片段净化** | 回复流卡片与会话汇总注入的 TW 片段先经 **host 白名单净化**(丢 `iframe`/`script`/`svg`/`on*`/`javascript:`/`data:text/html` 等)——TW 自己的解析器只剥 `on*`,`<iframe src="javascript:…">` 会原样通过并在 DSH 页面里执行(v0.19.1 修复的存储型 XSS) |
|
|
31
31
|
| 🔒 **写路由方法校验** | 每个写路由只接受自己的 HTTP 方法:跨站 `GET /sync`、`GET /restart`、`GET /upload` 一律 405 且无副作用(v0.19.0 修复了「任意网页一张 `<img>` 即可触发 pull/commit/push」的 CSRF 面) |
|
|
32
|
+
| 🔑 **密钥不外泄** | `bridge.token` / `ui.sendToAgent.token` 在 `/admin/state`、`/admin/config` 的回包里是 `********`(设置页原样保存 ≠ 覆盖,清空即删除),`git.remote` 里的 PAT 打码;**`/tw` 与 `/api` 代理拒绝 `$:/plugins/dsh-tiddlywiki/` 命名空间**——此前可绕过 `/get` 的限制直接经代理读到配置 tiddler(v0.19.3) |
|
|
33
|
+
| 🧯 **路由不会拖垮进程** | 所有路由经 `guardHandler` 包装:任何 rejection(含代理里 try 之外的 `new URL()`)都变成 413/500 响应,而不是宿主未处理的 promise rejection(那会**直接结束 dsh web 进程**并挂死请求);剪藏桥 listen 后保留常驻 `error` 监听(v0.19.3) |
|
|
32
34
|
| 📊 **回复流卡片** | 工具结果显示原生 TW 卡片(**按笔记自己的内容类型渲染**:Markdown 笔记就是 Markdown,v0.18.0);`[标题](/dsh-tiddlywiki/tw/#标题)` 点击直达 TW 面板 |
|
|
33
35
|
| 📤 **发送给 Agent** | TW 笔记工具栏一键把当前笔记注入所选 dsh 会话(可选工作模式/权限/附加说明) |
|
|
34
36
|
| 🧭 **内嵌编辑器** | 中央列内嵌完整 TW 5 编辑器(同源代理,Tailscale/内网/域名/HTTPS 均可) |
|
|
@@ -291,6 +293,8 @@ lib/ # 预构建产物(发布含 lib/**,提交入库;
|
|
|
291
293
|
|
|
292
294
|
> 最近几个主要版本的一句话记录(完整变更见 [Releases](https://github.com/bbqisbbq/dsh-tiddlywiki/releases) / git log)。
|
|
293
295
|
|
|
296
|
+
- **v0.19.3**(2026-09-11):**清掉审计清单里剩下的中优先级项**(安全面 / 健壮性 / 正确性)。**密钥不再外泄**:`bridge.token` / `ui.sendToAgent.token` 会被 `GET /admin/state` 与 `POST /admin/config` 的回包替换成 `********`(并给 `tokenSet` 标记),设置页原样保存不会把真 token 覆盖成掩码、清空即删除;`git.remote` 里的 PAT 同时打码,回填同值也被丢弃。更要紧的是**代理旁路**:`/get` 早先禁止读插件配置 tiddler,但 `/tw` 与 `/api` 会把任意路径转发给 TW 子进程,而它的 TiddlyWeb REST 对 `$:/…` 标题照答不误——`GET /dsh-tiddlywiki/tw/recipes/default/tiddlers/%24%3A%2Fplugins%2Fdsh-tiddlywiki%2Fconfig` 实测能拿到配置正文。现在两个代理都拦截 `$:/plugins/dsh-tiddlywiki/` 命名空间(selftest 有回归断言)。**健壮性**:所有路由统一经 `guardHandler` 包装——此前每个注册都是 `void handleX(req,res)`,而宿主没有 `unhandledRejection` 处理器,任何一次 rejection(含代理里 try 之外的 `new URL()`)都会**直接结束 dsh web 进程**、请求挂死;剪藏桥 listen 之后补上**常驻 `error` 监听**(此前移除唯一监听后,运行期 server error 就是未处理事件 → 崩进程),`stop()` 用 `closeAllConnections()` + 1s 上限,keep-alive 不再是卸载时的死等;`/tw` 代理在客户端断连时**中止上游 fetch 并销毁流**(此前会一直拉到 30s 超时)。**正确性**:会话汇总不再把查询失败(超时/5xx)报成「已删除/不存在」(只有 404 才算不存在),来自请求体/会话日志的 sessionId、rename 旧标题、检索词一律 HTML 转义(TW 会原样透传 HTML,汇总片段又会被注入 DSH 页面),sessionId 还加了字符集白名单;`/upload` 改**原子写**(`wx` + 仅对 EEXIST 走后缀链,修掉 TOCTOU 与「任何 access 错误都当名字可用」)、文件名末尾点/空格先规范化(`evil.html.` 此前能绕过可执行扩展名黑名单);SSRF 白名单补上多播 `224/4`、保留 `240/4`(含 `255.255.255.255`)、`192.0.2.0/24`、`198.51.100.0/24`、`203.0.113.0/24`、`192.88.99.0/24`;`readWikiInfo` 对顶层 `null`/数组给出可读错误而不是 `TypeError`;`/admin/info` 空操作不再重写 `tiddlywiki.info` + 重启 TW,校验失败 400 / 内部失败 500 分开;`/agent/create` 先校验工作模式再建目录(此前未知模式会留下孤儿目录);body 超限统一 413。
|
|
297
|
+
|
|
294
298
|
- **v0.19.2**(2026-09-11):**v0.19.1 的内容 + 让 flush 哨兵真正生效**。v0.19.1 在 npm 上只是被 **staged**(未确认),而那份 tarball 少了下面这个修复,所以补一个版本号(**请以 0.19.2 为准,0.19.1 可以取消掉**)。修复内容:`flushPendingWrites`(「重启 TW 前把 syncer 队列排干」的哨兵)**从来没成功过**——① 它写 `type: 'text/plain'` 却去等 `.tid` 文件,而 TW 的文件系统适配器按内容类型决定扩展名(`text/plain` 实际落 `.txt` + `.txt.meta`);② 它用 `mtime >= startedAt` 判定,而哨兵是紧接在等待之前写的,Windows 上新文件的 mtime 可能落在同一/前一个时钟刻,条件永不成立。两者叠加 → 每次调用都超时返回 false,而**所有调用方只把它当 warning**:`/sync`、工具 `git_sync`、seed 重启与启动路径的「排干 syncer」全部静默失效(启动路径还白等 8 秒)。现在按「文件名含 `dsh-tiddlywiki_flush-probe` + 文件内容含本次随机戳」判定(与扩展名/时钟无关),实测 <1.2s 返回;selftest 加了断言,另修掉一处「轮询结果被忽略就重启」的测试竞态(首轮 GitHub CI selftest 抓到的 404)。**其余同 v0.19.1**:CI 复活(`.gitattributes` LF + sourcemap 可复现)、渲染片段净化(存储型 XSS)、`/note` `/edit` 共享写策略(不再清掉人类笔记的标签/自定义字段)、重启单飞与启动/teardown 握手、`tiddlywiki_get` 字段摊平、`lint` 两个坏检查、客户端泄漏与草稿回写等。
|
|
295
299
|
- **v0.19.1**(2026-09-11):**第二轮代码审计的修复版 + 让 CI 重新变绿**。**顺带抓出一个"静默失效"的哨兵**:`flushPendingWrites` 一直用 `type: 'text/plain'` 写哨兵、却去等 `.tid` 文件(TW 的文件系统适配器按内容类型决定扩展名,`text/plain` 实际落 `.txt` + `.txt.meta`),叠加 `mtime >= startedAt` 的判定在新写入的同一时钟刻可能永不成立 → 每次调用都超时返回 false,而所有调用方只把它当 warning。也就是说 v0.19.0 声称的「重启前排干 syncer」**其实一直没生效**(`/sync`、工具 `git_sync`、seed 重启与启动路径全都受影响,启动路径还会白等 8 秒)。现在改成**按内容随机戳匹配**(不依赖扩展名、不依赖文件时间),实测 <1.2s 返回,并有 selftest 断言守门。**CI 其实是红的**:`lib/index.js.map` 内嵌源文件原文(sourcemap 的 `sourcesContent`),Windows 工作区是 CRLF、GitHub runner 检出是 LF,Linux 上重建出的 map 与提交版必然不同 → `static` 作业的 `git diff --exit-code -- lib/` 每次失败,而它一挂,另外三个 job(`needs: static`)**根本不会跑**(v0.19.0 声称的四档守门实际停摆)。修法:新增 **`.gitattributes`(`* text=auto eol=lf`)** 把工作区钉成 LF 并重建提交 lib/;顺带补上 **send-to-agent 的「bundle ↔ seed 逐字节」守门**(render 早就有,缺这条时「跑了 build 忘跑 gen」会 CI 全绿却发旧按钮)、`prepublishOnly` 预检、CI 失败时能看懂的错误提示。**安全(存储型 XSS)**:回复流卡片与会话汇总把 TW 片段 `dangerouslySetInnerHTML` 进 DSH 页面,而 TW 的解析器只剥 `on*`——实测 `<iframe src="javascript:…">`、`<a href="javascript:…">`、`<form action="javascript:…">` 全部原样通过(任何写进 wiki 的正文——agent 笔记、剪藏、导入——都能在 DSH 同源页面执行脚本并调用未鉴权的 `/dsh-tiddlywiki/*` 路由)。新增 **host 侧片段净化器**(`src/host/sanitize.ts`:丢 script/style/iframe/object/embed/form/svg/math…、丢 `on*`/`srcdoc`/`srcset`、URL 属性只放行 http(s)/mailto/tel/相对路径/栅格 `data:image/*`,并先做实体解码挡 `javascript:` 这类混淆),新增 **`POST /dsh-tiddlywiki/render`** 作为客户端唯一渲染入口(客户端不再直连 TW 的未净化 `/tw/render`,因此**老 wiki 也立刻受保护**);配套 payload 回归 `scripts/verify-render-sanitizer.mjs`(已进 CI)。**数据安全**:`/note` 与 `/edit` 此前不读旧条目就整体 PUT,用同名标题保存会**清掉人类笔记的标签与自定义字段**——现在两条人类路径与 agent 工具共用新的 **`src/host/write-policy.ts`**(先读后写、保留字段、`agent-written` 只给 agent 新建的条目);快速笔记卡片对「🕘 最近」载入的笔记回传 **`expectedRevision`**,人类在 TW 里的并发修改会让保存得到 **409** 而不是被覆盖;**重启 TW 前先排干 syncer**(`/sync` 与工具 `git_sync` 此前漏了 flush 哨兵——刚保存的笔记可能被重启吞掉);`WikiServer.restart()` 改为**内部单飞**(admin 路由不受 routes 层互斥保护,并发重启会留下孤儿 TW 进程);启动任务是 fire-and-forget,teardown 现在**先置 `disposed` 并等它收尾**(插件热更新/禁用时不再「disposer 先跑完、startup 后 spawn」留下孤儿进程与泄漏监听)。**工具层**:`tiddlywiki_get` 的自定义字段此前渲染成 `fields=[object Object]`(单条 GET 的 `fields` 嵌套没摊平)——`q`/`due`/`clip-url` 对模型完全不可见,已修;`tiddlywiki_lint` 的死链检查把**每一条指向图片/附件的链接**都误报成死链(标题集合取自排除二进制的列表),`missing-type` 则**永远不触发**(TW 服务端会给无 type 的条目补 `text/vnd.tiddlywiki`,改用 `[!has[type]]` 过滤器判定),描述与 `checks` 里的 `large-binary` 从未实现,已删除;`tw-api` 的瘦列表(`/tags`、lint 用)加短 TTL 缓存。**客户端**:TW 就绪重试的 40×150ms 定时器、`sync-button` 卸载后的迟到回调、`injectStyles` 的共享 `<style>` 被旧 disposer 删掉、渲染阶段改模块级缓存(改到 effect 阶段)、`tiddlywiki_list_tags` 卡片不截断(现最多 60 个 + 提示余量);快速笔记「在 TW 中编辑」成功后不再把同一份内容重新写成「未保存草稿」。**工程**:工具层 E2E 从 10 个工具补齐到 **15 个**(并断言一个都不能少)、selftest 新增「人类写路径保留字段 / 409 冲突」与「host /render 净化」端到端断言、`package-lock.json` 版本与 npm 描述同步。
|
|
296
300
|
|
package/lib/client.js
CHANGED
|
@@ -719,7 +719,7 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
719
719
|
}`,{label:`enum`,detail:`definition`,type:`keyword`})]),Ym=new nl,Xm=new Set([`Script`,`Block`,`FunctionExpression`,`FunctionDeclaration`,`ArrowFunction`,`MethodDeclaration`,`ForStatement`]);function Zm(e){return(t,n)=>{let r=t.node.getChild(`VariableDefinition`);return r&&n(r,e),!0}}const Qm=[`FunctionDeclaration`],$m={FunctionDeclaration:Zm(`function`),ClassDeclaration:Zm(`class`),ClassExpression:()=>!0,EnumDeclaration:Zm(`constant`),TypeAliasDeclaration:Zm(`type`),NamespaceDeclaration:Zm(`namespace`),VariableDefinition(e,t){e.matchContext(Qm)||t(e,`variable`)},TypeDefinition(e,t){t(e,`type`)},__proto__:null};function eh(e,t){let n=Ym.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(G.IncludeAnonymous).iterate(t=>{if(i)i=!1;else if(t.name){let e=$m[t.name];if(e&&e(t,a)||Xm.has(t.name))return!1}else if(t.to-t.from>8192){for(let n of eh(e,t.node))r.push(n);return!1}}),Ym.set(t,r),r}const th=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,nh=[`TemplateString`,`String`,`RegExp`,`LineComment`,`BlockComment`,`VariableDefinition`,`TypeDefinition`,`Label`,`PropertyDefinition`,`PropertyName`,`PrivatePropertyDefinition`,`PrivatePropertyName`,`JSXText`,`JSXAttributeValue`,`JSXOpenTag`,`JSXCloseTag`,`JSXSelfClosingTag`,`.`,`?.`];function rh(e){let t=Y(e.state).resolveInner(e.pos,-1);if(nh.indexOf(t.name)>-1)return null;let n=t.name==`VariableName`||t.to-t.from<20&&th.test(e.state.sliceDoc(t.from,t.to));if(!n&&!e.explicit)return null;let r=[];for(let n=t;n;n=n.parent)Xm.has(n.name)&&(r=r.concat(eh(e.state.doc,n)));return{options:r,from:n?t.from:e.pos,validFor:th}}const ih=$l.define({name:`javascript`,parser:Km.configure({props:[_u.add({IfStatement:ku({except:/^\s*({|else\b)/}),TryStatement:ku({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:Ou,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:Eu({closing:`}`}),ArrowFunction:e=>e.baseIndent+e.unit,"TemplateString BlockComment":()=>null,"Statement Property":ku({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}}),ju.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":Mu,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:`$`}}),ah={test:e=>/^JSX/.test(e.name),facet:Yl({commentTokens:{block:{open:`{/*`,close:`*/}`}}})},oh=ih.configure({dialect:`ts`},`typescript`),sh=ih.configure({dialect:`jsx`,props:[Xl.add(e=>e.isTop?[ah]:void 0)]}),ch=ih.configure({dialect:`jsx ts`,props:[Xl.add(e=>e.isTop?[ah]:void 0)]},`typescript`);let lh=e=>({label:e,type:`keyword`});const uh=`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(lh),dh=uh.concat([`declare`,`implements`,`private`,`protected`,`public`].map(lh));function fh(e={}){let t=e.jsx?e.typescript?ch:sh:e.typescript?oh:ih,n=e.typescript?Jm.concat(dh):qm.concat(uh);return new lu(t,[ih.data.of({autocomplete:rd(nh,nd(n))}),ih.data.of({autocomplete:rh}),e.jsx?gh:[]])}function ph(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 mh(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),gh=H.inputHandler.of((e,t,n,r,i)=>{if((hh?e.composing:e.compositionStarted)||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!ih.isActiveAt(e.state,t,-1))return!1;let a=i(),{state:o}=a,s=o.changeByRange(e=>{let{head:t}=e,n=Y(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=mh(o.doc,r.firstChild,t))||r.firstChild?.name==`JSXFragmentTag`)){let e=`${i}>`;return{range:j.cursor(t+e.length,-1),changes:{from:t,insert:e}}}}else if(r==`>`){let r=ph(n);if(r&&r.name==`JSXOpenTag`&&!/^\/?>|^<\//.test(o.doc.sliceString(t,t+2))&&(i=mh(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)}),_h=[`_blank`,`_self`,`_top`,`_parent`],vh=[`ascii`,`utf-8`,`utf-16`,`latin1`,`latin1`],yh=[`get`,`post`,`put`,`delete`],bh=[`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`],xh=[`true`,`false`],Q={},Sh={a:{attrs:{href:null,ping:null,type:null,media:null,target:_h,hreflang:null}},abbr:Q,address:Q,area:{attrs:{alt:null,coords:null,href:null,target:null,ping:null,media:null,hreflang:null,type:null,shape:[`default`,`rect`,`circle`,`poly`]}},article:Q,aside:Q,audio:{attrs:{src:null,mediagroup:null,crossorigin:[`anonymous`,`use-credentials`],preload:[`none`,`metadata`,`auto`],autoplay:[`autoplay`],loop:[`loop`],controls:[`controls`]}},b:Q,base:{attrs:{href:null,target:_h}},bdi:Q,bdo:Q,blockquote:{attrs:{cite:null}},body:Q,br:Q,button:{attrs:{form:null,formaction:null,name:null,value:null,autofocus:[`autofocus`],disabled:[`autofocus`],formenctype:bh,formmethod:yh,formnovalidate:[`novalidate`],formtarget:_h,type:[`submit`,`reset`,`button`]}},canvas:{attrs:{width:null,height:null}},caption:Q,center:Q,cite:Q,code:Q,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:Q,del:{attrs:{cite:null,datetime:null}},details:{attrs:{open:[`open`]}},dfn:Q,div:Q,dl:Q,dt:Q,em:Q,embed:{attrs:{src:null,type:null,width:null,height:null}},eventsource:{attrs:{src:null}},fieldset:{attrs:{disabled:[`disabled`],form:null,name:null}},figcaption:Q,figure:Q,footer:Q,form:{attrs:{action:null,name:null,"accept-charset":vh,autocomplete:[`on`,`off`],enctype:bh,method:yh,novalidate:[`novalidate`],target:_h}},h1:Q,h2:Q,h3:Q,h4:Q,h5:Q,h6:Q,head:{children:[`title`,`base`,`link`,`style`,`meta`,`script`,`noscript`,`command`]},header:Q,hgroup:Q,hr:Q,html:{attrs:{manifest:null}},i:Q,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:bh,formmethod:yh,formnovalidate:[`novalidate`],formtarget:_h,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:Q,keygen:{attrs:{challenge:null,form:null,name:null,autofocus:[`autofocus`],disabled:[`disabled`],keytype:[`RSA`]}},label:{attrs:{for:null,form:null}},legend:Q,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:Q,menu:{attrs:{label:null,type:[`list`,`context`,`toolbar`]}},meta:{attrs:{content:null,charset:vh,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:Q,noscript:Q,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:Q,param:{attrs:{name:null,value:null}},pre:Q,progress:{attrs:{value:null,max:null}},q:{attrs:{cite:null}},rp:Q,rt:Q,ruby:Q,samp:Q,script:{attrs:{type:[`text/javascript`],src:null,async:[`async`],defer:[`defer`],charset:vh}},section:Q,select:{attrs:{form:null,name:null,size:null,autofocus:[`autofocus`],disabled:[`disabled`],multiple:[`multiple`]}},slot:{attrs:{name:null}},small:Q,source:{attrs:{src:null,type:null,media:null}},span:Q,strong:Q,style:{attrs:{type:[`text/css`],media:null,scoped:null}},sub:Q,summary:Q,sup:Q,table:Q,tbody:Q,td:{attrs:{colspan:null,rowspan:null,headers:null}},template:Q,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:Q,th:{attrs:{colspan:null,rowspan:null,headers:null,scope:[`row`,`col`,`rowgroup`,`colgroup`]}},thead:Q,time:{attrs:{datetime:null}},title:Q,tr:Q,track:{attrs:{src:null,label:null,default:null,kind:[`subtitles`,`captions`,`descriptions`,`chapters`,`metadata`],srclang:null}},ul:{children:[`li`,`script`,`template`,`ul`,`ol`]},var:Q,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:Q},Ch={accesskey:null,class:null,contenteditable:xh,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:xh,autocorrect:xh,autocapitalize:xh,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":xh,"aria-autocomplete":[`inline`,`list`,`both`,`none`],"aria-busy":xh,"aria-checked":[`true`,`false`,`mixed`,`undefined`],"aria-controls":null,"aria-describedby":null,"aria-disabled":xh,"aria-dropeffect":null,"aria-expanded":[`true`,`false`,`undefined`],"aria-flowto":null,"aria-grabbed":[`true`,`false`,`undefined`],"aria-haspopup":xh,"aria-hidden":xh,"aria-invalid":[`true`,`false`,`grammar`,`spelling`],"aria-label":null,"aria-labelledby":null,"aria-level":null,"aria-live":[`off`,`polite`,`assertive`],"aria-multiline":xh,"aria-multiselectable":xh,"aria-owns":null,"aria-posinset":null,"aria-pressed":[`true`,`false`,`mixed`,`undefined`],"aria-readonly":xh,"aria-relevant":null,"aria-required":xh,"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},wh=`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 wh)Ch[e]=null;var Th=class{constructor(e,t){this.tags={...Sh,...e},this.globalAttrs={...Ch,...t},this.allTags=Object.keys(this.tags),this.globalAttrNames=Object.keys(this.globalAttrs)}};Th.default=new Th;function Eh(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 Dh(e,t=!1){for(;e;e=e.parent)if(e.name==`Element`)if(t)t=!1;else return e;return null}function Oh(e,t,n){return n.tags[Eh(e,Dh(t))]?.children||n.allTags}function kh(e,t){let n=[];for(let r=Dh(t);r&&!r.type.isTop;r=Dh(r.parent)){let i=Eh(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 Ah=/^[:\-\.\w\u00b7-\uffff]*$/;function jh(e,t,n,r,i){let a=/\s*>/.test(e.sliceDoc(i,i+5))?``:`>`,o=Dh(n,n.name==`StartTag`||n.name==`TagName`);return{from:r,to:i,options:Oh(e.doc,o,t).map(e=>({label:e,type:`type`})).concat(kh(e.doc,n).map((e,t)=>({label:`/`+e,apply:`/`+e+a,type:`type`,boost:99-t}))),validFor:/^\/?[:\-\.\w\u00b7-\uffff]*$/}}function Mh(e,t,n,r){let i=/\s*>/.test(e.sliceDoc(r,r+5))?``:`>`;return{from:n,to:r,options:kh(e.doc,t).map((e,t)=>({label:e,apply:e+i,type:`type`,boost:99-t})),validFor:Ah}}function Nh(e,t,n,r){let i=[],a=0;for(let r of Oh(e.doc,n,t))i.push({label:`<`+r,type:`type`});for(let t of kh(e.doc,n))i.push({label:`</`+t+`>`,type:`type`,boost:99-a++});return{from:r,to:r,options:i,validFor:/^<\/?[:\-\.\w\u00b7-\uffff]*$/}}function Ph(e,t,n,r,i){let a=Dh(n),o=a?t.tags[Eh(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:Ah}}function Fh(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=Dh(n),i=r?t.tags[Eh(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 Ih(e,t){let{state:n,pos:r}=t,i=Y(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)?Mh(n,i,i.from,r):jh(n,e,i,i.from,r):i.name==`StartTag`||i.name==`IncompleteTag`?jh(n,e,i,r,r):i.name==`StartCloseTag`||i.name==`IncompleteCloseTag`?Mh(n,i,r,r):i.name==`OpenTag`||i.name==`SelfClosingTag`||i.name==`AttributeName`?Ph(n,e,i,i.name==`AttributeName`?i.from:r,r):i.name==`Is`||i.name==`AttributeValue`||i.name==`UnquotedAttributeValue`?Fh(n,e,i,i.name==`Is`?r:i.from,r):t.explicit&&(a.name==`Element`||a.name==`Text`||a.name==`Document`)?Nh(n,e,i,r):null}function Lh(e){return Ih(Th.default,e)}function Rh(e){let{extraTags:t,extraGlobalAttributes:n}=e,r=n||t?new Th(t,n):Th.default;return e=>Ih(r,e)}const zh=ih.parser.configure({top:`SingleExpression`}),Bh=[{tag:`script`,attrs:e=>e.type==`text/typescript`||e.lang==`ts`,parser:oh.parser},{tag:`script`,attrs:e=>e.type==`text/babel`||e.type==`text/jsx`,parser:sh.parser},{tag:`script`,attrs:e=>e.type==`text/typescript-jsx`,parser:ch.parser},{tag:`script`,attrs(e){return/^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(e.type)},parser:zh},{tag:`script`,attrs(e){return!e.type||/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(e.type)},parser:ih.parser},{tag:`style`,attrs(e){return(!e.lang||e.lang==`css`)&&(!e.type||/^(text\/)?(x-)?(stylesheet|css)$/i.test(e.type))},parser:Mm.parser}],Vh=[{name:`style`,parser:Mm.parser.configure({top:`Styles`})}].concat(wh.map(e=>({name:e,parser:ih.parser}))),Hh=$l.define({name:`html`,parser:Zp.configure({props:[_u.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}}),ju.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}}}),Bu.add({"OpenTag CloseTag":e=>e.getChild(`TagName`)})]}),languageData:{commentTokens:{block:{open:`<!--`,close:`-->`}},indentOnInput:/^\s*<\/\w+\W$/,wordChars:`-_`}}),Uh=Hh.configure({wrap:tm(Bh,Vh)});function Wh(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=tm((e.nestedLanguages||[]).concat(Bh),(e.nestedAttributes||[]).concat(Vh))),new lu(n?Hh.configure({wrap:n,dialect:t}):t?Uh.configure({dialect:t}):Uh,[Uh.data.of({autocomplete:Rh(e)}),e.autoCloseTags===!1?[]:qh,fh().support,Nm().support])}const Gh=new Set(`area base br col command embed frame hr img input keygen link meta param source track wbr menuitem`.split(` `));function Kh(e,t,n){for(;;){if(t.lastChild?.name!=`CloseTag`)return!1;let r=t.parent;if(!r||Eh(e,r)!=n)return!0;t=r}}const qh=H.inputHandler.of((e,t,n,r,i)=>{if(e.composing||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!Uh.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=Y(o).resolveInner(n,-1),a;if(t&&r==`>`&&i.name==`EndTag`){let t=i.parent;if((a=Eh(o.doc,t.parent,n))&&!Gh.has(a)&&!Kh(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=Eh(o.doc,e,n))&&!Gh.has(a)){let e=n+ +(o.doc.sliceString(n,n+1)===`>`),t=`${a}>`;return{range:j.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)}),Jh=Yl({commentTokens:{block:{open:`<!--`,close:`-->`}}}),Yh=new U,Xh=Af.configure({props:[ju.add(e=>!e.is(`Block`)||e.is(`Document`)||Zh(e)!=null||Qh(e)?void 0:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})),Yh.add(Zh),_u.add({Document:()=>null}),Jl.add({Document:Jh})]});function Zh(e){let t=/^(?:ATX|Setext)Heading(\d)$/.exec(e.name);return t?+t[1]:void 0}function Qh(e){return e.name==`OrderedList`||e.name==`BulletList`}function $h(e,t){let n=e;for(;;){let e=n.nextSibling,r;if(!e||(r=Zh(e.type))!=null&&r<=t)break;n=e}return n.to}const eg=Au.of((e,t,n)=>{for(let r=Y(e).resolveInner(n,-1);r&&!(r.from<t);r=r.parent){let e=r.type.prop(Yh);if(e==null)continue;let t=$h(r,e);if(t>n)return{from:n,to:t}}return null});function tg(e){return new Zl(Jh,e,[],`markdown`)}const ng=tg(Xh),rg=tg(Xh.configure([Xf,$f,Qf,ep,{props:[ju.add({Table:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})})]}]));function ig(e,t){return n=>{if(n&&e){let t=null;if(n=/\S*/.exec(n)[0],t=typeof e==`function`?e(n):uu.matchLanguageName(e,n,!0),t instanceof uu)return t.support?t.support.language.parser:nu.getSkippingParser(t.load());if(t)return t.parser}return t?t.parser:null}}var ag=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(+sg(this.item,e)[2]+t):``;return this.spaceBefore+n+this.type+this.spaceAfter}};function og(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 ag(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 ag(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 ag(i.parent,s,s+t,a[1],e,n,i))}}return r}function sg(e,t){return/^(\s*)(\d+)(?=[.)])/.exec(t.sliceString(e.from,e.from+10))}function cg(e,t,n,r=0){for(let i=-1,a=e;;){if(a.name==`ListItem`){let e=sg(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 lg(e,t){let n=/^[ \t]*/.exec(e)[0].length;if(!n||t.facet(fu)!=` `)return e;let r=Un(e,4,n),i=``;for(let e=r;e>0;)e>=4?(i+=` `,e-=4):(i+=` `,e--);return i+e.slice(n)}const ug=((e={})=>({state:t,dispatch:n})=>{let r=Y(t),{doc:i}=t,a=null,o=t.changeByRange(n=>{if(!n.empty||!rg.isActiveAt(t,n.from,-1)&&!rg.isActiveAt(t,n.from,1))return a={range:n};let o=n.from,s=i.lineAt(o),c=og(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`&&cg(l.item,i,r,-2),e&&e.node.name==`OrderedList`&&cg(e.item,i,r),{range:j.cursor(t+n.length),changes:r}}else{let e=pg(c,t,s);return{range:j.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`&&cg(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?Un(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=lg(p,t),fg(l.node,t.doc)&&(p=pg(c,t,s)+t.lineBreak+p),d.push({from:m,to:o,insert:t.lineBreak+p}),{range:j.cursor(m+p.length+1),changes:d}});return a?!1:(n(t.update(o,{scrollIntoView:!0,userEvent:`input`})),!0)})();function dg(e){return e.name==`QuoteMark`||e.name==`ListMark`}function fg(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 pg(e,t,n){let r=``;for(let t=0,i=e.length-2;t<=i;t++)r+=e[t].blank(t<i?Un(n.text,4,e[t+1].from)-r.length:null,t<i);return lg(r,t)}function mg(e,t){let n=e.resolveInner(t,-1),r=t;dg(n)&&(r=n.from,n=n.parent);for(let e;e=n.childBefore(r);)if(dg(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:ug},{key:`Backspace`,run:({state:e,dispatch:t})=>{let n=Y(e),r=null,i=e.changeByRange(t=>{let i=t.from,{doc:a}=e;if(t.empty&&rg.isActiveAt(e,t.from)){let t=a.lineAt(i),r=og(mg(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:j.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(Un(t.text,4,n.to)-Un(t.text,4,n.from));return r==t.from&&(i=lg(i,e)),{range:j.cursor(r+i.length),changes:{from:r,to:t.from+n.to,insert:i}}}if(r<i)return{range:j.cursor(r),changes:{from:r,to:i}}}}}return r={range:t}});return r?!1:(t(e.update(i,{scrollIntoView:!0,userEvent:`delete`})),!0)}}],gg=Wh({matchClosingTags:!1});function _g(e={}){let{codeLanguages:t,defaultCodeLanguage:n,addKeymap:r=!0,base:{parser:i}=ng,completeHTMLTags:a=!0,pasteURLAsLink:o=!0,htmlTagLanguage:s=gg}=e;if(!(i instanceof rf))throw RangeError("Base parser provided to `markdown` should be a Markdown parser");let c=e.extensions?[e.extensions]:[],l=[s.support,eg],u;o&&l.push(Sg),n instanceof lu?(l.push(n.support),u=n.language):n&&(u=n);let d=t||u?ig(t,u):void 0;c.push(Mf({codeParser:d,htmlParser:s.language.parser})),r&&l.push(Gt.high(rc.of(hg)));let f=tg(i.configure(c));return a&&l.push(f.data.of({autocomplete:vg})),new lu(f,l)}function vg(e){let{state:t,pos:n}=e,r=/<[:\-\.\w\u00b7-\uffff]*$/.exec(t.sliceDoc(n-25,n));if(!r)return null;let i=Y(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:bg(),validFor:/^<[:\-\.\w\u00b7-\uffff]*$/}}let yg=null;function bg(){if(yg)return yg;let e=Lh(new $u(P.create({extensions:gg}),0,!0));return yg=e?e.options:[]}const xg=/code|horizontalrule|html|link|comment|processing|escape|entity|image|mark|url/i,Sg=H.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),!rg.isActiveAt(t.state,n.from,1)))return!1;let i=Y(t.state),a=!1;return i.iterate({from:n.from,to:n.to,enter:e=>{(e.from>n.from||xg.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)}}),Cg=e=>{let{state:t}=e,n=t.doc.lineAt(t.selection.main.from),r=Og(e.state,n.from);return r.line?Tg(e):r.block?Dg(e):!1};function wg(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 Tg=wg(Mg,0),Eg=wg(jg,0),Dg=wg((e,t)=>jg(e,t,Ag(t)),0);function Og(e,t){let n=e.languageDataAt(`commentTokens`,t,1);return n.length?n[0]:{}}function kg(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 Ag(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 jg(e,t,n=t.selection.ranges){let r=n.map(e=>Og(t,e.from).block);if(!r.every(e=>e))return null;let i=n.map((e,n)=>kg(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 Mg(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=Og(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 Ng=sn.define(),Pg=sn.define(),Fg=M.define(),Ig=M.define({combine(e){return wn(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)})}}),Lg=Ht.define({create(){return t_.empty},update(e,t){let n=t.state.facet(Ig),r=t.annotation(Ng);if(r){let i=Wg.fromTransaction(t,r.selection),a=r.side,o=a==0?e.undone:e.done;return o=i?Gg(o,o.length,n.minDepth,i):Xg(o,t.startState.selection),new t_(a==0?r.rest:o,a==0?o:r.rest)}let i=t.annotation(Pg);if((i==`full`||i==`before`)&&(e=e.isolate()),t.annotation(un.addToHistory)===!1)return t.changes.empty?e:e.addMapping(t.changes.desc);let a=Wg.fromTransaction(t),o=t.annotation(un.time),s=t.annotation(un.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 t_(e.done.map(Wg.fromJSON),e.undone.map(Wg.fromJSON))}});function Rg(e={}){return[Lg,Ig.of(e),H.domEventHandlers({beforeinput(e,t){let n=e.inputType==`historyUndo`?Bg:e.inputType==`historyRedo`?Vg:null;return n?(e.preventDefault(),n(t)):!1}})]}function zg(e,t){return function({state:n,dispatch:r}){if(!t&&n.readOnly)return!1;let i=n.field(Lg,!1);if(!i)return!1;let a=i.pop(e,n,t);return a?(r(a),!0):!1}}const Bg=zg(0,!1),Vg=zg(1,!1),Hg=zg(0,!0),Ug=zg(1,!0);var Wg=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&&Et.fromJSON(t.changes),[],t.mapped&&Tt.fromJSON(t.mapped),t.startSelection&&j.fromJSON(t.startSelection),t.selectionsAfter.map(j.fromJSON))}static fromTransaction(t,n){let r=Yg;for(let e of t.startState.facet(Fg)){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,Yg)}static selection(t){return new e(void 0,Yg,void 0,void 0,t)}};function Gg(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 Kg(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 qg(e,t){return e.ranges.length==t.ranges.length&&e.ranges.filter((e,n)=>e.empty!=t.ranges[n].empty).length===0}function Jg(e,t){return e.length?t.length?e.concat(t):e:t}const Yg=[];function Xg(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),Gg(e,e.length-1,1e9,n.setSelAfter(r)))}else return[Wg.selection([t])]}function Zg(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 Qg(e,t){if(!e.length)return e;let n=e.length,r=Yg;for(;n;){let i=$g(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?[Wg.selection(r)]:Yg}function $g(e,t,n){let r=Jg(e.selectionsAfter.length?e.selectionsAfter.map(e=>e.map(t)):Yg,n);if(!e.changes)return Wg.selection(r);let i=e.changes.map(t),a=t.mapDesc(e.changes,!0),o=e.mapped?e.mapped.composeDesc(a):a;return new Wg(i,N.mapEffects(e.effects,t),o,e.startSelection.map(a),r)}const e_=/^(input\.type|delete)($|\.)/;var t_=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||e_.test(r))&&(!s.selectionsAfter.length&&n-this.prevTime<i.newGroupDelay&&i.joinToEvent(a,Kg(s.changes,t.changes))||r==`input.type.compose`)?Gg(o,o.length-1,i.minDepth,new Wg(t.changes.compose(s.changes),Jg(N.mapEffects(t.effects,s.changes),s.effects),s.mapped,s.startSelection,Yg)):Gg(o,o.length,i.minDepth,t),new e(o,Yg,n,r)}addSelection(t,n,r,i){let a=this.done.length?this.done[this.done.length-1].selectionsAfter:Yg;return a.length>0&&n-this.prevTime<i&&r==this.prevUserEvent&&r&&/^select($|\.)/.test(r)&&qg(a[a.length-1],t)?this:new e(Xg(this.done,t),this.undone,n,r)}addMapping(t){return new e(Qg(this.done,t),Qg(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:Ng.of({side:e,rest:Zg(r),selection:a}),userEvent:e==0?`select.undo`:`select.redo`,scrollIntoView:!0});if(i.changes){let n=r.length==1?Yg:r.slice(0,r.length-1);return i.mapped&&(n=Qg(n,i.mapped)),t.update({changes:i.changes,selection:i.startSelection,effects:i.effects,annotations:Ng.of({side:e,rest:n,selection:a}),filter:!1,userEvent:e==0?`undo`:`redo`,scrollIntoView:!0})}else return null}};t_.empty=new t_(Yg,Yg);const n_=[{key:`Mod-z`,run:Bg,preventDefault:!0},{key:`Mod-y`,mac:`Mod-Shift-z`,run:Vg,preventDefault:!0},{linux:`Ctrl-Shift-z`,run:Vg,preventDefault:!0},{key:`Mod-u`,run:Hg,preventDefault:!0},{key:`Alt-u`,mac:`Mod-Shift-u`,run:Ug,preventDefault:!0}];function r_(e,t){return j.create(e.ranges.map(t),e.mainIndex)}function i_(e,t){return e.update({selection:t,scrollIntoView:!0,userEvent:`select`})}function a_({state:e,dispatch:t},n){let r=r_(e.selection,n);return r.eq(e.selection,!0)?!1:(t(i_(e,r)),!0)}function o_(e,t){return j.cursor(t?e.to:e.from)}function s_(e,t){return a_(e,n=>n.empty?e.moveByChar(n,t):o_(n,t))}function c_(e){return e.textDirectionAt(e.state.selection.main.head)==R.LTR}const l_=e=>s_(e,!c_(e)),u_=e=>s_(e,c_(e));function d_(e,t){return a_(e,n=>n.empty?e.moveByGroup(n,t):o_(n,t))}const f_=e=>d_(e,!c_(e)),p_=e=>d_(e,c_(e));typeof Intl<`u`&&Intl.Segmenter;function m_(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 h_(e,t,n){let r=Y(e).resolveInner(t.head),i=n?U.closedBy:U.openedBy;for(let a=t.head;;){let t=n?r.childAfter(a):r.childBefore(a);if(!t)break;m_(e,t,i)?r=t:a=n?t.to:t.from}let a=r.type.prop(i),o,s;return s=a&&(o=n?Uu(e,r.from,1):Uu(e,r.to,-1))&&o.matched?n?o.end.to:o.end.from:n?r.to:r.from,j.cursor(s,n?-1:1)}const g_=e=>a_(e,t=>h_(e.state,t,!c_(e))),__=e=>a_(e,t=>h_(e.state,t,c_(e)));function v_(e,t){return a_(e,n=>{if(!n.empty)return o_(n,t);let r=e.moveVertically(n,t);return r.head==n.head?e.moveToLineBoundary(n,t):r})}const y_=e=>v_(e,!1),b_=e=>v_(e,!0);function x_(e){let t=e.scrollDOM.clientHeight<e.scrollDOM.scrollHeight-2,n=0,r=0,i;if(t){for(let t of e.state.facet(H.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 S_(e,t){let n=x_(e),{state:r}=e,i=r_(r.selection,r=>r.empty?e.moveVertically(r,t,n.height):o_(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=H.scrollIntoView(i.main.head,{y:`start`,yMargin:t.top-s}))}return e.dispatch(i_(r,i),{effects:a}),!0}const C_=e=>S_(e,!1),w_=e=>S_(e,!0);function T_(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=j.cursor(r.from+n))}return i}const E_=e=>a_(e,t=>T_(e,t,!0)),D_=e=>a_(e,t=>T_(e,t,!1)),O_=e=>a_(e,t=>T_(e,t,!c_(e))),k_=e=>a_(e,t=>T_(e,t,c_(e))),A_=e=>a_(e,t=>j.cursor(e.lineBlockAt(t.head).from,1)),j_=e=>a_(e,t=>j.cursor(e.lineBlockAt(t.head).to,-1));function M_(e,t,n){let r=!1,i=r_(e.selection,t=>{let i=Uu(e,t.head,-1)||Uu(e,t.head,1)||t.head>0&&Uu(e,t.head-1,1)||t.head<e.doc.length&&Uu(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?j.range(t.anchor,a):j.cursor(a)});return r?(t(i_(e,i)),!0):!1}const N_=({state:e,dispatch:t})=>M_(e,t,!1);function P_(e,t,n){let r=r_(e.state.selection,e=>{e.undirectional&&e.head>=e.anchor!=t&&(e=j.range(e.head,e.anchor));let r=n(e);return j.range(e.anchor,r.head,r.goalColumn,r.bidiLevel||void 0,r.assoc)});return r.eq(e.state.selection)?!1:(e.dispatch(i_(e.state,r)),!0)}function F_(e,t){return P_(e,t,n=>e.moveByChar(n,t))}const I_=e=>F_(e,!c_(e)),L_=e=>F_(e,c_(e));function R_(e,t){return P_(e,t,n=>e.moveByGroup(n,t))}const z_=e=>R_(e,!c_(e)),B_=e=>R_(e,c_(e)),V_=e=>{let t=!c_(e);return P_(e,t,n=>h_(e.state,n,t))},H_=e=>{let t=c_(e);return P_(e,t,n=>h_(e.state,n,t))};function U_(e,t){return P_(e,t,n=>e.moveVertically(n,t))}const W_=e=>U_(e,!1),G_=e=>U_(e,!0);function K_(e,t){return P_(e,t,n=>e.moveVertically(n,t,x_(e).height))}const q_=e=>K_(e,!1),J_=e=>K_(e,!0),Y_=e=>P_(e,!0,t=>T_(e,t,!0)),X_=e=>P_(e,!1,t=>T_(e,t,!1)),Z_=e=>{let t=!c_(e);return P_(e,t,n=>T_(e,n,t))},Q_=e=>{let t=c_(e);return P_(e,t,n=>T_(e,n,t))},$_=e=>P_(e,!1,t=>j.cursor(e.lineBlockAt(t.head).from)),ev=e=>P_(e,!0,t=>j.cursor(e.lineBlockAt(t.head).to)),tv=({state:e,dispatch:t})=>(t(i_(e,{anchor:0})),!0),nv=({state:e,dispatch:t})=>(t(i_(e,{anchor:e.doc.length})),!0),rv=({state:e,dispatch:t})=>(t(i_(e,{anchor:e.selection.main.anchor,head:0})),!0),iv=({state:e,dispatch:t})=>(t(i_(e,{anchor:e.selection.main.anchor,head:e.doc.length})),!0),av=({state:e,dispatch:t})=>(t(e.update({selection:{anchor:0,head:e.doc.length},userEvent:`select`})),!0),ov=({state:e,dispatch:t})=>{let n=Tv(e).map(({from:t,to:n})=>j.undirectionalRange(t,Math.min(n+1,e.doc.length)));return t(e.update({selection:j.create(n),userEvent:`select`})),!0},sv=({state:e,dispatch:t})=>{let n=r_(e.selection,t=>{let n=Y(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 j.undirectionalRange(n.from,n.to)}return t});return n.eq(e.selection)?!1:(t(i_(e,n)),!0)};function cv(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(i_(n,j.create(i,i.length-1))),!0)}const lv=e=>cv(e,!1),uv=e=>cv(e,!0),dv=({state:e,dispatch:t})=>{let n=e.selection,r=null;return n.ranges.length>1?r=j.create([n.main]):n.main.empty||(r=j.create([j.cursor(n.main.head)])),r?(t(i_(e,r)),!0):!1};function fv(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=pv(e,o,!1)):o>i&&(n=`delete.forward`,o=pv(e,o,!0)),i=Math.min(i,o),a=Math.max(a,o)}else i=pv(e,i,!1),a=pv(e,a,!0);return i==a?{range:r}:{changes:{from:i,to:a},range:j.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`?H.announce.of(r.phrase(`Selection deleted`)):void 0})),!0)}function pv(e,t,n){if(e instanceof H)for(let r of e.state.facet(H.atomicRanges).map(t=>t(e)))r.between(t,t,(e,r)=>{e<t&&r>t&&(t=n?r:e)});return t}const mv=(e,t,n)=>fv(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=Un(s,a.tabSize)%pu(a)||pu(a);for(let t=0;t<e&&s[s.length-1-t]==` `;t++)i--;c=i}else c=vt(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=vt(o.text,c-o.from,!1,!1)+o.from);return c}),hv=e=>mv(e,!1,!0),gv=e=>mv(e,!0,!1),_v=(e,t)=>fv(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=vt(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}),vv=e=>_v(e,!1),yv=e=>_v(e,!0),bv=e=>fv(e,t=>{let n=e.lineBlockAt(t.head).to;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),xv=e=>fv(e,t=>{let n=e.moveToLineBoundary(t,!1).head;return t.head>n?n:Math.max(0,t.head-1)}),Sv=e=>fv(e,t=>{let n=e.moveToLineBoundary(t,!0).head;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),Cv=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=e.changeByRange(e=>({changes:{from:e.from,to:e.to,insert:A.of([``,``])},range:j.cursor(e.from)}));return t(e.update(n,{scrollIntoView:!0,userEvent:`input`})),!0},wv=({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:vt(r.text,n-r.from,!1)+r.from,a=n==r.to?n+1:vt(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:j.cursor(a)}});return n.changes.empty?!1:(t(e.update(n,{scrollIntoView:!0,userEvent:`move.character`})),!0)};function Tv(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 Ev(e,t,n){if(e.readOnly)return!1;let r=[],i=[];for(let t of Tv(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(j.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(j.range(e.anchor-o,e.head-o))}}return r.length?(t(e.update({changes:r,scrollIntoView:!0,selection:j.create(i,e.selection.mainIndex),userEvent:`move.line`})),!0):!1}const Dv=({state:e,dispatch:t})=>Ev(e,t,!1),Ov=({state:e,dispatch:t})=>Ev(e,t,!0);function kv(e,t,n){if(e.readOnly)return!1;let r=[];for(let t of Tv(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 Av=({state:e,dispatch:t})=>kv(e,t,!1),jv=({state:e,dispatch:t})=>kv(e,t,!0),Mv=e=>{if(e.state.readOnly)return!1;let{state:t}=e,n=t.changes(Tv(t).map(({from:e,to:n})=>(e>0?e--:n<t.doc.length&&n++,{from:e,to:n}))),r=r_(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 Nv(e,t){if(/\(\)|\[\]|\{\}/.test(e.sliceDoc(t-1,t+1)))return{from:t,to:t};let n=Y(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(U.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 Pv=Iv(!1),Fv=Iv(!0);function Iv(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&&Nv(t,r);e&&(r=i=(i<=a.to?a:t.doc.lineAt(i)).to);let s=new gu(t,{simulateBreak:r,simulateDoubleBreak:!!o}),c=hu(s,r);for(c??=Un(/^\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=[``,mu(t,c)];return o&&l.push(mu(t,s.lineIndent(a.from,-1))),{changes:{from:r,to:i,insert:A.of(l)},range:j.cursor(r+1+l[1].length)}});return n(t.update(r,{scrollIntoView:!0,userEvent:`input`})),!0}}function Lv(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:j.range(a.mapPos(r.anchor,1),a.mapPos(r.head,1))}})}const Rv=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=Object.create(null),r=new gu(e,{overrideIndentation:e=>n[e]??-1}),i=Lv(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=mu(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},zv=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(Lv(e,(t,n)=>{n.push({from:t.from,insert:e.facet(fu)})}),{userEvent:`input.indent`})),!0),Bv=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(Lv(e,(t,n)=>{let r=/^\s*/.exec(t.text)[0];if(!r)return;let i=Un(r,e.tabSize),a=0,o=mu(e,Math.max(0,i-pu(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),Vv=e=>(e.setTabFocusMode(),!0),Hv=[{key:`Ctrl-b`,run:l_,shift:I_,preventDefault:!0},{key:`Ctrl-f`,run:u_,shift:L_},{key:`Ctrl-p`,run:y_,shift:W_},{key:`Ctrl-n`,run:b_,shift:G_},{key:`Ctrl-a`,run:A_,shift:$_},{key:`Ctrl-e`,run:j_,shift:ev},{key:`Ctrl-d`,run:gv},{key:`Ctrl-h`,run:hv},{key:`Ctrl-k`,run:bv},{key:`Ctrl-Alt-h`,run:vv},{key:`Ctrl-o`,run:Cv},{key:`Ctrl-t`,run:wv},{key:`Ctrl-v`,run:w_}],Uv=[{key:`ArrowLeft`,run:l_,shift:I_,preventDefault:!0},{key:`Mod-ArrowLeft`,mac:`Alt-ArrowLeft`,run:f_,shift:z_,preventDefault:!0},{mac:`Cmd-ArrowLeft`,run:O_,shift:Z_,preventDefault:!0},{key:`ArrowRight`,run:u_,shift:L_,preventDefault:!0},{key:`Mod-ArrowRight`,mac:`Alt-ArrowRight`,run:p_,shift:B_,preventDefault:!0},{mac:`Cmd-ArrowRight`,run:k_,shift:Q_,preventDefault:!0},{key:`ArrowUp`,run:y_,shift:W_,preventDefault:!0},{mac:`Cmd-ArrowUp`,run:tv,shift:rv},{mac:`Ctrl-ArrowUp`,run:C_,shift:q_},{key:`ArrowDown`,run:b_,shift:G_,preventDefault:!0},{mac:`Cmd-ArrowDown`,run:nv,shift:iv},{mac:`Ctrl-ArrowDown`,run:w_,shift:J_},{key:`PageUp`,run:C_,shift:q_},{key:`PageDown`,run:w_,shift:J_},{key:`Home`,run:D_,shift:X_,preventDefault:!0},{key:`Mod-Home`,run:tv,shift:rv},{key:`End`,run:E_,shift:Y_,preventDefault:!0},{key:`Mod-End`,run:nv,shift:iv},{key:`Enter`,run:Pv,shift:Pv},{key:`Mod-a`,run:av},{key:`Backspace`,run:hv,shift:hv,preventDefault:!0},{key:`Delete`,run:gv,preventDefault:!0},{key:`Mod-Backspace`,mac:`Alt-Backspace`,run:vv,preventDefault:!0},{key:`Mod-Delete`,mac:`Alt-Delete`,run:yv,preventDefault:!0},{mac:`Mod-Backspace`,run:xv,preventDefault:!0},{mac:`Mod-Delete`,run:Sv,preventDefault:!0}].concat(Hv.map(e=>({mac:e.key,run:e.run,shift:e.shift}))),Wv=[{key:`Alt-ArrowLeft`,mac:`Ctrl-ArrowLeft`,run:g_,shift:V_},{key:`Alt-ArrowRight`,mac:`Ctrl-ArrowRight`,run:__,shift:H_},{key:`Alt-ArrowUp`,run:Dv},{key:`Shift-Alt-ArrowUp`,run:Av},{key:`Alt-ArrowDown`,run:Ov},{key:`Shift-Alt-ArrowDown`,run:jv},{key:`Mod-Alt-ArrowUp`,run:lv},{key:`Mod-Alt-ArrowDown`,run:uv},{key:`Escape`,run:dv},{key:`Mod-Enter`,run:Fv},{key:`Alt-l`,mac:`Ctrl-l`,run:ov},{key:`Mod-i`,run:sv,preventDefault:!0},{key:`Mod-[`,run:Bv},{key:`Mod-]`,run:zv},{key:`Mod-Alt-\\`,run:Rv},{key:`Shift-Mod-k`,run:Mv},{key:`Shift-Mod-\\`,run:N_},{key:`Mod-/`,run:Cg},{key:`Alt-A`,mac:`Ctrl-A`,run:Eg},{key:`Ctrl-m`,mac:`Shift-Alt-m`,run:Vv}].concat(Uv),Gv=`var(--dsw-alias-brand-primary, #3e63dd)`,Kv=`color-mix(in srgb, var(--dsw-alias-brand-primary, #3e63dd) 55%, transparent)`,qv=`var(--dsw-alias-label-dimmed, #999)`,Jv=`ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace`,Yv=Nu.define([{tag:[J.heading1,J.heading2,J.heading3,J.heading4,J.heading5,J.heading6],color:Gv,fontWeight:`700`},{tag:J.processingInstruction,color:Kv},{tag:J.monospace,fontFamily:Jv,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 12%, transparent)`,borderRadius:`4px`,padding:`0 3px`},{tag:J.content,fontFamily:Jv,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 8%, transparent)`},{tag:J.strong,fontWeight:`700`},{tag:J.emphasis,fontStyle:`italic`},{tag:J.strikethrough,textDecoration:`line-through`,opacity:`.75`},{tag:J.link,color:Gv,textDecoration:`underline`},{tag:J.url,color:Kv,textDecoration:`underline dotted`},{tag:J.quote,fontStyle:`italic`,color:`var(--dsw-alias-label-secondary, #888)`},{tag:J.contentSeparator,color:qv,textDecoration:`line-through`},{tag:J.comment,color:qv}]);function Xv(e={}){let t=document.createElement(`div`);t.className=`dsh-tw-note-editor`;let n=new H({parent:t,state:P.create({doc:``,extensions:[H.lineWrapping,Rg(),_g({base:rg}),Lu(Yv),yc(),Dc(e.placeholder??``),rc.of([...Wv,...n_,{key:`Mod-Enter`,run:()=>(e.onSave?.(),!0)}]),H.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?``:`
|
|
720
720
|
`}${e}\n`;n.dispatch({changes:{from:t,insert:r},selection:{anchor:t+r.length},scrollIntoView:!0}),n.focus()},focus:()=>n.focus()}}const Zv=`dsh-tw-note-state`,Qv=`dsh-tw-note-draft-v1`,$v=`dsh-tw-note-window-id`,ey=(()=>{try{let e=sessionStorage.getItem($v);if(e!==null&&e.length>0)return e;let t=Math.random().toString(36).slice(2,10);return sessionStorage.setItem($v,t),t}catch{return Math.random().toString(36).slice(2,10)}})();function ty(){return`dsh-tw-note-draft-v1:${ey}`}function ny(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 ry(e){try{return ny(localStorage.getItem(e))}catch{return null}}function iy(){let e=ry(ty());if(e!==null)return{draft:e,foreign:e.windowId!==void 0&&e.windowId!==ey};let t=ry(Qv);if(t===null)return null;let n={...t,windowId:ey};oy(n);try{localStorage.removeItem(Qv)}catch{}return{draft:n,foreign:!0}}function ay(e){oy({...e,windowId:ey})}function oy(e){try{localStorage.setItem(ty(),JSON.stringify({...e,windowId:ey}))}catch{}}function sy(){try{localStorage.removeItem(ty())}catch{}}function cy(e,t,n){return`${e}\u0000${t}\u0000${n.join(``)}`}function ly(e){return e<10?`0${e}`:String(e)}function uy(e=new Date){return`${e.getFullYear()}-${ly(e.getMonth()+1)}-${ly(e.getDate())} ${ly(e.getHours())}:${ly(e.getMinutes())}`}function dy(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 fy(){let e={showQuickNote:!0,defaultTag:`inbox`};try{let t=await fetch(p,{signal:AbortSignal.timeout(5e3)});if(!t.ok)return e;let n=await t.json();return{showQuickNote:n.ui?.showQuickNote!==!1,defaultTag:n.note?.tag??`inbox`}}catch{return e}}function py(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(`/dsh-tiddlywiki/tags`,{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]),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 my(e,t){if(e.size>67108864){O(`文件过大(≤ 64MB)`);return}try{let n=await fetch(`/dsh-tiddlywiki/upload?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){O(`上传失败:${r?.error??`HTTP ${n.status}`}`);return}let i=r.name??e.name,a=e.type.startsWith(`image/`)?``:`[${i}](${r.url})`;t.insertAtCaret(a),O(`已上传「${i}」并插入链接`)}catch(e){O(`上传失败:${e instanceof Error?e.message:String(e)}`)}}function hy(){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(Zv,{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=uy())},p=()=>{if(e===void 0)return;let t=e.editor.getValue(),n=e.titleInput.value.trim();if(t.trim().length===0&&n.length===0){sy();return}let r=cy(n,t,e.tagEditor.getTags());l!==null&&r===l||oy({text:t,title:n,tags:e.tagEditor.getTags(),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)},g=async(e,t,n)=>{try{let r=await fetch(`/dsh-tiddlywiki/edit`,{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?(O(`打开失败:${i?.error??`HTTP ${r.status}`}`),!1):typeof i.twUrl!=`string`||typeof i.draftTitle!=`string`?(O(`打开失败:服务未返回编辑器地址`),!1):(sy(),h(),l=cy(e,t,n),c=null,We(`${new URL(i.twUrl,location.origin).href}#${encodeURIComponent(i.draftTitle)}`,i.title??e),O(`已在弹出窗口打开「${i.title??e}」编辑器`),!0)}catch(e){return O(`打开失败:${e instanceof Error?e.message:String(e)}`),!1}},_=()=>{s=!1,e!==void 0&&(e.recentWrap.hidden=!0)},v=async t=>{try{let n=await fetch(`/dsh-tiddlywiki/get?title=${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(1e4)}),r=await n.json().catch(()=>null);if(!n.ok||r?.ok!==!0||typeof r.title!=`string`){O(`读取失败:${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=cy(r.title,r.text??``,r.tags??[]),h(),_(),O(`已载入「${r.title}」`),e.editor.focus()}catch(e){O(`读取失败:${e instanceof Error?e.message:String(e)}`)}},y=()=>{if(e===void 0)return;if(s){_();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(`/dsh-tiddlywiki/recent?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=[dy(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`,()=>{v(t.title)}),n.addEventListener(`keydown`,e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),v(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)}})()},b=()=>{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 v=document.createElement(`button`);v.type=`button`,v.className=`dsh-tw-note-draft-discard`,v.textContent=`丢弃`,d.append(f,v);let b=document.createElement(`div`);b.className=`dsh-tw-note-fields`;let x=document.createElement(`input`);x.className=`dsh-tw-note-title`,x.placeholder=`标题(默认时间戳)`,x.setAttribute(`aria-label`,`笔记标题(默认时间戳)`);let S=py({onChange:m});b.append(x,S.el),x.addEventListener(`input`,m);let C,w=Xv({placeholder:`写点东西… Markdown 高亮,可 📎/拖入文件
|
|
721
721
|
Ctrl+Enter 保存`,onSave:()=>{C?.()},onChange:m}),T=document.createElement(`button`);T.type=`button`,T.className=`dsh-tw-note-upload`,T.title=`上传文件到 wiki 并插入 Markdown 链接(也可直接拖入编辑器)`,T.textContent=`📎 上传`;let ee=document.createElement(`input`);ee.type=`file`,ee.multiple=!0,ee.hidden=!0,T.addEventListener(`click`,()=>{ee.click()}),ee.addEventListener(`change`,()=>{for(let e of Array.from(ee.files??[]))my(e,w);ee.value=``});let te=0;w.el.addEventListener(`dragenter`,e=>{e.preventDefault(),te++,w.el.classList.add(`dsh-tw-note-drop`)}),w.el.addEventListener(`dragover`,e=>{e.preventDefault()}),w.el.addEventListener(`dragleave`,e=>{e.preventDefault(),te=Math.max(0,te-1),te===0&&w.el.classList.remove(`dsh-tw-note-drop`)}),w.el.addEventListener(`drop`,e=>{e.preventDefault(),te=0,w.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))my(e,w)});let E=document.createElement(`div`);E.className=`dsh-tw-note-foot`;let D=document.createElement(`div`);D.className=`dsh-tw-note-foot-left`;let ne=document.createElement(`span`);ne.className=`dsh-tw-note-hint`,ne.textContent=`Ctrl+Enter`;let re=document.createElement(`button`);re.type=`button`,re.className=`dsh-tw-note-recent-btn`,re.title=`最近修改的笔记,点击载入继续编辑`,re.textContent=`🕘 最近`,re.addEventListener(`click`,y),D.append(T,re,ne);let ie=document.createElement(`div`);ie.className=`dsh-tw-note-foot-right`;let ae=document.createElement(`button`);ae.type=`button`,ae.className=`dsh-tw-note-edit`,ae.title=`保存并在 TiddlyWiki 原生编辑器中打开`,ae.textContent=`✏️ 在 TW 中编辑`;let oe=document.createElement(`button`);oe.type=`button`,oe.className=`dsh-tw-note-save`,oe.textContent=`保存`,ie.append(ae,oe),E.append(D,ie);let se=document.createElement(`div`);se.className=`dsh-tw-note-recent`,se.hidden=!0,r.append(a,d,b,w.el,E),t.append(r,se),document.body.append(t),e={root:t,card:r,editor:w,titleInput:x,tagEditor:S,saveBtn:oe,editBtn:ae,draftBanner:d,bannerText:f,recentBtn:re,recentWrap:se};let ce=()=>{n=!1,t.hidden=!0,_(),u(!1)},le=()=>{sy(),h(),l=cy(x.value.trim(),w.getValue(),S.getTags()),c=null,w.setValue(``),x.value=uy(),S.setTags([]),ce()},ue=!1;C=async()=>{if(ue)return;let e=w.getValue().trim();if(e.length===0){O(`内容为空,未保存`);return}ue=!0,oe.disabled=!0,oe.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(`/dsh-tiddlywiki/note`,{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){O(`保存被拒绝:这篇笔记在你读取之后被改动过。请用「🕘 最近」重新载入后再保存。`);return}O(`保存失败:${i?.error??`HTTP ${r.status}`}`);return}le(),O(`已保存「${i.title??x.value}」`)}catch(e){O(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{ue=!1,oe.disabled=!1,oe.textContent=`保存`}},oe.addEventListener(`click`,()=>{C?.()});let de=async()=>{let e=x.value.trim().length>0?x.value.trim():uy(),t=w.getValue(),n=S.getTags();ae.disabled=!0,ae.textContent=`打开中…`;try{await g(e,t,n)}finally{ae.disabled=!1,ae.textContent=`✏️ 在 TW 中编辑`}};ae.addEventListener(`click`,()=>{de()}),s.addEventListener(`click`,ce);let fe=null,pe=(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();fe={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(fe===null)return;let t=e.clientX-fe.startX,n=e.clientY-fe.startY;!fe.moved&&Math.abs(t)<4&&Math.abs(n)<4||(fe.moved=!0,pe(fe.origLeft+t,fe.origTop+n))});let me=e=>{if(fe!==null){try{a.releasePointerCapture(e.pointerId)}catch{}fe=null,a.classList.remove(`dsh-tw-note-head-dragging`)}};a.addEventListener(`pointerup`,me),a.addEventListener(`pointercancel`,me),v.addEventListener(`click`,()=>{sy(),h(),w.setValue(``),x.value=uy(),S.setTags([]),O(`已丢弃草稿`)}),i=()=>{p()},window.addEventListener(`pagehide`,i)};return{async open(r){if(t||(b(),e===void 0||n))return;n=!0,e.root.hidden=!1,d(r),u(!0);let i=iy(),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&&(O(`已恢复其它窗口的未保存草稿`),ay(o));else{if(f(),a=(await fy()).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,_(),u(!1))},async openNative(){if(!(t||r||Ge())){r=!0;try{let e=iy(),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():uy(),i=n?e.draft.text:``,o=[];if(n)o=e.draft.tags;else{if(a=(await fy()).defaultTag,t)return;o=[a]}e!==null&&e.foreign&&(e.draft.text.trim().length>0||e.draft.title.trim().length>0)&&(O(`已恢复其它窗口的未保存草稿`),ay(e.draft)),await g(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(),document.querySelector(`.dsh-tw-toast`)?.remove(),e=void 0}}}function gy(e){return e<10?`0${e}`:String(e)}function _y(e){return`${gy(e.getHours())}:${gy(e.getMinutes())}`}async function vy(){try{let e=await fetch(p,{signal:AbortSignal.timeout(8e3)});return e.ok?await e.json():null}catch{return null}}function yy(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(`上次同步 ${_y(t)}`),{state:i,label:a,tooltip:r.join(` · `),...t===void 0?{}:{lastSync:t}}}function by(){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=yy(n,t);(i.state!==e.state||i.tooltip!==e.tooltip)&&(e=i,o())},c=async()=>{if(i)return;let e=await vy();i||s(e)};return c(),n=window.setInterval(()=>{c()},3e4),{getState:()=>e,trigger:async()=>{if(i)return e;if(r)return O(`同步进行中…`),e;r=!0,e={...e,state:`syncing`,label:`同步中…`},o();try{let e=await fetch(`/dsh-tiddlywiki/sync`,{method:`POST`,signal:AbortSignal.timeout(12e4)}),n=await e.json().catch(()=>null);if(n===null||n.ok!==!0)O(`同步失败:${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})`)),O(`同步完成:${n.message??`OK`}${e}`)}}catch(e){O(`同步失败:${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 xy={showQuickNoteDock:!0,quickNoteMode:`native`,sidebarLabel:`TiddlyWiki`,tabLabel:`知识库`,showSessionTab:!0,showRightbarTab:!0};let Sy;function Cy(){Sy=void 0}async function wy(e={}){let t=Date.now();if(!e.force&&Sy!==void 0&&t-Sy.at<15e3)return Sy.value;try{let e=await fetch(p,{signal:AbortSignal.timeout(5e3)});if(!e.ok)return xy;let t=await e.json(),n={showQuickNoteDock:t.ui?.showQuickNoteDock!==!1,quickNoteMode:t.ui?.quickNoteMode===`card`?`card`:`native`,sidebarLabel:typeof t.ui?.sidebarLabel==`string`&&t.ui.sidebarLabel.trim().length>0?t.ui.sidebarLabel.trim():`TiddlyWiki`,tabLabel:typeof t.ui?.tabLabel==`string`&&t.ui.tabLabel.trim().length>0?t.ui.tabLabel.trim():`知识库`,showSessionTab:t.ui?.showSessionTab!==!1,showRightbarTab:t.ui?.showRightbarTab!==!1};return Sy={at:Date.now(),value:n},n}catch{return xy}}async function Ty(){try{let e=await fetch(p,{signal:AbortSignal.timeout(5e3)});if(!e.ok)return{showQuickNote:!0,showPanelStatus:!0,showSyncButton:!0};let t=await e.json();return{showQuickNote:t.ui?.showQuickNote!==!1,showPanelStatus:t.ui?.showPanelStatus!==!1,showSyncButton:t.ui?.showSyncButton!==!1}}catch{return{showQuickNote:!0,showPanelStatus:!0,showSyncButton:!0}}}async function Ey(){try{let e=await fetch(p,{signal:AbortSignal.timeout(8e3)});if(!e.ok)return{state:`failed`,text:`状态不可达`,logs:[]};let t=await e.json(),n=Array.isArray(t.logs)?t.logs.filter(e=>typeof e==`string`):[];return t.status===`running`?{state:`running`,text:`TW 在线 · ${t.url??``}`,logs:n}:t.status===`starting`?{state:`starting`,text:`TW 启动中…`,logs:n}:{state:`failed`,text:t.error??`TW 状态:${t.status??`?`}`,logs:n}}catch{return{state:`failed`,text:`状态不可达`,logs:[]}}}function Dy(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(`
|
|
722
|
-
`)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await Ey(),!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(),wy().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(me)),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 Ty();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),b(),x(),i?.remove()}}function Oy(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=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(Zv,e),wy().then(e=>i(e.quickNoteMode)),()=>window.removeEventListener(Zv,e)},[]),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:()=>{wy().then(t=>{t.quickNoteMode===`native`?Ge()?qe():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 ky(e){ge(e)}function Ay(){return _e()}async function jy(e){try{let t=await fetch(h,{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 My(e){try{let t=await fetch(`${m}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function Ny(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),h=c.useRef(0),g=c.useCallback(async()=>{let e=++p.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(`/dsh-tiddlywiki/session/summary`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(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 jy(r.title);if(e!==p.current)return;if(i===null){let t=await My(r.title);if(e!==p.current)return;if(!t){if(h.current++,h.current<3){g();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(/tw/render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}},[t]);c.useEffect(()=>{g()},[g]),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(`${m}?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){g();return}a(`error`),f(`汇总条目已失效且自动重建多次失败,请点「🔄 刷新」重试`)}})()},3e4);return()=>{e=!1,window.clearInterval(t)}},[i,l,g]),c.useEffect(()=>{n!=null&&r?.()},[n,r]);let _=()=>{h.current=0,g()},v;return v=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:_},`重试`)):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:_,disabled:i===`loading`,title:`重新生成并刷新汇总`},`🔄 刷新`)),v)}function Py(e,t){if(!(e===void 0||t.showSessionTab===!1))return ky(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:Ay},Ny))}const Fy=`/dsh-tiddlywiki/admin/info`,Iy=`/dsh-tiddlywiki/admin/seeds/run`;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 Ly(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 Ry(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=async()=>{try{let e=await Ly(`/dsh-tiddlywiki/admin/state`);if(t)return;zy(n,e,a),Uy(r,e,a,()=>t)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),o=$(`button`,`dsh-tw-settings-btn`,`重试`);o.type=`button`,o.addEventListener(`click`,()=>{a()}),r.append(i,o)}};return a(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function zy(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(`/dsh-tiddlywiki/sync`,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=await e.json().catch(()=>null);if(!e.ok||t?.ok!==!0)O(`同步失败:${t?.error??t?.message??`HTTP ${e.status}`}`);else{let e=``;t.changed===!0&&(e+=t.restarted===!0?`,TW 已重启`:`,TW 未自动重启`,t.restartError&&(e+=`(${t.restartError})`)),O(`同步完成:${t.message??`OK`}${e}`)}}catch(e){O(`同步失败:${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 Ly(`/dsh-tiddlywiki/admin/restart`,{method:`POST`}),O(`TW 已重启`)}catch(e){O(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function By(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,input:i,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,input:i,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,input:i,initial:n,read:a,changed:()=>a()!==n}),r.append(o)};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),((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,input:a,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o)})(`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 d=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,d.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof d.endpoint==`string`?d.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头)`,typeof d.token==`string`?d.token:``);let f=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof f.pageSize==`number`?f.pageSize:10);let p=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,p.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof p.port==`number`&&p.port>0?p.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置)`,typeof p.token==`string`?p.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof p.tag==`string`&&p.tag.trim().length>0?p.tag.trim():`clip`);let m=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);m.type=`button`,m.addEventListener(`click`,()=>{m.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 Ly(`/dsh-tiddlywiki/admin/config`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),Cy(),O(`配置已保存`),n()}catch(e){O(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{m.disabled=!1}})()}),r.append(m),e.append(r)}function Vy(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 Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),O(`插件已应用,TW 已重启`),r()}catch(e){O(`应用失败:${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=v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,b=$(`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===y,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(y=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),b.append(a)}let x=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);x.type=`button`,x.addEventListener(`click`,()=>{x.disabled=!0,(async()=>{try{await Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:y})}),O(`主题已应用,TW 已重启`),r()}catch(e){O(`应用失败:${e instanceof Error?e.message:String(e)}`),x.disabled=!1}})()}),h.append(g,_,b,x),e.append(h);let S=$(`section`,`dsh-tw-settings-section`);S.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let C=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),w=$(`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),w.append(n)}let T=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);T.type=`button`,T.addEventListener(`click`,()=>{T.disabled=!0,(async()=>{try{await Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),O(`语言已应用,TW 已重启`),r()}catch(e){O(`应用失败:${e instanceof Error?e.message:String(e)}`),T.disabled=!1}})()}),S.append(C,w,T),e.append(S)}function Hy(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=`/dsh-tiddlywiki/admin/seeds/remove`,s=async()=>{if(!t())try{let e=await Ly(`/dsh-tiddlywiki/admin/seeds`);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 c=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),l=$(`button`,`dsh-tw-settings-btn`,`重新初始化`);l.type=`button`,l.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,l.addEventListener(`click`,()=>{l.disabled=!0,l.textContent=`执行中…`,(async()=>{try{let e=await fetch(Iy,{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?O(`重新初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):O(`已重新初始化「${t.title}」`),s()}catch(e){O(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{l.disabled=!1,l.textContent=`重新初始化`}})()});let u=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);if(u.append(e,a,c,l),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(o,{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?O(`反初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):O(`已反初始化「${t.title}」`),s()}catch(e){O(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{e.disabled=!1,e.textContent=`反初始化`}})())}),u.append(e)}i.append(u)}a.textContent=`共 ${e.items.length} 项,${n} 项已就绪;可移除 ${r} 项`}catch(e){if(t())return;a.textContent=`加载初始化状态失败:${e instanceof Error?e.message:String(e)}`}},c=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`全部重新初始化`);c.type=`button`,c.title=`强制重写所有一次性预置内容(含可选 seed,会覆盖当前 tiddler/配置)`,c.addEventListener(`click`,()=>{c.disabled=!0,c.textContent=`执行中…`,(async()=>{try{let e=await fetch(Iy,{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?O(`重新初始化失败:${t?.error??`HTTP ${e.status}`}`):O(`全部已重新初始化`),s()}catch(e){O(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`全部重新初始化`}})()});let l=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`全部反初始化`);l.type=`button`,l.title=`移除所有可选 seed 写入的 tiddler 与 marker(功能必需项保留)`,l.addEventListener(`click`,()=>{window.confirm(`确定全部反初始化?将删除所有可选 seed 写入的 tiddler(含一次性 marker)。功能必需项(发送给 Agent 按钮 / TW 前端 API 基址)会保留。`)&&(l.disabled=!0,l.textContent=`移除中…`,(async()=>{try{let e=await fetch(o,{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?O(`反初始化失败:${t?.error??`HTTP ${e.status}`}`):O(`全部可选 seed 已反初始化`),s()}catch(e){O(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{l.disabled=!1,l.textContent=`全部反初始化`}})())}),n.append(r,a,i,c,l),e.append(n),s()}function Uy(e,t,n,r){e.replaceChildren(),By(e,t.config??{},n),Vy(e,t.info,t.catalog,n),Hy(e,r)}function Wy(){let e=c.useRef(null);return c.useEffect(()=>{let t=e.current;return t===null?void 0:Ry(t)},[]),c.createElement(`div`,{ref:e})}const Gy={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 Ky(e){return typeof e==`object`&&!!e&&e.kind===`tool-result`}function qy(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 Jy(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{}}catch{return{}}}function Yy(e){return Array.isArray(e)?e.filter(e=>typeof e?.text==`string`).map(e=>e.text).join(`
|
|
722
|
+
`)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await Ey(),!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(),wy().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(me)),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 Ty();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),b(),x(),i?.remove()}}function Oy(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=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(Zv,e),wy().then(e=>i(e.quickNoteMode)),()=>window.removeEventListener(Zv,e)},[]),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:()=>{wy().then(t=>{t.quickNoteMode===`native`?Ge()?qe():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 ky(e){ge(e)}function Ay(){return _e()}async function jy(e){try{let t=await fetch(h,{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 My(e){try{let t=await fetch(`${m}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function Ny(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),h=c.useRef(0),g=c.useCallback(async()=>{let e=++p.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(`/dsh-tiddlywiki/session/summary`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(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 jy(r.title);if(e!==p.current)return;if(i===null){let t=await My(r.title);if(e!==p.current)return;if(!t){if(h.current++,h.current<3){g();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(/tw/render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}},[t]);c.useEffect(()=>{g()},[g]),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(`${m}?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){g();return}a(`error`),f(`汇总条目已失效且自动重建多次失败,请点「🔄 刷新」重试`)}})()},3e4);return()=>{e=!1,window.clearInterval(t)}},[i,l,g]),c.useEffect(()=>{n!=null&&r?.()},[n,r]);let _=()=>{h.current=0,g()},v;return v=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:_},`重试`)):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:_,disabled:i===`loading`,title:`重新生成并刷新汇总`},`🔄 刷新`)),v)}function Py(e,t){if(!(e===void 0||t.showSessionTab===!1))return ky(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:Ay},Ny))}const Fy=`/dsh-tiddlywiki/admin/info`,Iy=`/dsh-tiddlywiki/admin/seeds/run`;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 Ly(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 Ry(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=async()=>{try{let e=await Ly(`/dsh-tiddlywiki/admin/state`);if(t)return;zy(n,e,a),Uy(r,e,a,()=>t)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),o=$(`button`,`dsh-tw-settings-btn`,`重试`);o.type=`button`,o.addEventListener(`click`,()=>{a()}),r.append(i,o)}};return a(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function zy(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(`/dsh-tiddlywiki/sync`,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=await e.json().catch(()=>null);if(!e.ok||t?.ok!==!0)O(`同步失败:${t?.error??t?.message??`HTTP ${e.status}`}`);else{let e=``;t.changed===!0&&(e+=t.restarted===!0?`,TW 已重启`:`,TW 未自动重启`,t.restartError&&(e+=`(${t.restartError})`)),O(`同步完成:${t.message??`OK`}${e}`)}}catch(e){O(`同步失败:${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 Ly(`/dsh-tiddlywiki/admin/restart`,{method:`POST`}),O(`TW 已重启`)}catch(e){O(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function By(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,input:i,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,input:i,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,input:i,initial:n,read:a,changed:()=>a()!==n}),r.append(o)};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),((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,input:a,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o)})(`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 d=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,d.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof d.endpoint==`string`?d.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头;已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof d.token==`string`?d.token:``);let f=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof f.pageSize==`number`?f.pageSize:10);let p=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,p.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof p.port==`number`&&p.port>0?p.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置。已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof p.token==`string`?p.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof p.tag==`string`&&p.tag.trim().length>0?p.tag.trim():`clip`);let m=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);m.type=`button`,m.addEventListener(`click`,()=>{m.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 Ly(`/dsh-tiddlywiki/admin/config`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),Cy(),O(`配置已保存`),n()}catch(e){O(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{m.disabled=!1}})()}),r.append(m),e.append(r)}function Vy(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 Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),O(`插件已应用,TW 已重启`),r()}catch(e){O(`应用失败:${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=v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,b=$(`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===y,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(y=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),b.append(a)}let x=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);x.type=`button`,x.addEventListener(`click`,()=>{x.disabled=!0,(async()=>{try{await Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:y})}),O(`主题已应用,TW 已重启`),r()}catch(e){O(`应用失败:${e instanceof Error?e.message:String(e)}`),x.disabled=!1}})()}),h.append(g,_,b,x),e.append(h);let S=$(`section`,`dsh-tw-settings-section`);S.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let C=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),w=$(`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),w.append(n)}let T=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);T.type=`button`,T.addEventListener(`click`,()=>{T.disabled=!0,(async()=>{try{await Ly(Fy,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),O(`语言已应用,TW 已重启`),r()}catch(e){O(`应用失败:${e instanceof Error?e.message:String(e)}`),T.disabled=!1}})()}),S.append(C,w,T),e.append(S)}function Hy(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=`/dsh-tiddlywiki/admin/seeds/remove`,s=async()=>{if(!t())try{let e=await Ly(`/dsh-tiddlywiki/admin/seeds`);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 c=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),l=$(`button`,`dsh-tw-settings-btn`,`重新初始化`);l.type=`button`,l.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,l.addEventListener(`click`,()=>{l.disabled=!0,l.textContent=`执行中…`,(async()=>{try{let e=await fetch(Iy,{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?O(`重新初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):O(`已重新初始化「${t.title}」`),s()}catch(e){O(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{l.disabled=!1,l.textContent=`重新初始化`}})()});let u=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);if(u.append(e,a,c,l),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(o,{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?O(`反初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):O(`已反初始化「${t.title}」`),s()}catch(e){O(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{e.disabled=!1,e.textContent=`反初始化`}})())}),u.append(e)}i.append(u)}a.textContent=`共 ${e.items.length} 项,${n} 项已就绪;可移除 ${r} 项`}catch(e){if(t())return;a.textContent=`加载初始化状态失败:${e instanceof Error?e.message:String(e)}`}},c=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`全部重新初始化`);c.type=`button`,c.title=`强制重写所有一次性预置内容(含可选 seed,会覆盖当前 tiddler/配置)`,c.addEventListener(`click`,()=>{c.disabled=!0,c.textContent=`执行中…`,(async()=>{try{let e=await fetch(Iy,{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?O(`重新初始化失败:${t?.error??`HTTP ${e.status}`}`):O(`全部已重新初始化`),s()}catch(e){O(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`全部重新初始化`}})()});let l=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`全部反初始化`);l.type=`button`,l.title=`移除所有可选 seed 写入的 tiddler 与 marker(功能必需项保留)`,l.addEventListener(`click`,()=>{window.confirm(`确定全部反初始化?将删除所有可选 seed 写入的 tiddler(含一次性 marker)。功能必需项(发送给 Agent 按钮 / TW 前端 API 基址)会保留。`)&&(l.disabled=!0,l.textContent=`移除中…`,(async()=>{try{let e=await fetch(o,{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?O(`反初始化失败:${t?.error??`HTTP ${e.status}`}`):O(`全部可选 seed 已反初始化`),s()}catch(e){O(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{l.disabled=!1,l.textContent=`全部反初始化`}})())}),n.append(r,a,i,c,l),e.append(n),s()}function Uy(e,t,n,r){e.replaceChildren(),By(e,t.config??{},n),Vy(e,t.info,t.catalog,n),Hy(e,r)}function Wy(){let e=c.useRef(null);return c.useEffect(()=>{let t=e.current;return t===null?void 0:Ry(t)},[]),c.createElement(`div`,{ref:e})}const Gy={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 Ky(e){return typeof e==`object`&&!!e&&e.kind===`tool-result`}function qy(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 Jy(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{}}catch{return{}}}function Yy(e){return Array.isArray(e)?e.filter(e=>typeof e?.text==`string`).map(e=>e.text).join(`
|
|
723
723
|
`):``}function Xy(e){return typeof e==`string`?e:``}async function Zy(e){try{let t=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(!t.ok)return null;let n=await t.json();return typeof n==`object`&&n?n:null}catch{return null}}async function Qy(e){try{let t=await fetch(h,{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 $y(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 eb(e){return t=>{t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||(t.preventDefault(),t.stopPropagation(),Me(e))}}function tb(e){let t=Gy[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=>c.createElement(`span`,{className:`dsh-tw-toolcard-tag`,key: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 nb=new Map;function rb(e){let t=nb.get(e);if(t!==void 0){if(Date.now()-t.at>3e5){nb.delete(e);return}return nb.delete(e),nb.set(e,t),t}}function ib(e,t){for(nb.delete(e),nb.set(e,{at:Date.now(),...t});nb.size>50;){let e=nb.keys().next().value;if(e===void 0)break;nb.delete(e)}}function ab(e){e.length>0&&nb.delete(e)}function ob(e){let t=e.join(`\0`);c.useEffect(()=>{for(let e of t.split(`\0`))ab(e)},[t])}function sb(e){let{title:t,fresh:n}=e,{loading:r,data:i}=$y(async()=>{n===!0&&ab(t);let e=rb(t);if(e!==void 0)return{get:e.get,html:e.html};let[r,i]=await Promise.all([Zy(`${m}?title=${encodeURIComponent(t)}`),Qy(t)]);return typeof i==`string`&&i.length>0&&ib(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(tb,{toolName:e.toolName,title:t,subtitle:e.subtitle,tags:l,onOpen:eb(t),foot:u===void 0?void 0:`修改于 ${u}`},s)}function cb(e){return c.createElement(`a`,{className:`dsh-tw-toolcard-row`,href:`/dsh-tiddlywiki/tw/#${encodeURIComponent(e.title)}`,onClick:eb(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 lb(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(cb,{key:`${e.title}-${t}`,...e}))),c.createElement(tb,{toolName:e.toolName,title:e.title,subtitle:e.subtitle},n)}function ub(e){let t=Xy(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.limit==`number`&&n.set(`limit`,String(e.args.limit));let r=n.toString(),i=$y(()=>Zy(`/dsh-tiddlywiki/search?${r}`),[r]).data,a=(Array.isArray(i?.items)?i.items:[]).map(e=>({title:Xy(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(lb,{toolName:e.toolName,title:t.length>0?t:`检索`,subtitle:s,rows:a,fallbackText:`没有匹配的笔记`})}function db(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=$y(()=>Zy(`/dsh-tiddlywiki/recent?${n}`),[n]).data,i=(Array.isArray(r?.items)?r.items:[]).map(e=>({title:Xy(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(lb,{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`?Xy(e.title):null).filter(e=>e!==null&&e.length>0).map(e=>({title:e}));return ob(t.map(e=>e.title)),c.createElement(lb,{toolName:e.toolName,title:`批量写入`,subtitle:t.length>0?`写入 ${t.length} 篇`:`(参数中没有可解析的 items)`,rows:t,fallbackText:`没有可展示的笔记`})}function pb(e){let t=$y(()=>Zy(`/dsh-tiddlywiki/tags`),[]).data,n=(Array.isArray(t?.items)?t.items:[]).map(e=>({tag:Xy(e.tag),count:typeof e.count==`number`?e.count:0})),r=n.slice(0,60),i;return i=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}`)),...n.length>r.length?[c.createElement(`span`,{className:`dsh-tw-toolcard-tag-more`,key:`__more`},`…另有 ${n.length-r.length} 个`)]:[]),c.createElement(tb,{toolName:e.toolName,title:`标签`,subtitle:`共 ${n.length} 个`},i)}function mb(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(tb,{toolName:e.toolName},t)}function hb(e){ob([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(tb,{toolName:e.toolName,title:e.title.length>0?e.title:void 0},t)}function gb(e,t){switch(e){case`tiddlywiki_get`:case`tiddlywiki_put`:case`tiddlywiki_append`:case`tiddlywiki_delete`:case`tiddlywiki_attach`:case`tiddlywiki_backlinks`:return Xy(t.title);case`tiddlywiki_rename`:return Xy(t.newTitle);case`tiddlywiki_search`:return Xy(t.query);case`tiddlywiki_recent`:case`tiddlywiki_list_tags`:case`tiddlywiki_batch_put`:case`tiddlywiki_trash`:case`tiddlywiki_lint`:case`tiddlywiki_git_sync`:case`tiddlywiki_git_resolve`:return``;default:return``}}function _b(e){let t=e.block,n=e.toolName,r=Ky(t),i=qy(t),a=n!==void 0&&n.length>0?n:i?.name??``,o=Jy(i?.argsRaw??``),s=r?Yy(t.content):``;if(i===null)return c.createElement(tb,{toolName:a},c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},s||`(无调用信息)`));if(!r)return c.createElement(tb,{toolName:a,title:gb(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-pending`},`处理中…`));if(t.isError===!0)return c.createElement(tb,{toolName:a,title:gb(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-error`},s||`工具调用失败`));switch(a){case`tiddlywiki_get`:return c.createElement(sb,{toolName:a,title:Xy(o.title),subtitle:`读取`});case`tiddlywiki_put`:return c.createElement(sb,{toolName:a,title:Xy(o.title),subtitle:`已写入`,fresh:!0});case`tiddlywiki_append`:return c.createElement(sb,{toolName:a,title:Xy(o.title),subtitle:`已增量写入`,fresh:!0});case`tiddlywiki_rename`:return c.createElement(sb,{toolName:a,title:Xy(o.newTitle),subtitle:`已重命名「${Xy(o.oldTitle)}」→`,fresh:!0});case`tiddlywiki_delete`:return c.createElement(hb,{toolName:a,title:Xy(o.title),text:s});case`tiddlywiki_batch_put`:return c.createElement(fb,{toolName:a,args:o,text:s});case`tiddlywiki_search`:return c.createElement(ub,{toolName:a,args:o,text:s});case`tiddlywiki_recent`:return c.createElement(db,{toolName:a,args:o,text:s});case`tiddlywiki_list_tags`:return c.createElement(pb,{toolName:a,text:s});case`tiddlywiki_git_sync`:case`tiddlywiki_git_resolve`:return c.createElement(mb,{toolName:a,text:s});default:return c.createElement(tb,{toolName:a,title:gb(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 yb(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}`},_b));r!==void 0&&t.push(r)}catch(e){console.error(`[dsh-tiddlywiki] register toolview ${n} failed:`,e)}return t}function bb(){let e=e=>{if(e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;let t=e.target;if(!(t instanceof Element))return;let n=t.closest(`a`);if(n===null)return;let r=(n.getAttribute(`href`)??``).match(/^\/dsh-tiddlywiki\/tw\/#(.+)$/);if(r===null||r[1]===void 0)return;e.preventDefault(),e.stopPropagation();let i=r[1];try{i=decodeURIComponent(i)}catch{}Me(i)};return document.addEventListener(`click`,e,!0),()=>document.removeEventListener(`click`,e,!0)}const xb=`dsh-tiddlywiki`,Sb=`dsh-tiddlywiki/rightbar`;function Cb(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=Te(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(pe,{detail:Sb}));let e=e=>{e.detail!==Sb&&o()};return document.addEventListener(pe,e),()=>document.removeEventListener(pe,e)},[a,o]),c.createElement(`div`,{ref:r,className:`dsh-tw-rightbar-tab`,"data-dsh-tw-rightbar":``})}function wb(){return{id:xb,kind:`dsh-tiddlywiki`,title:()=>_e(),guide:[{order:10,title:()=>`TiddlyWiki 知识库`,description:()=>`在右侧边栏打开 TiddlyWiki 编辑器(与聊天并排)`,icon:be}]}}function Tb(e,t){let n=[];try{n.push(e.register(wb()));let r=t.inject(`sidebar.right.pane.tab`,()=>t.register({name:`sidebar.right.pane.tab`,key:xb},Cb));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 we(),()=>{for(let e of n.splice(0))e()}}const Eb=[`slots`];function Db(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=hy(),t.push(()=>o?.dispose())}),i(`sync controller`,()=>{s=by(),t.push(()=>s?.dispose())}),i(`sidebar entry`,()=>t.push(b(a))),i(`center panel`,()=>t.push(Le(a))),o!==void 0&&s!==void 0){let e=o,n=s;i(`knowledge FAB`,()=>t.push(Dy(a,e,n)))}i(`editor popup`,()=>t.push(Je)),e.slots!==void 0&&wy().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:`快速笔记`},Oy(a)));n!==void 0&&t.push(n)}),i(`session summary tab`,()=>{let n=Py(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}wy().then(r=>{if(n||!r.showRightbarTab)return;let i=Tb(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(...yb(e.slots))}),i(`wiki link interceptor`,()=>t.push(bb())),i(`settings section`,()=>{let n=e.slots?.inject(`settings.section`,()=>e.slots?.register({name:`settings.section`,id:`dsh-tiddlywiki`,order:50,label:`TiddlyWiki 知识库`},Wy));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=Db,exports.inject=Eb,exports.name=`dsh-tiddlywiki/client`;
|
|
724
724
|
return module.exports;
|
|
725
725
|
}
|