dsh-tiddlywiki 0.23.3 → 0.23.4

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 CHANGED
@@ -109,6 +109,10 @@ dsh plugin --profile web add link:/path/to/dsh-tiddlywiki
109
109
  2. 冲突后用 `tiddlywiki_git_resolve` 二选一解决,再重新 sync(**绝不自动覆盖**)。
110
110
  3. 收工 `tiddlywiki_git_sync action=sync`(pull → commit → push)。
111
111
 
112
+ > 🛡 **带着冲突绝不提交**(v0.23.4):`commit` 之前会探测「进行中的 rebase / 未合并路径 / **工作树里残留的冲突标记**」,命中就**拒绝提交**(`/sync` 返回 409 + 文件名、自动提交只上报一次、`/status` 与设置页状态行显示「冲突未解决(N 个文件,已阻止提交)」)。这条守卫来自真实事故:autostash 重新应用冲突后 `rebase --abort` 已无事可 abort,冲突标记留在工作树里被自动提交**永久写进了 git 历史**(连带插件自己解析不了配置)。**删冲突标记的方式**:解决后 `tiddlywiki_git_resolve`(或手动编辑掉 `<<<<<<<`/`=======`/`>>>>>>>` 三行)再 sync。
113
+ >
114
+ > ⚙️ **配置文件坏了会拒绝保存**(v0.23.4):若 `$:/plugins/dsh-tiddlywiki/config` 不是合法 JSON(最典型就是残留冲突标记),设置页保存会**被拒绝**并在页面顶部显示红色横幅——而不是像以前那样拿空配置合并、把你其余的设置(`prompt.extra`/`git.remote`/`ui.*`…)一次抹掉。修好该 tiddler(或删掉它回落 `config:` 块)后即可正常保存。
115
+
112
116
  > 🔍 **检索/最近跳过二进制附件**(v0.16.20):`search`/`recent` 在**服务端**只取文本 tiddler(无 `type` 字段或 `text/*`),图片/音频/视频/PDF/zip 等二进制 tiddler(base64 正文)不参与检索、不出现在结果里——大 wiki(如数千张书籍扫描页图)从此从 515MB/17s 降到 ~0.4s,也不会被同名书页图刷屏。`get` 对二进制 tiddler 只返回元数据(`binary=true` + 类型/大小 + 链接),不返回 base64 正文。
113
117
 
114
118
  > ⚠️ `fields.type` 是 TW 的**内容类型保留字段**(`text/markdown` 等),业务分类请放 `tags`,别写进 `fields.type`。
@@ -401,6 +405,7 @@ lib/ # 预构建产物(发布含 lib/**,提交入库;
401
405
 
402
406
  > 最近几个主要版本的一句话记录(完整变更见 [Releases](https://github.com/bbqisbbq/dsh-tiddlywiki/releases) / git log)。
403
407
 
408
+ - **v0.23.4**(2026-09-18):**三处硬化,全部来自 v0.23.3 上线当天暴露的真实事故**。① **提交前拦冲突(数据安全)**:`git pull --rebase --autostash` 的 **autostash 重新应用**冲突后,`rebase --abort` 已无事可 abort,冲突标记留在工作树里,随后 60s 的 AutoCommitter 照常 `git add -A && commit` —— `<<<<<<< Updated upstream` 就这样被**永久提交并推送**进了 wiki 的配置 tiddler(`0b19ca6`,2026-09-17),插件随即解析不了自己的配置(微信发布一直是关的、`prompt.extra` 静默失效)。现在 `GitFace.conflictState()` 三重探测(进行中的 rebase / 未合并路径 / **工作树里残留的冲突块**),`commit()` 直接抛 `GitConflictStateError` 拒绝提交;`/sync` 回 409 + 文件名、agent 工具返回结构化失败、AutoCommitter 去重上报一次(不去刷屏);`pull()` 在 abort 后**复检**(autostash 形态正是 abort 之后才暴露);`/status` 与设置页状态行显示「冲突未解决(N 个文件,已阻止提交)」。⚠️ `MERGE_HEAD`/`CHERRY_PICK_HEAD` 故意**不**硬拒——`git commit` 正是收尾它们的动作(真 git E2E 抓出了这个设计错误)。② **配置解析失败拒绝写(数据丢失)**:`ConfigStore.set()` 在存量 tiddler 解析失败时,原先拿**空缓存**合并 → 一次设置页保存就把配置写成只剩表单里那几个字段的"残版"(18 日 13:38 实测:`prompt.extra`/`git.remote`/`ui.*` 全丢)。现在抛 `ConfigUnreadableError`、不 PUT,并把原因经 `/admin/state` 的 `configError` 渲染成设置页顶部红色横幅;瞬时**读**失败仍走"合并到缓存"(回归断言守住)。③ **adapter 版本校验**:`/wechat/ready` 原先只数文件在不在,旧版 adapter(不认识 `--title-file`、标题仍是必填位置参数)也会报"就绪",点按钮才在 opencli 里报"缺少必填参数"。现在按**定义**判新旧(`weixin-flow.js` 必须 `export function resolveNoteTitle(`、两个入口必须声明 `name: 'titleFile'`——**不是**字符串出现,注释里提到不算),`missing`(不存在)与 `stale`(过旧)语义互斥;按钮预检与路由 503 分别说「版本过旧」和「缺少发布脚本」。bundle 升 `0.2.0`。守门:新增 `scripts/verify-conflict-config-guards.mjs`(23 条:伪 exec 纯逻辑 + **真起临时 git 仓库的冲突 E2E**(真 merge 冲突 / 真残留标记,且解决后必须能提交)+ ConfigStore 拒绝写/回归/接线断言;**已反向验证**:拆掉 `contentScan` 或配置拒绝各红 2 条),`verify-wechat-publish.mjs` 17→24 条(+注释里提及新符号必须判旧、真源码符号对齐),bundle 守门 +3 条。
404
409
  - **v0.23.3**(2026-09-18):**TW 笔记工具栏新增「发布到公众号」按钮**(可选功能,与既有 CLI 等价,只是不用敲命令)。链路:TW 按钮 → `POST /dsh-tiddlywiki/wechat/publish` → 宿主 spawn `opencli weixin publish-note` → `GET …/wechat/publish/status` 轮询 → 覆盖层显示进度与日志尾部。**只到草稿箱为止**,发表仍由人工扫码(沿用 v0.23.2 定的策略)。三处硬骨头:① **标题不进 argv**——Windows 上 `opencli` 是 `.cmd` shim,必须经 cmd.exe 启动,于是标题里的 `&`/`|`/`^`/引号成了命令注入面、中文标题还会被 cmd 的代码页解成乱码;改成宿主写 UTF-8 文件 + adapter 新增 **`--title-file`**(位置参数照旧可用,两者都给时位置参数优先)。② **任务化而非同步请求**——命令要跑几十秒到几分钟,`POST` 立即返回 `jobId`,单并发(第二次 409)、15 分钟上限,超时用 `taskkill /T` 杀**整棵进程树**(只杀 cmd.exe 会留下孤儿 node 抓着 job 目录,实测 `EBUSY`)。③ **可选功能默认不打扰**——`wechat.enabled` 关着时三条 `/wechat/*` 路由一律 403、按钮插件不写进 wiki(新增 gated 起步 seed `wechat-publish`,与 `publish-spec`/`wechat-setup` 同进同退)。新增 `src/host/wechat-publish.ts`(命令组装纯函数 + job registry + 就绪探测)、三条路由(方法/同源守卫 + 可选 `x-wechat-publish-token`;`wechat.token` 与其它密钥一样在 `/admin/state` 打码)、TW bundle `$:/plugins/dsh/wechat-publish`(`scripts/bundle/wechat-publish/` + build/gen/verify 流水线,`wechat-publish.bundle.json` 逐字节守门)。守门:`scripts/verify-wechat-publish.mjs`(17 条:纯函数 + **真跑 spawn 的「假 opencli」E2E**(含标题不进 argv 的逐字断言)+ 真实 HTTP 路由守卫;**已反向验证**:拆掉 `guardWechat` 即红)+ `scripts/verify-wechat-publish-bundle.mjs`(进 `verify:static`)+ `verify-wechat-adapters.mjs` 新增「两个 publish adapter 都必须走 `resolveNoteTitle`」。
405
410
  - **v0.23.2**(2026-09-17):**多图发布命令 `publish-note-imgs` + 发布策略定为「到草稿箱为止」**。TW 笔记内嵌 `[img[...]]` 经 `/render` 是 data URI,微信存草稿会过滤非 mmbiz 图——新命令先把正文全部图片经 DataTransfer 逐张上传 CDN(轮询计数到期望值),按 DOM 顺序重写正文 src 再 insertHTML,从正文第一张设封面;发布前同样读 `pub-state`/`no-publish`(只告警不阻断)。`selectCoverFromContent` 封面校验改轮询,修「实际成功却报失败」的假阴性(实测 `list_ex` 的 `cover` 已是 mmbiz 而流程报失败)。安装脚本 FILES 收编至 5 个 adapter,守门断言同步。**策略**:adapter 负责到草稿落盘为止,发表(含原创声明/作者/留言等确认弹窗 + 管理员扫码)由人工完成——`--publish` 保留但 best-effort,遇弹窗会等到超时。文档新增:发表确认弹窗说明、`stale page identity` 续作法、`list_ex`/`appmsgpublish` 核实命令、GitHub ext release 落后 Web Store 备注、npm allowScripts 拦 postinstall 无害备注、**eval 诊断后台必须过滤不可见 toast 残留**(踩过:把残留文案当实时状态误判账号被拦,实际账号正常)。
406
411
 
package/lib/client.js CHANGED
@@ -761,9 +761,9 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
761
761
  }`,{label:`enum`,detail:`definition`,type:`keyword`})]),Ah=new Ll,jh=new Set([`Script`,`Block`,`FunctionExpression`,`FunctionDeclaration`,`ArrowFunction`,`MethodDeclaration`,`ForStatement`]);function Mh(e){return(t,n)=>{let r=t.node.getChild(`VariableDefinition`);return r&&n(r,e),!0}}const Nh=[`FunctionDeclaration`],Ph={FunctionDeclaration:Mh(`function`),ClassDeclaration:Mh(`class`),ClassExpression:()=>!0,EnumDeclaration:Mh(`constant`),TypeAliasDeclaration:Mh(`type`),NamespaceDeclaration:Mh(`namespace`),VariableDefinition(e,t){e.matchContext(Nh)||t(e,`variable`)},TypeDefinition(e,t){t(e,`type`)},__proto__:null};function Fh(e,t){let n=Ah.get(t);if(n)return n;let r=[],i=!0;function a(t,n){let i=e.sliceString(t.from,t.to);r.push({label:i,type:n})}return t.cursor(W.IncludeAnonymous).iterate(t=>{if(i)i=!1;else if(t.name){let e=Ph[t.name];if(e&&e(t,a)||jh.has(t.name))return!1}else if(t.to-t.from>8192){for(let n of Fh(e,t.node))r.push(n);return!1}}),Ah.set(t,r),r}const Ih=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,Lh=[`TemplateString`,`String`,`RegExp`,`LineComment`,`BlockComment`,`VariableDefinition`,`TypeDefinition`,`Label`,`PropertyDefinition`,`PropertyName`,`PrivatePropertyDefinition`,`PrivatePropertyName`,`JSXText`,`JSXAttributeValue`,`JSXOpenTag`,`JSXCloseTag`,`JSXSelfClosingTag`,`.`,`?.`];function Rh(e){let t=J(e.state).resolveInner(e.pos,-1);if(Lh.indexOf(t.name)>-1)return null;let n=t.name==`VariableName`||t.to-t.from<20&&Ih.test(e.state.sliceDoc(t.from,t.to));if(!n&&!e.explicit)return null;let r=[];for(let n=t;n;n=n.parent)jh.has(n.name)&&(r=r.concat(Fh(e.state.doc,n)));return{options:r,from:n?t.from:e.pos,validFor:Ih}}const zh=Pu.define({name:`javascript`,parser:Dh.configure({props:[Qu.add({IfStatement:ud({except:/^\s*({|else\b)/}),TryStatement:ud({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:ld,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:sd({closing:`}`}),ArrowFunction:e=>e.baseIndent+e.unit,"TemplateString BlockComment":()=>null,"Statement Property":ud({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}}),fd.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":pd,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:`$`}}),Bh={test:e=>/^JSX/.test(e.name),facet:Au({commentTokens:{block:{open:`{/*`,close:`*/}`}}})},Vh=zh.configure({dialect:`ts`},`typescript`),Hh=zh.configure({dialect:`jsx`,props:[ju.add(e=>e.isTop?[Bh]:void 0)]}),Uh=zh.configure({dialect:`jsx ts`,props:[ju.add(e=>e.isTop?[Bh]:void 0)]},`typescript`);let Wh=e=>({label:e,type:`keyword`});const Gh=`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(Wh),Kh=Gh.concat([`declare`,`implements`,`private`,`protected`,`public`].map(Wh));function qh(e={}){let t=e.jsx?e.typescript?Uh:Hh:e.typescript?Vh:zh,n=e.typescript?kh.concat(Kh):Oh.concat(Gh);return new Wu(t,[zh.data.of({autocomplete:Rd(Lh,Ld(n))}),zh.data.of({autocomplete:Rh}),e.jsx?Zh:[]])}function Jh(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 Yh(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 Xh=typeof navigator==`object`&&/Android\b/.test(navigator.userAgent),Zh=V.inputHandler.of((e,t,n,r,i)=>{if((Xh?e.composing:e.compositionStarted)||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!zh.isActiveAt(e.state,t,-1))return!1;let a=i(),{state:o}=a,s=o.changeByRange(e=>{let{head:t}=e,n=J(o).resolveInner(t-1,-1),i;if(n.name==`JSXStartTag`&&(n=n.parent),!(o.doc.sliceString(t-1,t)!=r||n.name==`JSXAttributeValue`&&n.to>t)){if(r==`>`&&n.name==`JSXFragmentTag`)return{range:e,changes:{from:t,insert:`</>`}};if(r==`/`&&n.name==`JSXStartCloseTag`){let e=n.parent,r=e.parent;if(r&&e.from==t-2&&((i=Yh(o.doc,r.firstChild,t))||r.firstChild?.name==`JSXFragmentTag`)){let e=`${i}>`;return{range:A.cursor(t+e.length,-1),changes:{from:t,insert:e}}}}else if(r==`>`){let r=Jh(n);if(r&&r.name==`JSXOpenTag`&&!/^\/?>|^<\//.test(o.doc.sliceString(t,t+2))&&(i=Yh(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)}),Qh=[`_blank`,`_self`,`_top`,`_parent`],$h=[`ascii`,`utf-8`,`utf-16`,`latin1`,`latin1`],eg=[`get`,`post`,`put`,`delete`],tg=[`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`],ng=[`true`,`false`],Z={},rg={a:{attrs:{href:null,ping:null,type:null,media:null,target:Qh,hreflang:null}},abbr:Z,address:Z,area:{attrs:{alt:null,coords:null,href:null,target:null,ping:null,media:null,hreflang:null,type:null,shape:[`default`,`rect`,`circle`,`poly`]}},article:Z,aside:Z,audio:{attrs:{src:null,mediagroup:null,crossorigin:[`anonymous`,`use-credentials`],preload:[`none`,`metadata`,`auto`],autoplay:[`autoplay`],loop:[`loop`],controls:[`controls`]}},b:Z,base:{attrs:{href:null,target:Qh}},bdi:Z,bdo:Z,blockquote:{attrs:{cite:null}},body:Z,br:Z,button:{attrs:{form:null,formaction:null,name:null,value:null,autofocus:[`autofocus`],disabled:[`autofocus`],formenctype:tg,formmethod:eg,formnovalidate:[`novalidate`],formtarget:Qh,type:[`submit`,`reset`,`button`]}},canvas:{attrs:{width:null,height:null}},caption:Z,center:Z,cite:Z,code:Z,col:{attrs:{span:null}},colgroup:{attrs:{span:null}},command:{attrs:{type:[`command`,`checkbox`,`radio`],label:null,icon:null,radiogroup:null,command:null,title:null,disabled:[`disabled`],checked:[`checked`]}},data:{attrs:{value:null}},datagrid:{attrs:{disabled:[`disabled`],multiple:[`multiple`]}},datalist:{attrs:{data:null}},dd:Z,del:{attrs:{cite:null,datetime:null}},details:{attrs:{open:[`open`]}},dfn:Z,div:Z,dl:Z,dt:Z,em:Z,embed:{attrs:{src:null,type:null,width:null,height:null}},eventsource:{attrs:{src:null}},fieldset:{attrs:{disabled:[`disabled`],form:null,name:null}},figcaption:Z,figure:Z,footer:Z,form:{attrs:{action:null,name:null,"accept-charset":$h,autocomplete:[`on`,`off`],enctype:tg,method:eg,novalidate:[`novalidate`],target:Qh}},h1:Z,h2:Z,h3:Z,h4:Z,h5:Z,h6:Z,head:{children:[`title`,`base`,`link`,`style`,`meta`,`script`,`noscript`,`command`]},header:Z,hgroup:Z,hr:Z,html:{attrs:{manifest:null}},i:Z,iframe:{attrs:{src:null,srcdoc:null,name:null,width:null,height:null,sandbox:[`allow-top-navigation`,`allow-same-origin`,`allow-forms`,`allow-scripts`],seamless:[`seamless`]}},img:{attrs:{alt:null,src:null,ismap:null,usemap:null,width:null,height:null,crossorigin:[`anonymous`,`use-credentials`]}},input:{attrs:{alt:null,dirname:null,form:null,formaction:null,height:null,list:null,max:null,maxlength:null,min:null,name:null,pattern:null,placeholder:null,size:null,src:null,step:null,value:null,width:null,accept:[`audio/*`,`video/*`,`image/*`],autocomplete:[`on`,`off`],autofocus:[`autofocus`],checked:[`checked`],disabled:[`disabled`],formenctype:tg,formmethod:eg,formnovalidate:[`novalidate`],formtarget:Qh,multiple:[`multiple`],readonly:[`readonly`],required:[`required`],type:[`hidden`,`text`,`search`,`tel`,`url`,`email`,`password`,`datetime`,`date`,`month`,`week`,`time`,`datetime-local`,`number`,`range`,`color`,`checkbox`,`radio`,`file`,`submit`,`image`,`reset`,`button`]}},ins:{attrs:{cite:null,datetime:null}},kbd:Z,keygen:{attrs:{challenge:null,form:null,name:null,autofocus:[`autofocus`],disabled:[`disabled`],keytype:[`RSA`]}},label:{attrs:{for:null,form:null}},legend:Z,li:{attrs:{value:null}},link:{attrs:{href:null,type:null,hreflang:null,media:null,sizes:[`all`,`16x16`,`16x16 32x32`,`16x16 32x32 64x64`]}},map:{attrs:{name:null}},mark:Z,menu:{attrs:{label:null,type:[`list`,`context`,`toolbar`]}},meta:{attrs:{content:null,charset:$h,name:[`viewport`,`application-name`,`author`,`description`,`generator`,`keywords`],"http-equiv":[`content-language`,`content-type`,`default-style`,`refresh`]}},meter:{attrs:{value:null,min:null,low:null,high:null,max:null,optimum:null}},nav:Z,noscript:Z,object:{attrs:{data:null,type:null,name:null,usemap:null,form:null,width:null,height:null,typemustmatch:[`typemustmatch`]}},ol:{attrs:{reversed:[`reversed`],start:null,type:[`1`,`a`,`A`,`i`,`I`]},children:[`li`,`script`,`template`,`ul`,`ol`]},optgroup:{attrs:{disabled:[`disabled`],label:null}},option:{attrs:{disabled:[`disabled`],label:null,selected:[`selected`],value:null}},output:{attrs:{for:null,form:null,name:null}},p:Z,param:{attrs:{name:null,value:null}},pre:Z,progress:{attrs:{value:null,max:null}},q:{attrs:{cite:null}},rp:Z,rt:Z,ruby:Z,samp:Z,script:{attrs:{type:[`text/javascript`],src:null,async:[`async`],defer:[`defer`],charset:$h}},section:Z,select:{attrs:{form:null,name:null,size:null,autofocus:[`autofocus`],disabled:[`disabled`],multiple:[`multiple`]}},slot:{attrs:{name:null}},small:Z,source:{attrs:{src:null,type:null,media:null}},span:Z,strong:Z,style:{attrs:{type:[`text/css`],media:null,scoped:null}},sub:Z,summary:Z,sup:Z,table:Z,tbody:Z,td:{attrs:{colspan:null,rowspan:null,headers:null}},template:Z,textarea:{attrs:{dirname:null,form:null,maxlength:null,name:null,placeholder:null,rows:null,cols:null,autofocus:[`autofocus`],disabled:[`disabled`],readonly:[`readonly`],required:[`required`],wrap:[`soft`,`hard`]}},tfoot:Z,th:{attrs:{colspan:null,rowspan:null,headers:null,scope:[`row`,`col`,`rowgroup`,`colgroup`]}},thead:Z,time:{attrs:{datetime:null}},title:Z,tr:Z,track:{attrs:{src:null,label:null,default:null,kind:[`subtitles`,`captions`,`descriptions`,`chapters`,`metadata`],srclang:null}},ul:{children:[`li`,`script`,`template`,`ul`,`ol`]},var:Z,video:{attrs:{src:null,poster:null,width:null,height:null,crossorigin:[`anonymous`,`use-credentials`],preload:[`auto`,`metadata`,`none`],autoplay:[`autoplay`],mediagroup:[`movie`],muted:[`muted`],controls:[`controls`]}},wbr:Z},ig={accesskey:null,class:null,contenteditable:ng,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:ng,autocorrect:ng,autocapitalize:ng,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":ng,"aria-autocomplete":[`inline`,`list`,`both`,`none`],"aria-busy":ng,"aria-checked":[`true`,`false`,`mixed`,`undefined`],"aria-controls":null,"aria-describedby":null,"aria-disabled":ng,"aria-dropeffect":null,"aria-expanded":[`true`,`false`,`undefined`],"aria-flowto":null,"aria-grabbed":[`true`,`false`,`undefined`],"aria-haspopup":ng,"aria-hidden":ng,"aria-invalid":[`true`,`false`,`grammar`,`spelling`],"aria-label":null,"aria-labelledby":null,"aria-level":null,"aria-live":[`off`,`polite`,`assertive`],"aria-multiline":ng,"aria-multiselectable":ng,"aria-owns":null,"aria-posinset":null,"aria-pressed":[`true`,`false`,`mixed`,`undefined`],"aria-readonly":ng,"aria-relevant":null,"aria-required":ng,"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},ag=`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 ag)ig[e]=null;var og=class{constructor(e,t){this.tags={...rg,...e},this.globalAttrs={...ig,...t},this.allTags=Object.keys(this.tags),this.globalAttrNames=Object.keys(this.globalAttrs)}};og.default=new og;function sg(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 cg(e,t=!1){for(;e;e=e.parent)if(e.name==`Element`)if(t)t=!1;else return e;return null}function lg(e,t,n){return n.tags[sg(e,cg(t))]?.children||n.allTags}function ug(e,t){let n=[];for(let r=cg(t);r&&!r.type.isTop;r=cg(r.parent)){let i=sg(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 dg=/^[:\-\.\w\u00b7-\uffff]*$/;function fg(e,t,n,r,i){let a=/\s*>/.test(e.sliceDoc(i,i+5))?``:`>`,o=cg(n,n.name==`StartTag`||n.name==`TagName`);return{from:r,to:i,options:lg(e.doc,o,t).map(e=>({label:e,type:`type`})).concat(ug(e.doc,n).map((e,t)=>({label:`/`+e,apply:`/`+e+a,type:`type`,boost:99-t}))),validFor:/^\/?[:\-\.\w\u00b7-\uffff]*$/}}function pg(e,t,n,r){let i=/\s*>/.test(e.sliceDoc(r,r+5))?``:`>`;return{from:n,to:r,options:ug(e.doc,t).map((e,t)=>({label:e,apply:e+i,type:`type`,boost:99-t})),validFor:dg}}function mg(e,t,n,r){let i=[],a=0;for(let r of lg(e.doc,n,t))i.push({label:`<`+r,type:`type`});for(let t of ug(e.doc,n))i.push({label:`</`+t+`>`,type:`type`,boost:99-a++});return{from:r,to:r,options:i,validFor:/^<\/?[:\-\.\w\u00b7-\uffff]*$/}}function hg(e,t,n,r,i){let a=cg(n),o=a?t.tags[sg(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:dg}}function gg(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=cg(n),i=r?t.tags[sg(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 _g(e,t){let{state:n,pos:r}=t,i=J(n).resolveInner(r,-1),a=i.resolve(r);for(let e=r,t;a==i&&(t=i.childBefore(e));){let n=t.lastChild;if(!n||!n.type.isError||n.from<n.to)break;a=i=t,e=n.from}return i.name==`TagName`?i.parent&&/CloseTag$/.test(i.parent.name)?pg(n,i,i.from,r):fg(n,e,i,i.from,r):i.name==`StartTag`||i.name==`IncompleteTag`?fg(n,e,i,r,r):i.name==`StartCloseTag`||i.name==`IncompleteCloseTag`?pg(n,i,r,r):i.name==`OpenTag`||i.name==`SelfClosingTag`||i.name==`AttributeName`?hg(n,e,i,i.name==`AttributeName`?i.from:r,r):i.name==`Is`||i.name==`AttributeValue`||i.name==`UnquotedAttributeValue`?gg(n,e,i,i.name==`Is`?r:i.from,r):t.explicit&&(a.name==`Element`||a.name==`Text`||a.name==`Document`)?mg(n,e,i,r):null}function vg(e){return _g(og.default,e)}function yg(e){let{extraTags:t,extraGlobalAttributes:n}=e,r=n||t?new og(t,n):og.default;return e=>_g(r,e)}const bg=zh.parser.configure({top:`SingleExpression`}),xg=[{tag:`script`,attrs:e=>e.type==`text/typescript`||e.lang==`ts`,parser:Vh.parser},{tag:`script`,attrs:e=>e.type==`text/babel`||e.type==`text/jsx`,parser:Hh.parser},{tag:`script`,attrs:e=>e.type==`text/typescript-jsx`,parser:Uh.parser},{tag:`script`,attrs(e){return/^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(e.type)},parser:bg},{tag:`script`,attrs(e){return!e.type||/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(e.type)},parser:zh.parser},{tag:`style`,attrs(e){return(!e.lang||e.lang==`css`)&&(!e.type||/^(text\/)?(x-)?(stylesheet|css)$/i.test(e.type))},parser:ph.parser}],Sg=[{name:`style`,parser:ph.parser.configure({top:`Styles`})}].concat(ag.map(e=>({name:e,parser:zh.parser}))),Cg=Pu.define({name:`html`,parser:Mm.configure({props:[Qu.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}}),fd.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}}}),xd.add({"OpenTag CloseTag":e=>e.getChild(`TagName`)})]}),languageData:{commentTokens:{block:{open:`<!--`,close:`-->`}},indentOnInput:/^\s*<\/\w+\W$/,wordChars:`-_`}}),wg=Cg.configure({wrap:Im(xg,Sg)});function Tg(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=Im((e.nestedLanguages||[]).concat(xg),(e.nestedAttributes||[]).concat(Sg))),new Wu(n?Cg.configure({wrap:n,dialect:t}):t?wg.configure({dialect:t}):wg,[wg.data.of({autocomplete:yg(e)}),e.autoCloseTags===!1?[]:Og,qh().support,mh().support])}const Eg=new Set(`area base br col command embed frame hr img input keygen link meta param source track wbr menuitem`.split(` `));function Dg(e,t,n){for(;;){if(t.lastChild?.name!=`CloseTag`)return!1;let r=t.parent;if(!r||sg(e,r)!=n)return!0;t=r}}const Og=V.inputHandler.of((e,t,n,r,i)=>{if(e.composing||e.state.readOnly||t!=n||r!=`>`&&r!=`/`||!wg.isActiveAt(e.state,t,-1))return!1;let a=i(),{state:o}=a,s=o.changeByRange(e=>{let t=o.doc.sliceString(e.from-1,e.to)==r,{head:n}=e,i=J(o).resolveInner(n,-1),a;if(t&&r==`>`&&i.name==`EndTag`){let t=i.parent;if((a=sg(o.doc,t.parent,n))&&!Eg.has(a)&&!Dg(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=sg(o.doc,e,n))&&!Eg.has(a)){let e=n+ +(o.doc.sliceString(n,n+1)===`>`),t=`${a}>`;return{range:A.cursor(n+t.length,-1),changes:{from:n,to:e,insert:t}}}}return{range:e}});return s.changes.empty?!1:(e.dispatch([a,o.update(s,{userEvent:`input.complete`,scrollIntoView:!0})]),!0)}),kg=Au({commentTokens:{block:{open:`<!--`,close:`-->`}}}),Ag=new H,jg=dp.configure({props:[fd.add(e=>!e.is(`Block`)||e.is(`Document`)||Mg(e)!=null||Ng(e)?void 0:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})),Ag.add(Mg),Qu.add({Document:()=>null}),ku.add({Document:kg})]});function Mg(e){let t=/^(?:ATX|Setext)Heading(\d)$/.exec(e.name);return t?+t[1]:void 0}function Ng(e){return e.name==`OrderedList`||e.name==`BulletList`}function Pg(e,t){let n=e;for(;;){let e=n.nextSibling,r;if(!e||(r=Mg(e.type))!=null&&r<=t)break;n=e}return n.to}const Fg=dd.of((e,t,n)=>{for(let r=J(e).resolveInner(n,-1);r&&!(r.from<t);r=r.parent){let e=r.type.prop(Ag);if(e==null)continue;let t=Pg(r,e);if(t>n)return{from:n,to:t}}return null});function Ig(e){return new Mu(kg,e,[],`markdown`)}const Lg=Ig(jg),Rg=Ig(jg.configure([jp,Pp,Np,Fp,{props:[fd.add({Table:(e,t)=>({from:t.doc.lineAt(e.from).to,to:e.to})})]}]));function zg(e,t){return n=>{if(n&&e){let t=null;if(n=/\S*/.exec(n)[0],t=typeof e==`function`?e(n):Gu.matchLanguageName(e,n,!0),t instanceof Gu)return t.support?t.support.language.parser:Lu.getSkippingParser(t.load());if(t)return t.parser}return t?t.parser:null}}var Bg=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(+Hg(this.item,e)[2]+t):``;return this.spaceBefore+n+this.type+this.spaceAfter}};function Vg(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 Bg(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 Bg(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 Bg(i.parent,s,s+t,a[1],e,n,i))}}return r}function Hg(e,t){return/^(\s*)(\d+)(?=[.)])/.exec(t.sliceString(e.from,e.from+10))}function Ug(e,t,n,r=0){for(let i=-1,a=e;;){if(a.name==`ListItem`){let e=Hg(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 Wg(e,t){let n=/^[ \t]*/.exec(e)[0].length;if(!n||t.facet(qu)!=` `)return e;let r=wr(e,4,n),i=``;for(let e=r;e>0;)e>=4?(i+=` `,e-=4):(i+=` `,e--);return i+e.slice(n)}const Gg=((e={})=>({state:t,dispatch:n})=>{let r=J(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=Vg(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`&&Ug(l.item,i,r,-2),e&&e.node.name==`OrderedList`&&Ug(e.item,i,r),{range:A.cursor(t+n.length),changes:r}}else{let e=Jg(c,t,s);return{range:A.cursor(o+e.length+1),changes:{from:s.from,insert:e+t.lineBreak}}}}if(l.node.name==`Blockquote`&&u&&s.from){let e=i.lineAt(s.from-1),r=/>\s*$/.exec(e.text);if(r&&r.index==l.from){let i=t.changes([{from:e.from+r.index,to:e.to},{from:s.from+l.from,to:s.to}]);return{range:n.map(i),changes:i}}}let d=[];l.node.name==`OrderedList`&&Ug(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?wr(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=Wg(p,t),qg(l.node,t.doc)&&(p=Jg(c,t,s)+t.lineBreak+p),d.push({from:m,to:o,insert:t.lineBreak+p}),{range:A.cursor(m+p.length+1),changes:d}});return a?!1:(n(t.update(o,{scrollIntoView:!0,userEvent:`input`})),!0)})();function Kg(e){return e.name==`QuoteMark`||e.name==`ListMark`}function qg(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 Jg(e,t,n){let r=``;for(let t=0,i=e.length-2;t<=i;t++)r+=e[t].blank(t<i?wr(n.text,4,e[t+1].from)-r.length:null,t<i);return Wg(r,t)}function Yg(e,t){let n=e.resolveInner(t,-1),r=t;Kg(n)&&(r=n.from,n=n.parent);for(let e;e=n.childBefore(r);)if(Kg(e))r=e.from;else if(e.name==`OrderedList`||e.name==`BulletList`)n=e.lastChild,r=n.to;else break;return n}const Xg=[{key:`Enter`,run:Gg},{key:`Backspace`,run:({state:e,dispatch:t})=>{let n=J(e),r=null,i=e.changeByRange(t=>{let i=t.from,{doc:a}=e;if(t.empty&&Rg.isActiveAt(e,t.from)){let t=a.lineAt(i),r=Vg(Yg(n,i),a);if(r.length){let n=r[r.length-1],a=n.to-n.spaceAfter.length+ +!!n.spaceAfter;if(i-t.from>a&&!/\S/.test(t.text.slice(a,i-t.from)))return{range:A.cursor(t.from+a),changes:{from:t.from+a,to:i}};if(i-t.from==a&&(n.item&&t.from<=n.item.from||/^[\s>]*$/.test(t.text.slice(0,n.to)))){let r=t.from+n.from;if(n.item&&n.node.from<n.item.from&&/\S/.test(t.text.slice(n.from,n.to))){let i=n.blank(wr(t.text,4,n.to)-wr(t.text,4,n.from));return r==t.from&&(i=Wg(i,e)),{range:A.cursor(r+i.length),changes:{from:r,to:t.from+n.to,insert:i}}}if(r<i)return{range:A.cursor(r),changes:{from:r,to:i}}}}}return r={range:t}});return r?!1:(t(e.update(i,{scrollIntoView:!0,userEvent:`delete`})),!0)}}],Zg=Tg({matchClosingTags:!1});function Qg(e={}){let{codeLanguages:t,defaultCodeLanguage:n,addKeymap:r=!0,base:{parser:i}=Lg,completeHTMLTags:a=!0,pasteURLAsLink:o=!0,htmlTagLanguage:s=Zg}=e;if(!(i instanceof zf))throw RangeError("Base parser provided to `markdown` should be a Markdown parser");let c=e.extensions?[e.extensions]:[],l=[s.support,Fg],u;o&&l.push(r_),n instanceof Wu?(l.push(n.support),u=n.language):n&&(u=n);let d=t||u?zg(t,u):void 0;c.push(pp({codeParser:d,htmlParser:s.language.parser})),r&&l.push(Dn.high(Rc.of(Xg)));let f=Ig(i.configure(c));return a&&l.push(f.data.of({autocomplete:$g})),new Wu(f,l)}function $g(e){let{state:t,pos:n}=e,r=/<[:\-\.\w\u00b7-\uffff]*$/.exec(t.sliceDoc(n-25,n));if(!r)return null;let i=J(t).resolveInner(n,-1);for(;i&&!i.type.isTop;){if(i.name==`CodeBlock`||i.name==`FencedCode`||i.name==`ProcessingInstructionBlock`||i.name==`CommentBlock`||i.name==`Link`||i.name==`Image`)return null;i=i.parent}return{from:n-r[0].length,to:n,options:t_(),validFor:/^<[:\-\.\w\u00b7-\uffff]*$/}}let e_=null;function t_(){if(e_)return e_;let e=vg(new Pd(N.create({extensions:Zg}),0,!0));return e_=e?e.options:[]}const n_=/code|horizontalrule|html|link|comment|processing|escape|entity|image|mark|url/i,r_=V.domEventHandlers({paste:(e,t)=>{let{main:n}=t.state.selection;if(n.empty)return!1;let r=e.clipboardData?.getData(`text/plain`);if(!r||!/^(https?:\/\/|mailto:|xmpp:|www\.)/.test(r)||(/^www\./.test(r)&&(r=`https://`+r),!Rg.isActiveAt(t.state,n.from,1)))return!1;let i=J(t.state),a=!1;return i.iterate({from:n.from,to:n.to,enter:e=>{(e.from>n.from||n_.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)}}),i_=e=>{let{state:t}=e,n=t.doc.lineAt(t.selection.main.from),r=l_(e.state,n.from);return r.line?o_(e):r.block?c_(e):!1};function a_(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 o_=a_(p_,0),s_=a_(f_,0),c_=a_((e,t)=>f_(e,t,d_(t)),0);function l_(e,t){let n=e.languageDataAt(`commentTokens`,t,1);return n.length?n[0]:{}}function u_(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 d_(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 f_(e,t,n=t.selection.ranges){let r=n.map(e=>l_(t,e.from).block);if(!r.every(e=>e))return null;let i=n.map((e,n)=>u_(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 p_(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=l_(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 m_=Hn.define(),h_=Hn.define(),g_=j.define(),__=j.define({combine(e){return ar(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)})}}),v_=wn.define({create(){return I_.empty},update(e,t){let n=t.state.facet(__),r=t.annotation(m_);if(r){let i=T_.fromTransaction(t,r.selection),a=r.side,o=a==0?e.undone:e.done;return o=i?E_(o,o.length,n.minDepth,i):j_(o,t.startState.selection),new I_(a==0?r.rest:o,a==0?o:r.rest)}let i=t.annotation(h_);if((i==`full`||i==`before`)&&(e=e.isolate()),t.annotation(Gn.addToHistory)===!1)return t.changes.empty?e:e.addMapping(t.changes.desc);let a=T_.fromTransaction(t),o=t.annotation(Gn.time),s=t.annotation(Gn.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 I_(e.done.map(T_.fromJSON),e.undone.map(T_.fromJSON))}});function y_(e={}){return[v_,__.of(e),V.domEventHandlers({beforeinput(e,t){let n=e.inputType==`historyUndo`?x_:e.inputType==`historyRedo`?S_:null;return n?(e.preventDefault(),n(t)):!1}})]}function b_(e,t){return function({state:n,dispatch:r}){if(!t&&n.readOnly)return!1;let i=n.field(v_,!1);if(!i)return!1;let a=i.pop(e,n,t);return a?(r(a),!0):!1}}const x_=b_(0,!1),S_=b_(1,!1),C_=b_(0,!0),w_=b_(1,!0);var T_=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&&cn.fromJSON(t.changes),[],t.mapped&&sn.fromJSON(t.mapped),t.startSelection&&A.fromJSON(t.startSelection),t.selectionsAfter.map(A.fromJSON))}static fromTransaction(t,n){let r=A_;for(let e of t.startState.facet(g_)){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,A_)}static selection(t){return new e(void 0,A_,void 0,void 0,t)}};function E_(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 D_(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 O_(e,t){return e.ranges.length==t.ranges.length&&e.ranges.filter((e,n)=>e.empty!=t.ranges[n].empty).length===0}function k_(e,t){return e.length?t.length?e.concat(t):e:t}const A_=[];function j_(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),E_(e,e.length-1,1e9,n.setSelAfter(r)))}else return[T_.selection([t])]}function M_(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 N_(e,t){if(!e.length)return e;let n=e.length,r=A_;for(;n;){let i=P_(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?[T_.selection(r)]:A_}function P_(e,t,n){let r=k_(e.selectionsAfter.length?e.selectionsAfter.map(e=>e.map(t)):A_,n);if(!e.changes)return T_.selection(r);let i=e.changes.map(t),a=t.mapDesc(e.changes,!0),o=e.mapped?e.mapped.composeDesc(a):a;return new T_(i,M.mapEffects(e.effects,t),o,e.startSelection.map(a),r)}const F_=/^(input\.type|delete)($|\.)/;var I_=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||F_.test(r))&&(!s.selectionsAfter.length&&n-this.prevTime<i.newGroupDelay&&i.joinToEvent(a,D_(s.changes,t.changes))||r==`input.type.compose`)?E_(o,o.length-1,i.minDepth,new T_(t.changes.compose(s.changes),k_(M.mapEffects(t.effects,s.changes),s.effects),s.mapped,s.startSelection,A_)):E_(o,o.length,i.minDepth,t),new e(o,A_,n,r)}addSelection(t,n,r,i){let a=this.done.length?this.done[this.done.length-1].selectionsAfter:A_;return a.length>0&&n-this.prevTime<i&&r==this.prevUserEvent&&r&&/^select($|\.)/.test(r)&&O_(a[a.length-1],t)?this:new e(j_(this.done,t),this.undone,n,r)}addMapping(t){return new e(N_(this.done,t),N_(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:m_.of({side:e,rest:M_(r),selection:a}),userEvent:e==0?`select.undo`:`select.redo`,scrollIntoView:!0});if(i.changes){let n=r.length==1?A_:r.slice(0,r.length-1);return i.mapped&&(n=N_(n,i.mapped)),t.update({changes:i.changes,selection:i.startSelection,effects:i.effects,annotations:m_.of({side:e,rest:n,selection:a}),filter:!1,userEvent:e==0?`undo`:`redo`,scrollIntoView:!0})}else return null}};I_.empty=new I_(A_,A_);const L_=[{key:`Mod-z`,run:x_,preventDefault:!0},{key:`Mod-y`,mac:`Mod-Shift-z`,run:S_,preventDefault:!0},{linux:`Ctrl-Shift-z`,run:S_,preventDefault:!0},{key:`Mod-u`,run:C_,preventDefault:!0},{key:`Alt-u`,mac:`Mod-Shift-u`,run:w_,preventDefault:!0}];function R_(e,t){return A.create(e.ranges.map(t),e.mainIndex)}function z_(e,t){return e.update({selection:t,scrollIntoView:!0,userEvent:`select`})}function B_({state:e,dispatch:t},n){let r=R_(e.selection,n);return r.eq(e.selection,!0)?!1:(t(z_(e,r)),!0)}function V_(e,t){return A.cursor(t?e.to:e.from)}function H_(e,t){return B_(e,n=>n.empty?e.moveByChar(n,t):V_(n,t))}function Q(e){return e.textDirectionAt(e.state.selection.main.head)==L.LTR}const U_=e=>H_(e,!Q(e)),W_=e=>H_(e,Q(e));function G_(e,t){return B_(e,n=>n.empty?e.moveByGroup(n,t):V_(n,t))}const K_=e=>G_(e,!Q(e)),q_=e=>G_(e,Q(e));typeof Intl<`u`&&Intl.Segmenter;function J_(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 Y_(e,t,n){let r=J(e).resolveInner(t.head),i=n?H.closedBy:H.openedBy;for(let a=t.head;;){let t=n?r.childAfter(a):r.childBefore(a);if(!t)break;J_(e,t,i)?r=t:a=n?t.to:t.from}let a=r.type.prop(i),o,s;return s=a&&(o=n?wd(e,r.from,1):wd(e,r.to,-1))&&o.matched?n?o.end.to:o.end.from:n?r.to:r.from,A.cursor(s,n?-1:1)}const X_=e=>B_(e,t=>Y_(e.state,t,!Q(e))),Z_=e=>B_(e,t=>Y_(e.state,t,Q(e)));function Q_(e,t){return B_(e,n=>{if(!n.empty)return V_(n,t);let r=e.moveVertically(n,t);return r.head==n.head?e.moveToLineBoundary(n,t):r})}const $_=e=>Q_(e,!1),ev=e=>Q_(e,!0);function tv(e){let t=e.scrollDOM.clientHeight<e.scrollDOM.scrollHeight-2,n=0,r=0,i;if(t){for(let t of e.state.facet(V.scrollMargins)){let i=t(e);i?.top&&(n=Math.max(i?.top,n)),i?.bottom&&(r=Math.max(i?.bottom,r))}i=e.scrollDOM.clientHeight-n-r}else i=(e.dom.ownerDocument.defaultView||window).innerHeight;return{marginTop:n,marginBottom:r,selfScroll:t,height:Math.max(e.defaultLineHeight,i-5)}}function nv(e,t){let n=tv(e),{state:r}=e,i=R_(r.selection,r=>r.empty?e.moveVertically(r,t,n.height):V_(r,t));if(i.eq(r.selection))return!1;let a;if(n.selfScroll){let t=e.coordsAtPos(r.selection.main.head),o=e.scrollDOM.getBoundingClientRect(),s=o.top+n.marginTop,c=o.bottom-n.marginBottom;t&&t.top>s&&t.bottom<c&&(a=V.scrollIntoView(i.main.head,{y:`start`,yMargin:t.top-s}))}return e.dispatch(z_(r,i),{effects:a}),!0}const rv=e=>nv(e,!1),iv=e=>nv(e,!0);function av(e,t,n){let r=e.lineBlockAt(t.head),i=e.moveToLineBoundary(t,n);if(i.head==t.head&&i.head!=(n?r.to:r.from)&&(i=e.moveToLineBoundary(t,n,!1)),!n&&i.head==r.from&&r.length){let n=/^\s*/.exec(e.state.sliceDoc(r.from,Math.min(r.from+100,r.to)))[0].length;n&&t.head!=r.from+n&&(i=A.cursor(r.from+n))}return i}const ov=e=>B_(e,t=>av(e,t,!0)),sv=e=>B_(e,t=>av(e,t,!1)),cv=e=>B_(e,t=>av(e,t,!Q(e))),lv=e=>B_(e,t=>av(e,t,Q(e))),uv=e=>B_(e,t=>A.cursor(e.lineBlockAt(t.head).from,1)),dv=e=>B_(e,t=>A.cursor(e.lineBlockAt(t.head).to,-1));function fv(e,t,n){let r=!1,i=R_(e.selection,t=>{let i=wd(e,t.head,-1)||wd(e,t.head,1)||t.head>0&&wd(e,t.head-1,1)||t.head<e.doc.length&&wd(e,t.head+1,-1);if(!i||!i.end)return t;r=!0;let a=i.start.from==t.head?i.end.to:i.end.from;return n?A.range(t.anchor,a):A.cursor(a)});return r?(t(z_(e,i)),!0):!1}const pv=({state:e,dispatch:t})=>fv(e,t,!1);function mv(e,t,n){let r=R_(e.state.selection,e=>{e.undirectional&&e.head>=e.anchor!=t&&(e=A.range(e.head,e.anchor));let r=n(e);return A.range(e.anchor,r.head,r.goalColumn,r.bidiLevel||void 0,r.assoc)});return r.eq(e.state.selection)?!1:(e.dispatch(z_(e.state,r)),!0)}function hv(e,t){return mv(e,t,n=>e.moveByChar(n,t))}const gv=e=>hv(e,!Q(e)),_v=e=>hv(e,Q(e));function vv(e,t){return mv(e,t,n=>e.moveByGroup(n,t))}const yv=e=>vv(e,!Q(e)),bv=e=>vv(e,Q(e)),xv=e=>{let t=!Q(e);return mv(e,t,n=>Y_(e.state,n,t))},Sv=e=>{let t=Q(e);return mv(e,t,n=>Y_(e.state,n,t))};function Cv(e,t){return mv(e,t,n=>e.moveVertically(n,t))}const wv=e=>Cv(e,!1),Tv=e=>Cv(e,!0);function Ev(e,t){return mv(e,t,n=>e.moveVertically(n,t,tv(e).height))}const Dv=e=>Ev(e,!1),Ov=e=>Ev(e,!0),kv=e=>mv(e,!0,t=>av(e,t,!0)),Av=e=>mv(e,!1,t=>av(e,t,!1)),jv=e=>{let t=!Q(e);return mv(e,t,n=>av(e,n,t))},Mv=e=>{let t=Q(e);return mv(e,t,n=>av(e,n,t))},Nv=e=>mv(e,!1,t=>A.cursor(e.lineBlockAt(t.head).from)),Pv=e=>mv(e,!0,t=>A.cursor(e.lineBlockAt(t.head).to)),Fv=({state:e,dispatch:t})=>(t(z_(e,{anchor:0})),!0),Iv=({state:e,dispatch:t})=>(t(z_(e,{anchor:e.doc.length})),!0),Lv=({state:e,dispatch:t})=>(t(z_(e,{anchor:e.selection.main.anchor,head:0})),!0),Rv=({state:e,dispatch:t})=>(t(z_(e,{anchor:e.selection.main.anchor,head:e.doc.length})),!0),zv=({state:e,dispatch:t})=>(t(e.update({selection:{anchor:0,head:e.doc.length},userEvent:`select`})),!0),Bv=({state:e,dispatch:t})=>{let n=ay(e).map(({from:t,to:n})=>A.undirectionalRange(t,Math.min(n+1,e.doc.length)));return t(e.update({selection:A.create(n),userEvent:`select`})),!0},Vv=({state:e,dispatch:t})=>{let n=R_(e.selection,t=>{let n=J(e),r=n.resolveStack(t.from,1);if(t.empty){let e=n.resolveStack(t.from,-1);e.node.from>=r.node.from&&e.node.to<=r.node.to&&(r=e)}for(let e=r;e;e=e.next){let{node:n}=e;if((n.from<t.from&&n.to>=t.to||n.to>t.to&&n.from<=t.from)&&e.next)return A.undirectionalRange(n.from,n.to)}return t});return n.eq(e.selection)?!1:(t(z_(e,n)),!0)};function Hv(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(z_(n,A.create(i,i.length-1))),!0)}const Uv=e=>Hv(e,!1),Wv=e=>Hv(e,!0),Gv=({state:e,dispatch:t})=>{let n=e.selection,r=null;return n.ranges.length>1?r=A.create([n.main]):n.main.empty||(r=A.create([A.cursor(n.main.head)])),r?(t(z_(e,r)),!0):!1};function Kv(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=qv(e,o,!1)):o>i&&(n=`delete.forward`,o=qv(e,o,!0)),i=Math.min(i,o),a=Math.max(a,o)}else i=qv(e,i,!1),a=qv(e,a,!0);return i==a?{range:r}:{changes:{from:i,to:a},range:A.cursor(i,i<r.head?-1:1)}});return i.changes.empty?!1:(e.dispatch(r.update(i,{scrollIntoView:!0,userEvent:n,effects:n==`delete.selection`?V.announce.of(r.phrase(`Selection deleted`)):void 0})),!0)}function qv(e,t,n){if(e instanceof V)for(let r of e.state.facet(V.atomicRanges).map(t=>t(e)))r.between(t,t,(e,r)=>{e<t&&r>t&&(t=n?r:e)});return t}const Jv=(e,t,n)=>Kv(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=wr(s,a.tabSize)%Ju(a)||Ju(a);for(let t=0;t<e&&s[s.length-1-t]==` `;t++)i--;c=i}else c=$t(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=$t(o.text,c-o.from,!1,!1)+o.from);return c}),Yv=e=>Jv(e,!1,!0),Xv=e=>Jv(e,!0,!1),Zv=(e,t)=>Kv(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=$t(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}),Qv=e=>Zv(e,!1),$v=e=>Zv(e,!0),ey=e=>Kv(e,t=>{let n=e.lineBlockAt(t.head).to;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),ty=e=>Kv(e,t=>{let n=e.moveToLineBoundary(t,!1).head;return t.head>n?n:Math.max(0,t.head-1)}),ny=e=>Kv(e,t=>{let n=e.moveToLineBoundary(t,!0).head;return t.head<n?n:Math.min(e.state.doc.length,t.head+1)}),ry=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=e.changeByRange(e=>({changes:{from:e.from,to:e.to,insert:k.of([``,``])},range:A.cursor(e.from)}));return t(e.update(n,{scrollIntoView:!0,userEvent:`input`})),!0},iy=({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:$t(r.text,n-r.from,!1)+r.from,a=n==r.to?n+1:$t(r.text,n-r.from,!0)+r.from;return{changes:{from:i,to:a,insert:e.doc.slice(n,a).append(e.doc.slice(i,n))},range:A.cursor(a)}});return n.changes.empty?!1:(t(e.update(n,{scrollIntoView:!0,userEvent:`move.character`})),!0)};function ay(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 oy(e,t,n){if(e.readOnly)return!1;let r=[],i=[];for(let t of ay(e)){if(n?t.to==e.doc.length:t.from==0)continue;let a=e.doc.lineAt(n?t.to+1:t.from-1),o=a.length+1;if(n){r.push({from:t.to,to:a.to},{from:t.from,insert:a.text+e.lineBreak});for(let n of t.ranges)i.push(A.range(Math.min(e.doc.length,n.anchor+o),Math.min(e.doc.length,n.head+o)))}else{r.push({from:a.from,to:t.from},{from:t.to,insert:e.lineBreak+a.text});for(let e of t.ranges)i.push(A.range(e.anchor-o,e.head-o))}}return r.length?(t(e.update({changes:r,scrollIntoView:!0,selection:A.create(i,e.selection.mainIndex),userEvent:`move.line`})),!0):!1}const sy=({state:e,dispatch:t})=>oy(e,t,!1),cy=({state:e,dispatch:t})=>oy(e,t,!0);function ly(e,t,n){if(e.readOnly)return!1;let r=[];for(let t of ay(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 uy=({state:e,dispatch:t})=>ly(e,t,!1),dy=({state:e,dispatch:t})=>ly(e,t,!0),fy=e=>{if(e.state.readOnly)return!1;let{state:t}=e,n=t.changes(ay(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 py(e,t){if(/\(\)|\[\]|\{\}/.test(e.sliceDoc(t-1,t+1)))return{from:t,to:t};let n=J(e).resolveInner(t),r=n.childBefore(t),i=n.childAfter(t),a;return r&&i&&r.to<=t&&i.from>=t&&(a=r.type.prop(H.closedBy))&&a.indexOf(i.name)>-1&&e.doc.lineAt(r.to).from==e.doc.lineAt(i.from).from&&!/\S/.test(e.sliceDoc(r.to,i.from))?{from:r.to,to:i.from}:null}const my=gy(!1),hy=gy(!0);function gy(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&&py(t,r);e&&(r=i=(i<=a.to?a:t.doc.lineAt(i)).to);let s=new Zu(t,{simulateBreak:r,simulateDoubleBreak:!!o}),c=Xu(s,r);for(c??=wr(/^\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=[``,Yu(t,c)];return o&&l.push(Yu(t,s.lineIndent(a.from,-1))),{changes:{from:r,to:i,insert:k.of(l)},range:A.cursor(r+1+l[1].length)}});return n(t.update(r,{scrollIntoView:!0,userEvent:`input`})),!0}}function _y(e,t){let n=-1;return e.changeByRange(r=>{let i=[];for(let a=r.from;a<=r.to;){let o=e.doc.lineAt(a);o.number>n&&(r.empty||r.to>o.from)&&(t(o,i,r),n=o.number),a=o.to+1}let a=e.changes(i);return{changes:i,range:A.range(a.mapPos(r.anchor,1),a.mapPos(r.head,1))}})}const vy=({state:e,dispatch:t})=>{if(e.readOnly)return!1;let n=Object.create(null),r=new Zu(e,{overrideIndentation:e=>n[e]??-1}),i=_y(e,(t,i,a)=>{let o=Xu(r,t.from);if(o==null)return;/\S/.test(t.text)||(o=0);let s=/^\s*/.exec(t.text)[0],c=Yu(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},yy=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(_y(e,(t,n)=>{n.push({from:t.from,insert:e.facet(qu)})}),{userEvent:`input.indent`})),!0),by=({state:e,dispatch:t})=>e.readOnly?!1:(t(e.update(_y(e,(t,n)=>{let r=/^\s*/.exec(t.text)[0];if(!r)return;let i=wr(r,e.tabSize),a=0,o=Yu(e,Math.max(0,i-Ju(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),xy=e=>(e.setTabFocusMode(),!0),Sy=[{key:`Ctrl-b`,run:U_,shift:gv,preventDefault:!0},{key:`Ctrl-f`,run:W_,shift:_v},{key:`Ctrl-p`,run:$_,shift:wv},{key:`Ctrl-n`,run:ev,shift:Tv},{key:`Ctrl-a`,run:uv,shift:Nv},{key:`Ctrl-e`,run:dv,shift:Pv},{key:`Ctrl-d`,run:Xv},{key:`Ctrl-h`,run:Yv},{key:`Ctrl-k`,run:ey},{key:`Ctrl-Alt-h`,run:Qv},{key:`Ctrl-o`,run:ry},{key:`Ctrl-t`,run:iy},{key:`Ctrl-v`,run:iv}],Cy=[{key:`ArrowLeft`,run:U_,shift:gv,preventDefault:!0},{key:`Mod-ArrowLeft`,mac:`Alt-ArrowLeft`,run:K_,shift:yv,preventDefault:!0},{mac:`Cmd-ArrowLeft`,run:cv,shift:jv,preventDefault:!0},{key:`ArrowRight`,run:W_,shift:_v,preventDefault:!0},{key:`Mod-ArrowRight`,mac:`Alt-ArrowRight`,run:q_,shift:bv,preventDefault:!0},{mac:`Cmd-ArrowRight`,run:lv,shift:Mv,preventDefault:!0},{key:`ArrowUp`,run:$_,shift:wv,preventDefault:!0},{mac:`Cmd-ArrowUp`,run:Fv,shift:Lv},{mac:`Ctrl-ArrowUp`,run:rv,shift:Dv},{key:`ArrowDown`,run:ev,shift:Tv,preventDefault:!0},{mac:`Cmd-ArrowDown`,run:Iv,shift:Rv},{mac:`Ctrl-ArrowDown`,run:iv,shift:Ov},{key:`PageUp`,run:rv,shift:Dv},{key:`PageDown`,run:iv,shift:Ov},{key:`Home`,run:sv,shift:Av,preventDefault:!0},{key:`Mod-Home`,run:Fv,shift:Lv},{key:`End`,run:ov,shift:kv,preventDefault:!0},{key:`Mod-End`,run:Iv,shift:Rv},{key:`Enter`,run:my,shift:my},{key:`Mod-a`,run:zv},{key:`Backspace`,run:Yv,shift:Yv,preventDefault:!0},{key:`Delete`,run:Xv,preventDefault:!0},{key:`Mod-Backspace`,mac:`Alt-Backspace`,run:Qv,preventDefault:!0},{key:`Mod-Delete`,mac:`Alt-Delete`,run:$v,preventDefault:!0},{mac:`Mod-Backspace`,run:ty,preventDefault:!0},{mac:`Mod-Delete`,run:ny,preventDefault:!0}].concat(Sy.map(e=>({mac:e.key,run:e.run,shift:e.shift}))),wy=[{key:`Alt-ArrowLeft`,mac:`Ctrl-ArrowLeft`,run:X_,shift:xv},{key:`Alt-ArrowRight`,mac:`Ctrl-ArrowRight`,run:Z_,shift:Sv},{key:`Alt-ArrowUp`,run:sy},{key:`Shift-Alt-ArrowUp`,run:uy},{key:`Alt-ArrowDown`,run:cy},{key:`Shift-Alt-ArrowDown`,run:dy},{key:`Mod-Alt-ArrowUp`,run:Uv},{key:`Mod-Alt-ArrowDown`,run:Wv},{key:`Escape`,run:Gv},{key:`Mod-Enter`,run:hy},{key:`Alt-l`,mac:`Ctrl-l`,run:Bv},{key:`Mod-i`,run:Vv,preventDefault:!0},{key:`Mod-[`,run:by},{key:`Mod-]`,run:yy},{key:`Mod-Alt-\\`,run:vy},{key:`Shift-Mod-k`,run:fy},{key:`Shift-Mod-\\`,run:pv},{key:`Mod-/`,run:i_},{key:`Alt-A`,mac:`Ctrl-A`,run:s_},{key:`Ctrl-m`,mac:`Shift-Alt-m`,run:xy}].concat(Cy),Ty=`var(--dsw-alias-brand-primary, #3e63dd)`,Ey=`color-mix(in srgb, var(--dsw-alias-brand-primary, #3e63dd) 55%, transparent)`,Dy=`var(--dsw-alias-label-dimmed, #999)`,Oy=`ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace`,ky=md.define([{tag:[q.heading1,q.heading2,q.heading3,q.heading4,q.heading5,q.heading6],color:Ty,fontWeight:`700`},{tag:q.processingInstruction,color:Ey},{tag:q.monospace,fontFamily:Oy,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 12%, transparent)`,borderRadius:`4px`,padding:`0 3px`},{tag:q.content,fontFamily:Oy,backgroundColor:`color-mix(in srgb, var(--dsw-alias-label-secondary, #888) 8%, transparent)`},{tag:q.strong,fontWeight:`700`},{tag:q.emphasis,fontStyle:`italic`},{tag:q.strikethrough,textDecoration:`line-through`,opacity:`.75`},{tag:q.link,color:Ty,textDecoration:`underline`},{tag:q.url,color:Ey,textDecoration:`underline dotted`},{tag:q.quote,fontStyle:`italic`,color:`var(--dsw-alias-label-secondary, #888)`},{tag:q.contentSeparator,color:Dy,textDecoration:`line-through`},{tag:q.comment,color:Dy}]);function Ay(e={}){let t=document.createElement(`div`);t.className=`dsh-tw-note-editor`;let n=new V({parent:t,state:N.create({doc:``,extensions:[V.lineWrapping,y_(),Qg({base:Rg}),vd(ky),el(),cl(e.placeholder??``),Rc.of([...wy,...L_,{key:`Mod-Enter`,run:()=>(e.onSave?.(),!0)}]),V.updateListener.of(t=>{t.docChanged&&e.onChange?.()})]})});return{el:t,view:n,getValue:()=>n.state.doc.toString(),setValue(e){n.dispatch({changes:{from:0,to:n.state.doc.length,insert:e}})},insertAtCaret(e){let{from:t}=n.state.selection.main,r=`${t===n.state.doc.lineAt(t).from?``:`
762
762
  `}${e}\n`;n.dispatch({changes:{from:t,insert:r},selection:{anchor:t+r.length},scrollIntoView:!0}),n.focus()},focus:()=>n.focus()}}const jy=`dsh-tw-note-state`,My=`dsh-tw-note-draft-v1`,Ny=`dsh-tw-note-window-id`,Py=(()=>{try{let e=sessionStorage.getItem(Ny);if(e!==null&&e.length>0)return e;let t=Math.random().toString(36).slice(2,10);return sessionStorage.setItem(Ny,t),t}catch{return Math.random().toString(36).slice(2,10)}})();function Fy(){return`dsh-tw-note-draft-v1:${Py}`}function Iy(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 Ly(e){try{return Iy(localStorage.getItem(e))}catch{return null}}function Ry(){let e=Ly(Fy());if(e!==null)return{draft:e,foreign:e.windowId!==void 0&&e.windowId!==Py};let t=Ly(My);if(t===null)return null;let n={...t,windowId:Py};By(n);try{localStorage.removeItem(My)}catch{}return{draft:n,foreign:!0}}function zy(e){By({...e,windowId:Py})}function By(e){try{localStorage.setItem(Fy(),JSON.stringify({...e,windowId:Py}))}catch{}}function Vy(){try{localStorage.removeItem(Fy())}catch{}}function Hy(e,t,n){return`${e}\u0000${t}\u0000${n.join(``)}`}function Uy(e){return e<10?`0${e}`:String(e)}function Wy(e=new Date){return`${e.getFullYear()}-${Uy(e.getMonth()+1)}-${Uy(e.getDate())} ${Uy(e.getHours())}:${Uy(e.getMinutes())}`}function Gy(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 Ky(){let e=await pe();return typeof e?.note?.tag==`string`&&e.note.tag.length>0?e.note.tag:`inbox`}function qy(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(ee,{signal:AbortSignal.timeout(5e3)}).then(e=>e.ok?e.json():Promise.resolve({})).then(e=>[...e.tags??[]].sort((e,t)=>e.localeCompare(t,`zh`))).catch(()=>[]),f.then(e=>{d=e}),f),m=()=>{let e=r.value.trim().toLowerCase(),t=d.filter(t=>!a.includes(t)&&(e.length===0||t.toLowerCase().includes(e))).slice(0,8);i.replaceChildren();for(let e of t){let t=document.createElement(`div`);t.className=`dsh-tw-note-tagsuggest-item`,t.textContent=e,t.setAttribute(`role`,`button`),t.tabIndex=0,t.setAttribute(`aria-label`,`添加标签「${e}」`),t.addEventListener(`mousedown`,t=>{t.preventDefault(),l(e)}),t.addEventListener(`keydown`,t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),l(e))}),i.append(t)}i.hidden=t.length===0};r.addEventListener(`focus`,()=>{p().then(m)}),r.addEventListener(`input`,()=>{d.length===0?p().then(m):m()}),r.addEventListener(`keydown`,e=>{e.key===`Enter`||e.key===`,`?(e.preventDefault(),u()):e.key===`Backspace`&&r.value.length===0&&a.length>0?(a.pop(),c(),s()):e.key===`Escape`&&o()});let h=e=>{t.contains(e.target)||o()};return document.addEventListener(`click`,h,!0),{el:t,getTags:()=>(u(),[...a]),peekTags:()=>[...a],setDefault:e=>{if(a.length===0){let t=e.trim();t.length>0&&(a.push(t),c())}},setTags:e=>{a.length=0;for(let t of Array.isArray(e)?e:[]){let e=typeof t==`string`?t.trim():``;e.length>0&&!a.includes(e)&&a.push(e)}r.value=``,c(),o()},dispose:()=>document.removeEventListener(`click`,h,!0)}}async function Jy(e,t){if(e.size>67108864){D(`文件过大(≤ 64MB)`);return}try{let n=await fetch(`${x}?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){D(`上传失败:${r?.error??`HTTP ${n.status}`}`);return}let i=r.name??e.name,a=e.type.startsWith(`image/`)?`![${i}](${r.url})`:`[${i}](${r.url})`;t.insertAtCaret(a),D(`已上传「${i}」并插入链接`)}catch(e){D(`上传失败:${e instanceof Error?e.message:String(e)}`)}}function Yy(){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(jy,{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=null,p=()=>{e!==void 0&&(f=Wy(),e.titleInput.value=f)},m=()=>{if(e===void 0)return;let t=e.editor.getValue(),n=e.titleInput.value.trim();if(t.trim().length===0&&(n.length===0||n===f)){Vy();return}let r=Hy(n,t,e.tagEditor.peekTags());l!==null&&r===l||By({text:t,title:n,tags:e.tagEditor.peekTags(),savedAt:Date.now()})},h=()=>{t||!n||e===void 0||(o!==void 0&&(clearTimeout(o),o=void 0),o=window.setTimeout(()=>{o=void 0,m()},500))},_=()=>{e!==void 0&&(e.draftBanner.hidden=!0)},ee=async(e,t,n)=>{try{let r=await fetch(y,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({title:e,tags:n,text:t}),signal:AbortSignal.timeout(1e4)}),i=await r.json().catch(()=>null);return!r.ok||i?.ok!==!0?(D(`打开失败:${i?.error??`HTTP ${r.status}`}`),!1):typeof i.twUrl!=`string`||typeof i.draftTitle!=`string`?(D(`打开失败:服务未返回编辑器地址`),!1):(Vy(),_(),l=Hy(e,t,n),c=null,wt(`${new URL(i.twUrl,location.origin).href}#${encodeURIComponent(i.draftTitle)}`,i.title??e),D(`已在弹出窗口打开「${i.title??e}」编辑器`),!0)}catch(e){return D(`打开失败:${e instanceof Error?e.message:String(e)}`),!1}},b=()=>{s=!1,e!==void 0&&(e.recentWrap.hidden=!0)},x=async t=>{try{let n=await fetch(`${g}?title=${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(1e4)}),r=await n.json().catch(()=>null);if(!n.ok||r?.ok!==!0||typeof r.title!=`string`){D(`读取失败:${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=Hy(r.title,r.text??``,r.tags??[]),_(),b(),D(`已载入「${r.title}」`),e.editor.focus()}catch(e){D(`读取失败:${e instanceof Error?e.message:String(e)}`)}},S=()=>{if(e===void 0)return;if(s){b();return}s=!0,e.recentWrap.hidden=!1,e.recentWrap.textContent=``;let t=document.createElement(`div`);t.className=`dsh-tw-note-recent-muted`,t.textContent=`加载中…`,e.recentWrap.append(t),(async()=>{try{let t=await(await fetch(`${te}?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=[Gy(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`,()=>{x(t.title)}),n.addEventListener(`keydown`,e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),x(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)}})()},C=()=>{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 s=document.createElement(`span`);s.className=`dsh-tw-note-label`,s.textContent=`📝 快速笔记`;let d=document.createElement(`button`);d.type=`button`,d.className=`dsh-tw-note-close`,d.title=`收起`,d.textContent=`✕`,a.append(s,d);let p=document.createElement(`div`);p.className=`dsh-tw-note-draft`,p.hidden=!0;let g=document.createElement(`span`);g.className=`dsh-tw-note-draft-text`,g.textContent=`已恢复未保存草稿`;let y=document.createElement(`button`);y.type=`button`,y.className=`dsh-tw-note-draft-discard`,y.textContent=`丢弃`,p.append(g,y);let te=document.createElement(`div`);te.className=`dsh-tw-note-fields`;let x=document.createElement(`input`);x.className=`dsh-tw-note-title`,x.placeholder=`标题(默认时间戳)`,x.setAttribute(`aria-label`,`笔记标题(默认时间戳)`);let C=qy({onChange:h});te.append(x,C.el),x.addEventListener(`input`,h);let w,T=Ay({placeholder:`写点东西… Markdown 高亮,可 📎/拖入文件
763
763
  Ctrl+Enter 保存`,onSave:()=>{w?.()},onChange:h}),ne=document.createElement(`button`);ne.type=`button`,ne.className=`dsh-tw-note-upload`,ne.title=`上传文件到 wiki 并插入 Markdown 链接(也可直接拖入编辑器)`,ne.textContent=`📎 上传`;let E=document.createElement(`input`);E.type=`file`,E.multiple=!0,E.hidden=!0,ne.addEventListener(`click`,()=>{E.click()}),E.addEventListener(`change`,()=>{for(let e of Array.from(E.files??[]))Jy(e,T);E.value=``});let re=0;T.el.addEventListener(`dragenter`,e=>{e.preventDefault(),re++,T.el.classList.add(`dsh-tw-note-drop`)}),T.el.addEventListener(`dragover`,e=>{e.preventDefault()}),T.el.addEventListener(`dragleave`,e=>{e.preventDefault(),re=Math.max(0,re-1),re===0&&T.el.classList.remove(`dsh-tw-note-drop`)}),T.el.addEventListener(`drop`,e=>{e.preventDefault(),re=0,T.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))Jy(e,T)});let ie=document.createElement(`div`);ie.className=`dsh-tw-note-foot`;let ae=document.createElement(`div`);ae.className=`dsh-tw-note-foot-left`;let oe=document.createElement(`span`);oe.className=`dsh-tw-note-hint`,oe.textContent=`Ctrl+Enter`;let se=document.createElement(`button`);se.type=`button`,se.className=`dsh-tw-note-recent-btn`,se.title=`最近修改的笔记,点击载入继续编辑`,se.textContent=`🕘 最近`,se.addEventListener(`click`,S),ae.append(ne,se,oe);let ce=document.createElement(`div`);ce.className=`dsh-tw-note-foot-right`;let le=document.createElement(`button`);le.type=`button`,le.className=`dsh-tw-note-edit`,le.title=`保存并在 TiddlyWiki 原生编辑器中打开`,le.textContent=`✏️ 在 TW 中编辑`;let ue=document.createElement(`button`);ue.type=`button`,ue.className=`dsh-tw-note-save`,ue.textContent=`保存`,ce.append(le,ue),ie.append(ae,ce);let de=document.createElement(`div`);de.className=`dsh-tw-note-recent`,de.hidden=!0,r.append(a,p,te,T.el,ie),t.append(r,de),document.body.append(t),e={root:t,card:r,editor:T,titleInput:x,tagEditor:C,saveBtn:ue,editBtn:le,draftBanner:p,bannerText:g,recentWrap:de};let fe=()=>{n=!1,t.hidden=!0,b(),u(!1)},pe=()=>{o!==void 0&&(clearTimeout(o),o=void 0),T.setValue(``),x.value=Wy(),f=x.value,C.setTags([]),l=Hy(x.value.trim(),``,[])},me=()=>{Vy(),_(),l=Hy(x.value.trim(),T.getValue(),C.getTags()),c=null,pe(),fe()},he=!1;w=async()=>{if(he)return;let e=T.getValue().trim();if(e.length===0){D(`内容为空,未保存`);return}he=!0,ue.disabled=!0,ue.textContent=`保存中…`;try{let t=x.value.trim(),n={title:t,tags:C.getTags(),text:e};c!==null&&c.title===t&&(c.modified!==void 0&&(n.expectedModified=c.modified),c.revision!==void 0&&(n.expectedRevision=c.revision));let r=await fetch(v,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n),signal:AbortSignal.timeout(1e4)}),i=await r.json().catch(()=>null);if(!r.ok||i?.ok!==!0){if(r.status===409||i?.conflict===!0){D(`保存被拒绝:这篇笔记在你读取之后被改动过。请用「🕘 最近」重新载入后再保存。`);return}D(`保存失败:${i?.error??`HTTP ${r.status}`}`);return}me(),D(`已保存「${i.title??x.value}」`)}catch(e){D(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{he=!1,ue.disabled=!1,ue.textContent=`保存`}},ue.addEventListener(`click`,()=>{w?.()});let ge=async()=>{let e=x.value.trim().length>0?x.value.trim():Wy(),t=T.getValue(),n=C.getTags();le.disabled=!0,le.textContent=`打开中…`;try{await ee(e,t,n)}finally{le.disabled=!1,le.textContent=`✏️ 在 TW 中编辑`}};le.addEventListener(`click`,()=>{ge()}),d.addEventListener(`click`,fe);let _e=null,ve=(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(d.contains(e.target))return;e.preventDefault();let n=t.getBoundingClientRect();_e={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(_e===null)return;let t=e.clientX-_e.startX,n=e.clientY-_e.startY;!_e.moved&&Math.abs(t)<4&&Math.abs(n)<4||(_e.moved=!0,ve(_e.origLeft+t,_e.origTop+n))});let ye=e=>{if(_e!==null){try{a.releasePointerCapture(e.pointerId)}catch{}_e=null,a.classList.remove(`dsh-tw-note-head-dragging`)}};a.addEventListener(`pointerup`,ye),a.addEventListener(`pointercancel`,ye),y.addEventListener(`click`,()=>{Vy(),_(),pe(),D(`已丢弃草稿`)}),i=()=>{m()},window.addEventListener(`pagehide`,i)};return{async open(r){if(t||(C(),e===void 0||n))return;n=!0,e.root.hidden=!1,d(r),u(!0);let i=Ry(),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&&(D(`已恢复其它窗口的未保存草稿`),zy(o));else{if(p(),a=await Ky(),t||e===void 0)return;e.tagEditor.setDefault(a)}e!==void 0&&e.editor.focus()},close(){e!==void 0&&(n=!1,e.root.hidden=!0,b(),u(!1))},async openNative(){if(!(t||r)&&!(Tt()&&!Et())){r=!0;try{let e=Ry(),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():Wy(),i=n?e.draft.text:``,o=[];if(n)o=e.draft.tags;else{if(a=await Ky(),t)return;o=[a]}e!==null&&e.foreign&&(e.draft.text.trim().length>0||e.draft.title.trim().length>0)&&(D(`已恢复其它窗口的未保存草稿`),zy(e.draft)),await ee(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),m(),e?.tagEditor.dispose(),e?.editor.view.destroy(),e?.root.remove(),e=void 0}}}function Xy(e){return e<10?`0${e}`:String(e)}function Zy(e){return`${Xy(e.getHours())}:${Xy(e.getMinutes())}`}function Qy(e,t){let n=e?.git,r=[`同步知识库`],i=`offline`;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`,r.push(`有 ${n.dirtyFiles?.length??0} 个未提交改动`)):i=e>0?`behind`:`clean`}return t!==void 0&&r.push(`上次同步 ${Zy(t)}`),{state:i,tooltip:r.join(` · `)}}function $y(){let e={state:`offline`,tooltip:`同步知识库`},t,n,r=!1,i=!1,a=new Set,o=()=>{for(let e of[...a])e()},s=n=>{if(r)return;let i=Qy(n,t);(i.state!==e.state||i.tooltip!==e.tooltip)&&(e=i,o())},c=async()=>{if(i)return;let e=await pe();i||s(e)};return c(),n=window.setInterval(()=>{c()},3e4),{getState:()=>e,trigger:async()=>{if(i)return e;if(r)return D(`同步进行中…`),e;r=!0,e={...e,state:`syncing`},o();try{let e=await fetch(S,{method:`POST`,signal:AbortSignal.timeout(12e4)}),n=de(await e.json().catch(()=>null),e.status);n.ok?(t=new Date,D(`同步完成:${n.message}`)):D(`同步失败:${n.message}`)}catch(e){D(`同步失败:${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()}}}async function eb(){let e=await be();return{showQuickNote:e.showQuickNote,showPanelStatus:e.showPanelStatus,showSyncButton:e.showSyncButton}}async function tb(){let e=await pe();if(e===null)return{state:`failed`,text:`状态不可达`,logs:[]};let t=Array.isArray(e.logs)?e.logs.filter(e=>typeof e==`string`):[];return e.status===`running`?{state:`running`,text:`TW 在线 · ${e.url??``}`,logs:t}:e.status===`starting`?{state:`starting`,text:`TW 启动中…`,logs:t}:{state:`failed`,text:e.error??`TW 状态:${e.status??`?`}`,logs:t}}function nb(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(`
764
- `)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await tb(),!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(),be().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(qe)),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)},ee=e.subscribe(()=>{d!==void 0&&(d.textContent=e.isOpen()?`收起 TW 面板`:`打开 TW 面板`)}),te=n.subscribe(_);return(async()=>{let e=await eb();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),ee(),te(),i?.remove()}}function rb(e){return function(){let[t,n]=c.useState(!1),[r,i]=c.useState(null),a=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{let e=!0,t=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(jy,t),be().then(t=>{e&&i(t.quickNoteMode)}),()=>{e=!1,window.removeEventListener(jy,t)}},[]),c.useLayoutEffect(()=>{let e=a.current;if(e===null)return;let t=()=>{let t=null,n=null,r=e;for(;r!==null&&r!==document.documentElement&&(r=r.parentElement,r!==null);){for(let e of r.querySelectorAll(`textarea, [contenteditable]:not([contenteditable="false"]), [role="textbox"]`))if(e.getBoundingClientRect().width>300){t=e,n=r;break}if(n!==null)break}if(t===null||n===null)return null;let i=n.getBoundingClientRect().width,a=t,o=null,s=0;for(;a!==null&&a!==n;){let e=a.getBoundingClientRect().width;e>0&&e<i-8&&e>=s&&(s=e,o=a),a=a.parentElement}return o},n=()=>{let n=e.getBoundingClientRect(),r=t(),i=r===null?n.right:r.getBoundingClientRect().right,a=Math.max(0,n.right-i);return e.style.paddingRight!==`${a}px`&&(e.style.paddingRight=`${a}px`),r!==null};n();let r=new ResizeObserver(n),i=e;for(;i!==null&&i!==document.documentElement&&(r.observe(i),!(i instanceof HTMLElement&&i.hasAttribute(`data-phase`)));)i=i.parentElement;window.addEventListener(`resize`,n),document.addEventListener(`visibilitychange`,n);let o=0,s=0,c=window.setInterval(()=>{if(s++,!n()){s>=20&&window.clearInterval(c);return}o++,o>=3&&window.clearInterval(c)},1500),l=window.setTimeout(n,120),u=window.setTimeout(n,600);return()=>{r.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`visibilitychange`,n),window.clearInterval(c),window.clearTimeout(l),window.clearTimeout(u)}},[]);let s=r===`native`,l=s?`快速笔记`:t?`快速笔记(已打开)`:`快速笔记`,u=s?`快速笔记:直接打开 TiddlyWiki 原生编辑器(再次点击可收起弹窗)`:t?`快速笔记已打开(点此按钮或卡片右上角 ✕ 收起)`:`打开快速笔记(在按钮上方弹出,可拖动标题栏移动)`;return c.createElement(`div`,{ref:a,className:`dsh-tw-dock-note`},c.createElement(`button`,{ref:o,type:`button`,className:t?`dsh-tw-dock-note-btn dsh-tw-dock-note-btn-active`:`dsh-tw-dock-note-btn`,title:u,onClick:()=>{be().then(t=>{t.quickNoteMode===`native`?Tt()&&!Et()?Ot():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)))}}async function ib(e,t=15e3){try{let n=await fetch(_,{method:`POST`,headers:{"content-type":`application/json`,"x-requested-with":`TiddlyWiki`},body:JSON.stringify({title:e}),signal:AbortSignal.timeout(t)});if(!n.ok)return null;let r=await n.text();return r.trim().length>0?r:null}catch{return null}}function ab(){return Xe()}async function ob(e){try{let t=await fetch(`${g}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function sb(e){let{sessionId:t,viewRequest:n,completeViewRequest:r}=e,[i,a]=c.useState(`loading`),[o,s]=c.useState(null),[l,u]=c.useState(null),[d,f]=c.useState(``),p=c.useRef(0),m=c.useRef(!0),h=c.useRef(0),g=c.useCallback(async()=>{let e=++p.current;if(m.current){if(a(`loading`),typeof t!=`string`||t.length===0){a(`error`),f(`缺少会话 ID`);return}if(h.current>=3){a(`error`),f(`连续 3 次生成失败,已停止自动重试,请点「🔄 刷新」`);return}try{let n=await fetch(w,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(!m.current||e!==p.current)return;if(!n.ok||r?.ok!==!0){h.current++,a(`error`),f(r?.error??`HTTP ${n.status}`);return}if(typeof r.title!=`string`||r.title.length===0){h.current++,a(`error`),f(`汇总生成失败:缺少标题`);return}u(r.title);let i=await ib(r.title);if(!m.current||e!==p.current)return;if(i===null){let t=await ob(r.title);if(!m.current||e!==p.current)return;if(!t){if(h.current++,h.current<3){g();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(host /render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(!m.current||e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}}},[t]);c.useEffect(()=>(m.current=!0,g(),()=>{m.current=!1}),[g]),c.useEffect(()=>{if(i!==`ready`||l===null)return;let e=!0,t=window.setInterval(()=>{(async()=>{if(!e)return;let t=await ob(l);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 cb(e,t){if(!(e===void 0||t.showSessionTab===!1))return Ye(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:ab},sb))}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 lb(e,t){let n=await fetch(e,{...t,signal: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 ub(e){let t=!1;e.classList.add(`dsh-tw-settings`);let n=$(`div`,`dsh-tw-settings-row dsh-tw-settings-status`),r=$(`div`,`dsh-tw-settings-body`);e.append(n,r);let i=[],a={},o=async()=>{try{let e=await lb(T);if(t)return;db(n,e,o),gb(r,e,o,()=>t,a)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),a=$(`button`,`dsh-tw-settings-btn`,`重试`);a.type=`button`,a.addEventListener(`click`,()=>{o()}),r.append(i,a)}};return o(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function db(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(S,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=de(await e.json().catch(()=>null),e.status);D(t.ok?`同步完成:${t.message}`:`同步失败:${t.message}`)}catch(e){D(`同步失败:${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 lb(ie,{method:`POST`}),D(`TW 已重启`)}catch(e){D(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function fb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`常规配置`));let i=t.note??{},a=t.git??{},o=t.ui??{},s=[],c=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.value=n;let a=$(`label`,`dsh-tw-settings-field`);a.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:()=>i.value.trim(),changed:()=>i.value.trim()!==n}),r.append(a)},l=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-check`);i.type=`checkbox`,i.checked=n;let a=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-check`);return a.append(i,$(`span`,`dsh-tw-settings-label`,t)),s.push({key:e,initial:n,read:()=>i.checked,changed:()=>i.checked!==n}),r.append(a),i},u=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.type=`number`,i.value=String(n);let a=()=>{let e=i.value.trim();if(e.length===0)return n;let t=Number(e);return Number.isFinite(t)?t:n},o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:a,changed:()=>a()!==n}),r.append(o)},d=(e,t,n,i)=>{let a=$(`select`,`dsh-tw-settings-input`);for(let e of i){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,e.value===n&&(t.selected=!0),a.append(t)}let o=$(`label`,`dsh-tw-settings-field`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o),a},f=(e,t,n,i)=>{let a=$(`textarea`,`dsh-tw-settings-input dsh-tw-settings-area`);a.rows=i,a.value=n;let o=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-area`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value.trim(),changed:()=>a.value.trim()!==n}),r.append(o),a};c(`note.tag`,`快速笔记默认 tag`,typeof i.tag==`string`?i.tag:`inbox`),l(`git.autoCommit`,`自动 commit(防抖)`,a.autoCommit!==!1),u(`git.debounceMs`,`自动 commit 防抖(ms)`,typeof a.debounceMs==`number`?a.debounceMs:6e4),c(`git.remote`,`git 远端(空=仅本地)`,typeof a.remote==`string`?a.remote:``),c(`git.branch`,`git 分支`,typeof a.branch==`string`?a.branch:`main`);let p=t.startup??{};u(`startup.readyTimeoutMs`,`TW 启动就绪等待(ms;默认 60000,范围 5000–600000,超时上限为其 3 倍,对下次启动/重启生效)`,typeof p.readyTimeoutMs==`number`&&p.readyTimeoutMs>0?p.readyTimeoutMs:6e4),l(`ui.showQuickNote`,`显示「知识库」按钮里的「快速笔记」入口`,o.showQuickNote!==!1),l(`ui.showQuickNoteDock`,`显示聊天输入框上方的「快速笔记」快捷按钮`,o.showQuickNoteDock!==!1),d(`ui.quickNoteMode`,`点击「快速笔记」的打开方式`,typeof o.quickNoteMode==`string`&&o.quickNoteMode===`card`?`card`:`native`,[{value:`native`,label:`原生编辑器:直接弹出 TW 原生编辑页(新建/恢复草稿)`},{value:`card`,label:`Markdown 卡片:弹出现有快速笔记卡片(CodeMirror 编辑器)`}]),c(`ui.sidebarLabel`,`侧边栏 TW 入口显示名称`,typeof o.sidebarLabel==`string`&&o.sidebarLabel.trim().length>0?o.sidebarLabel.trim():`TiddlyWiki`),l(`ui.showPanelStatus`,`显示「知识库」按钮里的 TW 面板/重载入口与状态行`,o.showPanelStatus!==!1),l(`ui.showSyncButton`,`显示「知识库」按钮里的「同步」入口与 git 状态点`,o.showSyncButton!==!1),l(`ui.followDshTheme`,`嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)`,o.followDshTheme!==!1),c(`ui.darkPalette`,`暗色时 TW palette(tiddler 标题)`,typeof o.darkPalette==`string`&&o.darkPalette.trim().length>0?o.darkPalette.trim():`$:/palettes/CupertinoDark`),c(`ui.tabLabel`,`会话顶部「知识库」Tab 名称`,typeof o.tabLabel==`string`&&o.tabLabel.trim().length>0?o.tabLabel.trim():`知识库`),l(`ui.showSessionTab`,`显示会话顶部「知识库」Tab(本会话相关 wiki 笔记汇总)`,o.showSessionTab!==!1),l(`ui.showRightbarTab`,`在 DSH 右侧边栏提供 TiddlyWiki 入口/Tab(与聊天并排)`,o.showRightbarTab!==!1);let m=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,m.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof m.endpoint==`string`?m.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头;已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof m.token==`string`?m.token:``);let h=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof h.pageSize==`number`?h.pageSize:10),r.append($(`h3`,`dsh-tw-settings-h`,`可选功能:微信公众号发布`)),r.append($(`div`,`dsh-tw-settings-muted`,`把 wiki 笔记一键发到公众号草稿箱(可选点发表)。**需要额外安装**:opencli 与 Browser Bridge 浏览器扩展,并让浏览器登录 mp.weixin.qq.com;adapter 在本仓库 tools/wechat/,安装与排错见 docs/wechat-publish-setup.md。不安装/不开启它,插件其他功能完全不受影响。开启后:注入提示词会多一条「发布前先读发布元数据规范」的约定,并在启动时把「发布元数据规范」与「微信公众号发布指南」(安装/换机还原步骤,等于仓库 docs/wechat-publish-setup.md)两篇文档写进 wiki(同名不覆盖)。`));let g=l(`wechat.enabled`,`启用微信公众号发布(默认关;需先按 docs/wechat-publish-setup.md 安装 opencli + 浏览器扩展)`,(t.wechat??{}).enabled===!0),_=t.prompt??{};r.append($(`h3`,`dsh-tw-settings-h`,`系统提示词(注入每个会话)`)),r.append($(`div`,`dsh-tw-settings-muted`,`插件把自己的约定(同步纪律 / 标签约定 / 链接格式等)注入每个会话的系统提示词。保存后**无需重启 dsh web**:section 会即时重新注册,当前会话从下一步起就使用新文本。`));let v=l(`prompt.enabled`,`注入 TiddlyWiki 提示词(关闭后本插件不再注入任何文本)`,_.enabled!==!1),y=d(`prompt.mode`,`内置文本形态`,_.mode===`full`?`full`:`slim`,[{value:`slim`,label:`精简(默认):只保留工具 schema 表达不了的约定`},{value:`full`,label:`完整:额外附一份由工具注册表实时生成的参数索引`}]),ee=f(`prompt.extra`,`附加说明(永远追加在末尾,可放团队/个人规范)`,typeof _.extra==`string`?_.extra:``,5),te=f(`prompt.override`,`整段替换(非空时取代上面的内置文本,附加说明仍会追加)`,typeof _.override==`string`?_.override:``,8),b=()=>s.some(e=>(e.key.startsWith(`prompt.`)||e.key===`wechat.enabled`)&&e.changed()),x=$(`button`,`dsh-tw-settings-btn`,`预览注入文本(按表单当前值)`);x.type=`button`,x.title=`按表单当前值渲染注入文本(不用先保存);点「保存配置」后这就是实际注入的内容`;let S=$(`pre`,`dsh-tw-settings-prompt-preview`);S.hidden=!0,x.addEventListener(`click`,()=>{if(!S.hidden){S.hidden=!0,S.textContent=``;return}x.disabled=!0,(async()=>{try{let e=await lb(ne,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({enabled:v.checked,mode:y.value,extra:ee.value,override:te.value,wechat:g.checked})});if(e.ok!==!0)throw Error(e.error??`获取失败`);S.textContent=e.enabled===!1?`(已关闭:不会注入任何提示词)`:`# 形态 ${e.mode??``} · ${e.length??0} 字符${b()?`(含未保存的修改,保存后才真正注入)`:``}\n\n${e.text??``}`,S.hidden=!1}catch(e){D(`读取提示词失败:${e instanceof Error?e.message:String(e)}`)}finally{x.disabled=!1}})()}),r.append(x,S);let C=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,C.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof C.port==`number`&&C.port>0?C.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置。已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof C.token==`string`?C.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof C.tag==`string`&&C.tag.trim().length>0?C.tag.trim():`clip`);let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);w.type=`button`,w.addEventListener(`click`,()=>{w.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 lb(re,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),ye(),D(`配置已保存`),n()}catch(e){D(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{w.disabled=!1}})()}),r.append(w),e.append(r)}function pb(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 lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),D(`插件已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),p.disabled=!1}})()}),m(``),u.append(d,f,p),e.append(u);let h=$(`section`,`dsh-tw-settings-section`);h.append($(`h3`,`dsh-tw-settings-h`,`主题管理(自带主题)`));let g=$(`div`,`dsh-tw-settings-muted`,`「加载」= TW 里可用的主题(可多选,依赖链自动带上,如 heavier 会带 snowwhite+vanilla);「活动」= 当前视觉主题(单选,自动加入加载集)。应用后重启 TW。`),_=$(`div`,`dsh-tw-settings-row dsh-tw-settings-head`);_.append($(`span`,`dsh-tw-settings-col`,`加载`),$(`span`,`dsh-tw-settings-col`,`活动`),$(`span`,`dsh-tw-settings-name`,`主题`));let v=t?.themes??[],y=t?.themeActive,ee=typeof y==`string`&&a.some(e=>e.name===y)?y:v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,te=$(`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===ee,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(ee=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),te.append(a)}let b=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);b.type=`button`,b.addEventListener(`click`,()=>{b.disabled=!0,(async()=>{try{await lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:ee})}),D(`主题已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),b.disabled=!1}})()}),h.append(g,_,te,b),e.append(h);let x=$(`section`,`dsh-tw-settings-section`);x.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let S=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),C=$(`div`,`dsh-tw-settings-list`);for(let e of o){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=l.has(e.name),t.addEventListener(`change`,()=>{t.checked?l.add(e.name):l.delete(e.name)});let n=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);n.append(t,r,i),C.append(n)}let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);w.type=`button`,w.addEventListener(`click`,()=>{w.disabled=!0,(async()=>{try{await lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),D(`语言已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),w.disabled=!1}})()}),x.append(S,C,w),e.append(x)}function mb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`知识库位置(可切换)`));let i=$(`div`,`dsh-tw-settings-muted`,`读取中…`),a=$(`div`,`dsh-tw-settings-muted`),o=$(`div`,`dsh-tw-settings-muted`),s=$(`div`,`dsh-tw-settings-muted`),c=$(`input`,`dsh-tw-settings-input`),l=$(`input`,`dsh-tw-settings-input`);c.placeholder=`绝对路径,如 D:\\notes 或 $DSH_HOME/tiddlywiki`,l.placeholder=`文件夹名(默认 main;填 . 表示直接用上面这个目录)`;let u=$(`label`,`dsh-tw-settings-field`);u.append($(`span`,`dsh-tw-settings-label`,`根目录(wikiRoot)`),c);let d=$(`label`,`dsh-tw-settings-field`);d.append($(`span`,`dsh-tw-settings-label`,`文件夹名(wiki)`),l);let f=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`切换到这个位置`);f.type=`button`;let p=$(`button`,`dsh-tw-settings-btn`,`恢复为配置默认`);p.type=`button`;let m=$(`div`,`dsh-tw-settings-row`);m.append(f,p);let h=$(`div`,`dsh-tw-settings-row dsh-tw-settings-candidates`),g=$(`div`,`dsh-tw-settings-muted`,"切换会停掉并就地重启 TW 子进程(几秒);新目录若还没有 tiddlywiki.info,插件会自动 `--init server` 初始化一个全新知识库。选中的位置会记在 $DSH_HOME 下的指针文件里(不进 wiki),可用「恢复为配置默认」清除。"),_=(e,t)=>{f.disabled=e,p.disabled=e,f.textContent=e?t:`切换到这个位置`},v=async()=>{if(!t())try{let e=await lb(ce);if(t())return;if(e.ok!==!0)throw Error(e.error??`获取失败`);let n=e.current??{};i.textContent=`当前:${n.path??`(未知)`}`;let r=n.source===`state`?`来源:指针文件(在设置页切换过)`:n.source===`config`?`来源:cordis 配置(config.wikiRoot / config.wiki)`:`来源:默认值($DSH_HOME/tiddlywiki + main)`;a.textContent=`${r} · 配置默认:${e.default?.path??`(未知)`}`,o.textContent=e.stateFile===void 0?``:`指针文件:${e.stateFile}(不存在=使用配置默认)`,s.textContent=e.error===void 0?``:`⚠️ ${e.error}`,c.value.length===0&&typeof n.root==`string`&&(c.value=n.root),l.value.length===0&&typeof n.name==`string`&&(l.value=n.name),h.replaceChildren();let u=e.candidates??[];if(u.length>0){h.append($(`span`,`dsh-tw-settings-label`,`同目录下可选的 wiki:`));for(let e of u){let t=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-chipbtn`,e===`.`?`(根目录本身)`:e);t.type=`button`,t.title=`填入文件夹名「${e}」`,t.addEventListener(`click`,()=>{l.value=e}),h.append(t)}}}catch(e){if(t())return;i.textContent=`读取位置失败:${e instanceof Error?e.message:String(e)}`}};f.addEventListener(`click`,()=>{let e=c.value.trim(),t=l.value.trim().length>0?l.value.trim():`main`;if(e.length===0){D(`请先填写根目录(绝对路径)`);return}window.confirm(`切换知识库到:\n${e}\\${t}\n\n会停止并重启 TW 子进程;当前对话/工具随后读写的是新知识库。确定继续?`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let r=await lb(le,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({root:e,name:t}),signal:AbortSignal.timeout(12e4)});r.warning===void 0?D(`已切换到 ${r.path??``}`):D(`已切换到 ${r.path??``}(注意:${r.warning})`),ye(),await v(),await n()}catch(e){D(`切换失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),p.addEventListener(`click`,()=>{window.confirm(`恢复为配置默认位置?会删除位置指针文件,并(必要时)切回配置里的知识库。`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let e=await lb(ue,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`,signal:AbortSignal.timeout(12e4)});D(e.warning===void 0?`已恢复为配置默认:${e.path??``}`:`已恢复默认(注意:${e.warning})`),ye(),await v(),await n()}catch(e){D(`恢复失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),r.append(i,a,o,u,d,m,h,s,g),e.append(r),v()}function hb(e,t){let n=$(`section`,`dsh-tw-settings-section`);n.append($(`h3`,`dsh-tw-settings-h`,`初始化(一次性预置)`));let r=$(`div`,`dsh-tw-settings-muted`,`这些是插件与 dsh 联动、需要在 wiki 里预置的 tiddler/配置。「发送给 Agent 按钮」和「TW 前端 API 基址」是功能必需项,启动时自动写入(只写缺失,不覆盖你的改动);其余为可选项,默认不自动写入、也不会强绑定——需要时点「重新初始化」写入,不想要了可随时「反初始化」移除。`),i=$(`div`,`dsh-tw-settings-list`),a=$(`div`,`dsh-tw-settings-muted`),o=async()=>{if(!t())try{let e=await lb(ae);if(t())return;if(e.ok!==!0||!Array.isArray(e.items))throw Error(e.error??`获取失败`);i.replaceChildren();let n=0,r=0;for(let t of e.items){t.present&&(n+=1),t.removable&&(r+=1);let e=$(`span`,`dsh-tw-settings-chip`,t.present?`✓`:`✗`);e.dataset.state=t.present?`ok`:`missing`,e.title=t.present?`已存在`:`缺失`;let a=$(`span`,`dsh-tw-settings-name`,t.title);a.title=t.id;let s=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),c=t.updateAvailable===!0?$(`span`,`dsh-tw-settings-chip`,`⬆ 有更新`):void 0;c!==void 0&&(c.dataset.state=`update`,c.title=`内置内容在本 wiki 预置之后更新过,可点「重新初始化」取用`);let l=t.userModified===!0?$(`span`,`dsh-tw-settings-chip`,`✏️ 本地已修改`):void 0;l!==void 0&&(l.dataset.state=`missing`,l.title=`这篇是你的内容:重新初始化会覆盖它`);let u=$(`button`,`dsh-tw-settings-btn`,t.updateAvailable===!0?`更新到内置版本`:`重新初始化`);u.type=`button`,u.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,u.addEventListener(`click`,()=>{if(t.updateAvailable===!0){let e=t.userModified===!0?`「${t.title}」有你的本地修改,更新会覆盖它。`:t.userModified===void 0?`无法确认「${t.title}」是否被你编辑过(旧格式标记),更新可能覆盖你的改动。`:``;if(!window.confirm(`${e}${e.length>0?`
764
+ `)},_=()=>{let e=n.getState();o!==void 0&&(o.dataset.state=e.state),a!==void 0&&(a.title=`知识库 · ${e.tooltip}`),g()},v=async()=>{p=await tb(),!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(),be().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(qe)),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)},ee=e.subscribe(()=>{d!==void 0&&(d.textContent=e.isOpen()?`收起 TW 面板`:`打开 TW 面板`)}),te=n.subscribe(_);return(async()=>{let e=await eb();r||!e.showQuickNote&&!e.showPanelStatus&&!e.showSyncButton||y(e)})(),()=>{r=!0,document.removeEventListener(`click`,h,!0),ee(),te(),i?.remove()}}function rb(e){return function(){let[t,n]=c.useState(!1),[r,i]=c.useState(null),a=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{let e=!0,t=e=>{let t=e.detail;n(t?.open===!0)};return window.addEventListener(jy,t),be().then(t=>{e&&i(t.quickNoteMode)}),()=>{e=!1,window.removeEventListener(jy,t)}},[]),c.useLayoutEffect(()=>{let e=a.current;if(e===null)return;let t=()=>{let t=null,n=null,r=e;for(;r!==null&&r!==document.documentElement&&(r=r.parentElement,r!==null);){for(let e of r.querySelectorAll(`textarea, [contenteditable]:not([contenteditable="false"]), [role="textbox"]`))if(e.getBoundingClientRect().width>300){t=e,n=r;break}if(n!==null)break}if(t===null||n===null)return null;let i=n.getBoundingClientRect().width,a=t,o=null,s=0;for(;a!==null&&a!==n;){let e=a.getBoundingClientRect().width;e>0&&e<i-8&&e>=s&&(s=e,o=a),a=a.parentElement}return o},n=()=>{let n=e.getBoundingClientRect(),r=t(),i=r===null?n.right:r.getBoundingClientRect().right,a=Math.max(0,n.right-i);return e.style.paddingRight!==`${a}px`&&(e.style.paddingRight=`${a}px`),r!==null};n();let r=new ResizeObserver(n),i=e;for(;i!==null&&i!==document.documentElement&&(r.observe(i),!(i instanceof HTMLElement&&i.hasAttribute(`data-phase`)));)i=i.parentElement;window.addEventListener(`resize`,n),document.addEventListener(`visibilitychange`,n);let o=0,s=0,c=window.setInterval(()=>{if(s++,!n()){s>=20&&window.clearInterval(c);return}o++,o>=3&&window.clearInterval(c)},1500),l=window.setTimeout(n,120),u=window.setTimeout(n,600);return()=>{r.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`visibilitychange`,n),window.clearInterval(c),window.clearTimeout(l),window.clearTimeout(u)}},[]);let s=r===`native`,l=s?`快速笔记`:t?`快速笔记(已打开)`:`快速笔记`,u=s?`快速笔记:直接打开 TiddlyWiki 原生编辑器(再次点击可收起弹窗)`:t?`快速笔记已打开(点此按钮或卡片右上角 ✕ 收起)`:`打开快速笔记(在按钮上方弹出,可拖动标题栏移动)`;return c.createElement(`div`,{ref:a,className:`dsh-tw-dock-note`},c.createElement(`button`,{ref:o,type:`button`,className:t?`dsh-tw-dock-note-btn dsh-tw-dock-note-btn-active`:`dsh-tw-dock-note-btn`,title:u,onClick:()=>{be().then(t=>{t.quickNoteMode===`native`?Tt()&&!Et()?Ot():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)))}}async function ib(e,t=15e3){try{let n=await fetch(_,{method:`POST`,headers:{"content-type":`application/json`,"x-requested-with":`TiddlyWiki`},body:JSON.stringify({title:e}),signal:AbortSignal.timeout(t)});if(!n.ok)return null;let r=await n.text();return r.trim().length>0?r:null}catch{return null}}function ab(){return Xe()}async function ob(e){try{let t=await fetch(`${g}?title=${encodeURIComponent(e)}`,{signal:AbortSignal.timeout(8e3)});return t.status!==404&&(await t.json().catch(()=>null))?.notFound!==!0}catch{return!0}}function sb(e){let{sessionId:t,viewRequest:n,completeViewRequest:r}=e,[i,a]=c.useState(`loading`),[o,s]=c.useState(null),[l,u]=c.useState(null),[d,f]=c.useState(``),p=c.useRef(0),m=c.useRef(!0),h=c.useRef(0),g=c.useCallback(async()=>{let e=++p.current;if(m.current){if(a(`loading`),typeof t!=`string`||t.length===0){a(`error`),f(`缺少会话 ID`);return}if(h.current>=3){a(`error`),f(`连续 3 次生成失败,已停止自动重试,请点「🔄 刷新」`);return}try{let n=await fetch(w,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({session:t}),signal:AbortSignal.timeout(25e3)}),r=await n.json().catch(()=>null);if(!m.current||e!==p.current)return;if(!n.ok||r?.ok!==!0){h.current++,a(`error`),f(r?.error??`HTTP ${n.status}`);return}if(typeof r.title!=`string`||r.title.length===0){h.current++,a(`error`),f(`汇总生成失败:缺少标题`);return}u(r.title);let i=await ib(r.title);if(!m.current||e!==p.current)return;if(i===null){let t=await ob(r.title);if(!m.current||e!==p.current)return;if(!t){if(h.current++,h.current<3){g();return}a(`error`),f(`汇总条目不存在,自动重建失败,请重试`);return}h.current++,a(`error`),f(`渲染失败:wiki 渲染服务不可用(host /render)`);return}h.current=0,s(i),a(`ready`)}catch(t){if(!m.current||e!==p.current)return;h.current++,a(`error`),f(t instanceof Error?t.message:String(t))}}},[t]);c.useEffect(()=>(m.current=!0,g(),()=>{m.current=!1}),[g]),c.useEffect(()=>{if(i!==`ready`||l===null)return;let e=!0,t=window.setInterval(()=>{(async()=>{if(!e)return;let t=await ob(l);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 cb(e,t){if(!(e===void 0||t.showSessionTab===!1))return Ye(t.tabLabel),e.inject(`conversation.view`,()=>e.register({name:`conversation.view`,id:`dsh-tiddlywiki-summary`,order:20,label:ab},sb))}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 lb(e,t){let n=await fetch(e,{...t,signal: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 ub(e){let t=!1;e.classList.add(`dsh-tw-settings`);let n=$(`div`,`dsh-tw-settings-row dsh-tw-settings-status`),r=$(`div`,`dsh-tw-settings-body`);e.append(n,r);let i=[],a={},o=async()=>{try{let e=await lb(T);if(t)return;db(n,e,o),gb(r,e,o,()=>t,a)}catch(e){if(t)return;r.replaceChildren(),n.replaceChildren();let i=$(`div`,`dsh-tw-settings-error`,`加载配置失败:${e instanceof Error?e.message:String(e)}`),a=$(`button`,`dsh-tw-settings-btn`,`重试`);a.type=`button`,a.addEventListener(`click`,()=>{o()}),r.append(i,a)}};return o(),i.push(()=>{t=!0,e.replaceChildren(),e.classList.remove(`dsh-tw-settings`)}),()=>{for(let e of i.splice(0))e()}}function db(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?.conflict===void 0?t.git?.dirty===!0?`有未提交改动`:``:`⚠️ 冲突未解决(${t.git.conflict.files.length} 个文件,已阻止提交)`].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(S,{method:`POST`,signal:AbortSignal.timeout(12e4)}),t=de(await e.json().catch(()=>null),e.status);D(t.ok?`同步完成:${t.message}`:`同步失败:${t.message}`)}catch(e){D(`同步失败:${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 lb(ie,{method:`POST`}),D(`TW 已重启`)}catch(e){D(`重启失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`重启 TW`,n()}})()}),e.append(a,o,s,c)}function fb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`常规配置`));let i=t.note??{},a=t.git??{},o=t.ui??{},s=[],c=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.value=n;let a=$(`label`,`dsh-tw-settings-field`);a.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:()=>i.value.trim(),changed:()=>i.value.trim()!==n}),r.append(a)},l=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-check`);i.type=`checkbox`,i.checked=n;let a=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-check`);return a.append(i,$(`span`,`dsh-tw-settings-label`,t)),s.push({key:e,initial:n,read:()=>i.checked,changed:()=>i.checked!==n}),r.append(a),i},u=(e,t,n)=>{let i=$(`input`,`dsh-tw-settings-input`);i.type=`number`,i.value=String(n);let a=()=>{let e=i.value.trim();if(e.length===0)return n;let t=Number(e);return Number.isFinite(t)?t:n},o=$(`label`,`dsh-tw-settings-field`);o.append($(`span`,`dsh-tw-settings-label`,t),i),s.push({key:e,initial:n,read:a,changed:()=>a()!==n}),r.append(o)},d=(e,t,n,i)=>{let a=$(`select`,`dsh-tw-settings-input`);for(let e of i){let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,e.value===n&&(t.selected=!0),a.append(t)}let o=$(`label`,`dsh-tw-settings-field`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value,changed:()=>a.value!==n}),r.append(o),a},f=(e,t,n,i)=>{let a=$(`textarea`,`dsh-tw-settings-input dsh-tw-settings-area`);a.rows=i,a.value=n;let o=$(`label`,`dsh-tw-settings-field dsh-tw-settings-field-area`);return o.append($(`span`,`dsh-tw-settings-label`,t),a),s.push({key:e,initial:n,read:()=>a.value.trim(),changed:()=>a.value.trim()!==n}),r.append(o),a};c(`note.tag`,`快速笔记默认 tag`,typeof i.tag==`string`?i.tag:`inbox`),l(`git.autoCommit`,`自动 commit(防抖)`,a.autoCommit!==!1),u(`git.debounceMs`,`自动 commit 防抖(ms)`,typeof a.debounceMs==`number`?a.debounceMs:6e4),c(`git.remote`,`git 远端(空=仅本地)`,typeof a.remote==`string`?a.remote:``),c(`git.branch`,`git 分支`,typeof a.branch==`string`?a.branch:`main`);let p=t.startup??{};u(`startup.readyTimeoutMs`,`TW 启动就绪等待(ms;默认 60000,范围 5000–600000,超时上限为其 3 倍,对下次启动/重启生效)`,typeof p.readyTimeoutMs==`number`&&p.readyTimeoutMs>0?p.readyTimeoutMs:6e4),l(`ui.showQuickNote`,`显示「知识库」按钮里的「快速笔记」入口`,o.showQuickNote!==!1),l(`ui.showQuickNoteDock`,`显示聊天输入框上方的「快速笔记」快捷按钮`,o.showQuickNoteDock!==!1),d(`ui.quickNoteMode`,`点击「快速笔记」的打开方式`,typeof o.quickNoteMode==`string`&&o.quickNoteMode===`card`?`card`:`native`,[{value:`native`,label:`原生编辑器:直接弹出 TW 原生编辑页(新建/恢复草稿)`},{value:`card`,label:`Markdown 卡片:弹出现有快速笔记卡片(CodeMirror 编辑器)`}]),c(`ui.sidebarLabel`,`侧边栏 TW 入口显示名称`,typeof o.sidebarLabel==`string`&&o.sidebarLabel.trim().length>0?o.sidebarLabel.trim():`TiddlyWiki`),l(`ui.showPanelStatus`,`显示「知识库」按钮里的 TW 面板/重载入口与状态行`,o.showPanelStatus!==!1),l(`ui.showSyncButton`,`显示「知识库」按钮里的「同步」入口与 git 状态点`,o.showSyncButton!==!1),l(`ui.followDshTheme`,`嵌入式 TW 跟随 DSH 深浅主题(暗色时自动切深色 palette,不写回 wiki)`,o.followDshTheme!==!1),c(`ui.darkPalette`,`暗色时 TW palette(tiddler 标题)`,typeof o.darkPalette==`string`&&o.darkPalette.trim().length>0?o.darkPalette.trim():`$:/palettes/CupertinoDark`),c(`ui.tabLabel`,`会话顶部「知识库」Tab 名称`,typeof o.tabLabel==`string`&&o.tabLabel.trim().length>0?o.tabLabel.trim():`知识库`),l(`ui.showSessionTab`,`显示会话顶部「知识库」Tab(本会话相关 wiki 笔记汇总)`,o.showSessionTab!==!1),l(`ui.showRightbarTab`,`在 DSH 右侧边栏提供 TiddlyWiki 入口/Tab(与聊天并排)`,o.showRightbarTab!==!1);let m=o.sendToAgent??{};l(`ui.sendToAgent.enabled`,`启用「发送给 Agent」(TW 笔记 → DSH 会话注入)`,m.enabled!==!1),c(`ui.sendToAgent.endpoint`,`TW 端请求基址(空=自动取当前 DSH origin)`,typeof m.endpoint==`string`?m.endpoint:``),c(`ui.sendToAgent.token`,`共享 token(非空时路由校验 x-send-to-agent-token 头;已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof m.token==`string`?m.token:``);let h=o.allArticles??{};u(`ui.allArticles.pageSize`,`「所有文章」每页条数`,typeof h.pageSize==`number`?h.pageSize:10),r.append($(`h3`,`dsh-tw-settings-h`,`可选功能:微信公众号发布`)),r.append($(`div`,`dsh-tw-settings-muted`,`把 wiki 笔记一键发到公众号草稿箱(可选点发表)。**需要额外安装**:opencli 与 Browser Bridge 浏览器扩展,并让浏览器登录 mp.weixin.qq.com;adapter 在本仓库 tools/wechat/,安装与排错见 docs/wechat-publish-setup.md。不安装/不开启它,插件其他功能完全不受影响。开启后:注入提示词会多一条「发布前先读发布元数据规范」的约定,并在启动时把「发布元数据规范」与「微信公众号发布指南」(安装/换机还原步骤,等于仓库 docs/wechat-publish-setup.md)两篇文档写进 wiki(同名不覆盖)。`));let g=l(`wechat.enabled`,`启用微信公众号发布(默认关;需先按 docs/wechat-publish-setup.md 安装 opencli + 浏览器扩展)`,(t.wechat??{}).enabled===!0),_=t.prompt??{};r.append($(`h3`,`dsh-tw-settings-h`,`系统提示词(注入每个会话)`)),r.append($(`div`,`dsh-tw-settings-muted`,`插件把自己的约定(同步纪律 / 标签约定 / 链接格式等)注入每个会话的系统提示词。保存后**无需重启 dsh web**:section 会即时重新注册,当前会话从下一步起就使用新文本。`));let v=l(`prompt.enabled`,`注入 TiddlyWiki 提示词(关闭后本插件不再注入任何文本)`,_.enabled!==!1),y=d(`prompt.mode`,`内置文本形态`,_.mode===`full`?`full`:`slim`,[{value:`slim`,label:`精简(默认):只保留工具 schema 表达不了的约定`},{value:`full`,label:`完整:额外附一份由工具注册表实时生成的参数索引`}]),ee=f(`prompt.extra`,`附加说明(永远追加在末尾,可放团队/个人规范)`,typeof _.extra==`string`?_.extra:``,5),te=f(`prompt.override`,`整段替换(非空时取代上面的内置文本,附加说明仍会追加)`,typeof _.override==`string`?_.override:``,8),b=()=>s.some(e=>(e.key.startsWith(`prompt.`)||e.key===`wechat.enabled`)&&e.changed()),x=$(`button`,`dsh-tw-settings-btn`,`预览注入文本(按表单当前值)`);x.type=`button`,x.title=`按表单当前值渲染注入文本(不用先保存);点「保存配置」后这就是实际注入的内容`;let S=$(`pre`,`dsh-tw-settings-prompt-preview`);S.hidden=!0,x.addEventListener(`click`,()=>{if(!S.hidden){S.hidden=!0,S.textContent=``;return}x.disabled=!0,(async()=>{try{let e=await lb(ne,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({enabled:v.checked,mode:y.value,extra:ee.value,override:te.value,wechat:g.checked})});if(e.ok!==!0)throw Error(e.error??`获取失败`);S.textContent=e.enabled===!1?`(已关闭:不会注入任何提示词)`:`# 形态 ${e.mode??``} · ${e.length??0} 字符${b()?`(含未保存的修改,保存后才真正注入)`:``}\n\n${e.text??``}`,S.hidden=!1}catch(e){D(`读取提示词失败:${e instanceof Error?e.message:String(e)}`)}finally{x.disabled=!1}})()}),r.append(x,S);let C=t.bridge??{};l(`bridge.enabled`,`启用「本地剪藏桥」(书签小工具后端监听 127.0.0.1 端口,保存后立即生效)`,C.enabled===!0),u(`bridge.port`,`剪藏桥端口(改端口需重启 dsh web 生效)`,typeof C.port==`number`&&C.port>0?C.port:8618),c(`bridge.token`,`剪藏桥 token(非空时校验书签的 x-clip-token 头;强烈建议设置。已设置时显示为 ********,原样保存=不改,清空=删除)`,typeof C.token==`string`?C.token:``),c(`bridge.tag`,`剪藏笔记默认 tag`,typeof C.tag==`string`&&C.tag.trim().length>0?C.tag.trim():`clip`);let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`保存配置`);w.type=`button`,w.addEventListener(`click`,()=>{w.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 lb(re,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),ye(),D(`配置已保存`),n()}catch(e){D(`保存失败:${e instanceof Error?e.message:String(e)}`)}finally{w.disabled=!1}})()}),r.append(w),e.append(r)}function pb(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 lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({plugins:[...s]})}),D(`插件已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),p.disabled=!1}})()}),m(``),u.append(d,f,p),e.append(u);let h=$(`section`,`dsh-tw-settings-section`);h.append($(`h3`,`dsh-tw-settings-h`,`主题管理(自带主题)`));let g=$(`div`,`dsh-tw-settings-muted`,`「加载」= TW 里可用的主题(可多选,依赖链自动带上,如 heavier 会带 snowwhite+vanilla);「活动」= 当前视觉主题(单选,自动加入加载集)。应用后重启 TW。`),_=$(`div`,`dsh-tw-settings-row dsh-tw-settings-head`);_.append($(`span`,`dsh-tw-settings-col`,`加载`),$(`span`,`dsh-tw-settings-col`,`活动`),$(`span`,`dsh-tw-settings-name`,`主题`));let v=t?.themes??[],y=t?.themeActive,ee=typeof y==`string`&&a.some(e=>e.name===y)?y:v.length>0?v[v.length-1]:`tiddlywiki/vanilla`,te=$(`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===ee,n.title=`设为活动主题`,n.addEventListener(`change`,()=>{n.checked&&(ee=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),te.append(a)}let b=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用主题(重启 TW)`);b.type=`button`,b.addEventListener(`click`,()=>{b.disabled=!0,(async()=>{try{await lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({themes:[...c],themeActive:ee})}),D(`主题已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),b.disabled=!1}})()}),h.append(g,_,te,b),e.append(h);let x=$(`section`,`dsh-tw-settings-section`);x.append($(`h3`,`dsh-tw-settings-h`,`语言管理(自带官方语言包)`));let S=$(`div`,`dsh-tw-settings-muted`,`勾选启用语言插件并重启 TW;如中文请选 zh-Hans(简体)或 zh-CN。`),C=$(`div`,`dsh-tw-settings-list`);for(let e of o){let t=$(`input`,`dsh-tw-settings-check`);t.type=`checkbox`,t.checked=l.has(e.name),t.addEventListener(`change`,()=>{t.checked?l.add(e.name):l.delete(e.name)});let n=$(`label`,`dsh-tw-settings-row dsh-tw-settings-plugin`),r=$(`span`,`dsh-tw-settings-name`,e.label);r.title=e.name;let i=$(`span`,`dsh-tw-settings-muted`,e.description||e.name);n.append(t,r,i),C.append(n)}let w=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`应用语言(重启 TW)`);w.type=`button`,w.addEventListener(`click`,()=>{w.disabled=!0,(async()=>{try{await lb(E,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({languages:[...l]})}),D(`语言已应用,TW 已重启`),r()}catch(e){D(`应用失败:${e instanceof Error?e.message:String(e)}`),w.disabled=!1}})()}),x.append(S,C,w),e.append(x)}function mb(e,t,n){let r=$(`section`,`dsh-tw-settings-section`);r.append($(`h3`,`dsh-tw-settings-h`,`知识库位置(可切换)`));let i=$(`div`,`dsh-tw-settings-muted`,`读取中…`),a=$(`div`,`dsh-tw-settings-muted`),o=$(`div`,`dsh-tw-settings-muted`),s=$(`div`,`dsh-tw-settings-muted`),c=$(`input`,`dsh-tw-settings-input`),l=$(`input`,`dsh-tw-settings-input`);c.placeholder=`绝对路径,如 D:\\notes 或 $DSH_HOME/tiddlywiki`,l.placeholder=`文件夹名(默认 main;填 . 表示直接用上面这个目录)`;let u=$(`label`,`dsh-tw-settings-field`);u.append($(`span`,`dsh-tw-settings-label`,`根目录(wikiRoot)`),c);let d=$(`label`,`dsh-tw-settings-field`);d.append($(`span`,`dsh-tw-settings-label`,`文件夹名(wiki)`),l);let f=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`切换到这个位置`);f.type=`button`;let p=$(`button`,`dsh-tw-settings-btn`,`恢复为配置默认`);p.type=`button`;let m=$(`div`,`dsh-tw-settings-row`);m.append(f,p);let h=$(`div`,`dsh-tw-settings-row dsh-tw-settings-candidates`),g=$(`div`,`dsh-tw-settings-muted`,"切换会停掉并就地重启 TW 子进程(几秒);新目录若还没有 tiddlywiki.info,插件会自动 `--init server` 初始化一个全新知识库。选中的位置会记在 $DSH_HOME 下的指针文件里(不进 wiki),可用「恢复为配置默认」清除。"),_=(e,t)=>{f.disabled=e,p.disabled=e,f.textContent=e?t:`切换到这个位置`},v=async()=>{if(!t())try{let e=await lb(ce);if(t())return;if(e.ok!==!0)throw Error(e.error??`获取失败`);let n=e.current??{};i.textContent=`当前:${n.path??`(未知)`}`;let r=n.source===`state`?`来源:指针文件(在设置页切换过)`:n.source===`config`?`来源:cordis 配置(config.wikiRoot / config.wiki)`:`来源:默认值($DSH_HOME/tiddlywiki + main)`;a.textContent=`${r} · 配置默认:${e.default?.path??`(未知)`}`,o.textContent=e.stateFile===void 0?``:`指针文件:${e.stateFile}(不存在=使用配置默认)`,s.textContent=e.error===void 0?``:`⚠️ ${e.error}`,c.value.length===0&&typeof n.root==`string`&&(c.value=n.root),l.value.length===0&&typeof n.name==`string`&&(l.value=n.name),h.replaceChildren();let u=e.candidates??[];if(u.length>0){h.append($(`span`,`dsh-tw-settings-label`,`同目录下可选的 wiki:`));for(let e of u){let t=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-chipbtn`,e===`.`?`(根目录本身)`:e);t.type=`button`,t.title=`填入文件夹名「${e}」`,t.addEventListener(`click`,()=>{l.value=e}),h.append(t)}}}catch(e){if(t())return;i.textContent=`读取位置失败:${e instanceof Error?e.message:String(e)}`}};f.addEventListener(`click`,()=>{let e=c.value.trim(),t=l.value.trim().length>0?l.value.trim():`main`;if(e.length===0){D(`请先填写根目录(绝对路径)`);return}window.confirm(`切换知识库到:\n${e}\\${t}\n\n会停止并重启 TW 子进程;当前对话/工具随后读写的是新知识库。确定继续?`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let r=await lb(le,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({root:e,name:t}),signal:AbortSignal.timeout(12e4)});r.warning===void 0?D(`已切换到 ${r.path??``}`):D(`已切换到 ${r.path??``}(注意:${r.warning})`),ye(),await v(),await n()}catch(e){D(`切换失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),p.addEventListener(`click`,()=>{window.confirm(`恢复为配置默认位置?会删除位置指针文件,并(必要时)切回配置里的知识库。`)&&(_(!0,`切换中…(重启 TW)`),(async()=>{try{let e=await lb(ue,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`,signal:AbortSignal.timeout(12e4)});D(e.warning===void 0?`已恢复为配置默认:${e.path??``}`:`已恢复默认(注意:${e.warning})`),ye(),await v(),await n()}catch(e){D(`恢复失败:${e instanceof Error?e.message:String(e)}`),await v()}finally{_(!1,``)}})())}),r.append(i,a,o,u,d,m,h,s,g),e.append(r),v()}function hb(e,t){let n=$(`section`,`dsh-tw-settings-section`);n.append($(`h3`,`dsh-tw-settings-h`,`初始化(一次性预置)`));let r=$(`div`,`dsh-tw-settings-muted`,`这些是插件与 dsh 联动、需要在 wiki 里预置的 tiddler/配置。「发送给 Agent 按钮」和「TW 前端 API 基址」是功能必需项,启动时自动写入(只写缺失,不覆盖你的改动);其余为可选项,默认不自动写入、也不会强绑定——需要时点「重新初始化」写入,不想要了可随时「反初始化」移除。`),i=$(`div`,`dsh-tw-settings-list`),a=$(`div`,`dsh-tw-settings-muted`),o=async()=>{if(!t())try{let e=await lb(ae);if(t())return;if(e.ok!==!0||!Array.isArray(e.items))throw Error(e.error??`获取失败`);i.replaceChildren();let n=0,r=0;for(let t of e.items){t.present&&(n+=1),t.removable&&(r+=1);let e=$(`span`,`dsh-tw-settings-chip`,t.present?`✓`:`✗`);e.dataset.state=t.present?`ok`:`missing`,e.title=t.present?`已存在`:`缺失`;let a=$(`span`,`dsh-tw-settings-name`,t.title);a.title=t.id;let s=$(`span`,`dsh-tw-settings-muted`,t.detail??t.description),c=t.updateAvailable===!0?$(`span`,`dsh-tw-settings-chip`,`⬆ 有更新`):void 0;c!==void 0&&(c.dataset.state=`update`,c.title=`内置内容在本 wiki 预置之后更新过,可点「重新初始化」取用`);let l=t.userModified===!0?$(`span`,`dsh-tw-settings-chip`,`✏️ 本地已修改`):void 0;l!==void 0&&(l.dataset.state=`missing`,l.title=`这篇是你的内容:重新初始化会覆盖它`);let u=$(`button`,`dsh-tw-settings-btn`,t.updateAvailable===!0?`更新到内置版本`:`重新初始化`);u.type=`button`,u.title=`强制重写「${t.title}」的内置内容(会覆盖当前 tiddler)`,u.addEventListener(`click`,()=>{if(t.updateAvailable===!0){let e=t.userModified===!0?`「${t.title}」有你的本地修改,更新会覆盖它。`:t.userModified===void 0?`无法确认「${t.title}」是否被你编辑过(旧格式标记),更新可能覆盖你的改动。`:``;if(!window.confirm(`${e}${e.length>0?`
765
765
 
766
- `:``}用内置版本覆盖?`))return}u.disabled=!0,u.textContent=`执行中…`,(async()=>{try{let e=await fetch(oe,{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?D(`重新初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):D(`已重新初始化「${t.title}」`),o()}catch(e){D(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{u.disabled=!1,u.textContent=t.updateAvailable===!0?`更新到内置版本`:`重新初始化`}})()});let d=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);if(d.append(e,a),c!==void 0&&d.append(c),l!==void 0&&d.append(l),d.append(s,u),t.removable){let e=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`反初始化`);e.type=`button`,e.title=`移除「${t.title}」写入的 tiddler 与 marker(恢复未初始化状态)`,e.addEventListener(`click`,()=>{window.confirm(`确定反初始化「${t.title}」?将删除它写入的 tiddler(含其一次性 marker),需要时可用「重新初始化」恢复。`)&&(e.disabled=!0,e.textContent=`移除中…`,(async()=>{try{let e=await fetch(se,{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?D(`反初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):D(`已反初始化「${t.title}」`),o()}catch(e){D(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{e.disabled=!1,e.textContent=`反初始化`}})())}),d.append(e)}i.append(d)}a.textContent=`共 ${e.items.length} 项,${n} 项已就绪;可移除 ${r} 项`}catch(e){if(t())return;a.textContent=`加载初始化状态失败:${e instanceof Error?e.message:String(e)}`}},s=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`全部重新初始化`);s.type=`button`,s.title=`强制重写所有一次性预置内容(含可选 seed,会覆盖当前 tiddler/配置)`,s.addEventListener(`click`,()=>{s.disabled=!0,s.textContent=`执行中…`,(async()=>{try{let e=await fetch(oe,{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?D(`重新初始化失败:${t?.error??`HTTP ${e.status}`}`):D(`全部已重新初始化`),o()}catch(e){D(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{s.disabled=!1,s.textContent=`全部重新初始化`}})()});let c=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`全部反初始化`);c.type=`button`,c.title=`移除所有可选 seed 写入的 tiddler 与 marker(功能必需项保留)`,c.addEventListener(`click`,()=>{window.confirm(`确定全部反初始化?将删除所有可选 seed 写入的 tiddler(含一次性 marker)。功能必需项(发送给 Agent 按钮 / TW 前端 API 基址)会保留。`)&&(c.disabled=!0,c.textContent=`移除中…`,(async()=>{try{let e=await fetch(se,{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?D(`反初始化失败:${t?.error??`HTTP ${e.status}`}`):D(`全部可选 seed 已反初始化`),o()}catch(e){D(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`全部反初始化`}})())}),n.append(r,a,i,s,c),e.append(n),o()}function gb(e,t,n,r,i){e.replaceChildren();let a=JSON.stringify(t.config??{});if(i.host===void 0||i.signature!==a){let e=$(`div`,`dsh-tw-settings-confighost`);fb(e,t.config??{},n),i.host=e,i.signature=a}e.append(i.host),mb(e,r,n),pb(e,t.info,t.catalog,n),hb(e,r)}function _b(){let e=c.useRef(null);return c.useEffect(()=>{let t=e.current;return t===null?void 0:ub(t)},[]),c.createElement(`div`,{ref:e})}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:`git 同步`,tiddlywiki_git_resolve:`git 冲突解决`};function yb(e){return typeof e==`object`&&!!e&&e.kind===`tool-result`}function bb(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 xb(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{}}catch{return{}}}function Sb(e){return Array.isArray(e)?e.filter(e=>typeof e?.text==`string`).map(e=>e.text).join(`
766
+ `:``}用内置版本覆盖?`))return}u.disabled=!0,u.textContent=`执行中…`,(async()=>{try{let e=await fetch(oe,{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?D(`重新初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):D(`已重新初始化「${t.title}」`),o()}catch(e){D(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{u.disabled=!1,u.textContent=t.updateAvailable===!0?`更新到内置版本`:`重新初始化`}})()});let d=$(`div`,`dsh-tw-settings-row dsh-tw-settings-plugin`);if(d.append(e,a),c!==void 0&&d.append(c),l!==void 0&&d.append(l),d.append(s,u),t.removable){let e=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`反初始化`);e.type=`button`,e.title=`移除「${t.title}」写入的 tiddler 与 marker(恢复未初始化状态)`,e.addEventListener(`click`,()=>{window.confirm(`确定反初始化「${t.title}」?将删除它写入的 tiddler(含其一次性 marker),需要时可用「重新初始化」恢复。`)&&(e.disabled=!0,e.textContent=`移除中…`,(async()=>{try{let e=await fetch(se,{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?D(`反初始化失败:${n?.error??n?.results?.[0]?.error??`HTTP ${e.status}`}`):D(`已反初始化「${t.title}」`),o()}catch(e){D(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{e.disabled=!1,e.textContent=`反初始化`}})())}),d.append(e)}i.append(d)}a.textContent=`共 ${e.items.length} 项,${n} 项已就绪;可移除 ${r} 项`}catch(e){if(t())return;a.textContent=`加载初始化状态失败:${e instanceof Error?e.message:String(e)}`}},s=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-primary`,`全部重新初始化`);s.type=`button`,s.title=`强制重写所有一次性预置内容(含可选 seed,会覆盖当前 tiddler/配置)`,s.addEventListener(`click`,()=>{s.disabled=!0,s.textContent=`执行中…`,(async()=>{try{let e=await fetch(oe,{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?D(`重新初始化失败:${t?.error??`HTTP ${e.status}`}`):D(`全部已重新初始化`),o()}catch(e){D(`重新初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{s.disabled=!1,s.textContent=`全部重新初始化`}})()});let c=$(`button`,`dsh-tw-settings-btn dsh-tw-settings-danger`,`全部反初始化`);c.type=`button`,c.title=`移除所有可选 seed 写入的 tiddler 与 marker(功能必需项保留)`,c.addEventListener(`click`,()=>{window.confirm(`确定全部反初始化?将删除所有可选 seed 写入的 tiddler(含一次性 marker)。功能必需项(发送给 Agent 按钮 / TW 前端 API 基址)会保留。`)&&(c.disabled=!0,c.textContent=`移除中…`,(async()=>{try{let e=await fetch(se,{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?D(`反初始化失败:${t?.error??`HTTP ${e.status}`}`):D(`全部可选 seed 已反初始化`),o()}catch(e){D(`反初始化失败:${e instanceof Error?e.message:String(e)}`)}finally{c.disabled=!1,c.textContent=`全部反初始化`}})())}),n.append(r,a,i,s,c),e.append(n),o()}function gb(e,t,n,r,i){if(e.replaceChildren(),typeof t.configError==`string`&&t.configError.length>0){let n=$(`div`,`dsh-tw-settings-banner`);n.dataset.tone=`error`,n.setAttribute(`style`,`border:1px solid #c0392b;background:#fdecea;color:#8c1c13;border-radius:6px;padding:10px 12px;margin:0 0 12px;font-size:12px;line-height:1.6;white-space:pre-wrap;`),n.textContent=`⚠️ 配置未生效:${t.configError}`,e.append(n)}let a=JSON.stringify(t.config??{});if(i.host===void 0||i.signature!==a){let e=$(`div`,`dsh-tw-settings-confighost`);fb(e,t.config??{},n),i.host=e,i.signature=a}e.append(i.host),mb(e,r,n),pb(e,t.info,t.catalog,n),hb(e,r)}function _b(){let e=c.useRef(null);return c.useEffect(()=>{let t=e.current;return t===null?void 0:ub(t)},[]),c.createElement(`div`,{ref:e})}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:`git 同步`,tiddlywiki_git_resolve:`git 冲突解决`};function yb(e){return typeof e==`object`&&!!e&&e.kind===`tool-result`}function bb(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 xb(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{}}catch{return{}}}function Sb(e){return Array.isArray(e)?e.filter(e=>typeof e?.text==`string`).map(e=>e.text).join(`
767
767
  `):``}function Cb(e){return typeof e==`string`?e:``}async function wb(e){try{let t=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(t.status===404){let e=await t.json().catch(()=>null);return typeof e==`object`&&e?e:{notFound:!0}}if(!t.ok)return null;let n=await t.json();return typeof n==`object`&&n?n:null}catch{return null}}async function Tb(e){return ib(e,1e4)}function Eb(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 Db(e){return t=>{t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||(t.preventDefault(),t.stopPropagation(),mt(e))}}function Ob(e){let t=vb[e.toolName]??e.toolName,n=c.createElement(`div`,{className:`dsh-tw-toolcard-head`},c.createElement(`span`,{className:`dsh-tw-toolcard-badge`},t),e.title!==void 0&&e.title.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-title`,title:e.title},e.title):null,e.onOpen===void 0?null:c.createElement(`button`,{type:`button`,className:`dsh-tw-toolcard-open`,onClick:e.onOpen},`在 TW 打开`)),r=e.subtitle!==void 0||e.tags!==void 0&&e.tags.length>0?c.createElement(`div`,{className:`dsh-tw-toolcard-meta`},e.subtitle===void 0?null:c.createElement(`span`,{className:`dsh-tw-toolcard-sub`},e.subtitle),e.tags!==void 0&&e.tags.length>0?c.createElement(`span`,{className:`dsh-tw-toolcard-tags`},...e.tags.map((e,t)=>c.createElement(`span`,{className:`dsh-tw-toolcard-tag`,key:`${t}-${e}`},e))):null):null;return c.createElement(`div`,{className:`dsh-tw-toolcard`},n,r,c.createElement(`div`,{className:`dsh-tw-toolcard-body`},e.children),e.foot!==void 0&&e.foot!==null?c.createElement(`div`,{className:`dsh-tw-toolcard-foot`},e.foot):null)}const kb=new Map;function Ab(e){let t=kb.get(e);if(t!==void 0){if(Date.now()-t.at>3e5){kb.delete(e);return}return kb.delete(e),kb.set(e,t),t}}function jb(e,t){for(kb.delete(e),kb.set(e,{at:Date.now(),...t});kb.size>50;){let e=kb.keys().next().value;if(e===void 0)break;kb.delete(e)}}function Mb(e){e.length>0&&kb.delete(e)}function Nb(e){let t=e.join(`\0`);c.useEffect(()=>{for(let e of t.split(`\0`))Mb(e)},[t])}function Pb(e){let{title:t,fresh:n}=e,{loading:r,data:i}=Eb(async()=>{n===!0&&Mb(t);let e=Ab(t);if(e!==void 0)return{get:e.get,html:e.html};let[r,i]=await Promise.all([wb(`${g}?title=${encodeURIComponent(t)}`),Tb(t)]);return typeof i==`string`&&i.length>0&&jb(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(Ob,{toolName:e.toolName,title:t,subtitle:e.subtitle,tags:l,onOpen:Db(t),foot:u===void 0?void 0:`修改于 ${u}`},s)}function Fb(e){let t=c.createElement(`span`,{className:`dsh-tw-toolcard-row-head`},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),n=typeof e.snippet==`string`&&e.snippet.trim().length>0?e.snippet:null;return c.createElement(`a`,{className:`dsh-tw-toolcard-row`,href:`${m}#${encodeURIComponent(e.title)}`,onClick:Db(e.title),title:n===null?e.title:`${e.title}\n${n}`},t,n===null?null:c.createElement(`span`,{className:`dsh-tw-toolcard-row-snippet`},n))}function Ib(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(Fb,{key:`${e.title}-${t}`,...e}))),c.createElement(Ob,{toolName:e.toolName,title:e.title,subtitle:e.subtitle},n)}function Lb(e){let t=Cb(e.args.query),n=new URLSearchParams;if(t.length>0&&n.set(`query`,t),Array.isArray(e.args.tags))for(let t of e.args.tags)typeof t==`string`&&t.length>0&&n.append(`tags`,t);typeof e.args.tag==`string`&&e.args.tag.length>0&&n.set(`tag`,e.args.tag),typeof e.args.since==`string`&&e.args.since.length>0&&n.set(`since`,e.args.since),typeof e.args.type==`string`&&e.args.type.length>0&&n.set(`type`,e.args.type),typeof e.args.field==`string`&&e.args.field.length>0&&n.set(`field`,e.args.field),typeof e.args.value==`string`&&e.args.value.length>0&&n.set(`value`,e.args.value),typeof e.args.limit==`number`&&n.set(`limit`,String(e.args.limit));let r=n.toString(),i=Eb(()=>wb(`${b}?${r}`),[r]).data,a=(Array.isArray(i?.items)?i.items:[]).map(e=>({title:Cb(e.title),tags:Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`):[],modified:typeof e.modified==`string`?e.modified:null,snippet:typeof e.snippet==`string`?e.snippet:``})),o=typeof i?.total==`number`?i.total:void 0,s=`关键词「${t||`(全部)`}」${o===void 0?``:` · 共 ${o} 条`}`;return c.createElement(Ib,{toolName:e.toolName,title:t.length>0?t:`检索`,subtitle:s,rows:a,fallbackText:`没有匹配的笔记`})}function Rb(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=Eb(()=>wb(`${te}?${n}`),[n]).data,i=(Array.isArray(r?.items)?r.items:[]).map(e=>({title:Cb(e.title),tags:Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`):[],modified:typeof e.modified==`string`?e.modified:null,snippet:typeof e.snippet==`string`?e.snippet:``}));return c.createElement(Ib,{toolName:e.toolName,title:`最近修改`,subtitle:i.length>0?`最近 ${i.length} 条`:``,rows:i,fallbackText:`暂无笔记`})}function zb(e){let t=(Array.isArray(e.args.items)?e.args.items:[]).map(e=>typeof e==`object`&&e&&typeof e.title==`string`?Cb(e.title):null).filter(e=>e!==null&&e.length>0).map(e=>({title:e}));return Nb(t.map(e=>e.title)),c.createElement(Ib,{toolName:e.toolName,title:`批量写入`,subtitle:t.length>0?`写入 ${t.length} 篇`:`(参数中没有可解析的 items)`,rows:t,fallbackText:`没有可展示的笔记`})}function Bb(e){let t=Eb(()=>wb(`${ee}?limit=60&sort=count`),[]).data,n=(Array.isArray(t?.items)?t.items:[]).map(e=>({tag:Cb(e.tag),count:typeof e.count==`number`?e.count:0})),r=n.slice(0,60),i=typeof t?.total==`number`?t.total:n.length,a;return a=n.length===0?c.createElement(`div`,{className:`dsh-tw-toolcard-empty`},`暂无标签`):c.createElement(`div`,{className:`dsh-tw-toolcard-tags-wrap`},...r.map(e=>c.createElement(`span`,{className:`dsh-tw-toolcard-tag`,key:e.tag},`${e.tag} · ${e.count}`)),...i>r.length?[c.createElement(`span`,{className:`dsh-tw-toolcard-tag-more`,key:`__more`},`…另有 ${i-r.length} 个`)]:[]),c.createElement(Ob,{toolName:e.toolName,title:`标签`,subtitle:`共 ${i} 个`},a)}function Vb(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(Ob,{toolName:e.toolName},t)}function Hb(e){Nb([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(Ob,{toolName:e.toolName,title:e.title.length>0?e.title:void 0},t)}function Ub(e,t){switch(e){case`tiddlywiki_get`:case`tiddlywiki_put`:case`tiddlywiki_append`:case`tiddlywiki_delete`:case`tiddlywiki_attach`:case`tiddlywiki_backlinks`:return Cb(t.title);case`tiddlywiki_rename`:return Cb(t.newTitle);case`tiddlywiki_search`:return Cb(t.query);default:return``}}function Wb(e){let t=e.block,n=e.toolName,r=yb(t),i=bb(t),a=n!==void 0&&n.length>0?n:i?.name??``,o=xb(i?.argsRaw??``),s=r?Sb(t.content):``;if(i===null)return c.createElement(Ob,{toolName:a},c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},s||`(无调用信息)`));if(!r)return c.createElement(Ob,{toolName:a,title:Ub(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-pending`},`处理中…`));if(t.isError===!0)return c.createElement(Ob,{toolName:a,title:Ub(a,o)},c.createElement(`div`,{className:`dsh-tw-toolcard-error`},s||`工具调用失败`));switch(a){case`tiddlywiki_get`:return c.createElement(Pb,{toolName:a,title:Cb(o.title),subtitle:`读取`});case`tiddlywiki_put`:return c.createElement(Pb,{toolName:a,title:Cb(o.title),subtitle:`已写入`,fresh:!0});case`tiddlywiki_append`:return c.createElement(Pb,{toolName:a,title:Cb(o.title),subtitle:`已增量写入`,fresh:!0});case`tiddlywiki_rename`:return c.createElement(Pb,{toolName:a,title:Cb(o.newTitle),subtitle:`已重命名「${Cb(o.oldTitle)}」→`,fresh:!0});case`tiddlywiki_delete`:return c.createElement(Hb,{toolName:a,title:Cb(o.title),text:s});case`tiddlywiki_batch_put`:return c.createElement(zb,{toolName:a,args:o});case`tiddlywiki_search`:return c.createElement(Lb,{toolName:a,args:o});case`tiddlywiki_recent`:return c.createElement(Rb,{toolName:a,args:o});case`tiddlywiki_list_tags`:return c.createElement(Bb,{toolName:a});case`tiddlywiki_git_sync`:case`tiddlywiki_git_resolve`:return c.createElement(Vb,{toolName:a,text:s});default:return c.createElement(Ob,{toolName:a,title:Ub(a,o)},c.createElement(`pre`,{className:`dsh-tw-toolcard-fallback`},s||`(完成)`))}}const Gb=[`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 Kb(e){let t=[];for(let n of Gb)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}`},Wb));r!==void 0&&t.push(r)}catch(e){console.error(`[dsh-tiddlywiki] register toolview ${n} failed:`,e)}return t}function qb(){let e=RegExp(`^${m.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}#(.+)$`),t=t=>{if(t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;let n=t.target;if(!(n instanceof Element))return;let r=n.closest(`a`);if(r===null)return;let i=(r.getAttribute(`href`)??``).match(e);if(i===null||i[1]===void 0)return;t.preventDefault(),t.stopPropagation();let a=i[1];try{a=decodeURIComponent(a)}catch{}mt(a)};return document.addEventListener(`click`,t,!0),()=>document.removeEventListener(`click`,t,!0)}const Jb=`dsh-tiddlywiki`,Yb=`dsh-tiddlywiki/rightbar`;function Xb(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=ot(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(Ke,{detail:Yb}));let e=e=>{e.detail!==Yb&&o()};return document.addEventListener(Ke,e),()=>document.removeEventListener(Ke,e)},[a,o]),c.createElement(`div`,{ref:r,className:`dsh-tw-rightbar-tab`})}function Zb(){return{id:Jb,kind:`dsh-tiddlywiki`,title:()=>Xe(),guide:[{order:10,title:()=>`TiddlyWiki 知识库`,description:()=>`在右侧边栏打开 TiddlyWiki 编辑器(与聊天并排)`,icon:Qe}]}}function Qb(e,t){let n=[];try{n.push(e.register(Zb()));let r=t.inject(`sidebar.right.pane.tab`,()=>t.register({name:`sidebar.right.pane.tab`,key:Jb},Xb));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 it(),()=>{for(let e of n.splice(0))e()}}const $b=[`slots`];function ex(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=Yy(),t.push(()=>o?.dispose())}),i(`sync controller`,()=>{s=$y(),t.push(()=>s?.dispose())}),i(`sidebar entry`,()=>t.push(Te(a))),i(`center panel`,()=>t.push(_t(a))),o!==void 0&&s!==void 0){let e=o,n=s;i(`knowledge FAB`,()=>t.push(nb(a,e,n)))}i(`editor popup`,()=>t.push(kt)),e.slots!==void 0&&be().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:`快速笔记`},rb(a)));n!==void 0&&t.push(n)}),i(`session summary tab`,()=>{let n=cb(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}be().then(r=>{if(n||!r.showRightbarTab)return;let i=Qb(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(...Kb(e.slots))}),i(`wiki link interceptor`,()=>t.push(qb())),i(`settings section`,()=>{let n=e.slots?.inject(`settings.section`,()=>e.slots?.register({name:`settings.section`,id:`dsh-tiddlywiki`,order:50,label:`TiddlyWiki 知识库`},_b));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=ex,exports.inject=$b,exports.name=`dsh-tiddlywiki/client`;
768
768
  return module.exports;
769
769
  }