From ba6a1069c8d4e88b6d357bcb5330f0a67f858082 Mon Sep 17 00:00:00 2001 From: Human Date: Mon, 1 Jun 2026 21:12:26 -0700 Subject: [PATCH] 0.77.9: author registry + claim authorship --- main.js | 109 +++++----- manifest.json | 2 +- package.json | 2 +- release-notes/0.77.9.md | 69 +++++++ src/author-registry.ts | 189 +++++++++++++++++ src/folder-suggest.ts | 9 +- src/main.ts | 396 +++++++++++++++++++++++++++++++++++- src/modals.ts | 92 ++++++++- src/note-picker.ts | 176 +++------------- src/settings.ts | 84 +++++++- src/time-picker.ts | 174 ++++++++++++++++ src/tree-index.ts | 9 + src/view.ts | 441 +++++++++++++++++++++++++++++++++++++--- styles.css | 114 +++++++++-- 14 files changed, 1594 insertions(+), 272 deletions(-) create mode 100644 release-notes/0.77.9.md create mode 100644 src/author-registry.ts create mode 100644 src/time-picker.ts diff --git a/main.js b/main.js index ace4c5e..f8271ff 100644 --- a/main.js +++ b/main.js @@ -1,82 +1,83 @@ -"use strict";var ri=Object.create;var be=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var oi=Object.getOwnPropertyNames;var li=Object.getPrototypeOf,ci=Object.prototype.hasOwnProperty;var ne=(v,f)=>()=>(v&&(f=v(v=0)),f);var di=(v,f)=>()=>(f||v((f={exports:{}}).exports,f),f.exports),Se=(v,f)=>{for(var t in f)be(v,t,{get:f[t],enumerable:!0})},Es=(v,f,t,e)=>{if(f&&typeof f=="object"||typeof f=="function")for(let s of oi(f))!ci.call(v,s)&&s!==t&&be(v,s,{get:()=>f[s],enumerable:!(e=ai(f,s))||e.enumerable});return v};var hi=(v,f,t)=>(t=v!=null?ri(li(v)):{},Es(f||!v||!v.__esModule?be(t,"default",{value:v,enumerable:!0}):t,v)),pi=v=>Es(be({},"__esModule",{value:!0}),v);function as(v){return Array.isArray(v)?v.filter(f=>typeof f=="string"):typeof v=="string"?v.split(/[,\s]+/).filter(Boolean):[]}function jt(v,f){let t=f.replace(/^#/,"");return as(v?.tags).some(e=>e.replace(/^#/,"")===t)}function os(v,f){let t=f.replace(/^#/,""),e=as(v.tags);e.some(s=>s.replace(/^#/,"")===t)||e.push(t),v.tags=e}function ls(v,f){let t=f.replace(/^#/,""),e=as(v.tags).filter(s=>s.replace(/^#/,"")!==t);e.length?v.tags=e:delete v.tags}var vt,Nt,Wt,B,re,xt=ne(()=>{"use strict";vt="stashpad-view",Nt="stashpad-panels",Wt="stashpad-detail",B="__root__";re=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children"]});var Te={};Se(Te,{ColorPickerModal:()=>Kt,ConfirmDeleteModal:()=>Zt,ConfirmModal:()=>Mt,CustomColorModal:()=>Ce,DueDatePickerModal:()=>le,LogModal:()=>qt,NotificationHistoryModal:()=>ce,SplitNoteModal:()=>oe});var gt,Vt,qt,Zt,oe,Ce,ae,Kt,Mt,le,Yt,ce,Gt=ne(()=>{"use strict";gt=require("obsidian"),Vt=class Vt extends gt.Modal{constructor(t,e,s){super(t);this.text=e;this.jsonlPath=s;this.events=[];this.visible=[];this.shownCount=0;this.typeFilter=null;this.listEl=null;this.footerEl=null;this.countEl=null;this.filterSelEl=null}onOpen(){this.contentEl.empty(),this.titleEl.setText("Stashpad log"),this.modalEl.addClass("stashpad-log-modal"),this.events=[];for(let a of this.text.trim().split(/\r?\n/))if(a)try{this.events.push(JSON.parse(a))}catch{}this.events.reverse();let t=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});this.countEl=t.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=t.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setTypeFilter(this.filterSelEl.value||null),this.refreshTypeFilter();let e=t.createEl("button",{text:"Reveal JSONL"});e.onclick=()=>this.shellAct("reveal");let s=t.createEl("button",{text:"Open in default app"});s.onclick=()=>this.shellAct("open");let i=t.createEl("button",{text:"Copy raw JSONL"}),n=null;i.onclick=async()=>{await navigator.clipboard.writeText(this.text),i.setText("Copied"),n!=null&&window.clearTimeout(n),n=window.setTimeout(()=>{i.setText("Copy raw JSONL"),n=null},1500)};let r=t.createEl("button",{text:"Export copy"});r.onclick=()=>this.exportCopy();let o=t.createEl("button",{cls:"mod-warning",text:"Clear log"});o.onclick=()=>this.clearLog(),this.listEl=this.contentEl.createDiv({cls:"stashpad-log-list"}),this.refreshList(),this.footerEl=this.contentEl.createDiv({cls:"stashpad-log-footer"}),this.renderFooter()}refreshList(){if(this.listEl){if(this.visible=this.typeFilter?this.events.filter(t=>t.type===this.typeFilter):this.events.slice(),this.shownCount=0,this.listEl.empty(),!this.visible.length){this.listEl.createDiv({cls:"stashpad-log-empty",text:this.typeFilter?`No "${this.typeFilter}" events.`:"No events yet."}),this.updateCount();return}this.appendMore(Vt.PAGE)}}setTypeFilter(t){(this.typeFilter??null)!==(t??null)&&(this.typeFilter=t,this.refreshList(),this.renderFooter())}refreshTypeFilter(){if(!this.filterSelEl)return;let t=this.filterSelEl;t.empty();let e=new Map;for(let n of this.events)e.set(n.type,(e.get(n.type)??0)+1);let s=[...e.entries()].sort((n,r)=>r[1]-n[1]||n[0].localeCompare(r[0])),i=t.createEl("option",{text:`All types (${this.events.length})`});i.value="";for(let[n,r]of s){let o=t.createEl("option",{text:`${n} (${r})`});o.value=n}this.typeFilter&&!e.has(this.typeFilter)&&(this.typeFilter=null),t.value=this.typeFilter??""}updateCount(){if(!this.countEl)return;let t=this.visible.length,e=this.typeFilter?`${t} ${this.typeFilter} event${t===1?"":"s"}`:`${t} event${t===1?"":"s"}`;this.shownCount===0||this.shownCount>=t?this.countEl.setText(e):this.countEl.setText(`Showing ${this.shownCount} of ${e}`)}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let s=this.shownCount;s{this.appendMore(Vt.PAGE),this.renderFooter()},t>Vt.PAGE){let s=this.footerEl.createEl("button",{text:`Load all (${t})`});s.onclick=()=>{this.appendMore(t),this.renderFooter()}}}shellAct(t){try{let e=this.app.vault.adapter.getFullPath?.(this.jsonlPath);if(!e)throw new Error("no full path");let{shell:s}=window.require("electron");t==="reveal"?s.showItemInFolder(e):s.openPath(e)}catch(e){new gt.Notice(`Couldn't ${t}: ${e.message}`)}}async exportCopy(){try{let t=(0,gt.moment)().format("YYYY-MM-DD_HHmmss"),e=this.jsonlPath.replace(/\/[^/]+$/,"")||"",s=e?`${e}/${t}-log.jsonl`:`${t}-log.jsonl`;return await this.app.vault.adapter.write(s,this.text),new gt.Notice(`Exported log \u2192 ${s}`),s}catch(t){return new gt.Notice(`Export failed: ${t.message}`),null}}clearLog(){new Mt(this.app,"Clear log?","A timestamped copy will be saved alongside the active log before it's truncated.","Export & clear",async t=>{if(!(!t||!await this.exportCopy())){try{await this.app.vault.adapter.write(this.jsonlPath,"")}catch(s){new gt.Notice(`Clear failed: ${s.message}`);return}this.text="",this.events=[],this.typeFilter=null,this.shownCount=0,this.refreshTypeFilter(),this.refreshList(),this.footerEl&&this.footerEl.empty(),new gt.Notice("Log cleared.")}}).open()}renderEvent(t){let e=document.createElement("div");e.className=`stashpad-log-row stashpad-log-${t.type}`;let s=(0,gt.moment)(t.ts).isValid()?(0,gt.moment)(t.ts).format("YYYY-MM-DD HH:mm:ss"):t.ts,i=document.createElement("span");i.className="stashpad-log-ts",i.textContent=s,e.appendChild(i);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=t.type,e.appendChild(n);let r=document.createElement("span");r.className="stashpad-log-author",r.textContent=t.author?t.author:"\u2014",t.author||r.classList.add("is-empty"),e.appendChild(r);let o=document.createElement("span");return o.className="stashpad-log-msg",o.textContent=this.describe(t),e.appendChild(o),e}describe(t){let e=t.payload??{};switch(t.type){case"create":return`Created "${e.path??t.id}" under ${e.parent??"?"}`;case"delete":{let s=Array.isArray(e.attachmentsRemoved)?e.attachmentsRemoved.length:0,i=e.mergedInto?` (merged into ${e.mergedInto})`:"";return`Deleted ${t.id}${i}${s?` \u2014 also removed ${s} attachment${s===1?"":"s"}`:""}`}case"missing":return`Missing: ${e.lastPath??t.id}`;case"parent_change":{let s=e.reason?` (${e.reason})`:"";return`Moved ${t.id} from ${e.from??"null"} \u2192 ${e.to??"null"}${s}`}case"rename":return`Renamed ${e.from??"?"} \u2192 ${e.to??"?"}`;case"reorder":{let s=e.count??1,i=e.dir??"?",n=e.parent??t.id??"?";return`Reordered ${s} note${s===1?"":"s"} (${i}) under ${n}`}case"complete":{let s=e.count??1,i=e.undo?" (undo)":e.redo?" (redo)":"";return`Marked ${s} note${s===1?"":"s"} complete${i}`}case"uncomplete":{let s=e.count??1,i=e.undo?" (undo)":e.redo?" (redo)":"";return`Unmarked ${s} note${s===1?"":"s"}${i}`}case"stash_export":{let s=e.noteCount??"?";return`Exported ${s} note${s===1?"":"s"} \u2192 ${e.path??"?"}`}case"stash_import":{let s=e.noteCount??"?",i=[];e.attachmentsWritten&&i.push(`${e.attachmentsWritten} attachment${e.attachmentsWritten===1?"":"s"}`),e.collisionsRenamed&&i.push(`${e.collisionsRenamed} renamed`);let n=i.length?` (${i.join(", ")})`:"";return`Imported ${s} note${s===1?"":"s"} from ${e.from??"?"} \u2192 ${e.into??"?"}${n}`}case"attachment_add":return`Added attachment ${e.path??t.id}`;case"attachment_remove":return`Removed attachment ${e.path??t.id}`;case"palette_color_add":return`Added palette color ${e.color??t.id}`;case"palette_color_remove":return`Removed palette color ${e.color??t.id}`;default:return JSON.stringify(e)}}onClose(){this.contentEl.empty()}};Vt.PAGE=100;qt=Vt,Zt=class extends gt.Modal{constructor(t,e,s,i,n,r){super(t);this.noteTitle=e;this.descendantCount=s;this.attachmentCount=i;this.offerAttachmentDelete=n;this.onChoose=r}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText(`Delete "${this.noteTitle}"?`);let t=[];this.descendantCount>0&&t.push(`${this.descendantCount} descendant note${this.descendantCount===1?"":"s"} will also be deleted.`),this.attachmentCount>0&&t.push(`${this.attachmentCount} attachment${this.attachmentCount===1?"":"s"} found across these notes.`),this.contentEl.createEl("p",{text:t.join(" ")});let e=this.offerAttachmentDelete&&this.attachmentCount>0;if(this.offerAttachmentDelete&&this.attachmentCount>0){let r=this.contentEl.createEl("label",{cls:"stashpad-modal-check"}),o=r.createEl("input",{type:"checkbox"});o.checked=e,o.onchange=()=>{e=o.checked},r.createSpan({text:" Also delete attachments"})}let s=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=s.createEl("button",{text:"Cancel"});i.onclick=()=>this.close();let n=s.createEl("button",{cls:"mod-warning",text:"Delete"});n.onclick=()=>{this.close(),this.onChoose(e)}}onClose(){this.contentEl.empty()}},oe=class extends gt.Modal{constructor(t,e,s,i){super(t);this.body=e;this.onSplitAtLine=s;this.onSplitAtChar=i;this.mode="line";this.cursorTextarea=null;this.lines=e.replace(/\r\n/g,` +"use strict";var hi=Object.create;var Se=Object.defineProperty;var pi=Object.getOwnPropertyDescriptor;var ui=Object.getOwnPropertyNames;var fi=Object.getPrototypeOf,mi=Object.prototype.hasOwnProperty;var Kt=(g,f)=>()=>(g&&(f=g(g=0)),f);var gi=(g,f)=>()=>(f||g((f={exports:{}}).exports,f),f.exports),ke=(g,f)=>{for(var t in f)Se(g,t,{get:f[t],enumerable:!0})},Ps=(g,f,t,e)=>{if(f&&typeof f=="object"||typeof f=="function")for(let s of ui(f))!mi.call(g,s)&&s!==t&&Se(g,s,{get:()=>f[s],enumerable:!(e=pi(f,s))||e.enumerable});return g};var vi=(g,f,t)=>(t=g!=null?hi(fi(g)):{},Ps(f||!g||!g.__esModule?Se(t,"default",{value:g,enumerable:!0}):t,g)),yi=g=>Ps(Se({},"__esModule",{value:!0}),g);function cs(g){return Array.isArray(g)?g.filter(f=>typeof f=="string"):typeof g=="string"?g.split(/[,\s]+/).filter(Boolean):[]}function zt(g,f){let t=f.replace(/^#/,"");return cs(g?.tags).some(e=>e.replace(/^#/,"")===t)}function ds(g,f){let t=f.replace(/^#/,""),e=cs(g.tags);e.some(s=>s.replace(/^#/,"")===t)||e.push(t),g.tags=e}function hs(g,f){let t=f.replace(/^#/,""),e=cs(g.tags).filter(s=>s.replace(/^#/,"")!==t);e.length?g.tags=e:delete g.tags}var mt,_t,Ht,R,ae,Ct=Kt(()=>{"use strict";mt="stashpad-view",_t="stashpad-panels",Ht="stashpad-detail",R="__root__";ae=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children"]});function wi(g,f){return g>12?g>=24?0:g:f==="am"?g===12?0:g:g===12?12:g+12}function Te(g,f){g.addClass("stashpad-when-pop-time");let t=f.seedPeriod,e=g.createDiv({cls:"stashpad-when-time-display"}),s=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});s.value=String(f.seedH),e.createSpan({cls:"stashpad-when-time-colon",text:":"});let i=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});i.value=String(f.seedM).padStart(2,"0");let n=e.createDiv({cls:"stashpad-when-time-period"}),r=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"AM"});r.type="button";let o=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"PM"});o.type="button";let a=()=>{r.toggleClass("is-active",t==="am"),o.toggleClass("is-active",t==="pm")};a(),r.addEventListener("mousedown",k=>k.preventDefault()),o.addEventListener("mousedown",k=>k.preventDefault()),r.addEventListener("click",k=>{k.preventDefault(),t="am",a()}),o.addEventListener("click",k=>{k.preventDefault(),t="pm",a()});let l=s;s.addEventListener("focus",()=>{l=s,s.select()}),i.addEventListener("focus",()=>{l=i,i.select()});let c=()=>{let C=(parseInt(s.value||"0",10)||0)>12;r.toggleClass("is-disabled",C),o.toggleClass("is-disabled",C),r.disabled=C,o.disabled=C},h=k=>{let C=k.value.replace(/\D/g,"").slice(0,2);if(C===""){k.value="",k===s&&c();return}let E=parseInt(C,10);k===s?E>24&&(E=24):E>59&&(E=59),k.value=String(E),k===s&&c()};for(let k of[s,i])k.addEventListener("input",()=>h(k));c();let u=()=>{let k=parseInt(s.value||"12",10)||12,C=parseInt(i.value||"0",10)||0,E=k>12;f.onFinalize({hours24:wi(k,t),minutes:C,raw:{hh:k,mm:C,period:t,is24:E}}),f.close()};f.setOnEnter?.(u);let d=[s,i,r,o],p=(k,C)=>{let E=d.indexOf(k);if(E===-1)return;let I=(E+C+d.length)%d.length;d[I].focus()},m=k=>{k.addEventListener("keydown",C=>{C.key==="Enter"?(C.preventDefault(),C.stopPropagation(),u()):C.key==="Escape"?(C.preventDefault(),C.stopPropagation(),f.close()):C.key==="Tab"&&(C.preventDefault(),C.stopPropagation(),p(k,C.shiftKey?-1:1))})},v=g.createDiv({cls:"stashpad-when-time-pad"}),y=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],b=null;for(let k of y){let C=v.createEl("button",{cls:"stashpad-when-time-padbtn"});C.type="button",k==="backspace"?(0,Ns.setIcon)(C,"delete"):k==="insert"?(C.setText("OK"),b=C):C.setText(k),k==="insert"&&C.addClass("is-go"),C.addEventListener("mousedown",E=>E.preventDefault()),C.addEventListener("click",E=>{if(E.preventDefault(),k==="insert"){u();return}if(k==="backspace"){l.value=l.value.slice(0,-1),h(l),l.focus();return}let I=l.selectionStart===0&&l.selectionEnd===l.value.length&&l.value.length>0,A=2,O=I||l.value.length>=A?k:l.value+k;l.value=O,h(l),l.focus(),l.setSelectionRange(l.value.length,l.value.length),l===s&&l.value.length>=A&&(i.focus(),i.select())})}b&&d.push(b);for(let k of d)m(k);s.focus(),s.select()}function Os(g){let{hh:f,mm:t,period:e,is24:s}=g.raw;return s?`${f}:${String(t).padStart(2,"0")}`:`${f}:${String(t).padStart(2,"0")}${e}`}var Ns,ps=Kt(()=>{"use strict";Ns=require("obsidian")});var Fe={};ke(Fe,{ColorPickerModal:()=>Vt,ConfirmDeleteModal:()=>Zt,ConfirmModal:()=>Ft,CustomColorModal:()=>xe,DueDatePickerModal:()=>ce,LogModal:()=>qt,NotificationHistoryModal:()=>de,SplitNoteModal:()=>le});var pt,jt,qt,Zt,le,xe,oe,Vt,Ft,ce,Ut,de,Gt=Kt(()=>{"use strict";pt=require("obsidian");ps();jt=class jt extends pt.Modal{constructor(t,e,s){super(t);this.text=e;this.jsonlPath=s;this.events=[];this.visible=[];this.shownCount=0;this.typeFilter=null;this.listEl=null;this.footerEl=null;this.countEl=null;this.filterSelEl=null}onOpen(){this.contentEl.empty(),this.titleEl.setText("Stashpad log"),this.modalEl.addClass("stashpad-log-modal"),this.events=[];for(let a of this.text.trim().split(/\r?\n/))if(a)try{this.events.push(JSON.parse(a))}catch{}this.events.reverse();let t=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});this.countEl=t.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=t.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setTypeFilter(this.filterSelEl.value||null),this.refreshTypeFilter();let e=t.createEl("button",{text:"Reveal JSONL"});e.onclick=()=>this.shellAct("reveal");let s=t.createEl("button",{text:"Open in default app"});s.onclick=()=>this.shellAct("open");let i=t.createEl("button",{text:"Copy raw JSONL"}),n=null;i.onclick=async()=>{await navigator.clipboard.writeText(this.text),i.setText("Copied"),n!=null&&window.clearTimeout(n),n=window.setTimeout(()=>{i.setText("Copy raw JSONL"),n=null},1500)};let r=t.createEl("button",{text:"Export copy"});r.onclick=()=>this.exportCopy();let o=t.createEl("button",{cls:"mod-warning",text:"Clear log"});o.onclick=()=>this.clearLog(),this.listEl=this.contentEl.createDiv({cls:"stashpad-log-list"}),this.refreshList(),this.footerEl=this.contentEl.createDiv({cls:"stashpad-log-footer"}),this.renderFooter()}refreshList(){if(this.listEl){if(this.visible=this.typeFilter?this.events.filter(t=>t.type===this.typeFilter):this.events.slice(),this.shownCount=0,this.listEl.empty(),!this.visible.length){this.listEl.createDiv({cls:"stashpad-log-empty",text:this.typeFilter?`No "${this.typeFilter}" events.`:"No events yet."}),this.updateCount();return}this.appendMore(jt.PAGE)}}setTypeFilter(t){(this.typeFilter??null)!==(t??null)&&(this.typeFilter=t,this.refreshList(),this.renderFooter())}refreshTypeFilter(){if(!this.filterSelEl)return;let t=this.filterSelEl;t.empty();let e=new Map;for(let n of this.events)e.set(n.type,(e.get(n.type)??0)+1);let s=[...e.entries()].sort((n,r)=>r[1]-n[1]||n[0].localeCompare(r[0])),i=t.createEl("option",{text:`All types (${this.events.length})`});i.value="";for(let[n,r]of s){let o=t.createEl("option",{text:`${n} (${r})`});o.value=n}this.typeFilter&&!e.has(this.typeFilter)&&(this.typeFilter=null),t.value=this.typeFilter??""}updateCount(){if(!this.countEl)return;let t=this.visible.length,e=this.typeFilter?`${t} ${this.typeFilter} event${t===1?"":"s"}`:`${t} event${t===1?"":"s"}`;this.shownCount===0||this.shownCount>=t?this.countEl.setText(e):this.countEl.setText(`Showing ${this.shownCount} of ${e}`)}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let s=this.shownCount;s{this.appendMore(jt.PAGE),this.renderFooter()},t>jt.PAGE){let s=this.footerEl.createEl("button",{text:`Load all (${t})`});s.onclick=()=>{this.appendMore(t),this.renderFooter()}}}shellAct(t){try{let e=this.app.vault.adapter.getFullPath?.(this.jsonlPath);if(!e)throw new Error("no full path");let{shell:s}=window.require("electron");t==="reveal"?s.showItemInFolder(e):s.openPath(e)}catch(e){new pt.Notice(`Couldn't ${t}: ${e.message}`)}}async exportCopy(){try{let t=(0,pt.moment)().format("YYYY-MM-DD_HHmmss"),e=this.jsonlPath.replace(/\/[^/]+$/,"")||"",s=e?`${e}/${t}-log.jsonl`:`${t}-log.jsonl`;return await this.app.vault.adapter.write(s,this.text),new pt.Notice(`Exported log \u2192 ${s}`),s}catch(t){return new pt.Notice(`Export failed: ${t.message}`),null}}clearLog(){new Ft(this.app,"Clear log?","A timestamped copy will be saved alongside the active log before it's truncated.","Export & clear",async t=>{if(!(!t||!await this.exportCopy())){try{await this.app.vault.adapter.write(this.jsonlPath,"")}catch(s){new pt.Notice(`Clear failed: ${s.message}`);return}this.text="",this.events=[],this.typeFilter=null,this.shownCount=0,this.refreshTypeFilter(),this.refreshList(),this.footerEl&&this.footerEl.empty(),new pt.Notice("Log cleared.")}}).open()}renderEvent(t){let e=document.createElement("div");e.className=`stashpad-log-row stashpad-log-${t.type}`;let s=(0,pt.moment)(t.ts).isValid()?(0,pt.moment)(t.ts).format("YYYY-MM-DD HH:mm:ss"):t.ts,i=document.createElement("span");i.className="stashpad-log-ts",i.textContent=s,e.appendChild(i);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=t.type,e.appendChild(n);let r=document.createElement("span");r.className="stashpad-log-author",r.textContent=t.author?t.author:"\u2014",t.author||r.classList.add("is-empty"),e.appendChild(r);let o=document.createElement("span");return o.className="stashpad-log-msg",o.textContent=this.describe(t),e.appendChild(o),e}describe(t){let e=t.payload??{};switch(t.type){case"create":return`Created "${e.path??t.id}" under ${e.parent??"?"}`;case"delete":{let s=Array.isArray(e.attachmentsRemoved)?e.attachmentsRemoved.length:0,i=e.mergedInto?` (merged into ${e.mergedInto})`:"";return`Deleted ${t.id}${i}${s?` \u2014 also removed ${s} attachment${s===1?"":"s"}`:""}`}case"missing":return`Missing: ${e.lastPath??t.id}`;case"parent_change":{let s=e.reason?` (${e.reason})`:"";return`Moved ${t.id} from ${e.from??"null"} \u2192 ${e.to??"null"}${s}`}case"rename":return`Renamed ${e.from??"?"} \u2192 ${e.to??"?"}`;case"reorder":{let s=e.count??1,i=e.dir??"?",n=e.parent??t.id??"?";return`Reordered ${s} note${s===1?"":"s"} (${i}) under ${n}`}case"complete":{let s=e.count??1,i=e.undo?" (undo)":e.redo?" (redo)":"";return`Marked ${s} note${s===1?"":"s"} complete${i}`}case"uncomplete":{let s=e.count??1,i=e.undo?" (undo)":e.redo?" (redo)":"";return`Unmarked ${s} note${s===1?"":"s"}${i}`}case"stash_export":{let s=e.noteCount??"?";return`Exported ${s} note${s===1?"":"s"} \u2192 ${e.path??"?"}`}case"stash_import":{let s=e.noteCount??"?",i=[];e.attachmentsWritten&&i.push(`${e.attachmentsWritten} attachment${e.attachmentsWritten===1?"":"s"}`),e.collisionsRenamed&&i.push(`${e.collisionsRenamed} renamed`);let n=i.length?` (${i.join(", ")})`:"";return`Imported ${s} note${s===1?"":"s"} from ${e.from??"?"} \u2192 ${e.into??"?"}${n}`}case"attachment_add":return`Added attachment ${e.path??t.id}`;case"attachment_remove":return`Removed attachment ${e.path??t.id}`;case"palette_color_add":return`Added palette color ${e.color??t.id}`;case"palette_color_remove":return`Removed palette color ${e.color??t.id}`;default:return JSON.stringify(e)}}onClose(){this.contentEl.empty()}};jt.PAGE=100;qt=jt,Zt=class extends pt.Modal{constructor(t,e,s,i,n,r){super(t);this.noteTitle=e;this.descendantCount=s;this.attachmentCount=i;this.offerAttachmentDelete=n;this.onChoose=r}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText(`Delete "${this.noteTitle}"?`);let t=[];this.descendantCount>0&&t.push(`${this.descendantCount} descendant note${this.descendantCount===1?"":"s"} will also be deleted.`),this.attachmentCount>0&&t.push(`${this.attachmentCount} attachment${this.attachmentCount===1?"":"s"} found across these notes.`),this.contentEl.createEl("p",{text:t.join(" ")});let e=this.offerAttachmentDelete&&this.attachmentCount>0;if(this.offerAttachmentDelete&&this.attachmentCount>0){let r=this.contentEl.createEl("label",{cls:"stashpad-modal-check"}),o=r.createEl("input",{type:"checkbox"});o.checked=e,o.onchange=()=>{e=o.checked},r.createSpan({text:" Also delete attachments"})}let s=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=s.createEl("button",{text:"Cancel"});i.onclick=()=>this.close();let n=s.createEl("button",{cls:"mod-warning",text:"Delete"});n.onclick=()=>{this.close(),this.onChoose(e)}}onClose(){this.contentEl.empty()}},le=class extends pt.Modal{constructor(t,e,s,i){super(t);this.body=e;this.onSplitAtLine=s;this.onSplitAtChar=i;this.mode="line";this.cursorTextarea=null;this.lines=e.replace(/\r\n/g,` `).split(` -`),this.lineCursorIdx=Math.max(1,Math.min(this.lines.length-1,Math.floor(this.lines.length/2))),this.lines.length<2&&(this.mode="cursor")}onOpen(){this.titleEl.setText("Split note"),this.modalEl.addClass("stashpad-split-modal"),this.render(),this.scope.register([],"Tab",t=>{this.lines.length<2||(t.preventDefault(),this.mode=this.mode==="line"?"cursor":"line",this.render())}),this.scope.register([],"Enter",t=>{this.mode==="line"&&(t.preventDefault(),this.commitLine())}),this.scope.register(["Mod"],"Enter",t=>{this.mode==="cursor"&&(t.preventDefault(),this.commitCursor())}),this.scope.register([],"ArrowUp",t=>{this.mode==="line"&&(t.preventDefault(),this.lineCursorIdx=Math.max(1,this.lineCursorIdx-1),this.render())}),this.scope.register([],"ArrowDown",t=>{this.mode==="line"&&(t.preventDefault(),this.lineCursorIdx=Math.min(this.lines.length-1,this.lineCursorIdx+1),this.render())})}commitLine(){let t=this.lineCursorIdx;this.close(),this.onSplitAtLine(t)}commitCursor(){let t=this.cursorTextarea;if(!t)return;let e=t.selectionStart;if(e<=0||e>=t.value.length){new gt.Notice("Move the cursor inside the text \u2014 neither end can be empty.");return}this.close(),this.onSplitAtChar(e)}render(){this.contentEl.empty();let t=this.contentEl.createDiv({cls:"stashpad-split-toggle-bar"});if(this.lines.length>=2){let n=t.createEl("button",{text:"Line split",cls:"stashpad-split-mode-btn"});this.mode==="line"&&n.addClass("is-active"),n.onclick=()=>{this.mode="line",this.render()}}let e=t.createEl("button",{text:"Cursor split",cls:"stashpad-split-mode-btn"});this.mode==="cursor"&&e.addClass("is-active"),e.onclick=()=>{this.mode="cursor",this.render()};let s=t.createEl("button",{text:"Split",cls:"stashpad-split-confirm-btn mod-cta"});s.onmousedown=n=>n.preventDefault(),s.onclick=()=>{this.mode==="line"?this.commitLine():this.commitCursor()},this.mode==="line"?this.renderLineMode():this.renderCursorMode();let i=this.contentEl.createDiv({cls:"stashpad-split-help"});gt.Platform.isMobile?i.setText(this.mode==="line"?"Tap a line to position the divider, then Split.":"Tap inside the text to position the cursor, then Split."):i.setText(this.mode==="line"?"\u2191/\u2193 pick split line \xB7 Enter or Split confirm \xB7 Tab \u2192 cursor mode \xB7 Esc cancel \xB7 Children stay with the first part":"Click or arrow to position cursor \xB7 Mod+Enter or Split confirm \xB7 Tab \u2192 line mode \xB7 Esc cancel \xB7 Children stay with the first part")}renderLineMode(){let t=this.contentEl.createDiv({cls:"stashpad-split-list"});for(let e=0;e{let i=Math.max(1,Math.min(this.lines.length-1,e));i!==this.lineCursorIdx&&(this.lineCursorIdx=i,this.render())}}}renderCursorMode(){let e=this.contentEl.createDiv({cls:"stashpad-split-cursor-wrap"}).createEl("textarea",{cls:"stashpad-split-cursor-ta"});e.value=this.body,e.readOnly=!1,this.cursorTextarea=e;let s=parseFloat(getComputedStyle(e).lineHeight)||22,i=gt.Platform.isMobile?3:12,n=2,r=()=>{e.style.height="auto";let o=Math.min(e.scrollHeight,s*i+16);e.style.height=`${Math.max(o,s*n+16)}px`};requestAnimationFrame(()=>{r();let o=Math.floor(e.value.length/2);e.focus(),e.setSelectionRange(o,o)}),e.addEventListener("input",r)}onClose(){this.cursorTextarea=null,this.contentEl.empty()}},Ce=class extends gt.Modal{constructor(t,e,s){super(t);this.onResult=s;this.delivered=!1;this.value=e&&/^#[0-9a-f]{6}$/i.test(e)?e:"#888888"}onOpen(){this.contentEl.empty(),this.titleEl.setText("Custom color"),this.modalEl.addClass("stashpad-custom-color-modal");let t=this.contentEl.createDiv({cls:"stashpad-custom-color-row"}),e=t.createDiv({cls:"stashpad-custom-color-preview"});e.style.background=this.value;let s=t.createEl("input",{type:"color"});s.value=this.value,s.addClass("stashpad-custom-color-wheel"),e.onclick=()=>s.click();let i=t.createEl("input",{type:"text"});i.addClass("stashpad-custom-color-hex"),i.placeholder="#RRGGBB",i.value=this.value,i.maxLength=7;let n=c=>{let d=c.startsWith("#")?c:"#"+c;/^#[0-9a-f]{6}$/i.test(d)&&(this.value=d,e.style.background=d,s.value=d,i.value!==d&&(i.value=d))};s.oninput=()=>n(s.value),i.oninput=()=>n(i.value);let r=this.contentEl.createDiv({cls:"stashpad-color-footer"}),o=r.createEl("button",{text:"Cancel"});o.onclick=()=>{this.delivered=!0,this.close()};let a=r.createEl("button",{cls:"mod-cta",text:"Save"});a.title="Apply this color to the selection (without adding to your palette).",a.onclick=()=>this.commit({addToPalette:!1});let l=r.createEl("button",{cls:"mod-cta",text:"Add to palette"});l.title="Apply and save this color so it appears as a tile next time.",l.onclick=()=>this.commit({addToPalette:!0}),this.scope.register([],"Enter",c=>{c.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",c=>{c.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>i.focus())}commit(t){this.delivered=!0,this.close(),this.onResult(this.value,t)}onClose(){this.delivered||(this.delivered=!0,this.onResult(this.value,{addToPalette:!1})),this.contentEl.empty()}},ae=class ae extends gt.Modal{constructor(t,e,s,i,n){super(t);this.currentColor=e;this.customPalette=s;this.onPick=i;this.onDeleteCustom=n;this.focusIdx=-1;this.items=[]}onOpen(){this.contentEl.empty(),this.titleEl.setText("Pick a color"),this.modalEl.addClass("stashpad-color-modal");let t=this.contentEl.createDiv({cls:"stashpad-color-grid"});this.items=[];let e=t.createDiv({cls:"stashpad-color-tile stashpad-color-none"});e.title="No color",e.onclick=()=>this.activate(0),this.items.push({kind:"none",color:null,el:e});let s=[...ae.DEFAULT_PALETTE,...this.customPalette];for(let o of s){let a=t.createDiv({cls:"stashpad-color-tile"});a.style.background=o,a.title=o;let l=!ae.DEFAULT_PALETTE.some(d=>d.toLowerCase()===o.toLowerCase()),c=this.items.length;if(a.onclick=()=>this.activate(c),l&&this.onDeleteCustom){let d=a.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});d.title="Remove from palette",d.onclick=p=>{p.stopPropagation(),this.handleDelete(o)}}this.items.push({kind:l?"custom":"preset",color:o,el:a})}let i=t.createDiv({cls:"stashpad-color-tile stashpad-color-add"});i.title="Custom color\u2026";let n=this.items.length;i.onclick=()=>this.activate(n),this.items.push({kind:"add",color:null,el:i});let r=this.items.findIndex(o=>this.currentColor===null?o.kind==="none":this.currentColor?o.color!==null&&o.color.toLowerCase()===this.currentColor.toLowerCase():!1);this.focusIdx=r>=0?r:0,this.refreshActive(),this.scope.register([],"ArrowRight",o=>{o.preventDefault(),this.moveFocus(1)}),this.scope.register([],"ArrowLeft",o=>{o.preventDefault(),this.moveFocus(-1)}),this.scope.register([],"ArrowDown",o=>{o.preventDefault(),this.moveFocus(this.columns())}),this.scope.register([],"ArrowUp",o=>{o.preventDefault(),this.moveFocus(-this.columns())}),this.scope.register([],"Enter",o=>{o.preventDefault(),this.activate(this.focusIdx)}),requestAnimationFrame(()=>this.modalEl.focus())}activate(t){if(t<0||t>=this.items.length)return;this.focusIdx=t,this.refreshActive();let e=this.items[t];if(e.kind==="add"){this.close(),new Ce(this.app,this.currentColor,(s,i)=>{this.onPick(s,i)}).open();return}this.close(),this.onPick(e.color,{addToPalette:!1})}columns(){if(!this.items.length)return 1;let t=this.items[0].el.parentElement;if(!t)return 1;let e=t.getBoundingClientRect(),s=this.items[0].el.getBoundingClientRect();if(s.width<=0)return 1;let i=s.top,n=0;for(let r of this.items){let o=r.el.getBoundingClientRect();if(Math.abs(o.top-i)<1)n++;else break}return Math.max(1,n)}async handleDelete(t){if(this.onDeleteCustom)try{let e=await this.onDeleteCustom(t);this.customPalette=Array.isArray(e)?e:this.customPalette.filter(s=>s.toLowerCase()!==t.toLowerCase()),this.onOpen()}catch(e){console.warn("Stashpad: palette delete failed",e)}}moveFocus(t){if(!this.items.length)return;let e=Math.max(0,Math.min(this.items.length-1,this.focusIdx+t));this.focusIdx=e,this.refreshActive()}refreshActive(){for(let t=0;t{this.didChoose=!0,this.close(),this.onChoose(!1)};let i=e.createEl("button",{cls:"mod-cta",text:this.confirmText});i.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>i.focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}},le=class extends gt.Modal{constructor(t,e,s){super(t);this.current=e;this.onPick=s;this.didChoose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Set due date");let t=null;if(this.current){let g=Date.parse(this.current);Number.isNaN(g)||(t=new Date(g))}let e=this.contentEl.createDiv({cls:"stashpad-due-picker"}),s=e.createDiv({cls:"stashpad-due-fields"}),i=s.createDiv({cls:"stashpad-due-field"}),n=i.createSpan({cls:"stashpad-due-field-icon"});(0,gt.setIcon)(n,"calendar");let r=i.createEl("input",{type:"date",cls:"stashpad-due-date"}),o=s.createDiv({cls:"stashpad-due-field"}),a=o.createSpan({cls:"stashpad-due-field-icon"});(0,gt.setIcon)(a,"clock");let l=o.createEl("input",{type:"time",cls:"stashpad-due-time"});n.onclick=()=>{try{r.showPicker?.()}catch{}},a.onclick=()=>{try{l.showPicker?.()}catch{}},t&&(r.value=this.toDateValue(t),l.value=this.toTimeValue(t));let c=e.createDiv({cls:"stashpad-due-grid"}),d=(g,y)=>{let S=c.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:g});S.onclick=()=>{let k=y();r.value=this.toDateValue(k),l.value||(l.value=this.toTimeValue(k))}},p=g=>(g.setHours(9,0,0,0),g);d("Today",()=>p(this.startOfTodayLocal())),d("Tomorrow",()=>{let g=this.startOfTodayLocal();return g.setDate(g.getDate()+1),p(g)}),d("Next week",()=>{let g=this.startOfTodayLocal();return g.setDate(g.getDate()+7),p(g)});let h=c.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});h.onclick=()=>{this.didChoose=!0,this.close(),this.onPick(null)};let u=c.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});u.onclick=()=>{this.didChoose=!0,this.close()};let m=c.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});m.onclick=()=>{if(!r.value){new gt.Notice("Pick a date first (or use Clear).");return}let[g,y,S]=r.value.split("-").map(E=>parseInt(E,10)),k=9,x=0;if(l.value){let[E,D]=l.value.split(":").map($=>parseInt($,10));k=E,x=D}let I=new Date(g,y-1,S,k,x,0,0);this.didChoose=!0,this.close(),this.onPick(I.toISOString())},requestAnimationFrame(()=>r.focus())}onClose(){this.contentEl.empty(),this.didChoose}startOfTodayLocal(){let t=new Date;return t.setHours(0,0,0,0),t}toDateValue(t){let e=t.getFullYear(),s=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${e}-${s}-${i}`}toTimeValue(t){let e=String(t.getHours()).padStart(2,"0"),s=String(t.getMinutes()).padStart(2,"0");return`${e}:${s}`}},Yt=class Yt extends gt.Modal{constructor(t,e,s,i=null,n){super(t);this.service=e;this.openLog=s;this.currentAuthorId=i;this.getNoteAuthorIds=n;this.records=[];this.visible=[];this.shownCount=0;this.categoryFilter=null;this.listEl=null;this.footerEl=null;this.countEl=null;this.filterSelEl=null;this.unsubscribe=null;this.authorFilter="all";this.authorSelEl=null}onOpen(){this.contentEl.empty(),this.titleEl.setText("Stashpad notification history"),this.modalEl.addClass("stashpad-log-modal"),this.modalEl.addClass("stashpad-notif-history-modal"),this.records=this.service.recent();let t=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=t.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=t.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setCategoryFilter(this.filterSelEl.value||null),this.refreshCategoryFilter(),this.authorSelEl=t.createEl("select",{cls:"stashpad-log-type-filter stashpad-notif-author-filter"}),this.authorSelEl.onchange=()=>this.setAuthorFilter(this.authorSelEl.value||"all"),this.refreshAuthorFilter(),this.openLog){let s=t.createEl("button",{text:"Open log"});s.title="Open the per-folder Stashpad log for the most recent notification's folder.",s.onclick=()=>{let i=this.records.find(n=>!!n.folder);this.openLog?.(i?.folder)}}let e=t.createEl("button",{cls:"mod-warning",text:"Clear history"});e.onclick=()=>{new Mt(this.app,"Clear notification history?",`This will permanently remove all ${this.records.length} stored notifications from the history. The current toasts on screen are unaffected. This can't be undone.`,"Clear history",s=>{s&&this.service.clearHistory()}).open()},this.listEl=this.contentEl.createDiv({cls:"stashpad-log-list"}),this.refreshList(),this.footerEl=this.contentEl.createDiv({cls:"stashpad-log-footer"}),this.renderFooter(),this.unsubscribe=this.service.onChange(()=>{this.records=this.service.recent(),this.refreshCategoryFilter(),this.refreshAuthorFilter(),this.refreshList(),this.renderFooter()})}setAuthorFilter(t){this.authorFilter!==t&&(this.authorFilter=t,this.refreshList(),this.renderFooter())}refreshAuthorFilter(){if(!this.authorSelEl)return;let t=this.authorSelEl;t.empty(),t.createEl("option",{text:"All authors"}).value="all",this.currentAuthorId&&(t.createEl("option",{text:"Me"}).value="me"),t.createEl("option",{text:"Cross-author"}).value="cross";let e=new Set;for(let i of this.records)i.authorId&&i.authorId!==this.currentAuthorId&&e.add(i.authorId);if(e.size>0){let i=t.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});i.disabled=!0;for(let n of[...e].sort())t.createEl("option",{text:n}).value=n}new Set(["all","cross",...this.currentAuthorId?["me"]:[],...e]).has(this.authorFilter)||(this.authorFilter="all"),t.value=this.authorFilter}isCrossAuthor(t){let e=t.authorId??null;if(!e)return!1;for(let s of t.affectedAuthorIds??[])if(s&&s!==e)return!0;if(!this.getNoteAuthorIds)return!1;for(let s of t.affectedIds){let i=this.getNoteAuthorIds(s);for(let n of i)if(n&&n!==e)return!0}return!1}onClose(){this.unsubscribe?.(),this.unsubscribe=null,this.contentEl.empty()}setCategoryFilter(t){(this.categoryFilter??null)!==(t??null)&&(this.categoryFilter=t,this.refreshList(),this.renderFooter())}refreshCategoryFilter(){if(!this.filterSelEl)return;let t=this.filterSelEl;t.empty();let e=new Map;for(let n of this.records)e.set(n.category,(e.get(n.category)??0)+1);let s=[...e.entries()].sort((n,r)=>r[1]-n[1]||n[0].localeCompare(r[0])),i=t.createEl("option",{text:`All categories (${this.records.length})`});i.value="";for(let[n,r]of s){let o=t.createEl("option",{text:`${n} (${r})`});o.value=n}this.categoryFilter&&!e.has(this.categoryFilter)&&(this.categoryFilter=null),t.value=this.categoryFilter??""}refreshList(){if(this.listEl){if(this.visible=this.records.filter(t=>{if(this.categoryFilter&&t.category!==this.categoryFilter)return!1;switch(this.authorFilter){case"all":return!0;case"me":return!!this.currentAuthorId&&t.authorId===this.currentAuthorId;case"cross":return this.isCrossAuthor(t);default:return t.authorId===this.authorFilter}}),this.shownCount=0,this.listEl.empty(),!this.visible.length){this.listEl.createDiv({cls:"stashpad-log-empty",text:this.categoryFilter?`No "${this.categoryFilter}" notifications.`:"No notifications yet."}),this.updateCount();return}this.appendMore(Yt.PAGE)}}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let s=this.shownCount;s0){let l=s.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let c of e.actionLabels){let d=l.createSpan({cls:"stashpad-notif-action-chip"});d.setText(c),d.title="Action button was shown on the original toast (handler not retained)."}}}updateCount(){if(!this.countEl)return;let t=this.visible.length,e=this.categoryFilter?`${t} ${this.categoryFilter} notification${t===1?"":"s"}`:`${t} notification${t===1?"":"s"}`;this.shownCount===0||this.shownCount>=t?this.countEl.setText(e):this.countEl.setText(`Showing ${this.shownCount} of ${e}`)}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let t=this.visible.length-this.shownCount;if(t<=0)return;let e=this.footerEl.createEl("button",{text:`Load ${Math.min(Yt.PAGE,t)} more`});if(e.onclick=()=>{this.appendMore(Yt.PAGE),this.renderFooter()},t>Yt.PAGE){let s=this.footerEl.createEl("button",{text:`Load all (${t})`});s.onclick=()=>{this.appendMore(t),this.renderFooter()}}}};Yt.PAGE=100;ce=Yt});var Be={};Se(Be,{newId:()=>Ft});function Ft(v=6){let f="",t=new Uint8Array(v);crypto.getRandomValues(t);for(let e=0;e{"use strict";Os="abcdefghijkmnpqrstuvwxyz23456789"});function Bt(v,f=It){let t=f instanceof Set?f:new Set(f.map(r=>r.toLowerCase())),e=(v.split(/\r?\n/).find(r=>r.trim().length>0)??"").trim();if(!e)return"Untitled";let i=e.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(r=>r&&!t.has(r.toLowerCase())).map(r=>r.length>=2&&/^[A-Z0-9]+$/.test(r)?r:r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()),n="";for(let r of i){let o=n?`${n}-${r}`:r;if(o.length>50)break;n=o}return n||"Untitled"}function Ht(v,f){return`${v}-${f}.md`}function Qt(v){let f=v.match(/-([a-z0-9]{4,12})$/);return f?f[1]:null}var It,pe=ne(()=>{"use strict";It=["a","an","the","and","or","but","if","then","else","of","in","on","at","to","for","with","by","from","as","is","are","was","were","be","been","being","i","you","he","she","it","we","they","this","that","these","those","my","your","our","their","do","does","did","so","just","very","really","im"]});var je={};Se(je,{JdBuildConfirmModal:()=>ue,buildJdIndexNotes:()=>ps,buildJdIndexPreview:()=>ze,buildJdPreviewNotice:()=>We,scanForJdNotes:()=>te});function hs(v,f){if(/^\d+-\d+$/.test(v))return null;if(v.includes(".")){let e=v.split(".").slice(0,-1).join(".");return f.has(e)?e:hs(e,f)}if(/^\d+$/.test(v)){let t=parseInt(v,10);for(let e of f){let s=e.match(/^(\d+)-(\d+)$/);if(!s)continue;let i=parseInt(s[1],10),n=parseInt(s[2],10);if(t>=i&&t<=n)return e}return null}return null}function te(v,f,t){let e=v.vault.getMarkdownFiles(),s=vi(e,t),i=t.jdIndexIncludeStashpadFolders===!0,n=i?new Set:new Set(f.discoverStashpadFolders()),r=h=>i?!1:Array.from(n).some(u=>h===u||h.startsWith(u+"/")),o=[],a=[],l=[];for(let h of s){let u=h.parent?.path?.replace(/\/+$/,"")??"";if(r(u)){l.push(h);continue}let m=h.basename.match($s);m?o.push({prefix:m[1],segments:m[1].split("."),title:m[2],file:h,folder:null}):a.push(h)}let c=(t.jdIndexScope??"vault")==="folder"?(t.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",d=h=>{let u=h.path.replace(/\/+$/,"");if(!(c&&u&&u!==c&&!u.startsWith(c+"/"))){if(u&&!r(u)){let m=h.name.match($s);m&&o.push({prefix:m[1],segments:m[1].split("."),title:m[2],file:null,folder:h})}}for(let m of h.children)m instanceof St.TFolder&&d(m)};d(v.vault.getRoot());let p=t.jdIndexSort??"natural";return o.sort((h,u)=>yi(h,u,p)),{indexed:o,nonIndex:a,skippedStashpadNotes:l}}async function ze(v,f,t){let e=us(t.jdIndexStashpadFolder??"");if(!e)return{...te(v,f,t),previewPath:null,error:"no-dest"};let s=te(v,f,t),i=gi(v,e);if(!i)return{...s,previewPath:null,error:"no-home"};let n=wi(s.indexed,s.nonIndex,s.skippedStashpadNotes),o=(await v.vault.read(i)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),a=o?`${o[0]}${n}`:n;return await v.vault.modify(i,a),{...s,previewPath:i.path}}function gi(v,f){let t=v.vault.getAbstractFileByPath(f);if(!(t instanceof St.TFolder))return null;for(let e of t.children){if(!(e instanceof St.TFile)||e.extension!=="md")continue;if((v.metadataCache.getFileCache(e)?.frontmatter??{}).id===B)return e}return null}async function ps(v,f,t){let e=us(t.jdIndexStashpadFolder??"");if(!e)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(f.discoverStashpadFolders()).has(e))return{created:0,updated:0,skipped:0,destFolder:e,error:"dest-not-stashpad"};let i=te(v,f,t),n=new Map;for(let g of i.indexed)n.set(g.prefix,g);for(let g of i.indexed)if(g.prefix.includes("."))for(let y=1;y{a.push(g);for(let y of o.get(g)??[])l(y)};for(let g of r)l(g);let c=new Map,d=v.vault.getAbstractFileByPath(e);if(d instanceof St.TFolder)for(let g of d.children){if(!(g instanceof St.TFile)||g.extension!=="md")continue;let y=v.metadataCache.getFileCache(g)?.frontmatter??{};typeof y.jdPrefix=="string"&&c.set(y.jdPrefix,g)}let p=new Map,h=0,u=0,m=0;for(let g of a){let y=n.get(g)??null,S=hs(g,new Set(n.keys())),k=S?p.get(S)??B:B,x=y?`${g} ${y.title}`:g,I=y?.file?`[[${y.file.basename}]]`:"",E=I?`${I} -`:`${x} -`,D=c.get(g);if(D){try{let $=null;await v.fileManager.processFrontMatter(D,H=>{H.jdPrefix=g,k&&(H.parent=k),(!H.id||typeof H.id!="string")&&(H.id=Ft()),H.created||(H.created=new Date().toISOString()),H.attachments||(H.attachments=[]),$=H.id});let P=(await v.vault.read(D)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),b=P?`${P[0]}${E}`:E;await v.vault.modify(D,b),$&&p.set(g,$),u++}catch($){console.error("[stashpad] buildJdIndexNotes: update failed",$),m++}continue}try{let $=Ft();p.set(g,$);let F=Bt(x,t.slugStopWords),P=Ht(F,$),b=`${e}/${P}`,H=["---",`id: ${$}`,`parent: ${k}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${g}"`,"---",""].join(` -`);await v.vault.create(b,H+E),h++}catch($){console.error("[stashpad] buildJdIndexNotes: create failed for",g,$),m++}}return{created:h,updated:u,skipped:m,destFolder:e}}function us(v){return(v||"").trim().replace(/^\/+|\/+$/g,"")}function vi(v,f){if((f.jdIndexScope??"vault")==="vault")return v;let t=us(f.jdIndexScopeFolder??"");return t?v.filter(e=>{let s=e.parent?.path?.replace(/\/+$/,"")??"";return s===t||s.startsWith(t+"/")}):v}function yi(v,f,t){if(t==="created"){let e=v.file.stat?.ctime??0,s=f.file.stat?.ctime??0;if(e!==s)return e-s}return Bs(v.segments,f.segments)}function Rs(v,f){let t=v.match(/^(\d+)-(\d+)$/),e=f.match(/^(\d+)-(\d+)$/),s=t?[t[1]]:v.split("."),i=e?[e[1]]:f.split(".");return Bs(s,i)}function Bs(v,f){let t=Math.min(v.length,f.length);for(let e=0;e{i.set(r,o);for(let a of e.get(r)??[])n(a,o+1)};for(let r of s)n(r,0);return{roots:s,childrenOf:e,depthOf:i}}function wi(v,f,t){let e=[],s=i=>"#".repeat(Math.min(i+1,6));if(e.push("# Indexed"),e.push(""),v.length===0){let i=t.length>0?`_No notes matched. ${t.length} note${t.length===1?" was":"s were"} excluded because they live inside a Stashpad folder \u2014 toggle "Include Stashpad folders in scan" in Settings \u2192 JD Index Builder if you want them included._`:"_No notes matched the JD-prefix convention. Check Scope and Designated folder in Settings \u2192 JD Index Builder._";e.push(i)}else{let i=new Map;for(let l of v)i.set(l.prefix,l);for(let l of v)if(l.prefix.includes("."))for(let c=1;c{let c=i.get(l),d=o.get(l)??0,p=" ".repeat(d),h=s(d),u=c?.folder?` ${c.title} _(folder)_`:(c?.file,"");c?.file?e.push(`${p}- ${h} [[${c.file.basename}|${c.prefix} ${c.title}]]`):c?.folder?e.push(`${p}- ${h} ${c.prefix}${u}`):e.push(`${p}- ${h} ${l}`);for(let m of r.get(l)??[])a(m)};for(let l of n)a(l)}if(f.length>0){e.push(""),e.push(`# Non-indexed (${f.length})`),e.push(""),e.push("_These notes don't match the JD-prefix convention. Rename them to ` ` and re-run to include them._"),e.push("");for(let i of f)e.push(`- # [[${i.basename}]] \xB7 \`${i.path}\``)}if(t.length>0){let i=new Map;for(let r of t){let o=r.parent?.path?.replace(/\/+$/,"")??"";i.set(o,(i.get(o)??0)+1)}let n=Array.from(i.entries()).sort((r,o)=>r[0].localeCompare(o[0]));e.push(""),e.push(`# Excluded folders (${n.length})`),e.push(""),e.push(`_Stashpad folders are excluded by default so the index doesn't reference itself. Toggle "Include Stashpad folders in scan" in Settings \u2192 JD Index Builder to include them._`),e.push("");for(let[r,o]of n)e.push(`- # All ${o} file${o===1?"":"s"} in \`${r||"(vault root)"}\``)}return e.join(` +`),this.lineCursorIdx=Math.max(1,Math.min(this.lines.length-1,Math.floor(this.lines.length/2))),this.lines.length<2&&(this.mode="cursor")}onOpen(){this.titleEl.setText("Split note"),this.modalEl.addClass("stashpad-split-modal"),this.render(),this.scope.register([],"Tab",t=>{this.lines.length<2||(t.preventDefault(),this.mode=this.mode==="line"?"cursor":"line",this.render())}),this.scope.register([],"Enter",t=>{this.mode==="line"&&(t.preventDefault(),this.commitLine())}),this.scope.register(["Mod"],"Enter",t=>{this.mode==="cursor"&&(t.preventDefault(),this.commitCursor())}),this.scope.register([],"ArrowUp",t=>{this.mode==="line"&&(t.preventDefault(),this.lineCursorIdx=Math.max(1,this.lineCursorIdx-1),this.render())}),this.scope.register([],"ArrowDown",t=>{this.mode==="line"&&(t.preventDefault(),this.lineCursorIdx=Math.min(this.lines.length-1,this.lineCursorIdx+1),this.render())})}commitLine(){let t=this.lineCursorIdx;this.close(),this.onSplitAtLine(t)}commitCursor(){let t=this.cursorTextarea;if(!t)return;let e=t.selectionStart;if(e<=0||e>=t.value.length){new pt.Notice("Move the cursor inside the text \u2014 neither end can be empty.");return}this.close(),this.onSplitAtChar(e)}render(){this.contentEl.empty();let t=this.contentEl.createDiv({cls:"stashpad-split-toggle-bar"});if(this.lines.length>=2){let n=t.createEl("button",{text:"Line split",cls:"stashpad-split-mode-btn"});this.mode==="line"&&n.addClass("is-active"),n.onclick=()=>{this.mode="line",this.render()}}let e=t.createEl("button",{text:"Cursor split",cls:"stashpad-split-mode-btn"});this.mode==="cursor"&&e.addClass("is-active"),e.onclick=()=>{this.mode="cursor",this.render()};let s=t.createEl("button",{text:"Split",cls:"stashpad-split-confirm-btn mod-cta"});s.onmousedown=n=>n.preventDefault(),s.onclick=()=>{this.mode==="line"?this.commitLine():this.commitCursor()},this.mode==="line"?this.renderLineMode():this.renderCursorMode();let i=this.contentEl.createDiv({cls:"stashpad-split-help"});pt.Platform.isMobile?i.setText(this.mode==="line"?"Tap a line to position the divider, then Split.":"Tap inside the text to position the cursor, then Split."):i.setText(this.mode==="line"?"\u2191/\u2193 pick split line \xB7 Enter or Split confirm \xB7 Tab \u2192 cursor mode \xB7 Esc cancel \xB7 Children stay with the first part":"Click or arrow to position cursor \xB7 Mod+Enter or Split confirm \xB7 Tab \u2192 line mode \xB7 Esc cancel \xB7 Children stay with the first part")}renderLineMode(){let t=this.contentEl.createDiv({cls:"stashpad-split-list"});for(let e=0;e<this.lines.length;e++){e===this.lineCursorIdx&&t.createDiv({cls:"stashpad-split-divider",text:"\u2500\u2500 split here \u2500\u2500"});let s=t.createDiv({cls:"stashpad-split-line"});s.createSpan({cls:"stashpad-split-lineno",text:String(e+1)}),s.createSpan({cls:"stashpad-split-text",text:this.lines[e]||" "}),s.onclick=()=>{let i=Math.max(1,Math.min(this.lines.length-1,e));i!==this.lineCursorIdx&&(this.lineCursorIdx=i,this.render())}}}renderCursorMode(){let e=this.contentEl.createDiv({cls:"stashpad-split-cursor-wrap"}).createEl("textarea",{cls:"stashpad-split-cursor-ta"});e.value=this.body,e.readOnly=!1,this.cursorTextarea=e;let s=parseFloat(getComputedStyle(e).lineHeight)||22,i=pt.Platform.isMobile?3:12,n=2,r=()=>{e.style.height="auto";let o=Math.min(e.scrollHeight,s*i+16);e.style.height=`${Math.max(o,s*n+16)}px`};requestAnimationFrame(()=>{r();let o=Math.floor(e.value.length/2);e.focus(),e.setSelectionRange(o,o)}),e.addEventListener("input",r)}onClose(){this.cursorTextarea=null,this.contentEl.empty()}},xe=class extends pt.Modal{constructor(t,e,s){super(t);this.onResult=s;this.delivered=!1;this.value=e&&/^#[0-9a-f]{6}$/i.test(e)?e:"#888888"}onOpen(){this.contentEl.empty(),this.titleEl.setText("Custom color"),this.modalEl.addClass("stashpad-custom-color-modal");let t=this.contentEl.createDiv({cls:"stashpad-custom-color-row"}),e=t.createDiv({cls:"stashpad-custom-color-preview"});e.style.background=this.value;let s=t.createEl("input",{type:"color"});s.value=this.value,s.addClass("stashpad-custom-color-wheel"),e.onclick=()=>s.click();let i=t.createEl("input",{type:"text"});i.addClass("stashpad-custom-color-hex"),i.placeholder="#RRGGBB",i.value=this.value,i.maxLength=7;let n=c=>{let h=c.startsWith("#")?c:"#"+c;/^#[0-9a-f]{6}$/i.test(h)&&(this.value=h,e.style.background=h,s.value=h,i.value!==h&&(i.value=h))};s.oninput=()=>n(s.value),i.oninput=()=>n(i.value);let r=this.contentEl.createDiv({cls:"stashpad-color-footer"}),o=r.createEl("button",{text:"Cancel"});o.onclick=()=>{this.delivered=!0,this.close()};let a=r.createEl("button",{cls:"mod-cta",text:"Save"});a.title="Apply this color to the selection (without adding to your palette).",a.onclick=()=>this.commit({addToPalette:!1});let l=r.createEl("button",{cls:"mod-cta",text:"Add to palette"});l.title="Apply and save this color so it appears as a tile next time.",l.onclick=()=>this.commit({addToPalette:!0}),this.scope.register([],"Enter",c=>{c.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",c=>{c.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>i.focus())}commit(t){this.delivered=!0,this.close(),this.onResult(this.value,t)}onClose(){this.delivered||(this.delivered=!0,this.onResult(this.value,{addToPalette:!1})),this.contentEl.empty()}},oe=class oe extends pt.Modal{constructor(t,e,s,i,n){super(t);this.currentColor=e;this.customPalette=s;this.onPick=i;this.onDeleteCustom=n;this.focusIdx=-1;this.items=[]}onOpen(){this.contentEl.empty(),this.titleEl.setText("Pick a color"),this.modalEl.addClass("stashpad-color-modal");let t=this.contentEl.createDiv({cls:"stashpad-color-grid"});this.items=[];let e=t.createDiv({cls:"stashpad-color-tile stashpad-color-none"});e.title="No color",e.onclick=()=>this.activate(0),this.items.push({kind:"none",color:null,el:e});let s=[...oe.DEFAULT_PALETTE,...this.customPalette];for(let o of s){let a=t.createDiv({cls:"stashpad-color-tile"});a.style.background=o,a.title=o;let l=!oe.DEFAULT_PALETTE.some(h=>h.toLowerCase()===o.toLowerCase()),c=this.items.length;if(a.onclick=()=>this.activate(c),l&&this.onDeleteCustom){let h=a.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});h.title="Remove from palette",h.onclick=u=>{u.stopPropagation(),this.handleDelete(o)}}this.items.push({kind:l?"custom":"preset",color:o,el:a})}let i=t.createDiv({cls:"stashpad-color-tile stashpad-color-add"});i.title="Custom color\u2026";let n=this.items.length;i.onclick=()=>this.activate(n),this.items.push({kind:"add",color:null,el:i});let r=this.items.findIndex(o=>this.currentColor===null?o.kind==="none":this.currentColor?o.color!==null&&o.color.toLowerCase()===this.currentColor.toLowerCase():!1);this.focusIdx=r>=0?r:0,this.refreshActive(),this.scope.register([],"ArrowRight",o=>{o.preventDefault(),this.moveFocus(1)}),this.scope.register([],"ArrowLeft",o=>{o.preventDefault(),this.moveFocus(-1)}),this.scope.register([],"ArrowDown",o=>{o.preventDefault(),this.moveFocus(this.columns())}),this.scope.register([],"ArrowUp",o=>{o.preventDefault(),this.moveFocus(-this.columns())}),this.scope.register([],"Enter",o=>{o.preventDefault(),this.activate(this.focusIdx)}),requestAnimationFrame(()=>this.modalEl.focus())}activate(t){if(t<0||t>=this.items.length)return;this.focusIdx=t,this.refreshActive();let e=this.items[t];if(e.kind==="add"){this.close(),new xe(this.app,this.currentColor,(s,i)=>{this.onPick(s,i)}).open();return}this.close(),this.onPick(e.color,{addToPalette:!1})}columns(){if(!this.items.length)return 1;let t=this.items[0].el.parentElement;if(!t)return 1;let e=t.getBoundingClientRect(),s=this.items[0].el.getBoundingClientRect();if(s.width<=0)return 1;let i=s.top,n=0;for(let r of this.items){let o=r.el.getBoundingClientRect();if(Math.abs(o.top-i)<1)n++;else break}return Math.max(1,n)}async handleDelete(t){if(this.onDeleteCustom)try{let e=await this.onDeleteCustom(t);this.customPalette=Array.isArray(e)?e:this.customPalette.filter(s=>s.toLowerCase()!==t.toLowerCase()),this.onOpen()}catch(e){console.warn("Stashpad: palette delete failed",e)}}moveFocus(t){if(!this.items.length)return;let e=Math.max(0,Math.min(this.items.length-1,this.focusIdx+t));this.focusIdx=e,this.refreshActive()}refreshActive(){for(let t=0;t<this.items.length;t++)this.items[t].el.toggleClass("is-active",t===this.focusIdx)}onClose(){this.contentEl.empty()}};oe.DEFAULT_PALETTE=["#E07A78","#E08A47","#E0A744","#B0CC6E","#6BC07A","#5BA9CE","#9B82C9","#C57AB5","#D75AA8"];Vt=oe,Ft=class extends pt.Modal{constructor(t,e,s,i,n){super(t);this.titleText=e;this.message=s;this.confirmText=i;this.onChoose=n;this.didChoose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText(this.titleText);let t=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let n of this.message.split(` +`))t.createDiv({cls:"stashpad-confirm-line",text:n});let e=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),s=e.createEl("button",{text:"Cancel"});s.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!1)};let i=e.createEl("button",{cls:"mod-cta",text:this.confirmText});i.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>i.focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}},ce=class extends pt.Modal{constructor(t,e,s){super(t);this.current=e;this.onPick=s;this.didChoose=!1;this.tinyClosePopover=null}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Set due date");let t=null;if(this.current){let v=Date.parse(this.current);Number.isNaN(v)||(t=new Date(v))}let e=this.contentEl.createDiv({cls:"stashpad-due-picker"}),s=e.createDiv({cls:"stashpad-due-fields"}),i=s.createDiv({cls:"stashpad-due-field"}),n=i.createSpan({cls:"stashpad-due-field-icon"});(0,pt.setIcon)(n,"calendar");let r=i.createEl("input",{type:"date",cls:"stashpad-due-date"}),o=s.createDiv({cls:"stashpad-due-field"}),a=o.createSpan({cls:"stashpad-due-field-icon"});(0,pt.setIcon)(a,"clock");let l=o.createEl("input",{type:"time",cls:"stashpad-due-time"});n.onclick=()=>{try{r.showPicker?.()}catch{}},a.onclick=()=>this.openTimeNumpad(a,l),t&&(r.value=this.toDateValue(t),l.value=this.toTimeValue(t));let c=e.createDiv({cls:"stashpad-due-grid"}),h=(v,y)=>{let b=c.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:v});b.onclick=()=>{let k=y();r.value=this.toDateValue(k),l.value||(l.value=this.toTimeValue(k))}},u=v=>(v.setHours(9,0,0,0),v);h("Today",()=>u(this.startOfTodayLocal())),h("Tomorrow",()=>{let v=this.startOfTodayLocal();return v.setDate(v.getDate()+1),u(v)}),h("Next week",()=>{let v=this.startOfTodayLocal();return v.setDate(v.getDate()+7),u(v)});let d=c.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});d.onclick=()=>{r.value="",l.value="",r.focus()};let p=c.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});p.onclick=()=>{this.didChoose=!0,this.close()};let m=c.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});m.onclick=()=>{if(!r.value){this.didChoose=!0,this.close(),this.onPick(null);return}let[v,y,b]=r.value.split("-").map(I=>parseInt(I,10)),k=9,C=0;if(l.value){let[I,A]=l.value.split(":").map(O=>parseInt(O,10));k=I,C=A}let E=new Date(v,y-1,b,k,C,0,0);this.didChoose=!0,this.close(),this.onPick(E.toISOString())},requestAnimationFrame(()=>r.focus())}onClose(){this.tinyClosePopover?.(),this.contentEl.empty(),this.didChoose}openTimeNumpad(t,e){this.tinyClosePopover?.();let s=9,i=0;if(e.value){let[d,p]=e.value.split(":").map(m=>parseInt(m,10));Number.isFinite(d)&&(s=d),Number.isFinite(p)&&(i=p)}else{let d=new Date;s=d.getHours(),i=d.getMinutes()}let n=s>=12?"pm":"am",r=s===0?12:s>12?s-12:s,o=document.body.createDiv({cls:"stashpad-when-popover stashpad-due-time-pop"});o.style.position="fixed",o.style.zIndex="9999";let a=null,l=()=>{o.remove(),document.removeEventListener("mousedown",c,!0),document.removeEventListener("keydown",h,!0),this.tinyClosePopover===l&&(this.tinyClosePopover=null)},c=d=>{!o.contains(d.target)&&d.target!==t&&!t.contains(d.target)&&l()},h=d=>{d.key==="Escape"?(d.preventDefault(),d.stopPropagation(),l()):d.key==="Enter"&&a&&(d.preventDefault(),d.stopPropagation(),a())};this.tinyClosePopover=l,Te(o,{seedH:r,seedM:i,seedPeriod:n,close:l,setOnEnter:d=>{a=d},onFinalize:d=>{e.value=`${String(d.hours24).padStart(2,"0")}:${String(d.minutes).padStart(2,"0")}`}});let u=t.getBoundingClientRect();o.style.left=`${Math.max(8,Math.min(u.left,window.innerWidth-220))}px`,o.style.top=`${u.bottom+4}px`,setTimeout(()=>{document.addEventListener("mousedown",c,!0),document.addEventListener("keydown",h,!0)},0)}startOfTodayLocal(){let t=new Date;return t.setHours(0,0,0,0),t}toDateValue(t){let e=t.getFullYear(),s=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${e}-${s}-${i}`}toTimeValue(t){let e=String(t.getHours()).padStart(2,"0"),s=String(t.getMinutes()).padStart(2,"0");return`${e}:${s}`}},Ut=class Ut extends pt.Modal{constructor(t,e,s,i=null,n){super(t);this.service=e;this.openLog=s;this.currentAuthorId=i;this.getNoteAuthorIds=n;this.records=[];this.visible=[];this.shownCount=0;this.categoryFilter=null;this.listEl=null;this.footerEl=null;this.countEl=null;this.filterSelEl=null;this.unsubscribe=null;this.authorFilter="all";this.authorSelEl=null}onOpen(){this.contentEl.empty(),this.titleEl.setText("Stashpad notification history"),this.modalEl.addClass("stashpad-log-modal"),this.modalEl.addClass("stashpad-notif-history-modal"),this.records=this.service.recent();let t=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=t.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=t.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setCategoryFilter(this.filterSelEl.value||null),this.refreshCategoryFilter(),this.authorSelEl=t.createEl("select",{cls:"stashpad-log-type-filter stashpad-notif-author-filter"}),this.authorSelEl.onchange=()=>this.setAuthorFilter(this.authorSelEl.value||"all"),this.refreshAuthorFilter(),this.openLog){let s=t.createEl("button",{text:"Open log"});s.title="Open the per-folder Stashpad log for the most recent notification's folder.",s.onclick=()=>{let i=this.records.find(n=>!!n.folder);this.openLog?.(i?.folder)}}let e=t.createEl("button",{cls:"mod-warning",text:"Clear history"});e.onclick=()=>{new Ft(this.app,"Clear notification history?",`This will permanently remove all ${this.records.length} stored notifications from the history. The current toasts on screen are unaffected. This can't be undone.`,"Clear history",s=>{s&&this.service.clearHistory()}).open()},this.listEl=this.contentEl.createDiv({cls:"stashpad-log-list"}),this.refreshList(),this.footerEl=this.contentEl.createDiv({cls:"stashpad-log-footer"}),this.renderFooter(),this.unsubscribe=this.service.onChange(()=>{this.records=this.service.recent(),this.refreshCategoryFilter(),this.refreshAuthorFilter(),this.refreshList(),this.renderFooter()})}setAuthorFilter(t){this.authorFilter!==t&&(this.authorFilter=t,this.refreshList(),this.renderFooter())}refreshAuthorFilter(){if(!this.authorSelEl)return;let t=this.authorSelEl;t.empty(),t.createEl("option",{text:"All authors"}).value="all",this.currentAuthorId&&(t.createEl("option",{text:"Me"}).value="me"),t.createEl("option",{text:"Cross-author"}).value="cross";let e=new Set;for(let i of this.records)i.authorId&&i.authorId!==this.currentAuthorId&&e.add(i.authorId);if(e.size>0){let i=t.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});i.disabled=!0;for(let n of[...e].sort())t.createEl("option",{text:n}).value=n}new Set(["all","cross",...this.currentAuthorId?["me"]:[],...e]).has(this.authorFilter)||(this.authorFilter="all"),t.value=this.authorFilter}isCrossAuthor(t){let e=t.authorId??null;if(!e)return!1;for(let s of t.affectedAuthorIds??[])if(s&&s!==e)return!0;if(!this.getNoteAuthorIds)return!1;for(let s of t.affectedIds){let i=this.getNoteAuthorIds(s);for(let n of i)if(n&&n!==e)return!0}return!1}onClose(){this.unsubscribe?.(),this.unsubscribe=null,this.contentEl.empty()}setCategoryFilter(t){(this.categoryFilter??null)!==(t??null)&&(this.categoryFilter=t,this.refreshList(),this.renderFooter())}refreshCategoryFilter(){if(!this.filterSelEl)return;let t=this.filterSelEl;t.empty();let e=new Map;for(let n of this.records)e.set(n.category,(e.get(n.category)??0)+1);let s=[...e.entries()].sort((n,r)=>r[1]-n[1]||n[0].localeCompare(r[0])),i=t.createEl("option",{text:`All categories (${this.records.length})`});i.value="";for(let[n,r]of s){let o=t.createEl("option",{text:`${n} (${r})`});o.value=n}this.categoryFilter&&!e.has(this.categoryFilter)&&(this.categoryFilter=null),t.value=this.categoryFilter??""}refreshList(){if(this.listEl){if(this.visible=this.records.filter(t=>{if(this.categoryFilter&&t.category!==this.categoryFilter)return!1;switch(this.authorFilter){case"all":return!0;case"me":return!!this.currentAuthorId&&t.authorId===this.currentAuthorId;case"cross":return this.isCrossAuthor(t);default:return t.authorId===this.authorFilter}}),this.shownCount=0,this.listEl.empty(),!this.visible.length){this.listEl.createDiv({cls:"stashpad-log-empty",text:this.categoryFilter?`No "${this.categoryFilter}" notifications.`:"No notifications yet."}),this.updateCount();return}this.appendMore(Ut.PAGE)}}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let s=this.shownCount;s<e;s++)this.renderRow(this.listEl,this.visible[s]);this.shownCount=e,this.updateCount()}renderRow(t,e){let s=t.createDiv({cls:`stashpad-notif-row stashpad-notif-row-${e.kind}`}),i=s.createDiv({cls:"stashpad-notif-meta"}),n=i.createSpan({cls:"stashpad-notif-time"}),r=(0,pt.moment)(e.ts);if(n.setText(r.fromNow()),n.title=r.format("YYYY-MM-DD HH:mm:ss"),i.createSpan({cls:`stashpad-notif-cat stashpad-notif-cat-${e.category}`}).setText(e.category),s.createDiv({cls:"stashpad-notif-msg"}).setText(e.message),e.actionLabels.length>0){let l=s.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let c of e.actionLabels){let h=l.createSpan({cls:"stashpad-notif-action-chip"});h.setText(c),h.title="Action button was shown on the original toast (handler not retained)."}}}updateCount(){if(!this.countEl)return;let t=this.visible.length,e=this.categoryFilter?`${t} ${this.categoryFilter} notification${t===1?"":"s"}`:`${t} notification${t===1?"":"s"}`;this.shownCount===0||this.shownCount>=t?this.countEl.setText(e):this.countEl.setText(`Showing ${this.shownCount} of ${e}`)}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let t=this.visible.length-this.shownCount;if(t<=0)return;let e=this.footerEl.createEl("button",{text:`Load ${Math.min(Ut.PAGE,t)} more`});if(e.onclick=()=>{this.appendMore(Ut.PAGE),this.renderFooter()},t>Ut.PAGE){let s=this.footerEl.createEl("button",{text:`Load all (${t})`});s.onclick=()=>{this.appendMore(t),this.renderFooter()}}}};Ut.PAGE=100;de=Ut});var ze={};ke(ze,{newId:()=>Tt});function Tt(g=6){let f="",t=new Uint8Array(g);crypto.getRandomValues(t);for(let e=0;e<g;e++)f+=Ws[t[e]%Ws.length];return f}var Ws,Ot=Kt(()=>{"use strict";Ws="abcdefghijkmnpqrstuvwxyz23456789"});function $t(g,f=Et){let t=f instanceof Set?f:new Set(f.map(r=>r.toLowerCase())),e=(g.split(/\r?\n/).find(r=>r.trim().length>0)??"").trim();if(!e)return"Untitled";let i=e.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(r=>r&&!t.has(r.toLowerCase())).map(r=>r.length>=2&&/^[A-Z0-9]+$/.test(r)?r:r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()),n="";for(let r of i){let o=n?`${n}-${r}`:r;if(o.length>50)break;n=o}return n||"Untitled"}function Rt(g,f){return`${g}-${f}.md`}function Qt(g){let f=g.match(/-([a-z0-9]{4,12})$/);return f?f[1]:null}var Et,ue=Kt(()=>{"use strict";Et=["a","an","the","and","or","but","if","then","else","of","in","on","at","to","for","with","by","from","as","is","are","was","were","be","been","being","i","you","he","she","it","we","they","this","that","these","those","my","your","our","their","do","does","did","so","just","very","really","im"]});var Ve={};ke(Ve,{JdBuildConfirmModal:()=>fe,buildJdIndexNotes:()=>gs,buildJdIndexPreview:()=>je,buildJdPreviewNotice:()=>Ue,scanForJdNotes:()=>te});function ms(g,f){if(/^\d+-\d+$/.test(g))return null;if(g.includes(".")){let e=g.split(".").slice(0,-1).join(".");return f.has(e)?e:ms(e,f)}if(/^\d+$/.test(g)){let t=parseInt(g,10);for(let e of f){let s=e.match(/^(\d+)-(\d+)$/);if(!s)continue;let i=parseInt(s[1],10),n=parseInt(s[2],10);if(t>=i&&t<=n)return e}return null}return null}function te(g,f,t){let e=g.vault.getMarkdownFiles(),s=Ti(e,t),i=t.jdIndexIncludeStashpadFolders===!0,n=i?new Set:new Set(f.discoverStashpadFolders()),r=d=>i?!1:Array.from(n).some(p=>d===p||d.startsWith(p+"/")),o=[],a=[],l=[];for(let d of s){let p=d.parent?.path?.replace(/\/+$/,"")??"";if(r(p)){l.push(d);continue}let m=d.basename.match(js);m?o.push({prefix:m[1],segments:m[1].split("."),title:m[2],file:d,folder:null}):a.push(d)}let c=(t.jdIndexScope??"vault")==="folder"?(t.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",h=d=>{let p=d.path.replace(/\/+$/,"");if(!(c&&p&&p!==c&&!p.startsWith(c+"/"))){if(p&&!r(p)){let m=d.name.match(js);m&&o.push({prefix:m[1],segments:m[1].split("."),title:m[2],file:null,folder:d})}}for(let m of d.children)m instanceof bt.TFolder&&h(m)};h(g.vault.getRoot());let u=t.jdIndexSort??"natural";return o.sort((d,p)=>xi(d,p,u)),{indexed:o,nonIndex:a,skippedStashpadNotes:l}}async function je(g,f,t){let e=vs(t.jdIndexStashpadFolder??"");if(!e)return{...te(g,f,t),previewPath:null,error:"no-dest"};let s=te(g,f,t),i=Ci(g,e);if(!i)return{...s,previewPath:null,error:"no-home"};let n=Fi(s.indexed,s.nonIndex,s.skippedStashpadNotes),o=(await g.vault.read(i)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),a=o?`${o[0]}${n}`:n;return await g.vault.modify(i,a),{...s,previewPath:i.path}}function Ci(g,f){let t=g.vault.getAbstractFileByPath(f);if(!(t instanceof bt.TFolder))return null;for(let e of t.children){if(!(e instanceof bt.TFile)||e.extension!=="md")continue;if((g.metadataCache.getFileCache(e)?.frontmatter??{}).id===R)return e}return null}async function gs(g,f,t){let e=vs(t.jdIndexStashpadFolder??"");if(!e)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(f.discoverStashpadFolders()).has(e))return{created:0,updated:0,skipped:0,destFolder:e,error:"dest-not-stashpad"};let i=te(g,f,t),n=new Map;for(let v of i.indexed)n.set(v.prefix,v);for(let v of i.indexed)if(v.prefix.includes("."))for(let y=1;y<v.segments.length;y++){let b=v.segments.slice(0,y).join(".");n.has(b)||n.set(b,null)}let{roots:r,childrenOf:o}=Ys(n),a=[],l=v=>{a.push(v);for(let y of o.get(v)??[])l(y)};for(let v of r)l(v);let c=new Map,h=g.vault.getAbstractFileByPath(e);if(h instanceof bt.TFolder)for(let v of h.children){if(!(v instanceof bt.TFile)||v.extension!=="md")continue;let y=g.metadataCache.getFileCache(v)?.frontmatter??{};typeof y.jdPrefix=="string"&&c.set(y.jdPrefix,v)}let u=new Map,d=0,p=0,m=0;for(let v of a){let y=n.get(v)??null,b=ms(v,new Set(n.keys())),k=b?u.get(b)??R:R,C=y?`${v} ${y.title}`:v,E=y?.file?`[[${y.file.basename}]]`:"",I=E?`${E} +`:`${C} +`,A=c.get(v);if(A){try{let O=null;await g.fileManager.processFrontMatter(A,B=>{B.jdPrefix=v,k&&(B.parent=k),(!B.id||typeof B.id!="string")&&(B.id=Tt()),B.created||(B.created=new Date().toISOString()),B.attachments||(B.attachments=[]),O=B.id});let D=(await g.vault.read(A)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),S=D?`${D[0]}${I}`:I;await g.vault.modify(A,S),O&&u.set(v,O),p++}catch(O){console.error("[stashpad] buildJdIndexNotes: update failed",O),m++}continue}try{let O=Tt();u.set(v,O);let F=$t(C,t.slugStopWords),D=Rt(F,O),S=`${e}/${D}`,B=["---",`id: ${O}`,`parent: ${k}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${v}"`,"---",""].join(` +`);await g.vault.create(S,B+I),d++}catch(O){console.error("[stashpad] buildJdIndexNotes: create failed for",v,O),m++}}return{created:d,updated:p,skipped:m,destFolder:e}}function vs(g){return(g||"").trim().replace(/^\/+|\/+$/g,"")}function Ti(g,f){if((f.jdIndexScope??"vault")==="vault")return g;let t=vs(f.jdIndexScopeFolder??"");return t?g.filter(e=>{let s=e.parent?.path?.replace(/\/+$/,"")??"";return s===t||s.startsWith(t+"/")}):g}function xi(g,f,t){if(t==="created"){let e=g.file.stat?.ctime??0,s=f.file.stat?.ctime??0;if(e!==s)return e-s}return Vs(g.segments,f.segments)}function Us(g,f){let t=g.match(/^(\d+)-(\d+)$/),e=f.match(/^(\d+)-(\d+)$/),s=t?[t[1]]:g.split("."),i=e?[e[1]]:f.split(".");return Vs(s,i)}function Vs(g,f){let t=Math.min(g.length,f.length);for(let e=0;e<t;e++){let s=g[e],i=f[e],n=/^\d+$/.test(s),r=/^\d+$/.test(i);if(n&&r){let o=parseInt(s,10)-parseInt(i,10);if(o!==0)return o}else{if(n&&!r)return-1;if(!n&&r)return 1;{let o=s.localeCompare(i,void 0,{numeric:!0,sensitivity:"base"});if(o!==0)return o}}}return g.length-f.length}function Ys(g){let f=new Set(g.keys()),t=new Map,e=new Map;for(let r of f){let o=ms(r,f);if(t.set(r,o),o!==null){let a=e.get(o)??[];a.push(r),e.set(o,a)}}let s=[];for(let r of f)t.get(r)===null&&s.push(r);s.sort(Us);for(let r of e.values())r.sort(Us);let i=new Map,n=(r,o)=>{i.set(r,o);for(let a of e.get(r)??[])n(a,o+1)};for(let r of s)n(r,0);return{roots:s,childrenOf:e,depthOf:i}}function Fi(g,f,t){let e=[],s=i=>"#".repeat(Math.min(i+1,6));if(e.push("# Indexed"),e.push(""),g.length===0){let i=t.length>0?`_No notes matched. ${t.length} note${t.length===1?" was":"s were"} excluded because they live inside a Stashpad folder \u2014 toggle "Include Stashpad folders in scan" in Settings \u2192 JD Index Builder if you want them included._`:"_No notes matched the JD-prefix convention. Check Scope and Designated folder in Settings \u2192 JD Index Builder._";e.push(i)}else{let i=new Map;for(let l of g)i.set(l.prefix,l);for(let l of g)if(l.prefix.includes("."))for(let c=1;c<l.segments.length;c++){let h=l.segments.slice(0,c).join(".");i.has(h)||i.set(h,null)}let{roots:n,childrenOf:r,depthOf:o}=Ys(i),a=l=>{let c=i.get(l),h=o.get(l)??0,u=" ".repeat(h),d=s(h),p=c?.folder?` ${c.title} _(folder)_`:(c?.file,"");c?.file?e.push(`${u}- ${d} [[${c.file.basename}|${c.prefix} ${c.title}]]`):c?.folder?e.push(`${u}- ${d} ${c.prefix}${p}`):e.push(`${u}- ${d} ${l}`);for(let m of r.get(l)??[])a(m)};for(let l of n)a(l)}if(f.length>0){e.push(""),e.push(`# Non-indexed (${f.length})`),e.push(""),e.push("_These notes don't match the JD-prefix convention. Rename them to `<prefix> <title>` and re-run to include them._"),e.push("");for(let i of f)e.push(`- # [[${i.basename}]] \xB7 \`${i.path}\``)}if(t.length>0){let i=new Map;for(let r of t){let o=r.parent?.path?.replace(/\/+$/,"")??"";i.set(o,(i.get(o)??0)+1)}let n=Array.from(i.entries()).sort((r,o)=>r[0].localeCompare(o[0]));e.push(""),e.push(`# Excluded folders (${n.length})`),e.push(""),e.push(`_Stashpad folders are excluded by default so the index doesn't reference itself. Toggle "Include Stashpad folders in scan" in Settings \u2192 JD Index Builder to include them._`),e.push("");for(let[r,o]of n)e.push(`- # All ${o} file${o===1?"":"s"} in \`${r||"(vault root)"}\``)}return e.join(` `)+` -`}function We(v,f){let t=document.createDocumentFragment(),e=t.createEl("div",{text:"Home note updated"});e.style.fontWeight="600",e.style.marginBottom="6px";let s=t.createEl("ul");s.style.margin="0 0 8px 0",s.style.paddingLeft="18px",s.createEl("li",{text:`${f.indexed.length} indexed`}),s.createEl("li",{text:`${f.nonIndex.length+f.skippedStashpadNotes.length} excluded`});let i=t.createEl("button",{text:"Open",cls:"mod-cta"});i.style.padding="2px 10px",i.style.fontSize="var(--font-ui-smaller)";let n;return i.onclick=async r=>{if(r.stopPropagation(),f.previewPath){let o=v.vault.getAbstractFileByPath(f.previewPath);o instanceof St.TFile&&await v.workspace.getLeaf("tab").openFile(o)}n?.hide()},n=new St.Notice(t,0),n}var St,$s,ue,fe=ne(()=>{"use strict";St=require("obsidian");Rt();pe();xt();$s=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;ue=class extends St.Modal{constructor(t,e,s,i,n){super(t);this.plugin=e;this.settings=s;this.indexedCount=i;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:t,titleEl:e}=this,s=!this.settings.jdIndexHasBuilt,i=this.indexedCount>this.LARGE_BUILD;e.setText(s?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,r=t.createEl("p"),o=`${this.indexedCount} note${this.indexedCount===1?"":"s"}`;s?(r.appendText(`Stashpad is about to create ${o} (plus synthetic parents as needed) inside "`),r.createEl("code",{text:n}),r.appendText('". Existing notes with the same '),r.createEl("code",{text:"jdPrefix"}),r.appendText(" are updated, never deleted \u2014 but if the prefix detection picks up notes you didn't mean to index, you'll end up with a lot of unwanted notes."),t.createEl("p").setText("Running Preview first writes a single Markdown file showing exactly what would be built (and what wouldn't), so you can sanity-check before committing.")):i?(r.appendText(`You're about to create ${this.indexedCount} notes in "`),r.createEl("code",{text:n}),r.appendText(`". That's a big batch \u2014 if anything looks off, Preview the single-file output first.`)):(r.appendText('Build the JD index into "'),r.createEl("code",{text:n}),r.appendText(`"? Stashpad will create / update ${o}. Existing notes with matching `),r.createEl("code",{text:"jdPrefix"}),r.appendText(" are updated in place.")),this.previewRan&&this.previewPath&&t.createEl("p",{cls:"setting-item-description"}).setText(`\u2713 Preview written to home note (${this.previewPath}). Open it before building if you haven't.`);let a=new St.Setting(t);(s||i)&&a.addButton(l=>{l.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),l.setCta(),l.onClick(async()=>{try{let c=await ze(this.app,this.plugin,this.settings);if(c.error==="no-dest"){new St.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(c.error==="no-home"){new St.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=c.previewPath,We(this.app,c),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(c){new St.Notice(`Preview failed: ${c?.message??c}`,8e3)}})}),a.addButton(l=>{l.setButtonText(s?"Build anyway":"Build"),!s&&!i&&l.setCta(),l.onClick(async()=>{this.close(),await this.onBuild()})}),a.addButton(l=>{l.setButtonText("Cancel"),l.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var qs=di((Ks,Ss)=>{(function(v){typeof Ks=="object"&&typeof Ss<"u"?Ss.exports=v():typeof define=="function"&&define.amd?define([],v):(typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:this).JSZip=v()})(function(){return function v(f,t,e){function s(r,o){if(!t[r]){if(!f[r]){var a=typeof require=="function"&&require;if(!o&&a)return a(r,!0);if(i)return i(r,!0);var l=new Error("Cannot find module '"+r+"'");throw l.code="MODULE_NOT_FOUND",l}var c=t[r]={exports:{}};f[r][0].call(c.exports,function(d){var p=f[r][1][d];return s(p||d)},c,c.exports,v,f,t,e)}return t[r].exports}for(var i=typeof require=="function"&&require,n=0;n<e.length;n++)s(e[n]);return s}({1:[function(v,f,t){"use strict";var e=v("./utils"),s=v("./support"),i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.encode=function(n){for(var r,o,a,l,c,d,p,h=[],u=0,m=n.length,g=m,y=e.getTypeOf(n)!=="string";u<n.length;)g=m-u,a=y?(r=n[u++],o=u<m?n[u++]:0,u<m?n[u++]:0):(r=n.charCodeAt(u++),o=u<m?n.charCodeAt(u++):0,u<m?n.charCodeAt(u++):0),l=r>>2,c=(3&r)<<4|o>>4,d=1<g?(15&o)<<2|a>>6:64,p=2<g?63&a:64,h.push(i.charAt(l)+i.charAt(c)+i.charAt(d)+i.charAt(p));return h.join("")},t.decode=function(n){var r,o,a,l,c,d,p=0,h=0,u="data:";if(n.substr(0,u.length)===u)throw new Error("Invalid base64 input, it looks like a data url.");var m,g=3*(n=n.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(n.charAt(n.length-1)===i.charAt(64)&&g--,n.charAt(n.length-2)===i.charAt(64)&&g--,g%1!=0)throw new Error("Invalid base64 input, bad content length.");for(m=s.uint8array?new Uint8Array(0|g):new Array(0|g);p<n.length;)r=i.indexOf(n.charAt(p++))<<2|(l=i.indexOf(n.charAt(p++)))>>4,o=(15&l)<<4|(c=i.indexOf(n.charAt(p++)))>>2,a=(3&c)<<6|(d=i.indexOf(n.charAt(p++))),m[h++]=r,c!==64&&(m[h++]=o),d!==64&&(m[h++]=a);return m}},{"./support":30,"./utils":32}],2:[function(v,f,t){"use strict";var e=v("./external"),s=v("./stream/DataWorker"),i=v("./stream/Crc32Probe"),n=v("./stream/DataLengthProbe");function r(o,a,l,c,d){this.compressedSize=o,this.uncompressedSize=a,this.crc32=l,this.compression=c,this.compressedContent=d}r.prototype={getContentWorker:function(){var o=new s(e.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new n("data_length")),a=this;return o.on("end",function(){if(this.streamInfo.data_length!==a.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),o},getCompressedWorker:function(){return new s(e.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},r.createWorkerFrom=function(o,a,l){return o.pipe(new i).pipe(new n("uncompressedSize")).pipe(a.compressWorker(l)).pipe(new n("compressedSize")).withStreamInfo("compression",a)},f.exports=r},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(v,f,t){"use strict";var e=v("./stream/GenericWorker");t.STORE={magic:"\0\0",compressWorker:function(){return new e("STORE compression")},uncompressWorker:function(){return new e("STORE decompression")}},t.DEFLATE=v("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(v,f,t){"use strict";var e=v("./utils"),s=function(){for(var i,n=[],r=0;r<256;r++){i=r;for(var o=0;o<8;o++)i=1&i?3988292384^i>>>1:i>>>1;n[r]=i}return n}();f.exports=function(i,n){return i!==void 0&&i.length?e.getTypeOf(i)!=="string"?function(r,o,a,l){var c=s,d=l+a;r^=-1;for(var p=l;p<d;p++)r=r>>>8^c[255&(r^o[p])];return-1^r}(0|n,i,i.length,0):function(r,o,a,l){var c=s,d=l+a;r^=-1;for(var p=l;p<d;p++)r=r>>>8^c[255&(r^o.charCodeAt(p))];return-1^r}(0|n,i,i.length,0):0}},{"./utils":32}],5:[function(v,f,t){"use strict";t.base64=!1,t.binary=!1,t.dir=!1,t.createFolders=!0,t.date=null,t.compression=null,t.compressionOptions=null,t.comment=null,t.unixPermissions=null,t.dosPermissions=null},{}],6:[function(v,f,t){"use strict";var e=null;e=typeof Promise<"u"?Promise:v("lie"),f.exports={Promise:e}},{lie:37}],7:[function(v,f,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",s=v("pako"),i=v("./utils"),n=v("./stream/GenericWorker"),r=e?"uint8array":"array";function o(a,l){n.call(this,"FlateWorker/"+a),this._pako=null,this._pakoAction=a,this._pakoOptions=l,this.meta={}}t.magic="\b\0",i.inherits(o,n),o.prototype.processChunk=function(a){this.meta=a.meta,this._pako===null&&this._createPako(),this._pako.push(i.transformTo(r,a.data),!1)},o.prototype.flush=function(){n.prototype.flush.call(this),this._pako===null&&this._createPako(),this._pako.push([],!0)},o.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this._pako=null},o.prototype._createPako=function(){this._pako=new s[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var a=this;this._pako.onData=function(l){a.push({data:l,meta:a.meta})}},t.compressWorker=function(a){return new o("Deflate",a)},t.uncompressWorker=function(){return new o("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(v,f,t){"use strict";function e(c,d){var p,h="";for(p=0;p<d;p++)h+=String.fromCharCode(255&c),c>>>=8;return h}function s(c,d,p,h,u,m){var g,y,S=c.file,k=c.compression,x=m!==r.utf8encode,I=i.transformTo("string",m(S.name)),E=i.transformTo("string",r.utf8encode(S.name)),D=S.comment,$=i.transformTo("string",m(D)),F=i.transformTo("string",r.utf8encode(D)),P=E.length!==S.name.length,b=F.length!==D.length,H="",et="",V="",W=S.dir,z=S.date,Q={crc32:0,compressedSize:0,uncompressedSize:0};d&&!p||(Q.crc32=c.crc32,Q.compressedSize=c.compressedSize,Q.uncompressedSize=c.uncompressedSize);var N=0;d&&(N|=8),x||!P&&!b||(N|=2048);var M=0,J=0;W&&(M|=16),u==="UNIX"?(J=798,M|=function(Y,pt){var mt=Y;return Y||(mt=pt?16893:33204),(65535&mt)<<16}(S.unixPermissions,W)):(J=20,M|=function(Y){return 63&(Y||0)}(S.dosPermissions)),g=z.getUTCHours(),g<<=6,g|=z.getUTCMinutes(),g<<=5,g|=z.getUTCSeconds()/2,y=z.getUTCFullYear()-1980,y<<=4,y|=z.getUTCMonth()+1,y<<=5,y|=z.getUTCDate(),P&&(et=e(1,1)+e(o(I),4)+E,H+="up"+e(et.length,2)+et),b&&(V=e(1,1)+e(o($),4)+F,H+="uc"+e(V.length,2)+V);var q="";return q+=` -\0`,q+=e(N,2),q+=k.magic,q+=e(g,2),q+=e(y,2),q+=e(Q.crc32,4),q+=e(Q.compressedSize,4),q+=e(Q.uncompressedSize,4),q+=e(I.length,2),q+=e(H.length,2),{fileRecord:a.LOCAL_FILE_HEADER+q+I+H,dirRecord:a.CENTRAL_FILE_HEADER+e(J,2)+q+e($.length,2)+"\0\0\0\0"+e(M,4)+e(h,4)+I+H+$}}var i=v("../utils"),n=v("../stream/GenericWorker"),r=v("../utf8"),o=v("../crc32"),a=v("../signature");function l(c,d,p,h){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=d,this.zipPlatform=p,this.encodeFileName=h,this.streamFiles=c,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}i.inherits(l,n),l.prototype.push=function(c){var d=c.meta.percent||0,p=this.entriesCount,h=this._sources.length;this.accumulate?this.contentBuffer.push(c):(this.bytesWritten+=c.data.length,n.prototype.push.call(this,{data:c.data,meta:{currentFile:this.currentFile,percent:p?(d+100*(p-h-1))/p:100}}))},l.prototype.openedSource=function(c){this.currentSourceOffset=this.bytesWritten,this.currentFile=c.file.name;var d=this.streamFiles&&!c.file.dir;if(d){var p=s(c,d,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:p.fileRecord,meta:{percent:0}})}else this.accumulate=!0},l.prototype.closedSource=function(c){this.accumulate=!1;var d=this.streamFiles&&!c.file.dir,p=s(c,d,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(p.dirRecord),d)this.push({data:function(h){return a.DATA_DESCRIPTOR+e(h.crc32,4)+e(h.compressedSize,4)+e(h.uncompressedSize,4)}(c),meta:{percent:100}});else for(this.push({data:p.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},l.prototype.flush=function(){for(var c=this.bytesWritten,d=0;d<this.dirRecords.length;d++)this.push({data:this.dirRecords[d],meta:{percent:100}});var p=this.bytesWritten-c,h=function(u,m,g,y,S){var k=i.transformTo("string",S(y));return a.CENTRAL_DIRECTORY_END+"\0\0\0\0"+e(u,2)+e(u,2)+e(m,4)+e(g,4)+e(k.length,2)+k}(this.dirRecords.length,p,c,this.zipComment,this.encodeFileName);this.push({data:h,meta:{percent:100}})},l.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},l.prototype.registerPrevious=function(c){this._sources.push(c);var d=this;return c.on("data",function(p){d.processChunk(p)}),c.on("end",function(){d.closedSource(d.previous.streamInfo),d._sources.length?d.prepareNextSource():d.end()}),c.on("error",function(p){d.error(p)}),this},l.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},l.prototype.error=function(c){var d=this._sources;if(!n.prototype.error.call(this,c))return!1;for(var p=0;p<d.length;p++)try{d[p].error(c)}catch{}return!0},l.prototype.lock=function(){n.prototype.lock.call(this);for(var c=this._sources,d=0;d<c.length;d++)c[d].lock()},f.exports=l},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(v,f,t){"use strict";var e=v("../compressions"),s=v("./ZipFileWorker");t.generateWorker=function(i,n,r){var o=new s(n.streamFiles,r,n.platform,n.encodeFileName),a=0;try{i.forEach(function(l,c){a++;var d=function(m,g){var y=m||g,S=e[y];if(!S)throw new Error(y+" is not a valid compression method !");return S}(c.options.compression,n.compression),p=c.options.compressionOptions||n.compressionOptions||{},h=c.dir,u=c.date;c._compressWorker(d,p).withStreamInfo("file",{name:l,dir:h,date:u,comment:c.comment||"",unixPermissions:c.unixPermissions,dosPermissions:c.dosPermissions}).pipe(o)}),o.entriesCount=a}catch(l){o.error(l)}return o}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(v,f,t){"use strict";function e(){if(!(this instanceof e))return new e;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var s=new e;for(var i in this)typeof this[i]!="function"&&(s[i]=this[i]);return s}}(e.prototype=v("./object")).loadAsync=v("./load"),e.support=v("./support"),e.defaults=v("./defaults"),e.version="3.10.1",e.loadAsync=function(s,i){return new e().loadAsync(s,i)},e.external=v("./external"),f.exports=e},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(v,f,t){"use strict";var e=v("./utils"),s=v("./external"),i=v("./utf8"),n=v("./zipEntries"),r=v("./stream/Crc32Probe"),o=v("./nodejsUtils");function a(l){return new s.Promise(function(c,d){var p=l.decompressed.getContentWorker().pipe(new r);p.on("error",function(h){d(h)}).on("end",function(){p.streamInfo.crc32!==l.decompressed.crc32?d(new Error("Corrupted zip : CRC32 mismatch")):c()}).resume()})}f.exports=function(l,c){var d=this;return c=e.extend(c||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:i.utf8decode}),o.isNode&&o.isStream(l)?s.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):e.prepareContent("the loaded zip file",l,!0,c.optimizedBinaryString,c.base64).then(function(p){var h=new n(c);return h.load(p),h}).then(function(p){var h=[s.Promise.resolve(p)],u=p.files;if(c.checkCRC32)for(var m=0;m<u.length;m++)h.push(a(u[m]));return s.Promise.all(h)}).then(function(p){for(var h=p.shift(),u=h.files,m=0;m<u.length;m++){var g=u[m],y=g.fileNameStr,S=e.resolve(g.fileNameStr);d.file(S,g.decompressed,{binary:!0,optimizedBinaryString:!0,date:g.date,dir:g.dir,comment:g.fileCommentStr.length?g.fileCommentStr:null,unixPermissions:g.unixPermissions,dosPermissions:g.dosPermissions,createFolders:c.createFolders}),g.dir||(d.file(S).unsafeOriginalName=y)}return h.zipComment.length&&(d.comment=h.zipComment),d})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(v,f,t){"use strict";var e=v("../utils"),s=v("../stream/GenericWorker");function i(n,r){s.call(this,"Nodejs stream input adapter for "+n),this._upstreamEnded=!1,this._bindStream(r)}e.inherits(i,s),i.prototype._bindStream=function(n){var r=this;(this._stream=n).pause(),n.on("data",function(o){r.push({data:o,meta:{percent:0}})}).on("error",function(o){r.isPaused?this.generatedError=o:r.error(o)}).on("end",function(){r.isPaused?r._upstreamEnded=!0:r.end()})},i.prototype.pause=function(){return!!s.prototype.pause.call(this)&&(this._stream.pause(),!0)},i.prototype.resume=function(){return!!s.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},f.exports=i},{"../stream/GenericWorker":28,"../utils":32}],13:[function(v,f,t){"use strict";var e=v("readable-stream").Readable;function s(i,n,r){e.call(this,n),this._helper=i;var o=this;i.on("data",function(a,l){o.push(a)||o._helper.pause(),r&&r(l)}).on("error",function(a){o.emit("error",a)}).on("end",function(){o.push(null)})}v("../utils").inherits(s,e),s.prototype._read=function(){this._helper.resume()},f.exports=s},{"../utils":32,"readable-stream":16}],14:[function(v,f,t){"use strict";f.exports={isNode:typeof Buffer<"u",newBufferFrom:function(e,s){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,s);if(typeof e=="number")throw new Error('The "data" argument must not be a number');return new Buffer(e,s)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var s=new Buffer(e);return s.fill(0),s},isBuffer:function(e){return Buffer.isBuffer(e)},isStream:function(e){return e&&typeof e.on=="function"&&typeof e.pause=="function"&&typeof e.resume=="function"}}},{}],15:[function(v,f,t){"use strict";function e(S,k,x){var I,E=i.getTypeOf(k),D=i.extend(x||{},o);D.date=D.date||new Date,D.compression!==null&&(D.compression=D.compression.toUpperCase()),typeof D.unixPermissions=="string"&&(D.unixPermissions=parseInt(D.unixPermissions,8)),D.unixPermissions&&16384&D.unixPermissions&&(D.dir=!0),D.dosPermissions&&16&D.dosPermissions&&(D.dir=!0),D.dir&&(S=u(S)),D.createFolders&&(I=h(S))&&m.call(this,I,!0);var $=E==="string"&&D.binary===!1&&D.base64===!1;x&&x.binary!==void 0||(D.binary=!$),(k instanceof a&&k.uncompressedSize===0||D.dir||!k||k.length===0)&&(D.base64=!1,D.binary=!0,k="",D.compression="STORE",E="string");var F=null;F=k instanceof a||k instanceof n?k:d.isNode&&d.isStream(k)?new p(S,k):i.prepareContent(S,k,D.binary,D.optimizedBinaryString,D.base64);var P=new l(S,F,D);this.files[S]=P}var s=v("./utf8"),i=v("./utils"),n=v("./stream/GenericWorker"),r=v("./stream/StreamHelper"),o=v("./defaults"),a=v("./compressedObject"),l=v("./zipObject"),c=v("./generate"),d=v("./nodejsUtils"),p=v("./nodejs/NodejsStreamInputAdapter"),h=function(S){S.slice(-1)==="/"&&(S=S.substring(0,S.length-1));var k=S.lastIndexOf("/");return 0<k?S.substring(0,k):""},u=function(S){return S.slice(-1)!=="/"&&(S+="/"),S},m=function(S,k){return k=k!==void 0?k:o.createFolders,S=u(S),this.files[S]||e.call(this,S,null,{dir:!0,createFolders:k}),this.files[S]};function g(S){return Object.prototype.toString.call(S)==="[object RegExp]"}var y={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(S){var k,x,I;for(k in this.files)I=this.files[k],(x=k.slice(this.root.length,k.length))&&k.slice(0,this.root.length)===this.root&&S(x,I)},filter:function(S){var k=[];return this.forEach(function(x,I){S(x,I)&&k.push(I)}),k},file:function(S,k,x){if(arguments.length!==1)return S=this.root+S,e.call(this,S,k,x),this;if(g(S)){var I=S;return this.filter(function(D,$){return!$.dir&&I.test(D)})}var E=this.files[this.root+S];return E&&!E.dir?E:null},folder:function(S){if(!S)return this;if(g(S))return this.filter(function(E,D){return D.dir&&S.test(E)});var k=this.root+S,x=m.call(this,k),I=this.clone();return I.root=x.name,I},remove:function(S){S=this.root+S;var k=this.files[S];if(k||(S.slice(-1)!=="/"&&(S+="/"),k=this.files[S]),k&&!k.dir)delete this.files[S];else for(var x=this.filter(function(E,D){return D.name.slice(0,S.length)===S}),I=0;I<x.length;I++)delete this.files[x[I].name];return this},generate:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(S){var k,x={};try{if((x=i.extend(S||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:s.utf8encode})).type=x.type.toLowerCase(),x.compression=x.compression.toUpperCase(),x.type==="binarystring"&&(x.type="string"),!x.type)throw new Error("No output type specified.");i.checkSupport(x.type),x.platform!=="darwin"&&x.platform!=="freebsd"&&x.platform!=="linux"&&x.platform!=="sunos"||(x.platform="UNIX"),x.platform==="win32"&&(x.platform="DOS");var I=x.comment||this.comment||"";k=c.generateWorker(this,x,I)}catch(E){(k=new n("error")).error(E)}return new r(k,x.type||"string",x.mimeType)},generateAsync:function(S,k){return this.generateInternalStream(S).accumulate(k)},generateNodeStream:function(S,k){return(S=S||{}).type||(S.type="nodebuffer"),this.generateInternalStream(S).toNodejsStream(k)}};f.exports=y},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(v,f,t){"use strict";f.exports=v("stream")},{stream:void 0}],17:[function(v,f,t){"use strict";var e=v("./DataReader");function s(i){e.call(this,i);for(var n=0;n<this.data.length;n++)i[n]=255&i[n]}v("../utils").inherits(s,e),s.prototype.byteAt=function(i){return this.data[this.zero+i]},s.prototype.lastIndexOfSignature=function(i){for(var n=i.charCodeAt(0),r=i.charCodeAt(1),o=i.charCodeAt(2),a=i.charCodeAt(3),l=this.length-4;0<=l;--l)if(this.data[l]===n&&this.data[l+1]===r&&this.data[l+2]===o&&this.data[l+3]===a)return l-this.zero;return-1},s.prototype.readAndCheckSignature=function(i){var n=i.charCodeAt(0),r=i.charCodeAt(1),o=i.charCodeAt(2),a=i.charCodeAt(3),l=this.readData(4);return n===l[0]&&r===l[1]&&o===l[2]&&a===l[3]},s.prototype.readData=function(i){if(this.checkOffset(i),i===0)return[];var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./DataReader":18}],18:[function(v,f,t){"use strict";var e=v("../utils");function s(i){this.data=i,this.length=i.length,this.index=0,this.zero=0}s.prototype={checkOffset:function(i){this.checkIndex(this.index+i)},checkIndex:function(i){if(this.length<this.zero+i||i<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+i+"). Corrupted zip ?")},setIndex:function(i){this.checkIndex(i),this.index=i},skip:function(i){this.setIndex(this.index+i)},byteAt:function(){},readInt:function(i){var n,r=0;for(this.checkOffset(i),n=this.index+i-1;n>=this.index;n--)r=(r<<8)+this.byteAt(n);return this.index+=i,r},readString:function(i){return e.transformTo("string",this.readData(i))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var i=this.readInt(4);return new Date(Date.UTC(1980+(i>>25&127),(i>>21&15)-1,i>>16&31,i>>11&31,i>>5&63,(31&i)<<1))}},f.exports=s},{"../utils":32}],19:[function(v,f,t){"use strict";var e=v("./Uint8ArrayReader");function s(i){e.call(this,i)}v("../utils").inherits(s,e),s.prototype.readData=function(i){this.checkOffset(i);var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(v,f,t){"use strict";var e=v("./DataReader");function s(i){e.call(this,i)}v("../utils").inherits(s,e),s.prototype.byteAt=function(i){return this.data.charCodeAt(this.zero+i)},s.prototype.lastIndexOfSignature=function(i){return this.data.lastIndexOf(i)-this.zero},s.prototype.readAndCheckSignature=function(i){return i===this.readData(4)},s.prototype.readData=function(i){this.checkOffset(i);var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./DataReader":18}],21:[function(v,f,t){"use strict";var e=v("./ArrayReader");function s(i){e.call(this,i)}v("../utils").inherits(s,e),s.prototype.readData=function(i){if(this.checkOffset(i),i===0)return new Uint8Array(0);var n=this.data.subarray(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./ArrayReader":17}],22:[function(v,f,t){"use strict";var e=v("../utils"),s=v("../support"),i=v("./ArrayReader"),n=v("./StringReader"),r=v("./NodeBufferReader"),o=v("./Uint8ArrayReader");f.exports=function(a){var l=e.getTypeOf(a);return e.checkSupport(l),l!=="string"||s.uint8array?l==="nodebuffer"?new r(a):s.uint8array?new o(e.transformTo("uint8array",a)):new i(e.transformTo("array",a)):new n(a)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(v,f,t){"use strict";t.LOCAL_FILE_HEADER="PK",t.CENTRAL_FILE_HEADER="PK",t.CENTRAL_DIRECTORY_END="PK",t.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK\x07",t.ZIP64_CENTRAL_DIRECTORY_END="PK",t.DATA_DESCRIPTOR="PK\x07\b"},{}],24:[function(v,f,t){"use strict";var e=v("./GenericWorker"),s=v("../utils");function i(n){e.call(this,"ConvertWorker to "+n),this.destType=n}s.inherits(i,e),i.prototype.processChunk=function(n){this.push({data:s.transformTo(this.destType,n.data),meta:n.meta})},f.exports=i},{"../utils":32,"./GenericWorker":28}],25:[function(v,f,t){"use strict";var e=v("./GenericWorker"),s=v("../crc32");function i(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}v("../utils").inherits(i,e),i.prototype.processChunk=function(n){this.streamInfo.crc32=s(n.data,this.streamInfo.crc32||0),this.push(n)},f.exports=i},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(v,f,t){"use strict";var e=v("../utils"),s=v("./GenericWorker");function i(n){s.call(this,"DataLengthProbe for "+n),this.propName=n,this.withStreamInfo(n,0)}e.inherits(i,s),i.prototype.processChunk=function(n){if(n){var r=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=r+n.data.length}s.prototype.processChunk.call(this,n)},f.exports=i},{"../utils":32,"./GenericWorker":28}],27:[function(v,f,t){"use strict";var e=v("../utils"),s=v("./GenericWorker");function i(n){s.call(this,"DataWorker");var r=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,n.then(function(o){r.dataIsReady=!0,r.data=o,r.max=o&&o.length||0,r.type=e.getTypeOf(o),r.isPaused||r._tickAndRepeat()},function(o){r.error(o)})}e.inherits(i,s),i.prototype.cleanUp=function(){s.prototype.cleanUp.call(this),this.data=null},i.prototype.resume=function(){return!!s.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,e.delay(this._tickAndRepeat,[],this)),!0)},i.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(e.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},i.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var n=null,r=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":n=this.data.substring(this.index,r);break;case"uint8array":n=this.data.subarray(this.index,r);break;case"array":case"nodebuffer":n=this.data.slice(this.index,r)}return this.index=r,this.push({data:n,meta:{percent:this.max?this.index/this.max*100:0}})},f.exports=i},{"../utils":32,"./GenericWorker":28}],28:[function(v,f,t){"use strict";function e(s){this.name=s||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}e.prototype={push:function(s){this.emit("data",s)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(s){this.emit("error",s)}return!0},error:function(s){return!this.isFinished&&(this.isPaused?this.generatedError=s:(this.isFinished=!0,this.emit("error",s),this.previous&&this.previous.error(s),this.cleanUp()),!0)},on:function(s,i){return this._listeners[s].push(i),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(s,i){if(this._listeners[s])for(var n=0;n<this._listeners[s].length;n++)this._listeners[s][n].call(this,i)},pipe:function(s){return s.registerPrevious(this)},registerPrevious:function(s){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=s.streamInfo,this.mergeStreamInfo(),this.previous=s;var i=this;return s.on("data",function(n){i.processChunk(n)}),s.on("end",function(){i.end()}),s.on("error",function(n){i.error(n)}),this},pause:function(){return!this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return!1;var s=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),s=!0),this.previous&&this.previous.resume(),!s},flush:function(){},processChunk:function(s){this.push(s)},withStreamInfo:function(s,i){return this.extraStreamInfo[s]=i,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var s in this.extraStreamInfo)Object.prototype.hasOwnProperty.call(this.extraStreamInfo,s)&&(this.streamInfo[s]=this.extraStreamInfo[s])},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock()},toString:function(){var s="Worker "+this.name;return this.previous?this.previous+" -> "+s:s}},f.exports=e},{}],29:[function(v,f,t){"use strict";var e=v("../utils"),s=v("./ConvertWorker"),i=v("./GenericWorker"),n=v("../base64"),r=v("../support"),o=v("../external"),a=null;if(r.nodestream)try{a=v("../nodejs/NodejsStreamOutputAdapter")}catch{}function l(d,p){return new o.Promise(function(h,u){var m=[],g=d._internalType,y=d._outputType,S=d._mimeType;d.on("data",function(k,x){m.push(k),p&&p(x)}).on("error",function(k){m=[],u(k)}).on("end",function(){try{var k=function(x,I,E){switch(x){case"blob":return e.newBlob(e.transformTo("arraybuffer",I),E);case"base64":return n.encode(I);default:return e.transformTo(x,I)}}(y,function(x,I){var E,D=0,$=null,F=0;for(E=0;E<I.length;E++)F+=I[E].length;switch(x){case"string":return I.join("");case"array":return Array.prototype.concat.apply([],I);case"uint8array":for($=new Uint8Array(F),E=0;E<I.length;E++)$.set(I[E],D),D+=I[E].length;return $;case"nodebuffer":return Buffer.concat(I);default:throw new Error("concat : unsupported type '"+x+"'")}}(g,m),S);h(k)}catch(x){u(x)}m=[]}).resume()})}function c(d,p,h){var u=p;switch(p){case"blob":case"arraybuffer":u="uint8array";break;case"base64":u="string"}try{this._internalType=u,this._outputType=p,this._mimeType=h,e.checkSupport(u),this._worker=d.pipe(new s(u)),d.lock()}catch(m){this._worker=new i("error"),this._worker.error(m)}}c.prototype={accumulate:function(d){return l(this,d)},on:function(d,p){var h=this;return d==="data"?this._worker.on(d,function(u){p.call(h,u.data,u.meta)}):this._worker.on(d,function(){e.delay(p,arguments,h)}),this},resume:function(){return e.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(d){if(e.checkSupport("nodestream"),this._outputType!=="nodebuffer")throw new Error(this._outputType+" is not supported by this method");return new a(this,{objectMode:this._outputType!=="nodebuffer"},d)}},f.exports=c},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(v,f,t){"use strict";if(t.base64=!0,t.array=!0,t.string=!0,t.arraybuffer=typeof ArrayBuffer<"u"&&typeof Uint8Array<"u",t.nodebuffer=typeof Buffer<"u",t.uint8array=typeof Uint8Array<"u",typeof ArrayBuffer>"u")t.blob=!1;else{var e=new ArrayBuffer(0);try{t.blob=new Blob([e],{type:"application/zip"}).size===0}catch{try{var s=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);s.append(e),t.blob=s.getBlob("application/zip").size===0}catch{t.blob=!1}}}try{t.nodestream=!!v("readable-stream").Readable}catch{t.nodestream=!1}},{"readable-stream":16}],31:[function(v,f,t){"use strict";for(var e=v("./utils"),s=v("./support"),i=v("./nodejsUtils"),n=v("./stream/GenericWorker"),r=new Array(256),o=0;o<256;o++)r[o]=252<=o?6:248<=o?5:240<=o?4:224<=o?3:192<=o?2:1;r[254]=r[254]=1;function a(){n.call(this,"utf-8 decode"),this.leftOver=null}function l(){n.call(this,"utf-8 encode")}t.utf8encode=function(c){return s.nodebuffer?i.newBufferFrom(c,"utf-8"):function(d){var p,h,u,m,g,y=d.length,S=0;for(m=0;m<y;m++)(64512&(h=d.charCodeAt(m)))==55296&&m+1<y&&(64512&(u=d.charCodeAt(m+1)))==56320&&(h=65536+(h-55296<<10)+(u-56320),m++),S+=h<128?1:h<2048?2:h<65536?3:4;for(p=s.uint8array?new Uint8Array(S):new Array(S),m=g=0;g<S;m++)(64512&(h=d.charCodeAt(m)))==55296&&m+1<y&&(64512&(u=d.charCodeAt(m+1)))==56320&&(h=65536+(h-55296<<10)+(u-56320),m++),h<128?p[g++]=h:(h<2048?p[g++]=192|h>>>6:(h<65536?p[g++]=224|h>>>12:(p[g++]=240|h>>>18,p[g++]=128|h>>>12&63),p[g++]=128|h>>>6&63),p[g++]=128|63&h);return p}(c)},t.utf8decode=function(c){return s.nodebuffer?e.transformTo("nodebuffer",c).toString("utf-8"):function(d){var p,h,u,m,g=d.length,y=new Array(2*g);for(p=h=0;p<g;)if((u=d[p++])<128)y[h++]=u;else if(4<(m=r[u]))y[h++]=65533,p+=m-1;else{for(u&=m===2?31:m===3?15:7;1<m&&p<g;)u=u<<6|63&d[p++],m--;1<m?y[h++]=65533:u<65536?y[h++]=u:(u-=65536,y[h++]=55296|u>>10&1023,y[h++]=56320|1023&u)}return y.length!==h&&(y.subarray?y=y.subarray(0,h):y.length=h),e.applyFromCharCode(y)}(c=e.transformTo(s.uint8array?"uint8array":"array",c))},e.inherits(a,n),a.prototype.processChunk=function(c){var d=e.transformTo(s.uint8array?"uint8array":"array",c.data);if(this.leftOver&&this.leftOver.length){if(s.uint8array){var p=d;(d=new Uint8Array(p.length+this.leftOver.length)).set(this.leftOver,0),d.set(p,this.leftOver.length)}else d=this.leftOver.concat(d);this.leftOver=null}var h=function(m,g){var y;for((g=g||m.length)>m.length&&(g=m.length),y=g-1;0<=y&&(192&m[y])==128;)y--;return y<0||y===0?g:y+r[m[y]]>g?y:g}(d),u=d;h!==d.length&&(s.uint8array?(u=d.subarray(0,h),this.leftOver=d.subarray(h,d.length)):(u=d.slice(0,h),this.leftOver=d.slice(h,d.length))),this.push({data:t.utf8decode(u),meta:c.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:t.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},t.Utf8DecodeWorker=a,e.inherits(l,n),l.prototype.processChunk=function(c){this.push({data:t.utf8encode(c.data),meta:c.meta})},t.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(v,f,t){"use strict";var e=v("./support"),s=v("./base64"),i=v("./nodejsUtils"),n=v("./external");function r(p){return p}function o(p,h){for(var u=0;u<p.length;++u)h[u]=255&p.charCodeAt(u);return h}v("setimmediate"),t.newBlob=function(p,h){t.checkSupport("blob");try{return new Blob([p],{type:h})}catch{try{var u=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return u.append(p),u.getBlob(h)}catch{throw new Error("Bug : can't construct the Blob.")}}};var a={stringifyByChunk:function(p,h,u){var m=[],g=0,y=p.length;if(y<=u)return String.fromCharCode.apply(null,p);for(;g<y;)h==="array"||h==="nodebuffer"?m.push(String.fromCharCode.apply(null,p.slice(g,Math.min(g+u,y)))):m.push(String.fromCharCode.apply(null,p.subarray(g,Math.min(g+u,y)))),g+=u;return m.join("")},stringifyByChar:function(p){for(var h="",u=0;u<p.length;u++)h+=String.fromCharCode(p[u]);return h},applyCanBeUsed:{uint8array:function(){try{return e.uint8array&&String.fromCharCode.apply(null,new Uint8Array(1)).length===1}catch{return!1}}(),nodebuffer:function(){try{return e.nodebuffer&&String.fromCharCode.apply(null,i.allocBuffer(1)).length===1}catch{return!1}}()}};function l(p){var h=65536,u=t.getTypeOf(p),m=!0;if(u==="uint8array"?m=a.applyCanBeUsed.uint8array:u==="nodebuffer"&&(m=a.applyCanBeUsed.nodebuffer),m)for(;1<h;)try{return a.stringifyByChunk(p,u,h)}catch{h=Math.floor(h/2)}return a.stringifyByChar(p)}function c(p,h){for(var u=0;u<p.length;u++)h[u]=p[u];return h}t.applyFromCharCode=l;var d={};d.string={string:r,array:function(p){return o(p,new Array(p.length))},arraybuffer:function(p){return d.string.uint8array(p).buffer},uint8array:function(p){return o(p,new Uint8Array(p.length))},nodebuffer:function(p){return o(p,i.allocBuffer(p.length))}},d.array={string:l,array:r,arraybuffer:function(p){return new Uint8Array(p).buffer},uint8array:function(p){return new Uint8Array(p)},nodebuffer:function(p){return i.newBufferFrom(p)}},d.arraybuffer={string:function(p){return l(new Uint8Array(p))},array:function(p){return c(new Uint8Array(p),new Array(p.byteLength))},arraybuffer:r,uint8array:function(p){return new Uint8Array(p)},nodebuffer:function(p){return i.newBufferFrom(new Uint8Array(p))}},d.uint8array={string:l,array:function(p){return c(p,new Array(p.length))},arraybuffer:function(p){return p.buffer},uint8array:r,nodebuffer:function(p){return i.newBufferFrom(p)}},d.nodebuffer={string:l,array:function(p){return c(p,new Array(p.length))},arraybuffer:function(p){return d.nodebuffer.uint8array(p).buffer},uint8array:function(p){return c(p,new Uint8Array(p.length))},nodebuffer:r},t.transformTo=function(p,h){if(h=h||"",!p)return h;t.checkSupport(p);var u=t.getTypeOf(h);return d[u][p](h)},t.resolve=function(p){for(var h=p.split("/"),u=[],m=0;m<h.length;m++){var g=h[m];g==="."||g===""&&m!==0&&m!==h.length-1||(g===".."?u.pop():u.push(g))}return u.join("/")},t.getTypeOf=function(p){return typeof p=="string"?"string":Object.prototype.toString.call(p)==="[object Array]"?"array":e.nodebuffer&&i.isBuffer(p)?"nodebuffer":e.uint8array&&p instanceof Uint8Array?"uint8array":e.arraybuffer&&p instanceof ArrayBuffer?"arraybuffer":void 0},t.checkSupport=function(p){if(!e[p.toLowerCase()])throw new Error(p+" is not supported by this platform")},t.MAX_VALUE_16BITS=65535,t.MAX_VALUE_32BITS=-1,t.pretty=function(p){var h,u,m="";for(u=0;u<(p||"").length;u++)m+="\\x"+((h=p.charCodeAt(u))<16?"0":"")+h.toString(16).toUpperCase();return m},t.delay=function(p,h,u){setImmediate(function(){p.apply(u||null,h||[])})},t.inherits=function(p,h){function u(){}u.prototype=h.prototype,p.prototype=new u},t.extend=function(){var p,h,u={};for(p=0;p<arguments.length;p++)for(h in arguments[p])Object.prototype.hasOwnProperty.call(arguments[p],h)&&u[h]===void 0&&(u[h]=arguments[p][h]);return u},t.prepareContent=function(p,h,u,m,g){return n.Promise.resolve(h).then(function(y){return e.blob&&(y instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(y))!==-1)&&typeof FileReader<"u"?new n.Promise(function(S,k){var x=new FileReader;x.onload=function(I){S(I.target.result)},x.onerror=function(I){k(I.target.error)},x.readAsArrayBuffer(y)}):y}).then(function(y){var S=t.getTypeOf(y);return S?(S==="arraybuffer"?y=t.transformTo("uint8array",y):S==="string"&&(g?y=s.decode(y):u&&m!==!0&&(y=function(k){return o(k,e.uint8array?new Uint8Array(k.length):new Array(k.length))}(y))),y):n.Promise.reject(new Error("Can't read the data of '"+p+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,setimmediate:54}],33:[function(v,f,t){"use strict";var e=v("./reader/readerFor"),s=v("./utils"),i=v("./signature"),n=v("./zipEntry"),r=v("./support");function o(a){this.files=[],this.loadOptions=a}o.prototype={checkSignature:function(a){if(!this.reader.readAndCheckSignature(a)){this.reader.index-=4;var l=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+s.pretty(l)+", expected "+s.pretty(a)+")")}},isSignature:function(a,l){var c=this.reader.index;this.reader.setIndex(a);var d=this.reader.readString(4)===l;return this.reader.setIndex(c),d},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var a=this.reader.readData(this.zipCommentLength),l=r.uint8array?"uint8array":"array",c=s.transformTo(l,a);this.zipComment=this.loadOptions.decodeFileName(c)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,l,c,d=this.zip64EndOfCentralSize-44;0<d;)a=this.reader.readInt(2),l=this.reader.readInt(4),c=this.reader.readData(l),this.zip64ExtensibleData[a]={id:a,length:l,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,l;for(a=0;a<this.files.length;a++)l=this.files[a],this.reader.setIndex(l.localHeaderOffset),this.checkSignature(i.LOCAL_FILE_HEADER),l.readLocalPart(this.reader),l.handleUTF8(),l.processAttributes()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(i.CENTRAL_FILE_HEADER);)(a=new n({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(a);if(this.centralDirRecords!==this.files.length&&this.centralDirRecords!==0&&this.files.length===0)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(i.CENTRAL_DIRECTORY_END);if(a<0)throw this.isSignature(0,i.LOCAL_FILE_HEADER)?new Error("Corrupted zip: can't find end of central directory"):new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");this.reader.setIndex(a);var l=a;if(this.checkSignature(i.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===s.MAX_VALUE_16BITS||this.diskWithCentralDirStart===s.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===s.MAX_VALUE_16BITS||this.centralDirRecords===s.MAX_VALUE_16BITS||this.centralDirSize===s.MAX_VALUE_32BITS||this.centralDirOffset===s.MAX_VALUE_32BITS){if(this.zip64=!0,(a=this.reader.lastIndexOfSignature(i.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(a),this.checkSignature(i.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,i.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(i.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(i.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var c=this.centralDirOffset+this.centralDirSize;this.zip64&&(c+=20,c+=12+this.zip64EndOfCentralSize);var d=l-c;if(0<d)this.isSignature(l,i.CENTRAL_FILE_HEADER)||(this.reader.zero=d);else if(d<0)throw new Error("Corrupted zip: missing "+Math.abs(d)+" bytes.")},prepareReader:function(a){this.reader=e(a)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},f.exports=o},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(v,f,t){"use strict";var e=v("./reader/readerFor"),s=v("./utils"),i=v("./compressedObject"),n=v("./crc32"),r=v("./utf8"),o=v("./compressions"),a=v("./support");function l(c,d){this.options=c,this.loadOptions=d}l.prototype={isEncrypted:function(){return(1&this.bitFlag)==1},useUTF8:function(){return(2048&this.bitFlag)==2048},readLocalPart:function(c){var d,p;if(c.skip(22),this.fileNameLength=c.readInt(2),p=c.readInt(2),this.fileName=c.readData(this.fileNameLength),c.skip(p),this.compressedSize===-1||this.uncompressedSize===-1)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if((d=function(h){for(var u in o)if(Object.prototype.hasOwnProperty.call(o,u)&&o[u].magic===h)return o[u];return null}(this.compressionMethod))===null)throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new i(this.compressedSize,this.uncompressedSize,this.crc32,d,c.readData(this.compressedSize))},readCentralPart:function(c){this.versionMadeBy=c.readInt(2),c.skip(2),this.bitFlag=c.readInt(2),this.compressionMethod=c.readString(2),this.date=c.readDate(),this.crc32=c.readInt(4),this.compressedSize=c.readInt(4),this.uncompressedSize=c.readInt(4);var d=c.readInt(2);if(this.extraFieldsLength=c.readInt(2),this.fileCommentLength=c.readInt(2),this.diskNumberStart=c.readInt(2),this.internalFileAttributes=c.readInt(2),this.externalFileAttributes=c.readInt(4),this.localHeaderOffset=c.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");c.skip(d),this.readExtraFields(c),this.parseZIP64ExtraField(c),this.fileComment=c.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var c=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),c==0&&(this.dosPermissions=63&this.externalFileAttributes),c==3&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||this.fileNameStr.slice(-1)!=="/"||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var c=e(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=c.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=c.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=c.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=c.readInt(4))}},readExtraFields:function(c){var d,p,h,u=c.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});c.index+4<u;)d=c.readInt(2),p=c.readInt(2),h=c.readData(p),this.extraFields[d]={id:d,length:p,value:h};c.setIndex(u)},handleUTF8:function(){var c=a.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=r.utf8decode(this.fileName),this.fileCommentStr=r.utf8decode(this.fileComment);else{var d=this.findExtraFieldUnicodePath();if(d!==null)this.fileNameStr=d;else{var p=s.transformTo(c,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(p)}var h=this.findExtraFieldUnicodeComment();if(h!==null)this.fileCommentStr=h;else{var u=s.transformTo(c,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(u)}}},findExtraFieldUnicodePath:function(){var c=this.extraFields[28789];if(c){var d=e(c.value);return d.readInt(1)!==1||n(this.fileName)!==d.readInt(4)?null:r.utf8decode(d.readData(c.length-5))}return null},findExtraFieldUnicodeComment:function(){var c=this.extraFields[25461];if(c){var d=e(c.value);return d.readInt(1)!==1||n(this.fileComment)!==d.readInt(4)?null:r.utf8decode(d.readData(c.length-5))}return null}},f.exports=l},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(v,f,t){"use strict";function e(d,p,h){this.name=d,this.dir=h.dir,this.date=h.date,this.comment=h.comment,this.unixPermissions=h.unixPermissions,this.dosPermissions=h.dosPermissions,this._data=p,this._dataBinary=h.binary,this.options={compression:h.compression,compressionOptions:h.compressionOptions}}var s=v("./stream/StreamHelper"),i=v("./stream/DataWorker"),n=v("./utf8"),r=v("./compressedObject"),o=v("./stream/GenericWorker");e.prototype={internalStream:function(d){var p=null,h="string";try{if(!d)throw new Error("No output type specified.");var u=(h=d.toLowerCase())==="string"||h==="text";h!=="binarystring"&&h!=="text"||(h="string"),p=this._decompressWorker();var m=!this._dataBinary;m&&!u&&(p=p.pipe(new n.Utf8EncodeWorker)),!m&&u&&(p=p.pipe(new n.Utf8DecodeWorker))}catch(g){(p=new o("error")).error(g)}return new s(p,h,"")},async:function(d,p){return this.internalStream(d).accumulate(p)},nodeStream:function(d,p){return this.internalStream(d||"nodebuffer").toNodejsStream(p)},_compressWorker:function(d,p){if(this._data instanceof r&&this._data.compression.magic===d.magic)return this._data.getCompressedWorker();var h=this._decompressWorker();return this._dataBinary||(h=h.pipe(new n.Utf8EncodeWorker)),r.createWorkerFrom(h,d,p)},_decompressWorker:function(){return this._data instanceof r?this._data.getContentWorker():this._data instanceof o?this._data:new i(this._data)}};for(var a=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],l=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},c=0;c<a.length;c++)e.prototype[a[c]]=l;f.exports=e},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(v,f,t){(function(e){"use strict";var s,i,n=e.MutationObserver||e.WebKitMutationObserver;if(n){var r=0,o=new n(d),a=e.document.createTextNode("");o.observe(a,{characterData:!0}),s=function(){a.data=r=++r%2}}else if(e.setImmediate||e.MessageChannel===void 0)s="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var p=e.document.createElement("script");p.onreadystatechange=function(){d(),p.onreadystatechange=null,p.parentNode.removeChild(p),p=null},e.document.documentElement.appendChild(p)}:function(){setTimeout(d,0)};else{var l=new e.MessageChannel;l.port1.onmessage=d,s=function(){l.port2.postMessage(0)}}var c=[];function d(){var p,h;i=!0;for(var u=c.length;u;){for(h=c,c=[],p=-1;++p<u;)h[p]();u=c.length}i=!1}f.exports=function(p){c.push(p)!==1||i||s()}}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}],37:[function(v,f,t){"use strict";var e=v("immediate");function s(){}var i={},n=["REJECTED"],r=["FULFILLED"],o=["PENDING"];function a(u){if(typeof u!="function")throw new TypeError("resolver must be a function");this.state=o,this.queue=[],this.outcome=void 0,u!==s&&p(this,u)}function l(u,m,g){this.promise=u,typeof m=="function"&&(this.onFulfilled=m,this.callFulfilled=this.otherCallFulfilled),typeof g=="function"&&(this.onRejected=g,this.callRejected=this.otherCallRejected)}function c(u,m,g){e(function(){var y;try{y=m(g)}catch(S){return i.reject(u,S)}y===u?i.reject(u,new TypeError("Cannot resolve promise with itself")):i.resolve(u,y)})}function d(u){var m=u&&u.then;if(u&&(typeof u=="object"||typeof u=="function")&&typeof m=="function")return function(){m.apply(u,arguments)}}function p(u,m){var g=!1;function y(x){g||(g=!0,i.reject(u,x))}function S(x){g||(g=!0,i.resolve(u,x))}var k=h(function(){m(S,y)});k.status==="error"&&y(k.value)}function h(u,m){var g={};try{g.value=u(m),g.status="success"}catch(y){g.status="error",g.value=y}return g}(f.exports=a).prototype.finally=function(u){if(typeof u!="function")return this;var m=this.constructor;return this.then(function(g){return m.resolve(u()).then(function(){return g})},function(g){return m.resolve(u()).then(function(){throw g})})},a.prototype.catch=function(u){return this.then(null,u)},a.prototype.then=function(u,m){if(typeof u!="function"&&this.state===r||typeof m!="function"&&this.state===n)return this;var g=new this.constructor(s);return this.state!==o?c(g,this.state===r?u:m,this.outcome):this.queue.push(new l(g,u,m)),g},l.prototype.callFulfilled=function(u){i.resolve(this.promise,u)},l.prototype.otherCallFulfilled=function(u){c(this.promise,this.onFulfilled,u)},l.prototype.callRejected=function(u){i.reject(this.promise,u)},l.prototype.otherCallRejected=function(u){c(this.promise,this.onRejected,u)},i.resolve=function(u,m){var g=h(d,m);if(g.status==="error")return i.reject(u,g.value);var y=g.value;if(y)p(u,y);else{u.state=r,u.outcome=m;for(var S=-1,k=u.queue.length;++S<k;)u.queue[S].callFulfilled(m)}return u},i.reject=function(u,m){u.state=n,u.outcome=m;for(var g=-1,y=u.queue.length;++g<y;)u.queue[g].callRejected(m);return u},a.resolve=function(u){return u instanceof this?u:i.resolve(new this(s),u)},a.reject=function(u){var m=new this(s);return i.reject(m,u)},a.all=function(u){var m=this;if(Object.prototype.toString.call(u)!=="[object Array]")return this.reject(new TypeError("must be an array"));var g=u.length,y=!1;if(!g)return this.resolve([]);for(var S=new Array(g),k=0,x=-1,I=new this(s);++x<g;)E(u[x],x);return I;function E(D,$){m.resolve(D).then(function(F){S[$]=F,++k!==g||y||(y=!0,i.resolve(I,S))},function(F){y||(y=!0,i.reject(I,F))})}},a.race=function(u){var m=this;if(Object.prototype.toString.call(u)!=="[object Array]")return this.reject(new TypeError("must be an array"));var g=u.length,y=!1;if(!g)return this.resolve([]);for(var S=-1,k=new this(s);++S<g;)x=u[S],m.resolve(x).then(function(I){y||(y=!0,i.resolve(k,I))},function(I){y||(y=!0,i.reject(k,I))});var x;return k}},{immediate:36}],38:[function(v,f,t){"use strict";var e={};(0,v("./lib/utils/common").assign)(e,v("./lib/deflate"),v("./lib/inflate"),v("./lib/zlib/constants")),f.exports=e},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(v,f,t){"use strict";var e=v("./zlib/deflate"),s=v("./utils/common"),i=v("./utils/strings"),n=v("./zlib/messages"),r=v("./zlib/zstream"),o=Object.prototype.toString,a=0,l=-1,c=0,d=8;function p(u){if(!(this instanceof p))return new p(u);this.options=s.assign({level:l,method:d,chunkSize:16384,windowBits:15,memLevel:8,strategy:c,to:""},u||{});var m=this.options;m.raw&&0<m.windowBits?m.windowBits=-m.windowBits:m.gzip&&0<m.windowBits&&m.windowBits<16&&(m.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new r,this.strm.avail_out=0;var g=e.deflateInit2(this.strm,m.level,m.method,m.windowBits,m.memLevel,m.strategy);if(g!==a)throw new Error(n[g]);if(m.header&&e.deflateSetHeader(this.strm,m.header),m.dictionary){var y;if(y=typeof m.dictionary=="string"?i.string2buf(m.dictionary):o.call(m.dictionary)==="[object ArrayBuffer]"?new Uint8Array(m.dictionary):m.dictionary,(g=e.deflateSetDictionary(this.strm,y))!==a)throw new Error(n[g]);this._dict_set=!0}}function h(u,m){var g=new p(m);if(g.push(u,!0),g.err)throw g.msg||n[g.err];return g.result}p.prototype.push=function(u,m){var g,y,S=this.strm,k=this.options.chunkSize;if(this.ended)return!1;y=m===~~m?m:m===!0?4:0,typeof u=="string"?S.input=i.string2buf(u):o.call(u)==="[object ArrayBuffer]"?S.input=new Uint8Array(u):S.input=u,S.next_in=0,S.avail_in=S.input.length;do{if(S.avail_out===0&&(S.output=new s.Buf8(k),S.next_out=0,S.avail_out=k),(g=e.deflate(S,y))!==1&&g!==a)return this.onEnd(g),!(this.ended=!0);S.avail_out!==0&&(S.avail_in!==0||y!==4&&y!==2)||(this.options.to==="string"?this.onData(i.buf2binstring(s.shrinkBuf(S.output,S.next_out))):this.onData(s.shrinkBuf(S.output,S.next_out)))}while((0<S.avail_in||S.avail_out===0)&&g!==1);return y===4?(g=e.deflateEnd(this.strm),this.onEnd(g),this.ended=!0,g===a):y!==2||(this.onEnd(a),!(S.avail_out=0))},p.prototype.onData=function(u){this.chunks.push(u)},p.prototype.onEnd=function(u){u===a&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=u,this.msg=this.strm.msg},t.Deflate=p,t.deflate=h,t.deflateRaw=function(u,m){return(m=m||{}).raw=!0,h(u,m)},t.gzip=function(u,m){return(m=m||{}).gzip=!0,h(u,m)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(v,f,t){"use strict";var e=v("./zlib/inflate"),s=v("./utils/common"),i=v("./utils/strings"),n=v("./zlib/constants"),r=v("./zlib/messages"),o=v("./zlib/zstream"),a=v("./zlib/gzheader"),l=Object.prototype.toString;function c(p){if(!(this instanceof c))return new c(p);this.options=s.assign({chunkSize:16384,windowBits:0,to:""},p||{});var h=this.options;h.raw&&0<=h.windowBits&&h.windowBits<16&&(h.windowBits=-h.windowBits,h.windowBits===0&&(h.windowBits=-15)),!(0<=h.windowBits&&h.windowBits<16)||p&&p.windowBits||(h.windowBits+=32),15<h.windowBits&&h.windowBits<48&&!(15&h.windowBits)&&(h.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new o,this.strm.avail_out=0;var u=e.inflateInit2(this.strm,h.windowBits);if(u!==n.Z_OK)throw new Error(r[u]);this.header=new a,e.inflateGetHeader(this.strm,this.header)}function d(p,h){var u=new c(h);if(u.push(p,!0),u.err)throw u.msg||r[u.err];return u.result}c.prototype.push=function(p,h){var u,m,g,y,S,k,x=this.strm,I=this.options.chunkSize,E=this.options.dictionary,D=!1;if(this.ended)return!1;m=h===~~h?h:h===!0?n.Z_FINISH:n.Z_NO_FLUSH,typeof p=="string"?x.input=i.binstring2buf(p):l.call(p)==="[object ArrayBuffer]"?x.input=new Uint8Array(p):x.input=p,x.next_in=0,x.avail_in=x.input.length;do{if(x.avail_out===0&&(x.output=new s.Buf8(I),x.next_out=0,x.avail_out=I),(u=e.inflate(x,n.Z_NO_FLUSH))===n.Z_NEED_DICT&&E&&(k=typeof E=="string"?i.string2buf(E):l.call(E)==="[object ArrayBuffer]"?new Uint8Array(E):E,u=e.inflateSetDictionary(this.strm,k)),u===n.Z_BUF_ERROR&&D===!0&&(u=n.Z_OK,D=!1),u!==n.Z_STREAM_END&&u!==n.Z_OK)return this.onEnd(u),!(this.ended=!0);x.next_out&&(x.avail_out!==0&&u!==n.Z_STREAM_END&&(x.avail_in!==0||m!==n.Z_FINISH&&m!==n.Z_SYNC_FLUSH)||(this.options.to==="string"?(g=i.utf8border(x.output,x.next_out),y=x.next_out-g,S=i.buf2string(x.output,g),x.next_out=y,x.avail_out=I-y,y&&s.arraySet(x.output,x.output,g,y,0),this.onData(S)):this.onData(s.shrinkBuf(x.output,x.next_out)))),x.avail_in===0&&x.avail_out===0&&(D=!0)}while((0<x.avail_in||x.avail_out===0)&&u!==n.Z_STREAM_END);return u===n.Z_STREAM_END&&(m=n.Z_FINISH),m===n.Z_FINISH?(u=e.inflateEnd(this.strm),this.onEnd(u),this.ended=!0,u===n.Z_OK):m!==n.Z_SYNC_FLUSH||(this.onEnd(n.Z_OK),!(x.avail_out=0))},c.prototype.onData=function(p){this.chunks.push(p)},c.prototype.onEnd=function(p){p===n.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=p,this.msg=this.strm.msg},t.Inflate=c,t.inflate=d,t.inflateRaw=function(p,h){return(h=h||{}).raw=!0,d(p,h)},t.ungzip=d},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(v,f,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";t.assign=function(n){for(var r=Array.prototype.slice.call(arguments,1);r.length;){var o=r.shift();if(o){if(typeof o!="object")throw new TypeError(o+"must be non-object");for(var a in o)o.hasOwnProperty(a)&&(n[a]=o[a])}}return n},t.shrinkBuf=function(n,r){return n.length===r?n:n.subarray?n.subarray(0,r):(n.length=r,n)};var s={arraySet:function(n,r,o,a,l){if(r.subarray&&n.subarray)n.set(r.subarray(o,o+a),l);else for(var c=0;c<a;c++)n[l+c]=r[o+c]},flattenChunks:function(n){var r,o,a,l,c,d;for(r=a=0,o=n.length;r<o;r++)a+=n[r].length;for(d=new Uint8Array(a),r=l=0,o=n.length;r<o;r++)c=n[r],d.set(c,l),l+=c.length;return d}},i={arraySet:function(n,r,o,a,l){for(var c=0;c<a;c++)n[l+c]=r[o+c]},flattenChunks:function(n){return[].concat.apply([],n)}};t.setTyped=function(n){n?(t.Buf8=Uint8Array,t.Buf16=Uint16Array,t.Buf32=Int32Array,t.assign(t,s)):(t.Buf8=Array,t.Buf16=Array,t.Buf32=Array,t.assign(t,i))},t.setTyped(e)},{}],42:[function(v,f,t){"use strict";var e=v("./common"),s=!0,i=!0;try{String.fromCharCode.apply(null,[0])}catch{s=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch{i=!1}for(var n=new e.Buf8(256),r=0;r<256;r++)n[r]=252<=r?6:248<=r?5:240<=r?4:224<=r?3:192<=r?2:1;function o(a,l){if(l<65537&&(a.subarray&&i||!a.subarray&&s))return String.fromCharCode.apply(null,e.shrinkBuf(a,l));for(var c="",d=0;d<l;d++)c+=String.fromCharCode(a[d]);return c}n[254]=n[254]=1,t.string2buf=function(a){var l,c,d,p,h,u=a.length,m=0;for(p=0;p<u;p++)(64512&(c=a.charCodeAt(p)))==55296&&p+1<u&&(64512&(d=a.charCodeAt(p+1)))==56320&&(c=65536+(c-55296<<10)+(d-56320),p++),m+=c<128?1:c<2048?2:c<65536?3:4;for(l=new e.Buf8(m),p=h=0;h<m;p++)(64512&(c=a.charCodeAt(p)))==55296&&p+1<u&&(64512&(d=a.charCodeAt(p+1)))==56320&&(c=65536+(c-55296<<10)+(d-56320),p++),c<128?l[h++]=c:(c<2048?l[h++]=192|c>>>6:(c<65536?l[h++]=224|c>>>12:(l[h++]=240|c>>>18,l[h++]=128|c>>>12&63),l[h++]=128|c>>>6&63),l[h++]=128|63&c);return l},t.buf2binstring=function(a){return o(a,a.length)},t.binstring2buf=function(a){for(var l=new e.Buf8(a.length),c=0,d=l.length;c<d;c++)l[c]=a.charCodeAt(c);return l},t.buf2string=function(a,l){var c,d,p,h,u=l||a.length,m=new Array(2*u);for(c=d=0;c<u;)if((p=a[c++])<128)m[d++]=p;else if(4<(h=n[p]))m[d++]=65533,c+=h-1;else{for(p&=h===2?31:h===3?15:7;1<h&&c<u;)p=p<<6|63&a[c++],h--;1<h?m[d++]=65533:p<65536?m[d++]=p:(p-=65536,m[d++]=55296|p>>10&1023,m[d++]=56320|1023&p)}return o(m,d)},t.utf8border=function(a,l){var c;for((l=l||a.length)>a.length&&(l=a.length),c=l-1;0<=c&&(192&a[c])==128;)c--;return c<0||c===0?l:c+n[a[c]]>l?c:l}},{"./common":41}],43:[function(v,f,t){"use strict";f.exports=function(e,s,i,n){for(var r=65535&e|0,o=e>>>16&65535|0,a=0;i!==0;){for(i-=a=2e3<i?2e3:i;o=o+(r=r+s[n++]|0)|0,--a;);r%=65521,o%=65521}return r|o<<16|0}},{}],44:[function(v,f,t){"use strict";f.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],45:[function(v,f,t){"use strict";var e=function(){for(var s,i=[],n=0;n<256;n++){s=n;for(var r=0;r<8;r++)s=1&s?3988292384^s>>>1:s>>>1;i[n]=s}return i}();f.exports=function(s,i,n,r){var o=e,a=r+n;s^=-1;for(var l=r;l<a;l++)s=s>>>8^o[255&(s^i[l])];return-1^s}},{}],46:[function(v,f,t){"use strict";var e,s=v("../utils/common"),i=v("./trees"),n=v("./adler32"),r=v("./crc32"),o=v("./messages"),a=0,l=4,c=0,d=-2,p=-1,h=4,u=2,m=8,g=9,y=286,S=30,k=19,x=2*y+1,I=15,E=3,D=258,$=D+E+1,F=42,P=113,b=1,H=2,et=3,V=4;function W(w,R){return w.msg=o[R],R}function z(w){return(w<<1)-(4<w?9:0)}function Q(w){for(var R=w.length;0<=--R;)w[R]=0}function N(w){var R=w.state,L=R.pending;L>w.avail_out&&(L=w.avail_out),L!==0&&(s.arraySet(w.output,R.pending_buf,R.pending_out,L,w.next_out),w.next_out+=L,R.pending_out+=L,w.total_out+=L,w.avail_out-=L,R.pending-=L,R.pending===0&&(R.pending_out=0))}function M(w,R){i._tr_flush_block(w,0<=w.block_start?w.block_start:-1,w.strstart-w.block_start,R),w.block_start=w.strstart,N(w.strm)}function J(w,R){w.pending_buf[w.pending++]=R}function q(w,R){w.pending_buf[w.pending++]=R>>>8&255,w.pending_buf[w.pending++]=255&R}function Y(w,R){var L,T,C=w.max_chain_length,A=w.strstart,j=w.prev_length,U=w.nice_match,_=w.strstart>w.w_size-$?w.strstart-(w.w_size-$):0,K=w.window,X=w.w_mask,Z=w.prev,st=w.strstart+D,ft=K[A+j-1],G=K[A+j];w.prev_length>=w.good_match&&(C>>=2),U>w.lookahead&&(U=w.lookahead);do if(K[(L=R)+j]===G&&K[L+j-1]===ft&&K[L]===K[A]&&K[++L]===K[A+1]){A+=2,L++;do;while(K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&K[++A]===K[++L]&&A<st);if(T=D-(st-A),A=st-D,j<T){if(w.match_start=R,U<=(j=T))break;ft=K[A+j-1],G=K[A+j]}}while((R=Z[R&X])>_&&--C!=0);return j<=w.lookahead?j:w.lookahead}function pt(w){var R,L,T,C,A,j,U,_,K,X,Z=w.w_size;do{if(C=w.window_size-w.lookahead-w.strstart,w.strstart>=Z+(Z-$)){for(s.arraySet(w.window,w.window,Z,Z,0),w.match_start-=Z,w.strstart-=Z,w.block_start-=Z,R=L=w.hash_size;T=w.head[--R],w.head[R]=Z<=T?T-Z:0,--L;);for(R=L=Z;T=w.prev[--R],w.prev[R]=Z<=T?T-Z:0,--L;);C+=Z}if(w.strm.avail_in===0)break;if(j=w.strm,U=w.window,_=w.strstart+w.lookahead,K=C,X=void 0,X=j.avail_in,K<X&&(X=K),L=X===0?0:(j.avail_in-=X,s.arraySet(U,j.input,j.next_in,X,_),j.state.wrap===1?j.adler=n(j.adler,U,X,_):j.state.wrap===2&&(j.adler=r(j.adler,U,X,_)),j.next_in+=X,j.total_in+=X,X),w.lookahead+=L,w.lookahead+w.insert>=E)for(A=w.strstart-w.insert,w.ins_h=w.window[A],w.ins_h=(w.ins_h<<w.hash_shift^w.window[A+1])&w.hash_mask;w.insert&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[A+E-1])&w.hash_mask,w.prev[A&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=A,A++,w.insert--,!(w.lookahead+w.insert<E)););}while(w.lookahead<$&&w.strm.avail_in!==0)}function mt(w,R){for(var L,T;;){if(w.lookahead<$){if(pt(w),w.lookahead<$&&R===a)return b;if(w.lookahead===0)break}if(L=0,w.lookahead>=E&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+E-1])&w.hash_mask,L=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),L!==0&&w.strstart-L<=w.w_size-$&&(w.match_length=Y(w,L)),w.match_length>=E)if(T=i._tr_tally(w,w.strstart-w.match_start,w.match_length-E),w.lookahead-=w.match_length,w.match_length<=w.max_lazy_match&&w.lookahead>=E){for(w.match_length--;w.strstart++,w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+E-1])&w.hash_mask,L=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart,--w.match_length!=0;);w.strstart++}else w.strstart+=w.match_length,w.match_length=0,w.ins_h=w.window[w.strstart],w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+1])&w.hash_mask;else T=i._tr_tally(w,0,w.window[w.strstart]),w.lookahead--,w.strstart++;if(T&&(M(w,!1),w.strm.avail_out===0))return b}return w.insert=w.strstart<E-1?w.strstart:E-1,R===l?(M(w,!0),w.strm.avail_out===0?et:V):w.last_lit&&(M(w,!1),w.strm.avail_out===0)?b:H}function nt(w,R){for(var L,T,C;;){if(w.lookahead<$){if(pt(w),w.lookahead<$&&R===a)return b;if(w.lookahead===0)break}if(L=0,w.lookahead>=E&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+E-1])&w.hash_mask,L=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),w.prev_length=w.match_length,w.prev_match=w.match_start,w.match_length=E-1,L!==0&&w.prev_length<w.max_lazy_match&&w.strstart-L<=w.w_size-$&&(w.match_length=Y(w,L),w.match_length<=5&&(w.strategy===1||w.match_length===E&&4096<w.strstart-w.match_start)&&(w.match_length=E-1)),w.prev_length>=E&&w.match_length<=w.prev_length){for(C=w.strstart+w.lookahead-E,T=i._tr_tally(w,w.strstart-1-w.prev_match,w.prev_length-E),w.lookahead-=w.prev_length-1,w.prev_length-=2;++w.strstart<=C&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+E-1])&w.hash_mask,L=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),--w.prev_length!=0;);if(w.match_available=0,w.match_length=E-1,w.strstart++,T&&(M(w,!1),w.strm.avail_out===0))return b}else if(w.match_available){if((T=i._tr_tally(w,0,w.window[w.strstart-1]))&&M(w,!1),w.strstart++,w.lookahead--,w.strm.avail_out===0)return b}else w.match_available=1,w.strstart++,w.lookahead--}return w.match_available&&(T=i._tr_tally(w,0,w.window[w.strstart-1]),w.match_available=0),w.insert=w.strstart<E-1?w.strstart:E-1,R===l?(M(w,!0),w.strm.avail_out===0?et:V):w.last_lit&&(M(w,!1),w.strm.avail_out===0)?b:H}function lt(w,R,L,T,C){this.good_length=w,this.max_lazy=R,this.nice_length=L,this.max_chain=T,this.func=C}function ot(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=m,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new s.Buf16(2*x),this.dyn_dtree=new s.Buf16(2*(2*S+1)),this.bl_tree=new s.Buf16(2*(2*k+1)),Q(this.dyn_ltree),Q(this.dyn_dtree),Q(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new s.Buf16(I+1),this.heap=new s.Buf16(2*y+1),Q(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new s.Buf16(2*y+1),Q(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function it(w){var R;return w&&w.state?(w.total_in=w.total_out=0,w.data_type=u,(R=w.state).pending=0,R.pending_out=0,R.wrap<0&&(R.wrap=-R.wrap),R.status=R.wrap?F:P,w.adler=R.wrap===2?0:1,R.last_flush=a,i._tr_init(R),c):W(w,d)}function dt(w){var R=it(w);return R===c&&function(L){L.window_size=2*L.w_size,Q(L.head),L.max_lazy_match=e[L.level].max_lazy,L.good_match=e[L.level].good_length,L.nice_match=e[L.level].nice_length,L.max_chain_length=e[L.level].max_chain,L.strstart=0,L.block_start=0,L.lookahead=0,L.insert=0,L.match_length=L.prev_length=E-1,L.match_available=0,L.ins_h=0}(w.state),R}function ht(w,R,L,T,C,A){if(!w)return d;var j=1;if(R===p&&(R=6),T<0?(j=0,T=-T):15<T&&(j=2,T-=16),C<1||g<C||L!==m||T<8||15<T||R<0||9<R||A<0||h<A)return W(w,d);T===8&&(T=9);var U=new ot;return(w.state=U).strm=w,U.wrap=j,U.gzhead=null,U.w_bits=T,U.w_size=1<<U.w_bits,U.w_mask=U.w_size-1,U.hash_bits=C+7,U.hash_size=1<<U.hash_bits,U.hash_mask=U.hash_size-1,U.hash_shift=~~((U.hash_bits+E-1)/E),U.window=new s.Buf8(2*U.w_size),U.head=new s.Buf16(U.hash_size),U.prev=new s.Buf16(U.w_size),U.lit_bufsize=1<<C+6,U.pending_buf_size=4*U.lit_bufsize,U.pending_buf=new s.Buf8(U.pending_buf_size),U.d_buf=1*U.lit_bufsize,U.l_buf=3*U.lit_bufsize,U.level=R,U.strategy=A,U.method=L,dt(w)}e=[new lt(0,0,0,0,function(w,R){var L=65535;for(L>w.pending_buf_size-5&&(L=w.pending_buf_size-5);;){if(w.lookahead<=1){if(pt(w),w.lookahead===0&&R===a)return b;if(w.lookahead===0)break}w.strstart+=w.lookahead,w.lookahead=0;var T=w.block_start+L;if((w.strstart===0||w.strstart>=T)&&(w.lookahead=w.strstart-T,w.strstart=T,M(w,!1),w.strm.avail_out===0)||w.strstart-w.block_start>=w.w_size-$&&(M(w,!1),w.strm.avail_out===0))return b}return w.insert=0,R===l?(M(w,!0),w.strm.avail_out===0?et:V):(w.strstart>w.block_start&&(M(w,!1),w.strm.avail_out),b)}),new lt(4,4,8,4,mt),new lt(4,5,16,8,mt),new lt(4,6,32,32,mt),new lt(4,4,16,16,nt),new lt(8,16,32,32,nt),new lt(8,16,128,128,nt),new lt(8,32,128,256,nt),new lt(32,128,258,1024,nt),new lt(32,258,258,4096,nt)],t.deflateInit=function(w,R){return ht(w,R,m,15,8,0)},t.deflateInit2=ht,t.deflateReset=dt,t.deflateResetKeep=it,t.deflateSetHeader=function(w,R){return w&&w.state?w.state.wrap!==2?d:(w.state.gzhead=R,c):d},t.deflate=function(w,R){var L,T,C,A;if(!w||!w.state||5<R||R<0)return w?W(w,d):d;if(T=w.state,!w.output||!w.input&&w.avail_in!==0||T.status===666&&R!==l)return W(w,w.avail_out===0?-5:d);if(T.strm=w,L=T.last_flush,T.last_flush=R,T.status===F)if(T.wrap===2)w.adler=0,J(T,31),J(T,139),J(T,8),T.gzhead?(J(T,(T.gzhead.text?1:0)+(T.gzhead.hcrc?2:0)+(T.gzhead.extra?4:0)+(T.gzhead.name?8:0)+(T.gzhead.comment?16:0)),J(T,255&T.gzhead.time),J(T,T.gzhead.time>>8&255),J(T,T.gzhead.time>>16&255),J(T,T.gzhead.time>>24&255),J(T,T.level===9?2:2<=T.strategy||T.level<2?4:0),J(T,255&T.gzhead.os),T.gzhead.extra&&T.gzhead.extra.length&&(J(T,255&T.gzhead.extra.length),J(T,T.gzhead.extra.length>>8&255)),T.gzhead.hcrc&&(w.adler=r(w.adler,T.pending_buf,T.pending,0)),T.gzindex=0,T.status=69):(J(T,0),J(T,0),J(T,0),J(T,0),J(T,0),J(T,T.level===9?2:2<=T.strategy||T.level<2?4:0),J(T,3),T.status=P);else{var j=m+(T.w_bits-8<<4)<<8;j|=(2<=T.strategy||T.level<2?0:T.level<6?1:T.level===6?2:3)<<6,T.strstart!==0&&(j|=32),j+=31-j%31,T.status=P,q(T,j),T.strstart!==0&&(q(T,w.adler>>>16),q(T,65535&w.adler)),w.adler=1}if(T.status===69)if(T.gzhead.extra){for(C=T.pending;T.gzindex<(65535&T.gzhead.extra.length)&&(T.pending!==T.pending_buf_size||(T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),N(w),C=T.pending,T.pending!==T.pending_buf_size));)J(T,255&T.gzhead.extra[T.gzindex]),T.gzindex++;T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),T.gzindex===T.gzhead.extra.length&&(T.gzindex=0,T.status=73)}else T.status=73;if(T.status===73)if(T.gzhead.name){C=T.pending;do{if(T.pending===T.pending_buf_size&&(T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),N(w),C=T.pending,T.pending===T.pending_buf_size)){A=1;break}A=T.gzindex<T.gzhead.name.length?255&T.gzhead.name.charCodeAt(T.gzindex++):0,J(T,A)}while(A!==0);T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),A===0&&(T.gzindex=0,T.status=91)}else T.status=91;if(T.status===91)if(T.gzhead.comment){C=T.pending;do{if(T.pending===T.pending_buf_size&&(T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),N(w),C=T.pending,T.pending===T.pending_buf_size)){A=1;break}A=T.gzindex<T.gzhead.comment.length?255&T.gzhead.comment.charCodeAt(T.gzindex++):0,J(T,A)}while(A!==0);T.gzhead.hcrc&&T.pending>C&&(w.adler=r(w.adler,T.pending_buf,T.pending-C,C)),A===0&&(T.status=103)}else T.status=103;if(T.status===103&&(T.gzhead.hcrc?(T.pending+2>T.pending_buf_size&&N(w),T.pending+2<=T.pending_buf_size&&(J(T,255&w.adler),J(T,w.adler>>8&255),w.adler=0,T.status=P)):T.status=P),T.pending!==0){if(N(w),w.avail_out===0)return T.last_flush=-1,c}else if(w.avail_in===0&&z(R)<=z(L)&&R!==l)return W(w,-5);if(T.status===666&&w.avail_in!==0)return W(w,-5);if(w.avail_in!==0||T.lookahead!==0||R!==a&&T.status!==666){var U=T.strategy===2?function(_,K){for(var X;;){if(_.lookahead===0&&(pt(_),_.lookahead===0)){if(K===a)return b;break}if(_.match_length=0,X=i._tr_tally(_,0,_.window[_.strstart]),_.lookahead--,_.strstart++,X&&(M(_,!1),_.strm.avail_out===0))return b}return _.insert=0,K===l?(M(_,!0),_.strm.avail_out===0?et:V):_.last_lit&&(M(_,!1),_.strm.avail_out===0)?b:H}(T,R):T.strategy===3?function(_,K){for(var X,Z,st,ft,G=_.window;;){if(_.lookahead<=D){if(pt(_),_.lookahead<=D&&K===a)return b;if(_.lookahead===0)break}if(_.match_length=0,_.lookahead>=E&&0<_.strstart&&(Z=G[st=_.strstart-1])===G[++st]&&Z===G[++st]&&Z===G[++st]){ft=_.strstart+D;do;while(Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&Z===G[++st]&&st<ft);_.match_length=D-(ft-st),_.match_length>_.lookahead&&(_.match_length=_.lookahead)}if(_.match_length>=E?(X=i._tr_tally(_,1,_.match_length-E),_.lookahead-=_.match_length,_.strstart+=_.match_length,_.match_length=0):(X=i._tr_tally(_,0,_.window[_.strstart]),_.lookahead--,_.strstart++),X&&(M(_,!1),_.strm.avail_out===0))return b}return _.insert=0,K===l?(M(_,!0),_.strm.avail_out===0?et:V):_.last_lit&&(M(_,!1),_.strm.avail_out===0)?b:H}(T,R):e[T.level].func(T,R);if(U!==et&&U!==V||(T.status=666),U===b||U===et)return w.avail_out===0&&(T.last_flush=-1),c;if(U===H&&(R===1?i._tr_align(T):R!==5&&(i._tr_stored_block(T,0,0,!1),R===3&&(Q(T.head),T.lookahead===0&&(T.strstart=0,T.block_start=0,T.insert=0))),N(w),w.avail_out===0))return T.last_flush=-1,c}return R!==l?c:T.wrap<=0?1:(T.wrap===2?(J(T,255&w.adler),J(T,w.adler>>8&255),J(T,w.adler>>16&255),J(T,w.adler>>24&255),J(T,255&w.total_in),J(T,w.total_in>>8&255),J(T,w.total_in>>16&255),J(T,w.total_in>>24&255)):(q(T,w.adler>>>16),q(T,65535&w.adler)),N(w),0<T.wrap&&(T.wrap=-T.wrap),T.pending!==0?c:1)},t.deflateEnd=function(w){var R;return w&&w.state?(R=w.state.status)!==F&&R!==69&&R!==73&&R!==91&&R!==103&&R!==P&&R!==666?W(w,d):(w.state=null,R===P?W(w,-3):c):d},t.deflateSetDictionary=function(w,R){var L,T,C,A,j,U,_,K,X=R.length;if(!w||!w.state||(A=(L=w.state).wrap)===2||A===1&&L.status!==F||L.lookahead)return d;for(A===1&&(w.adler=n(w.adler,R,X,0)),L.wrap=0,X>=L.w_size&&(A===0&&(Q(L.head),L.strstart=0,L.block_start=0,L.insert=0),K=new s.Buf8(L.w_size),s.arraySet(K,R,X-L.w_size,L.w_size,0),R=K,X=L.w_size),j=w.avail_in,U=w.next_in,_=w.input,w.avail_in=X,w.next_in=0,w.input=R,pt(L);L.lookahead>=E;){for(T=L.strstart,C=L.lookahead-(E-1);L.ins_h=(L.ins_h<<L.hash_shift^L.window[T+E-1])&L.hash_mask,L.prev[T&L.w_mask]=L.head[L.ins_h],L.head[L.ins_h]=T,T++,--C;);L.strstart=T,L.lookahead=E-1,pt(L)}return L.strstart+=L.lookahead,L.block_start=L.strstart,L.insert=L.lookahead,L.lookahead=0,L.match_length=L.prev_length=E-1,L.match_available=0,w.next_in=U,w.input=_,w.avail_in=j,L.wrap=A,c},t.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(v,f,t){"use strict";f.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],48:[function(v,f,t){"use strict";f.exports=function(e,s){var i,n,r,o,a,l,c,d,p,h,u,m,g,y,S,k,x,I,E,D,$,F,P,b,H;i=e.state,n=e.next_in,b=e.input,r=n+(e.avail_in-5),o=e.next_out,H=e.output,a=o-(s-e.avail_out),l=o+(e.avail_out-257),c=i.dmax,d=i.wsize,p=i.whave,h=i.wnext,u=i.window,m=i.hold,g=i.bits,y=i.lencode,S=i.distcode,k=(1<<i.lenbits)-1,x=(1<<i.distbits)-1;t:do{g<15&&(m+=b[n++]<<g,g+=8,m+=b[n++]<<g,g+=8),I=y[m&k];e:for(;;){if(m>>>=E=I>>>24,g-=E,(E=I>>>16&255)===0)H[o++]=65535&I;else{if(!(16&E)){if(!(64&E)){I=y[(65535&I)+(m&(1<<E)-1)];continue e}if(32&E){i.mode=12;break t}e.msg="invalid literal/length code",i.mode=30;break t}D=65535&I,(E&=15)&&(g<E&&(m+=b[n++]<<g,g+=8),D+=m&(1<<E)-1,m>>>=E,g-=E),g<15&&(m+=b[n++]<<g,g+=8,m+=b[n++]<<g,g+=8),I=S[m&x];s:for(;;){if(m>>>=E=I>>>24,g-=E,!(16&(E=I>>>16&255))){if(!(64&E)){I=S[(65535&I)+(m&(1<<E)-1)];continue s}e.msg="invalid distance code",i.mode=30;break t}if($=65535&I,g<(E&=15)&&(m+=b[n++]<<g,(g+=8)<E&&(m+=b[n++]<<g,g+=8)),c<($+=m&(1<<E)-1)){e.msg="invalid distance too far back",i.mode=30;break t}if(m>>>=E,g-=E,(E=o-a)<$){if(p<(E=$-E)&&i.sane){e.msg="invalid distance too far back",i.mode=30;break t}if(P=u,(F=0)===h){if(F+=d-E,E<D){for(D-=E;H[o++]=u[F++],--E;);F=o-$,P=H}}else if(h<E){if(F+=d+h-E,(E-=h)<D){for(D-=E;H[o++]=u[F++],--E;);if(F=0,h<D){for(D-=E=h;H[o++]=u[F++],--E;);F=o-$,P=H}}}else if(F+=h-E,E<D){for(D-=E;H[o++]=u[F++],--E;);F=o-$,P=H}for(;2<D;)H[o++]=P[F++],H[o++]=P[F++],H[o++]=P[F++],D-=3;D&&(H[o++]=P[F++],1<D&&(H[o++]=P[F++]))}else{for(F=o-$;H[o++]=H[F++],H[o++]=H[F++],H[o++]=H[F++],2<(D-=3););D&&(H[o++]=H[F++],1<D&&(H[o++]=H[F++]))}break}}break}}while(n<r&&o<l);n-=D=g>>3,m&=(1<<(g-=D<<3))-1,e.next_in=n,e.next_out=o,e.avail_in=n<r?r-n+5:5-(n-r),e.avail_out=o<l?l-o+257:257-(o-l),i.hold=m,i.bits=g}},{}],49:[function(v,f,t){"use strict";var e=v("../utils/common"),s=v("./adler32"),i=v("./crc32"),n=v("./inffast"),r=v("./inftrees"),o=1,a=2,l=0,c=-2,d=1,p=852,h=592;function u(F){return(F>>>24&255)+(F>>>8&65280)+((65280&F)<<8)+((255&F)<<24)}function m(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new e.Buf16(320),this.work=new e.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function g(F){var P;return F&&F.state?(P=F.state,F.total_in=F.total_out=P.total=0,F.msg="",P.wrap&&(F.adler=1&P.wrap),P.mode=d,P.last=0,P.havedict=0,P.dmax=32768,P.head=null,P.hold=0,P.bits=0,P.lencode=P.lendyn=new e.Buf32(p),P.distcode=P.distdyn=new e.Buf32(h),P.sane=1,P.back=-1,l):c}function y(F){var P;return F&&F.state?((P=F.state).wsize=0,P.whave=0,P.wnext=0,g(F)):c}function S(F,P){var b,H;return F&&F.state?(H=F.state,P<0?(b=0,P=-P):(b=1+(P>>4),P<48&&(P&=15)),P&&(P<8||15<P)?c:(H.window!==null&&H.wbits!==P&&(H.window=null),H.wrap=b,H.wbits=P,y(F))):c}function k(F,P){var b,H;return F?(H=new m,(F.state=H).window=null,(b=S(F,P))!==l&&(F.state=null),b):c}var x,I,E=!0;function D(F){if(E){var P;for(x=new e.Buf32(512),I=new e.Buf32(32),P=0;P<144;)F.lens[P++]=8;for(;P<256;)F.lens[P++]=9;for(;P<280;)F.lens[P++]=7;for(;P<288;)F.lens[P++]=8;for(r(o,F.lens,0,288,x,0,F.work,{bits:9}),P=0;P<32;)F.lens[P++]=5;r(a,F.lens,0,32,I,0,F.work,{bits:5}),E=!1}F.lencode=x,F.lenbits=9,F.distcode=I,F.distbits=5}function $(F,P,b,H){var et,V=F.state;return V.window===null&&(V.wsize=1<<V.wbits,V.wnext=0,V.whave=0,V.window=new e.Buf8(V.wsize)),H>=V.wsize?(e.arraySet(V.window,P,b-V.wsize,V.wsize,0),V.wnext=0,V.whave=V.wsize):(H<(et=V.wsize-V.wnext)&&(et=H),e.arraySet(V.window,P,b-H,et,V.wnext),(H-=et)?(e.arraySet(V.window,P,b-H,H,0),V.wnext=H,V.whave=V.wsize):(V.wnext+=et,V.wnext===V.wsize&&(V.wnext=0),V.whave<V.wsize&&(V.whave+=et))),0}t.inflateReset=y,t.inflateReset2=S,t.inflateResetKeep=g,t.inflateInit=function(F){return k(F,15)},t.inflateInit2=k,t.inflate=function(F,P){var b,H,et,V,W,z,Q,N,M,J,q,Y,pt,mt,nt,lt,ot,it,dt,ht,w,R,L,T,C=0,A=new e.Buf8(4),j=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!F||!F.state||!F.output||!F.input&&F.avail_in!==0)return c;(b=F.state).mode===12&&(b.mode=13),W=F.next_out,et=F.output,Q=F.avail_out,V=F.next_in,H=F.input,z=F.avail_in,N=b.hold,M=b.bits,J=z,q=Q,R=l;t:for(;;)switch(b.mode){case d:if(b.wrap===0){b.mode=13;break}for(;M<16;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(2&b.wrap&&N===35615){A[b.check=0]=255&N,A[1]=N>>>8&255,b.check=i(b.check,A,2,0),M=N=0,b.mode=2;break}if(b.flags=0,b.head&&(b.head.done=!1),!(1&b.wrap)||(((255&N)<<8)+(N>>8))%31){F.msg="incorrect header check",b.mode=30;break}if((15&N)!=8){F.msg="unknown compression method",b.mode=30;break}if(M-=4,w=8+(15&(N>>>=4)),b.wbits===0)b.wbits=w;else if(w>b.wbits){F.msg="invalid window size",b.mode=30;break}b.dmax=1<<w,F.adler=b.check=1,b.mode=512&N?10:12,M=N=0;break;case 2:for(;M<16;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(b.flags=N,(255&b.flags)!=8){F.msg="unknown compression method",b.mode=30;break}if(57344&b.flags){F.msg="unknown header flags set",b.mode=30;break}b.head&&(b.head.text=N>>8&1),512&b.flags&&(A[0]=255&N,A[1]=N>>>8&255,b.check=i(b.check,A,2,0)),M=N=0,b.mode=3;case 3:for(;M<32;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.head&&(b.head.time=N),512&b.flags&&(A[0]=255&N,A[1]=N>>>8&255,A[2]=N>>>16&255,A[3]=N>>>24&255,b.check=i(b.check,A,4,0)),M=N=0,b.mode=4;case 4:for(;M<16;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.head&&(b.head.xflags=255&N,b.head.os=N>>8),512&b.flags&&(A[0]=255&N,A[1]=N>>>8&255,b.check=i(b.check,A,2,0)),M=N=0,b.mode=5;case 5:if(1024&b.flags){for(;M<16;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.length=N,b.head&&(b.head.extra_len=N),512&b.flags&&(A[0]=255&N,A[1]=N>>>8&255,b.check=i(b.check,A,2,0)),M=N=0}else b.head&&(b.head.extra=null);b.mode=6;case 6:if(1024&b.flags&&(z<(Y=b.length)&&(Y=z),Y&&(b.head&&(w=b.head.extra_len-b.length,b.head.extra||(b.head.extra=new Array(b.head.extra_len)),e.arraySet(b.head.extra,H,V,Y,w)),512&b.flags&&(b.check=i(b.check,H,Y,V)),z-=Y,V+=Y,b.length-=Y),b.length))break t;b.length=0,b.mode=7;case 7:if(2048&b.flags){if(z===0)break t;for(Y=0;w=H[V+Y++],b.head&&w&&b.length<65536&&(b.head.name+=String.fromCharCode(w)),w&&Y<z;);if(512&b.flags&&(b.check=i(b.check,H,Y,V)),z-=Y,V+=Y,w)break t}else b.head&&(b.head.name=null);b.length=0,b.mode=8;case 8:if(4096&b.flags){if(z===0)break t;for(Y=0;w=H[V+Y++],b.head&&w&&b.length<65536&&(b.head.comment+=String.fromCharCode(w)),w&&Y<z;);if(512&b.flags&&(b.check=i(b.check,H,Y,V)),z-=Y,V+=Y,w)break t}else b.head&&(b.head.comment=null);b.mode=9;case 9:if(512&b.flags){for(;M<16;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(N!==(65535&b.check)){F.msg="header crc mismatch",b.mode=30;break}M=N=0}b.head&&(b.head.hcrc=b.flags>>9&1,b.head.done=!0),F.adler=b.check=0,b.mode=12;break;case 10:for(;M<32;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}F.adler=b.check=u(N),M=N=0,b.mode=11;case 11:if(b.havedict===0)return F.next_out=W,F.avail_out=Q,F.next_in=V,F.avail_in=z,b.hold=N,b.bits=M,2;F.adler=b.check=1,b.mode=12;case 12:if(P===5||P===6)break t;case 13:if(b.last){N>>>=7&M,M-=7&M,b.mode=27;break}for(;M<3;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}switch(b.last=1&N,M-=1,3&(N>>>=1)){case 0:b.mode=14;break;case 1:if(D(b),b.mode=20,P!==6)break;N>>>=2,M-=2;break t;case 2:b.mode=17;break;case 3:F.msg="invalid block type",b.mode=30}N>>>=2,M-=2;break;case 14:for(N>>>=7&M,M-=7&M;M<32;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if((65535&N)!=(N>>>16^65535)){F.msg="invalid stored block lengths",b.mode=30;break}if(b.length=65535&N,M=N=0,b.mode=15,P===6)break t;case 15:b.mode=16;case 16:if(Y=b.length){if(z<Y&&(Y=z),Q<Y&&(Y=Q),Y===0)break t;e.arraySet(et,H,V,Y,W),z-=Y,V+=Y,Q-=Y,W+=Y,b.length-=Y;break}b.mode=12;break;case 17:for(;M<14;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(b.nlen=257+(31&N),N>>>=5,M-=5,b.ndist=1+(31&N),N>>>=5,M-=5,b.ncode=4+(15&N),N>>>=4,M-=4,286<b.nlen||30<b.ndist){F.msg="too many length or distance symbols",b.mode=30;break}b.have=0,b.mode=18;case 18:for(;b.have<b.ncode;){for(;M<3;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.lens[j[b.have++]]=7&N,N>>>=3,M-=3}for(;b.have<19;)b.lens[j[b.have++]]=0;if(b.lencode=b.lendyn,b.lenbits=7,L={bits:b.lenbits},R=r(0,b.lens,0,19,b.lencode,0,b.work,L),b.lenbits=L.bits,R){F.msg="invalid code lengths set",b.mode=30;break}b.have=0,b.mode=19;case 19:for(;b.have<b.nlen+b.ndist;){for(;lt=(C=b.lencode[N&(1<<b.lenbits)-1])>>>16&255,ot=65535&C,!((nt=C>>>24)<=M);){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(ot<16)N>>>=nt,M-=nt,b.lens[b.have++]=ot;else{if(ot===16){for(T=nt+2;M<T;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(N>>>=nt,M-=nt,b.have===0){F.msg="invalid bit length repeat",b.mode=30;break}w=b.lens[b.have-1],Y=3+(3&N),N>>>=2,M-=2}else if(ot===17){for(T=nt+3;M<T;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}M-=nt,w=0,Y=3+(7&(N>>>=nt)),N>>>=3,M-=3}else{for(T=nt+7;M<T;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}M-=nt,w=0,Y=11+(127&(N>>>=nt)),N>>>=7,M-=7}if(b.have+Y>b.nlen+b.ndist){F.msg="invalid bit length repeat",b.mode=30;break}for(;Y--;)b.lens[b.have++]=w}}if(b.mode===30)break;if(b.lens[256]===0){F.msg="invalid code -- missing end-of-block",b.mode=30;break}if(b.lenbits=9,L={bits:b.lenbits},R=r(o,b.lens,0,b.nlen,b.lencode,0,b.work,L),b.lenbits=L.bits,R){F.msg="invalid literal/lengths set",b.mode=30;break}if(b.distbits=6,b.distcode=b.distdyn,L={bits:b.distbits},R=r(a,b.lens,b.nlen,b.ndist,b.distcode,0,b.work,L),b.distbits=L.bits,R){F.msg="invalid distances set",b.mode=30;break}if(b.mode=20,P===6)break t;case 20:b.mode=21;case 21:if(6<=z&&258<=Q){F.next_out=W,F.avail_out=Q,F.next_in=V,F.avail_in=z,b.hold=N,b.bits=M,n(F,q),W=F.next_out,et=F.output,Q=F.avail_out,V=F.next_in,H=F.input,z=F.avail_in,N=b.hold,M=b.bits,b.mode===12&&(b.back=-1);break}for(b.back=0;lt=(C=b.lencode[N&(1<<b.lenbits)-1])>>>16&255,ot=65535&C,!((nt=C>>>24)<=M);){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(lt&&!(240<)){for(it=nt,dt=lt,ht=ot;lt=(C=b.lencode[ht+((N&(1<<it+dt)-1)>>it)])>>>16&255,ot=65535&C,!(it+(nt=C>>>24)<=M);){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}N>>>=it,M-=it,b.back+=it}if(N>>>=nt,M-=nt,b.back+=nt,b.length=ot,lt===0){b.mode=26;break}if(32<){b.back=-1,b.mode=12;break}if(64<){F.msg="invalid literal/length code",b.mode=30;break}b.extra=15<,b.mode=22;case 22:if(b.extra){for(T=b.extra;M<T;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.length+=N&(1<<b.extra)-1,N>>>=b.extra,M-=b.extra,b.back+=b.extra}b.was=b.length,b.mode=23;case 23:for(;lt=(C=b.distcode[N&(1<<b.distbits)-1])>>>16&255,ot=65535&C,!((nt=C>>>24)<=M);){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(!(240<)){for(it=nt,dt=lt,ht=ot;lt=(C=b.distcode[ht+((N&(1<<it+dt)-1)>>it)])>>>16&255,ot=65535&C,!(it+(nt=C>>>24)<=M);){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}N>>>=it,M-=it,b.back+=it}if(N>>>=nt,M-=nt,b.back+=nt,64<){F.msg="invalid distance code",b.mode=30;break}b.offset=ot,b.extra=15<,b.mode=24;case 24:if(b.extra){for(T=b.extra;M<T;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}b.offset+=N&(1<<b.extra)-1,N>>>=b.extra,M-=b.extra,b.back+=b.extra}if(b.offset>b.dmax){F.msg="invalid distance too far back",b.mode=30;break}b.mode=25;case 25:if(Q===0)break t;if(Y=q-Q,b.offset>Y){if((Y=b.offset-Y)>b.whave&&b.sane){F.msg="invalid distance too far back",b.mode=30;break}pt=Y>b.wnext?(Y-=b.wnext,b.wsize-Y):b.wnext-Y,Y>b.length&&(Y=b.length),mt=b.window}else mt=et,pt=W-b.offset,Y=b.length;for(Q<Y&&(Y=Q),Q-=Y,b.length-=Y;et[W++]=mt[pt++],--Y;);b.length===0&&(b.mode=21);break;case 26:if(Q===0)break t;et[W++]=b.length,Q--,b.mode=21;break;case 27:if(b.wrap){for(;M<32;){if(z===0)break t;z--,N|=H[V++]<<M,M+=8}if(q-=Q,F.total_out+=q,b.total+=q,q&&(F.adler=b.check=b.flags?i(b.check,et,q,W-q):s(b.check,et,q,W-q)),q=Q,(b.flags?N:u(N))!==b.check){F.msg="incorrect data check",b.mode=30;break}M=N=0}b.mode=28;case 28:if(b.wrap&&b.flags){for(;M<32;){if(z===0)break t;z--,N+=H[V++]<<M,M+=8}if(N!==(4294967295&b.total)){F.msg="incorrect length check",b.mode=30;break}M=N=0}b.mode=29;case 29:R=1;break t;case 30:R=-3;break t;case 31:return-4;case 32:default:return c}return F.next_out=W,F.avail_out=Q,F.next_in=V,F.avail_in=z,b.hold=N,b.bits=M,(b.wsize||q!==F.avail_out&&b.mode<30&&(b.mode<27||P!==4))&&$(F,F.output,F.next_out,q-F.avail_out)?(b.mode=31,-4):(J-=F.avail_in,q-=F.avail_out,F.total_in+=J,F.total_out+=q,b.total+=q,b.wrap&&q&&(F.adler=b.check=b.flags?i(b.check,et,q,F.next_out-q):s(b.check,et,q,F.next_out-q)),F.data_type=b.bits+(b.last?64:0)+(b.mode===12?128:0)+(b.mode===20||b.mode===15?256:0),(J==0&&q===0||P===4)&&R===l&&(R=-5),R)},t.inflateEnd=function(F){if(!F||!F.state)return c;var P=F.state;return P.window&&(P.window=null),F.state=null,l},t.inflateGetHeader=function(F,P){var b;return F&&F.state&&2&(b=F.state).wrap?((b.head=P).done=!1,l):c},t.inflateSetDictionary=function(F,P){var b,H=P.length;return F&&F.state?(b=F.state).wrap!==0&&b.mode!==11?c:b.mode===11&&s(1,P,H,0)!==b.check?-3:$(F,P,H,H)?(b.mode=31,-4):(b.havedict=1,l):c},t.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(v,f,t){"use strict";var e=v("../utils/common"),s=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],i=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],n=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],r=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];f.exports=function(o,a,l,c,d,p,h,u){var m,g,y,S,k,x,I,E,D,$=u.bits,F=0,P=0,b=0,H=0,et=0,V=0,W=0,z=0,Q=0,N=0,M=null,J=0,q=new e.Buf16(16),Y=new e.Buf16(16),pt=null,mt=0;for(F=0;F<=15;F++)q[F]=0;for(P=0;P<c;P++)q[a[l+P]]++;for(et=$,H=15;1<=H&&q[H]===0;H--);if(H<et&&(et=H),H===0)return d[p++]=20971520,d[p++]=20971520,u.bits=1,0;for(b=1;b<H&&q[b]===0;b++);for(et<b&&(et=b),F=z=1;F<=15;F++)if(z<<=1,(z-=q[F])<0)return-1;if(0<z&&(o===0||H!==1))return-1;for(Y[1]=0,F=1;F<15;F++)Y[F+1]=Y[F]+q[F];for(P=0;P<c;P++)a[l+P]!==0&&(h[Y[a[l+P]]++]=P);if(x=o===0?(M=pt=h,19):o===1?(M=s,J-=257,pt=i,mt-=257,256):(M=n,pt=r,-1),F=b,k=p,W=P=N=0,y=-1,S=(Q=1<<(V=et))-1,o===1&&852<Q||o===2&&592<Q)return 1;for(;;){for(I=F-W,D=h[P]<x?(E=0,h[P]):h[P]>x?(E=pt[mt+h[P]],M[J+h[P]]):(E=96,0),m=1<<F-W,b=g=1<<V;d[k+(N>>W)+(g-=m)]=I<<24|E<<16|D|0,g!==0;);for(m=1<<F-1;N&m;)m>>=1;if(m!==0?(N&=m-1,N+=m):N=0,P++,--q[F]==0){if(F===H)break;F=a[l+h[P]]}if(et<F&&(N&S)!==y){for(W===0&&(W=et),k+=b,z=1<<(V=F-W);V+W<H&&!((z-=q[V+W])<=0);)V++,z<<=1;if(Q+=1<<V,o===1&&852<Q||o===2&&592<Q)return 1;d[y=N&S]=et<<24|V<<16|k-p|0}}return N!==0&&(d[k+N]=F-W<<24|64<<16|0),u.bits=et,0}},{"../utils/common":41}],51:[function(v,f,t){"use strict";f.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],52:[function(v,f,t){"use strict";var e=v("../utils/common"),s=0,i=1;function n(C){for(var A=C.length;0<=--A;)C[A]=0}var r=0,o=29,a=256,l=a+1+o,c=30,d=19,p=2*l+1,h=15,u=16,m=7,g=256,y=16,S=17,k=18,x=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],I=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],E=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],D=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],$=new Array(2*(l+2));n($);var F=new Array(2*c);n(F);var P=new Array(512);n(P);var b=new Array(256);n(b);var H=new Array(o);n(H);var et,V,W,z=new Array(c);function Q(C,A,j,U,_){this.static_tree=C,this.extra_bits=A,this.extra_base=j,this.elems=U,this.max_length=_,this.has_stree=C&&C.length}function N(C,A){this.dyn_tree=C,this.max_code=0,this.stat_desc=A}function M(C){return C<256?P[C]:P[256+(C>>>7)]}function J(C,A){C.pending_buf[C.pending++]=255&A,C.pending_buf[C.pending++]=A>>>8&255}function q(C,A,j){C.bi_valid>u-j?(C.bi_buf|=A<<C.bi_valid&65535,J(C,C.bi_buf),C.bi_buf=A>>u-C.bi_valid,C.bi_valid+=j-u):(C.bi_buf|=A<<C.bi_valid&65535,C.bi_valid+=j)}function Y(C,A,j){q(C,j[2*A],j[2*A+1])}function pt(C,A){for(var j=0;j|=1&C,C>>>=1,j<<=1,0<--A;);return j>>>1}function mt(C,A,j){var U,_,K=new Array(h+1),X=0;for(U=1;U<=h;U++)K[U]=X=X+j[U-1]<<1;for(_=0;_<=A;_++){var Z=C[2*_+1];Z!==0&&(C[2*_]=pt(K[Z]++,Z))}}function nt(C){var A;for(A=0;A<l;A++)C.dyn_ltree[2*A]=0;for(A=0;A<c;A++)C.dyn_dtree[2*A]=0;for(A=0;A<d;A++)C.bl_tree[2*A]=0;C.dyn_ltree[2*g]=1,C.opt_len=C.static_len=0,C.last_lit=C.matches=0}function lt(C){8<C.bi_valid?J(C,C.bi_buf):0<C.bi_valid&&(C.pending_buf[C.pending++]=C.bi_buf),C.bi_buf=0,C.bi_valid=0}function ot(C,A,j,U){var _=2*A,K=2*j;return C[_]<C[K]||C[_]===C[K]&&U[A]<=U[j]}function it(C,A,j){for(var U=C.heap[j],_=j<<1;_<=C.heap_len&&(_<C.heap_len&&ot(A,C.heap[_+1],C.heap[_],C.depth)&&_++,!ot(A,U,C.heap[_],C.depth));)C.heap[j]=C.heap[_],j=_,_<<=1;C.heap[j]=U}function dt(C,A,j){var U,_,K,X,Z=0;if(C.last_lit!==0)for(;U=C.pending_buf[C.d_buf+2*Z]<<8|C.pending_buf[C.d_buf+2*Z+1],_=C.pending_buf[C.l_buf+Z],Z++,U===0?Y(C,_,A):(Y(C,(K=b[_])+a+1,A),(X=x[K])!==0&&q(C,_-=H[K],X),Y(C,K=M(--U),j),(X=I[K])!==0&&q(C,U-=z[K],X)),Z<C.last_lit;);Y(C,g,A)}function ht(C,A){var j,U,_,K=A.dyn_tree,X=A.stat_desc.static_tree,Z=A.stat_desc.has_stree,st=A.stat_desc.elems,ft=-1;for(C.heap_len=0,C.heap_max=p,j=0;j<st;j++)K[2*j]!==0?(C.heap[++C.heap_len]=ft=j,C.depth[j]=0):K[2*j+1]=0;for(;C.heap_len<2;)K[2*(_=C.heap[++C.heap_len]=ft<2?++ft:0)]=1,C.depth[_]=0,C.opt_len--,Z&&(C.static_len-=X[2*_+1]);for(A.max_code=ft,j=C.heap_len>>1;1<=j;j--)it(C,K,j);for(_=st;j=C.heap[1],C.heap[1]=C.heap[C.heap_len--],it(C,K,1),U=C.heap[1],C.heap[--C.heap_max]=j,C.heap[--C.heap_max]=U,K[2*_]=K[2*j]+K[2*U],C.depth[_]=(C.depth[j]>=C.depth[U]?C.depth[j]:C.depth[U])+1,K[2*j+1]=K[2*U+1]=_,C.heap[1]=_++,it(C,K,1),2<=C.heap_len;);C.heap[--C.heap_max]=C.heap[1],function(G,rt){var bt,Ct,Et,yt,ye,rs,At=rt.dyn_tree,xs=rt.max_code,si=rt.stat_desc.static_tree,ii=rt.stat_desc.has_stree,ni=rt.stat_desc.extra_bits,Fs=rt.stat_desc.extra_base,ie=rt.stat_desc.max_length,we=0;for(yt=0;yt<=h;yt++)G.bl_count[yt]=0;for(At[2*G.heap[G.heap_max]+1]=0,bt=G.heap_max+1;bt<p;bt++)ie<(yt=At[2*At[2*(Ct=G.heap[bt])+1]+1]+1)&&(yt=ie,we++),At[2*Ct+1]=yt,xs<Ct||(G.bl_count[yt]++,ye=0,Fs<=Ct&&(ye=ni[Ct-Fs]),rs=At[2*Ct],G.opt_len+=rs*(yt+ye),ii&&(G.static_len+=rs*(si[2*Ct+1]+ye)));if(we!==0){do{for(yt=ie-1;G.bl_count[yt]===0;)yt--;G.bl_count[yt]--,G.bl_count[yt+1]+=2,G.bl_count[ie]--,we-=2}while(0<we);for(yt=ie;yt!==0;yt--)for(Ct=G.bl_count[yt];Ct!==0;)xs<(Et=G.heap[--bt])||(At[2*Et+1]!==yt&&(G.opt_len+=(yt-At[2*Et+1])*At[2*Et],At[2*Et+1]=yt),Ct--)}}(C,A),mt(K,ft,C.bl_count)}function w(C,A,j){var U,_,K=-1,X=A[1],Z=0,st=7,ft=4;for(X===0&&(st=138,ft=3),A[2*(j+1)+1]=65535,U=0;U<=j;U++)_=X,X=A[2*(U+1)+1],++Z<st&&_===X||(Z<ft?C.bl_tree[2*_]+=Z:_!==0?(_!==K&&C.bl_tree[2*_]++,C.bl_tree[2*y]++):Z<=10?C.bl_tree[2*S]++:C.bl_tree[2*k]++,K=_,ft=(Z=0)===X?(st=138,3):_===X?(st=6,3):(st=7,4))}function R(C,A,j){var U,_,K=-1,X=A[1],Z=0,st=7,ft=4;for(X===0&&(st=138,ft=3),U=0;U<=j;U++)if(_=X,X=A[2*(U+1)+1],!(++Z<st&&_===X)){if(Z<ft)for(;Y(C,_,C.bl_tree),--Z!=0;);else _!==0?(_!==K&&(Y(C,_,C.bl_tree),Z--),Y(C,y,C.bl_tree),q(C,Z-3,2)):Z<=10?(Y(C,S,C.bl_tree),q(C,Z-3,3)):(Y(C,k,C.bl_tree),q(C,Z-11,7));K=_,ft=(Z=0)===X?(st=138,3):_===X?(st=6,3):(st=7,4)}}n(z);var L=!1;function T(C,A,j,U){q(C,(r<<1)+(U?1:0),3),function(_,K,X,Z){lt(_),Z&&(J(_,X),J(_,~X)),e.arraySet(_.pending_buf,_.window,K,X,_.pending),_.pending+=X}(C,A,j,!0)}t._tr_init=function(C){L||(function(){var A,j,U,_,K,X=new Array(h+1);for(_=U=0;_<o-1;_++)for(H[_]=U,A=0;A<1<<x[_];A++)b[U++]=_;for(b[U-1]=_,_=K=0;_<16;_++)for(z[_]=K,A=0;A<1<<I[_];A++)P[K++]=_;for(K>>=7;_<c;_++)for(z[_]=K<<7,A=0;A<1<<I[_]-7;A++)P[256+K++]=_;for(j=0;j<=h;j++)X[j]=0;for(A=0;A<=143;)$[2*A+1]=8,A++,X[8]++;for(;A<=255;)$[2*A+1]=9,A++,X[9]++;for(;A<=279;)$[2*A+1]=7,A++,X[7]++;for(;A<=287;)$[2*A+1]=8,A++,X[8]++;for(mt($,l+1,X),A=0;A<c;A++)F[2*A+1]=5,F[2*A]=pt(A,5);et=new Q($,x,a+1,l,h),V=new Q(F,I,0,c,h),W=new Q(new Array(0),E,0,d,m)}(),L=!0),C.l_desc=new N(C.dyn_ltree,et),C.d_desc=new N(C.dyn_dtree,V),C.bl_desc=new N(C.bl_tree,W),C.bi_buf=0,C.bi_valid=0,nt(C)},t._tr_stored_block=T,t._tr_flush_block=function(C,A,j,U){var _,K,X=0;0<C.level?(C.strm.data_type===2&&(C.strm.data_type=function(Z){var st,ft=4093624447;for(st=0;st<=31;st++,ft>>>=1)if(1&ft&&Z.dyn_ltree[2*st]!==0)return s;if(Z.dyn_ltree[18]!==0||Z.dyn_ltree[20]!==0||Z.dyn_ltree[26]!==0)return i;for(st=32;st<a;st++)if(Z.dyn_ltree[2*st]!==0)return i;return s}(C)),ht(C,C.l_desc),ht(C,C.d_desc),X=function(Z){var st;for(w(Z,Z.dyn_ltree,Z.l_desc.max_code),w(Z,Z.dyn_dtree,Z.d_desc.max_code),ht(Z,Z.bl_desc),st=d-1;3<=st&&Z.bl_tree[2*D[st]+1]===0;st--);return Z.opt_len+=3*(st+1)+5+5+4,st}(C),_=C.opt_len+3+7>>>3,(K=C.static_len+3+7>>>3)<=_&&(_=K)):_=K=j+5,j+4<=_&&A!==-1?T(C,A,j,U):C.strategy===4||K===_?(q(C,2+(U?1:0),3),dt(C,$,F)):(q(C,4+(U?1:0),3),function(Z,st,ft,G){var rt;for(q(Z,st-257,5),q(Z,ft-1,5),q(Z,G-4,4),rt=0;rt<G;rt++)q(Z,Z.bl_tree[2*D[rt]+1],3);R(Z,Z.dyn_ltree,st-1),R(Z,Z.dyn_dtree,ft-1)}(C,C.l_desc.max_code+1,C.d_desc.max_code+1,X+1),dt(C,C.dyn_ltree,C.dyn_dtree)),nt(C),U&<(C)},t._tr_tally=function(C,A,j){return C.pending_buf[C.d_buf+2*C.last_lit]=A>>>8&255,C.pending_buf[C.d_buf+2*C.last_lit+1]=255&A,C.pending_buf[C.l_buf+C.last_lit]=255&j,C.last_lit++,A===0?C.dyn_ltree[2*j]++:(C.matches++,A--,C.dyn_ltree[2*(b[j]+a+1)]++,C.dyn_dtree[2*M(A)]++),C.last_lit===C.lit_bufsize-1},t._tr_align=function(C){q(C,2,3),Y(C,g,$),function(A){A.bi_valid===16?(J(A,A.bi_buf),A.bi_buf=0,A.bi_valid=0):8<=A.bi_valid&&(A.pending_buf[A.pending++]=255&A.bi_buf,A.bi_buf>>=8,A.bi_valid-=8)}(C)}},{"../utils/common":41}],53:[function(v,f,t){"use strict";f.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(v,f,t){(function(e){(function(s,i){"use strict";if(!s.setImmediate){var n,r,o,a,l=1,c={},d=!1,p=s.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(s);h=h&&h.setTimeout?h:s,n={}.toString.call(s.process)==="[object process]"?function(y){process.nextTick(function(){m(y)})}:function(){if(s.postMessage&&!s.importScripts){var y=!0,S=s.onmessage;return s.onmessage=function(){y=!1},s.postMessage("","*"),s.onmessage=S,y}}()?(a="setImmediate$"+Math.random()+"$",s.addEventListener?s.addEventListener("message",g,!1):s.attachEvent("onmessage",g),function(y){s.postMessage(a+y,"*")}):s.MessageChannel?((o=new MessageChannel).port1.onmessage=function(y){m(y.data)},function(y){o.port2.postMessage(y)}):p&&"onreadystatechange"in p.createElement("script")?(r=p.documentElement,function(y){var S=p.createElement("script");S.onreadystatechange=function(){m(y),S.onreadystatechange=null,r.removeChild(S),S=null},r.appendChild(S)}):function(y){setTimeout(m,0,y)},h.setImmediate=function(y){typeof y!="function"&&(y=new Function(""+y));for(var S=new Array(arguments.length-1),k=0;k<S.length;k++)S[k]=arguments[k+1];var x={callback:y,args:S};return c[l]=x,n(l),l++},h.clearImmediate=u}function u(y){delete c[y]}function m(y){if(d)setTimeout(m,0,y);else{var S=c[y];if(S){d=!0;try{(function(k){var x=k.callback,I=k.args;switch(I.length){case 0:x();break;case 1:x(I[0]);break;case 2:x(I[0],I[1]);break;case 3:x(I[0],I[1],I[2]);break;default:x.apply(i,I)}})(S)}finally{u(y),d=!1}}}}function g(y){y.source===s&&typeof y.data=="string"&&y.data.indexOf(a)===0&&m(+y.data.slice(a.length))}})(typeof self>"u"?e===void 0?this:e:self)}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}]},{},[10])(10)})});var Oi={};Se(Oi,{default:()=>ns});module.exports=pi(Oi);var at=require("obsidian");xt();var Tt=require("obsidian");var wt=require("obsidian");xt();function ke(v){let f=(v.dateDisplayTimezone||"").trim();return f?{timeZone:f}:{}}function Pt(v,f){try{return new Intl.DateTimeFormat(void 0,f).format(new Date(v))}catch{let{timeZone:t,...e}=f;return new Intl.DateTimeFormat(void 0,e).format(new Date(v))}}function Ut(v,f){let t=ke(f);switch(f.dateDisplayFormat??"locale"){case"iso":return As(v,f,!0);case"us":return Pt(v,{...t,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return Pt(v,{...t,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return Pt(v,{...t,dateStyle:"full",timeStyle:"short"});case"locale":default:return Pt(v,{...t,dateStyle:"medium",timeStyle:"short"})}}function Is(v,f){let t=ke(f);switch(f.dateDisplayFormat??"locale"){case"iso":return As(v,f,!1);case"us":return Pt(v,{...t,month:"numeric",day:"numeric",year:"numeric"});case"eu":return Pt(v,{...t,day:"numeric",month:"numeric",year:"numeric"});case"long":return Pt(v,{...t,dateStyle:"full"});case"locale":default:{let e=new Date,s=new Date(v).getFullYear()===e.getFullYear();return Pt(v,s?{...t,month:"short",day:"numeric"}:{...t,month:"short",day:"numeric",year:"numeric"})}}}function Ds(v,f){let t=ke(f),e=f.dateDisplayFormat==="iso"||f.dateDisplayFormat==="eu";return Pt(v,{...t,hour:e?"2-digit":"numeric",minute:"2-digit",...e?{hourCycle:"h23"}:{}})}function As(v,f,t){let e=ke(f),s=new Intl.DateTimeFormat("en-CA",{...e,year:"numeric",month:"2-digit",day:"2-digit",...t?{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:{}}).formatToParts(new Date(v)),i=r=>s.find(o=>o.type===r)?.value??"",n=`${i("year")}-${i("month")}-${i("day")}`;return t?`${n} ${i("hour")}:${i("minute")}`:n}function xe(v,f,t){let e=v.createSpan({cls:"stashpad-count-badge"});t&&e.addClass("is-expanded"),e.setText(f>99?"99+":String(f))}var de={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},Fe=class extends wt.ItemView{constructor(t,e){super(t);this.plugin=e;this.activePanel="pinned";this.taskFilter="all";this.expanded=new Set;this.renderTimer=null;this.sharedAuthorFilter="all";this.sharedContribOnly=!1}setActivePanel(t){this.activePanel=t,this.containerEl.isConnected&&this.render()}getViewType(){return Nt}getDisplayText(){return"Stashpad panels"}getIcon(){return"panel-left"}async onOpen(){this.render(),this.registerEvent(this.app.metadataCache.on("changed",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("rename",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("delete",()=>this.scheduleRender())),this.registerEvent(this.app.workspace.on("active-leaf-change",t=>{t&&t.view.getViewType()===vt&&this.scheduleRender()}))}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},80))}render(){let t=this.contentEl;t.empty(),t.addClass("stashpad-panels-root");let e=t.createDiv({cls:"stashpad-panels-globals"}),s=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,wt.setIcon)(s.createSpan({cls:"stashpad-panels-global-btn-icon"}),"search"),s.createSpan({cls:"stashpad-panels-global-btn-text",text:"Search"}),s.onclick=()=>this.openSearchFromPanel();let i=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,wt.setIcon)(i.createSpan({cls:"stashpad-panels-global-btn-icon"}),"folder-tree"),i.createSpan({cls:"stashpad-panels-global-btn-text",text:"Folder Switcher"}),i.onclick=()=>this.plugin.openFolderPicker();let n=e.createDiv({cls:"stashpad-panels-globals-row"}),r=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,wt.setIcon)(r.createSpan({cls:"stashpad-panels-global-btn-icon"}),"scroll-text"),r.createSpan({cls:"stashpad-panels-global-btn-text",text:"Log"}),r.onclick=()=>this.openLogFromPanel();let o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,wt.setIcon)(o.createSpan({cls:"stashpad-panels-global-btn-icon"}),"bell"),o.createSpan({cls:"stashpad-panels-global-btn-text",text:"Notifications"}),o.onclick=()=>this.openNotificationsFromPanel();let a=t.createDiv({cls:"stashpad-panels-bar"});for(let c of Object.keys(de)){let d=de[c],p=a.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,wt.setIcon)(p.createSpan({cls:"stashpad-panels-bar-btn-icon"}),d.icon),p.createSpan({cls:"stashpad-panels-bar-btn-text",text:d.label}),this.activePanel===c&&p.addClass("is-active"),p.onclick=()=>{this.activePanel!==c&&(this.activePanel=c,this.render())}}let l=t.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(l):this.activePanel==="shared"?this.renderSharedPanel(l):this.activePanel==="tasks"&&this.renderTasksPanel(l)}renderPinnedPanel(t){let e=t.createDiv({cls:"stashpad-panel-pinned"}),s=e.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),i=s.createSpan({cls:"stashpad-pinned-icon"});(0,wt.setIcon)(i,"home"),s.createSpan({cls:"stashpad-pinned-label",text:"Home"}),s.onclick=()=>this.openHomeFromPanel();let n=this.plugin.settings.pinnedNotes??[];if(n.length===0){e.createDiv({cls:"stashpad-pinned-empty"}).setText("No pinned notes yet \u2014 right-click a note and choose \u201CPin to sidebar.\u201D");return}let r=new Map;n.forEach((l,c)=>{let d=r.get(l.folder);d||(d=[],r.set(l.folder,d)),d.push({pin:l,idx:c})});let o=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,a=Array.from(r.keys());o&&r.has(o)&&(a.splice(a.indexOf(o),1),a.unshift(o));for(let l of a){let c=l.split("/").pop()||l,d=e.createDiv({cls:"stashpad-pinned-group-header"});l===o&&d.addClass("is-active-folder"),d.createSpan({cls:"stashpad-pinned-group-name",text:c});let p=r.get(l)??[];for(let{pin:h,idx:u}of p)this.renderPinnedRow(e,h,u)}}renderPinnedRow(t,e,s){let i=this.findFileFor(e);if(!i)return;let n=this.app.metadataCache.getFileCache(i)?.frontmatter??{},r=this.titleFromFile(i),o=typeof n.color=="string"?n.color:null,a=n.completed===!0,l=this.childrenOf(e.folder,e.id).length,c=l>0,d=this.expanded.has(`${e.folder}|${e.id}`),p=t.createDiv({cls:"stashpad-pinned-row"});o&&p.addClass("has-color"),a&&p.addClass("is-completed"),p.draggable=!0,p.dataset.pinIdx=String(s),p.addEventListener("dragstart",y=>{y.dataTransfer?.setData("text/plain",String(s)),y.dataTransfer&&(y.dataTransfer.effectAllowed="move"),p.addClass("is-dragging")}),p.addEventListener("dragend",()=>p.removeClass("is-dragging")),p.addEventListener("dragover",y=>{y.preventDefault(),y.dataTransfer&&(y.dataTransfer.dropEffect="move");let S=p.getBoundingClientRect(),k=y.clientY-S.top<S.height/2;p.toggleClass("drop-before",k),p.toggleClass("drop-after",!k)}),p.addEventListener("dragleave",()=>{p.removeClass("drop-before"),p.removeClass("drop-after")}),p.addEventListener("drop",y=>{y.preventDefault(),p.removeClass("drop-before"),p.removeClass("drop-after");let S=parseInt(y.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(S)||S===s)return;let k=p.getBoundingClientRect(),x=y.clientY-k.top<k.height/2;this.reorderPin(S,x?s:s+1)});let h=p.createSpan({cls:"stashpad-pinned-toggle"});c&&(xe(h,l,d),h.onclick=y=>{y.stopPropagation();let S=`${e.folder}|${e.id}`;this.expanded.has(S)?this.expanded.delete(S):this.expanded.add(S),this.render()});let u=p.createSpan({cls:"stashpad-pinned-icon"});(0,wt.setIcon)(u,c?"folder-tree":"file-text"),o&&(u.style.color=o);let m=p.createSpan({cls:"stashpad-pinned-label",text:r});m.onclick=()=>this.openPinFromPanel(e);let g=e.folder.split("/").pop()||e.folder;if(p.createSpan({cls:"stashpad-pinned-folder",text:g}),p.oncontextmenu=y=>{y.preventDefault();let S=new wt.Menu;S.addItem(k=>k.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(e)})),S.showAtMouseEvent(y)},c&&d){let y=t.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(y,e.folder,e.id,1)}}async reorderPin(t,e){let s=(this.plugin.settings.pinnedNotes??[]).slice();if(t<0||t>=s.length)return;let[i]=s.splice(t,1),n=e>t?e-1:e;s.splice(Math.max(0,Math.min(n,s.length)),0,i),this.plugin.settings.pinnedNotes=s,await this.plugin.saveSettings(),this.render()}renderPinnedSubtree(t,e,s,i){let n=this.childrenOf(e,s);for(let r of n){let o=this.app.metadataCache.getFileCache(r)?.frontmatter??{},a=typeof o.id=="string"?o.id:null;if(!a)continue;let l=typeof o.color=="string"?o.color:null,c=o.completed===!0,d=this.childrenOf(e,a).length,p=d>0,h=this.expanded.has(`${e}|${a}`),u=t.createDiv({cls:"stashpad-pinned-subrow"});c&&u.addClass("is-completed"),u.style.paddingLeft=`${i*16}px`;let m=u.createSpan({cls:"stashpad-pinned-toggle"});p&&(xe(m,d,h),m.onclick=S=>{S.stopPropagation();let k=`${e}|${a}`;this.expanded.has(k)?this.expanded.delete(k):this.expanded.add(k),this.render()});let g=u.createSpan({cls:"stashpad-pinned-icon"});(0,wt.setIcon)(g,"file-text"),l&&(g.style.color=l);let y=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(r)});y.onclick=()=>this.openPinFromPanel({folder:e,id:a}),p&&h&&this.renderPinnedSubtree(t,e,a,i+1)}}findFileFor(t){for(let e of this.app.vault.getMarkdownFiles()){if((e.parent?.path?.replace(/\/+$/,"")??"")!==t.folder)continue;if(this.app.metadataCache.getFileCache(e)?.frontmatter?.id===t.id)return e}return null}childrenOf(t,e){let s=[];for(let i of this.app.vault.getMarkdownFiles()){if((i.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let r=this.app.metadataCache.getFileCache(i)?.frontmatter;if(!r||typeof r.id!="string")continue;let o=r.parent;if(o===e||e===B&&(o==null||o===B)){if(r.id===B)continue;s.push(i)}}return s.sort((i,n)=>{let r=this.app.metadataCache.getFileCache(i)?.frontmatter,o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=r?.created??"",l=o?.created??"";return a.localeCompare(l)}),s}titleFromFile(t){return t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||t.basename}async openSearchFromPanel(){let t=await this.resolveTargetStashpad();t&&typeof t.openSearchModal=="function"&&t.openSearchModal()}async openLogFromPanel(){let t=this.app.vault.adapter,e=this.plugin.pluginPrivatePath("log.jsonl");if(!await t.exists(e)){new wt.Notice("No log yet \u2014 make some changes first.");return}let s=await t.read(e),{LogModal:i}=await Promise.resolve().then(()=>(Gt(),Te));new i(this.app,s,e).open()}openNotificationsFromPanel(){this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")}async openHomeFromPanel(){let t=await this.resolveTargetStashpad();t&&typeof t.navigateTo=="function"&&t.navigateTo(B)}async openPinFromPanel(t){await this.plugin.activateViewForFolder(t.folder);let e=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();e&&typeof e.navigateTo=="function"&&e.navigateTo(t.id)}async resolveTargetStashpad(){let t=this.plugin.lastActiveStashpadLeaf;if(t&&t.view.getViewType()===vt)return this.app.workspace.revealLeaf(t),t.view;let e=this.findActiveStashpad();if(e)return e;let s=this.app.workspace.getLeavesOfType(vt);return s.length>0?(this.app.workspace.revealLeaf(s[0]),s[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let t=this.app.workspace.activeLeaf;return t&&t.view.getViewType()===vt?t.view:null}renderSharedPanel(t){let e=t.createDiv({cls:"stashpad-panel-shared"}),s=(this.plugin.settings.authorId??"").trim();if(!s){e.createDiv({cls:"stashpad-shared-empty"}).setText("Set an author name in Stashpad settings to populate Shared.");return}let i=this.collectSharedNotes(s),n=new Map;for(let c of i){let d=c.authorId;d&&!n.has(d)&&n.set(d,c.authorDisplay||d)}let r=e.createDiv({cls:"stashpad-shared-filters"}),o=(c,d,p)=>{let h=r.createEl("button",{cls:"stashpad-shared-chip",text:c});return d&&h.addClass("is-active"),h.onclick=p,h};if(o("All",this.sharedAuthorFilter==="all",()=>{this.sharedAuthorFilter="all",this.render()}),o("Mine",this.sharedAuthorFilter==="mine",()=>{this.sharedAuthorFilter="mine",this.render()}),o("Others",this.sharedAuthorFilter==="others",()=>{this.sharedAuthorFilter="others",this.render()}),n.size>1){let c=r.createEl("select",{cls:"stashpad-shared-author-select"}),d=c.createEl("option",{text:"Any author"});d.value="__any__";for(let[h,u]of n){let m=c.createEl("option",{text:u});m.value=h}let p=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;c.value=p,c.onchange=()=>{let h=c.value;h==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=h,this.render()}}let a=r.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&a.addClass("is-active"),a.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let l=i.filter(c=>{if(this.sharedContribOnly&&c.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return c.authorId===s;case"others":return c.authorId!==s;default:return c.authorId===this.sharedAuthorFilter}});if(l.length===0){e.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let c of l){let d=e.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),p=d.createSpan({cls:"stashpad-pinned-icon"});(0,wt.setIcon)(p,"users"),c.color&&(p.style.color=c.color);let h=d.createSpan({cls:"stashpad-pinned-label",text:c.title});h.onclick=()=>this.openSharedFromPanel(c.folder,c.id);let u=c.folder.split("/").pop()||c.folder;d.createSpan({cls:"stashpad-pinned-folder",text:u}),c.authorDisplay&&d.createSpan({cls:"stashpad-shared-meta"}).setText(c.authorId===s?`you \xB7 ${c.contributorCount} contributor${c.contributorCount===1?"":"s"}`:`by ${c.authorDisplay}${c.contributorCount>0?` \xB7 ${c.contributorCount} contributor${c.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(t){let e=this.plugin.discoverStashpadFolders(),s=new Set(e),i=new Map;for(let r of this.app.vault.getMarkdownFiles()){let o=r.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(o))continue;let a=this.app.metadataCache.getFileCache(r)?.frontmatter??{};a.id===B&&i.set(o,this.extractAuthorId(a.author))}let n=[];for(let r of this.app.vault.getMarkdownFiles()){let o=r.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(o)||o.endsWith("/_authors")||r.path.includes("/_authors/"))continue;let a=this.app.metadataCache.getFileCache(r)?.frontmatter??{};if(typeof a.id!="string"||a.id===B)continue;let l=this.extractAuthorId(a.author),c=Array.isArray(a.contributors)?a.contributors.filter(S=>typeof S=="string"):[],d=i.get(o)??null;if(!(c.length>0||d===t&&(l!==null&&l!==t)))continue;let g=this.titleFromFile(r),y=typeof a.color=="string"?a.color:null;n.push({file:r,folder:o,id:a.id,title:g,color:y,authorId:l,authorDisplay:this.extractAuthorDisplay(a.author)||(l??""),contributorCount:c.length})}return n.sort((r,o)=>{let a=this.app.metadataCache.getFileCache(r.file)?.frontmatter??{},l=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=a.modified??a.created??"";return(l.modified??l.created??"").localeCompare(c)}),n}extractAuthorId(t){if(typeof t!="string")return null;let e=t.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return e?e[1]:null}extractAuthorDisplay(t){if(typeof t!="string")return"";let e=t.match(/\|([^\]]+)\]\]/);if(e)return e[1].trim();let s=t.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return s?s[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(t,e){await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();s&&typeof s.navigateTo=="function"&&s.navigateTo(e)}renderTasksPanel(t){let e=t.createDiv({cls:"stashpad-panel-tasks"}),s=this.collectTasks();if(s.length===0){e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks yet \u2014 press H on a note to mark it a task, or D to give it a due date.");return}let i=new Date;i.setHours(0,0,0,0);let n=i.getTime(),r=n+24*60*60*1e3,o={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let m of s){if(m.completed){o.completed.push(m);continue}if(m.due==null){o.nodate.push(m);continue}m.due<n?o.overdue.push(m):m.due<r?o.today.push(m):o.upcoming.push(m)}let a=(m,g)=>m.due==null&&g.due==null?m.title.localeCompare(g.title):m.due==null?1:g.due==null?-1:m.due-g.due,l=[{key:"overdue",label:"Overdue",icon:"alert-circle"},{key:"today",label:"Due today",icon:"calendar-clock"},{key:"upcoming",label:"Upcoming",icon:"calendar"},{key:"nodate",label:"No date",icon:"inbox"},{key:"completed",label:"Completed",icon:"check-circle-2"}],c=e.createDiv({cls:"stashpad-task-filters"}),d=s.length,p=(m,g,y)=>{let S=c.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===m&&S.addClass("is-active"),S.createSpan({cls:"stashpad-task-filter-label",text:g}),S.createSpan({cls:"stashpad-task-filter-count",text:String(y)}),S.onclick=()=>{this.taskFilter=m,this.render()}};p("all","All",d),p("overdue","Overdue",o.overdue.length),p("today","Today",o.today.length),p("upcoming","Upcoming",o.upcoming.length),p("nodate","No date",o.nodate.length),p("completed","Done",o.completed.length);let h=this.taskFilter==="all"?l:l.filter(m=>m.key===this.taskFilter),u=!1;for(let m of h){let g=o[m.key];if(g.length!==0){if(u=!0,g.sort(m.key==="completed"?(y,S)=>a(S,y):a),this.taskFilter==="all"){let y=e.createDiv({cls:`stashpad-task-section-header is-${m.key}`});(0,wt.setIcon)(y.createSpan({cls:"stashpad-task-section-icon"}),m.icon),y.createSpan({cls:"stashpad-task-section-name",text:m.label}),y.createSpan({cls:"stashpad-task-section-count",text:String(g.length)})}for(let y of g)this.renderTaskRow(e,y,m.key==="today")}}if(!u&&this.taskFilter!=="all"){e.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${h[0]?.label??this.taskFilter}".`);return}u||e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(t,e,s){let i=t.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});e.color&&i.addClass("has-color"),e.completed&&i.addClass("is-completed");let n=i.createSpan({cls:"stashpad-pinned-icon stashpad-task-checkbox"});(0,wt.setIcon)(n,e.completed?"check-square":"square"),e.color&&(n.style.color=e.color),n.title=e.completed?"Mark not done":"Mark done",n.onclick=o=>{o.stopPropagation(),this.toggleTaskCompleted(e)};let r=i.createSpan({cls:"stashpad-pinned-label",text:e.title});if(r.onclick=()=>this.openTaskFromPanel(e.folder,e.id),i.createSpan({cls:"stashpad-task-folder",text:e.folder.split("/").pop()||e.folder}),e.due!=null){let o=i.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(e.due,s)});e.due<Date.now()&&!e.completed&&o.addClass("is-overdue")}else e.dueRaw&&i.createSpan({cls:"stashpad-task-due",text:e.dueRaw});i.oncontextmenu=o=>{o.preventDefault();let a=new wt.Menu;a.addItem(l=>l.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(e.folder,e.id)})),a.showAtMouseEvent(o)}}formatDueShort(t,e){return e?Ds(t,this.plugin.settings):Is(t,this.plugin.settings)}async openTaskFromPanel(t,e){await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();s&&typeof s.navigateTo=="function"&&s.navigateTo(e)}async toggleTaskCompleted(t){try{await this.app.fileManager.processFrontMatter(t.file,e=>{e.completed=e.completed!==!0})}catch(e){new wt.Notice(`Couldn't update task: ${e.message}`);return}this.scheduleRender()}collectTasks(){let t=this.plugin.discoverStashpadFolders(),e=new Set(t),s=[];for(let i of this.app.vault.getMarkdownFiles()){let n=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(n))continue;let r=this.app.metadataCache.getFileCache(i)?.frontmatter??{},o=typeof r.id=="string"?r.id:null;if(!o||o===B)continue;let a=r.completed===!0,l=jt(r,"task")||r.task===!0||r.completed!==void 0,c=typeof r.due=="string"||typeof r.due=="number"?String(r.due):null,d=null;if(c){let p=Date.parse(c);Number.isNaN(p)||(d=p)}!l&&!a&&d==null&&!c||s.push({file:i,folder:n,id:o,title:this.titleFromFile(i),task:l,completed:a,due:d,dueRaw:c,color:typeof r.color=="string"?r.color:null})}return s}};async function Ee(v){let f=v.workspace.getLeavesOfType(Nt);if(f.length>0){v.workspace.revealLeaf(f[0]);return}let t=v.workspace.getLeftLeaf(!1);if(!t){new wt.Notice("Stashpad: couldn't open the panels view.");return}await t.setViewState({type:Nt,active:!0}),v.workspace.revealLeaf(t)}var Ps=require("obsidian"),Jt=class{constructor(f,t){this.app=f;this.ta=t;this.popupEl=null;this.items=[];this.activeIdx=0;this.state=null;this.fileIndex=[];this.tagIndex=[];this.indexBuilt=!1;this.vaultListeners=[];this.scope=null;this.onInput=()=>{let f=this.detectTrigger();if(!f){this.close();return}this.openFor(f)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=f=>{f.key==="Escape"&&(!this.state||!this.items.length||(f.preventDefault(),f.stopPropagation(),f.stopImmediatePropagation(),this.close()))};this.onKeyDown=f=>{!this.state||!this.items.length||(f.key==="ArrowDown"?(f.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive()):f.key==="ArrowUp"?(f.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive()):f.key==="Enter"||f.key==="Tab"?(f.preventDefault(),f.stopPropagation(),this.commit()):f.key==="Escape"&&(f.preventDefault(),f.stopPropagation(),f.stopImmediatePropagation(),this.close()))}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let f=this.ta.ownerDocument??document;f.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>f.removeEventListener("keydown",this.onDocEscape,!0)),this.buildIndex();let t=()=>{this.indexBuilt=!1},e=this.app.vault;e.on("create",t),e.on("delete",t),e.on("rename",t),this.vaultListeners.push(()=>e.off("create",t),()=>e.off("delete",t),()=>e.off("rename",t))}isOpen(){return!!this.state&&this.items.length>0}detach(){this.close(),this.ta.removeEventListener("input",this.onInput),this.ta.removeEventListener("keydown",this.onKeyDown,!0),this.ta.removeEventListener("blur",this.onBlur);for(let f of this.vaultListeners)f();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;this.fileIndex=this.app.vault.getFiles().filter(t=>t.extension!=="edtz").map(t=>{let e=t.extension==="md",s=e?t.basename:t.name,i=e?t.basename:t.name;return{label:s,lower:s.toLowerCase(),insertText:i,file:t}});let f=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(f).sort((t,e)=>(f[e]||0)-(f[t]||0)),this.indexBuilt=!0}detectTrigger(){let f=this.ta.value,t=this.ta.selectionStart;if(t==null)return null;let e=f.slice(0,t),s=e.match(/\[\[([^\]\[\n]*)$/);if(s){let n=s[1];return{kind:"link",query:n,replaceStart:t-n.length-2,replaceEnd:t}}let i=e.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(i){let n=i[2];return{kind:"tag",query:n,replaceStart:t-n.length-1,replaceEnd:t}}return null}buildItems(f){this.buildIndex();let t=f.query.toLowerCase().trim(),e=t?t.split(/\s+/).filter(Boolean):[],s=i=>{if(!e.length)return!0;for(let n of e)if(!i.includes(n))return!1;return!0};return f.kind==="link"?this.fileIndex.filter(n=>s(n.lower)).slice(0,50).map(n=>({label:n.label,insert:`[[${n.insertText}]]`,subtitle:n.file.path})):this.tagIndex.filter(n=>s(n.toLowerCase())).slice(0,30).map(n=>({label:n,insert:n,subtitle:""}))}openFor(f){if(this.state=f,this.items=this.buildItems(f),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let f=new Ps.Scope(this.app.scope);f.register([],"Escape",t=>(t.preventDefault(),this.close(),!1)),this.scope=f,this.app.keymap?.pushScope(f)}popScope(){if(this.scope){try{this.app.keymap?.popScope(this.scope)}catch{}this.scope=null}}renderPopup(){if(!this.popupEl){let t=this.ta.ownerDocument??document;this.popupEl=t.body.createDiv({cls:"stashpad-composer-suggest"}),this.popupEl.tabIndex=-1,this.popupEl.addEventListener("mousedown",e=>e.preventDefault())}let f=this.popupEl;f.empty();for(let t=0;t<this.items.length;t++){let e=this.items[t],s=f.createDiv({cls:"stashpad-composer-suggest-row"});t===this.activeIdx&&s.addClass("is-active"),s.createSpan({cls:"stashpad-composer-suggest-label",text:e.label}),e.subtitle&&s.createSpan({cls:"stashpad-composer-suggest-sub",text:e.subtitle}),s.onmousedown=i=>{i.preventDefault(),this.activeIdx=t,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let f=this.popupEl.children;for(let e=0;e<f.length;e++)f[e].toggleClass("is-active",e===this.activeIdx);let t=f[this.activeIdx];t&&t.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let f=this.ta.getBoundingClientRect(),t=this.popupEl.offsetHeight||200,e=f.top-t-4,s=f.left;this.popupEl.style.left=`${Math.max(8,s)}px`,this.popupEl.style.top=`${Math.max(8,e)}px`,this.popupEl.style.minWidth=`${Math.min(360,f.width)}px`}commit(){if(!this.state||!this.items.length)return;let f=this.items[this.activeIdx];if(!f)return;let t=this.ta.value.slice(0,this.state.replaceStart),e=this.ta.value.slice(this.state.replaceEnd),s=f.insert;this.ta.value=t+s+e;let i=t.length+s.length;this.ta.setSelectionRange(i,i),this.ta.dispatchEvent(new Event("input",{bubbles:!0})),this.close(),this.ta.focus()}close(){this.popupEl&&(this.popupEl.remove(),this.popupEl=null),this.state=null,this.items=[],this.activeIdx=0,this.popScope()}};xt();var Ie=class extends Tt.ItemView{constructor(t,e){super(t);this.plugin=e;this.displayedPath=null;this.unsubscribeSelection=null;this.renderTimer=null;this.expanded=new Set;this.composerAutocomplete=null;this.composerInputEl=null;this.composerDraft="";this.composerDraftForId=null;this.displayedId=null;this.unsubscribeContent=null}getViewType(){return Wt}getDisplayText(){return"Stashpad detail"}getIcon(){return"panel-right"}async onOpen(){this.render(),this.unsubscribeSelection=this.plugin.onStashpadSelectionChange(()=>{this.displayedId=null,this.scheduleRender()}),this.unsubscribeContent=this.plugin.onStashpadContentChange(()=>this.scheduleRender()),this.registerEvent(this.app.workspace.on("active-leaf-change",t=>{!t||t===this.leaf||t.view?.getViewType?.()===vt&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("modify",t=>{this.displayedPath&&t.path===this.displayedPath&&this.scheduleRender()})),this.registerEvent(this.app.metadataCache.on("changed",t=>{this.displayedPath&&t.path===this.displayedPath&&this.scheduleRender()}))}async onClose(){this.unsubscribeSelection?.(),this.unsubscribeSelection=null,this.unsubscribeContent?.(),this.unsubscribeContent=null,this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,this.renderTimer!=null&&(window.clearTimeout(this.renderTimer),this.renderTimer=null)}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},60))}resolveDisplayed(){if(this.displayedId){let e=this.plugin.lastActiveStashpadLeaf?.view;if(e?.getViewType?.()===vt&&e.tree?.get){let s=e.tree.get(this.displayedId);if(s?.file)return{folder:e.noteFolder,id:this.displayedId,file:s.file}}this.displayedId=null}let t=this.plugin.getActiveStashpadSelection();return t&&(this.displayedId=t.id),t}async render(){let t=this.contentEl,e=!!this.composerInputEl&&document.activeElement===this.composerInputEl,s=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let i=this.resolveDisplayed();if(!i){this.displayedPath=null;let h=t.createDiv({cls:"stashpad-detail-empty"});(0,Tt.setIcon)(h.createSpan({cls:"stashpad-detail-empty-icon"}),"panel-right"),h.createSpan({cls:"stashpad-detail-empty-text",text:"No Stashpad note selected. Cursor or click a note in a Stashpad list to inspect it here."});return}let n=i.file;this.displayedPath=n.path;let r=this.app.metadataCache.getFileCache(n)?.frontmatter??{},o=t.createDiv({cls:"stashpad-detail-scroll"}),a=o.createDiv({cls:"stashpad-detail-header"}),l=a.createDiv({cls:"stashpad-detail-titlerow"});l.createDiv({cls:"stashpad-detail-title",text:this.titleFor(n)});let c=l.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,Tt.setIcon)(c,"arrow-up-right"),c.title="Open this note in a new Stashpad tab",c.onclick=()=>{this.openInStashpad(i.folder,i.id)};let d=a.createDiv({cls:"stashpad-detail-metarow"});if(i.folder&&d.createSpan({cls:"stashpad-detail-meta-chip",text:i.folder.split("/").pop()||i.folder}),typeof r.color=="string"&&r.color){let h=d.createSpan({cls:"stashpad-detail-meta-color"});h.style.background=r.color,h.title=r.color}if(r.completed===!0&&d.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof r.due=="string"||typeof r.due=="number"){let h=Date.parse(String(r.due)),u=Number.isNaN(h)?String(r.due):Ut(h,this.plugin.settings);d.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${u}`})}if(Array.isArray(r.tags))for(let h of r.tags.filter(u=>typeof u=="string"))d.createSpan({cls:"stashpad-detail-meta-tag",text:`#${h.replace(/^#/,"")}`});let p=o.createDiv({cls:"stashpad-detail-body"});try{let h=await this.app.vault.cachedRead(n),u=this.stripFrontmatter(h);await Tt.MarkdownRenderer.render(this.app,u,p,n.path,this)}catch(h){p.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${n.path}\`: ${h.message}`})}if(this.renderFooterMeta(o,n,r,i),this.renderChildren(o,i.folder,i.id),this.renderComposer(t,i),e&&this.composerInputEl&&(this.composerInputEl.focus(),s!=null)){let h=Math.min(s,this.composerInputEl.value.length);try{this.composerInputEl.setSelectionRange(h,h)}catch{}}}renderComposer(t,e){let s=t.createDiv({cls:"stashpad-detail-composer"}),i=s.createEl("textarea",{cls:"stashpad-detail-composer-input",attr:{placeholder:"Add a child note\u2026",rows:"2"}});this.composerInputEl=i,this.composerDraftForId===e.id?i.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=e.id),i.addEventListener("input",()=>{this.composerDraft=i.value,this.composerDraftForId=e.id}),i.addEventListener("keydown",r=>{if(r.key==="Enter"&&!r.shiftKey&&!r.isComposing){if(this.composerAutocomplete?.isOpen?.())return;r.preventDefault(),this.submitComposer(e)}});let n=s.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,Tt.setIcon)(n.createSpan({cls:"stashpad-detail-composer-send-icon"}),"plus"),n.createSpan({cls:"stashpad-detail-composer-send-text",text:"Add child note"}),n.title="Add child note (Enter)",n.onclick=()=>void this.submitComposer(e),this.composerAutocomplete=new Jt(this.app,i),this.composerAutocomplete.attach()}async submitComposer(t){let e=(this.composerInputEl?.value??"").trim();if(!e)return;let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==vt||typeof s.createNoteUnder!="function"){new Tt.Notice("Open a Stashpad view to add notes.");return}try{await s.createNoteUnder(e,t.id)}catch(i){new Tt.Notice(`Couldn't add note: ${i.message}`);return}this.composerDraft="",this.composerDraftForId=t.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(t,e,s){let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==vt)return;let n=i.tree;if(!n?.getChildren)return;let r=n.getChildren(s);if(!r||r.length===0)return;let o=t.createDiv({cls:"stashpad-detail-children"});o.createDiv({cls:"stashpad-detail-children-header",text:`Children (${r.length})`});let a=o.createDiv({cls:"stashpad-detail-children-list"});for(let l of r)l.file&&this.renderDetailChildRow(a,i,n,e,l,0)}renderDetailChildRow(t,e,s,i,n,r){if(!n.file)return;let o=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},a=typeof o.color=="string"?o.color:null,l=o.completed===!0,c=s.getChildren(n.id),d=c.length>0,p=`${i}|${n.id}`,h=this.expanded.has(p),u=t.createDiv({cls:"stashpad-detail-child-row"});l&&u.addClass("is-completed"),r>0&&(u.style.paddingLeft=`${r*16}px`),u.draggable=!0,u.dataset.id=n.id,u.addEventListener("dragstart",k=>{k.dataTransfer?.setData("text/plain",n.id),k.dataTransfer&&(k.dataTransfer.effectAllowed="move"),u.addClass("is-dragging")}),u.addEventListener("dragend",()=>u.removeClass("is-dragging")),u.addEventListener("dragover",k=>{k.preventDefault(),k.dataTransfer&&(k.dataTransfer.dropEffect="move");let x=u.getBoundingClientRect(),I=k.clientY-x.top<x.height/2;u.toggleClass("drop-before",I),u.toggleClass("drop-after",!I)}),u.addEventListener("dragleave",()=>{u.removeClass("drop-before"),u.removeClass("drop-after")}),u.addEventListener("drop",k=>{k.preventDefault(),u.removeClass("drop-before"),u.removeClass("drop-after");let x=k.dataTransfer?.getData("text/plain");if(!x||x===n.id)return;let I=u.getBoundingClientRect(),E=k.clientY-I.top<I.height/2;typeof e.reorderToTarget=="function"&&e.reorderToTarget([x],n.id,E?"before":"after")}),u.oncontextmenu=k=>{k.preventDefault();let x=s.get(n.id);x&&typeof e.openNoteMenu=="function"&&e.openNoteMenu(k,x)};let m=u.createSpan({cls:"stashpad-detail-child-toggle"});if(d&&(xe(m,c.length,h),m.onclick=k=>{k.stopPropagation(),this.expanded.has(p)?this.expanded.delete(p):this.expanded.add(p),this.render()}),jt(o,"task")||o.task===!0||o.completed!==void 0){let k=u.createSpan({cls:"stashpad-detail-child-checkbox"});(0,Tt.setIcon)(k,l?"check-square":"square"),k.title=l?"Mark not done":"Mark done",k.addEventListener("mousedown",x=>x.stopPropagation()),k.addEventListener("dblclick",x=>{x.preventDefault(),x.stopPropagation()}),k.onclick=x=>{x.preventDefault(),x.stopPropagation();let I=s.get(n.id);I&&typeof e.toggleCompletedForNode=="function"&&e.toggleCompletedForNode(I)}}let y=u.createSpan({cls:"stashpad-detail-child-icon"});(0,Tt.setIcon)(y,d?"folder-tree":"file-text"),a&&(y.style.color=a);let S=u.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(S.onclick=()=>{e?.navigateTo&&e.navigateTo(n.id)},d&&h)for(let k of c)this.renderDetailChildRow(t,e,s,i,k,r+1)}renderFooterMeta(t,e,s,i){let n=t.createDiv({cls:"stashpad-detail-footer-meta"}),r=[];if(typeof s.author=="string"&&s.author&&r.push({label:"Author",value:this.stripWikiLink(s.author)}),Array.isArray(s.contributors)){let o=s.contributors.filter(a=>typeof a=="string").map(a=>this.stripWikiLink(a));o.length>0&&r.push({label:"Contributors",value:o.join(", ")})}if(typeof s.modified=="string"&&r.push({label:"Modified",value:this.formatTime(s.modified)}),typeof s.created=="string"&&r.push({label:"Created",value:this.formatTime(s.created)}),r.push({label:"Path",value:e.path}),r.push({label:"ID",value:i.id}),r.length===0){n.remove();return}for(let o of r){let a=n.createDiv({cls:"stashpad-detail-meta-line"});a.createSpan({cls:"stashpad-detail-meta-key",text:o.label}),a.createSpan({cls:"stashpad-detail-meta-val",text:o.value})}}titleFor(t){return t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")}stripFrontmatter(t){if(!t.startsWith("---"))return t;let e=t.indexOf(` ----`,3);return e<0?t:t.slice(e+4).replace(/^\n+/,"")}stripWikiLink(t){let e=t.match(/^\[\[(.+?)(?:\|(.+))?\]\]$/);return e?e[2]??(e[1].split("/").pop()??e[1]).replace(/\.md$/,""):t}formatTime(t){let e=Date.parse(t);return Number.isFinite(e)?Ut(e,this.plugin.settings):t}async openInStashpad(t,e){try{await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view;s?.navigateTo&&e!==B&&s.navigateTo(e)}catch(s){new Tt.Notice(`Couldn't open: ${s.message}`)}}};async function De(v){let f=v.workspace.getLeavesOfType(Wt);if(f.length>0){v.workspace.revealLeaf(f[0]);return}let t=v.workspace.getRightLeaf(!1);if(!t){new Tt.Notice("Stashpad: couldn't open the detail panel.");return}await t.setViewState({type:Wt,active:!0}),v.workspace.revealLeaf(t)}var O=require("obsidian");xt();var Ot=require("obsidian");xt();function ui(v,f){let t=v.vault.getAbstractFileByPath(f);if(!(t instanceof Ot.TFolder))return[];let e=[],s=[t];for(;s.length;){let i=s.pop();for(let n of i.children)n instanceof Ot.TFile?n.extension==="md"&&e.push(n):n instanceof Ot.TFolder&&s.push(n)}return e}var Ae=class{constructor(f){this.app=f;this.nodes=new Map;this.byPath=new Map;this.listeners=new Set;this.orderProvider=null;this.synthetic=new Map;this.coalesceTimer=null;this.nodes.set(B,{id:B,parent:null,children:[],file:null,created:""})}setOrderProvider(f){this.orderProvider=f}onChange(f){return this.listeners.add(f),()=>this.listeners.delete(f)}emit(){for(let f of this.listeners)f()}rebuild(f){f!==void 0&&(this.currentFolder=f);let t=this.currentFolder,e=this.byPath,s=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(B,{id:B,parent:null,children:[],file:null,created:""});let i=t?ui(this.app,t):this.app.vault.getMarkdownFiles();for(let n of i){let r=this.app.metadataCache.getFileCache(n)?.frontmatter,o=r?.id;if(!o){let l=e.get(n.path),c=l?s.get(l):void 0,d=this.synthetic.get(n.path),p=c??d;p&&(this.nodes.set(p.id,{...p,children:[],file:n}),this.byPath.set(n.path,p.id));continue}if(this.synthetic.delete(n.path),o===B){let l=this.nodes.get(B);l.file=n,l.created=r?.created??"",this.byPath.set(n.path,B);continue}let a=r?.parent??null;this.nodes.set(o,{id:o,parent:a??B,children:[],file:n,created:r?.created??""}),this.byPath.set(n.path,o)}for(let n of this.nodes.values()){if(n.id===B)continue;let r=n.parent??B;(this.nodes.get(r)??this.nodes.get(B)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((r,o)=>{let a=this.nodes.get(r),l=this.nodes.get(o);return(a.created||"").localeCompare(l.created||"")}),this.orderProvider){let r=this.orderProvider(n.id);if(r.length>0){let o=new Map;r.forEach((a,l)=>o.set(a,l)),n.children.sort((a,l)=>{let c=o.has(a)?o.get(a):1/0,d=o.has(l)?o.get(l):1/0;return c===d?0:c-d})}}this.emit()}insertSynthetic(f){if(!f.file)return;let t=f.file.path;this.synthetic.set(t,f),this.nodes.set(f.id,f),this.byPath.set(t,f.id);let e=f.parent??B,s=this.nodes.get(e);s&&!s.children.includes(f.id)&&s.children.push(f.id),this.emit()}get(f){return this.nodes.get(f)}getRoot(){return this.nodes.get(B)}getChildren(f){let t=this.nodes.get(f);return t?t.children.map(e=>this.nodes.get(e)).filter(e=>!!e):[]}pathTo(f){let t=[],e=this.nodes.get(f);for(;e&&e.id!==B;)t.unshift(e),e=e.parent?this.nodes.get(e.parent):void 0;return t}idForPath(f){return this.byPath.get(f)}snapshot(){let f={};for(let t of this.nodes.values())t.id===B||!t.file||(f[t.id]={parent:t.parent===B?null:t.parent,path:t.file.path});return f}hookMetadataCache(f){let t=a=>{let l=this.currentFolder;return l?typeof a!="string"?!1:a===l||a.startsWith(l+"/"):!0},e=!1,s=()=>{e=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,e&&(e=!1,this.emit(),f())},16))},i=a=>{a instanceof Ot.TFile&&t(a.path)&&a.extension==="md"&&this.applyChange(a)&&s()},n=a=>{a instanceof Ot.TFile&&t(a.path)&&a.extension==="md"&&this.applyChange(a)&&s()},r=a=>{let l=a?.path;typeof l=="string"&&t(l)&&this.applyDelete(l)&&s()},o=(a,l)=>{if(!(a instanceof Ot.TFile))return;let c=typeof l=="string"?l:null;!t(a.path)&&!t(c)||this.applyRename(a,c??"")&&s()};return this.app.metadataCache.on("changed",i),this.app.vault.on("create",n),this.app.vault.on("delete",r),this.app.vault.on("rename",o),()=>{this.app.metadataCache.off("changed",i),this.app.vault.off("create",n),this.app.vault.off("delete",r),this.app.vault.off("rename",o),this.coalesceTimer!=null&&(window.clearTimeout(this.coalesceTimer),this.coalesceTimer=null)}}applyChange(f){let t=this.app.metadataCache.getFileCache(f)?.frontmatter,e=t?.id,s=this.byPath.get(f.path);if(!e){if(s){let l=this.nodes.get(s);if(l&&l.file!==f)return l.file=f,!0}return!1}if(this.synthetic.delete(f.path),e===B){let l=this.nodes.get(B),c=t?.created??"",d=!1;return l.file!==f&&(l.file=f,d=!0),l.created!==c&&(l.created=c,d=!0),this.byPath.get(f.path)!==B&&(this.byPath.set(f.path,B),d=!0),d}let i=t?.parent??B,n=t?.created??"";if(!(i===B||this.nodes.has(i)))return this.rebuild(),!0;if(s&&s!==e)return this.rebuild(),!0;let o=this.nodes.get(e);if(!o){let l={id:e,parent:i,children:[],file:f,created:n};return this.nodes.set(e,l),this.byPath.set(f.path,e),this.attachToParent(l),this.resortChildrenOf(i),!0}let a=!1;if(o.file!==f&&(o.file=f,a=!0),o.created!==n&&(o.created=n,this.resortChildrenOf(o.parent??B),a=!0),o.parent!==i){let l=o.parent??B;this.detachFromParent(o),o.parent=i,this.attachToParent(o),this.resortChildrenOf(l),this.resortChildrenOf(i),a=!0}return a}applyDelete(f){let t=this.byPath.get(f);if(!t)return!1;let e=this.nodes.get(t);if(!e)return this.byPath.delete(f),this.synthetic.delete(f),!0;this.detachFromParent(e);let s=this.nodes.get(B);for(let i of e.children){let n=this.nodes.get(i);n&&(n.parent=B,s.children.includes(i)||s.children.push(i))}return e.children.length>0&&this.resortChildrenOf(B),this.nodes.delete(t),this.byPath.delete(f),this.synthetic.delete(f),!0}applyRename(f,t){let e=this.currentFolder,s=!e||t===e||t.startsWith(e+"/"),i=!e||f.path===e||f.path.startsWith(e+"/");if(!s&&!i)return!1;if(s&&!i)return this.applyDelete(t);if(!s&&i)return this.applyChange(f);let n=this.byPath.get(t);if(!n)return this.applyChange(f);this.byPath.delete(t),this.byPath.set(f.path,n);let r=this.nodes.get(n);return r&&(r.file=f),!0}detachFromParent(f){let t=this.nodes.get(f.parent??B);if(!t)return;let e=t.children.indexOf(f.id);e>=0&&t.children.splice(e,1)}attachToParent(f){let t=this.nodes.get(f.parent??B);t||(t=this.nodes.get(B)),t.children.includes(f.id)||t.children.push(f.id)}resortChildrenOf(f){let t=this.nodes.get(f);if(t&&(t.children.sort((e,s)=>{let i=this.nodes.get(e),n=this.nodes.get(s);return(i.created||"").localeCompare(n.created||"")}),this.orderProvider)){let e=this.orderProvider(f);if(e.length>0){let s=new Map;e.forEach((i,n)=>s.set(i,n)),t.children.sort((i,n)=>{let r=s.has(i)?s.get(i):1/0,o=s.has(n)?s.get(n):1/0;return r===o?0:r-o})}}}};var Ms=".stashpad-order.json",Pe=class{constructor(f){this.app=f;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(f){if(this.cache.has(f))return this.cache.get(f);let t=`${f}/${Ms}`,e=this.app.vault.adapter,s={};try{if(await e.exists(t)){let i=await e.read(t),n=JSON.parse(i);if(n&&typeof n=="object"&&!Array.isArray(n))for(let[r,o]of Object.entries(n))Array.isArray(o)&&o.every(a=>typeof a=="string")&&(s[r]=o)}}catch(i){console.warn("Stashpad: order load failed",i)}return this.cache.set(f,s),s}async save(f){this.scheduleWrite(f)}async flush(f){let t=this.pendingTimers.get(f);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(f)),await this.writeNow(f)}scheduleWrite(f){let t=this.pendingTimers.get(f);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(f),this.writeNow(f)},150);this.pendingTimers.set(f,e)}async writeNow(f){let e=(this.writeInFlight.get(f)??Promise.resolve()).then(()=>this.doWrite(f));this.writeInFlight.set(f,e);try{await e}finally{this.writeInFlight.get(f)===e&&this.writeInFlight.delete(f)}}async doWrite(f){let t=this.cache.get(f)??{},e={};for(let[n,r]of Object.entries(t))r.length>0&&(e[n]=r);this.cache.set(f,e);let s=`${f}/${Ms}`,i=this.app.vault.adapter;try{if(Object.keys(e).length===0)try{await i.remove(s)}catch{}else await i.write(s,JSON.stringify(e,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(f,t){return this.cache.get(f)?.[t]?.slice()??[]}setOrder(f,t,e){let s=this.cache.get(f)??{};s[t]=e.slice(),this.cache.set(f,s)}appendChild(f,t,e){let s=this.cache.get(f)??{},i=s[t]??[];i.includes(e)||i.push(e),s[t]=i,this.cache.set(f,s)}removeChild(f,t){let e=this.cache.get(f);if(e)for(let s of Object.values(e)){let i=s.indexOf(t);i>=0&&s.splice(i,1)}}invalidate(f){this.cache.delete(f)}};var he={manual:"Manual","created-asc":"Created \u2014 oldest first","created-desc":"Created \u2014 newest first","modified-asc":"Modified \u2014 oldest first","modified-desc":"Modified \u2014 newest first","title-az":"Title \u2014 A\u2192Z","title-za":"Title \u2014 Z\u2192A"},cs=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],fi=new Set(cs),_s=".stashpad-sort.json",Me=class{constructor(f){this.app=f;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(f){if(this.cache.has(f))return this.cache.get(f);let t=`${f}/${_s}`,e=this.app.vault.adapter,s={};try{if(await e.exists(t)){let i=JSON.parse(await e.read(t));if(i&&typeof i=="object"&&!Array.isArray(i))for(let[n,r]of Object.entries(i))typeof r=="string"&&fi.has(r)&&(s[n]=r)}}catch(i){console.warn("Stashpad: sort load failed",i)}return this.cache.set(f,s),s}async save(f){this.scheduleWrite(f)}async flush(f){let t=this.pendingTimers.get(f);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(f)),await this.writeNow(f)}scheduleWrite(f){let t=this.pendingTimers.get(f);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(f),this.writeNow(f)},150);this.pendingTimers.set(f,e)}async writeNow(f){let e=(this.writeInFlight.get(f)??Promise.resolve()).then(()=>this.doWrite(f));this.writeInFlight.set(f,e);try{await e}finally{this.writeInFlight.get(f)===e&&this.writeInFlight.delete(f)}}async doWrite(f){let t=this.cache.get(f)??{},e=`${f}/${_s}`,s=this.app.vault.adapter;try{if(Object.keys(t).length===0)try{await s.remove(e)}catch{}else await s.write(e,JSON.stringify(t,null,2))}catch(i){console.warn("Stashpad: sort save failed",i)}}getMode(f,t){return this.cache.get(f)?.[t]??"manual"}setMode(f,t,e){let s=this.cache.get(f)??{};e==="manual"?delete s[t]:s[t]=e,this.cache.set(f,s)}removeParent(f,t){let e=this.cache.get(f);e&&delete e[t]}invalidate(f){this.cache.delete(f)}};xt();var $t="parentLink",Xt="children";var Ne=class Ne{constructor(f,t){this.app=f;this.getTree=t;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.errorListeners=new Set}onActivity(f){return this.activityListeners.add(f),()=>this.activityListeners.delete(f)}emitActivity(){let f=this.pending.size;for(let t of this.activityListeners)try{t(f)}catch(e){console.warn("[Stashpad] fmSync activity listener failed",e)}}schedule(f){if(!f)return;let t=this.pending.size;this.pending.add(f),this.pending.size!==t&&this.emitActivity(),this.kick()}scheduleParentChange(f,t,e){this.schedule(f),t&&this.schedule(t),this.schedule(e)}scheduleSubtree(f){let t=this.getTree(),e=s=>{this.schedule(s);for(let i of t.getChildren(s))e(i.id)};e(f)}scheduleParentOfDeleted(f){f&&this.schedule(f)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let f=this.pending.values().next().value;if(f===void 0)break;this.pending.delete(f),this.emitActivity(),await this.syncOne(f)}}pendingCount(){return this.pending.size}onError(f){return this.errorListeners.add(f),()=>this.errorListeners.delete(f)}emitError(f,t){for(let e of this.errorListeners)try{e(f,t)}catch(s){console.warn("[Stashpad] fmSync error listener failed",s)}}reset(){this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null),this.pending.clear()}kick(){this.timer!=null||this.pending.size===0||(this.timer=window.setTimeout(()=>this.tick(),Ne.PACING_MS))}async tick(){this.timer=null;let f=this.pending.values().next().value;if(f!==void 0){this.pending.delete(f),this.emitActivity();try{await this.syncOne(f)}catch(t){console.warn("[Stashpad] frontmatter sync tick failed",t)}this.pending.size>0&&this.kick()}}wouldWrite(f){let e=this.getTree().get(f);if(!e||!e.file)return!1;let s=this.computeParentLink(e),i=this.computeChildrenLinks(e),n=this.app.metadataCache.getFileCache(e.file)?.frontmatter,r=n&&typeof n[$t]=="string"?n[$t]:null,o=n?.[Xt],a=Array.isArray(o)?o.filter(l=>typeof l=="string"):[];if((r??null)!==(s??null)||a.length!==i.length)return!0;for(let l=0;l<a.length;l++)if(a[l]!==i[l])return!0;return!1}async syncOne(f){let e=this.getTree().get(f);if(!e||!e.file||!this.wouldWrite(f))return;let s=this.computeParentLink(e),i=this.computeChildrenLinks(e);try{await this.app.fileManager.processFrontMatter(e.file,n=>{s?n[$t]=s:delete n[$t],i.length>0?n[Xt]=i:delete n[Xt]})}catch(n){console.warn("[Stashpad] frontmatter sync failed",e.file?.path,n),this.emitError(e.file.path,n)}}computeParentLink(f){if(f.id===B)return null;let t=this.getTree();if(!f.parent||f.parent===B){let s=t.getRoot();return s&&s.id!==f.id&&s.file?_e(s.file.path):null}let e=t.get(f.parent);return e?.file?_e(e.file.path):null}computeChildrenLinks(f){return this.getTree().getChildren(f.id).filter(e=>!!e.file).map(e=>_e(e.file.path))}};Ne.PACING_MS=100;var Le=Ne;async function Ls(v,f){let t=f.endsWith("/")?f:f+"/",e=new Map,s=new Map;for(let l of v.vault.getMarkdownFiles()){if(l.path!==f&&!l.path.startsWith(t))continue;let c=v.metadataCache.getFileCache(l)?.frontmatter,d=typeof c?.id=="string"?c.id:null;if(!d)continue;let p=typeof c?.parent=="string"?c.parent:B;e.set(d,{file:l,id:d,parent:p});let h=s.get(p)??[];h.push(d),s.set(p,h)}let i=l=>_e(l.file.path),n=l=>{if(l.id===B)return null;if(l.parent===B||!l.parent){let d=e.get(B);return d?i(d):null}let c=e.get(l.parent);return c?i(c):null},r=l=>{let c=s.get(l.id)??[],d=[];for(let p of c){let h=e.get(p);h&&d.push(i(h))}return d},o=0,a=0;for(let l of e.values()){o+=1;let c=n(l),d=r(l),p=v.metadataCache.getFileCache(l.file)?.frontmatter,h=p&&typeof p[$t]=="string"?p[$t]:null,u=p?.[Xt],m=Array.isArray(u)?u.filter(S=>typeof S=="string"):[],g=(h??null)===(c??null),y=m.length===d.length&&m.every((S,k)=>S===d[k]);if(!(g&&y))try{await v.fileManager.processFrontMatter(l.file,S=>{c?S[$t]=c:delete S[$t],d.length>0?S[Xt]=d:delete S[Xt]}),a+=1,await new Promise(S=>setTimeout(S,50))}catch(S){console.warn("[Stashpad] rebootstrap fm sync failed",l.file.path,S)}}return{checked:o,written:a}}function _e(v){return`[[${v.replace(/\.md$/i,"")}]]`}var $e=require("obsidian"),ds={create:{label:"Create",desc:"Confirmations after a new note is created."},edit:{label:"Edit",desc:"Edit-related toasts (currently rare)."},delete:{label:"Delete",desc:"Confirmations after deleting one or more notes."},move:{label:"Move",desc:"After reparenting or moving notes between folders."},merge:{label:"Merge",desc:"After combining multiple notes into one."},split:{label:"Split",desc:"After splitting a note in two."},clone:{label:"Clone",desc:"After duplicating notes or subtrees."},complete:{label:"Complete",desc:"When a note is marked complete."},uncomplete:{label:"Uncomplete",desc:"When a note's complete mark is removed."},export:{label:"Export",desc:".stash exports \u2014 success + the action buttons."},import:{label:"Import",desc:".stash imports (both manual and the drop-folder auto-import)."},attachment:{label:"Attachment",desc:"Attachment add / remove notifications."},color:{label:"Color",desc:"Per-note color changes."},reorder:{label:"Reorder",desc:"Drag-reorder and keyboard moveUp/Down/Top/Bottom."},multiplayer:{label:"Multiplayer",desc:"Cross-author activity (someone else touched your notes or vice versa)."},system:{label:"System",desc:"Plumbing toasts: backfill progress, integrity warnings, errors not tied to a verb."}},mi={info:4e3,success:4e3,warning:6e3,error:1e4},Ns=5e3,Oe=class{constructor(f){this.app=f;this.history=[];this.nextId=1;this.historyLimit=Ns;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(f){this.defaultAuthorId=f||null}show(f){let t=f.kind??"info",e=f.category??"system",s={id:this.nextId++,ts:Date.now(),message:f.message,kind:t,category:e,authorId:f.authorId??this.defaultAuthorId??void 0,affectedIds:f.affectedIds?f.affectedIds.slice():[],affectedPaths:f.affectedPaths?f.affectedPaths.slice():[],affectedAuthorIds:f.affectedAuthorIds?f.affectedAuthorIds.slice():[],folder:f.folder,actionLabels:(f.actions??[]).map(r=>r.label)};if(this.pushHistory(s),this.muted.has(e))return null;let i=this.buildContent(f,t),n=f.duration??mi[t];return new $e.Notice(i,n)}onChange(f){return this.changeListeners.add(f),()=>this.changeListeners.delete(f)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(f,t){t?this.muted.add(f):this.muted.delete(f)}isMuted(f){return this.muted.has(f)}loadMutedFromList(f){this.muted=new Set(f)}mutedList(){return Array.from(this.muted)}loadHistory(f){let t=this.applyLimit(f.slice());this.history=t;let e=0;for(let s of t)s.id>e&&(e=s.id);this.nextId=Math.max(this.nextId,e+1),this.emit()}setHistoryLimit(f){this.historyLimit=Number.isFinite(f)?f:Ns,this.history=this.applyLimit(this.history),this.emit()}applyLimit(f){return this.historyLimit<=0||f.length<=this.historyLimit?f:f.slice(f.length-this.historyLimit)}pushHistory(f){this.history.push(f),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let f of this.changeListeners)try{f()}catch(t){console.warn("[Stashpad] notification listener failed",t)}}buildContent(f,t){let e=document.createDocumentFragment(),s=document.createElement("div");s.className=`stashpad-notice stashpad-notice-${t}`;let i=document.createElement("div");i.className="stashpad-notice-message";let n=f.message.split(/(`[^`\n]+`)/);for(let r of n)if(r.length>1&&r.startsWith("`")&&r.endsWith("`")){let o=document.createElement("code");o.textContent=r.slice(1,-1),i.appendChild(o)}else r.length>0&&i.appendChild(document.createTextNode(r));if(s.appendChild(i),f.actions&&f.actions.length>0){let r=document.createElement("div");r.className="stashpad-notice-actions";for(let o of f.actions){let a=document.createElement("button");a.className="stashpad-notice-action",a.textContent=o.label,a.addEventListener("click",l=>{if(l.stopPropagation(),Promise.resolve().then(()=>o.onClick()).catch(c=>console.warn("[Stashpad] notification action failed",c)),!o.keepOpen){let c=a.closest(".notice");c&&c.parentElement&&c.parentElement.removeChild(c)}}),r.appendChild(a)}s.appendChild(r)}return e.appendChild(s),e}};function Re(v,f,t){let e=v.vault.getAbstractFileByPath(f);if(!(e instanceof $e.TFile))return[];let s=[{label:"Reveal",keepOpen:!0,onClick:()=>{let i=v.workspace.getLeavesOfType("file-explorer")[0];if(!i)return;v.workspace.revealLeaf(i),i.view?.revealInFolder?.(e)}}];return t||s.push({label:"Show in Finder",keepOpen:!0,onClick:()=>{try{let i=window.require?.("electron")?.shell,r=v.vault.adapter?.getFullPath?.(f);r&&i?.showItemInFolder&&i.showItemInFolder(r)}catch(i){console.warn("[Stashpad] showItemInFolder failed",i)}}}),s}Rt();pe();var He=class{constructor(f,t){this.tree=f;this.log=t}async sweep(f){let t=await this.log.readState(),e=this.tree.snapshot(),s=n=>{if(!f)return!0;let r=f.replace(/\/+$/,"");return n===r||n.startsWith(r+"/")};for(let[n,r]of Object.entries(e)){let o=t[n];o?o.parent!==r.parent?await this.log.append({type:"parent_change",id:n,payload:{from:o.parent,to:r.parent}}):o.path!==r.path&&await this.log.append({type:"rename",id:n,payload:{from:o.path,to:r.path}}):await this.log.append({type:"create",id:n,payload:{path:r.path,parent:r.parent}})}for(let[n,r]of Object.entries(t))!e[n]&&s(r.path)&&await this.log.append({type:"missing",id:n,payload:{lastPath:r.path}});let i={};for(let[n,r]of Object.entries(t))s(r.path)||(i[n]=r);for(let[n,r]of Object.entries(e))i[n]=r;await this.log.writeState(i)}};var tt=require("obsidian");fe();var Ue=require("obsidian"),ee=class extends Ue.AbstractInputSuggest{constructor(t,e){super(t,e);this.inputEl=e}getSuggestions(t){let e=t.toLowerCase(),s=[],i=n=>{n.path!=="/"&&(!e||n.path.toLowerCase().includes(e))&&s.push(n);for(let r of n.children)r instanceof Ue.TFolder&&i(r)};return i(this.app.vault.getRoot()),s.slice(0,100)}renderSuggestion(t,e){e.setText(t.path)}selectSuggestion(t){this.setValue(t.path),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}};xt();Gt();var fs=(()=>{try{return typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/i.test(navigator.platform||navigator.userAgent||"")}catch{return!1}})();function ms(v){if(!v)return"(none)";let f=v.replace(/\bMod\b/g,fs?"Cmd":"Ctrl");return fs&&(f=f.replace(/\bAlt\b/g,"Option")),f}function zs(v,f,t={allowSingleKey:!0}){let e=v.placeholder,s=v.value;v.placeholder="Press a key\u2026 (Backspace to cancel)",v.value="",v.classList.add("is-recording");let i=!1,n=()=>{v.placeholder=e,v.classList.remove("is-recording"),i||(v.value=s),v.removeEventListener("keydown",r,!0),v.removeEventListener("blur",o)},r=a=>{if(a.key==="Control"||a.key==="Shift"||a.key==="Alt"||a.key==="Meta"||a.key==="OS")return;let l=!!a.code&&(/^Key[A-Z]$/.test(a.code)||/^Digit\d$/.test(a.code));if((a.key==="Dead"||a.key==="Process"||a.key==="Unidentified")&&!l)return;if(a.preventDefault(),a.stopPropagation(),a.key==="Backspace"&&!a.metaKey&&!a.ctrlKey&&!a.altKey&&!a.shiftKey){n();return}let c=[];fs?(a.metaKey&&c.push("Mod"),a.ctrlKey&&c.push("Ctrl")):a.ctrlKey&&c.push("Mod"),a.altKey&&c.push("Alt"),a.shiftKey&&c.push("Shift");let d=bi(a.key,a.code);if(!d||c.length===0&&!t.allowSingleKey)return;c.push(d);let p=c.join("+");i=!0,n(),f(p)},o=()=>n();return v.addEventListener("keydown",r,!0),v.addEventListener("blur",o),n}function bi(v,f){if(!v)return"";if(f){let t=/^Key([A-Z])$/.exec(f);if(t)return t[1];let e=/^Digit(\d)$/.exec(f);if(e)return e[1]}return v.length===1?v.toUpperCase():v}pe();Rt();var me=null,Ve=new Set;function Ye(v){if(me!==v){me=v;for(let f of Ve)f()}}function _t(){return me}function Ws(v){if(me===v){me=null;for(let f of Ve)f()}}function js(v){return Ve.add(v),()=>Ve.delete(v)}var ge=[{id:"move",label:"Move (picker)",desc:"Open a fuzzy picker to choose the new parent.",defaultPrimary:"M"},{id:"pickMove",label:"Move (in-list)",desc:"Highlight a note in the list with arrows; Enter sets it as parent.",defaultPrimary:"O"},{id:"merge",label:"Merge",desc:"Concatenate selected notes into the oldest one.",defaultPrimary:"&"},{id:"copy",label:"Copy",desc:"Copy selected note bodies to clipboard.",defaultPrimary:"C"},{id:"copyTree",label:"Copy tree",desc:"Copy the focused note + all descendants, indented.",defaultPrimary:"Y"},{id:"openEditor",label:"Open in editor",desc:"Open the cursor row (or focused note) in a regular Obsidian markdown tab.",defaultPrimary:"E"},{id:"openTab",label:"Open in new Stashpad tab",desc:"Open the cursor row (or focused note) in a new Stashpad tab focused on it.",defaultPrimary:"T"},{id:"split",label:"Split note",desc:"Split the cursor row (or focused note) into two notes at a chosen line.",defaultPrimary:"S"},{id:"copyOutline",label:"Copy as outline",desc:"Copy selection (or cursor row) as a nested ![[embed]] outline.",defaultPrimary:"L"},{id:"toggleSplit",label:"Toggle split-on-newlines",desc:"Default: Mod+/",defaultPrimary:"Mod+/"},{id:"pickDestination",label:"Pick destination",desc:"Default: Mod+D",defaultPrimary:"Mod+D"},{id:"search",label:"Search notes",desc:"Default: Mod+F",defaultPrimary:"Mod+F"},{id:"searchInParent",label:"Search in current parent",desc:"Default: Mod+Alt+F (Mod+Shift+F is taken by Obsidian's global search).",defaultPrimary:"Mod+Alt+F"},{id:"delete",label:"Delete selection",desc:"Default: Mod+Backspace",defaultPrimary:"Mod+Backspace"},{id:"undo",label:"Undo",desc:"Default: Mod+Z (Stashpad-only \u2014 won't fire while typing in the composer).",defaultPrimary:"Mod+Z"},{id:"redo",label:"Redo",desc:"Default: Mod+Shift+Z",defaultPrimary:"Mod+Shift+Z"},{id:"toggleComplete",label:"Toggle complete (strikethrough)",desc:"Default: Mod+Enter \u2014 marks selected/focused notes as complete.",defaultPrimary:"Mod+Enter"},{id:"moveUp",label:"Move note up",desc:"Default: Mod+ArrowUp",defaultPrimary:"Mod+ArrowUp"},{id:"moveDown",label:"Move note down",desc:"Default: Mod+ArrowDown",defaultPrimary:"Mod+ArrowDown"},{id:"moveToTop",label:"Move note to top",desc:"Default: Mod+Shift+ArrowUp",defaultPrimary:"Mod+Shift+ArrowUp"},{id:"moveToBottom",label:"Move note to bottom",desc:"Default: Mod+Shift+ArrowDown",defaultPrimary:"Mod+Shift+ArrowDown"},{id:"outdent",label:"Outdent (move to grandparent)",desc:"Default: Mod+[ \u2014 re-parents the selection one level up.",defaultPrimary:"Mod+["},{id:"setColor",label:"Set note color",desc:"Default: Shift+: \u2014 open the color picker for the selection.",defaultPrimary:"Shift+:"},{id:"clone",label:"Clone (duplicate / copy) selection",desc:"Default: Mod+Shift+D \u2014 clone selected notes (with their subtrees) as siblings.",defaultPrimary:"Mod+Shift+D"},{id:"insertTemplate",label:"Insert template (clone an existing note)",desc:"Pick any note in this Stashpad; clone it (with subtree + attachments) into the current view, retimestamped.",defaultPrimary:""},{id:"toggleExpand",label:"Show more / show less (expand toggle)",desc:"Default: Shift+? \u2014 toggle the clamp on the cursor row (or every selected row).",defaultPrimary:"Shift+?"},{id:"exportStash",label:"Export selection to .stash",desc:"Export the selected subtree(s) as a .stash bundle (notes + attachments).",defaultPrimary:""},{id:"importStash",label:"Import .stash file",desc:"Open the .stash bundle picker and import its notes into this Stashpad.",defaultPrimary:""},{id:"pickFolder",label:"Open / switch / create Stashpad folder",desc:"Default: Mod+S \u2014 opens the unified folder picker (reveal, switch, create, convert).",defaultPrimary:"Mod+S"},{id:"cloneStashpadTab",label:"Clone (duplicate / copy) this Stashpad tab",desc:'Open a second tab on the same folder + focus, mirroring the "copy" button in the focused-header actions.',defaultPrimary:""},{id:"selectAll",label:"Select all notes in view",desc:"Default: Mod+A \u2014 adds every visible row to the selection.",defaultPrimary:"Mod+A"},{id:"copyCodeBlock",label:"Copy code from codeblock",desc:"Default: { \u2014 copy the contents of the cursor row's first codeblock (or pick one when multiple exist).",defaultPrimary:"{"},{id:"swapWithParent",label:"Swap with parent (ouroboros)",desc:"Promote the cursor row above its current parent; the parent slides under it (carrying its other children). No default \u2014 bind in this tab.",defaultPrimary:""},{id:"togglePin",label:"Pin / unpin selected note",desc:"Default: P \u2014 toggle the sidebar pin state of the cursor row (or focused note).",defaultPrimary:"P"},{id:"toggleTask",label:"Toggle task (todo)",desc:"Default: H \u2014 mark the selection (or cursor row) as a task / todo, or clear it. Tasks appear in the Tasks panel.",defaultPrimary:"H"},{id:"setDue",label:"Set due date\u2026",desc:"Default: D \u2014 open a date+time picker to set (or clear) the due date on the selection. Setting a due date also marks the note as a task.",defaultPrimary:"D"}];function vs(){let v={};for(let f of ge)v[f.id]={primary:f.defaultPrimary,secondary:"",preferRight:!1};return v}var zt={folder:"Stashpad",importDropFolder:"_imports",exportFolder:"_exports",useTemplatesFormat:!1,prefixTimestampsOnCopy:!0,splitOnLines:!1,confirmCrossParentDrag:!0,confirmBulkDelete:!0,confirmAttachmentDelete:!0,autofocusComposerAfterSend:!0,popoutDuplicates:!0,pinnedNotes:[],hideMobileToolbarInStashpad:!0,slugStopWords:[],searchIncludedFolders:[],searchExcludedFolders:[],shortcuts:{move:"M",pickMove:"O",merge:"&",copy:"C",copyTree:"Y",openEditor:"E",openTab:"T",split:"S",copyOutline:"L"},mod:{toggleSplit:"Mod+/",pickDestination:"Mod+D",search:"Mod+F",delete:"Mod+Backspace",undo:"Mod+Z",redo:"Mod+Shift+Z",toggleComplete:"Mod+Enter",moveUp:"Mod+ArrowUp",moveDown:"Mod+ArrowDown",moveToTop:"Mod+Shift+ArrowUp",moveToBottom:"Mod+Shift+ArrowDown",outdent:"Mod+[",setColor:"Shift+:"},customPalette:[],colorAliases:{},noteTemplates:{},authorName:"",authorId:"",authorRole:"",authorDepartment:"",showAuthor:!0,showContributors:!0,showLastEdit:!0,viewModes:{},includeAttachmentsInEverything:{},hideChildlessNotes:{},hideCompletedNotes:{},mutedNotificationCategories:[],notificationHistoryLimit:5e3,autoNavOnMoveIn:!1,autoNavOnMoveOut:!1,autoExpandCursorRow:!1,autoOpenDetailPanel:!1,doubleClickToFocus:!0,dateDisplayFormat:"locale",dateDisplayTimezone:"",jdIndexScope:"vault",jdIndexScopeFolder:"",jdIndexStashpadFolder:"",jdIndexFile:"Index",jdIndexIncludeStashpadFolders:!1,jdIndexSort:"natural",jdIndexHasBuilt:!1,drafts:{},lastSubmitted:{},bindings:vs()},Us=JSON.parse(JSON.stringify(zt)),gs=new Set;function kt(){return Us}function ys(v){Us=v;for(let f of gs)f()}function Vs(v){return gs.add(v),()=>gs.delete(v)}function Ze(v){try{let f=v.internalPlugins?.plugins?.templates;if(!f?.enabled)return null;let t=f.instance?.options??{};return{dateFormat:t.dateFormat||"YYYY-MM-DD",timeFormat:t.timeFormat||"HH:mm"}}catch{return null}}var Ke=[{id:"general",label:"General"},{id:"diagnostics",label:"Diagnostics"},{id:"authorship",label:"Authorship"},{id:"templates",label:"Templates"},{id:"jdindex",label:"JD Index"},{id:"hotkeys",label:"Hotkeys"}],qe=class extends tt.PluginSettingTab{constructor(t,e){super(t,e);this.plugin=e;this.activeTab="general";this.searchQuery=""}openToTab(t){this.activeTab=t,this.searchQuery="",this.containerEl?.isShown?.()!==!1&&this.display()}focusSearchInput(){let t=this.containerEl?.querySelector(".stashpad-settings-search-input");t&&(t.focus(),t.setSelectionRange(t.value.length,t.value.length))}display(){let{containerEl:t}=this;t.empty(),t.addClass("stashpad-settings-tabbed"),t.createEl("h2",{text:"Stashpad",cls:"stashpad-settings-title"});let s=t.createDiv({cls:"stashpad-settings-search-wrap"}).createEl("input",{type:"text",placeholder:"Search settings\u2026",cls:"stashpad-settings-search-input"});s.value=this.searchQuery;let i=this.searchQuery.trim().length>0,n=t.createDiv({cls:"stashpad-settings-tabs"});i&&n.addClass("is-search-mode");for(let a of Ke){let l=n.createEl("button",{cls:"stashpad-settings-tab",text:a.label});!i&&this.activeTab===a.id&&l.addClass("is-active"),l.onclick=()=>{this.searchQuery="",this.activeTab=a.id,this.display()}}let r=t.createDiv({cls:"stashpad-settings-body"});if(i){for(let a of Ke){let l=r.createDiv({cls:"stashpad-settings-search-group"});l.createEl("h3",{text:a.label,cls:"stashpad-settings-search-group-header"});let c=l.createDiv();this.renderTabContent(c,a.id)}this.applySearchFilter(r)}else this.renderTabContent(r,this.activeTab);let o=i;s.oninput=()=>{this.searchQuery=s.value;let a=this.searchQuery.trim().length>0;if(a!==o){let l=s.selectionStart??s.value.length;this.display();let c=t.querySelector(".stashpad-settings-search-input");c&&(c.focus(),c.setSelectionRange(l,l));return}a&&this.applySearchFilter(r)},this.searchQuery&&setTimeout(()=>{s.focus(),s.setSelectionRange(s.value.length,s.value.length)},0)}applySearchFilter(t){let e=this.searchQuery.trim().toLowerCase();if(!e)return;t.querySelectorAll(".setting-item").forEach(i=>{let n=i.querySelector(".setting-item-name")?.textContent?.toLowerCase()??"",r=i.querySelector(".setting-item-description")?.textContent?.toLowerCase()??"",o=n.includes(e)||r.includes(e);i.style.display=o?"":"none"}),t.querySelectorAll(".stashpad-settings-search-group").forEach(i=>{let n=Array.from(i.querySelectorAll(".setting-item")).some(r=>r.style.display!=="none");i.style.display=n?"":"none"})}renderTabContent(t,e){switch(e){case"general":this.renderGeneralTab(t);break;case"diagnostics":this.renderDiagnosticsTab(t);break;case"authorship":this.renderAuthorshipSection(t);break;case"templates":this.renderTemplatesTab(t);break;case"jdindex":this.renderJdIndexSection(t);break;case"hotkeys":this.renderHotkeysTab(t);break}}renderDiagnosticsTab(t){new tt.Setting(t).setName("Open log file").setDesc("Append-only history of creates, deletes, parent changes, renames. Stored alongside the plugin's other private files.").addButton(r=>r.setButtonText("Open log").onClick(async()=>{let o=this.app.vault.adapter,a=this.plugin.pluginPrivatePath("log.jsonl");if(!await o.exists(a)){new tt.Notice("No log yet \u2014 make some changes first.");return}let l=await o.read(a);new qt(this.app,l,a).open()})),new tt.Setting(t).setName("Notification history limit").setDesc("Maximum number of notifications kept in the persistent history. Set to 0 for unlimited (the file size grows with usage; expect a few hundred KB per ~5000 entries). Default: 5000.").addText(r=>r.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000").onChange(async o=>{let a=parseInt(o,10);Number.isFinite(a)&&(this.plugin.settings.notificationHistoryLimit=a,this.plugin.notifications.setHistoryLimit(a),await this.plugin.saveSettings())}));let e=t.createEl("details",{cls:"stashpad-notif-mute-details"});e.createEl("summary",{text:"Mute notification categories"}),e.createDiv({cls:"stashpad-notif-mute-help"}).setText("Muted categories don't pop toasts but still appear in the history panel so you can review what was suppressed.");let i=new Set(this.plugin.settings.mutedNotificationCategories??[]),n=Object.keys(ds);for(let r of n){let o=ds[r];new tt.Setting(e).setName(o.label).setDesc(o.desc).addToggle(a=>a.setValue(!i.has(r)).onChange(async l=>{let c=!l;c?i.add(r):i.delete(r),this.plugin.settings.mutedNotificationCategories=Array.from(i),this.plugin.notifications.setMuted(r,c),await this.plugin.saveSettings()}))}new tt.Setting(t).setName("Notification history").setDesc("Browse the last 200 toasts. Filter by category. Live-updates as new notifications arrive. Muted categories still appear here so you can review what was suppressed.").addButton(r=>r.setButtonText("View notification history").onClick(()=>{new ce(this.app,this.plugin.notifications,async o=>{let a=this.app.vault.adapter,l=this.plugin.pluginPrivatePath("log.jsonl");if(!await a.exists(l)){new tt.Notice("No log yet \u2014 make some changes first.");return}let c=await a.read(l);new qt(this.app,c,l).open()},this.plugin.settings.authorId||null,o=>this.plugin.lookupNoteAuthorIds(o)).open()}))}renderGeneralTab(t){new tt.Setting(t).setName("Stashpad notes folder").setDesc("Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.").addText(i=>{new ee(this.app,i.inputEl),i.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad").onChange(async n=>{let r=(n||"").trim().replace(/^\/+|\/+$/g,"")||zt.folder,o=r.split("/").filter(Boolean).pop()??"";if(new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed"].map(l=>(l??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(o)){new tt.Notice(`"${r}" uses a reserved Stashpad subfolder name. Pick something else.`);return}this.plugin.settings.folder=r,await this.plugin.saveSettings()})}),new tt.Setting(t).setName("Stash import subfolder").setDesc("Subfolder name (relative to each Stashpad folder) where dropped .stash files auto-import. Created on demand. Leave blank to disable auto-import.").addText(i=>i.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports").onChange(async n=>{this.plugin.settings.importDropFolder=(n||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})),new tt.Setting(t).setName("Stash export subfolder").setDesc("Subfolder name (relative to each Stashpad folder) where exports land. Must differ from the import subfolder above.").addText(i=>i.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async n=>{let r=(n||"").trim().replace(/^\/+|\/+$/g,"")||zt.exportFolder;this.plugin.settings.exportFolder=r,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Rebootstrap existing Stashpad folders").setDesc("Walk every folder that has a home note: ensure infrastructure (_imports, _exports, drafts file), backfill the redundant parentLink + children frontmatter fields, AND rename any note whose filename slug no longer matches its body's first line. Safe to run anytime; skip-if-equal means already-synced notes are no-op writes.").addButton(i=>i.setButtonText("Rebootstrap now").onClick(async()=>{i.setDisabled(!0).setButtonText("Working\u2026");try{let{touched:n,fmChecked:r,fmWritten:o,slugsRenamed:a}=await this.plugin.rebootstrapAllFolders(),l=[];l.push(`rebootstrapped ${n.length} folder${n.length===1?"":"s"}`),o>0?l.push(`updated frontmatter on ${o} of ${r} notes`):r>0&&l.push(`frontmatter already in sync (${r} notes checked)`),a>0&&l.push(`renamed ${a} note${a===1?"":"s"} to match body`),new tt.Notice(`Stashpad: ${l.join("; ")}.`)}catch(n){new tt.Notice(`Stashpad: rebootstrap failed (${n.message})`)}finally{i.setDisabled(!1).setButtonText("Rebootstrap now")}})),new tt.Setting(t).setName("Use Templates plugin date/time formats").setDesc("When on, timestamps use the formats configured in the core Templates plugin. Off: YYYY.MM.DD + HH:mm A.").addToggle(i=>i.setValue(this.plugin.settings.useTemplatesFormat).onChange(async n=>{this.plugin.settings.useTemplatesFormat=n,await this.plugin.saveSettings()}));let e=Ze(this.app);t.createDiv({cls:"setting-item-description stashpad-settings-note"}).setText(e?`Templates plugin: date = "${e.dateFormat}", time = "${e.timeFormat}"`:"Templates plugin not enabled.");{let i=null,n=()=>{if(!i)return;let r=Date.now(),o=Ut(r,this.plugin.settings);i.setText(`Sample: ${o}`)};new tt.Setting(t).setName("Date display format").setDesc("How due dates and created/modified times are shown in the Tasks and detail panels.").addDropdown(r=>{r.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),r.addOption("long","Locale, long (Thursday, March 5\u2026)"),r.addOption("iso","ISO (2026-03-05 09:00)"),r.addOption("us","US (3/5/2026, 9:00 AM)"),r.addOption("eu","EU (5/3/2026, 09:00)"),r.setValue(this.plugin.settings.dateDisplayFormat??"locale"),r.onChange(async o=>{this.plugin.settings.dateDisplayFormat=o,await this.plugin.saveSettings(),n()})}),new tt.Setting(t).setName("Display timezone").setDesc("IANA timezone name (e.g. America/New_York, Europe/London, Asia/Kolkata). Leave blank to use your system timezone.").addText(r=>{r.setPlaceholder("(system timezone)"),r.setValue(this.plugin.settings.dateDisplayTimezone??""),r.onChange(async o=>{this.plugin.settings.dateDisplayTimezone=(o||"").trim(),await this.plugin.saveSettings(),n()})}),i=t.createDiv({cls:"setting-item-description stashpad-settings-note"}),n()}new tt.Setting(t).setName("Navigate into parent after moving a note IN").setDesc("When you move a note onto another note via the in-list move picker (drag-onto-sibling), automatically drill into the new parent so you can see the moved note in its new home. Off = stay focused where you were.").addToggle(i=>i.setValue(this.plugin.settings.autoNavOnMoveIn).onChange(async n=>{this.plugin.settings.autoNavOnMoveIn=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Navigate to destination after moving a note OUT").setDesc("When you outdent a note, move it via the cross-parent picker, or send it to Home, automatically drill into the destination parent. Off = stay focused where you were.").addToggle(i=>i.setValue(this.plugin.settings.autoNavOnMoveOut).onChange(async n=>{this.plugin.settings.autoNavOnMoveOut=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Double-click a note to open it").setDesc("Double-click (or double-tap on mobile) a note in the list to focus/open it \u2014 the same as pressing \u2192 or clicking the enter arrow. Single click still just selects. On by default.").addToggle(i=>i.setValue(this.plugin.settings.doubleClickToFocus).onChange(async n=>{this.plugin.settings.doubleClickToFocus=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Auto-open the detail panel").setDesc("Open the right-sidebar Stashpad detail panel automatically whenever a Stashpad view becomes active. The panel shows the cursored note's body, metadata, and children. Off = open manually via ribbon or command palette.").addToggle(i=>i.setValue(this.plugin.settings.autoOpenDetailPanel).onChange(async n=>{this.plugin.settings.autoOpenDetailPanel=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Expand the cursor row's body automatically").setDesc("As you arrow-key through the list, the row under the cursor temporarily un-clamps to show its full body. Moving away re-collapses it. Doesn't affect the persistent 'Show more' state \u2014 this is a transient view-only effect.").addToggle(i=>i.setValue(this.plugin.settings.autoExpandCursorRow).onChange(async n=>{this.plugin.settings.autoExpandCursorRow=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Confirm cross-parent drag-and-drop").setDesc("When dragging notes onto a note that has a different parent, ask before re-parenting (turn off to allow direct moves).").addToggle(i=>i.setValue(this.plugin.settings.confirmCrossParentDrag).onChange(async n=>{this.plugin.settings.confirmCrossParentDrag=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Confirm bulk deletes").setDesc("Warn before deletes that affect more than one note \u2014 multi-selection delete OR deleting a note that has descendants. A single childless note with no attachments never prompts. Off = those deletes apply immediately (undo still recovers everything).").addToggle(i=>i.setValue(this.plugin.settings.confirmBulkDelete).onChange(async n=>{this.plugin.settings.confirmBulkDelete=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Offer to delete attachments with note").setDesc(`When a note references attachments, the delete modal includes an "Also delete attachments" checkbox so orphaned files don't pile up in your vault. Attachments are detected from both ![[\u2026]] embeds in the body and the frontmatter attachments: list. Off = attachments are always preserved on delete (no checkbox shown), and a single childless note with attachments deletes silently.`).addToggle(i=>i.setValue(this.plugin.settings.confirmAttachmentDelete).onChange(async n=>{this.plugin.settings.confirmAttachmentDelete=n,await this.plugin.saveSettings()}));{let i=null,n=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:It).join(` -`);new tt.Setting(t).setName("Slug stop-words").setDesc("Words removed from auto-generated note titles (filenames). One per line.").addTextArea(r=>{r.setValue(n),i=r.inputEl,i.rows=6,i.style.fontFamily="var(--font-monospace)",r.onChange(async o=>{let a=(o||"").split(/\r?\n/).map(l=>l.trim().toLowerCase()).filter(Boolean);this.plugin.settings.slugStopWords=a,await this.plugin.saveSettings()})}).addExtraButton(r=>r.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(async()=>{this.plugin.settings.slugStopWords=[...It],i&&(i.value=It.join(` -`)),await this.plugin.saveSettings()}))}{let i=this.plugin.discoverStashpadFolders();if(new tt.Setting(t).setName("Cross-Stashpad search scope").setDesc("Toggle each Stashpad's pill to choose whether its notes contribute to cross-folder search. Excluded folders are still valid move destinations \u2014 their notes just don't appear in search results from elsewhere."),i.length===0)t.createEl("p",{cls:"setting-item-description"}).setText('No Stashpads found in this vault yet. A Stashpad is just a folder that contains a Stashpad-shaped note (frontmatter has both `id` and `parent`). Easiest way: open Stashpad (ribbon icon or command "Reveal or open Stashpad") \u2014 it auto-creates the default folder on first use. Or create one below.');else{let r=t.createDiv({cls:"stashpad-folder-list"});for(let o of i)this.renderFolderScopeRow(r,o)}let n=null;new tt.Setting(t).setName("Create a new Stashpad").setDesc("Type a vault-relative folder path. The folder is created (with intermediates) and seeded with a Home note so Stashpad recognizes it.").addText(r=>{r.setPlaceholder("my-stashpad"),n=r.inputEl}).addButton(r=>r.setButtonText("Create").setCta().onClick(async()=>{let o=(n?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!o){new tt.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(o),new tt.Notice(`Created Stashpad "${o}".`),n&&(n.value=""),await this.plugin.waitForStashpadFolder(o,2e3),this.display()}catch(a){new tt.Notice(`Couldn't create: ${a.message}`)}}))}new tt.Setting(t).setName("Autofocus composer after sending").setDesc("After Enter-submitting a note, return focus to the composer so you can keep typing. Off keeps focus in the list \u2014 useful if you want arrow keys to work without an extra click.").addToggle(i=>i.setValue(this.plugin.settings.autofocusComposerAfterSend).onChange(async n=>{this.plugin.settings.autofocusComposerAfterSend=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Open in new window \u2014 duplicate tab").setDesc("ON: the new-window button (in the time-filter row) duplicates the current Stashpad tab \u2014 original stays open in the main window. OFF: the leaf is MOVED to the new window, closing the original tab.").addToggle(i=>i.setValue(this.plugin.settings.popoutDuplicates).onChange(async n=>{this.plugin.settings.popoutDuplicates=n,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Prefix timestamps when copying").setDesc("Include each note's timestamp before its body when copying with C or Y.").addToggle(i=>i.setValue(this.plugin.settings.prefixTimestampsOnCopy).onChange(async n=>{this.plugin.settings.prefixTimestampsOnCopy=n,await this.plugin.saveSettings()}))}renderTemplatesTab(t){this.renderColorAliasesSection(t),this.renderNoteTemplatesSection(t)}renderHotkeysTab(t){t.createEl("p",{cls:"setting-item-description",text:"Each command has up to two slots. Click a slot and press a key (or chord) to bind it; press Backspace (delete on Mac) to cancel without binding; or click \u2715 to clear an existing binding. When both slots are set, the pill on the right decides which one is active."});for(let e of ge)this.renderBindingRow(t,e)}renderJdIndexSection(t){let e=t.createEl("h3",{text:"JD Index Builder"});e.id="stashpad-jd-index-section";let s=t.createEl("p",{cls:"setting-item-description"});s.innerHTML="Builds a Johnny-Decimal-style index inside a designated Stashpad folder. Two commands:<br/><strong>Preview</strong> overwrites the designated folder’s HOME note body with the would-be hierarchy + everything that didn’t match. Frontmatter is preserved; everything below it is replaced.<br/><strong>Build</strong> creates an actual hierarchy of Stashpad notes (one per prefix), with child\u2192parent relationships matching the dotted segments.<br/>Matches strict prefixes only: all-digits (<code>10 Life</code>) or alphanumeric-with-dots (<code>1.2 Family</code>, <code>animal.duck.yellow Eggs</code>). Mixed schemes sort numbers first, then alphabetically.";let i=this.plugin.discoverStashpadFolders();new tt.Setting(t).setName("Scope").setDesc("Scan the whole vault, or restrict to a single folder + its descendants.").addDropdown(a=>{a.addOption("vault","Entire vault"),a.addOption("folder","Single folder"),a.setValue(this.plugin.settings.jdIndexScope??"vault"),a.onChange(async l=>{this.plugin.settings.jdIndexScope=l==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new tt.Setting(t).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(a=>{new ee(this.app,a.inputEl),a.setPlaceholder("Path/To/Folder"),a.setValue(this.plugin.settings.jdIndexScopeFolder??""),a.onChange(async l=>{this.plugin.settings.jdIndexScopeFolder=(l||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new tt.Setting(t).setName("Include Stashpad folders in scan").setDesc("By default, notes inside any known Stashpad folder are excluded \u2014 the index destination shouldn't index itself, and other Stashpad folders are usually already organized. Toggle on if you want them included anyway.").addToggle(a=>{a.setValue(this.plugin.settings.jdIndexIncludeStashpadFolders===!0),a.onChange(async l=>{this.plugin.settings.jdIndexIncludeStashpadFolders=l,await this.plugin.saveSettings(),this.display()})}),new tt.Setting(t).setName("Designated Stashpad folder for Index").setDesc("Required. Must be a Stashpad folder. The index hierarchy is built here. New notes are created; nothing is deleted.").addText(a=>{new ee(this.app,a.inputEl),a.setPlaceholder(i[0]??"(pick a Stashpad folder)"),a.setValue(this.plugin.settings.jdIndexStashpadFolder??""),a.onChange(async l=>{this.plugin.settings.jdIndexStashpadFolder=(l||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new tt.Setting(t).setName("Sort").setDesc("Order of entries within the same depth. Natural: numbers first then alphabetical (recommended). Created: by source file's creation time \u2014 handy when prefixes are word-only and don't carry ordering.").addDropdown(a=>{a.addOption("natural","Natural (numeric \u2192 alphabetical)"),a.addOption("created","By creation time"),a.setValue(this.plugin.settings.jdIndexSort??"natural"),a.onChange(async l=>{this.plugin.settings.jdIndexSort=l==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=te(this.app,this.plugin,this.plugin.settings),r=t.createEl("p",{cls:"setting-item-description"}),o=n.skippedStashpadNotes.length>0?` (${n.skippedStashpadNotes.length} Stashpad-folder note${n.skippedStashpadNotes.length===1?"":"s"} excluded by default)`:"";r.setText(`Preview: ${n.indexed.length} note${n.indexed.length===1?"":"s"} would be indexed, ${n.nonIndex.length} would NOT be indexed${o}.`),new tt.Setting(t).setName("Actions").setDesc("Preview aggressively overwrites the designated folder's HOME note body (frontmatter preserved). Build creates Stashpad notes (existing notes with the same jdPrefix are updated, not duplicated).").addButton(a=>{a.setButtonText("Preview"),a.setTooltip("Overwrites the designated Stashpad folder's HOME note body with the preview."),a.onClick(async()=>{try{let l=await ze(this.app,this.plugin,this.plugin.settings);if(l.error==="no-dest"){new tt.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(l.error==="no-home"){new tt.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}We(this.app,l),this.display()}catch(l){console.error("[stashpad] preview failed",l),new tt.Notice(`Preview failed: ${l?.message??l}`,8e3)}})}).addButton(a=>{a.setButtonText("Build Stashpad notes"),a.setCta(),a.setTooltip("Create the Stashpad-note hierarchy. Existing notes with matching jdPrefix are updated."),a.onClick(()=>{if(!(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new tt.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new ue(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let d=await ps(this.app,this.plugin,this.plugin.settings);if(d.error==="no-dest"){new tt.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(d.error==="dest-not-stashpad"){new tt.Notice(`"${d.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder (or create one first).`,7e3);return}this.plugin.settings.jdIndexHasBuilt=!0,await this.plugin.saveSettings(),new tt.Notice(`Built: ${d.created} created, ${d.updated} updated, ${d.skipped} skipped \u2192 ${d.destFolder}`,6e3),this.display()}catch(d){console.error("[stashpad] build failed",d),new tt.Notice(`Build failed: ${d?.message??d}`,8e3)}}).open()})}).addButton(a=>{a.setButtonText("Reveal in Finder"),a.setTooltip("Open the designated Stashpad folder in your OS file browser."),a.onClick(async()=>{let l=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!l){new tt.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(l)){new tt.Notice(`Folder "${l}" doesn't exist yet.`,5e3);return}try{let d=this.app.vault.adapter.basePath;if(d){let{shell:p}=window.require?.("electron")??{},h=`${d}/${l}`;p?.openPath?.(h)}else new tt.Notice("Reveal in file system not supported on this platform.",4e3)}catch(d){new tt.Notice(`Couldn't open folder: ${d?.message??d}`,5e3)}})})}renderColorAliasesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0){new tt.Setting(t).setName("Color Aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let s=(()=>{let r=_t()?.noteFolder;return r&&e.includes(r)?r:e[0]})();new tt.Setting(t).setName("Color Aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(r=>{for(let o of e)r.addOption(o,o);r.setValue(s),r.onChange(o=>{s=o,n()})}),t.createEl("p",{cls:"setting-item-description",text:"Give each per-note color a friendly name. Filters and pickers display the alias instead of the hex code; the underlying color stays the same. The same hex in two Stashpads can have different aliases."});let i=t.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{i.empty();let r=this.plugin.collectColorsInFolder(s),o=new Map(r.map(d=>[d.hex,d.count])),a=this.plugin.settings.colorAliases?.[s.replace(/\/+$/,"")]??{},l=new Set([...o.keys(),...Object.keys(a)]);if(l.size===0){i.createEl("p",{cls:"setting-item-description",text:`No colors used or aliased in "${s}" yet. Set a per-note color (Shift+: or right-click \u2192 Set color) and it'll appear here.`});return}let c=[...l].map(d=>({hex:d,count:o.get(d)??0}));c.sort((d,p)=>p.count-d.count||d.hex.localeCompare(p.hex));for(let d of c)this.renderColorAliasRow(i,s,d.hex,d.count,n)};n()}renderAuthorshipSection(t){t.createEl("h3",{text:"Authorship"}),t.createEl("p",{cls:"setting-item-description",text:"Stamp each new note with your name. If the vault is later shared (e.g. a coworker opens it with --config pointing at their own settings folder), every modification automatically tracks contributors on top of the original author. Names link to per-user pages in <stashpad>/_authors/."}),new tt.Setting(t).setName("Author name").setDesc("Your display name. Used in the note footer + as the author/contributor link target. Leave blank to opt out (notes won't be stamped).").addText(s=>{s.setValue(this.plugin.settings.authorName).onChange(async i=>{this.plugin.settings.authorName=i.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=Ft()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new tt.Setting(t).setName("Author id (auto-assigned)").setDesc("Stable id appended to your name on links so coworkers with the same name don't collide. Generated once and shouldn't change. If you really need to reset it, clear and retype your author name above.").addText(s=>{s.setValue(this.plugin.settings.authorId).setDisabled(!0)}),new tt.Setting(t).setName("Title / role").setDesc('Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").').addText(s=>{s.setValue(this.plugin.settings.authorRole).onChange(async i=>{this.plugin.settings.authorRole=i.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new tt.Setting(t).setName("Department / team").setDesc('Optional. Shown on your author page (e.g. "Engineering", "Growth").').addText(s=>{s.setValue(this.plugin.settings.authorDepartment).onChange(async i=>{this.plugin.settings.authorDepartment=i.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new tt.Setting(t).setName("Show author in note footer").addToggle(s=>s.setValue(this.plugin.settings.showAuthor).onChange(async i=>{this.plugin.settings.showAuthor=i,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Show contributors in note footer").addToggle(s=>s.setValue(this.plugin.settings.showContributors).onChange(async i=>{this.plugin.settings.showContributors=i,await this.plugin.saveSettings()})),new tt.Setting(t).setName("Show last edit time in note footer").addToggle(s=>s.setValue(this.plugin.settings.showLastEdit).onChange(async i=>{this.plugin.settings.showLastEdit=i,await this.plugin.saveSettings()}));let e=this.plugin.collectAuthoredFolders();if(e.length>0){t.createEl("h4",{text:"Folders you've worked in"});let s=t.createDiv({cls:"stashpad-authored-folders-list"});for(let i of e){let n=s.createDiv({cls:"stashpad-authored-folder-row"}),r=n.createEl("a",{cls:"stashpad-authored-folder-link",text:i.folder});r.onclick=a=>{a.preventDefault(),this.plugin.activateViewForFolder(i.folder)};let o=[];i.authored>0&&o.push(`authored ${i.authored}`),i.contributed>0&&o.push(`contributed to ${i.contributed}`),n.createSpan({cls:"stashpad-authored-folder-counts",text:` \xB7 ${o.join(", ")}`})}}}renderNoteTemplatesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0)return;new tt.Setting(t).setName("Note templates per Stashpad").setDesc("Pick a markdown file to use as the default template for new notes in each Stashpad. The template's frontmatter becomes the new note's frontmatter (id/parent/created/attachments are always set by Stashpad). If the body contains {{body}}, that's where the user-typed body goes; otherwise the user body is followed by the template body.");let s=t.createDiv({cls:"stashpad-note-templates-list"}),i=n=>{let r=n.replace(/\/+$/,""),o=s.createDiv({cls:"stashpad-note-template-row"});o.createSpan({cls:"stashpad-note-template-folder"}).setText(n);let l=o.createDiv({cls:"stashpad-note-template-input-wrap"}),c=l.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});c.value=(this.plugin.settings.noteTemplates??{})[r]??"";let d=l.createDiv({cls:"stashpad-note-template-suggest"});d.style.display="none";let p=o.createDiv({cls:"stashpad-note-template-warn"});p.style.display="none";let h=()=>this.app.vault.getMarkdownFiles().map(y=>y.path).filter(y=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(y)).sort(),u=()=>{d.empty();let y=c.value.trim().toLowerCase(),S=h().filter(k=>!y||k.toLowerCase().includes(y)).slice(0,12);if(S.length===0){d.style.display="none";return}d.style.display="";for(let k of S)d.createDiv({cls:"stashpad-note-template-suggest-item",text:k}).addEventListener("mousedown",async I=>{I.preventDefault(),c.value=k,await m(),d.style.display="none"})},m=async()=>{let y=c.value.trim(),S={...this.plugin.settings.noteTemplates??{}};y?S[r]=y:delete S[r],this.plugin.settings.noteTemplates=S,await this.plugin.saveSettings(),g()},g=()=>{p.empty(),p.style.display="none";let y=c.value.trim();if(!y)return;let S=this.app.vault.getAbstractFileByPath(y);if(!S||S.extension!=="md"){p.style.display="",p.setText(`\u26A0 "${y}" is not a markdown file in this vault.`);return}let k=this.app.metadataCache.getFileCache(S)?.frontmatter??{},I=re.filter(E=>{let D=k[E];return!(D==null||typeof D=="string"&&D.trim()===""||Array.isArray(D)&&D.length===0)});I.length!==0&&(p.style.display="",p.setText(`\u26A0 Template defines ${I.join(", ")} \u2014 Stashpad always sets ${I.length===1?"this":"these"} on new notes, so the template value${I.length===1?"":"s"} will be ignored.`))};c.addEventListener("focus",u),c.addEventListener("input",u),c.addEventListener("blur",()=>{setTimeout(()=>{d.style.display="none"},150)}),c.addEventListener("change",()=>{m()}),g()};for(let n of e)i(n)}renderColorAliasRow(t,e,s,i,n){let r=t.createDiv({cls:"stashpad-color-alias-row"});i===0&&r.addClass("is-unused");let o=r.createSpan({cls:"stashpad-color-alias-swatch"});o.style.background=s,o.title="Click to bulk-recolor every note of this color in this Stashpad",o.onclick=()=>{let d=this.plugin.settings.customPalette??[];new Kt(this.app,s,d,async p=>{if((p??null)===null&&i===0){await this.plugin.setColorAlias(e,s,""),n();return}if(p&&p.toLowerCase()===s){n();return}let h=await this.plugin.recolorAllInFolder(e,s,p??null);if(h>0)new tt.Notice(`Recolored ${h} note${h===1?"":"s"}.`);else if(i===0){let u=this.plugin.getColorAlias(e,s);u&&(await this.plugin.setColorAlias(e,s,""),p&&await this.plugin.setColorAlias(e,p,u))}n()},async p=>{let h=(this.plugin.settings.customPalette??[]).filter(u=>u.toLowerCase()!==p.toLowerCase());return this.plugin.settings.customPalette=h,await this.plugin.saveSettings(),h}).open()};let a=r.createDiv({cls:"stashpad-color-alias-meta"});a.createSpan({cls:"stashpad-color-alias-hex",text:s}),a.createSpan({cls:"stashpad-color-alias-count",text:i===0?"\xB7 unused":`\xB7 ${i} note${i===1?"":"s"}`});let l=r.createEl("input",{type:"text",cls:"stashpad-color-alias-input",attr:{placeholder:"Alias (optional)"}});l.value=this.plugin.getColorAlias(e,s)??"",l.onchange=async()=>{await this.plugin.setColorAlias(e,s,l.value),!l.value.trim()&&i===0&&n()};let c=r.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});l.value||(c.style.visibility="hidden"),c.onclick=async()=>{await this.plugin.setColorAlias(e,s,""),i===0?n():(l.value="",c.style.visibility="hidden")}}renderFolderScopeRow(t,e){let s=t.createDiv({cls:"stashpad-folder-row"});s.createSpan({cls:"stashpad-folder-row-label",text:e});let i=s.createSpan({cls:"stashpad-folder-row-state"}),n=s.createDiv({cls:"stashpad-binding-pill"});n.setAttribute("role","switch"),n.setAttribute("tabindex","0");let r=n.createDiv({cls:"stashpad-binding-pill-knob"}),o=()=>(this.plugin.settings.searchExcludedFolders??[]).includes(e),a=()=>{let c=o();n.toggleClass("is-right",c),n.setAttribute("aria-checked",String(c)),r.setText(c?"X":"\u2713"),i.setText(c?"Excluded":"Included"),i.toggleClass("is-excluded",c),n.title=c?"Excluded \u2014 notes here won't appear in cross-Stashpad search. Click to include.":"Included \u2014 notes here appear in cross-Stashpad search. Click to exclude."},l=async()=>{let c=new Set(this.plugin.settings.searchExcludedFolders??[]);c.has(e)?c.delete(e):c.add(e),this.plugin.settings.searchExcludedFolders=[...c].sort(),a(),await this.plugin.saveSettings()};n.onclick=()=>void l(),n.onkeydown=c=>{(c.key===" "||c.key==="Enter")&&(c.preventDefault(),l())},a()}renderBindingRow(t,e){let s=new tt.Setting(t).setName(e.label).setDesc(e.desc),i=()=>this.plugin.settings.bindings[e.id],n,r,o=()=>{},a=u=>{let m=s.controlEl.createDiv({cls:"stashpad-binding-slot"}),g=m.createEl("input",{type:"text"});g.readOnly=!0,g.placeholder="Click & press a key",g.value=ms(i()[u]),g.classList.add("stashpad-binding-input");let y=()=>{g.size=Math.max(3,g.value.length||g.placeholder.length)};y(),g.onclick=()=>{zs(g,async k=>{this.plugin.settings.bindings[e.id][u]=k,g.value=ms(k),y(),await this.plugin.saveSettings(),o()})};let S=m.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});return S.title="Clear this slot",S.onclick=async()=>{this.plugin.settings.bindings[e.id][u]="",g.value="",y(),await this.plugin.saveSettings(),o()},g};n=a("primary"),r=a("secondary");let l=s.controlEl.createDiv({cls:"stashpad-binding-pill"});l.setAttribute("role","switch"),l.setAttribute("tabindex","0");let c=l.createDiv({cls:"stashpad-binding-pill-knob"}),d=s.controlEl.createDiv({cls:"stashpad-binding-useboth"}),p=d.createEl("input",{type:"checkbox"});p.title="Use both bindings simultaneously (overrides the L/R toggle)",d.createSpan({text:"Use both"}),p.onchange=async()=>{this.plugin.settings.bindings[e.id].useBoth=p.checked,await this.plugin.saveSettings(),o()},o=()=>{let u=i(),m=!!(u.primary&&u.secondary);p.checked=!!u.useBoth,p.disabled=!m,d.toggleClass("is-disabled",!m);let g=!!u.useBoth&&m;l.toggleClass("is-disabled",!m||g),l.toggleClass("is-right",u.preferRight),l.setAttribute("aria-checked",String(u.preferRight)),l.setAttribute("aria-disabled",String(!m||g)),c.setText(u.preferRight?"R":"L"),l.title=m?g?'Overridden by "Use both"':u.preferRight?"Right slot active \u2014 click for left":"Left slot active \u2014 click for right":"Set both slots to enable the toggle"};let h=async()=>{let u=i();!u.primary||!u.secondary||(this.plugin.settings.bindings[e.id].preferRight=!u.preferRight,o(),await this.plugin.saveSettings())};l.onclick=()=>void h(),l.onkeydown=u=>{(u.key===" "||u.key==="Enter")&&(u.preventDefault(),h())},o()}};var ut=require("obsidian");xt();function ws(v){let f=v.trim().toLowerCase();if(!f)return null;let t=Date.now(),e=u=>(0,ut.moment)(u).startOf("day").valueOf(),s=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/,i=0,n=!1,r=f,o=s.exec(f);if(o&&(o[3]||o[2])){let u=parseInt(o[1],10),m=o[2]?parseInt(o[2],10):0,g=o[3];g==="pm"&&u<12&&(u+=12),g==="am"&&u===12&&(u=0),u>=0&&u<24&&m>=0&&m<60&&(i=(u*3600+m*60)*1e3,n=!0,r=f.replace(o[0]," ").replace(/\s+/g," ").trim())}let a=u=>n?u+i:u;if(r===""||r==="today")return a(e(t));if(r==="yesterday")return a(e(t)-864e5);if(r==="tomorrow")return a(e(t)+864e5);let l=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],c=["sun","mon","tue","wed","thu","fri","sat"],d=l.indexOf(r)>=0?l.indexOf(r):c.indexOf(r);if(d>=0){let u=(0,ut.moment)().startOf("day"),g=(u.day()-d+7)%7;return a(u.subtract(g,"days").valueOf())}let p=/^(\d+)\s*([dwmy])$/.exec(r);if(p){let u=parseInt(p[1],10),m={d:"days",w:"weeks",m:"months",y:"years"}[p[2]];return a((0,ut.moment)().subtract(u,m).startOf("day").valueOf())}let h=(0,ut.moment)(r,["YYYY-MM-DD","YYYY/MM/DD","MM-DD-YYYY","MM/DD/YYYY","M-D-YYYY","M/D/YYYY"],!0);return h.isValid()?a(h.startOf("day").valueOf()):null}function Ys(v){let f={text:[],filters:{}},t=(v||"").trim();if(!t)return f;let e=/\b(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,s=t,i;for(;(i=e.exec(t))!=null;){let n=i[1].toLowerCase(),r=(i[2]!==void 0?i[2]:i[3]??"").trim();if(r){if(n==="in")f.filters.in=r.toLowerCase();else if(n==="before"){let o=ws(r);o!=null&&(f.filters.before=o)}else if(n==="after"){let o=ws(r);o!=null&&(f.filters.after=o)}else if(n==="on"){let o=ws(r);if(o!=null)if(/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(r))f.filters.on={start:o-6e4,end:o+6e4};else{let l=(0,ut.moment)(o).startOf("day").valueOf();f.filters.on={start:l,end:l+864e5}}}s=s.replace(i[0]," ")}}for(let n of s.split(/\s+/))n&&f.text.push(n.toLowerCase());return f}var Lt=class v extends ut.SuggestModal{constructor(t,e,s,i){super(t);this.tree=e;this.titleFn=s;this.opts=i;this.notes=[];this.pendingCleanups=[];this.crossFolderIndex=null;this.whenBuilderEl=null;this.whenMode="on";this.whenSingleText="";this.whenBetweenEndText="";this.setPlaceholder(i.placeholder??(i.mode==="search"?"Search notes\u2026":"Pick a note\u2026")),this.loadAll()}onClose(){for(;this.pendingCleanups.length>0;){let t=this.pendingCleanups.pop();try{t&&t()}catch{}}}loadAll(){let t=(s,i)=>{let n=this.tree.get(s);n?.file&&s!==B?this.notes.push({node:n,title:`${" ".repeat(i)}${this.titleFn(n)}`,body:""}):n?.file&&s===B&&this.notes.push({node:n,title:"Home",body:""});for(let r of this.tree.getChildren(s))t(r.id,i+1)},e=this.tree.getRoot();e.file&&this.notes.push({node:e,title:"Home",body:""});for(let s of this.tree.getChildren(B))t(s.id,1);for(let s of this.notes)s.node?.file&&this.app.vault.cachedRead(s.node.file).then(i=>{s.body=this.stripFm(i)});if(this.opts.crossFolderNotes){let s=this.opts.crossFolderNotes();for(let i of s)this.notes.push({node:null,title:i.title,body:i.body,cross:i});for(let i of this.notes)!i.cross||i.body||i.cross.file&&this.app.vault.cachedRead(i.cross.file).then(n=>{i.body=this.stripFm(n)})}}createdMsFor(t){if(t.node?.created){let e=Date.parse(t.node.created);if(!Number.isNaN(e))return e}return t.cross?.file?.stat?.ctime!=null?t.cross.file.stat.ctime:null}stripFm(t){if(!t.startsWith("---"))return t;let e=t.indexOf(` ----`,3);return e===-1?t:t.slice(e+4).replace(/^\r?\n/,"")}getSuggestions(t){let e=t.trim().toLowerCase(),s=Ys(t),i=s.text;console.log("[Stashpad] search query parsed",{query:t,text:s.text,filters:s.filters});let n=y=>{if(!i.length)return!0;for(let S of i)if(!y.includes(S))return!1;return!0},r=null,o=null;if(s.filters.in){let y=s.filters.in.split(/\s+/).filter(Boolean);r=new Set,o=new Map;let S=I=>y.every(E=>I.toLowerCase().includes(E)),k=I=>{if(!r.has(I)){r.add(I);for(let E of this.tree.getChildren(I))k(E.id)}};for(let I of this.notes)!I.node||I.cross||S(I.title)&&k(I.node.id);let x=new Map;for(let I of this.notes){if(!I.cross)continue;let E=x.get(I.cross.folder)??[];E.push(I),x.set(I.cross.folder,E)}for(let[I,E]of x){let D=new Map;for(let P of E){let b=P.cross?.parentId??null;if(!b)continue;let H=D.get(b)??[];H.push(P.cross.id),D.set(b,H)}let $=new Set;o.set(I,$);let F=P=>{if(!$.has(P)){$.add(P);for(let b of D.get(P)??[])F(b)}};for(let P of E)S(P.title)&&F(P.cross.id)}}let a=y=>{let S=s.filters;if(r||o)if(y.cross){let k=o?.get(y.cross.folder);if(!k||!k.has(y.cross.id))return!1}else if(y.node){if(!r||!r.has(y.node.id))return!1}else return!1;if(S.before||S.after||S.on){let k=this.createdMsFor(y);if(k==null||S.before!=null&&k>=S.before||S.after!=null&&k<=S.after||S.on&&(k<S.on.start||k>=S.on.end))return!1}return!0},l=y=>n(y.toLowerCase()),c=this.notes.filter(y=>!y.cross),d=this.notes.filter(y=>y.cross),p=(y,S)=>({id:y.cross?`cross:${y.cross.id}`:y.node.id,label:y.title,node:y.node,kind:"note",bodyPreview:this.previewFromBody(y.body,S),matchLine:S,crossFolder:y.cross?.folder,crossFile:y.cross?.file}),h=y=>{let S=[];for(let k of y)if(a(k))if(this.opts.mode==="search"){if(!e){S.push(p(k,-1));continue}let x=n(k.title.toLowerCase()),I=k.body.split(/\r?\n/),E=[];for(let $=0;$<I.length;$++)l(I[$])&&E.push($);let D=E.length>0||n(k.body.toLowerCase());if(!x&&!D)continue;if(E.length===0)S.push(p(k,-1));else{let $=[],F=-100;for(let b of E)b-F>5&&$.push(b),F=b;let P=5;for(let b of $.slice(0,P))S.push(p(k,b))}}else{if(e&&!n(k.title.toLowerCase())&&!n(k.body.toLowerCase()))continue;S.push(p(k,-1))}return S},u=h(c),m=[...u];if(this.opts.mode==="search"?e?!0:u.length<10:!!e){let y=h(d);this.opts.mode==="search"&&!e&&(m.length=Math.min(m.length,50)),m.push(...y)}if(this.opts.folderResults){let y=this.opts.folderResults(),S=!e||y.some(k=>{let x=k.split("/").pop()??k;return n(`${k.toLowerCase()} ${x.toLowerCase()}`)});if(y.length>0&&S){let k={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};Object.keys(s.filters).length>0?m.push(k):m.unshift(k)}}return this.opts.allowCreate&&e&&!m.some(y=>y.label.trim().toLowerCase()===e)&&m.push({id:"__create__",label:`Create new: "${t}"`,node:null,kind:"create"}),m}previewFromBody(t,e){let s=t.split(/\r?\n/);if(e<0)return s.filter(o=>o.trim().length>0).slice(0,3).join(` +`}function Ue(g,f){let t=document.createDocumentFragment(),e=t.createEl("div",{text:"Home note updated"});e.style.fontWeight="600",e.style.marginBottom="6px";let s=t.createEl("ul");s.style.margin="0 0 8px 0",s.style.paddingLeft="18px",s.createEl("li",{text:`${f.indexed.length} indexed`}),s.createEl("li",{text:`${f.nonIndex.length+f.skippedStashpadNotes.length} excluded`});let i=t.createEl("button",{text:"Open",cls:"mod-cta"});i.style.padding="2px 10px",i.style.fontSize="var(--font-ui-smaller)";let n;return i.onclick=async r=>{if(r.stopPropagation(),f.previewPath){let o=g.vault.getAbstractFileByPath(f.previewPath);o instanceof bt.TFile&&await g.workspace.getLeaf("tab").openFile(o)}n?.hide()},n=new bt.Notice(t,0),n}var bt,js,fe,me=Kt(()=>{"use strict";bt=require("obsidian");Ot();ue();Ct();js=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;fe=class extends bt.Modal{constructor(t,e,s,i,n){super(t);this.plugin=e;this.settings=s;this.indexedCount=i;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:t,titleEl:e}=this,s=!this.settings.jdIndexHasBuilt,i=this.indexedCount>this.LARGE_BUILD;e.setText(s?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,r=t.createEl("p"),o=`${this.indexedCount} note${this.indexedCount===1?"":"s"}`;s?(r.appendText(`Stashpad is about to create ${o} (plus synthetic parents as needed) inside "`),r.createEl("code",{text:n}),r.appendText('". Existing notes with the same '),r.createEl("code",{text:"jdPrefix"}),r.appendText(" are updated, never deleted \u2014 but if the prefix detection picks up notes you didn't mean to index, you'll end up with a lot of unwanted notes."),t.createEl("p").setText("Running Preview first writes a single Markdown file showing exactly what would be built (and what wouldn't), so you can sanity-check before committing.")):i?(r.appendText(`You're about to create ${this.indexedCount} notes in "`),r.createEl("code",{text:n}),r.appendText(`". That's a big batch \u2014 if anything looks off, Preview the single-file output first.`)):(r.appendText('Build the JD index into "'),r.createEl("code",{text:n}),r.appendText(`"? Stashpad will create / update ${o}. Existing notes with matching `),r.createEl("code",{text:"jdPrefix"}),r.appendText(" are updated in place.")),this.previewRan&&this.previewPath&&t.createEl("p",{cls:"setting-item-description"}).setText(`\u2713 Preview written to home note (${this.previewPath}). Open it before building if you haven't.`);let a=new bt.Setting(t);(s||i)&&a.addButton(l=>{l.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),l.setCta(),l.onClick(async()=>{try{let c=await je(this.app,this.plugin,this.settings);if(c.error==="no-dest"){new bt.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(c.error==="no-home"){new bt.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=c.previewPath,Ue(this.app,c),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(c){new bt.Notice(`Preview failed: ${c?.message??c}`,8e3)}})}),a.addButton(l=>{l.setButtonText(s?"Build anyway":"Build"),!s&&!i&&l.setCta(),l.onClick(async()=>{this.close(),await this.onBuild()})}),a.addButton(l=>{l.setButtonText("Cancel"),l.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var ti=gi((Qs,xs)=>{(function(g){typeof Qs=="object"&&typeof xs<"u"?xs.exports=g():typeof define=="function"&&define.amd?define([],g):(typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:this).JSZip=g()})(function(){return function g(f,t,e){function s(r,o){if(!t[r]){if(!f[r]){var a=typeof require=="function"&&require;if(!o&&a)return a(r,!0);if(i)return i(r,!0);var l=new Error("Cannot find module '"+r+"'");throw l.code="MODULE_NOT_FOUND",l}var c=t[r]={exports:{}};f[r][0].call(c.exports,function(h){var u=f[r][1][h];return s(u||h)},c,c.exports,g,f,t,e)}return t[r].exports}for(var i=typeof require=="function"&&require,n=0;n<e.length;n++)s(e[n]);return s}({1:[function(g,f,t){"use strict";var e=g("./utils"),s=g("./support"),i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.encode=function(n){for(var r,o,a,l,c,h,u,d=[],p=0,m=n.length,v=m,y=e.getTypeOf(n)!=="string";p<n.length;)v=m-p,a=y?(r=n[p++],o=p<m?n[p++]:0,p<m?n[p++]:0):(r=n.charCodeAt(p++),o=p<m?n.charCodeAt(p++):0,p<m?n.charCodeAt(p++):0),l=r>>2,c=(3&r)<<4|o>>4,h=1<v?(15&o)<<2|a>>6:64,u=2<v?63&a:64,d.push(i.charAt(l)+i.charAt(c)+i.charAt(h)+i.charAt(u));return d.join("")},t.decode=function(n){var r,o,a,l,c,h,u=0,d=0,p="data:";if(n.substr(0,p.length)===p)throw new Error("Invalid base64 input, it looks like a data url.");var m,v=3*(n=n.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(n.charAt(n.length-1)===i.charAt(64)&&v--,n.charAt(n.length-2)===i.charAt(64)&&v--,v%1!=0)throw new Error("Invalid base64 input, bad content length.");for(m=s.uint8array?new Uint8Array(0|v):new Array(0|v);u<n.length;)r=i.indexOf(n.charAt(u++))<<2|(l=i.indexOf(n.charAt(u++)))>>4,o=(15&l)<<4|(c=i.indexOf(n.charAt(u++)))>>2,a=(3&c)<<6|(h=i.indexOf(n.charAt(u++))),m[d++]=r,c!==64&&(m[d++]=o),h!==64&&(m[d++]=a);return m}},{"./support":30,"./utils":32}],2:[function(g,f,t){"use strict";var e=g("./external"),s=g("./stream/DataWorker"),i=g("./stream/Crc32Probe"),n=g("./stream/DataLengthProbe");function r(o,a,l,c,h){this.compressedSize=o,this.uncompressedSize=a,this.crc32=l,this.compression=c,this.compressedContent=h}r.prototype={getContentWorker:function(){var o=new s(e.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new n("data_length")),a=this;return o.on("end",function(){if(this.streamInfo.data_length!==a.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),o},getCompressedWorker:function(){return new s(e.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},r.createWorkerFrom=function(o,a,l){return o.pipe(new i).pipe(new n("uncompressedSize")).pipe(a.compressWorker(l)).pipe(new n("compressedSize")).withStreamInfo("compression",a)},f.exports=r},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(g,f,t){"use strict";var e=g("./stream/GenericWorker");t.STORE={magic:"\0\0",compressWorker:function(){return new e("STORE compression")},uncompressWorker:function(){return new e("STORE decompression")}},t.DEFLATE=g("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(g,f,t){"use strict";var e=g("./utils"),s=function(){for(var i,n=[],r=0;r<256;r++){i=r;for(var o=0;o<8;o++)i=1&i?3988292384^i>>>1:i>>>1;n[r]=i}return n}();f.exports=function(i,n){return i!==void 0&&i.length?e.getTypeOf(i)!=="string"?function(r,o,a,l){var c=s,h=l+a;r^=-1;for(var u=l;u<h;u++)r=r>>>8^c[255&(r^o[u])];return-1^r}(0|n,i,i.length,0):function(r,o,a,l){var c=s,h=l+a;r^=-1;for(var u=l;u<h;u++)r=r>>>8^c[255&(r^o.charCodeAt(u))];return-1^r}(0|n,i,i.length,0):0}},{"./utils":32}],5:[function(g,f,t){"use strict";t.base64=!1,t.binary=!1,t.dir=!1,t.createFolders=!0,t.date=null,t.compression=null,t.compressionOptions=null,t.comment=null,t.unixPermissions=null,t.dosPermissions=null},{}],6:[function(g,f,t){"use strict";var e=null;e=typeof Promise<"u"?Promise:g("lie"),f.exports={Promise:e}},{lie:37}],7:[function(g,f,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",s=g("pako"),i=g("./utils"),n=g("./stream/GenericWorker"),r=e?"uint8array":"array";function o(a,l){n.call(this,"FlateWorker/"+a),this._pako=null,this._pakoAction=a,this._pakoOptions=l,this.meta={}}t.magic="\b\0",i.inherits(o,n),o.prototype.processChunk=function(a){this.meta=a.meta,this._pako===null&&this._createPako(),this._pako.push(i.transformTo(r,a.data),!1)},o.prototype.flush=function(){n.prototype.flush.call(this),this._pako===null&&this._createPako(),this._pako.push([],!0)},o.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this._pako=null},o.prototype._createPako=function(){this._pako=new s[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var a=this;this._pako.onData=function(l){a.push({data:l,meta:a.meta})}},t.compressWorker=function(a){return new o("Deflate",a)},t.uncompressWorker=function(){return new o("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(g,f,t){"use strict";function e(c,h){var u,d="";for(u=0;u<h;u++)d+=String.fromCharCode(255&c),c>>>=8;return d}function s(c,h,u,d,p,m){var v,y,b=c.file,k=c.compression,C=m!==r.utf8encode,E=i.transformTo("string",m(b.name)),I=i.transformTo("string",r.utf8encode(b.name)),A=b.comment,O=i.transformTo("string",m(A)),F=i.transformTo("string",r.utf8encode(A)),D=I.length!==b.name.length,S=F.length!==A.length,B="",tt="",U="",z=b.dir,W=b.date,X={crc32:0,compressedSize:0,uncompressedSize:0};h&&!u||(X.crc32=c.crc32,X.compressedSize=c.compressedSize,X.uncompressedSize=c.uncompressedSize);var L=0;h&&(L|=8),C||!D&&!S||(L|=2048);var P=0,J=0;z&&(P|=16),p==="UNIX"?(J=798,P|=function(Y,ct){var ht=Y;return Y||(ht=ct?16893:33204),(65535&ht)<<16}(b.unixPermissions,z)):(J=20,P|=function(Y){return 63&(Y||0)}(b.dosPermissions)),v=W.getUTCHours(),v<<=6,v|=W.getUTCMinutes(),v<<=5,v|=W.getUTCSeconds()/2,y=W.getUTCFullYear()-1980,y<<=4,y|=W.getUTCMonth()+1,y<<=5,y|=W.getUTCDate(),D&&(tt=e(1,1)+e(o(E),4)+I,B+="up"+e(tt.length,2)+tt),S&&(U=e(1,1)+e(o(O),4)+F,B+="uc"+e(U.length,2)+U);var K="";return K+=` +\0`,K+=e(L,2),K+=k.magic,K+=e(v,2),K+=e(y,2),K+=e(X.crc32,4),K+=e(X.compressedSize,4),K+=e(X.uncompressedSize,4),K+=e(E.length,2),K+=e(B.length,2),{fileRecord:a.LOCAL_FILE_HEADER+K+E+B,dirRecord:a.CENTRAL_FILE_HEADER+e(J,2)+K+e(O.length,2)+"\0\0\0\0"+e(P,4)+e(d,4)+E+B+O}}var i=g("../utils"),n=g("../stream/GenericWorker"),r=g("../utf8"),o=g("../crc32"),a=g("../signature");function l(c,h,u,d){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=h,this.zipPlatform=u,this.encodeFileName=d,this.streamFiles=c,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}i.inherits(l,n),l.prototype.push=function(c){var h=c.meta.percent||0,u=this.entriesCount,d=this._sources.length;this.accumulate?this.contentBuffer.push(c):(this.bytesWritten+=c.data.length,n.prototype.push.call(this,{data:c.data,meta:{currentFile:this.currentFile,percent:u?(h+100*(u-d-1))/u:100}}))},l.prototype.openedSource=function(c){this.currentSourceOffset=this.bytesWritten,this.currentFile=c.file.name;var h=this.streamFiles&&!c.file.dir;if(h){var u=s(c,h,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:u.fileRecord,meta:{percent:0}})}else this.accumulate=!0},l.prototype.closedSource=function(c){this.accumulate=!1;var h=this.streamFiles&&!c.file.dir,u=s(c,h,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(u.dirRecord),h)this.push({data:function(d){return a.DATA_DESCRIPTOR+e(d.crc32,4)+e(d.compressedSize,4)+e(d.uncompressedSize,4)}(c),meta:{percent:100}});else for(this.push({data:u.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},l.prototype.flush=function(){for(var c=this.bytesWritten,h=0;h<this.dirRecords.length;h++)this.push({data:this.dirRecords[h],meta:{percent:100}});var u=this.bytesWritten-c,d=function(p,m,v,y,b){var k=i.transformTo("string",b(y));return a.CENTRAL_DIRECTORY_END+"\0\0\0\0"+e(p,2)+e(p,2)+e(m,4)+e(v,4)+e(k.length,2)+k}(this.dirRecords.length,u,c,this.zipComment,this.encodeFileName);this.push({data:d,meta:{percent:100}})},l.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},l.prototype.registerPrevious=function(c){this._sources.push(c);var h=this;return c.on("data",function(u){h.processChunk(u)}),c.on("end",function(){h.closedSource(h.previous.streamInfo),h._sources.length?h.prepareNextSource():h.end()}),c.on("error",function(u){h.error(u)}),this},l.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},l.prototype.error=function(c){var h=this._sources;if(!n.prototype.error.call(this,c))return!1;for(var u=0;u<h.length;u++)try{h[u].error(c)}catch{}return!0},l.prototype.lock=function(){n.prototype.lock.call(this);for(var c=this._sources,h=0;h<c.length;h++)c[h].lock()},f.exports=l},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(g,f,t){"use strict";var e=g("../compressions"),s=g("./ZipFileWorker");t.generateWorker=function(i,n,r){var o=new s(n.streamFiles,r,n.platform,n.encodeFileName),a=0;try{i.forEach(function(l,c){a++;var h=function(m,v){var y=m||v,b=e[y];if(!b)throw new Error(y+" is not a valid compression method !");return b}(c.options.compression,n.compression),u=c.options.compressionOptions||n.compressionOptions||{},d=c.dir,p=c.date;c._compressWorker(h,u).withStreamInfo("file",{name:l,dir:d,date:p,comment:c.comment||"",unixPermissions:c.unixPermissions,dosPermissions:c.dosPermissions}).pipe(o)}),o.entriesCount=a}catch(l){o.error(l)}return o}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(g,f,t){"use strict";function e(){if(!(this instanceof e))return new e;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var s=new e;for(var i in this)typeof this[i]!="function"&&(s[i]=this[i]);return s}}(e.prototype=g("./object")).loadAsync=g("./load"),e.support=g("./support"),e.defaults=g("./defaults"),e.version="3.10.1",e.loadAsync=function(s,i){return new e().loadAsync(s,i)},e.external=g("./external"),f.exports=e},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(g,f,t){"use strict";var e=g("./utils"),s=g("./external"),i=g("./utf8"),n=g("./zipEntries"),r=g("./stream/Crc32Probe"),o=g("./nodejsUtils");function a(l){return new s.Promise(function(c,h){var u=l.decompressed.getContentWorker().pipe(new r);u.on("error",function(d){h(d)}).on("end",function(){u.streamInfo.crc32!==l.decompressed.crc32?h(new Error("Corrupted zip : CRC32 mismatch")):c()}).resume()})}f.exports=function(l,c){var h=this;return c=e.extend(c||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:i.utf8decode}),o.isNode&&o.isStream(l)?s.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):e.prepareContent("the loaded zip file",l,!0,c.optimizedBinaryString,c.base64).then(function(u){var d=new n(c);return d.load(u),d}).then(function(u){var d=[s.Promise.resolve(u)],p=u.files;if(c.checkCRC32)for(var m=0;m<p.length;m++)d.push(a(p[m]));return s.Promise.all(d)}).then(function(u){for(var d=u.shift(),p=d.files,m=0;m<p.length;m++){var v=p[m],y=v.fileNameStr,b=e.resolve(v.fileNameStr);h.file(b,v.decompressed,{binary:!0,optimizedBinaryString:!0,date:v.date,dir:v.dir,comment:v.fileCommentStr.length?v.fileCommentStr:null,unixPermissions:v.unixPermissions,dosPermissions:v.dosPermissions,createFolders:c.createFolders}),v.dir||(h.file(b).unsafeOriginalName=y)}return d.zipComment.length&&(h.comment=d.zipComment),h})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(g,f,t){"use strict";var e=g("../utils"),s=g("../stream/GenericWorker");function i(n,r){s.call(this,"Nodejs stream input adapter for "+n),this._upstreamEnded=!1,this._bindStream(r)}e.inherits(i,s),i.prototype._bindStream=function(n){var r=this;(this._stream=n).pause(),n.on("data",function(o){r.push({data:o,meta:{percent:0}})}).on("error",function(o){r.isPaused?this.generatedError=o:r.error(o)}).on("end",function(){r.isPaused?r._upstreamEnded=!0:r.end()})},i.prototype.pause=function(){return!!s.prototype.pause.call(this)&&(this._stream.pause(),!0)},i.prototype.resume=function(){return!!s.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},f.exports=i},{"../stream/GenericWorker":28,"../utils":32}],13:[function(g,f,t){"use strict";var e=g("readable-stream").Readable;function s(i,n,r){e.call(this,n),this._helper=i;var o=this;i.on("data",function(a,l){o.push(a)||o._helper.pause(),r&&r(l)}).on("error",function(a){o.emit("error",a)}).on("end",function(){o.push(null)})}g("../utils").inherits(s,e),s.prototype._read=function(){this._helper.resume()},f.exports=s},{"../utils":32,"readable-stream":16}],14:[function(g,f,t){"use strict";f.exports={isNode:typeof Buffer<"u",newBufferFrom:function(e,s){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,s);if(typeof e=="number")throw new Error('The "data" argument must not be a number');return new Buffer(e,s)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var s=new Buffer(e);return s.fill(0),s},isBuffer:function(e){return Buffer.isBuffer(e)},isStream:function(e){return e&&typeof e.on=="function"&&typeof e.pause=="function"&&typeof e.resume=="function"}}},{}],15:[function(g,f,t){"use strict";function e(b,k,C){var E,I=i.getTypeOf(k),A=i.extend(C||{},o);A.date=A.date||new Date,A.compression!==null&&(A.compression=A.compression.toUpperCase()),typeof A.unixPermissions=="string"&&(A.unixPermissions=parseInt(A.unixPermissions,8)),A.unixPermissions&&16384&A.unixPermissions&&(A.dir=!0),A.dosPermissions&&16&A.dosPermissions&&(A.dir=!0),A.dir&&(b=p(b)),A.createFolders&&(E=d(b))&&m.call(this,E,!0);var O=I==="string"&&A.binary===!1&&A.base64===!1;C&&C.binary!==void 0||(A.binary=!O),(k instanceof a&&k.uncompressedSize===0||A.dir||!k||k.length===0)&&(A.base64=!1,A.binary=!0,k="",A.compression="STORE",I="string");var F=null;F=k instanceof a||k instanceof n?k:h.isNode&&h.isStream(k)?new u(b,k):i.prepareContent(b,k,A.binary,A.optimizedBinaryString,A.base64);var D=new l(b,F,A);this.files[b]=D}var s=g("./utf8"),i=g("./utils"),n=g("./stream/GenericWorker"),r=g("./stream/StreamHelper"),o=g("./defaults"),a=g("./compressedObject"),l=g("./zipObject"),c=g("./generate"),h=g("./nodejsUtils"),u=g("./nodejs/NodejsStreamInputAdapter"),d=function(b){b.slice(-1)==="/"&&(b=b.substring(0,b.length-1));var k=b.lastIndexOf("/");return 0<k?b.substring(0,k):""},p=function(b){return b.slice(-1)!=="/"&&(b+="/"),b},m=function(b,k){return k=k!==void 0?k:o.createFolders,b=p(b),this.files[b]||e.call(this,b,null,{dir:!0,createFolders:k}),this.files[b]};function v(b){return Object.prototype.toString.call(b)==="[object RegExp]"}var y={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(b){var k,C,E;for(k in this.files)E=this.files[k],(C=k.slice(this.root.length,k.length))&&k.slice(0,this.root.length)===this.root&&b(C,E)},filter:function(b){var k=[];return this.forEach(function(C,E){b(C,E)&&k.push(E)}),k},file:function(b,k,C){if(arguments.length!==1)return b=this.root+b,e.call(this,b,k,C),this;if(v(b)){var E=b;return this.filter(function(A,O){return!O.dir&&E.test(A)})}var I=this.files[this.root+b];return I&&!I.dir?I:null},folder:function(b){if(!b)return this;if(v(b))return this.filter(function(I,A){return A.dir&&b.test(I)});var k=this.root+b,C=m.call(this,k),E=this.clone();return E.root=C.name,E},remove:function(b){b=this.root+b;var k=this.files[b];if(k||(b.slice(-1)!=="/"&&(b+="/"),k=this.files[b]),k&&!k.dir)delete this.files[b];else for(var C=this.filter(function(I,A){return A.name.slice(0,b.length)===b}),E=0;E<C.length;E++)delete this.files[C[E].name];return this},generate:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(b){var k,C={};try{if((C=i.extend(b||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:s.utf8encode})).type=C.type.toLowerCase(),C.compression=C.compression.toUpperCase(),C.type==="binarystring"&&(C.type="string"),!C.type)throw new Error("No output type specified.");i.checkSupport(C.type),C.platform!=="darwin"&&C.platform!=="freebsd"&&C.platform!=="linux"&&C.platform!=="sunos"||(C.platform="UNIX"),C.platform==="win32"&&(C.platform="DOS");var E=C.comment||this.comment||"";k=c.generateWorker(this,C,E)}catch(I){(k=new n("error")).error(I)}return new r(k,C.type||"string",C.mimeType)},generateAsync:function(b,k){return this.generateInternalStream(b).accumulate(k)},generateNodeStream:function(b,k){return(b=b||{}).type||(b.type="nodebuffer"),this.generateInternalStream(b).toNodejsStream(k)}};f.exports=y},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(g,f,t){"use strict";f.exports=g("stream")},{stream:void 0}],17:[function(g,f,t){"use strict";var e=g("./DataReader");function s(i){e.call(this,i);for(var n=0;n<this.data.length;n++)i[n]=255&i[n]}g("../utils").inherits(s,e),s.prototype.byteAt=function(i){return this.data[this.zero+i]},s.prototype.lastIndexOfSignature=function(i){for(var n=i.charCodeAt(0),r=i.charCodeAt(1),o=i.charCodeAt(2),a=i.charCodeAt(3),l=this.length-4;0<=l;--l)if(this.data[l]===n&&this.data[l+1]===r&&this.data[l+2]===o&&this.data[l+3]===a)return l-this.zero;return-1},s.prototype.readAndCheckSignature=function(i){var n=i.charCodeAt(0),r=i.charCodeAt(1),o=i.charCodeAt(2),a=i.charCodeAt(3),l=this.readData(4);return n===l[0]&&r===l[1]&&o===l[2]&&a===l[3]},s.prototype.readData=function(i){if(this.checkOffset(i),i===0)return[];var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./DataReader":18}],18:[function(g,f,t){"use strict";var e=g("../utils");function s(i){this.data=i,this.length=i.length,this.index=0,this.zero=0}s.prototype={checkOffset:function(i){this.checkIndex(this.index+i)},checkIndex:function(i){if(this.length<this.zero+i||i<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+i+"). Corrupted zip ?")},setIndex:function(i){this.checkIndex(i),this.index=i},skip:function(i){this.setIndex(this.index+i)},byteAt:function(){},readInt:function(i){var n,r=0;for(this.checkOffset(i),n=this.index+i-1;n>=this.index;n--)r=(r<<8)+this.byteAt(n);return this.index+=i,r},readString:function(i){return e.transformTo("string",this.readData(i))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var i=this.readInt(4);return new Date(Date.UTC(1980+(i>>25&127),(i>>21&15)-1,i>>16&31,i>>11&31,i>>5&63,(31&i)<<1))}},f.exports=s},{"../utils":32}],19:[function(g,f,t){"use strict";var e=g("./Uint8ArrayReader");function s(i){e.call(this,i)}g("../utils").inherits(s,e),s.prototype.readData=function(i){this.checkOffset(i);var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(g,f,t){"use strict";var e=g("./DataReader");function s(i){e.call(this,i)}g("../utils").inherits(s,e),s.prototype.byteAt=function(i){return this.data.charCodeAt(this.zero+i)},s.prototype.lastIndexOfSignature=function(i){return this.data.lastIndexOf(i)-this.zero},s.prototype.readAndCheckSignature=function(i){return i===this.readData(4)},s.prototype.readData=function(i){this.checkOffset(i);var n=this.data.slice(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./DataReader":18}],21:[function(g,f,t){"use strict";var e=g("./ArrayReader");function s(i){e.call(this,i)}g("../utils").inherits(s,e),s.prototype.readData=function(i){if(this.checkOffset(i),i===0)return new Uint8Array(0);var n=this.data.subarray(this.zero+this.index,this.zero+this.index+i);return this.index+=i,n},f.exports=s},{"../utils":32,"./ArrayReader":17}],22:[function(g,f,t){"use strict";var e=g("../utils"),s=g("../support"),i=g("./ArrayReader"),n=g("./StringReader"),r=g("./NodeBufferReader"),o=g("./Uint8ArrayReader");f.exports=function(a){var l=e.getTypeOf(a);return e.checkSupport(l),l!=="string"||s.uint8array?l==="nodebuffer"?new r(a):s.uint8array?new o(e.transformTo("uint8array",a)):new i(e.transformTo("array",a)):new n(a)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(g,f,t){"use strict";t.LOCAL_FILE_HEADER="PK",t.CENTRAL_FILE_HEADER="PK",t.CENTRAL_DIRECTORY_END="PK",t.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK\x07",t.ZIP64_CENTRAL_DIRECTORY_END="PK",t.DATA_DESCRIPTOR="PK\x07\b"},{}],24:[function(g,f,t){"use strict";var e=g("./GenericWorker"),s=g("../utils");function i(n){e.call(this,"ConvertWorker to "+n),this.destType=n}s.inherits(i,e),i.prototype.processChunk=function(n){this.push({data:s.transformTo(this.destType,n.data),meta:n.meta})},f.exports=i},{"../utils":32,"./GenericWorker":28}],25:[function(g,f,t){"use strict";var e=g("./GenericWorker"),s=g("../crc32");function i(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}g("../utils").inherits(i,e),i.prototype.processChunk=function(n){this.streamInfo.crc32=s(n.data,this.streamInfo.crc32||0),this.push(n)},f.exports=i},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(g,f,t){"use strict";var e=g("../utils"),s=g("./GenericWorker");function i(n){s.call(this,"DataLengthProbe for "+n),this.propName=n,this.withStreamInfo(n,0)}e.inherits(i,s),i.prototype.processChunk=function(n){if(n){var r=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=r+n.data.length}s.prototype.processChunk.call(this,n)},f.exports=i},{"../utils":32,"./GenericWorker":28}],27:[function(g,f,t){"use strict";var e=g("../utils"),s=g("./GenericWorker");function i(n){s.call(this,"DataWorker");var r=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,n.then(function(o){r.dataIsReady=!0,r.data=o,r.max=o&&o.length||0,r.type=e.getTypeOf(o),r.isPaused||r._tickAndRepeat()},function(o){r.error(o)})}e.inherits(i,s),i.prototype.cleanUp=function(){s.prototype.cleanUp.call(this),this.data=null},i.prototype.resume=function(){return!!s.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,e.delay(this._tickAndRepeat,[],this)),!0)},i.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(e.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},i.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var n=null,r=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":n=this.data.substring(this.index,r);break;case"uint8array":n=this.data.subarray(this.index,r);break;case"array":case"nodebuffer":n=this.data.slice(this.index,r)}return this.index=r,this.push({data:n,meta:{percent:this.max?this.index/this.max*100:0}})},f.exports=i},{"../utils":32,"./GenericWorker":28}],28:[function(g,f,t){"use strict";function e(s){this.name=s||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}e.prototype={push:function(s){this.emit("data",s)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(s){this.emit("error",s)}return!0},error:function(s){return!this.isFinished&&(this.isPaused?this.generatedError=s:(this.isFinished=!0,this.emit("error",s),this.previous&&this.previous.error(s),this.cleanUp()),!0)},on:function(s,i){return this._listeners[s].push(i),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(s,i){if(this._listeners[s])for(var n=0;n<this._listeners[s].length;n++)this._listeners[s][n].call(this,i)},pipe:function(s){return s.registerPrevious(this)},registerPrevious:function(s){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=s.streamInfo,this.mergeStreamInfo(),this.previous=s;var i=this;return s.on("data",function(n){i.processChunk(n)}),s.on("end",function(){i.end()}),s.on("error",function(n){i.error(n)}),this},pause:function(){return!this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return!1;var s=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),s=!0),this.previous&&this.previous.resume(),!s},flush:function(){},processChunk:function(s){this.push(s)},withStreamInfo:function(s,i){return this.extraStreamInfo[s]=i,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var s in this.extraStreamInfo)Object.prototype.hasOwnProperty.call(this.extraStreamInfo,s)&&(this.streamInfo[s]=this.extraStreamInfo[s])},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock()},toString:function(){var s="Worker "+this.name;return this.previous?this.previous+" -> "+s:s}},f.exports=e},{}],29:[function(g,f,t){"use strict";var e=g("../utils"),s=g("./ConvertWorker"),i=g("./GenericWorker"),n=g("../base64"),r=g("../support"),o=g("../external"),a=null;if(r.nodestream)try{a=g("../nodejs/NodejsStreamOutputAdapter")}catch{}function l(h,u){return new o.Promise(function(d,p){var m=[],v=h._internalType,y=h._outputType,b=h._mimeType;h.on("data",function(k,C){m.push(k),u&&u(C)}).on("error",function(k){m=[],p(k)}).on("end",function(){try{var k=function(C,E,I){switch(C){case"blob":return e.newBlob(e.transformTo("arraybuffer",E),I);case"base64":return n.encode(E);default:return e.transformTo(C,E)}}(y,function(C,E){var I,A=0,O=null,F=0;for(I=0;I<E.length;I++)F+=E[I].length;switch(C){case"string":return E.join("");case"array":return Array.prototype.concat.apply([],E);case"uint8array":for(O=new Uint8Array(F),I=0;I<E.length;I++)O.set(E[I],A),A+=E[I].length;return O;case"nodebuffer":return Buffer.concat(E);default:throw new Error("concat : unsupported type '"+C+"'")}}(v,m),b);d(k)}catch(C){p(C)}m=[]}).resume()})}function c(h,u,d){var p=u;switch(u){case"blob":case"arraybuffer":p="uint8array";break;case"base64":p="string"}try{this._internalType=p,this._outputType=u,this._mimeType=d,e.checkSupport(p),this._worker=h.pipe(new s(p)),h.lock()}catch(m){this._worker=new i("error"),this._worker.error(m)}}c.prototype={accumulate:function(h){return l(this,h)},on:function(h,u){var d=this;return h==="data"?this._worker.on(h,function(p){u.call(d,p.data,p.meta)}):this._worker.on(h,function(){e.delay(u,arguments,d)}),this},resume:function(){return e.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(h){if(e.checkSupport("nodestream"),this._outputType!=="nodebuffer")throw new Error(this._outputType+" is not supported by this method");return new a(this,{objectMode:this._outputType!=="nodebuffer"},h)}},f.exports=c},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(g,f,t){"use strict";if(t.base64=!0,t.array=!0,t.string=!0,t.arraybuffer=typeof ArrayBuffer<"u"&&typeof Uint8Array<"u",t.nodebuffer=typeof Buffer<"u",t.uint8array=typeof Uint8Array<"u",typeof ArrayBuffer>"u")t.blob=!1;else{var e=new ArrayBuffer(0);try{t.blob=new Blob([e],{type:"application/zip"}).size===0}catch{try{var s=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);s.append(e),t.blob=s.getBlob("application/zip").size===0}catch{t.blob=!1}}}try{t.nodestream=!!g("readable-stream").Readable}catch{t.nodestream=!1}},{"readable-stream":16}],31:[function(g,f,t){"use strict";for(var e=g("./utils"),s=g("./support"),i=g("./nodejsUtils"),n=g("./stream/GenericWorker"),r=new Array(256),o=0;o<256;o++)r[o]=252<=o?6:248<=o?5:240<=o?4:224<=o?3:192<=o?2:1;r[254]=r[254]=1;function a(){n.call(this,"utf-8 decode"),this.leftOver=null}function l(){n.call(this,"utf-8 encode")}t.utf8encode=function(c){return s.nodebuffer?i.newBufferFrom(c,"utf-8"):function(h){var u,d,p,m,v,y=h.length,b=0;for(m=0;m<y;m++)(64512&(d=h.charCodeAt(m)))==55296&&m+1<y&&(64512&(p=h.charCodeAt(m+1)))==56320&&(d=65536+(d-55296<<10)+(p-56320),m++),b+=d<128?1:d<2048?2:d<65536?3:4;for(u=s.uint8array?new Uint8Array(b):new Array(b),m=v=0;v<b;m++)(64512&(d=h.charCodeAt(m)))==55296&&m+1<y&&(64512&(p=h.charCodeAt(m+1)))==56320&&(d=65536+(d-55296<<10)+(p-56320),m++),d<128?u[v++]=d:(d<2048?u[v++]=192|d>>>6:(d<65536?u[v++]=224|d>>>12:(u[v++]=240|d>>>18,u[v++]=128|d>>>12&63),u[v++]=128|d>>>6&63),u[v++]=128|63&d);return u}(c)},t.utf8decode=function(c){return s.nodebuffer?e.transformTo("nodebuffer",c).toString("utf-8"):function(h){var u,d,p,m,v=h.length,y=new Array(2*v);for(u=d=0;u<v;)if((p=h[u++])<128)y[d++]=p;else if(4<(m=r[p]))y[d++]=65533,u+=m-1;else{for(p&=m===2?31:m===3?15:7;1<m&&u<v;)p=p<<6|63&h[u++],m--;1<m?y[d++]=65533:p<65536?y[d++]=p:(p-=65536,y[d++]=55296|p>>10&1023,y[d++]=56320|1023&p)}return y.length!==d&&(y.subarray?y=y.subarray(0,d):y.length=d),e.applyFromCharCode(y)}(c=e.transformTo(s.uint8array?"uint8array":"array",c))},e.inherits(a,n),a.prototype.processChunk=function(c){var h=e.transformTo(s.uint8array?"uint8array":"array",c.data);if(this.leftOver&&this.leftOver.length){if(s.uint8array){var u=h;(h=new Uint8Array(u.length+this.leftOver.length)).set(this.leftOver,0),h.set(u,this.leftOver.length)}else h=this.leftOver.concat(h);this.leftOver=null}var d=function(m,v){var y;for((v=v||m.length)>m.length&&(v=m.length),y=v-1;0<=y&&(192&m[y])==128;)y--;return y<0||y===0?v:y+r[m[y]]>v?y:v}(h),p=h;d!==h.length&&(s.uint8array?(p=h.subarray(0,d),this.leftOver=h.subarray(d,h.length)):(p=h.slice(0,d),this.leftOver=h.slice(d,h.length))),this.push({data:t.utf8decode(p),meta:c.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:t.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},t.Utf8DecodeWorker=a,e.inherits(l,n),l.prototype.processChunk=function(c){this.push({data:t.utf8encode(c.data),meta:c.meta})},t.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(g,f,t){"use strict";var e=g("./support"),s=g("./base64"),i=g("./nodejsUtils"),n=g("./external");function r(u){return u}function o(u,d){for(var p=0;p<u.length;++p)d[p]=255&u.charCodeAt(p);return d}g("setimmediate"),t.newBlob=function(u,d){t.checkSupport("blob");try{return new Blob([u],{type:d})}catch{try{var p=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return p.append(u),p.getBlob(d)}catch{throw new Error("Bug : can't construct the Blob.")}}};var a={stringifyByChunk:function(u,d,p){var m=[],v=0,y=u.length;if(y<=p)return String.fromCharCode.apply(null,u);for(;v<y;)d==="array"||d==="nodebuffer"?m.push(String.fromCharCode.apply(null,u.slice(v,Math.min(v+p,y)))):m.push(String.fromCharCode.apply(null,u.subarray(v,Math.min(v+p,y)))),v+=p;return m.join("")},stringifyByChar:function(u){for(var d="",p=0;p<u.length;p++)d+=String.fromCharCode(u[p]);return d},applyCanBeUsed:{uint8array:function(){try{return e.uint8array&&String.fromCharCode.apply(null,new Uint8Array(1)).length===1}catch{return!1}}(),nodebuffer:function(){try{return e.nodebuffer&&String.fromCharCode.apply(null,i.allocBuffer(1)).length===1}catch{return!1}}()}};function l(u){var d=65536,p=t.getTypeOf(u),m=!0;if(p==="uint8array"?m=a.applyCanBeUsed.uint8array:p==="nodebuffer"&&(m=a.applyCanBeUsed.nodebuffer),m)for(;1<d;)try{return a.stringifyByChunk(u,p,d)}catch{d=Math.floor(d/2)}return a.stringifyByChar(u)}function c(u,d){for(var p=0;p<u.length;p++)d[p]=u[p];return d}t.applyFromCharCode=l;var h={};h.string={string:r,array:function(u){return o(u,new Array(u.length))},arraybuffer:function(u){return h.string.uint8array(u).buffer},uint8array:function(u){return o(u,new Uint8Array(u.length))},nodebuffer:function(u){return o(u,i.allocBuffer(u.length))}},h.array={string:l,array:r,arraybuffer:function(u){return new Uint8Array(u).buffer},uint8array:function(u){return new Uint8Array(u)},nodebuffer:function(u){return i.newBufferFrom(u)}},h.arraybuffer={string:function(u){return l(new Uint8Array(u))},array:function(u){return c(new Uint8Array(u),new Array(u.byteLength))},arraybuffer:r,uint8array:function(u){return new Uint8Array(u)},nodebuffer:function(u){return i.newBufferFrom(new Uint8Array(u))}},h.uint8array={string:l,array:function(u){return c(u,new Array(u.length))},arraybuffer:function(u){return u.buffer},uint8array:r,nodebuffer:function(u){return i.newBufferFrom(u)}},h.nodebuffer={string:l,array:function(u){return c(u,new Array(u.length))},arraybuffer:function(u){return h.nodebuffer.uint8array(u).buffer},uint8array:function(u){return c(u,new Uint8Array(u.length))},nodebuffer:r},t.transformTo=function(u,d){if(d=d||"",!u)return d;t.checkSupport(u);var p=t.getTypeOf(d);return h[p][u](d)},t.resolve=function(u){for(var d=u.split("/"),p=[],m=0;m<d.length;m++){var v=d[m];v==="."||v===""&&m!==0&&m!==d.length-1||(v===".."?p.pop():p.push(v))}return p.join("/")},t.getTypeOf=function(u){return typeof u=="string"?"string":Object.prototype.toString.call(u)==="[object Array]"?"array":e.nodebuffer&&i.isBuffer(u)?"nodebuffer":e.uint8array&&u instanceof Uint8Array?"uint8array":e.arraybuffer&&u instanceof ArrayBuffer?"arraybuffer":void 0},t.checkSupport=function(u){if(!e[u.toLowerCase()])throw new Error(u+" is not supported by this platform")},t.MAX_VALUE_16BITS=65535,t.MAX_VALUE_32BITS=-1,t.pretty=function(u){var d,p,m="";for(p=0;p<(u||"").length;p++)m+="\\x"+((d=u.charCodeAt(p))<16?"0":"")+d.toString(16).toUpperCase();return m},t.delay=function(u,d,p){setImmediate(function(){u.apply(p||null,d||[])})},t.inherits=function(u,d){function p(){}p.prototype=d.prototype,u.prototype=new p},t.extend=function(){var u,d,p={};for(u=0;u<arguments.length;u++)for(d in arguments[u])Object.prototype.hasOwnProperty.call(arguments[u],d)&&p[d]===void 0&&(p[d]=arguments[u][d]);return p},t.prepareContent=function(u,d,p,m,v){return n.Promise.resolve(d).then(function(y){return e.blob&&(y instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(y))!==-1)&&typeof FileReader<"u"?new n.Promise(function(b,k){var C=new FileReader;C.onload=function(E){b(E.target.result)},C.onerror=function(E){k(E.target.error)},C.readAsArrayBuffer(y)}):y}).then(function(y){var b=t.getTypeOf(y);return b?(b==="arraybuffer"?y=t.transformTo("uint8array",y):b==="string"&&(v?y=s.decode(y):p&&m!==!0&&(y=function(k){return o(k,e.uint8array?new Uint8Array(k.length):new Array(k.length))}(y))),y):n.Promise.reject(new Error("Can't read the data of '"+u+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,setimmediate:54}],33:[function(g,f,t){"use strict";var e=g("./reader/readerFor"),s=g("./utils"),i=g("./signature"),n=g("./zipEntry"),r=g("./support");function o(a){this.files=[],this.loadOptions=a}o.prototype={checkSignature:function(a){if(!this.reader.readAndCheckSignature(a)){this.reader.index-=4;var l=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+s.pretty(l)+", expected "+s.pretty(a)+")")}},isSignature:function(a,l){var c=this.reader.index;this.reader.setIndex(a);var h=this.reader.readString(4)===l;return this.reader.setIndex(c),h},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var a=this.reader.readData(this.zipCommentLength),l=r.uint8array?"uint8array":"array",c=s.transformTo(l,a);this.zipComment=this.loadOptions.decodeFileName(c)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,l,c,h=this.zip64EndOfCentralSize-44;0<h;)a=this.reader.readInt(2),l=this.reader.readInt(4),c=this.reader.readData(l),this.zip64ExtensibleData[a]={id:a,length:l,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,l;for(a=0;a<this.files.length;a++)l=this.files[a],this.reader.setIndex(l.localHeaderOffset),this.checkSignature(i.LOCAL_FILE_HEADER),l.readLocalPart(this.reader),l.handleUTF8(),l.processAttributes()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(i.CENTRAL_FILE_HEADER);)(a=new n({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(a);if(this.centralDirRecords!==this.files.length&&this.centralDirRecords!==0&&this.files.length===0)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(i.CENTRAL_DIRECTORY_END);if(a<0)throw this.isSignature(0,i.LOCAL_FILE_HEADER)?new Error("Corrupted zip: can't find end of central directory"):new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");this.reader.setIndex(a);var l=a;if(this.checkSignature(i.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===s.MAX_VALUE_16BITS||this.diskWithCentralDirStart===s.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===s.MAX_VALUE_16BITS||this.centralDirRecords===s.MAX_VALUE_16BITS||this.centralDirSize===s.MAX_VALUE_32BITS||this.centralDirOffset===s.MAX_VALUE_32BITS){if(this.zip64=!0,(a=this.reader.lastIndexOfSignature(i.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(a),this.checkSignature(i.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,i.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(i.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(i.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var c=this.centralDirOffset+this.centralDirSize;this.zip64&&(c+=20,c+=12+this.zip64EndOfCentralSize);var h=l-c;if(0<h)this.isSignature(l,i.CENTRAL_FILE_HEADER)||(this.reader.zero=h);else if(h<0)throw new Error("Corrupted zip: missing "+Math.abs(h)+" bytes.")},prepareReader:function(a){this.reader=e(a)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},f.exports=o},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(g,f,t){"use strict";var e=g("./reader/readerFor"),s=g("./utils"),i=g("./compressedObject"),n=g("./crc32"),r=g("./utf8"),o=g("./compressions"),a=g("./support");function l(c,h){this.options=c,this.loadOptions=h}l.prototype={isEncrypted:function(){return(1&this.bitFlag)==1},useUTF8:function(){return(2048&this.bitFlag)==2048},readLocalPart:function(c){var h,u;if(c.skip(22),this.fileNameLength=c.readInt(2),u=c.readInt(2),this.fileName=c.readData(this.fileNameLength),c.skip(u),this.compressedSize===-1||this.uncompressedSize===-1)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if((h=function(d){for(var p in o)if(Object.prototype.hasOwnProperty.call(o,p)&&o[p].magic===d)return o[p];return null}(this.compressionMethod))===null)throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new i(this.compressedSize,this.uncompressedSize,this.crc32,h,c.readData(this.compressedSize))},readCentralPart:function(c){this.versionMadeBy=c.readInt(2),c.skip(2),this.bitFlag=c.readInt(2),this.compressionMethod=c.readString(2),this.date=c.readDate(),this.crc32=c.readInt(4),this.compressedSize=c.readInt(4),this.uncompressedSize=c.readInt(4);var h=c.readInt(2);if(this.extraFieldsLength=c.readInt(2),this.fileCommentLength=c.readInt(2),this.diskNumberStart=c.readInt(2),this.internalFileAttributes=c.readInt(2),this.externalFileAttributes=c.readInt(4),this.localHeaderOffset=c.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");c.skip(h),this.readExtraFields(c),this.parseZIP64ExtraField(c),this.fileComment=c.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var c=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),c==0&&(this.dosPermissions=63&this.externalFileAttributes),c==3&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||this.fileNameStr.slice(-1)!=="/"||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var c=e(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=c.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=c.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=c.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=c.readInt(4))}},readExtraFields:function(c){var h,u,d,p=c.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});c.index+4<p;)h=c.readInt(2),u=c.readInt(2),d=c.readData(u),this.extraFields[h]={id:h,length:u,value:d};c.setIndex(p)},handleUTF8:function(){var c=a.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=r.utf8decode(this.fileName),this.fileCommentStr=r.utf8decode(this.fileComment);else{var h=this.findExtraFieldUnicodePath();if(h!==null)this.fileNameStr=h;else{var u=s.transformTo(c,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(u)}var d=this.findExtraFieldUnicodeComment();if(d!==null)this.fileCommentStr=d;else{var p=s.transformTo(c,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(p)}}},findExtraFieldUnicodePath:function(){var c=this.extraFields[28789];if(c){var h=e(c.value);return h.readInt(1)!==1||n(this.fileName)!==h.readInt(4)?null:r.utf8decode(h.readData(c.length-5))}return null},findExtraFieldUnicodeComment:function(){var c=this.extraFields[25461];if(c){var h=e(c.value);return h.readInt(1)!==1||n(this.fileComment)!==h.readInt(4)?null:r.utf8decode(h.readData(c.length-5))}return null}},f.exports=l},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(g,f,t){"use strict";function e(h,u,d){this.name=h,this.dir=d.dir,this.date=d.date,this.comment=d.comment,this.unixPermissions=d.unixPermissions,this.dosPermissions=d.dosPermissions,this._data=u,this._dataBinary=d.binary,this.options={compression:d.compression,compressionOptions:d.compressionOptions}}var s=g("./stream/StreamHelper"),i=g("./stream/DataWorker"),n=g("./utf8"),r=g("./compressedObject"),o=g("./stream/GenericWorker");e.prototype={internalStream:function(h){var u=null,d="string";try{if(!h)throw new Error("No output type specified.");var p=(d=h.toLowerCase())==="string"||d==="text";d!=="binarystring"&&d!=="text"||(d="string"),u=this._decompressWorker();var m=!this._dataBinary;m&&!p&&(u=u.pipe(new n.Utf8EncodeWorker)),!m&&p&&(u=u.pipe(new n.Utf8DecodeWorker))}catch(v){(u=new o("error")).error(v)}return new s(u,d,"")},async:function(h,u){return this.internalStream(h).accumulate(u)},nodeStream:function(h,u){return this.internalStream(h||"nodebuffer").toNodejsStream(u)},_compressWorker:function(h,u){if(this._data instanceof r&&this._data.compression.magic===h.magic)return this._data.getCompressedWorker();var d=this._decompressWorker();return this._dataBinary||(d=d.pipe(new n.Utf8EncodeWorker)),r.createWorkerFrom(d,h,u)},_decompressWorker:function(){return this._data instanceof r?this._data.getContentWorker():this._data instanceof o?this._data:new i(this._data)}};for(var a=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],l=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},c=0;c<a.length;c++)e.prototype[a[c]]=l;f.exports=e},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(g,f,t){(function(e){"use strict";var s,i,n=e.MutationObserver||e.WebKitMutationObserver;if(n){var r=0,o=new n(h),a=e.document.createTextNode("");o.observe(a,{characterData:!0}),s=function(){a.data=r=++r%2}}else if(e.setImmediate||e.MessageChannel===void 0)s="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var u=e.document.createElement("script");u.onreadystatechange=function(){h(),u.onreadystatechange=null,u.parentNode.removeChild(u),u=null},e.document.documentElement.appendChild(u)}:function(){setTimeout(h,0)};else{var l=new e.MessageChannel;l.port1.onmessage=h,s=function(){l.port2.postMessage(0)}}var c=[];function h(){var u,d;i=!0;for(var p=c.length;p;){for(d=c,c=[],u=-1;++u<p;)d[u]();p=c.length}i=!1}f.exports=function(u){c.push(u)!==1||i||s()}}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}],37:[function(g,f,t){"use strict";var e=g("immediate");function s(){}var i={},n=["REJECTED"],r=["FULFILLED"],o=["PENDING"];function a(p){if(typeof p!="function")throw new TypeError("resolver must be a function");this.state=o,this.queue=[],this.outcome=void 0,p!==s&&u(this,p)}function l(p,m,v){this.promise=p,typeof m=="function"&&(this.onFulfilled=m,this.callFulfilled=this.otherCallFulfilled),typeof v=="function"&&(this.onRejected=v,this.callRejected=this.otherCallRejected)}function c(p,m,v){e(function(){var y;try{y=m(v)}catch(b){return i.reject(p,b)}y===p?i.reject(p,new TypeError("Cannot resolve promise with itself")):i.resolve(p,y)})}function h(p){var m=p&&p.then;if(p&&(typeof p=="object"||typeof p=="function")&&typeof m=="function")return function(){m.apply(p,arguments)}}function u(p,m){var v=!1;function y(C){v||(v=!0,i.reject(p,C))}function b(C){v||(v=!0,i.resolve(p,C))}var k=d(function(){m(b,y)});k.status==="error"&&y(k.value)}function d(p,m){var v={};try{v.value=p(m),v.status="success"}catch(y){v.status="error",v.value=y}return v}(f.exports=a).prototype.finally=function(p){if(typeof p!="function")return this;var m=this.constructor;return this.then(function(v){return m.resolve(p()).then(function(){return v})},function(v){return m.resolve(p()).then(function(){throw v})})},a.prototype.catch=function(p){return this.then(null,p)},a.prototype.then=function(p,m){if(typeof p!="function"&&this.state===r||typeof m!="function"&&this.state===n)return this;var v=new this.constructor(s);return this.state!==o?c(v,this.state===r?p:m,this.outcome):this.queue.push(new l(v,p,m)),v},l.prototype.callFulfilled=function(p){i.resolve(this.promise,p)},l.prototype.otherCallFulfilled=function(p){c(this.promise,this.onFulfilled,p)},l.prototype.callRejected=function(p){i.reject(this.promise,p)},l.prototype.otherCallRejected=function(p){c(this.promise,this.onRejected,p)},i.resolve=function(p,m){var v=d(h,m);if(v.status==="error")return i.reject(p,v.value);var y=v.value;if(y)u(p,y);else{p.state=r,p.outcome=m;for(var b=-1,k=p.queue.length;++b<k;)p.queue[b].callFulfilled(m)}return p},i.reject=function(p,m){p.state=n,p.outcome=m;for(var v=-1,y=p.queue.length;++v<y;)p.queue[v].callRejected(m);return p},a.resolve=function(p){return p instanceof this?p:i.resolve(new this(s),p)},a.reject=function(p){var m=new this(s);return i.reject(m,p)},a.all=function(p){var m=this;if(Object.prototype.toString.call(p)!=="[object Array]")return this.reject(new TypeError("must be an array"));var v=p.length,y=!1;if(!v)return this.resolve([]);for(var b=new Array(v),k=0,C=-1,E=new this(s);++C<v;)I(p[C],C);return E;function I(A,O){m.resolve(A).then(function(F){b[O]=F,++k!==v||y||(y=!0,i.resolve(E,b))},function(F){y||(y=!0,i.reject(E,F))})}},a.race=function(p){var m=this;if(Object.prototype.toString.call(p)!=="[object Array]")return this.reject(new TypeError("must be an array"));var v=p.length,y=!1;if(!v)return this.resolve([]);for(var b=-1,k=new this(s);++b<v;)C=p[b],m.resolve(C).then(function(E){y||(y=!0,i.resolve(k,E))},function(E){y||(y=!0,i.reject(k,E))});var C;return k}},{immediate:36}],38:[function(g,f,t){"use strict";var e={};(0,g("./lib/utils/common").assign)(e,g("./lib/deflate"),g("./lib/inflate"),g("./lib/zlib/constants")),f.exports=e},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(g,f,t){"use strict";var e=g("./zlib/deflate"),s=g("./utils/common"),i=g("./utils/strings"),n=g("./zlib/messages"),r=g("./zlib/zstream"),o=Object.prototype.toString,a=0,l=-1,c=0,h=8;function u(p){if(!(this instanceof u))return new u(p);this.options=s.assign({level:l,method:h,chunkSize:16384,windowBits:15,memLevel:8,strategy:c,to:""},p||{});var m=this.options;m.raw&&0<m.windowBits?m.windowBits=-m.windowBits:m.gzip&&0<m.windowBits&&m.windowBits<16&&(m.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new r,this.strm.avail_out=0;var v=e.deflateInit2(this.strm,m.level,m.method,m.windowBits,m.memLevel,m.strategy);if(v!==a)throw new Error(n[v]);if(m.header&&e.deflateSetHeader(this.strm,m.header),m.dictionary){var y;if(y=typeof m.dictionary=="string"?i.string2buf(m.dictionary):o.call(m.dictionary)==="[object ArrayBuffer]"?new Uint8Array(m.dictionary):m.dictionary,(v=e.deflateSetDictionary(this.strm,y))!==a)throw new Error(n[v]);this._dict_set=!0}}function d(p,m){var v=new u(m);if(v.push(p,!0),v.err)throw v.msg||n[v.err];return v.result}u.prototype.push=function(p,m){var v,y,b=this.strm,k=this.options.chunkSize;if(this.ended)return!1;y=m===~~m?m:m===!0?4:0,typeof p=="string"?b.input=i.string2buf(p):o.call(p)==="[object ArrayBuffer]"?b.input=new Uint8Array(p):b.input=p,b.next_in=0,b.avail_in=b.input.length;do{if(b.avail_out===0&&(b.output=new s.Buf8(k),b.next_out=0,b.avail_out=k),(v=e.deflate(b,y))!==1&&v!==a)return this.onEnd(v),!(this.ended=!0);b.avail_out!==0&&(b.avail_in!==0||y!==4&&y!==2)||(this.options.to==="string"?this.onData(i.buf2binstring(s.shrinkBuf(b.output,b.next_out))):this.onData(s.shrinkBuf(b.output,b.next_out)))}while((0<b.avail_in||b.avail_out===0)&&v!==1);return y===4?(v=e.deflateEnd(this.strm),this.onEnd(v),this.ended=!0,v===a):y!==2||(this.onEnd(a),!(b.avail_out=0))},u.prototype.onData=function(p){this.chunks.push(p)},u.prototype.onEnd=function(p){p===a&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=p,this.msg=this.strm.msg},t.Deflate=u,t.deflate=d,t.deflateRaw=function(p,m){return(m=m||{}).raw=!0,d(p,m)},t.gzip=function(p,m){return(m=m||{}).gzip=!0,d(p,m)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(g,f,t){"use strict";var e=g("./zlib/inflate"),s=g("./utils/common"),i=g("./utils/strings"),n=g("./zlib/constants"),r=g("./zlib/messages"),o=g("./zlib/zstream"),a=g("./zlib/gzheader"),l=Object.prototype.toString;function c(u){if(!(this instanceof c))return new c(u);this.options=s.assign({chunkSize:16384,windowBits:0,to:""},u||{});var d=this.options;d.raw&&0<=d.windowBits&&d.windowBits<16&&(d.windowBits=-d.windowBits,d.windowBits===0&&(d.windowBits=-15)),!(0<=d.windowBits&&d.windowBits<16)||u&&u.windowBits||(d.windowBits+=32),15<d.windowBits&&d.windowBits<48&&!(15&d.windowBits)&&(d.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new o,this.strm.avail_out=0;var p=e.inflateInit2(this.strm,d.windowBits);if(p!==n.Z_OK)throw new Error(r[p]);this.header=new a,e.inflateGetHeader(this.strm,this.header)}function h(u,d){var p=new c(d);if(p.push(u,!0),p.err)throw p.msg||r[p.err];return p.result}c.prototype.push=function(u,d){var p,m,v,y,b,k,C=this.strm,E=this.options.chunkSize,I=this.options.dictionary,A=!1;if(this.ended)return!1;m=d===~~d?d:d===!0?n.Z_FINISH:n.Z_NO_FLUSH,typeof u=="string"?C.input=i.binstring2buf(u):l.call(u)==="[object ArrayBuffer]"?C.input=new Uint8Array(u):C.input=u,C.next_in=0,C.avail_in=C.input.length;do{if(C.avail_out===0&&(C.output=new s.Buf8(E),C.next_out=0,C.avail_out=E),(p=e.inflate(C,n.Z_NO_FLUSH))===n.Z_NEED_DICT&&I&&(k=typeof I=="string"?i.string2buf(I):l.call(I)==="[object ArrayBuffer]"?new Uint8Array(I):I,p=e.inflateSetDictionary(this.strm,k)),p===n.Z_BUF_ERROR&&A===!0&&(p=n.Z_OK,A=!1),p!==n.Z_STREAM_END&&p!==n.Z_OK)return this.onEnd(p),!(this.ended=!0);C.next_out&&(C.avail_out!==0&&p!==n.Z_STREAM_END&&(C.avail_in!==0||m!==n.Z_FINISH&&m!==n.Z_SYNC_FLUSH)||(this.options.to==="string"?(v=i.utf8border(C.output,C.next_out),y=C.next_out-v,b=i.buf2string(C.output,v),C.next_out=y,C.avail_out=E-y,y&&s.arraySet(C.output,C.output,v,y,0),this.onData(b)):this.onData(s.shrinkBuf(C.output,C.next_out)))),C.avail_in===0&&C.avail_out===0&&(A=!0)}while((0<C.avail_in||C.avail_out===0)&&p!==n.Z_STREAM_END);return p===n.Z_STREAM_END&&(m=n.Z_FINISH),m===n.Z_FINISH?(p=e.inflateEnd(this.strm),this.onEnd(p),this.ended=!0,p===n.Z_OK):m!==n.Z_SYNC_FLUSH||(this.onEnd(n.Z_OK),!(C.avail_out=0))},c.prototype.onData=function(u){this.chunks.push(u)},c.prototype.onEnd=function(u){u===n.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=u,this.msg=this.strm.msg},t.Inflate=c,t.inflate=h,t.inflateRaw=function(u,d){return(d=d||{}).raw=!0,h(u,d)},t.ungzip=h},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(g,f,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";t.assign=function(n){for(var r=Array.prototype.slice.call(arguments,1);r.length;){var o=r.shift();if(o){if(typeof o!="object")throw new TypeError(o+"must be non-object");for(var a in o)o.hasOwnProperty(a)&&(n[a]=o[a])}}return n},t.shrinkBuf=function(n,r){return n.length===r?n:n.subarray?n.subarray(0,r):(n.length=r,n)};var s={arraySet:function(n,r,o,a,l){if(r.subarray&&n.subarray)n.set(r.subarray(o,o+a),l);else for(var c=0;c<a;c++)n[l+c]=r[o+c]},flattenChunks:function(n){var r,o,a,l,c,h;for(r=a=0,o=n.length;r<o;r++)a+=n[r].length;for(h=new Uint8Array(a),r=l=0,o=n.length;r<o;r++)c=n[r],h.set(c,l),l+=c.length;return h}},i={arraySet:function(n,r,o,a,l){for(var c=0;c<a;c++)n[l+c]=r[o+c]},flattenChunks:function(n){return[].concat.apply([],n)}};t.setTyped=function(n){n?(t.Buf8=Uint8Array,t.Buf16=Uint16Array,t.Buf32=Int32Array,t.assign(t,s)):(t.Buf8=Array,t.Buf16=Array,t.Buf32=Array,t.assign(t,i))},t.setTyped(e)},{}],42:[function(g,f,t){"use strict";var e=g("./common"),s=!0,i=!0;try{String.fromCharCode.apply(null,[0])}catch{s=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch{i=!1}for(var n=new e.Buf8(256),r=0;r<256;r++)n[r]=252<=r?6:248<=r?5:240<=r?4:224<=r?3:192<=r?2:1;function o(a,l){if(l<65537&&(a.subarray&&i||!a.subarray&&s))return String.fromCharCode.apply(null,e.shrinkBuf(a,l));for(var c="",h=0;h<l;h++)c+=String.fromCharCode(a[h]);return c}n[254]=n[254]=1,t.string2buf=function(a){var l,c,h,u,d,p=a.length,m=0;for(u=0;u<p;u++)(64512&(c=a.charCodeAt(u)))==55296&&u+1<p&&(64512&(h=a.charCodeAt(u+1)))==56320&&(c=65536+(c-55296<<10)+(h-56320),u++),m+=c<128?1:c<2048?2:c<65536?3:4;for(l=new e.Buf8(m),u=d=0;d<m;u++)(64512&(c=a.charCodeAt(u)))==55296&&u+1<p&&(64512&(h=a.charCodeAt(u+1)))==56320&&(c=65536+(c-55296<<10)+(h-56320),u++),c<128?l[d++]=c:(c<2048?l[d++]=192|c>>>6:(c<65536?l[d++]=224|c>>>12:(l[d++]=240|c>>>18,l[d++]=128|c>>>12&63),l[d++]=128|c>>>6&63),l[d++]=128|63&c);return l},t.buf2binstring=function(a){return o(a,a.length)},t.binstring2buf=function(a){for(var l=new e.Buf8(a.length),c=0,h=l.length;c<h;c++)l[c]=a.charCodeAt(c);return l},t.buf2string=function(a,l){var c,h,u,d,p=l||a.length,m=new Array(2*p);for(c=h=0;c<p;)if((u=a[c++])<128)m[h++]=u;else if(4<(d=n[u]))m[h++]=65533,c+=d-1;else{for(u&=d===2?31:d===3?15:7;1<d&&c<p;)u=u<<6|63&a[c++],d--;1<d?m[h++]=65533:u<65536?m[h++]=u:(u-=65536,m[h++]=55296|u>>10&1023,m[h++]=56320|1023&u)}return o(m,h)},t.utf8border=function(a,l){var c;for((l=l||a.length)>a.length&&(l=a.length),c=l-1;0<=c&&(192&a[c])==128;)c--;return c<0||c===0?l:c+n[a[c]]>l?c:l}},{"./common":41}],43:[function(g,f,t){"use strict";f.exports=function(e,s,i,n){for(var r=65535&e|0,o=e>>>16&65535|0,a=0;i!==0;){for(i-=a=2e3<i?2e3:i;o=o+(r=r+s[n++]|0)|0,--a;);r%=65521,o%=65521}return r|o<<16|0}},{}],44:[function(g,f,t){"use strict";f.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],45:[function(g,f,t){"use strict";var e=function(){for(var s,i=[],n=0;n<256;n++){s=n;for(var r=0;r<8;r++)s=1&s?3988292384^s>>>1:s>>>1;i[n]=s}return i}();f.exports=function(s,i,n,r){var o=e,a=r+n;s^=-1;for(var l=r;l<a;l++)s=s>>>8^o[255&(s^i[l])];return-1^s}},{}],46:[function(g,f,t){"use strict";var e,s=g("../utils/common"),i=g("./trees"),n=g("./adler32"),r=g("./crc32"),o=g("./messages"),a=0,l=4,c=0,h=-2,u=-1,d=4,p=2,m=8,v=9,y=286,b=30,k=19,C=2*y+1,E=15,I=3,A=258,O=A+I+1,F=42,D=113,S=1,B=2,tt=3,U=4;function z(w,H){return w.msg=o[H],H}function W(w){return(w<<1)-(4<w?9:0)}function X(w){for(var H=w.length;0<=--H;)w[H]=0}function L(w){var H=w.state,$=H.pending;$>w.avail_out&&($=w.avail_out),$!==0&&(s.arraySet(w.output,H.pending_buf,H.pending_out,$,w.next_out),w.next_out+=$,H.pending_out+=$,w.total_out+=$,w.avail_out-=$,H.pending-=$,H.pending===0&&(H.pending_out=0))}function P(w,H){i._tr_flush_block(w,0<=w.block_start?w.block_start:-1,w.strstart-w.block_start,H),w.block_start=w.strstart,L(w.strm)}function J(w,H){w.pending_buf[w.pending++]=H}function K(w,H){w.pending_buf[w.pending++]=H>>>8&255,w.pending_buf[w.pending++]=255&H}function Y(w,H){var $,x,T=w.max_chain_length,M=w.strstart,j=w.prev_length,V=w.nice_match,_=w.strstart>w.w_size-O?w.strstart-(w.w_size-O):0,q=w.window,Q=w.w_mask,Z=w.prev,et=w.strstart+A,ut=q[M+j-1],lt=q[M+j];w.prev_length>=w.good_match&&(T>>=2),V>w.lookahead&&(V=w.lookahead);do if(q[($=H)+j]===lt&&q[$+j-1]===ut&&q[$]===q[M]&&q[++$]===q[M+1]){M+=2,$++;do;while(q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&q[++M]===q[++$]&&M<et);if(x=A-(et-M),M=et-A,j<x){if(w.match_start=H,V<=(j=x))break;ut=q[M+j-1],lt=q[M+j]}}while((H=Z[H&Q])>_&&--T!=0);return j<=w.lookahead?j:w.lookahead}function ct(w){var H,$,x,T,M,j,V,_,q,Q,Z=w.w_size;do{if(T=w.window_size-w.lookahead-w.strstart,w.strstart>=Z+(Z-O)){for(s.arraySet(w.window,w.window,Z,Z,0),w.match_start-=Z,w.strstart-=Z,w.block_start-=Z,H=$=w.hash_size;x=w.head[--H],w.head[H]=Z<=x?x-Z:0,--$;);for(H=$=Z;x=w.prev[--H],w.prev[H]=Z<=x?x-Z:0,--$;);T+=Z}if(w.strm.avail_in===0)break;if(j=w.strm,V=w.window,_=w.strstart+w.lookahead,q=T,Q=void 0,Q=j.avail_in,q<Q&&(Q=q),$=Q===0?0:(j.avail_in-=Q,s.arraySet(V,j.input,j.next_in,Q,_),j.state.wrap===1?j.adler=n(j.adler,V,Q,_):j.state.wrap===2&&(j.adler=r(j.adler,V,Q,_)),j.next_in+=Q,j.total_in+=Q,Q),w.lookahead+=$,w.lookahead+w.insert>=I)for(M=w.strstart-w.insert,w.ins_h=w.window[M],w.ins_h=(w.ins_h<<w.hash_shift^w.window[M+1])&w.hash_mask;w.insert&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[M+I-1])&w.hash_mask,w.prev[M&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=M,M++,w.insert--,!(w.lookahead+w.insert<I)););}while(w.lookahead<O&&w.strm.avail_in!==0)}function ht(w,H){for(var $,x;;){if(w.lookahead<O){if(ct(w),w.lookahead<O&&H===a)return S;if(w.lookahead===0)break}if($=0,w.lookahead>=I&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+I-1])&w.hash_mask,$=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),$!==0&&w.strstart-$<=w.w_size-O&&(w.match_length=Y(w,$)),w.match_length>=I)if(x=i._tr_tally(w,w.strstart-w.match_start,w.match_length-I),w.lookahead-=w.match_length,w.match_length<=w.max_lazy_match&&w.lookahead>=I){for(w.match_length--;w.strstart++,w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+I-1])&w.hash_mask,$=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart,--w.match_length!=0;);w.strstart++}else w.strstart+=w.match_length,w.match_length=0,w.ins_h=w.window[w.strstart],w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+1])&w.hash_mask;else x=i._tr_tally(w,0,w.window[w.strstart]),w.lookahead--,w.strstart++;if(x&&(P(w,!1),w.strm.avail_out===0))return S}return w.insert=w.strstart<I-1?w.strstart:I-1,H===l?(P(w,!0),w.strm.avail_out===0?tt:U):w.last_lit&&(P(w,!1),w.strm.avail_out===0)?S:B}function nt(w,H){for(var $,x,T;;){if(w.lookahead<O){if(ct(w),w.lookahead<O&&H===a)return S;if(w.lookahead===0)break}if($=0,w.lookahead>=I&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+I-1])&w.hash_mask,$=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),w.prev_length=w.match_length,w.prev_match=w.match_start,w.match_length=I-1,$!==0&&w.prev_length<w.max_lazy_match&&w.strstart-$<=w.w_size-O&&(w.match_length=Y(w,$),w.match_length<=5&&(w.strategy===1||w.match_length===I&&4096<w.strstart-w.match_start)&&(w.match_length=I-1)),w.prev_length>=I&&w.match_length<=w.prev_length){for(T=w.strstart+w.lookahead-I,x=i._tr_tally(w,w.strstart-1-w.prev_match,w.prev_length-I),w.lookahead-=w.prev_length-1,w.prev_length-=2;++w.strstart<=T&&(w.ins_h=(w.ins_h<<w.hash_shift^w.window[w.strstart+I-1])&w.hash_mask,$=w.prev[w.strstart&w.w_mask]=w.head[w.ins_h],w.head[w.ins_h]=w.strstart),--w.prev_length!=0;);if(w.match_available=0,w.match_length=I-1,w.strstart++,x&&(P(w,!1),w.strm.avail_out===0))return S}else if(w.match_available){if((x=i._tr_tally(w,0,w.window[w.strstart-1]))&&P(w,!1),w.strstart++,w.lookahead--,w.strm.avail_out===0)return S}else w.match_available=1,w.strstart++,w.lookahead--}return w.match_available&&(x=i._tr_tally(w,0,w.window[w.strstart-1]),w.match_available=0),w.insert=w.strstart<I-1?w.strstart:I-1,H===l?(P(w,!0),w.strm.avail_out===0?tt:U):w.last_lit&&(P(w,!1),w.strm.avail_out===0)?S:B}function rt(w,H,$,x,T){this.good_length=w,this.max_lazy=H,this.nice_length=$,this.max_chain=x,this.func=T}function at(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=m,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new s.Buf16(2*C),this.dyn_dtree=new s.Buf16(2*(2*b+1)),this.bl_tree=new s.Buf16(2*(2*k+1)),X(this.dyn_ltree),X(this.dyn_dtree),X(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new s.Buf16(E+1),this.heap=new s.Buf16(2*y+1),X(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new s.Buf16(2*y+1),X(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function st(w){var H;return w&&w.state?(w.total_in=w.total_out=0,w.data_type=p,(H=w.state).pending=0,H.pending_out=0,H.wrap<0&&(H.wrap=-H.wrap),H.status=H.wrap?F:D,w.adler=H.wrap===2?0:1,H.last_flush=a,i._tr_init(H),c):z(w,h)}function gt(w){var H=st(w);return H===c&&function($){$.window_size=2*$.w_size,X($.head),$.max_lazy_match=e[$.level].max_lazy,$.good_match=e[$.level].good_length,$.nice_match=e[$.level].nice_length,$.max_chain_length=e[$.level].max_chain,$.strstart=0,$.block_start=0,$.lookahead=0,$.insert=0,$.match_length=$.prev_length=I-1,$.match_available=0,$.ins_h=0}(w.state),H}function ft(w,H,$,x,T,M){if(!w)return h;var j=1;if(H===u&&(H=6),x<0?(j=0,x=-x):15<x&&(j=2,x-=16),T<1||v<T||$!==m||x<8||15<x||H<0||9<H||M<0||d<M)return z(w,h);x===8&&(x=9);var V=new at;return(w.state=V).strm=w,V.wrap=j,V.gzhead=null,V.w_bits=x,V.w_size=1<<V.w_bits,V.w_mask=V.w_size-1,V.hash_bits=T+7,V.hash_size=1<<V.hash_bits,V.hash_mask=V.hash_size-1,V.hash_shift=~~((V.hash_bits+I-1)/I),V.window=new s.Buf8(2*V.w_size),V.head=new s.Buf16(V.hash_size),V.prev=new s.Buf16(V.w_size),V.lit_bufsize=1<<T+6,V.pending_buf_size=4*V.lit_bufsize,V.pending_buf=new s.Buf8(V.pending_buf_size),V.d_buf=1*V.lit_bufsize,V.l_buf=3*V.lit_bufsize,V.level=H,V.strategy=M,V.method=$,gt(w)}e=[new rt(0,0,0,0,function(w,H){var $=65535;for($>w.pending_buf_size-5&&($=w.pending_buf_size-5);;){if(w.lookahead<=1){if(ct(w),w.lookahead===0&&H===a)return S;if(w.lookahead===0)break}w.strstart+=w.lookahead,w.lookahead=0;var x=w.block_start+$;if((w.strstart===0||w.strstart>=x)&&(w.lookahead=w.strstart-x,w.strstart=x,P(w,!1),w.strm.avail_out===0)||w.strstart-w.block_start>=w.w_size-O&&(P(w,!1),w.strm.avail_out===0))return S}return w.insert=0,H===l?(P(w,!0),w.strm.avail_out===0?tt:U):(w.strstart>w.block_start&&(P(w,!1),w.strm.avail_out),S)}),new rt(4,4,8,4,ht),new rt(4,5,16,8,ht),new rt(4,6,32,32,ht),new rt(4,4,16,16,nt),new rt(8,16,32,32,nt),new rt(8,16,128,128,nt),new rt(8,32,128,256,nt),new rt(32,128,258,1024,nt),new rt(32,258,258,4096,nt)],t.deflateInit=function(w,H){return ft(w,H,m,15,8,0)},t.deflateInit2=ft,t.deflateReset=gt,t.deflateResetKeep=st,t.deflateSetHeader=function(w,H){return w&&w.state?w.state.wrap!==2?h:(w.state.gzhead=H,c):h},t.deflate=function(w,H){var $,x,T,M;if(!w||!w.state||5<H||H<0)return w?z(w,h):h;if(x=w.state,!w.output||!w.input&&w.avail_in!==0||x.status===666&&H!==l)return z(w,w.avail_out===0?-5:h);if(x.strm=w,$=x.last_flush,x.last_flush=H,x.status===F)if(x.wrap===2)w.adler=0,J(x,31),J(x,139),J(x,8),x.gzhead?(J(x,(x.gzhead.text?1:0)+(x.gzhead.hcrc?2:0)+(x.gzhead.extra?4:0)+(x.gzhead.name?8:0)+(x.gzhead.comment?16:0)),J(x,255&x.gzhead.time),J(x,x.gzhead.time>>8&255),J(x,x.gzhead.time>>16&255),J(x,x.gzhead.time>>24&255),J(x,x.level===9?2:2<=x.strategy||x.level<2?4:0),J(x,255&x.gzhead.os),x.gzhead.extra&&x.gzhead.extra.length&&(J(x,255&x.gzhead.extra.length),J(x,x.gzhead.extra.length>>8&255)),x.gzhead.hcrc&&(w.adler=r(w.adler,x.pending_buf,x.pending,0)),x.gzindex=0,x.status=69):(J(x,0),J(x,0),J(x,0),J(x,0),J(x,0),J(x,x.level===9?2:2<=x.strategy||x.level<2?4:0),J(x,3),x.status=D);else{var j=m+(x.w_bits-8<<4)<<8;j|=(2<=x.strategy||x.level<2?0:x.level<6?1:x.level===6?2:3)<<6,x.strstart!==0&&(j|=32),j+=31-j%31,x.status=D,K(x,j),x.strstart!==0&&(K(x,w.adler>>>16),K(x,65535&w.adler)),w.adler=1}if(x.status===69)if(x.gzhead.extra){for(T=x.pending;x.gzindex<(65535&x.gzhead.extra.length)&&(x.pending!==x.pending_buf_size||(x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),L(w),T=x.pending,x.pending!==x.pending_buf_size));)J(x,255&x.gzhead.extra[x.gzindex]),x.gzindex++;x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),x.gzindex===x.gzhead.extra.length&&(x.gzindex=0,x.status=73)}else x.status=73;if(x.status===73)if(x.gzhead.name){T=x.pending;do{if(x.pending===x.pending_buf_size&&(x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),L(w),T=x.pending,x.pending===x.pending_buf_size)){M=1;break}M=x.gzindex<x.gzhead.name.length?255&x.gzhead.name.charCodeAt(x.gzindex++):0,J(x,M)}while(M!==0);x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),M===0&&(x.gzindex=0,x.status=91)}else x.status=91;if(x.status===91)if(x.gzhead.comment){T=x.pending;do{if(x.pending===x.pending_buf_size&&(x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),L(w),T=x.pending,x.pending===x.pending_buf_size)){M=1;break}M=x.gzindex<x.gzhead.comment.length?255&x.gzhead.comment.charCodeAt(x.gzindex++):0,J(x,M)}while(M!==0);x.gzhead.hcrc&&x.pending>T&&(w.adler=r(w.adler,x.pending_buf,x.pending-T,T)),M===0&&(x.status=103)}else x.status=103;if(x.status===103&&(x.gzhead.hcrc?(x.pending+2>x.pending_buf_size&&L(w),x.pending+2<=x.pending_buf_size&&(J(x,255&w.adler),J(x,w.adler>>8&255),w.adler=0,x.status=D)):x.status=D),x.pending!==0){if(L(w),w.avail_out===0)return x.last_flush=-1,c}else if(w.avail_in===0&&W(H)<=W($)&&H!==l)return z(w,-5);if(x.status===666&&w.avail_in!==0)return z(w,-5);if(w.avail_in!==0||x.lookahead!==0||H!==a&&x.status!==666){var V=x.strategy===2?function(_,q){for(var Q;;){if(_.lookahead===0&&(ct(_),_.lookahead===0)){if(q===a)return S;break}if(_.match_length=0,Q=i._tr_tally(_,0,_.window[_.strstart]),_.lookahead--,_.strstart++,Q&&(P(_,!1),_.strm.avail_out===0))return S}return _.insert=0,q===l?(P(_,!0),_.strm.avail_out===0?tt:U):_.last_lit&&(P(_,!1),_.strm.avail_out===0)?S:B}(x,H):x.strategy===3?function(_,q){for(var Q,Z,et,ut,lt=_.window;;){if(_.lookahead<=A){if(ct(_),_.lookahead<=A&&q===a)return S;if(_.lookahead===0)break}if(_.match_length=0,_.lookahead>=I&&0<_.strstart&&(Z=lt[et=_.strstart-1])===lt[++et]&&Z===lt[++et]&&Z===lt[++et]){ut=_.strstart+A;do;while(Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&Z===lt[++et]&&et<ut);_.match_length=A-(ut-et),_.match_length>_.lookahead&&(_.match_length=_.lookahead)}if(_.match_length>=I?(Q=i._tr_tally(_,1,_.match_length-I),_.lookahead-=_.match_length,_.strstart+=_.match_length,_.match_length=0):(Q=i._tr_tally(_,0,_.window[_.strstart]),_.lookahead--,_.strstart++),Q&&(P(_,!1),_.strm.avail_out===0))return S}return _.insert=0,q===l?(P(_,!0),_.strm.avail_out===0?tt:U):_.last_lit&&(P(_,!1),_.strm.avail_out===0)?S:B}(x,H):e[x.level].func(x,H);if(V!==tt&&V!==U||(x.status=666),V===S||V===tt)return w.avail_out===0&&(x.last_flush=-1),c;if(V===B&&(H===1?i._tr_align(x):H!==5&&(i._tr_stored_block(x,0,0,!1),H===3&&(X(x.head),x.lookahead===0&&(x.strstart=0,x.block_start=0,x.insert=0))),L(w),w.avail_out===0))return x.last_flush=-1,c}return H!==l?c:x.wrap<=0?1:(x.wrap===2?(J(x,255&w.adler),J(x,w.adler>>8&255),J(x,w.adler>>16&255),J(x,w.adler>>24&255),J(x,255&w.total_in),J(x,w.total_in>>8&255),J(x,w.total_in>>16&255),J(x,w.total_in>>24&255)):(K(x,w.adler>>>16),K(x,65535&w.adler)),L(w),0<x.wrap&&(x.wrap=-x.wrap),x.pending!==0?c:1)},t.deflateEnd=function(w){var H;return w&&w.state?(H=w.state.status)!==F&&H!==69&&H!==73&&H!==91&&H!==103&&H!==D&&H!==666?z(w,h):(w.state=null,H===D?z(w,-3):c):h},t.deflateSetDictionary=function(w,H){var $,x,T,M,j,V,_,q,Q=H.length;if(!w||!w.state||(M=($=w.state).wrap)===2||M===1&&$.status!==F||$.lookahead)return h;for(M===1&&(w.adler=n(w.adler,H,Q,0)),$.wrap=0,Q>=$.w_size&&(M===0&&(X($.head),$.strstart=0,$.block_start=0,$.insert=0),q=new s.Buf8($.w_size),s.arraySet(q,H,Q-$.w_size,$.w_size,0),H=q,Q=$.w_size),j=w.avail_in,V=w.next_in,_=w.input,w.avail_in=Q,w.next_in=0,w.input=H,ct($);$.lookahead>=I;){for(x=$.strstart,T=$.lookahead-(I-1);$.ins_h=($.ins_h<<$.hash_shift^$.window[x+I-1])&$.hash_mask,$.prev[x&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=x,x++,--T;);$.strstart=x,$.lookahead=I-1,ct($)}return $.strstart+=$.lookahead,$.block_start=$.strstart,$.insert=$.lookahead,$.lookahead=0,$.match_length=$.prev_length=I-1,$.match_available=0,w.next_in=V,w.input=_,w.avail_in=j,$.wrap=M,c},t.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(g,f,t){"use strict";f.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],48:[function(g,f,t){"use strict";f.exports=function(e,s){var i,n,r,o,a,l,c,h,u,d,p,m,v,y,b,k,C,E,I,A,O,F,D,S,B;i=e.state,n=e.next_in,S=e.input,r=n+(e.avail_in-5),o=e.next_out,B=e.output,a=o-(s-e.avail_out),l=o+(e.avail_out-257),c=i.dmax,h=i.wsize,u=i.whave,d=i.wnext,p=i.window,m=i.hold,v=i.bits,y=i.lencode,b=i.distcode,k=(1<<i.lenbits)-1,C=(1<<i.distbits)-1;t:do{v<15&&(m+=S[n++]<<v,v+=8,m+=S[n++]<<v,v+=8),E=y[m&k];e:for(;;){if(m>>>=I=E>>>24,v-=I,(I=E>>>16&255)===0)B[o++]=65535&E;else{if(!(16&I)){if(!(64&I)){E=y[(65535&E)+(m&(1<<I)-1)];continue e}if(32&I){i.mode=12;break t}e.msg="invalid literal/length code",i.mode=30;break t}A=65535&E,(I&=15)&&(v<I&&(m+=S[n++]<<v,v+=8),A+=m&(1<<I)-1,m>>>=I,v-=I),v<15&&(m+=S[n++]<<v,v+=8,m+=S[n++]<<v,v+=8),E=b[m&C];s:for(;;){if(m>>>=I=E>>>24,v-=I,!(16&(I=E>>>16&255))){if(!(64&I)){E=b[(65535&E)+(m&(1<<I)-1)];continue s}e.msg="invalid distance code",i.mode=30;break t}if(O=65535&E,v<(I&=15)&&(m+=S[n++]<<v,(v+=8)<I&&(m+=S[n++]<<v,v+=8)),c<(O+=m&(1<<I)-1)){e.msg="invalid distance too far back",i.mode=30;break t}if(m>>>=I,v-=I,(I=o-a)<O){if(u<(I=O-I)&&i.sane){e.msg="invalid distance too far back",i.mode=30;break t}if(D=p,(F=0)===d){if(F+=h-I,I<A){for(A-=I;B[o++]=p[F++],--I;);F=o-O,D=B}}else if(d<I){if(F+=h+d-I,(I-=d)<A){for(A-=I;B[o++]=p[F++],--I;);if(F=0,d<A){for(A-=I=d;B[o++]=p[F++],--I;);F=o-O,D=B}}}else if(F+=d-I,I<A){for(A-=I;B[o++]=p[F++],--I;);F=o-O,D=B}for(;2<A;)B[o++]=D[F++],B[o++]=D[F++],B[o++]=D[F++],A-=3;A&&(B[o++]=D[F++],1<A&&(B[o++]=D[F++]))}else{for(F=o-O;B[o++]=B[F++],B[o++]=B[F++],B[o++]=B[F++],2<(A-=3););A&&(B[o++]=B[F++],1<A&&(B[o++]=B[F++]))}break}}break}}while(n<r&&o<l);n-=A=v>>3,m&=(1<<(v-=A<<3))-1,e.next_in=n,e.next_out=o,e.avail_in=n<r?r-n+5:5-(n-r),e.avail_out=o<l?l-o+257:257-(o-l),i.hold=m,i.bits=v}},{}],49:[function(g,f,t){"use strict";var e=g("../utils/common"),s=g("./adler32"),i=g("./crc32"),n=g("./inffast"),r=g("./inftrees"),o=1,a=2,l=0,c=-2,h=1,u=852,d=592;function p(F){return(F>>>24&255)+(F>>>8&65280)+((65280&F)<<8)+((255&F)<<24)}function m(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new e.Buf16(320),this.work=new e.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function v(F){var D;return F&&F.state?(D=F.state,F.total_in=F.total_out=D.total=0,F.msg="",D.wrap&&(F.adler=1&D.wrap),D.mode=h,D.last=0,D.havedict=0,D.dmax=32768,D.head=null,D.hold=0,D.bits=0,D.lencode=D.lendyn=new e.Buf32(u),D.distcode=D.distdyn=new e.Buf32(d),D.sane=1,D.back=-1,l):c}function y(F){var D;return F&&F.state?((D=F.state).wsize=0,D.whave=0,D.wnext=0,v(F)):c}function b(F,D){var S,B;return F&&F.state?(B=F.state,D<0?(S=0,D=-D):(S=1+(D>>4),D<48&&(D&=15)),D&&(D<8||15<D)?c:(B.window!==null&&B.wbits!==D&&(B.window=null),B.wrap=S,B.wbits=D,y(F))):c}function k(F,D){var S,B;return F?(B=new m,(F.state=B).window=null,(S=b(F,D))!==l&&(F.state=null),S):c}var C,E,I=!0;function A(F){if(I){var D;for(C=new e.Buf32(512),E=new e.Buf32(32),D=0;D<144;)F.lens[D++]=8;for(;D<256;)F.lens[D++]=9;for(;D<280;)F.lens[D++]=7;for(;D<288;)F.lens[D++]=8;for(r(o,F.lens,0,288,C,0,F.work,{bits:9}),D=0;D<32;)F.lens[D++]=5;r(a,F.lens,0,32,E,0,F.work,{bits:5}),I=!1}F.lencode=C,F.lenbits=9,F.distcode=E,F.distbits=5}function O(F,D,S,B){var tt,U=F.state;return U.window===null&&(U.wsize=1<<U.wbits,U.wnext=0,U.whave=0,U.window=new e.Buf8(U.wsize)),B>=U.wsize?(e.arraySet(U.window,D,S-U.wsize,U.wsize,0),U.wnext=0,U.whave=U.wsize):(B<(tt=U.wsize-U.wnext)&&(tt=B),e.arraySet(U.window,D,S-B,tt,U.wnext),(B-=tt)?(e.arraySet(U.window,D,S-B,B,0),U.wnext=B,U.whave=U.wsize):(U.wnext+=tt,U.wnext===U.wsize&&(U.wnext=0),U.whave<U.wsize&&(U.whave+=tt))),0}t.inflateReset=y,t.inflateReset2=b,t.inflateResetKeep=v,t.inflateInit=function(F){return k(F,15)},t.inflateInit2=k,t.inflate=function(F,D){var S,B,tt,U,z,W,X,L,P,J,K,Y,ct,ht,nt,rt,at,st,gt,ft,w,H,$,x,T=0,M=new e.Buf8(4),j=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!F||!F.state||!F.output||!F.input&&F.avail_in!==0)return c;(S=F.state).mode===12&&(S.mode=13),z=F.next_out,tt=F.output,X=F.avail_out,U=F.next_in,B=F.input,W=F.avail_in,L=S.hold,P=S.bits,J=W,K=X,H=l;t:for(;;)switch(S.mode){case h:if(S.wrap===0){S.mode=13;break}for(;P<16;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(2&S.wrap&&L===35615){M[S.check=0]=255&L,M[1]=L>>>8&255,S.check=i(S.check,M,2,0),P=L=0,S.mode=2;break}if(S.flags=0,S.head&&(S.head.done=!1),!(1&S.wrap)||(((255&L)<<8)+(L>>8))%31){F.msg="incorrect header check",S.mode=30;break}if((15&L)!=8){F.msg="unknown compression method",S.mode=30;break}if(P-=4,w=8+(15&(L>>>=4)),S.wbits===0)S.wbits=w;else if(w>S.wbits){F.msg="invalid window size",S.mode=30;break}S.dmax=1<<w,F.adler=S.check=1,S.mode=512&L?10:12,P=L=0;break;case 2:for(;P<16;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(S.flags=L,(255&S.flags)!=8){F.msg="unknown compression method",S.mode=30;break}if(57344&S.flags){F.msg="unknown header flags set",S.mode=30;break}S.head&&(S.head.text=L>>8&1),512&S.flags&&(M[0]=255&L,M[1]=L>>>8&255,S.check=i(S.check,M,2,0)),P=L=0,S.mode=3;case 3:for(;P<32;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.head&&(S.head.time=L),512&S.flags&&(M[0]=255&L,M[1]=L>>>8&255,M[2]=L>>>16&255,M[3]=L>>>24&255,S.check=i(S.check,M,4,0)),P=L=0,S.mode=4;case 4:for(;P<16;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.head&&(S.head.xflags=255&L,S.head.os=L>>8),512&S.flags&&(M[0]=255&L,M[1]=L>>>8&255,S.check=i(S.check,M,2,0)),P=L=0,S.mode=5;case 5:if(1024&S.flags){for(;P<16;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.length=L,S.head&&(S.head.extra_len=L),512&S.flags&&(M[0]=255&L,M[1]=L>>>8&255,S.check=i(S.check,M,2,0)),P=L=0}else S.head&&(S.head.extra=null);S.mode=6;case 6:if(1024&S.flags&&(W<(Y=S.length)&&(Y=W),Y&&(S.head&&(w=S.head.extra_len-S.length,S.head.extra||(S.head.extra=new Array(S.head.extra_len)),e.arraySet(S.head.extra,B,U,Y,w)),512&S.flags&&(S.check=i(S.check,B,Y,U)),W-=Y,U+=Y,S.length-=Y),S.length))break t;S.length=0,S.mode=7;case 7:if(2048&S.flags){if(W===0)break t;for(Y=0;w=B[U+Y++],S.head&&w&&S.length<65536&&(S.head.name+=String.fromCharCode(w)),w&&Y<W;);if(512&S.flags&&(S.check=i(S.check,B,Y,U)),W-=Y,U+=Y,w)break t}else S.head&&(S.head.name=null);S.length=0,S.mode=8;case 8:if(4096&S.flags){if(W===0)break t;for(Y=0;w=B[U+Y++],S.head&&w&&S.length<65536&&(S.head.comment+=String.fromCharCode(w)),w&&Y<W;);if(512&S.flags&&(S.check=i(S.check,B,Y,U)),W-=Y,U+=Y,w)break t}else S.head&&(S.head.comment=null);S.mode=9;case 9:if(512&S.flags){for(;P<16;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(L!==(65535&S.check)){F.msg="header crc mismatch",S.mode=30;break}P=L=0}S.head&&(S.head.hcrc=S.flags>>9&1,S.head.done=!0),F.adler=S.check=0,S.mode=12;break;case 10:for(;P<32;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}F.adler=S.check=p(L),P=L=0,S.mode=11;case 11:if(S.havedict===0)return F.next_out=z,F.avail_out=X,F.next_in=U,F.avail_in=W,S.hold=L,S.bits=P,2;F.adler=S.check=1,S.mode=12;case 12:if(D===5||D===6)break t;case 13:if(S.last){L>>>=7&P,P-=7&P,S.mode=27;break}for(;P<3;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}switch(S.last=1&L,P-=1,3&(L>>>=1)){case 0:S.mode=14;break;case 1:if(A(S),S.mode=20,D!==6)break;L>>>=2,P-=2;break t;case 2:S.mode=17;break;case 3:F.msg="invalid block type",S.mode=30}L>>>=2,P-=2;break;case 14:for(L>>>=7&P,P-=7&P;P<32;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if((65535&L)!=(L>>>16^65535)){F.msg="invalid stored block lengths",S.mode=30;break}if(S.length=65535&L,P=L=0,S.mode=15,D===6)break t;case 15:S.mode=16;case 16:if(Y=S.length){if(W<Y&&(Y=W),X<Y&&(Y=X),Y===0)break t;e.arraySet(tt,B,U,Y,z),W-=Y,U+=Y,X-=Y,z+=Y,S.length-=Y;break}S.mode=12;break;case 17:for(;P<14;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(S.nlen=257+(31&L),L>>>=5,P-=5,S.ndist=1+(31&L),L>>>=5,P-=5,S.ncode=4+(15&L),L>>>=4,P-=4,286<S.nlen||30<S.ndist){F.msg="too many length or distance symbols",S.mode=30;break}S.have=0,S.mode=18;case 18:for(;S.have<S.ncode;){for(;P<3;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.lens[j[S.have++]]=7&L,L>>>=3,P-=3}for(;S.have<19;)S.lens[j[S.have++]]=0;if(S.lencode=S.lendyn,S.lenbits=7,$={bits:S.lenbits},H=r(0,S.lens,0,19,S.lencode,0,S.work,$),S.lenbits=$.bits,H){F.msg="invalid code lengths set",S.mode=30;break}S.have=0,S.mode=19;case 19:for(;S.have<S.nlen+S.ndist;){for(;rt=(T=S.lencode[L&(1<<S.lenbits)-1])>>>16&255,at=65535&T,!((nt=T>>>24)<=P);){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(at<16)L>>>=nt,P-=nt,S.lens[S.have++]=at;else{if(at===16){for(x=nt+2;P<x;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(L>>>=nt,P-=nt,S.have===0){F.msg="invalid bit length repeat",S.mode=30;break}w=S.lens[S.have-1],Y=3+(3&L),L>>>=2,P-=2}else if(at===17){for(x=nt+3;P<x;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}P-=nt,w=0,Y=3+(7&(L>>>=nt)),L>>>=3,P-=3}else{for(x=nt+7;P<x;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}P-=nt,w=0,Y=11+(127&(L>>>=nt)),L>>>=7,P-=7}if(S.have+Y>S.nlen+S.ndist){F.msg="invalid bit length repeat",S.mode=30;break}for(;Y--;)S.lens[S.have++]=w}}if(S.mode===30)break;if(S.lens[256]===0){F.msg="invalid code -- missing end-of-block",S.mode=30;break}if(S.lenbits=9,$={bits:S.lenbits},H=r(o,S.lens,0,S.nlen,S.lencode,0,S.work,$),S.lenbits=$.bits,H){F.msg="invalid literal/lengths set",S.mode=30;break}if(S.distbits=6,S.distcode=S.distdyn,$={bits:S.distbits},H=r(a,S.lens,S.nlen,S.ndist,S.distcode,0,S.work,$),S.distbits=$.bits,H){F.msg="invalid distances set",S.mode=30;break}if(S.mode=20,D===6)break t;case 20:S.mode=21;case 21:if(6<=W&&258<=X){F.next_out=z,F.avail_out=X,F.next_in=U,F.avail_in=W,S.hold=L,S.bits=P,n(F,K),z=F.next_out,tt=F.output,X=F.avail_out,U=F.next_in,B=F.input,W=F.avail_in,L=S.hold,P=S.bits,S.mode===12&&(S.back=-1);break}for(S.back=0;rt=(T=S.lencode[L&(1<<S.lenbits)-1])>>>16&255,at=65535&T,!((nt=T>>>24)<=P);){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(rt&&!(240&rt)){for(st=nt,gt=rt,ft=at;rt=(T=S.lencode[ft+((L&(1<<st+gt)-1)>>st)])>>>16&255,at=65535&T,!(st+(nt=T>>>24)<=P);){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}L>>>=st,P-=st,S.back+=st}if(L>>>=nt,P-=nt,S.back+=nt,S.length=at,rt===0){S.mode=26;break}if(32&rt){S.back=-1,S.mode=12;break}if(64&rt){F.msg="invalid literal/length code",S.mode=30;break}S.extra=15&rt,S.mode=22;case 22:if(S.extra){for(x=S.extra;P<x;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.length+=L&(1<<S.extra)-1,L>>>=S.extra,P-=S.extra,S.back+=S.extra}S.was=S.length,S.mode=23;case 23:for(;rt=(T=S.distcode[L&(1<<S.distbits)-1])>>>16&255,at=65535&T,!((nt=T>>>24)<=P);){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(!(240&rt)){for(st=nt,gt=rt,ft=at;rt=(T=S.distcode[ft+((L&(1<<st+gt)-1)>>st)])>>>16&255,at=65535&T,!(st+(nt=T>>>24)<=P);){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}L>>>=st,P-=st,S.back+=st}if(L>>>=nt,P-=nt,S.back+=nt,64&rt){F.msg="invalid distance code",S.mode=30;break}S.offset=at,S.extra=15&rt,S.mode=24;case 24:if(S.extra){for(x=S.extra;P<x;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}S.offset+=L&(1<<S.extra)-1,L>>>=S.extra,P-=S.extra,S.back+=S.extra}if(S.offset>S.dmax){F.msg="invalid distance too far back",S.mode=30;break}S.mode=25;case 25:if(X===0)break t;if(Y=K-X,S.offset>Y){if((Y=S.offset-Y)>S.whave&&S.sane){F.msg="invalid distance too far back",S.mode=30;break}ct=Y>S.wnext?(Y-=S.wnext,S.wsize-Y):S.wnext-Y,Y>S.length&&(Y=S.length),ht=S.window}else ht=tt,ct=z-S.offset,Y=S.length;for(X<Y&&(Y=X),X-=Y,S.length-=Y;tt[z++]=ht[ct++],--Y;);S.length===0&&(S.mode=21);break;case 26:if(X===0)break t;tt[z++]=S.length,X--,S.mode=21;break;case 27:if(S.wrap){for(;P<32;){if(W===0)break t;W--,L|=B[U++]<<P,P+=8}if(K-=X,F.total_out+=K,S.total+=K,K&&(F.adler=S.check=S.flags?i(S.check,tt,K,z-K):s(S.check,tt,K,z-K)),K=X,(S.flags?L:p(L))!==S.check){F.msg="incorrect data check",S.mode=30;break}P=L=0}S.mode=28;case 28:if(S.wrap&&S.flags){for(;P<32;){if(W===0)break t;W--,L+=B[U++]<<P,P+=8}if(L!==(4294967295&S.total)){F.msg="incorrect length check",S.mode=30;break}P=L=0}S.mode=29;case 29:H=1;break t;case 30:H=-3;break t;case 31:return-4;case 32:default:return c}return F.next_out=z,F.avail_out=X,F.next_in=U,F.avail_in=W,S.hold=L,S.bits=P,(S.wsize||K!==F.avail_out&&S.mode<30&&(S.mode<27||D!==4))&&O(F,F.output,F.next_out,K-F.avail_out)?(S.mode=31,-4):(J-=F.avail_in,K-=F.avail_out,F.total_in+=J,F.total_out+=K,S.total+=K,S.wrap&&K&&(F.adler=S.check=S.flags?i(S.check,tt,K,F.next_out-K):s(S.check,tt,K,F.next_out-K)),F.data_type=S.bits+(S.last?64:0)+(S.mode===12?128:0)+(S.mode===20||S.mode===15?256:0),(J==0&&K===0||D===4)&&H===l&&(H=-5),H)},t.inflateEnd=function(F){if(!F||!F.state)return c;var D=F.state;return D.window&&(D.window=null),F.state=null,l},t.inflateGetHeader=function(F,D){var S;return F&&F.state&&2&(S=F.state).wrap?((S.head=D).done=!1,l):c},t.inflateSetDictionary=function(F,D){var S,B=D.length;return F&&F.state?(S=F.state).wrap!==0&&S.mode!==11?c:S.mode===11&&s(1,D,B,0)!==S.check?-3:O(F,D,B,B)?(S.mode=31,-4):(S.havedict=1,l):c},t.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(g,f,t){"use strict";var e=g("../utils/common"),s=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],i=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],n=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],r=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];f.exports=function(o,a,l,c,h,u,d,p){var m,v,y,b,k,C,E,I,A,O=p.bits,F=0,D=0,S=0,B=0,tt=0,U=0,z=0,W=0,X=0,L=0,P=null,J=0,K=new e.Buf16(16),Y=new e.Buf16(16),ct=null,ht=0;for(F=0;F<=15;F++)K[F]=0;for(D=0;D<c;D++)K[a[l+D]]++;for(tt=O,B=15;1<=B&&K[B]===0;B--);if(B<tt&&(tt=B),B===0)return h[u++]=20971520,h[u++]=20971520,p.bits=1,0;for(S=1;S<B&&K[S]===0;S++);for(tt<S&&(tt=S),F=W=1;F<=15;F++)if(W<<=1,(W-=K[F])<0)return-1;if(0<W&&(o===0||B!==1))return-1;for(Y[1]=0,F=1;F<15;F++)Y[F+1]=Y[F]+K[F];for(D=0;D<c;D++)a[l+D]!==0&&(d[Y[a[l+D]]++]=D);if(C=o===0?(P=ct=d,19):o===1?(P=s,J-=257,ct=i,ht-=257,256):(P=n,ct=r,-1),F=S,k=u,z=D=L=0,y=-1,b=(X=1<<(U=tt))-1,o===1&&852<X||o===2&&592<X)return 1;for(;;){for(E=F-z,A=d[D]<C?(I=0,d[D]):d[D]>C?(I=ct[ht+d[D]],P[J+d[D]]):(I=96,0),m=1<<F-z,S=v=1<<U;h[k+(L>>z)+(v-=m)]=E<<24|I<<16|A|0,v!==0;);for(m=1<<F-1;L&m;)m>>=1;if(m!==0?(L&=m-1,L+=m):L=0,D++,--K[F]==0){if(F===B)break;F=a[l+d[D]]}if(tt<F&&(L&b)!==y){for(z===0&&(z=tt),k+=S,W=1<<(U=F-z);U+z<B&&!((W-=K[U+z])<=0);)U++,W<<=1;if(X+=1<<U,o===1&&852<X||o===2&&592<X)return 1;h[y=L&b]=tt<<24|U<<16|k-u|0}}return L!==0&&(h[k+L]=F-z<<24|64<<16|0),p.bits=tt,0}},{"../utils/common":41}],51:[function(g,f,t){"use strict";f.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],52:[function(g,f,t){"use strict";var e=g("../utils/common"),s=0,i=1;function n(T){for(var M=T.length;0<=--M;)T[M]=0}var r=0,o=29,a=256,l=a+1+o,c=30,h=19,u=2*l+1,d=15,p=16,m=7,v=256,y=16,b=17,k=18,C=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],E=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],I=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],O=new Array(2*(l+2));n(O);var F=new Array(2*c);n(F);var D=new Array(512);n(D);var S=new Array(256);n(S);var B=new Array(o);n(B);var tt,U,z,W=new Array(c);function X(T,M,j,V,_){this.static_tree=T,this.extra_bits=M,this.extra_base=j,this.elems=V,this.max_length=_,this.has_stree=T&&T.length}function L(T,M){this.dyn_tree=T,this.max_code=0,this.stat_desc=M}function P(T){return T<256?D[T]:D[256+(T>>>7)]}function J(T,M){T.pending_buf[T.pending++]=255&M,T.pending_buf[T.pending++]=M>>>8&255}function K(T,M,j){T.bi_valid>p-j?(T.bi_buf|=M<<T.bi_valid&65535,J(T,T.bi_buf),T.bi_buf=M>>p-T.bi_valid,T.bi_valid+=j-p):(T.bi_buf|=M<<T.bi_valid&65535,T.bi_valid+=j)}function Y(T,M,j){K(T,j[2*M],j[2*M+1])}function ct(T,M){for(var j=0;j|=1&T,T>>>=1,j<<=1,0<--M;);return j>>>1}function ht(T,M,j){var V,_,q=new Array(d+1),Q=0;for(V=1;V<=d;V++)q[V]=Q=Q+j[V-1]<<1;for(_=0;_<=M;_++){var Z=T[2*_+1];Z!==0&&(T[2*_]=ct(q[Z]++,Z))}}function nt(T){var M;for(M=0;M<l;M++)T.dyn_ltree[2*M]=0;for(M=0;M<c;M++)T.dyn_dtree[2*M]=0;for(M=0;M<h;M++)T.bl_tree[2*M]=0;T.dyn_ltree[2*v]=1,T.opt_len=T.static_len=0,T.last_lit=T.matches=0}function rt(T){8<T.bi_valid?J(T,T.bi_buf):0<T.bi_valid&&(T.pending_buf[T.pending++]=T.bi_buf),T.bi_buf=0,T.bi_valid=0}function at(T,M,j,V){var _=2*M,q=2*j;return T[_]<T[q]||T[_]===T[q]&&V[M]<=V[j]}function st(T,M,j){for(var V=T.heap[j],_=j<<1;_<=T.heap_len&&(_<T.heap_len&&at(M,T.heap[_+1],T.heap[_],T.depth)&&_++,!at(M,V,T.heap[_],T.depth));)T.heap[j]=T.heap[_],j=_,_<<=1;T.heap[j]=V}function gt(T,M,j){var V,_,q,Q,Z=0;if(T.last_lit!==0)for(;V=T.pending_buf[T.d_buf+2*Z]<<8|T.pending_buf[T.d_buf+2*Z+1],_=T.pending_buf[T.l_buf+Z],Z++,V===0?Y(T,_,M):(Y(T,(q=S[_])+a+1,M),(Q=C[q])!==0&&K(T,_-=B[q],Q),Y(T,q=P(--V),j),(Q=E[q])!==0&&K(T,V-=W[q],Q)),Z<T.last_lit;);Y(T,v,M)}function ft(T,M){var j,V,_,q=M.dyn_tree,Q=M.stat_desc.static_tree,Z=M.stat_desc.has_stree,et=M.stat_desc.elems,ut=-1;for(T.heap_len=0,T.heap_max=u,j=0;j<et;j++)q[2*j]!==0?(T.heap[++T.heap_len]=ut=j,T.depth[j]=0):q[2*j+1]=0;for(;T.heap_len<2;)q[2*(_=T.heap[++T.heap_len]=ut<2?++ut:0)]=1,T.depth[_]=0,T.opt_len--,Z&&(T.static_len-=Q[2*_+1]);for(M.max_code=ut,j=T.heap_len>>1;1<=j;j--)st(T,q,j);for(_=et;j=T.heap[1],T.heap[1]=T.heap[T.heap_len--],st(T,q,1),V=T.heap[1],T.heap[--T.heap_max]=j,T.heap[--T.heap_max]=V,q[2*_]=q[2*j]+q[2*V],T.depth[_]=(T.depth[j]>=T.depth[V]?T.depth[j]:T.depth[V])+1,q[2*j+1]=q[2*V+1]=_,T.heap[1]=_++,st(T,q,1),2<=T.heap_len;);T.heap[--T.heap_max]=T.heap[1],function(lt,kt){var ie,xt,ne,vt,we,ls,At=kt.dyn_tree,As=kt.max_code,li=kt.stat_desc.static_tree,ci=kt.stat_desc.has_stree,di=kt.stat_desc.extra_bits,Ds=kt.stat_desc.extra_base,re=kt.stat_desc.max_length,be=0;for(vt=0;vt<=d;vt++)lt.bl_count[vt]=0;for(At[2*lt.heap[lt.heap_max]+1]=0,ie=lt.heap_max+1;ie<u;ie++)re<(vt=At[2*At[2*(xt=lt.heap[ie])+1]+1]+1)&&(vt=re,be++),At[2*xt+1]=vt,As<xt||(lt.bl_count[vt]++,we=0,Ds<=xt&&(we=di[xt-Ds]),ls=At[2*xt],lt.opt_len+=ls*(vt+we),ci&&(lt.static_len+=ls*(li[2*xt+1]+we)));if(be!==0){do{for(vt=re-1;lt.bl_count[vt]===0;)vt--;lt.bl_count[vt]--,lt.bl_count[vt+1]+=2,lt.bl_count[re]--,be-=2}while(0<be);for(vt=re;vt!==0;vt--)for(xt=lt.bl_count[vt];xt!==0;)As<(ne=lt.heap[--ie])||(At[2*ne+1]!==vt&&(lt.opt_len+=(vt-At[2*ne+1])*At[2*ne],At[2*ne+1]=vt),xt--)}}(T,M),ht(q,ut,T.bl_count)}function w(T,M,j){var V,_,q=-1,Q=M[1],Z=0,et=7,ut=4;for(Q===0&&(et=138,ut=3),M[2*(j+1)+1]=65535,V=0;V<=j;V++)_=Q,Q=M[2*(V+1)+1],++Z<et&&_===Q||(Z<ut?T.bl_tree[2*_]+=Z:_!==0?(_!==q&&T.bl_tree[2*_]++,T.bl_tree[2*y]++):Z<=10?T.bl_tree[2*b]++:T.bl_tree[2*k]++,q=_,ut=(Z=0)===Q?(et=138,3):_===Q?(et=6,3):(et=7,4))}function H(T,M,j){var V,_,q=-1,Q=M[1],Z=0,et=7,ut=4;for(Q===0&&(et=138,ut=3),V=0;V<=j;V++)if(_=Q,Q=M[2*(V+1)+1],!(++Z<et&&_===Q)){if(Z<ut)for(;Y(T,_,T.bl_tree),--Z!=0;);else _!==0?(_!==q&&(Y(T,_,T.bl_tree),Z--),Y(T,y,T.bl_tree),K(T,Z-3,2)):Z<=10?(Y(T,b,T.bl_tree),K(T,Z-3,3)):(Y(T,k,T.bl_tree),K(T,Z-11,7));q=_,ut=(Z=0)===Q?(et=138,3):_===Q?(et=6,3):(et=7,4)}}n(W);var $=!1;function x(T,M,j,V){K(T,(r<<1)+(V?1:0),3),function(_,q,Q,Z){rt(_),Z&&(J(_,Q),J(_,~Q)),e.arraySet(_.pending_buf,_.window,q,Q,_.pending),_.pending+=Q}(T,M,j,!0)}t._tr_init=function(T){$||(function(){var M,j,V,_,q,Q=new Array(d+1);for(_=V=0;_<o-1;_++)for(B[_]=V,M=0;M<1<<C[_];M++)S[V++]=_;for(S[V-1]=_,_=q=0;_<16;_++)for(W[_]=q,M=0;M<1<<E[_];M++)D[q++]=_;for(q>>=7;_<c;_++)for(W[_]=q<<7,M=0;M<1<<E[_]-7;M++)D[256+q++]=_;for(j=0;j<=d;j++)Q[j]=0;for(M=0;M<=143;)O[2*M+1]=8,M++,Q[8]++;for(;M<=255;)O[2*M+1]=9,M++,Q[9]++;for(;M<=279;)O[2*M+1]=7,M++,Q[7]++;for(;M<=287;)O[2*M+1]=8,M++,Q[8]++;for(ht(O,l+1,Q),M=0;M<c;M++)F[2*M+1]=5,F[2*M]=ct(M,5);tt=new X(O,C,a+1,l,d),U=new X(F,E,0,c,d),z=new X(new Array(0),I,0,h,m)}(),$=!0),T.l_desc=new L(T.dyn_ltree,tt),T.d_desc=new L(T.dyn_dtree,U),T.bl_desc=new L(T.bl_tree,z),T.bi_buf=0,T.bi_valid=0,nt(T)},t._tr_stored_block=x,t._tr_flush_block=function(T,M,j,V){var _,q,Q=0;0<T.level?(T.strm.data_type===2&&(T.strm.data_type=function(Z){var et,ut=4093624447;for(et=0;et<=31;et++,ut>>>=1)if(1&ut&&Z.dyn_ltree[2*et]!==0)return s;if(Z.dyn_ltree[18]!==0||Z.dyn_ltree[20]!==0||Z.dyn_ltree[26]!==0)return i;for(et=32;et<a;et++)if(Z.dyn_ltree[2*et]!==0)return i;return s}(T)),ft(T,T.l_desc),ft(T,T.d_desc),Q=function(Z){var et;for(w(Z,Z.dyn_ltree,Z.l_desc.max_code),w(Z,Z.dyn_dtree,Z.d_desc.max_code),ft(Z,Z.bl_desc),et=h-1;3<=et&&Z.bl_tree[2*A[et]+1]===0;et--);return Z.opt_len+=3*(et+1)+5+5+4,et}(T),_=T.opt_len+3+7>>>3,(q=T.static_len+3+7>>>3)<=_&&(_=q)):_=q=j+5,j+4<=_&&M!==-1?x(T,M,j,V):T.strategy===4||q===_?(K(T,2+(V?1:0),3),gt(T,O,F)):(K(T,4+(V?1:0),3),function(Z,et,ut,lt){var kt;for(K(Z,et-257,5),K(Z,ut-1,5),K(Z,lt-4,4),kt=0;kt<lt;kt++)K(Z,Z.bl_tree[2*A[kt]+1],3);H(Z,Z.dyn_ltree,et-1),H(Z,Z.dyn_dtree,ut-1)}(T,T.l_desc.max_code+1,T.d_desc.max_code+1,Q+1),gt(T,T.dyn_ltree,T.dyn_dtree)),nt(T),V&&rt(T)},t._tr_tally=function(T,M,j){return T.pending_buf[T.d_buf+2*T.last_lit]=M>>>8&255,T.pending_buf[T.d_buf+2*T.last_lit+1]=255&M,T.pending_buf[T.l_buf+T.last_lit]=255&j,T.last_lit++,M===0?T.dyn_ltree[2*j]++:(T.matches++,M--,T.dyn_ltree[2*(S[j]+a+1)]++,T.dyn_dtree[2*P(M)]++),T.last_lit===T.lit_bufsize-1},t._tr_align=function(T){K(T,2,3),Y(T,v,O),function(M){M.bi_valid===16?(J(M,M.bi_buf),M.bi_buf=0,M.bi_valid=0):8<=M.bi_valid&&(M.pending_buf[M.pending++]=255&M.bi_buf,M.bi_buf>>=8,M.bi_valid-=8)}(T)}},{"../utils/common":41}],53:[function(g,f,t){"use strict";f.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(g,f,t){(function(e){(function(s,i){"use strict";if(!s.setImmediate){var n,r,o,a,l=1,c={},h=!1,u=s.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(s);d=d&&d.setTimeout?d:s,n={}.toString.call(s.process)==="[object process]"?function(y){process.nextTick(function(){m(y)})}:function(){if(s.postMessage&&!s.importScripts){var y=!0,b=s.onmessage;return s.onmessage=function(){y=!1},s.postMessage("","*"),s.onmessage=b,y}}()?(a="setImmediate$"+Math.random()+"$",s.addEventListener?s.addEventListener("message",v,!1):s.attachEvent("onmessage",v),function(y){s.postMessage(a+y,"*")}):s.MessageChannel?((o=new MessageChannel).port1.onmessage=function(y){m(y.data)},function(y){o.port2.postMessage(y)}):u&&"onreadystatechange"in u.createElement("script")?(r=u.documentElement,function(y){var b=u.createElement("script");b.onreadystatechange=function(){m(y),b.onreadystatechange=null,r.removeChild(b),b=null},r.appendChild(b)}):function(y){setTimeout(m,0,y)},d.setImmediate=function(y){typeof y!="function"&&(y=new Function(""+y));for(var b=new Array(arguments.length-1),k=0;k<b.length;k++)b[k]=arguments[k+1];var C={callback:y,args:b};return c[l]=C,n(l),l++},d.clearImmediate=p}function p(y){delete c[y]}function m(y){if(h)setTimeout(m,0,y);else{var b=c[y];if(b){h=!0;try{(function(k){var C=k.callback,E=k.args;switch(E.length){case 0:C();break;case 1:C(E[0]);break;case 2:C(E[0],E[1]);break;case 3:C(E[0],E[1],E[2]);break;default:C.apply(i,E)}})(b)}finally{p(y),h=!1}}}}function v(y){y.source===s&&typeof y.data=="string"&&y.data.indexOf(a)===0&&m(+y.data.slice(a.length))}})(typeof self>"u"?e===void 0?this:e:self)}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}]},{},[10])(10)})});var ji={};ke(ji,{default:()=>os});module.exports=yi(ji);var it=require("obsidian");Ct();var St=require("obsidian");var yt=require("obsidian");Ct();function Ce(g){let f=(g.dateDisplayTimezone||"").trim();return f?{timeZone:f}:{}}function Dt(g,f){try{return new Intl.DateTimeFormat(void 0,f).format(new Date(g))}catch{let{timeZone:t,...e}=f;return new Intl.DateTimeFormat(void 0,e).format(new Date(g))}}function Wt(g,f){let t=Ce(f);switch(f.dateDisplayFormat??"locale"){case"iso":return Ls(g,f,!0);case"us":return Dt(g,{...t,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return Dt(g,{...t,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return Dt(g,{...t,dateStyle:"full",timeStyle:"short"});case"locale":default:return Dt(g,{...t,dateStyle:"medium",timeStyle:"short"})}}function Ms(g,f){let t=Ce(f);switch(f.dateDisplayFormat??"locale"){case"iso":return Ls(g,f,!1);case"us":return Dt(g,{...t,month:"numeric",day:"numeric",year:"numeric"});case"eu":return Dt(g,{...t,day:"numeric",month:"numeric",year:"numeric"});case"long":return Dt(g,{...t,dateStyle:"full"});case"locale":default:{let e=new Date,s=new Date(g).getFullYear()===e.getFullYear();return Dt(g,s?{...t,month:"short",day:"numeric"}:{...t,month:"short",day:"numeric",year:"numeric"})}}}function _s(g,f){let t=Ce(f),e=f.dateDisplayFormat==="iso"||f.dateDisplayFormat==="eu";return Dt(g,{...t,hour:e?"2-digit":"numeric",minute:"2-digit",...e?{hourCycle:"h23"}:{}})}function Ls(g,f,t){let e=Ce(f),s=new Intl.DateTimeFormat("en-CA",{...e,year:"numeric",month:"2-digit",day:"2-digit",...t?{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:{}}).formatToParts(new Date(g)),i=r=>s.find(o=>o.type===r)?.value??"",n=`${i("year")}-${i("month")}-${i("day")}`;return t?`${n} ${i("hour")}:${i("minute")}`:n}function Ee(g,f,t){let e=g.createSpan({cls:"stashpad-count-badge"});t&&e.addClass("is-expanded"),e.setText(f>99?"99+":String(f))}var he={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},Ie=class extends yt.ItemView{constructor(t,e){super(t);this.plugin=e;this.activePanel="pinned";this.taskFilter="all";this.expanded=new Set;this.renderTimer=null;this.sharedAuthorFilter="all";this.sharedContribOnly=!1}setActivePanel(t){this.activePanel=t,this.containerEl.isConnected&&this.render()}getViewType(){return _t}getDisplayText(){return"Stashpad panels"}getIcon(){return"panel-left"}async onOpen(){this.render(),this.registerEvent(this.app.metadataCache.on("changed",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("rename",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("delete",()=>this.scheduleRender())),this.registerEvent(this.app.workspace.on("active-leaf-change",t=>{t&&t.view.getViewType()===mt&&this.scheduleRender()}))}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},80))}render(){let t=this.contentEl;t.empty(),t.addClass("stashpad-panels-root");let e=t.createDiv({cls:"stashpad-panels-globals"}),s=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(s.createSpan({cls:"stashpad-panels-global-btn-icon"}),"search"),s.createSpan({cls:"stashpad-panels-global-btn-text",text:"Search"}),s.onclick=()=>this.openSearchFromPanel();let i=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(i.createSpan({cls:"stashpad-panels-global-btn-icon"}),"folder-tree"),i.createSpan({cls:"stashpad-panels-global-btn-text",text:"Folder Switcher"}),i.onclick=()=>this.plugin.openFolderPicker();let n=e.createDiv({cls:"stashpad-panels-globals-row"}),r=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(r.createSpan({cls:"stashpad-panels-global-btn-icon"}),"scroll-text"),r.createSpan({cls:"stashpad-panels-global-btn-text",text:"Log"}),r.onclick=()=>this.openLogFromPanel();let o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(o.createSpan({cls:"stashpad-panels-global-btn-icon"}),"bell"),o.createSpan({cls:"stashpad-panels-global-btn-text",text:"Notifications"}),o.onclick=()=>this.openNotificationsFromPanel();let a=t.createDiv({cls:"stashpad-panels-bar"});for(let c of Object.keys(he)){let h=he[c],u=a.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,yt.setIcon)(u.createSpan({cls:"stashpad-panels-bar-btn-icon"}),h.icon),u.createSpan({cls:"stashpad-panels-bar-btn-text",text:h.label}),this.activePanel===c&&u.addClass("is-active"),u.onclick=()=>{this.activePanel!==c&&(this.activePanel=c,this.render())}}let l=t.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(l):this.activePanel==="shared"?this.renderSharedPanel(l):this.activePanel==="tasks"&&this.renderTasksPanel(l)}renderPinnedPanel(t){let e=t.createDiv({cls:"stashpad-panel-pinned"}),s=e.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),i=s.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(i,"home"),s.createSpan({cls:"stashpad-pinned-label",text:"Home"}),s.onclick=()=>this.openHomeFromPanel();let n=this.plugin.settings.pinnedNotes??[];if(n.length===0){e.createDiv({cls:"stashpad-pinned-empty"}).setText("No pinned notes yet \u2014 right-click a note and choose \u201CPin to sidebar.\u201D");return}let r=new Map;n.forEach((l,c)=>{let h=r.get(l.folder);h||(h=[],r.set(l.folder,h)),h.push({pin:l,idx:c})});let o=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,a=Array.from(r.keys());o&&r.has(o)&&(a.splice(a.indexOf(o),1),a.unshift(o));for(let l of a){let c=l.split("/").pop()||l,h=e.createDiv({cls:"stashpad-pinned-group-header"});l===o&&h.addClass("is-active-folder"),h.createSpan({cls:"stashpad-pinned-group-name",text:c});let u=r.get(l)??[];for(let{pin:d,idx:p}of u)this.renderPinnedRow(e,d,p)}}renderPinnedRow(t,e,s){let i=this.findFileFor(e);if(!i)return;let n=this.app.metadataCache.getFileCache(i)?.frontmatter??{},r=this.titleFromFile(i),o=typeof n.color=="string"?n.color:null,a=n.completed===!0,l=this.childrenOf(e.folder,e.id).length,c=l>0,h=this.expanded.has(`${e.folder}|${e.id}`),u=t.createDiv({cls:"stashpad-pinned-row"});o&&u.addClass("has-color"),a&&u.addClass("is-completed"),u.draggable=!0,u.dataset.pinIdx=String(s),u.addEventListener("dragstart",y=>{y.dataTransfer?.setData("text/plain",String(s)),y.dataTransfer&&(y.dataTransfer.effectAllowed="move"),u.addClass("is-dragging")}),u.addEventListener("dragend",()=>u.removeClass("is-dragging")),u.addEventListener("dragover",y=>{y.preventDefault(),y.dataTransfer&&(y.dataTransfer.dropEffect="move");let b=u.getBoundingClientRect(),k=y.clientY-b.top<b.height/2;u.toggleClass("drop-before",k),u.toggleClass("drop-after",!k)}),u.addEventListener("dragleave",()=>{u.removeClass("drop-before"),u.removeClass("drop-after")}),u.addEventListener("drop",y=>{y.preventDefault(),u.removeClass("drop-before"),u.removeClass("drop-after");let b=parseInt(y.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(b)||b===s)return;let k=u.getBoundingClientRect(),C=y.clientY-k.top<k.height/2;this.reorderPin(b,C?s:s+1)});let d=u.createSpan({cls:"stashpad-pinned-toggle"});c&&(Ee(d,l,h),d.onclick=y=>{y.stopPropagation();let b=`${e.folder}|${e.id}`;this.expanded.has(b)?this.expanded.delete(b):this.expanded.add(b),this.render()});let p=u.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(p,c?"folder-tree":"file-text"),o&&(p.style.color=o);let m=u.createSpan({cls:"stashpad-pinned-label",text:r});m.onclick=()=>this.openPinFromPanel(e);let v=e.folder.split("/").pop()||e.folder;if(u.createSpan({cls:"stashpad-pinned-folder",text:v}),u.oncontextmenu=y=>{y.preventDefault();let b=new yt.Menu;b.addItem(k=>k.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(e)})),b.showAtMouseEvent(y)},c&&h){let y=t.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(y,e.folder,e.id,1)}}async reorderPin(t,e){let s=(this.plugin.settings.pinnedNotes??[]).slice();if(t<0||t>=s.length)return;let[i]=s.splice(t,1),n=e>t?e-1:e;s.splice(Math.max(0,Math.min(n,s.length)),0,i),this.plugin.settings.pinnedNotes=s,await this.plugin.saveSettings(),this.render()}renderPinnedSubtree(t,e,s,i){let n=this.childrenOf(e,s);for(let r of n){let o=this.app.metadataCache.getFileCache(r)?.frontmatter??{},a=typeof o.id=="string"?o.id:null;if(!a)continue;let l=typeof o.color=="string"?o.color:null,c=o.completed===!0,h=this.childrenOf(e,a).length,u=h>0,d=this.expanded.has(`${e}|${a}`),p=t.createDiv({cls:"stashpad-pinned-subrow"});c&&p.addClass("is-completed"),p.style.paddingLeft=`${i*16}px`;let m=p.createSpan({cls:"stashpad-pinned-toggle"});u&&(Ee(m,h,d),m.onclick=b=>{b.stopPropagation();let k=`${e}|${a}`;this.expanded.has(k)?this.expanded.delete(k):this.expanded.add(k),this.render()});let v=p.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(v,"file-text"),l&&(v.style.color=l);let y=p.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(r)});y.onclick=()=>this.openPinFromPanel({folder:e,id:a}),u&&d&&this.renderPinnedSubtree(t,e,a,i+1)}}findFileFor(t){for(let e of this.app.vault.getMarkdownFiles()){if((e.parent?.path?.replace(/\/+$/,"")??"")!==t.folder)continue;if(this.app.metadataCache.getFileCache(e)?.frontmatter?.id===t.id)return e}return null}childrenOf(t,e){let s=[];for(let i of this.app.vault.getMarkdownFiles()){if((i.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let r=this.app.metadataCache.getFileCache(i)?.frontmatter;if(!r||typeof r.id!="string")continue;let o=r.parent;if(o===e||e===R&&(o==null||o===R)){if(r.id===R)continue;s.push(i)}}return s.sort((i,n)=>{let r=this.app.metadataCache.getFileCache(i)?.frontmatter,o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=r?.created??"",l=o?.created??"";return a.localeCompare(l)}),s}titleFromFile(t){return t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||t.basename}async openSearchFromPanel(){let t=await this.resolveTargetStashpad();t&&typeof t.openSearchModal=="function"&&t.openSearchModal()}async openLogFromPanel(){let t=this.app.vault.adapter,e=this.plugin.pluginPrivatePath("log.jsonl");if(!await t.exists(e)){new yt.Notice("No log yet \u2014 make some changes first.");return}let s=await t.read(e),{LogModal:i}=await Promise.resolve().then(()=>(Gt(),Fe));new i(this.app,s,e).open()}openNotificationsFromPanel(){this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")}async openHomeFromPanel(){let t=await this.resolveTargetStashpad();t&&typeof t.navigateTo=="function"&&t.navigateTo(R)}async openPinFromPanel(t){await this.plugin.activateViewForFolder(t.folder);let e=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();e&&typeof e.navigateTo=="function"&&e.navigateTo(t.id)}async resolveTargetStashpad(){let t=this.plugin.lastActiveStashpadLeaf;if(t&&t.view.getViewType()===mt)return this.app.workspace.revealLeaf(t),t.view;let e=this.findActiveStashpad();if(e)return e;let s=this.app.workspace.getLeavesOfType(mt);return s.length>0?(this.app.workspace.revealLeaf(s[0]),s[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let t=this.app.workspace.activeLeaf;return t&&t.view.getViewType()===mt?t.view:null}renderSharedPanel(t){let e=t.createDiv({cls:"stashpad-panel-shared"}),s=(this.plugin.settings.authorId??"").trim();if(!s){e.createDiv({cls:"stashpad-shared-empty"}).setText("Set an author name in Stashpad settings to populate Shared.");return}let i=this.collectSharedNotes(s),n=new Map;for(let c of i){let h=c.authorId;h&&!n.has(h)&&n.set(h,c.authorDisplay||h)}let r=e.createDiv({cls:"stashpad-shared-filters"}),o=(c,h,u)=>{let d=r.createEl("button",{cls:"stashpad-shared-chip",text:c});return h&&d.addClass("is-active"),d.onclick=u,d};if(o("All",this.sharedAuthorFilter==="all",()=>{this.sharedAuthorFilter="all",this.render()}),o("Mine",this.sharedAuthorFilter==="mine",()=>{this.sharedAuthorFilter="mine",this.render()}),o("Others",this.sharedAuthorFilter==="others",()=>{this.sharedAuthorFilter="others",this.render()}),n.size>1){let c=r.createEl("select",{cls:"stashpad-shared-author-select"}),h=c.createEl("option",{text:"Any author"});h.value="__any__";for(let[d,p]of n){let m=c.createEl("option",{text:p});m.value=d}let u=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;c.value=u,c.onchange=()=>{let d=c.value;d==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=d,this.render()}}let a=r.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&a.addClass("is-active"),a.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let l=i.filter(c=>{if(this.sharedContribOnly&&c.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return c.authorId===s;case"others":return c.authorId!==s;default:return c.authorId===this.sharedAuthorFilter}});if(l.length===0){e.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let c of l){let h=e.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),u=h.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(u,"users"),c.color&&(u.style.color=c.color);let d=h.createSpan({cls:"stashpad-pinned-label",text:c.title});d.onclick=()=>this.openSharedFromPanel(c.folder,c.id);let p=c.folder.split("/").pop()||c.folder;h.createSpan({cls:"stashpad-pinned-folder",text:p}),c.authorDisplay&&h.createSpan({cls:"stashpad-shared-meta"}).setText(c.authorId===s?`you \xB7 ${c.contributorCount} contributor${c.contributorCount===1?"":"s"}`:`by ${c.authorDisplay}${c.contributorCount>0?` \xB7 ${c.contributorCount} contributor${c.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(t){let e=this.plugin.discoverStashpadFolders(),s=new Set(e),i=new Map;for(let r of this.app.vault.getMarkdownFiles()){let o=r.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(o))continue;let a=this.app.metadataCache.getFileCache(r)?.frontmatter??{};a.id===R&&i.set(o,this.extractAuthorId(a.author))}let n=[];for(let r of this.app.vault.getMarkdownFiles()){let o=r.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(o)||o.endsWith("/_authors")||r.path.includes("/_authors/"))continue;let a=this.app.metadataCache.getFileCache(r)?.frontmatter??{};if(typeof a.id!="string"||a.id===R)continue;let l=this.extractAuthorId(a.author),c=Array.isArray(a.contributors)?a.contributors.filter(b=>typeof b=="string"):[],h=i.get(o)??null;if(!(c.length>0||h===t&&(l!==null&&l!==t)))continue;let v=this.titleFromFile(r),y=typeof a.color=="string"?a.color:null;n.push({file:r,folder:o,id:a.id,title:v,color:y,authorId:l,authorDisplay:this.extractAuthorDisplay(a.author)||(l??""),contributorCount:c.length})}return n.sort((r,o)=>{let a=this.app.metadataCache.getFileCache(r.file)?.frontmatter??{},l=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=a.modified??a.created??"";return(l.modified??l.created??"").localeCompare(c)}),n}extractAuthorId(t){if(typeof t!="string")return null;let e=t.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return e?e[1]:null}extractAuthorDisplay(t){if(typeof t!="string")return"";let e=t.match(/\|([^\]]+)\]\]/);if(e)return e[1].trim();let s=t.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return s?s[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(t,e){await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();s&&typeof s.navigateTo=="function"&&s.navigateTo(e)}renderTasksPanel(t){let e=t.createDiv({cls:"stashpad-panel-tasks"}),s=this.collectTasks();if(s.length===0){e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks yet \u2014 press H on a note to mark it a task, or D to give it a due date.");return}let i=new Date;i.setHours(0,0,0,0);let n=i.getTime(),r=n+24*60*60*1e3,o={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let m of s){if(m.completed){o.completed.push(m);continue}if(m.due==null){o.nodate.push(m);continue}m.due<n?o.overdue.push(m):m.due<r?o.today.push(m):o.upcoming.push(m)}let a=(m,v)=>m.due==null&&v.due==null?m.title.localeCompare(v.title):m.due==null?1:v.due==null?-1:m.due-v.due,l=[{key:"overdue",label:"Overdue",icon:"alert-circle"},{key:"today",label:"Due today",icon:"calendar-clock"},{key:"upcoming",label:"Upcoming",icon:"calendar"},{key:"nodate",label:"No date",icon:"inbox"},{key:"completed",label:"Completed",icon:"check-circle-2"}],c=e.createDiv({cls:"stashpad-task-filters"}),h=s.length,u=(m,v,y)=>{let b=c.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===m&&b.addClass("is-active"),b.createSpan({cls:"stashpad-task-filter-label",text:v}),b.createSpan({cls:"stashpad-task-filter-count",text:String(y)}),b.onclick=()=>{this.taskFilter=m,this.render()}};u("all","All",h),u("overdue","Overdue",o.overdue.length),u("today","Today",o.today.length),u("upcoming","Upcoming",o.upcoming.length),u("nodate","No date",o.nodate.length),u("completed","Done",o.completed.length);let d=this.taskFilter==="all"?l:l.filter(m=>m.key===this.taskFilter),p=!1;for(let m of d){let v=o[m.key];if(v.length!==0){if(p=!0,v.sort(m.key==="completed"?(y,b)=>a(b,y):a),this.taskFilter==="all"){let y=e.createDiv({cls:`stashpad-task-section-header is-${m.key}`});(0,yt.setIcon)(y.createSpan({cls:"stashpad-task-section-icon"}),m.icon),y.createSpan({cls:"stashpad-task-section-name",text:m.label}),y.createSpan({cls:"stashpad-task-section-count",text:String(v.length)})}for(let y of v)this.renderTaskRow(e,y,m.key==="today")}}if(!p&&this.taskFilter!=="all"){e.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${d[0]?.label??this.taskFilter}".`);return}p||e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(t,e,s){let i=t.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});e.color&&i.addClass("has-color"),e.completed&&i.addClass("is-completed");let n=i.createSpan({cls:"stashpad-pinned-icon stashpad-task-checkbox"});(0,yt.setIcon)(n,e.completed?"check-square":"square"),e.color&&(n.style.color=e.color),n.title=e.completed?"Mark not done":"Mark done",n.onclick=o=>{o.stopPropagation(),this.toggleTaskCompleted(e)};let r=i.createSpan({cls:"stashpad-pinned-label",text:e.title});if(r.onclick=()=>this.openTaskFromPanel(e.folder,e.id),i.createSpan({cls:"stashpad-task-folder",text:e.folder.split("/").pop()||e.folder}),e.due!=null){let o=i.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(e.due,s)});e.due<Date.now()&&!e.completed&&o.addClass("is-overdue")}else e.dueRaw&&i.createSpan({cls:"stashpad-task-due",text:e.dueRaw});i.oncontextmenu=o=>{o.preventDefault();let a=new yt.Menu;a.addItem(l=>l.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(e.folder,e.id)})),a.showAtMouseEvent(o)}}formatDueShort(t,e){return e?_s(t,this.plugin.settings):Ms(t,this.plugin.settings)}async openTaskFromPanel(t,e){await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();s&&typeof s.navigateTo=="function"&&s.navigateTo(e)}async toggleTaskCompleted(t){try{await this.app.fileManager.processFrontMatter(t.file,e=>{e.completed=e.completed!==!0})}catch(e){new yt.Notice(`Couldn't update task: ${e.message}`);return}this.scheduleRender()}collectTasks(){let t=this.plugin.discoverStashpadFolders(),e=new Set(t),s=[];for(let i of this.app.vault.getMarkdownFiles()){let n=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(n))continue;let r=this.app.metadataCache.getFileCache(i)?.frontmatter??{},o=typeof r.id=="string"?r.id:null;if(!o||o===R)continue;let a=r.completed===!0,l=zt(r,"task")||r.task===!0||r.completed!==void 0,c=typeof r.due=="string"||typeof r.due=="number"?String(r.due):null,h=null;if(c){let u=Date.parse(c);Number.isNaN(u)||(h=u)}!l&&!a&&h==null&&!c||s.push({file:i,folder:n,id:o,title:this.titleFromFile(i),task:l,completed:a,due:h,dueRaw:c,color:typeof r.color=="string"?r.color:null})}return s}};async function Ae(g){let f=g.workspace.getLeavesOfType(_t);if(f.length>0){g.workspace.revealLeaf(f[0]);return}let t=g.workspace.getLeftLeaf(!1);if(!t){new yt.Notice("Stashpad: couldn't open the panels view.");return}await t.setViewState({type:_t,active:!0}),g.workspace.revealLeaf(t)}var $s=require("obsidian"),Jt=class{constructor(f,t){this.app=f;this.ta=t;this.popupEl=null;this.items=[];this.activeIdx=0;this.state=null;this.fileIndex=[];this.tagIndex=[];this.indexBuilt=!1;this.vaultListeners=[];this.scope=null;this.onInput=()=>{let f=this.detectTrigger();if(!f){this.close();return}this.openFor(f)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=f=>{f.key==="Escape"&&(!this.state||!this.items.length||(f.preventDefault(),f.stopPropagation(),f.stopImmediatePropagation(),this.close()))};this.onKeyDown=f=>{!this.state||!this.items.length||(f.key==="ArrowDown"?(f.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive()):f.key==="ArrowUp"?(f.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive()):f.key==="Enter"||f.key==="Tab"?(f.preventDefault(),f.stopPropagation(),this.commit()):f.key==="Escape"&&(f.preventDefault(),f.stopPropagation(),f.stopImmediatePropagation(),this.close()))}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let f=this.ta.ownerDocument??document;f.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>f.removeEventListener("keydown",this.onDocEscape,!0)),this.buildIndex();let t=()=>{this.indexBuilt=!1},e=this.app.vault;e.on("create",t),e.on("delete",t),e.on("rename",t),this.vaultListeners.push(()=>e.off("create",t),()=>e.off("delete",t),()=>e.off("rename",t))}isOpen(){return!!this.state&&this.items.length>0}detach(){this.close(),this.ta.removeEventListener("input",this.onInput),this.ta.removeEventListener("keydown",this.onKeyDown,!0),this.ta.removeEventListener("blur",this.onBlur);for(let f of this.vaultListeners)f();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;this.fileIndex=this.app.vault.getFiles().filter(t=>t.extension!=="edtz").map(t=>{let e=t.extension==="md",s=e?t.basename:t.name,i=e?t.basename:t.name;return{label:s,lower:s.toLowerCase(),insertText:i,file:t}});let f=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(f).sort((t,e)=>(f[e]||0)-(f[t]||0)),this.indexBuilt=!0}detectTrigger(){let f=this.ta.value,t=this.ta.selectionStart;if(t==null)return null;let e=f.slice(0,t),s=e.match(/\[\[([^\]\[\n]*)$/);if(s){let n=s[1];return{kind:"link",query:n,replaceStart:t-n.length-2,replaceEnd:t}}let i=e.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(i){let n=i[2];return{kind:"tag",query:n,replaceStart:t-n.length-1,replaceEnd:t}}return null}buildItems(f){this.buildIndex();let t=f.query.toLowerCase().trim(),e=t?t.split(/\s+/).filter(Boolean):[],s=i=>{if(!e.length)return!0;for(let n of e)if(!i.includes(n))return!1;return!0};return f.kind==="link"?this.fileIndex.filter(n=>s(n.lower)).slice(0,50).map(n=>({label:n.label,insert:`[[${n.insertText}]]`,subtitle:n.file.path})):this.tagIndex.filter(n=>s(n.toLowerCase())).slice(0,30).map(n=>({label:n,insert:n,subtitle:""}))}openFor(f){if(this.state=f,this.items=this.buildItems(f),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let f=new $s.Scope(this.app.scope);f.register([],"Escape",t=>(t.preventDefault(),this.close(),!1)),this.scope=f,this.app.keymap?.pushScope(f)}popScope(){if(this.scope){try{this.app.keymap?.popScope(this.scope)}catch{}this.scope=null}}renderPopup(){if(!this.popupEl){let t=this.ta.ownerDocument??document;this.popupEl=t.body.createDiv({cls:"stashpad-composer-suggest"}),this.popupEl.tabIndex=-1,this.popupEl.addEventListener("mousedown",e=>e.preventDefault())}let f=this.popupEl;f.empty();for(let t=0;t<this.items.length;t++){let e=this.items[t],s=f.createDiv({cls:"stashpad-composer-suggest-row"});t===this.activeIdx&&s.addClass("is-active"),s.createSpan({cls:"stashpad-composer-suggest-label",text:e.label}),e.subtitle&&s.createSpan({cls:"stashpad-composer-suggest-sub",text:e.subtitle}),s.onmousedown=i=>{i.preventDefault(),this.activeIdx=t,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let f=this.popupEl.children;for(let e=0;e<f.length;e++)f[e].toggleClass("is-active",e===this.activeIdx);let t=f[this.activeIdx];t&&t.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let f=this.ta.getBoundingClientRect(),t=this.popupEl.offsetHeight||200,e=f.top-t-4,s=f.left;this.popupEl.style.left=`${Math.max(8,s)}px`,this.popupEl.style.top=`${Math.max(8,e)}px`,this.popupEl.style.minWidth=`${Math.min(360,f.width)}px`}commit(){if(!this.state||!this.items.length)return;let f=this.items[this.activeIdx];if(!f)return;let t=this.ta.value.slice(0,this.state.replaceStart),e=this.ta.value.slice(this.state.replaceEnd),s=f.insert;this.ta.value=t+s+e;let i=t.length+s.length;this.ta.setSelectionRange(i,i),this.ta.dispatchEvent(new Event("input",{bubbles:!0})),this.close(),this.ta.focus()}close(){this.popupEl&&(this.popupEl.remove(),this.popupEl=null),this.state=null,this.items=[],this.activeIdx=0,this.popScope()}};Ct();var De=class extends St.ItemView{constructor(t,e){super(t);this.plugin=e;this.displayedPath=null;this.unsubscribeSelection=null;this.renderTimer=null;this.expanded=new Set;this.composerAutocomplete=null;this.composerInputEl=null;this.composerDraft="";this.composerDraftForId=null;this.displayedId=null;this.unsubscribeContent=null}getViewType(){return Ht}getDisplayText(){return"Stashpad detail"}getIcon(){return"panel-right"}async onOpen(){this.render(),this.unsubscribeSelection=this.plugin.onStashpadSelectionChange(()=>{this.displayedId=null,this.scheduleRender()}),this.unsubscribeContent=this.plugin.onStashpadContentChange(()=>this.scheduleRender()),this.registerEvent(this.app.workspace.on("active-leaf-change",t=>{!t||t===this.leaf||t.view?.getViewType?.()===mt&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("modify",t=>{this.displayedPath&&t.path===this.displayedPath&&this.scheduleRender()})),this.registerEvent(this.app.metadataCache.on("changed",t=>{this.displayedPath&&t.path===this.displayedPath&&this.scheduleRender()}))}async onClose(){this.unsubscribeSelection?.(),this.unsubscribeSelection=null,this.unsubscribeContent?.(),this.unsubscribeContent=null,this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,this.renderTimer!=null&&(window.clearTimeout(this.renderTimer),this.renderTimer=null)}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},60))}resolveDisplayed(){if(this.displayedId){let e=this.plugin.lastActiveStashpadLeaf?.view;if(e?.getViewType?.()===mt&&e.tree?.get){let s=e.tree.get(this.displayedId);if(s?.file)return{folder:e.noteFolder,id:this.displayedId,file:s.file}}this.displayedId=null}let t=this.plugin.getActiveStashpadSelection();return t&&(this.displayedId=t.id),t}async render(){let t=this.contentEl,e=!!this.composerInputEl&&document.activeElement===this.composerInputEl,s=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let i=this.resolveDisplayed();if(!i){this.displayedPath=null;let d=t.createDiv({cls:"stashpad-detail-empty"});(0,St.setIcon)(d.createSpan({cls:"stashpad-detail-empty-icon"}),"panel-right"),d.createSpan({cls:"stashpad-detail-empty-text",text:"No Stashpad note selected. Cursor or click a note in a Stashpad list to inspect it here."});return}let n=i.file;this.displayedPath=n.path;let r=this.app.metadataCache.getFileCache(n)?.frontmatter??{},o=t.createDiv({cls:"stashpad-detail-scroll"}),a=o.createDiv({cls:"stashpad-detail-header"}),l=a.createDiv({cls:"stashpad-detail-titlerow"});l.createDiv({cls:"stashpad-detail-title",text:this.titleFor(n)});let c=l.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,St.setIcon)(c,"arrow-up-right"),c.title="Open this note in a new Stashpad tab",c.onclick=()=>{this.openInStashpad(i.folder,i.id)};let h=a.createDiv({cls:"stashpad-detail-metarow"});if(i.folder&&h.createSpan({cls:"stashpad-detail-meta-chip",text:i.folder.split("/").pop()||i.folder}),typeof r.color=="string"&&r.color){let d=h.createSpan({cls:"stashpad-detail-meta-color"});d.style.background=r.color,d.title=r.color}if(r.completed===!0&&h.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof r.due=="string"||typeof r.due=="number"){let d=Date.parse(String(r.due)),p=Number.isNaN(d)?String(r.due):Wt(d,this.plugin.settings);h.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${p}`})}if(Array.isArray(r.tags))for(let d of r.tags.filter(p=>typeof p=="string"))h.createSpan({cls:"stashpad-detail-meta-tag",text:`#${d.replace(/^#/,"")}`});let u=o.createDiv({cls:"stashpad-detail-body"});try{let d=await this.app.vault.cachedRead(n),p=this.stripFrontmatter(d);await St.MarkdownRenderer.render(this.app,p,u,n.path,this)}catch(d){u.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${n.path}\`: ${d.message}`})}if(this.renderFooterMeta(o,n,r,i),this.renderChildren(o,i.folder,i.id),this.renderComposer(t,i),e&&this.composerInputEl&&(this.composerInputEl.focus(),s!=null)){let d=Math.min(s,this.composerInputEl.value.length);try{this.composerInputEl.setSelectionRange(d,d)}catch{}}}renderComposer(t,e){let s=t.createDiv({cls:"stashpad-detail-composer"}),i=s.createEl("textarea",{cls:"stashpad-detail-composer-input",attr:{placeholder:"Add a child note\u2026",rows:"2"}});this.composerInputEl=i,this.composerDraftForId===e.id?i.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=e.id),i.addEventListener("input",()=>{this.composerDraft=i.value,this.composerDraftForId=e.id}),i.addEventListener("keydown",r=>{if(r.key==="Enter"&&!r.shiftKey&&!r.isComposing){if(this.composerAutocomplete?.isOpen?.())return;r.preventDefault(),this.submitComposer(e)}});let n=s.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,St.setIcon)(n.createSpan({cls:"stashpad-detail-composer-send-icon"}),"plus"),n.createSpan({cls:"stashpad-detail-composer-send-text",text:"Add child note"}),n.title="Add child note (Enter)",n.onclick=()=>void this.submitComposer(e),this.composerAutocomplete=new Jt(this.app,i),this.composerAutocomplete.attach()}async submitComposer(t){let e=(this.composerInputEl?.value??"").trim();if(!e)return;let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==mt||typeof s.createNoteUnder!="function"){new St.Notice("Open a Stashpad view to add notes.");return}try{await s.createNoteUnder(e,t.id)}catch(i){new St.Notice(`Couldn't add note: ${i.message}`);return}this.composerDraft="",this.composerDraftForId=t.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(t,e,s){let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==mt)return;let n=i.tree;if(!n?.getChildren)return;let r=n.getChildren(s);if(!r||r.length===0)return;let o=t.createDiv({cls:"stashpad-detail-children"});o.createDiv({cls:"stashpad-detail-children-header",text:`Children (${r.length})`});let a=o.createDiv({cls:"stashpad-detail-children-list"});for(let l of r)l.file&&this.renderDetailChildRow(a,i,n,e,l,0)}renderDetailChildRow(t,e,s,i,n,r){if(!n.file)return;let o=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},a=typeof o.color=="string"?o.color:null,l=o.completed===!0,c=s.getChildren(n.id),h=c.length>0,u=`${i}|${n.id}`,d=this.expanded.has(u),p=t.createDiv({cls:"stashpad-detail-child-row"});l&&p.addClass("is-completed"),r>0&&(p.style.paddingLeft=`${r*16}px`),p.draggable=!0,p.dataset.id=n.id,p.addEventListener("dragstart",k=>{k.dataTransfer?.setData("text/plain",n.id),k.dataTransfer&&(k.dataTransfer.effectAllowed="move"),p.addClass("is-dragging")}),p.addEventListener("dragend",()=>p.removeClass("is-dragging")),p.addEventListener("dragover",k=>{k.preventDefault(),k.dataTransfer&&(k.dataTransfer.dropEffect="move");let C=p.getBoundingClientRect(),E=k.clientY-C.top<C.height/2;p.toggleClass("drop-before",E),p.toggleClass("drop-after",!E)}),p.addEventListener("dragleave",()=>{p.removeClass("drop-before"),p.removeClass("drop-after")}),p.addEventListener("drop",k=>{k.preventDefault(),p.removeClass("drop-before"),p.removeClass("drop-after");let C=k.dataTransfer?.getData("text/plain");if(!C||C===n.id)return;let E=p.getBoundingClientRect(),I=k.clientY-E.top<E.height/2;typeof e.reorderToTarget=="function"&&e.reorderToTarget([C],n.id,I?"before":"after")}),p.oncontextmenu=k=>{k.preventDefault();let C=s.get(n.id);C&&typeof e.openNoteMenu=="function"&&e.openNoteMenu(k,C)};let m=p.createSpan({cls:"stashpad-detail-child-toggle"});if(h&&(Ee(m,c.length,d),m.onclick=k=>{k.stopPropagation(),this.expanded.has(u)?this.expanded.delete(u):this.expanded.add(u),this.render()}),zt(o,"task")||o.task===!0||o.completed!==void 0){let k=p.createSpan({cls:"stashpad-detail-child-checkbox"});(0,St.setIcon)(k,l?"check-square":"square"),k.title=l?"Mark not done":"Mark done",k.addEventListener("mousedown",C=>C.stopPropagation()),k.addEventListener("dblclick",C=>{C.preventDefault(),C.stopPropagation()}),k.onclick=C=>{C.preventDefault(),C.stopPropagation();let E=s.get(n.id);E&&typeof e.toggleCompletedForNode=="function"&&e.toggleCompletedForNode(E)}}let y=p.createSpan({cls:"stashpad-detail-child-icon"});(0,St.setIcon)(y,h?"folder-tree":"file-text"),a&&(y.style.color=a);let b=p.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(b.onclick=()=>{e?.navigateTo&&e.navigateTo(n.id)},h&&d)for(let k of c)this.renderDetailChildRow(t,e,s,i,k,r+1)}renderFooterMeta(t,e,s,i){let n=t.createDiv({cls:"stashpad-detail-footer-meta"}),r=[];if(typeof s.author=="string"&&s.author&&r.push({label:"Author",value:this.stripWikiLink(s.author)}),Array.isArray(s.contributors)){let o=s.contributors.filter(a=>typeof a=="string").map(a=>this.stripWikiLink(a));o.length>0&&r.push({label:"Contributors",value:o.join(", ")})}if(typeof s.modified=="string"&&r.push({label:"Modified",value:this.formatTime(s.modified)}),typeof s.created=="string"&&r.push({label:"Created",value:this.formatTime(s.created)}),r.push({label:"Path",value:e.path}),r.push({label:"ID",value:i.id}),r.length===0){n.remove();return}for(let o of r){let a=n.createDiv({cls:"stashpad-detail-meta-line"});a.createSpan({cls:"stashpad-detail-meta-key",text:o.label}),a.createSpan({cls:"stashpad-detail-meta-val",text:o.value})}}titleFor(t){return t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")}stripFrontmatter(t){if(!t.startsWith("---"))return t;let e=t.indexOf(` +---`,3);return e<0?t:t.slice(e+4).replace(/^\n+/,"")}stripWikiLink(t){let e=t.match(/^\[\[(.+?)(?:\|(.+))?\]\]$/);return e?e[2]??(e[1].split("/").pop()??e[1]).replace(/\.md$/,""):t}formatTime(t){let e=Date.parse(t);return Number.isFinite(e)?Wt(e,this.plugin.settings):t}async openInStashpad(t,e){try{await this.plugin.activateViewForFolder(t);let s=this.plugin.lastActiveStashpadLeaf?.view;s?.navigateTo&&e!==R&&s.navigateTo(e)}catch(s){new St.Notice(`Couldn't open: ${s.message}`)}}};async function Pe(g){let f=g.workspace.getLeavesOfType(Ht);if(f.length>0){g.workspace.revealLeaf(f[0]);return}let t=g.workspace.getRightLeaf(!1);if(!t){new St.Notice("Stashpad: couldn't open the detail panel.");return}await t.setViewState({type:Ht,active:!0}),g.workspace.revealLeaf(t)}var N=require("obsidian");Ct();var Lt=require("obsidian");Ct();function bi(g,f){let t=g.vault.getAbstractFileByPath(f);if(!(t instanceof Lt.TFolder))return[];let e=[],s=[t];for(;s.length;){let i=s.pop();for(let n of i.children)n instanceof Lt.TFile?n.extension==="md"&&e.push(n):n instanceof Lt.TFolder&&s.push(n)}return e}var Me=class{constructor(f){this.app=f;this.nodes=new Map;this.byPath=new Map;this.listeners=new Set;this.orderProvider=null;this.synthetic=new Map;this.coalesceTimer=null;this.nodes.set(R,{id:R,parent:null,children:[],file:null,created:""})}setOrderProvider(f){this.orderProvider=f}onChange(f){return this.listeners.add(f),()=>this.listeners.delete(f)}emit(){for(let f of this.listeners)f()}rebuild(f){f!==void 0&&(this.currentFolder=f);let t=this.currentFolder,e=this.byPath,s=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(R,{id:R,parent:null,children:[],file:null,created:""});let i=t?bi(this.app,t):this.app.vault.getMarkdownFiles();for(let n of i){let r=this.app.metadataCache.getFileCache(n)?.frontmatter,o=r?.id;if(!o){let l=e.get(n.path),c=l?s.get(l):void 0,h=this.synthetic.get(n.path),u=c??h;u&&(this.nodes.set(u.id,{...u,children:[],file:n}),this.byPath.set(n.path,u.id));continue}if(this.synthetic.delete(n.path),o===R){let l=this.nodes.get(R);l.file=n,l.created=r?.created??"",this.byPath.set(n.path,R);continue}let a=r?.parent??null;this.nodes.set(o,{id:o,parent:a??R,children:[],file:n,created:r?.created??""}),this.byPath.set(n.path,o)}for(let n of this.nodes.values()){if(n.id===R)continue;let r=n.parent??R;(this.nodes.get(r)??this.nodes.get(R)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((r,o)=>{let a=this.nodes.get(r),l=this.nodes.get(o);return(a.created||"").localeCompare(l.created||"")}),this.orderProvider){let r=this.orderProvider(n.id);if(r.length>0){let o=new Map;r.forEach((a,l)=>o.set(a,l)),n.children.sort((a,l)=>{let c=o.has(a)?o.get(a):1/0,h=o.has(l)?o.get(l):1/0;return c===h?0:c-h})}}this.emit()}insertSynthetic(f){if(!f.file)return;let t=f.file.path;this.synthetic.set(t,f),this.nodes.set(f.id,f),this.byPath.set(t,f.id);let e=f.parent??R,s=this.nodes.get(e);s&&!s.children.includes(f.id)&&s.children.push(f.id),this.emit()}get(f){return this.nodes.get(f)}getRoot(){return this.nodes.get(R)}getChildren(f){let t=this.nodes.get(f);return t?t.children.map(e=>this.nodes.get(e)).filter(e=>!!e):[]}fileBackedCount(){let f=0;for(let t of this.nodes.values())t.file&&f++;return f}pathTo(f){let t=[],e=this.nodes.get(f);for(;e&&e.id!==R;)t.unshift(e),e=e.parent?this.nodes.get(e.parent):void 0;return t}idForPath(f){return this.byPath.get(f)}snapshot(){let f={};for(let t of this.nodes.values())t.id===R||!t.file||(f[t.id]={parent:t.parent===R?null:t.parent,path:t.file.path});return f}hookMetadataCache(f){let t=a=>{let l=this.currentFolder;return l?typeof a!="string"?!1:a===l||a.startsWith(l+"/"):!0},e=!1,s=()=>{e=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,e&&(e=!1,this.emit(),f())},16))},i=a=>{a instanceof Lt.TFile&&t(a.path)&&a.extension==="md"&&this.applyChange(a)&&s()},n=a=>{a instanceof Lt.TFile&&t(a.path)&&a.extension==="md"&&this.applyChange(a)&&s()},r=a=>{let l=a?.path;typeof l=="string"&&t(l)&&this.applyDelete(l)&&s()},o=(a,l)=>{if(!(a instanceof Lt.TFile))return;let c=typeof l=="string"?l:null;!t(a.path)&&!t(c)||this.applyRename(a,c??"")&&s()};return this.app.metadataCache.on("changed",i),this.app.vault.on("create",n),this.app.vault.on("delete",r),this.app.vault.on("rename",o),()=>{this.app.metadataCache.off("changed",i),this.app.vault.off("create",n),this.app.vault.off("delete",r),this.app.vault.off("rename",o),this.coalesceTimer!=null&&(window.clearTimeout(this.coalesceTimer),this.coalesceTimer=null)}}applyChange(f){let t=this.app.metadataCache.getFileCache(f)?.frontmatter,e=t?.id,s=this.byPath.get(f.path);if(!e){if(s){let l=this.nodes.get(s);if(l&&l.file!==f)return l.file=f,!0}return!1}if(this.synthetic.delete(f.path),e===R){let l=this.nodes.get(R),c=t?.created??"",h=!1;return l.file!==f&&(l.file=f,h=!0),l.created!==c&&(l.created=c,h=!0),this.byPath.get(f.path)!==R&&(this.byPath.set(f.path,R),h=!0),h}let i=t?.parent??R,n=t?.created??"";if(!(i===R||this.nodes.has(i)))return this.rebuild(),!0;if(s&&s!==e)return this.rebuild(),!0;let o=this.nodes.get(e);if(!o){let l={id:e,parent:i,children:[],file:f,created:n};return this.nodes.set(e,l),this.byPath.set(f.path,e),this.attachToParent(l),this.resortChildrenOf(i),!0}let a=!1;if(o.file!==f&&(o.file=f,a=!0),o.created!==n&&(o.created=n,this.resortChildrenOf(o.parent??R),a=!0),o.parent!==i){let l=o.parent??R;this.detachFromParent(o),o.parent=i,this.attachToParent(o),this.resortChildrenOf(l),this.resortChildrenOf(i),a=!0}return a}applyDelete(f){let t=this.byPath.get(f);if(!t)return!1;let e=this.nodes.get(t);if(!e)return this.byPath.delete(f),this.synthetic.delete(f),!0;this.detachFromParent(e);let s=this.nodes.get(R);for(let i of e.children){let n=this.nodes.get(i);n&&(n.parent=R,s.children.includes(i)||s.children.push(i))}return e.children.length>0&&this.resortChildrenOf(R),this.nodes.delete(t),this.byPath.delete(f),this.synthetic.delete(f),!0}applyRename(f,t){let e=this.currentFolder,s=!e||t===e||t.startsWith(e+"/"),i=!e||f.path===e||f.path.startsWith(e+"/");if(!s&&!i)return!1;if(s&&!i)return this.applyDelete(t);if(!s&&i)return this.applyChange(f);let n=this.byPath.get(t);if(!n)return this.applyChange(f);this.byPath.delete(t),this.byPath.set(f.path,n);let r=this.nodes.get(n);return r&&(r.file=f),!0}detachFromParent(f){let t=this.nodes.get(f.parent??R);if(!t)return;let e=t.children.indexOf(f.id);e>=0&&t.children.splice(e,1)}attachToParent(f){let t=this.nodes.get(f.parent??R);t||(t=this.nodes.get(R)),t.children.includes(f.id)||t.children.push(f.id)}resortChildrenOf(f){let t=this.nodes.get(f);if(t&&(t.children.sort((e,s)=>{let i=this.nodes.get(e),n=this.nodes.get(s);return(i.created||"").localeCompare(n.created||"")}),this.orderProvider)){let e=this.orderProvider(f);if(e.length>0){let s=new Map;e.forEach((i,n)=>s.set(i,n)),t.children.sort((i,n)=>{let r=s.has(i)?s.get(i):1/0,o=s.has(n)?s.get(n):1/0;return r===o?0:r-o})}}}};var Rs=".stashpad-order.json",_e=class{constructor(f){this.app=f;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(f){if(this.cache.has(f))return this.cache.get(f);let t=`${f}/${Rs}`,e=this.app.vault.adapter,s={};try{if(await e.exists(t)){let i=await e.read(t),n=JSON.parse(i);if(n&&typeof n=="object"&&!Array.isArray(n))for(let[r,o]of Object.entries(n))Array.isArray(o)&&o.every(a=>typeof a=="string")&&(s[r]=o)}}catch(i){console.warn("Stashpad: order load failed",i)}return this.cache.set(f,s),s}async save(f){this.scheduleWrite(f)}async flush(f){let t=this.pendingTimers.get(f);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(f)),await this.writeNow(f)}scheduleWrite(f){let t=this.pendingTimers.get(f);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(f),this.writeNow(f)},150);this.pendingTimers.set(f,e)}async writeNow(f){let e=(this.writeInFlight.get(f)??Promise.resolve()).then(()=>this.doWrite(f));this.writeInFlight.set(f,e);try{await e}finally{this.writeInFlight.get(f)===e&&this.writeInFlight.delete(f)}}async doWrite(f){let t=this.cache.get(f)??{},e={};for(let[n,r]of Object.entries(t))r.length>0&&(e[n]=r);this.cache.set(f,e);let s=`${f}/${Rs}`,i=this.app.vault.adapter;try{if(Object.keys(e).length===0)try{await i.remove(s)}catch{}else await i.write(s,JSON.stringify(e,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(f,t){return this.cache.get(f)?.[t]?.slice()??[]}setOrder(f,t,e){let s=this.cache.get(f)??{};s[t]=e.slice(),this.cache.set(f,s)}appendChild(f,t,e){let s=this.cache.get(f)??{},i=s[t]??[];i.includes(e)||i.push(e),s[t]=i,this.cache.set(f,s)}removeChild(f,t){let e=this.cache.get(f);if(e)for(let s of Object.values(e)){let i=s.indexOf(t);i>=0&&s.splice(i,1)}}invalidate(f){this.cache.delete(f)}};var pe={manual:"Manual","created-asc":"Created \u2014 oldest first","created-desc":"Created \u2014 newest first","modified-asc":"Modified \u2014 oldest first","modified-desc":"Modified \u2014 newest first","title-az":"Title \u2014 A\u2192Z","title-za":"Title \u2014 Z\u2192A"},us=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],Si=new Set(us),Bs=".stashpad-sort.json",Le=class{constructor(f){this.app=f;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(f){if(this.cache.has(f))return this.cache.get(f);let t=`${f}/${Bs}`,e=this.app.vault.adapter,s={};try{if(await e.exists(t)){let i=JSON.parse(await e.read(t));if(i&&typeof i=="object"&&!Array.isArray(i))for(let[n,r]of Object.entries(i))typeof r=="string"&&Si.has(r)&&(s[n]=r)}}catch(i){console.warn("Stashpad: sort load failed",i)}return this.cache.set(f,s),s}async save(f){this.scheduleWrite(f)}async flush(f){let t=this.pendingTimers.get(f);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(f)),await this.writeNow(f)}scheduleWrite(f){let t=this.pendingTimers.get(f);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(f),this.writeNow(f)},150);this.pendingTimers.set(f,e)}async writeNow(f){let e=(this.writeInFlight.get(f)??Promise.resolve()).then(()=>this.doWrite(f));this.writeInFlight.set(f,e);try{await e}finally{this.writeInFlight.get(f)===e&&this.writeInFlight.delete(f)}}async doWrite(f){let t=this.cache.get(f)??{},e=`${f}/${Bs}`,s=this.app.vault.adapter;try{if(Object.keys(t).length===0)try{await s.remove(e)}catch{}else await s.write(e,JSON.stringify(t,null,2))}catch(i){console.warn("Stashpad: sort save failed",i)}}getMode(f,t){return this.cache.get(f)?.[t]??"manual"}setMode(f,t,e){let s=this.cache.get(f)??{};e==="manual"?delete s[t]:s[t]=e,this.cache.set(f,s)}removeParent(f,t){let e=this.cache.get(f);e&&delete e[t]}invalidate(f){this.cache.delete(f)}};Ct();var Nt="parentLink",Xt="children";var $e=class $e{constructor(f,t){this.app=f;this.getTree=t;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.errorListeners=new Set}onActivity(f){return this.activityListeners.add(f),()=>this.activityListeners.delete(f)}emitActivity(){let f=this.pending.size;for(let t of this.activityListeners)try{t(f)}catch(e){console.warn("[Stashpad] fmSync activity listener failed",e)}}schedule(f){if(!f)return;let t=this.pending.size;this.pending.add(f),this.pending.size!==t&&this.emitActivity(),this.kick()}scheduleParentChange(f,t,e){this.schedule(f),t&&this.schedule(t),this.schedule(e)}scheduleSubtree(f){let t=this.getTree(),e=s=>{this.schedule(s);for(let i of t.getChildren(s))e(i.id)};e(f)}scheduleParentOfDeleted(f){f&&this.schedule(f)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let f=this.pending.values().next().value;if(f===void 0)break;this.pending.delete(f),this.emitActivity(),await this.syncOne(f)}}pendingCount(){return this.pending.size}onError(f){return this.errorListeners.add(f),()=>this.errorListeners.delete(f)}emitError(f,t){for(let e of this.errorListeners)try{e(f,t)}catch(s){console.warn("[Stashpad] fmSync error listener failed",s)}}reset(){this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null),this.pending.clear()}kick(){this.timer!=null||this.pending.size===0||(this.timer=window.setTimeout(()=>this.tick(),$e.PACING_MS))}async tick(){this.timer=null;let f=this.pending.values().next().value;if(f!==void 0){this.pending.delete(f),this.emitActivity();try{await this.syncOne(f)}catch(t){console.warn("[Stashpad] frontmatter sync tick failed",t)}this.pending.size>0&&this.kick()}}wouldWrite(f){let e=this.getTree().get(f);if(!e||!e.file)return!1;let s=this.computeParentLink(e),i=this.computeChildrenLinks(e),n=this.app.metadataCache.getFileCache(e.file)?.frontmatter,r=n&&typeof n[Nt]=="string"?n[Nt]:null,o=n?.[Xt],a=Array.isArray(o)?o.filter(l=>typeof l=="string"):[];if((r??null)!==(s??null)||a.length!==i.length)return!0;for(let l=0;l<a.length;l++)if(a[l]!==i[l])return!0;return!1}async syncOne(f){let e=this.getTree().get(f);if(!e||!e.file||!this.wouldWrite(f))return;let s=this.computeParentLink(e),i=this.computeChildrenLinks(e);try{await this.app.fileManager.processFrontMatter(e.file,n=>{s?n[Nt]=s:delete n[Nt],i.length>0?n[Xt]=i:delete n[Xt]})}catch(n){console.warn("[Stashpad] frontmatter sync failed",e.file?.path,n),this.emitError(e.file.path,n)}}computeParentLink(f){if(f.id===R)return null;let t=this.getTree();if(!f.parent||f.parent===R){let s=t.getRoot();return s&&s.id!==f.id&&s.file?Ne(s.file.path):null}let e=t.get(f.parent);return e?.file?Ne(e.file.path):null}computeChildrenLinks(f){return this.getTree().getChildren(f.id).filter(e=>!!e.file).map(e=>Ne(e.file.path))}};$e.PACING_MS=100;var Oe=$e;async function Hs(g,f){let t=f.endsWith("/")?f:f+"/",e=new Map,s=new Map;for(let l of g.vault.getMarkdownFiles()){if(l.path!==f&&!l.path.startsWith(t))continue;let c=g.metadataCache.getFileCache(l)?.frontmatter,h=typeof c?.id=="string"?c.id:null;if(!h)continue;let u=typeof c?.parent=="string"?c.parent:R;e.set(h,{file:l,id:h,parent:u});let d=s.get(u)??[];d.push(h),s.set(u,d)}let i=l=>Ne(l.file.path),n=l=>{if(l.id===R)return null;if(l.parent===R||!l.parent){let h=e.get(R);return h?i(h):null}let c=e.get(l.parent);return c?i(c):null},r=l=>{let c=s.get(l.id)??[],h=[];for(let u of c){let d=e.get(u);d&&h.push(i(d))}return h},o=0,a=0;for(let l of e.values()){o+=1;let c=n(l),h=r(l),u=g.metadataCache.getFileCache(l.file)?.frontmatter,d=u&&typeof u[Nt]=="string"?u[Nt]:null,p=u?.[Xt],m=Array.isArray(p)?p.filter(b=>typeof b=="string"):[],v=(d??null)===(c??null),y=m.length===h.length&&m.every((b,k)=>b===h[k]);if(!(v&&y))try{await g.fileManager.processFrontMatter(l.file,b=>{c?b[Nt]=c:delete b[Nt],h.length>0?b[Xt]=h:delete b[Xt]}),a+=1,await new Promise(b=>setTimeout(b,50))}catch(b){console.warn("[Stashpad] rebootstrap fm sync failed",l.file.path,b)}}return{checked:o,written:a}}function Ne(g){return`[[${g.replace(/\.md$/i,"")}]]`}var Be=require("obsidian"),fs={create:{label:"Create",desc:"Confirmations after a new note is created."},edit:{label:"Edit",desc:"Edit-related toasts (currently rare)."},delete:{label:"Delete",desc:"Confirmations after deleting one or more notes."},move:{label:"Move",desc:"After reparenting or moving notes between folders."},merge:{label:"Merge",desc:"After combining multiple notes into one."},split:{label:"Split",desc:"After splitting a note in two."},clone:{label:"Clone",desc:"After duplicating notes or subtrees."},complete:{label:"Complete",desc:"When a note is marked complete."},uncomplete:{label:"Uncomplete",desc:"When a note's complete mark is removed."},export:{label:"Export",desc:".stash exports \u2014 success + the action buttons."},import:{label:"Import",desc:".stash imports (both manual and the drop-folder auto-import)."},attachment:{label:"Attachment",desc:"Attachment add / remove notifications."},color:{label:"Color",desc:"Per-note color changes."},reorder:{label:"Reorder",desc:"Drag-reorder and keyboard moveUp/Down/Top/Bottom."},multiplayer:{label:"Multiplayer",desc:"Cross-author activity (someone else touched your notes or vice versa)."},system:{label:"System",desc:"Plumbing toasts: backfill progress, integrity warnings, errors not tied to a verb."}},ki={info:4e3,success:4e3,warning:6e3,error:1e4},zs=5e3,Re=class{constructor(f){this.app=f;this.history=[];this.nextId=1;this.historyLimit=zs;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(f){this.defaultAuthorId=f||null}show(f){let t=f.kind??"info",e=f.category??"system",s={id:this.nextId++,ts:Date.now(),message:f.message,kind:t,category:e,authorId:f.authorId??this.defaultAuthorId??void 0,affectedIds:f.affectedIds?f.affectedIds.slice():[],affectedPaths:f.affectedPaths?f.affectedPaths.slice():[],affectedAuthorIds:f.affectedAuthorIds?f.affectedAuthorIds.slice():[],folder:f.folder,actionLabels:(f.actions??[]).map(r=>r.label)};if(this.pushHistory(s),this.muted.has(e))return null;let i=this.buildContent(f,t),n=f.duration??ki[t];return new Be.Notice(i,n)}onChange(f){return this.changeListeners.add(f),()=>this.changeListeners.delete(f)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(f,t){t?this.muted.add(f):this.muted.delete(f)}isMuted(f){return this.muted.has(f)}loadMutedFromList(f){this.muted=new Set(f)}mutedList(){return Array.from(this.muted)}loadHistory(f){let t=this.applyLimit(f.slice());this.history=t;let e=0;for(let s of t)s.id>e&&(e=s.id);this.nextId=Math.max(this.nextId,e+1),this.emit()}setHistoryLimit(f){this.historyLimit=Number.isFinite(f)?f:zs,this.history=this.applyLimit(this.history),this.emit()}applyLimit(f){return this.historyLimit<=0||f.length<=this.historyLimit?f:f.slice(f.length-this.historyLimit)}pushHistory(f){this.history.push(f),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let f of this.changeListeners)try{f()}catch(t){console.warn("[Stashpad] notification listener failed",t)}}buildContent(f,t){let e=document.createDocumentFragment(),s=document.createElement("div");s.className=`stashpad-notice stashpad-notice-${t}`;let i=document.createElement("div");i.className="stashpad-notice-message";let n=f.message.split(/(`[^`\n]+`)/);for(let r of n)if(r.length>1&&r.startsWith("`")&&r.endsWith("`")){let o=document.createElement("code");o.textContent=r.slice(1,-1),i.appendChild(o)}else r.length>0&&i.appendChild(document.createTextNode(r));if(s.appendChild(i),f.actions&&f.actions.length>0){let r=document.createElement("div");r.className="stashpad-notice-actions";for(let o of f.actions){let a=document.createElement("button");a.className="stashpad-notice-action",a.textContent=o.label,a.addEventListener("click",l=>{if(l.stopPropagation(),Promise.resolve().then(()=>o.onClick()).catch(c=>console.warn("[Stashpad] notification action failed",c)),!o.keepOpen){let c=a.closest(".notice");c&&c.parentElement&&c.parentElement.removeChild(c)}}),r.appendChild(a)}s.appendChild(r)}return e.appendChild(s),e}};function He(g,f,t){let e=g.vault.getAbstractFileByPath(f);if(!(e instanceof Be.TFile))return[];let s=[{label:"Reveal",keepOpen:!0,onClick:()=>{let i=g.workspace.getLeavesOfType("file-explorer")[0];if(!i)return;g.workspace.revealLeaf(i),i.view?.revealInFolder?.(e)}}];return t||s.push({label:"Show in Finder",keepOpen:!0,onClick:()=>{try{let i=window.require?.("electron")?.shell,r=g.vault.adapter?.getFullPath?.(f);r&&i?.showItemInFolder&&i.showItemInFolder(r)}catch(i){console.warn("[Stashpad] showItemInFolder failed",i)}}}),s}Ot();ue();var We=class{constructor(f,t){this.tree=f;this.log=t}async sweep(f){let t=await this.log.readState(),e=this.tree.snapshot(),s=n=>{if(!f)return!0;let r=f.replace(/\/+$/,"");return n===r||n.startsWith(r+"/")};for(let[n,r]of Object.entries(e)){let o=t[n];o?o.parent!==r.parent?await this.log.append({type:"parent_change",id:n,payload:{from:o.parent,to:r.parent}}):o.path!==r.path&&await this.log.append({type:"rename",id:n,payload:{from:o.path,to:r.path}}):await this.log.append({type:"create",id:n,payload:{path:r.path,parent:r.parent}})}for(let[n,r]of Object.entries(t))!e[n]&&s(r.path)&&await this.log.append({type:"missing",id:n,payload:{lastPath:r.path}});let i={};for(let[n,r]of Object.entries(t))s(r.path)||(i[n]=r);for(let[n,r]of Object.entries(e))i[n]=r;await this.log.writeState(i)}};var G=require("obsidian");me();var Ye=require("obsidian"),ee=class extends Ye.AbstractInputSuggest{constructor(t,e){super(t,e);this.inputEl=e}getSuggestions(t){let e=t.toLowerCase().split(/\s+/).filter(Boolean),s=r=>e.every(o=>r.toLowerCase().includes(o)),i=[],n=r=>{r.path!=="/"&&s(r.path)&&i.push(r);for(let o of r.children)o instanceof Ye.TFolder&&n(o)};return n(this.app.vault.getRoot()),i.slice(0,100)}renderSuggestion(t,e){e.setText(t.path)}selectSuggestion(t){this.setValue(t.path),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}};Ct();Gt();var ys=(()=>{try{return typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/i.test(navigator.platform||navigator.userAgent||"")}catch{return!1}})();function ws(g){if(!g)return"(none)";let f=g.replace(/\bMod\b/g,ys?"Cmd":"Ctrl");return ys&&(f=f.replace(/\bAlt\b/g,"Option")),f}function Ks(g,f,t={allowSingleKey:!0}){let e=g.placeholder,s=g.value;g.placeholder="Press a key\u2026 (Backspace to cancel)",g.value="",g.classList.add("is-recording");let i=!1,n=()=>{g.placeholder=e,g.classList.remove("is-recording"),i||(g.value=s),g.removeEventListener("keydown",r,!0),g.removeEventListener("blur",o)},r=a=>{if(a.key==="Control"||a.key==="Shift"||a.key==="Alt"||a.key==="Meta"||a.key==="OS")return;let l=!!a.code&&(/^Key[A-Z]$/.test(a.code)||/^Digit\d$/.test(a.code));if((a.key==="Dead"||a.key==="Process"||a.key==="Unidentified")&&!l)return;if(a.preventDefault(),a.stopPropagation(),a.key==="Backspace"&&!a.metaKey&&!a.ctrlKey&&!a.altKey&&!a.shiftKey){n();return}let c=[];ys?(a.metaKey&&c.push("Mod"),a.ctrlKey&&c.push("Ctrl")):a.ctrlKey&&c.push("Mod"),a.altKey&&c.push("Alt"),a.shiftKey&&c.push("Shift");let h=Ei(a.key,a.code);if(!h||c.length===0&&!t.allowSingleKey)return;c.push(h);let u=c.join("+");i=!0,n(),f(u)},o=()=>n();return g.addEventListener("keydown",r,!0),g.addEventListener("blur",o),n}function Ei(g,f){if(!g)return"";if(f){let t=/^Key([A-Z])$/.exec(f);if(t)return t[1];let e=/^Digit(\d)$/.exec(f);if(e)return e[1]}return g.length===1?g.toUpperCase():g}ue();Ot();var ge=null,Ke=new Set;function qe(g){if(ge!==g){ge=g;for(let f of Ke)f()}}function Pt(){return ge}function qs(g){if(ge===g){ge=null;for(let f of Ke)f()}}function Zs(g){return Ke.add(g),()=>Ke.delete(g)}var ve=[{id:"move",label:"Move (picker)",desc:"Open a fuzzy picker to choose the new parent.",defaultPrimary:"M"},{id:"pickMove",label:"Move (in-list)",desc:"Highlight a note in the list with arrows; Enter sets it as parent.",defaultPrimary:"O"},{id:"merge",label:"Merge",desc:"Concatenate selected notes into the oldest one.",defaultPrimary:"&"},{id:"copy",label:"Copy",desc:"Copy selected note bodies to clipboard.",defaultPrimary:"C"},{id:"copyTree",label:"Copy tree",desc:"Copy the focused note + all descendants, indented.",defaultPrimary:"Y"},{id:"openEditor",label:"Open in editor",desc:"Open the cursor row (or focused note) in a regular Obsidian markdown tab.",defaultPrimary:"E"},{id:"openTab",label:"Open in new Stashpad tab",desc:"Open the cursor row (or focused note) in a new Stashpad tab focused on it.",defaultPrimary:"T"},{id:"split",label:"Split note",desc:"Split the cursor row (or focused note) into two notes at a chosen line.",defaultPrimary:"S"},{id:"copyOutline",label:"Copy as outline",desc:"Copy selection (or cursor row) as a nested ![[embed]] outline.",defaultPrimary:"L"},{id:"toggleSplit",label:"Toggle split-on-newlines",desc:"Default: Mod+/",defaultPrimary:"Mod+/"},{id:"pickDestination",label:"Pick destination",desc:"Default: Mod+D",defaultPrimary:"Mod+D"},{id:"search",label:"Search notes",desc:"Default: Mod+F",defaultPrimary:"Mod+F"},{id:"searchInParent",label:"Search in current parent",desc:"Default: Mod+Alt+F (Mod+Shift+F is taken by Obsidian's global search).",defaultPrimary:"Mod+Alt+F"},{id:"delete",label:"Delete selection",desc:"Default: Mod+Backspace",defaultPrimary:"Mod+Backspace"},{id:"undo",label:"Undo",desc:"Default: Mod+Z (Stashpad-only \u2014 won't fire while typing in the composer).",defaultPrimary:"Mod+Z"},{id:"redo",label:"Redo",desc:"Default: Mod+Shift+Z",defaultPrimary:"Mod+Shift+Z"},{id:"toggleComplete",label:"Toggle complete (strikethrough)",desc:"Default: Mod+Enter \u2014 marks selected/focused notes as complete.",defaultPrimary:"Mod+Enter"},{id:"moveUp",label:"Move note up",desc:"Default: Mod+ArrowUp",defaultPrimary:"Mod+ArrowUp"},{id:"moveDown",label:"Move note down",desc:"Default: Mod+ArrowDown",defaultPrimary:"Mod+ArrowDown"},{id:"moveToTop",label:"Move note to top",desc:"Default: Mod+Shift+ArrowUp",defaultPrimary:"Mod+Shift+ArrowUp"},{id:"moveToBottom",label:"Move note to bottom",desc:"Default: Mod+Shift+ArrowDown",defaultPrimary:"Mod+Shift+ArrowDown"},{id:"outdent",label:"Outdent (move to grandparent)",desc:"Default: Mod+[ \u2014 re-parents the selection one level up.",defaultPrimary:"Mod+["},{id:"setColor",label:"Set note color",desc:"Default: Shift+: \u2014 open the color picker for the selection.",defaultPrimary:"Shift+:"},{id:"clone",label:"Clone (duplicate / copy) selection",desc:"Default: Mod+Shift+D \u2014 clone selected notes (with their subtrees) as siblings.",defaultPrimary:"Mod+Shift+D"},{id:"insertTemplate",label:"Insert template (clone an existing note)",desc:"Pick any note in this Stashpad; clone it (with subtree + attachments) into the current view, retimestamped.",defaultPrimary:""},{id:"toggleExpand",label:"Show more / show less (expand toggle)",desc:"Default: Shift+? \u2014 toggle the clamp on the cursor row (or every selected row).",defaultPrimary:"Shift+?"},{id:"exportStash",label:"Export selection to .stash",desc:"Export the selected subtree(s) as a .stash bundle (notes + attachments).",defaultPrimary:""},{id:"importStash",label:"Import .stash file",desc:"Open the .stash bundle picker and import its notes into this Stashpad.",defaultPrimary:""},{id:"pickFolder",label:"Open / switch / create Stashpad folder",desc:"Default: Mod+S \u2014 opens the unified folder picker (reveal, switch, create, convert).",defaultPrimary:"Mod+S"},{id:"cloneStashpadTab",label:"Clone (duplicate / copy) this Stashpad tab",desc:'Open a second tab on the same folder + focus, mirroring the "copy" button in the focused-header actions.',defaultPrimary:""},{id:"selectAll",label:"Select all notes in view",desc:"Default: Mod+A \u2014 adds every visible row to the selection.",defaultPrimary:"Mod+A"},{id:"copyCodeBlock",label:"Copy code from codeblock",desc:"Default: { \u2014 copy the contents of the cursor row's first codeblock (or pick one when multiple exist).",defaultPrimary:"{"},{id:"swapWithParent",label:"Swap with parent (ouroboros)",desc:"Promote the cursor row above its current parent; the parent slides under it (carrying its other children). No default \u2014 bind in this tab.",defaultPrimary:""},{id:"togglePin",label:"Pin / unpin selected note",desc:"Default: P \u2014 toggle the sidebar pin state of the cursor row (or focused note).",defaultPrimary:"P"},{id:"toggleTask",label:"Toggle task (todo)",desc:"Default: H \u2014 mark the selection (or cursor row) as a task / todo, or clear it. Tasks appear in the Tasks panel.",defaultPrimary:"H"},{id:"setDue",label:"Set due date\u2026",desc:"Default: D \u2014 open a date+time picker to set (or clear) the due date on the selection. Setting a due date also marks the note as a task.",defaultPrimary:"D"}];function Ss(){let g={};for(let f of ve)g[f.id]={primary:f.defaultPrimary,secondary:"",preferRight:!1};return g}var Bt={folder:"Stashpad",importDropFolder:"_imports",exportFolder:"_exports",useTemplatesFormat:!1,prefixTimestampsOnCopy:!0,splitOnLines:!1,confirmCrossParentDrag:!0,confirmBulkDelete:!0,confirmAttachmentDelete:!0,autofocusComposerAfterSend:!0,popoutDuplicates:!0,pinnedNotes:[],hideMobileToolbarInStashpad:!0,slugStopWords:[],searchIncludedFolders:[],searchExcludedFolders:[],shortcuts:{move:"M",pickMove:"O",merge:"&",copy:"C",copyTree:"Y",openEditor:"E",openTab:"T",split:"S",copyOutline:"L"},mod:{toggleSplit:"Mod+/",pickDestination:"Mod+D",search:"Mod+F",delete:"Mod+Backspace",undo:"Mod+Z",redo:"Mod+Shift+Z",toggleComplete:"Mod+Enter",moveUp:"Mod+ArrowUp",moveDown:"Mod+ArrowDown",moveToTop:"Mod+Shift+ArrowUp",moveToBottom:"Mod+Shift+ArrowDown",outdent:"Mod+[",setColor:"Shift+:"},customPalette:[],colorAliases:{},noteTemplates:{},authorName:"",authorId:"",authorRole:"",authorDepartment:"",showAuthor:!0,showContributors:!0,showLastEdit:!0,viewModes:{},includeAttachmentsInEverything:{},hideChildlessNotes:{},hideCompletedNotes:{},mutedNotificationCategories:[],notificationHistoryLimit:5e3,autoNavOnMoveIn:!1,autoNavOnMoveOut:!1,autoExpandCursorRow:!1,autoOpenDetailPanel:!1,doubleClickToFocus:!0,dateDisplayFormat:"locale",dateDisplayTimezone:"",jdIndexScope:"vault",jdIndexScopeFolder:"",jdIndexStashpadFolder:"",jdIndexFile:"Index",jdIndexIncludeStashpadFolders:!1,jdIndexSort:"natural",jdIndexHasBuilt:!1,drafts:{},lastSubmitted:{},bindings:Ss()},Gs=JSON.parse(JSON.stringify(Bt)),bs=new Set;function wt(){return Gs}function ks(g){Gs=g;for(let f of bs)f()}function Js(g){return bs.add(g),()=>bs.delete(g)}function Je(g){try{let f=g.internalPlugins?.plugins?.templates;if(!f?.enabled)return null;let t=f.instance?.options??{};return{dateFormat:t.dateFormat||"YYYY-MM-DD",timeFormat:t.timeFormat||"HH:mm"}}catch{return null}}var Ze=[{id:"general",label:"General"},{id:"diagnostics",label:"Diagnostics"},{id:"authorship",label:"Authorship"},{id:"templates",label:"Templates"},{id:"jdindex",label:"JD Index"},{id:"hotkeys",label:"Hotkeys"}],Ge=class extends G.PluginSettingTab{constructor(t,e){super(t,e);this.plugin=e;this.activeTab="general";this.searchQuery=""}openToTab(t){this.activeTab=t,this.searchQuery="",this.containerEl?.isShown?.()!==!1&&this.display()}focusSearchInput(){let t=this.containerEl?.querySelector(".stashpad-settings-search-input");t&&(t.focus(),t.setSelectionRange(t.value.length,t.value.length))}display(){let{containerEl:t}=this;t.empty(),t.addClass("stashpad-settings-tabbed"),t.createEl("h2",{text:"Stashpad",cls:"stashpad-settings-title"});let s=t.createDiv({cls:"stashpad-settings-search-wrap"}).createEl("input",{type:"text",placeholder:"Search settings\u2026",cls:"stashpad-settings-search-input"});s.value=this.searchQuery;let i=this.searchQuery.trim().length>0,n=t.createDiv({cls:"stashpad-settings-tabs"});i&&n.addClass("is-search-mode");for(let a of Ze){let l=n.createEl("button",{cls:"stashpad-settings-tab",text:a.label});!i&&this.activeTab===a.id&&l.addClass("is-active"),l.onclick=()=>{this.searchQuery="",this.activeTab=a.id,this.display()}}let r=t.createDiv({cls:"stashpad-settings-body"});if(i){for(let a of Ze){let l=r.createDiv({cls:"stashpad-settings-search-group"});l.createEl("h3",{text:a.label,cls:"stashpad-settings-search-group-header"});let c=l.createDiv();this.renderTabContent(c,a.id)}this.applySearchFilter(r)}else this.renderTabContent(r,this.activeTab);let o=i;s.oninput=()=>{this.searchQuery=s.value;let a=this.searchQuery.trim().length>0;if(a!==o){let l=s.selectionStart??s.value.length;this.display();let c=t.querySelector(".stashpad-settings-search-input");c&&(c.focus(),c.setSelectionRange(l,l));return}a&&this.applySearchFilter(r)},this.searchQuery&&setTimeout(()=>{s.focus(),s.setSelectionRange(s.value.length,s.value.length)},0)}applySearchFilter(t){let e=this.searchQuery.trim().toLowerCase();if(!e)return;let s=e.split(/\s+/).filter(Boolean),i=r=>s.every(o=>r.includes(o));t.querySelectorAll(".setting-item").forEach(r=>{let o=r.querySelector(".setting-item-name")?.textContent?.toLowerCase()??"",a=r.querySelector(".setting-item-description")?.textContent?.toLowerCase()??"";r.style.display=i(`${o} ${a}`)?"":"none"}),t.querySelectorAll(".stashpad-settings-search-group").forEach(r=>{let o=Array.from(r.querySelectorAll(".setting-item")).some(a=>a.style.display!=="none");r.style.display=o?"":"none"})}renderTabContent(t,e){switch(e){case"general":this.renderGeneralTab(t);break;case"diagnostics":this.renderDiagnosticsTab(t);break;case"authorship":this.renderAuthorshipSection(t);break;case"templates":this.renderTemplatesTab(t);break;case"jdindex":this.renderJdIndexSection(t);break;case"hotkeys":this.renderHotkeysTab(t);break}}renderDiagnosticsTab(t){new G.Setting(t).setName("Open log file").setDesc("Append-only history of creates, deletes, parent changes, renames. Stored alongside the plugin's other private files.").addButton(r=>r.setButtonText("Open log").onClick(async()=>{let o=this.app.vault.adapter,a=this.plugin.pluginPrivatePath("log.jsonl");if(!await o.exists(a)){new G.Notice("No log yet \u2014 make some changes first.");return}let l=await o.read(a);new qt(this.app,l,a).open()})),new G.Setting(t).setName("Notification history limit").setDesc("Maximum number of notifications kept in the persistent history. Set to 0 for unlimited (the file size grows with usage; expect a few hundred KB per ~5000 entries). Default: 5000.").addText(r=>r.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000").onChange(async o=>{let a=parseInt(o,10);Number.isFinite(a)&&(this.plugin.settings.notificationHistoryLimit=a,this.plugin.notifications.setHistoryLimit(a),await this.plugin.saveSettings())}));let e=t.createEl("details",{cls:"stashpad-notif-mute-details"});e.createEl("summary",{text:"Mute notification categories"}),e.createDiv({cls:"stashpad-notif-mute-help"}).setText("Muted categories don't pop toasts but still appear in the history panel so you can review what was suppressed.");let i=new Set(this.plugin.settings.mutedNotificationCategories??[]),n=Object.keys(fs);for(let r of n){let o=fs[r];new G.Setting(e).setName(o.label).setDesc(o.desc).addToggle(a=>a.setValue(!i.has(r)).onChange(async l=>{let c=!l;c?i.add(r):i.delete(r),this.plugin.settings.mutedNotificationCategories=Array.from(i),this.plugin.notifications.setMuted(r,c),await this.plugin.saveSettings()}))}new G.Setting(t).setName("Notification history").setDesc("Browse the last 200 toasts. Filter by category. Live-updates as new notifications arrive. Muted categories still appear here so you can review what was suppressed.").addButton(r=>r.setButtonText("View notification history").onClick(()=>{new de(this.app,this.plugin.notifications,async o=>{let a=this.app.vault.adapter,l=this.plugin.pluginPrivatePath("log.jsonl");if(!await a.exists(l)){new G.Notice("No log yet \u2014 make some changes first.");return}let c=await a.read(l);new qt(this.app,c,l).open()},this.plugin.settings.authorId||null,o=>this.plugin.lookupNoteAuthorIds(o)).open()}))}renderGeneralTab(t){new G.Setting(t).setName("Stashpad notes folder").setDesc("Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.").addText(i=>{new ee(this.app,i.inputEl),i.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad").onChange(async n=>{let r=(n||"").trim().replace(/^\/+|\/+$/g,"")||Bt.folder,o=r.split("/").filter(Boolean).pop()??"";if(new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed"].map(l=>(l??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(o)){new G.Notice(`"${r}" uses a reserved Stashpad subfolder name. Pick something else.`);return}this.plugin.settings.folder=r,await this.plugin.saveSettings()})}),new G.Setting(t).setName("Stash import subfolder").setDesc("Subfolder name (relative to each Stashpad folder) where dropped .stash files auto-import. Created on demand. Leave blank to disable auto-import.").addText(i=>i.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports").onChange(async n=>{this.plugin.settings.importDropFolder=(n||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})),new G.Setting(t).setName("Stash export subfolder").setDesc("Subfolder name (relative to each Stashpad folder) where exports land. Must differ from the import subfolder above.").addText(i=>i.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async n=>{let r=(n||"").trim().replace(/^\/+|\/+$/g,"")||Bt.exportFolder;this.plugin.settings.exportFolder=r,await this.plugin.saveSettings()})),new G.Setting(t).setName("Rebootstrap existing Stashpad folders").setDesc("Walk every folder that has a home note: ensure infrastructure (_imports, _exports, drafts file), backfill the redundant parentLink + children frontmatter fields, AND rename any note whose filename slug no longer matches its body's first line. Safe to run anytime; skip-if-equal means already-synced notes are no-op writes.").addButton(i=>i.setButtonText("Rebootstrap now").onClick(async()=>{i.setDisabled(!0).setButtonText("Working\u2026");try{let{touched:n,fmChecked:r,fmWritten:o,slugsRenamed:a,authors:l}=await this.plugin.rebootstrapAllFolders(),c=[];c.push(`rebootstrapped ${n.length} folder${n.length===1?"":"s"}`),o>0?c.push(`updated frontmatter on ${o} of ${r} notes`):r>0&&c.push(`frontmatter already in sync (${r} notes checked)`),a>0&&c.push(`renamed ${a} note${a===1?"":"s"} to match body`),l>0&&c.push(`rebuilt author registry (${l} author${l===1?"":"s"})`),new G.Notice(`Stashpad: ${c.join("; ")}.`)}catch(n){new G.Notice(`Stashpad: rebootstrap failed (${n.message})`)}finally{i.setDisabled(!1).setButtonText("Rebootstrap now")}})),new G.Setting(t).setName("Use Templates plugin date/time formats").setDesc("When on, timestamps use the formats configured in the core Templates plugin. Off: YYYY.MM.DD + HH:mm A.").addToggle(i=>i.setValue(this.plugin.settings.useTemplatesFormat).onChange(async n=>{this.plugin.settings.useTemplatesFormat=n,await this.plugin.saveSettings()}));let e=Je(this.app);t.createDiv({cls:"setting-item-description stashpad-settings-note"}).setText(e?`Templates plugin: date = "${e.dateFormat}", time = "${e.timeFormat}"`:"Templates plugin not enabled.");{let i=null,n=()=>{if(!i)return;let r=Date.now(),o=Wt(r,this.plugin.settings);i.setText(`Sample: ${o}`)};new G.Setting(t).setName("Date display format").setDesc("How due dates and created/modified times are shown in the Tasks and detail panels.").addDropdown(r=>{r.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),r.addOption("long","Locale, long (Thursday, March 5\u2026)"),r.addOption("iso","ISO (2026-03-05 09:00)"),r.addOption("us","US (3/5/2026, 9:00 AM)"),r.addOption("eu","EU (5/3/2026, 09:00)"),r.setValue(this.plugin.settings.dateDisplayFormat??"locale"),r.onChange(async o=>{this.plugin.settings.dateDisplayFormat=o,await this.plugin.saveSettings(),n()})}),new G.Setting(t).setName("Display timezone").setDesc("IANA timezone name (e.g. America/New_York, Europe/London, Asia/Kolkata). Leave blank to use your system timezone.").addText(r=>{r.setPlaceholder("(system timezone)"),r.setValue(this.plugin.settings.dateDisplayTimezone??""),r.onChange(async o=>{this.plugin.settings.dateDisplayTimezone=(o||"").trim(),await this.plugin.saveSettings(),n()})}),i=t.createDiv({cls:"setting-item-description stashpad-settings-note"}),n()}new G.Setting(t).setName("Navigate into parent after moving a note IN").setDesc("When you move a note onto another note via the in-list move picker (drag-onto-sibling), automatically drill into the new parent so you can see the moved note in its new home. Off = stay focused where you were.").addToggle(i=>i.setValue(this.plugin.settings.autoNavOnMoveIn).onChange(async n=>{this.plugin.settings.autoNavOnMoveIn=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Navigate to destination after moving a note OUT").setDesc("When you outdent a note, move it via the cross-parent picker, or send it to Home, automatically drill into the destination parent. Off = stay focused where you were.").addToggle(i=>i.setValue(this.plugin.settings.autoNavOnMoveOut).onChange(async n=>{this.plugin.settings.autoNavOnMoveOut=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Double-click a note to open it").setDesc("Double-click (or double-tap on mobile) a note in the list to focus/open it \u2014 the same as pressing \u2192 or clicking the enter arrow. Single click still just selects. On by default.").addToggle(i=>i.setValue(this.plugin.settings.doubleClickToFocus).onChange(async n=>{this.plugin.settings.doubleClickToFocus=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Auto-open the detail panel").setDesc("Open the right-sidebar Stashpad detail panel automatically whenever a Stashpad view becomes active. The panel shows the cursored note's body, metadata, and children. Off = open manually via ribbon or command palette.").addToggle(i=>i.setValue(this.plugin.settings.autoOpenDetailPanel).onChange(async n=>{this.plugin.settings.autoOpenDetailPanel=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Expand the cursor row's body automatically").setDesc("As you arrow-key through the list, the row under the cursor temporarily un-clamps to show its full body. Moving away re-collapses it. Doesn't affect the persistent 'Show more' state \u2014 this is a transient view-only effect.").addToggle(i=>i.setValue(this.plugin.settings.autoExpandCursorRow).onChange(async n=>{this.plugin.settings.autoExpandCursorRow=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Confirm cross-parent drag-and-drop").setDesc("When dragging notes onto a note that has a different parent, ask before re-parenting (turn off to allow direct moves).").addToggle(i=>i.setValue(this.plugin.settings.confirmCrossParentDrag).onChange(async n=>{this.plugin.settings.confirmCrossParentDrag=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Confirm bulk deletes").setDesc("Warn before deletes that affect more than one note \u2014 multi-selection delete OR deleting a note that has descendants. A single childless note with no attachments never prompts. Off = those deletes apply immediately (undo still recovers everything).").addToggle(i=>i.setValue(this.plugin.settings.confirmBulkDelete).onChange(async n=>{this.plugin.settings.confirmBulkDelete=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Offer to delete attachments with note").setDesc(`When a note references attachments, the delete modal includes an "Also delete attachments" checkbox so orphaned files don't pile up in your vault. Attachments are detected from both ![[\u2026]] embeds in the body and the frontmatter attachments: list. Off = attachments are always preserved on delete (no checkbox shown), and a single childless note with attachments deletes silently.`).addToggle(i=>i.setValue(this.plugin.settings.confirmAttachmentDelete).onChange(async n=>{this.plugin.settings.confirmAttachmentDelete=n,await this.plugin.saveSettings()}));{let i=null,n=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:Et).join(` +`);new G.Setting(t).setName("Slug stop-words").setDesc("Words removed from auto-generated note titles (filenames). One per line.").addTextArea(r=>{r.setValue(n),i=r.inputEl,i.rows=6,i.style.fontFamily="var(--font-monospace)",r.onChange(async o=>{let a=(o||"").split(/\r?\n/).map(l=>l.trim().toLowerCase()).filter(Boolean);this.plugin.settings.slugStopWords=a,await this.plugin.saveSettings()})}).addExtraButton(r=>r.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(async()=>{this.plugin.settings.slugStopWords=[...Et],i&&(i.value=Et.join(` +`)),await this.plugin.saveSettings()}))}{let i=this.plugin.discoverStashpadFolders();if(new G.Setting(t).setName("Cross-Stashpad search scope").setDesc("Toggle each Stashpad's pill to choose whether its notes contribute to cross-folder search. Excluded folders are still valid move destinations \u2014 their notes just don't appear in search results from elsewhere."),i.length===0)t.createEl("p",{cls:"setting-item-description"}).setText('No Stashpads found in this vault yet. A Stashpad is just a folder that contains a Stashpad-shaped note (frontmatter has both `id` and `parent`). Easiest way: open Stashpad (ribbon icon or command "Reveal or open Stashpad") \u2014 it auto-creates the default folder on first use. Or create one below.');else{let r=t.createDiv({cls:"stashpad-folder-list"});for(let o of i)this.renderFolderScopeRow(r,o)}let n=null;new G.Setting(t).setName("Create a new Stashpad").setDesc("Type a vault-relative folder path. The folder is created (with intermediates) and seeded with a Home note so Stashpad recognizes it.").addText(r=>{r.setPlaceholder("my-stashpad"),n=r.inputEl}).addButton(r=>r.setButtonText("Create").setCta().onClick(async()=>{let o=(n?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!o){new G.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(o),new G.Notice(`Created Stashpad "${o}".`),n&&(n.value=""),await this.plugin.waitForStashpadFolder(o,2e3),this.display()}catch(a){new G.Notice(`Couldn't create: ${a.message}`)}}))}new G.Setting(t).setName("Autofocus composer after sending").setDesc("After Enter-submitting a note, return focus to the composer so you can keep typing. Off keeps focus in the list \u2014 useful if you want arrow keys to work without an extra click.").addToggle(i=>i.setValue(this.plugin.settings.autofocusComposerAfterSend).onChange(async n=>{this.plugin.settings.autofocusComposerAfterSend=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Open in new window \u2014 duplicate tab").setDesc("ON: the new-window button (in the time-filter row) duplicates the current Stashpad tab \u2014 original stays open in the main window. OFF: the leaf is MOVED to the new window, closing the original tab.").addToggle(i=>i.setValue(this.plugin.settings.popoutDuplicates).onChange(async n=>{this.plugin.settings.popoutDuplicates=n,await this.plugin.saveSettings()})),new G.Setting(t).setName("Prefix timestamps when copying").setDesc("Include each note's timestamp before its body when copying with C or Y.").addToggle(i=>i.setValue(this.plugin.settings.prefixTimestampsOnCopy).onChange(async n=>{this.plugin.settings.prefixTimestampsOnCopy=n,await this.plugin.saveSettings()}))}renderTemplatesTab(t){this.renderColorAliasesSection(t),this.renderNoteTemplatesSection(t)}renderHotkeysTab(t){t.createEl("p",{cls:"setting-item-description",text:"Each command has up to two slots. Click a slot and press a key (or chord) to bind it; press Backspace (delete on Mac) to cancel without binding; or click \u2715 to clear an existing binding. When both slots are set, the pill on the right decides which one is active."});for(let e of ve)this.renderBindingRow(t,e)}renderJdIndexSection(t){let e=t.createEl("h3",{text:"JD Index Builder"});e.id="stashpad-jd-index-section";let s=t.createEl("p",{cls:"setting-item-description"});s.innerHTML="Builds a Johnny-Decimal-style index inside a designated Stashpad folder. Two commands:<br/><strong>Preview</strong> overwrites the designated folder’s HOME note body with the would-be hierarchy + everything that didn’t match. Frontmatter is preserved; everything below it is replaced.<br/><strong>Build</strong> creates an actual hierarchy of Stashpad notes (one per prefix), with child\u2192parent relationships matching the dotted segments.<br/>Matches strict prefixes only: all-digits (<code>10 Life</code>) or alphanumeric-with-dots (<code>1.2 Family</code>, <code>animal.duck.yellow Eggs</code>). Mixed schemes sort numbers first, then alphabetically.";let i=this.plugin.discoverStashpadFolders();new G.Setting(t).setName("Scope").setDesc("Scan the whole vault, or restrict to a single folder + its descendants.").addDropdown(a=>{a.addOption("vault","Entire vault"),a.addOption("folder","Single folder"),a.setValue(this.plugin.settings.jdIndexScope??"vault"),a.onChange(async l=>{this.plugin.settings.jdIndexScope=l==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new G.Setting(t).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(a=>{new ee(this.app,a.inputEl),a.setPlaceholder("Path/To/Folder"),a.setValue(this.plugin.settings.jdIndexScopeFolder??""),a.onChange(async l=>{this.plugin.settings.jdIndexScopeFolder=(l||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new G.Setting(t).setName("Include Stashpad folders in scan").setDesc("By default, notes inside any known Stashpad folder are excluded \u2014 the index destination shouldn't index itself, and other Stashpad folders are usually already organized. Toggle on if you want them included anyway.").addToggle(a=>{a.setValue(this.plugin.settings.jdIndexIncludeStashpadFolders===!0),a.onChange(async l=>{this.plugin.settings.jdIndexIncludeStashpadFolders=l,await this.plugin.saveSettings(),this.display()})}),new G.Setting(t).setName("Designated Stashpad folder for Index").setDesc("Required. Must be a Stashpad folder. The index hierarchy is built here. New notes are created; nothing is deleted.").addText(a=>{new ee(this.app,a.inputEl),a.setPlaceholder(i[0]??"(pick a Stashpad folder)"),a.setValue(this.plugin.settings.jdIndexStashpadFolder??""),a.onChange(async l=>{this.plugin.settings.jdIndexStashpadFolder=(l||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new G.Setting(t).setName("Sort").setDesc("Order of entries within the same depth. Natural: numbers first then alphabetical (recommended). Created: by source file's creation time \u2014 handy when prefixes are word-only and don't carry ordering.").addDropdown(a=>{a.addOption("natural","Natural (numeric \u2192 alphabetical)"),a.addOption("created","By creation time"),a.setValue(this.plugin.settings.jdIndexSort??"natural"),a.onChange(async l=>{this.plugin.settings.jdIndexSort=l==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=te(this.app,this.plugin,this.plugin.settings),r=t.createEl("p",{cls:"setting-item-description"}),o=n.skippedStashpadNotes.length>0?` (${n.skippedStashpadNotes.length} Stashpad-folder note${n.skippedStashpadNotes.length===1?"":"s"} excluded by default)`:"";r.setText(`Preview: ${n.indexed.length} note${n.indexed.length===1?"":"s"} would be indexed, ${n.nonIndex.length} would NOT be indexed${o}.`),new G.Setting(t).setName("Actions").setDesc("Preview aggressively overwrites the designated folder's HOME note body (frontmatter preserved). Build creates Stashpad notes (existing notes with the same jdPrefix are updated, not duplicated).").addButton(a=>{a.setButtonText("Preview"),a.setTooltip("Overwrites the designated Stashpad folder's HOME note body with the preview."),a.onClick(async()=>{try{let l=await je(this.app,this.plugin,this.plugin.settings);if(l.error==="no-dest"){new G.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(l.error==="no-home"){new G.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}Ue(this.app,l),this.display()}catch(l){console.error("[stashpad] preview failed",l),new G.Notice(`Preview failed: ${l?.message??l}`,8e3)}})}).addButton(a=>{a.setButtonText("Build Stashpad notes"),a.setCta(),a.setTooltip("Create the Stashpad-note hierarchy. Existing notes with matching jdPrefix are updated."),a.onClick(()=>{if(!(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new G.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new fe(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let h=await gs(this.app,this.plugin,this.plugin.settings);if(h.error==="no-dest"){new G.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(h.error==="dest-not-stashpad"){new G.Notice(`"${h.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder (or create one first).`,7e3);return}this.plugin.settings.jdIndexHasBuilt=!0,await this.plugin.saveSettings(),new G.Notice(`Built: ${h.created} created, ${h.updated} updated, ${h.skipped} skipped \u2192 ${h.destFolder}`,6e3),this.display()}catch(h){console.error("[stashpad] build failed",h),new G.Notice(`Build failed: ${h?.message??h}`,8e3)}}).open()})}).addButton(a=>{a.setButtonText("Reveal in Finder"),a.setTooltip("Open the designated Stashpad folder in your OS file browser."),a.onClick(async()=>{let l=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!l){new G.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(l)){new G.Notice(`Folder "${l}" doesn't exist yet.`,5e3);return}try{let h=this.app.vault.adapter.basePath;if(h){let{shell:u}=window.require?.("electron")??{},d=`${h}/${l}`;u?.openPath?.(d)}else new G.Notice("Reveal in file system not supported on this platform.",4e3)}catch(h){new G.Notice(`Couldn't open folder: ${h?.message??h}`,5e3)}})})}renderColorAliasesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0){new G.Setting(t).setName("Color Aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let s=(()=>{let r=Pt()?.noteFolder;return r&&e.includes(r)?r:e[0]})();new G.Setting(t).setName("Color Aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(r=>{for(let o of e)r.addOption(o,o);r.setValue(s),r.onChange(o=>{s=o,n()})}),t.createEl("p",{cls:"setting-item-description",text:"Give each per-note color a friendly name. Filters and pickers display the alias instead of the hex code; the underlying color stays the same. The same hex in two Stashpads can have different aliases."});let i=t.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{i.empty();let r=this.plugin.collectColorsInFolder(s),o=new Map(r.map(h=>[h.hex,h.count])),a=this.plugin.settings.colorAliases?.[s.replace(/\/+$/,"")]??{},l=new Set([...o.keys(),...Object.keys(a)]);if(l.size===0){i.createEl("p",{cls:"setting-item-description",text:`No colors used or aliased in "${s}" yet. Set a per-note color (Shift+: or right-click \u2192 Set color) and it'll appear here.`});return}let c=[...l].map(h=>({hex:h,count:o.get(h)??0}));c.sort((h,u)=>u.count-h.count||h.hex.localeCompare(u.hex));for(let h of c)this.renderColorAliasRow(i,s,h.hex,h.count,n)};n()}renderAuthorshipSection(t){t.createEl("h3",{text:"Authorship"}),t.createEl("p",{cls:"setting-item-description",text:"Stamp each new note with your name. If the vault is later shared (e.g. a coworker opens it with --config pointing at their own settings folder), every modification automatically tracks contributors on top of the original author. Names link to per-user pages in <stashpad>/_authors/."}),new G.Setting(t).setName("Author name").setDesc("Your display name. Used in the note footer + as the author/contributor link target. Leave blank to opt out (notes won't be stamped).").addText(s=>{s.setValue(this.plugin.settings.authorName).onChange(async i=>{this.plugin.settings.authorName=i.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=Tt()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new G.Setting(t).setName("Author id (auto-assigned)").setDesc("Stable id appended to your name on links so coworkers with the same name don't collide. Generated once and shouldn't change. If you really need to reset it, clear and retype your author name above.").addText(s=>{s.setValue(this.plugin.settings.authorId).setDisabled(!0)}),new G.Setting(t).setName("Title / role").setDesc('Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").').addText(s=>{s.setValue(this.plugin.settings.authorRole).onChange(async i=>{this.plugin.settings.authorRole=i.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new G.Setting(t).setName("Department / team").setDesc('Optional. Shown on your author page (e.g. "Engineering", "Growth").').addText(s=>{s.setValue(this.plugin.settings.authorDepartment).onChange(async i=>{this.plugin.settings.authorDepartment=i.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new G.Setting(t).setName("Show author in note footer").addToggle(s=>s.setValue(this.plugin.settings.showAuthor).onChange(async i=>{this.plugin.settings.showAuthor=i,await this.plugin.saveSettings()})),new G.Setting(t).setName("Show contributors in note footer").addToggle(s=>s.setValue(this.plugin.settings.showContributors).onChange(async i=>{this.plugin.settings.showContributors=i,await this.plugin.saveSettings()})),new G.Setting(t).setName("Show last edit time in note footer").addToggle(s=>s.setValue(this.plugin.settings.showLastEdit).onChange(async i=>{this.plugin.settings.showLastEdit=i,await this.plugin.saveSettings()}));let e=this.plugin.collectAuthoredFolders();if(e.length>0){t.createEl("h4",{text:"Folders you've worked in"});let s=t.createDiv({cls:"stashpad-authored-folders-list"});for(let i of e){let n=s.createDiv({cls:"stashpad-authored-folder-row"}),r=n.createEl("a",{cls:"stashpad-authored-folder-link",text:i.folder});r.onclick=a=>{a.preventDefault(),this.plugin.activateViewForFolder(i.folder)};let o=[];i.authored>0&&o.push(`authored ${i.authored}`),i.contributed>0&&o.push(`contributed to ${i.contributed}`),n.createSpan({cls:"stashpad-authored-folder-counts",text:` \xB7 ${o.join(", ")}`})}}this.renderKnownAuthorsSection(t)}renderKnownAuthorsSection(t){t.createEl("h4",{text:"Known authors (registry)"}),t.createEl("div",{cls:"setting-item-description",text:"A rebuildable cache of every author Stashpad has seen, with rename history. Not a source of truth \u2014 the author id stored in each note is authoritative. Use it to recover deleted author pages or audit name changes."}),new G.Setting(t).setName("Registry maintenance").setDesc("Rebuild scans the whole vault to reconstruct the list. Restore regenerates any deleted author pages across every Stashpad folder.").addButton(i=>i.setButtonText("Rebuild").onClick(async()=>{i.setDisabled(!0).setButtonText("Rebuilding\u2026");try{let n=await this.plugin.rebuildAuthorRegistry();new G.Notice(`Author registry rebuilt: ${n.total} author(s).`)}catch(n){new G.Notice(`Rebuild failed: ${n.message}`)}i.setDisabled(!1).setButtonText("Rebuild"),this.display()})).addButton(i=>i.setButtonText("Restore missing pages").onClick(async()=>{i.setDisabled(!0).setButtonText("Restoring\u2026");try{let n=await this.plugin.restoreMissingAuthorStubs();new G.Notice(n.created>0?`Restored ${n.created} author page(s).`:"No missing author pages.")}catch(n){new G.Notice(`Restore failed: ${n.message}`)}i.setDisabled(!1).setButtonText("Restore missing pages")}));let e=this.plugin.authorRegistry.all();if(e.length===0){t.createEl("div",{cls:"setting-item-description",text:"No authors recorded yet. Rebuild to scan the vault."});return}let s=t.createDiv({cls:"stashpad-known-authors-list"});for(let i of e){let n=s.createDiv({cls:"stashpad-known-author-row"}),r=n.createDiv({cls:"stashpad-known-author-main"});r.createSpan({cls:"stashpad-known-author-name",text:i.name||"(unnamed)"});let o=[];if(i.role&&o.push(i.role),i.department&&o.push(i.department),o.push(`id ${i.id}`),r.createSpan({cls:"stashpad-known-author-meta",text:` \xB7 ${o.join(" \xB7 ")}`}),i.renames&&i.renames.length>0){let a=n.createDiv({cls:"stashpad-known-author-history"}),l=i.renames.map(c=>`${c.from} \u2192 ${c.to}`).join(", ");a.setText(`Renamed: ${l}`)}}}renderNoteTemplatesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0)return;new G.Setting(t).setName("Note templates per Stashpad").setDesc("Pick a markdown file to use as the default template for new notes in each Stashpad. The template's frontmatter becomes the new note's frontmatter (id/parent/created/attachments are always set by Stashpad). If the body contains {{body}}, that's where the user-typed body goes; otherwise the user body is followed by the template body.");let s=t.createDiv({cls:"stashpad-note-templates-list"}),i=n=>{let r=n.replace(/\/+$/,""),o=s.createDiv({cls:"stashpad-note-template-row"});o.createSpan({cls:"stashpad-note-template-folder"}).setText(n);let l=o.createDiv({cls:"stashpad-note-template-input-wrap"}),c=l.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});c.value=(this.plugin.settings.noteTemplates??{})[r]??"";let h=l.createDiv({cls:"stashpad-note-template-suggest"});h.style.display="none";let u=o.createDiv({cls:"stashpad-note-template-warn"});u.style.display="none";let d=()=>this.app.vault.getMarkdownFiles().map(y=>y.path).filter(y=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(y)).sort(),p=()=>{h.empty();let y=c.value.trim().toLowerCase().split(/\s+/).filter(Boolean),b=C=>{let E=C.toLowerCase();return y.every(I=>E.includes(I))},k=d().filter(C=>b(C)).slice(0,12);if(k.length===0){h.style.display="none";return}h.style.display="";for(let C of k)h.createDiv({cls:"stashpad-note-template-suggest-item",text:C}).addEventListener("mousedown",async I=>{I.preventDefault(),c.value=C,await m(),h.style.display="none"})},m=async()=>{let y=c.value.trim(),b={...this.plugin.settings.noteTemplates??{}};y?b[r]=y:delete b[r],this.plugin.settings.noteTemplates=b,await this.plugin.saveSettings(),v()},v=()=>{u.empty(),u.style.display="none";let y=c.value.trim();if(!y)return;let b=this.app.vault.getAbstractFileByPath(y);if(!b||b.extension!=="md"){u.style.display="",u.setText(`\u26A0 "${y}" is not a markdown file in this vault.`);return}let k=this.app.metadataCache.getFileCache(b)?.frontmatter??{},E=ae.filter(I=>{let A=k[I];return!(A==null||typeof A=="string"&&A.trim()===""||Array.isArray(A)&&A.length===0)});E.length!==0&&(u.style.display="",u.setText(`\u26A0 Template defines ${E.join(", ")} \u2014 Stashpad always sets ${E.length===1?"this":"these"} on new notes, so the template value${E.length===1?"":"s"} will be ignored.`))};c.addEventListener("focus",p),c.addEventListener("input",p),c.addEventListener("blur",()=>{setTimeout(()=>{h.style.display="none"},150)}),c.addEventListener("change",()=>{m()}),v()};for(let n of e)i(n)}renderColorAliasRow(t,e,s,i,n){let r=t.createDiv({cls:"stashpad-color-alias-row"});i===0&&r.addClass("is-unused");let o=r.createSpan({cls:"stashpad-color-alias-swatch"});o.style.background=s,o.title="Click to bulk-recolor every note of this color in this Stashpad",o.onclick=()=>{let h=this.plugin.settings.customPalette??[];new Vt(this.app,s,h,async u=>{if((u??null)===null&&i===0){await this.plugin.setColorAlias(e,s,""),n();return}if(u&&u.toLowerCase()===s){n();return}let d=await this.plugin.recolorAllInFolder(e,s,u??null);if(d>0)new G.Notice(`Recolored ${d} note${d===1?"":"s"}.`);else if(i===0){let p=this.plugin.getColorAlias(e,s);p&&(await this.plugin.setColorAlias(e,s,""),u&&await this.plugin.setColorAlias(e,u,p))}n()},async u=>{let d=(this.plugin.settings.customPalette??[]).filter(p=>p.toLowerCase()!==u.toLowerCase());return this.plugin.settings.customPalette=d,await this.plugin.saveSettings(),d}).open()};let a=r.createDiv({cls:"stashpad-color-alias-meta"});a.createSpan({cls:"stashpad-color-alias-hex",text:s}),a.createSpan({cls:"stashpad-color-alias-count",text:i===0?"\xB7 unused":`\xB7 ${i} note${i===1?"":"s"}`});let l=r.createEl("input",{type:"text",cls:"stashpad-color-alias-input",attr:{placeholder:"Alias (optional)"}});l.value=this.plugin.getColorAlias(e,s)??"",l.onchange=async()=>{await this.plugin.setColorAlias(e,s,l.value),!l.value.trim()&&i===0&&n()};let c=r.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});l.value||(c.style.visibility="hidden"),c.onclick=async()=>{await this.plugin.setColorAlias(e,s,""),i===0?n():(l.value="",c.style.visibility="hidden")}}renderFolderScopeRow(t,e){let s=t.createDiv({cls:"stashpad-folder-row"});s.createSpan({cls:"stashpad-folder-row-label",text:e});let i=s.createSpan({cls:"stashpad-folder-row-state"}),n=s.createDiv({cls:"stashpad-binding-pill"});n.setAttribute("role","switch"),n.setAttribute("tabindex","0");let r=n.createDiv({cls:"stashpad-binding-pill-knob"}),o=()=>(this.plugin.settings.searchExcludedFolders??[]).includes(e),a=()=>{let c=o();n.toggleClass("is-right",c),n.setAttribute("aria-checked",String(c)),r.setText(c?"X":"\u2713"),i.setText(c?"Excluded":"Included"),i.toggleClass("is-excluded",c),n.title=c?"Excluded \u2014 notes here won't appear in cross-Stashpad search. Click to include.":"Included \u2014 notes here appear in cross-Stashpad search. Click to exclude."},l=async()=>{let c=new Set(this.plugin.settings.searchExcludedFolders??[]);c.has(e)?c.delete(e):c.add(e),this.plugin.settings.searchExcludedFolders=[...c].sort(),a(),await this.plugin.saveSettings()};n.onclick=()=>void l(),n.onkeydown=c=>{(c.key===" "||c.key==="Enter")&&(c.preventDefault(),l())},a()}renderBindingRow(t,e){let s=new G.Setting(t).setName(e.label).setDesc(e.desc),i=()=>this.plugin.settings.bindings[e.id],n,r,o=()=>{},a=p=>{let m=s.controlEl.createDiv({cls:"stashpad-binding-slot"}),v=m.createEl("input",{type:"text"});v.readOnly=!0,v.placeholder="Click & press a key",v.value=ws(i()[p]),v.classList.add("stashpad-binding-input");let y=()=>{v.size=Math.max(3,v.value.length||v.placeholder.length)};y(),v.onclick=()=>{Ks(v,async k=>{this.plugin.settings.bindings[e.id][p]=k,v.value=ws(k),y(),await this.plugin.saveSettings(),o()})};let b=m.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});return b.title="Clear this slot",b.onclick=async()=>{this.plugin.settings.bindings[e.id][p]="",v.value="",y(),await this.plugin.saveSettings(),o()},v};n=a("primary"),r=a("secondary");let l=s.controlEl.createDiv({cls:"stashpad-binding-pill"});l.setAttribute("role","switch"),l.setAttribute("tabindex","0");let c=l.createDiv({cls:"stashpad-binding-pill-knob"}),h=s.controlEl.createDiv({cls:"stashpad-binding-useboth"}),u=h.createEl("input",{type:"checkbox"});u.title="Use both bindings simultaneously (overrides the L/R toggle)",h.createSpan({text:"Use both"}),u.onchange=async()=>{this.plugin.settings.bindings[e.id].useBoth=u.checked,await this.plugin.saveSettings(),o()},o=()=>{let p=i(),m=!!(p.primary&&p.secondary);u.checked=!!p.useBoth,u.disabled=!m,h.toggleClass("is-disabled",!m);let v=!!p.useBoth&&m;l.toggleClass("is-disabled",!m||v),l.toggleClass("is-right",p.preferRight),l.setAttribute("aria-checked",String(p.preferRight)),l.setAttribute("aria-disabled",String(!m||v)),c.setText(p.preferRight?"R":"L"),l.title=m?v?'Overridden by "Use both"':p.preferRight?"Right slot active \u2014 click for left":"Left slot active \u2014 click for right":"Set both slots to enable the toggle"};let d=async()=>{let p=i();!p.primary||!p.secondary||(this.plugin.settings.bindings[e.id].preferRight=!p.preferRight,o(),await this.plugin.saveSettings())};l.onclick=()=>void d(),l.onkeydown=p=>{(p.key===" "||p.key==="Enter")&&(p.preventDefault(),d())},o()}};var dt=require("obsidian");Ct();ps();function Cs(g){let f=g.trim().toLowerCase();if(!f)return null;let t=Date.now(),e=p=>(0,dt.moment)(p).startOf("day").valueOf(),s=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/,i=0,n=!1,r=f,o=s.exec(f);if(o&&(o[3]||o[2])){let p=parseInt(o[1],10),m=o[2]?parseInt(o[2],10):0,v=o[3];v==="pm"&&p<12&&(p+=12),v==="am"&&p===12&&(p=0),p>=0&&p<24&&m>=0&&m<60&&(i=(p*3600+m*60)*1e3,n=!0,r=f.replace(o[0]," ").replace(/\s+/g," ").trim())}let a=p=>n?p+i:p;if(r===""||r==="today")return a(e(t));if(r==="yesterday")return a(e(t)-864e5);if(r==="tomorrow")return a(e(t)+864e5);let l=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],c=["sun","mon","tue","wed","thu","fri","sat"],h=l.indexOf(r)>=0?l.indexOf(r):c.indexOf(r);if(h>=0){let p=(0,dt.moment)().startOf("day"),v=(p.day()-h+7)%7;return a(p.subtract(v,"days").valueOf())}let u=/^(\d+)\s*([dwmy])$/.exec(r);if(u){let p=parseInt(u[1],10),m={d:"days",w:"weeks",m:"months",y:"years"}[u[2]];return a((0,dt.moment)().subtract(p,m).startOf("day").valueOf())}let d=(0,dt.moment)(r,["YYYY-MM-DD","YYYY/MM/DD","MM-DD-YYYY","MM/DD/YYYY","M-D-YYYY","M/D/YYYY"],!0);return d.isValid()?a(d.startOf("day").valueOf()):null}function Xs(g){let f={text:[],filters:{}},t=(g||"").trim();if(!t)return f;let e=/\b(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,s=t,i;for(;(i=e.exec(t))!=null;){let n=i[1].toLowerCase(),r=(i[2]!==void 0?i[2]:i[3]??"").trim();if(r){if(n==="in")f.filters.in=r.toLowerCase();else if(n==="before"){let o=Cs(r);o!=null&&(f.filters.before=o)}else if(n==="after"){let o=Cs(r);o!=null&&(f.filters.after=o)}else if(n==="on"){let o=Cs(r);if(o!=null)if(/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(r))f.filters.on={start:o-6e4,end:o+6e4};else{let l=(0,dt.moment)(o).startOf("day").valueOf();f.filters.on={start:l,end:l+864e5}}}s=s.replace(i[0]," ")}}for(let n of s.split(/\s+/))n&&f.text.push(n.toLowerCase());return f}var Mt=class g extends dt.SuggestModal{constructor(t,e,s,i){super(t);this.tree=e;this.titleFn=s;this.opts=i;this.notes=[];this.pendingCleanups=[];this.crossFolderIndex=null;this.whenBuilderEl=null;this.whenMode="on";this.whenSingleText="";this.whenBetweenEndText="";this.setPlaceholder(i.placeholder??(i.mode==="search"?"Search notes\u2026":"Pick a note\u2026")),this.loadAll()}onClose(){for(;this.pendingCleanups.length>0;){let t=this.pendingCleanups.pop();try{t&&t()}catch{}}}loadAll(){let t=(s,i)=>{let n=this.tree.get(s);n?.file&&s!==R?this.notes.push({node:n,title:`${" ".repeat(i)}${this.titleFn(n)}`,body:""}):n?.file&&s===R&&this.notes.push({node:n,title:"Home",body:""});for(let r of this.tree.getChildren(s))t(r.id,i+1)},e=this.tree.getRoot();e.file&&this.notes.push({node:e,title:"Home",body:""});for(let s of this.tree.getChildren(R))t(s.id,1);for(let s of this.notes)s.node?.file&&this.app.vault.cachedRead(s.node.file).then(i=>{s.body=this.stripFm(i)});if(this.opts.crossFolderNotes){let s=this.opts.crossFolderNotes();for(let i of s)this.notes.push({node:null,title:i.title,body:i.body,cross:i});for(let i of this.notes)!i.cross||i.body||i.cross.file&&this.app.vault.cachedRead(i.cross.file).then(n=>{i.body=this.stripFm(n)})}}createdMsFor(t){if(t.node?.created){let e=Date.parse(t.node.created);if(!Number.isNaN(e))return e}return t.cross?.file?.stat?.ctime!=null?t.cross.file.stat.ctime:null}stripFm(t){if(!t.startsWith("---"))return t;let e=t.indexOf(` +---`,3);return e===-1?t:t.slice(e+4).replace(/^\r?\n/,"")}getSuggestions(t){let e=t.trim().toLowerCase(),s=Xs(t),i=s.text;console.log("[Stashpad] search query parsed",{query:t,text:s.text,filters:s.filters});let n=y=>{if(!i.length)return!0;for(let b of i)if(!y.includes(b))return!1;return!0},r=null,o=null;if(s.filters.in){let y=s.filters.in.split(/\s+/).filter(Boolean);r=new Set,o=new Map;let b=E=>y.every(I=>E.toLowerCase().includes(I)),k=E=>{if(!r.has(E)){r.add(E);for(let I of this.tree.getChildren(E))k(I.id)}};for(let E of this.notes)!E.node||E.cross||b(E.title)&&k(E.node.id);let C=new Map;for(let E of this.notes){if(!E.cross)continue;let I=C.get(E.cross.folder)??[];I.push(E),C.set(E.cross.folder,I)}for(let[E,I]of C){let A=new Map;for(let D of I){let S=D.cross?.parentId??null;if(!S)continue;let B=A.get(S)??[];B.push(D.cross.id),A.set(S,B)}let O=new Set;o.set(E,O);let F=D=>{if(!O.has(D)){O.add(D);for(let S of A.get(D)??[])F(S)}};for(let D of I)b(D.title)&&F(D.cross.id)}}let a=y=>{let b=s.filters;if(r||o)if(y.cross){let k=o?.get(y.cross.folder);if(!k||!k.has(y.cross.id))return!1}else if(y.node){if(!r||!r.has(y.node.id))return!1}else return!1;if(b.before||b.after||b.on){let k=this.createdMsFor(y);if(k==null||b.before!=null&&k>=b.before||b.after!=null&&k<=b.after||b.on&&(k<b.on.start||k>=b.on.end))return!1}return!0},l=y=>n(y.toLowerCase()),c=this.notes.filter(y=>!y.cross),h=this.notes.filter(y=>y.cross),u=(y,b)=>({id:y.cross?`cross:${y.cross.id}`:y.node.id,label:y.title,node:y.node,kind:"note",bodyPreview:this.previewFromBody(y.body,b),matchLine:b,crossFolder:y.cross?.folder,crossFile:y.cross?.file}),d=y=>{let b=[];for(let k of y)if(a(k))if(this.opts.mode==="search"){if(!e){b.push(u(k,-1));continue}let C=n(k.title.toLowerCase()),E=k.body.split(/\r?\n/),I=[];for(let O=0;O<E.length;O++)l(E[O])&&I.push(O);let A=I.length>0||n(k.body.toLowerCase());if(!C&&!A)continue;if(I.length===0)b.push(u(k,-1));else{let O=[],F=-100;for(let S of I)S-F>5&&O.push(S),F=S;let D=5;for(let S of O.slice(0,D))b.push(u(k,S))}}else{if(e&&!n(k.title.toLowerCase())&&!n(k.body.toLowerCase()))continue;b.push(u(k,-1))}return b},p=d(c),m=[...p];if(this.opts.mode==="search"?e?!0:p.length<10:!!e){let y=d(h);this.opts.mode==="search"&&!e&&(m.length=Math.min(m.length,50)),m.push(...y)}if(this.opts.folderResults){let y=this.opts.folderResults(),b=!e||y.some(k=>{let C=k.split("/").pop()??k;return n(`${k.toLowerCase()} ${C.toLowerCase()}`)});if(y.length>0&&b){let k={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};Object.keys(s.filters).length>0?m.push(k):m.unshift(k)}}return this.opts.allowCreate&&e&&!m.some(y=>y.label.trim().toLowerCase()===e)&&m.push({id:"__create__",label:`Create new: "${t}"`,node:null,kind:"create"}),m}previewFromBody(t,e){let s=t.split(/\r?\n/);if(e<0)return s.filter(o=>o.trim().length>0).slice(0,3).join(` `);let i=Math.max(0,e-2),n=Math.min(s.length,e+3);return s.slice(i,n).filter(r=>r.trim().length>0).join(` -`)}renderSuggestion(t,e){if(e.addClass("stashpad-suggest-item"),t.kind==="create"){e.createDiv({cls:"stashpad-suggest-create",text:t.label});return}if(t.kind==="folder-open"){e.addClass("is-folder-open"),e.createDiv({cls:"stashpad-suggest-title",text:t.label}),t.folder?e.createDiv({cls:"stashpad-suggest-preview",text:t.folder}):e.createDiv({cls:"stashpad-suggest-preview",text:"Click to choose a folder\u2026"});return}t.crossFolder&&e.addClass("is-cross-folder"),e.addClass("stashpad-suggest-row");let s=e.createDiv({cls:"stashpad-suggest-body"}),i=this.notes.find(h=>t.crossFolder?h.cross?.id===t.id.replace(/^cross:/,""):h.node?.id===t.id),n=Ys(this.inputEl?.value??"").text,r=this.firstLineOfBody(i?.body??"")||t.label.trim(),o=s.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(o,r,n);let a=t.crossFolder??this.opts.localFolder??null;if(t.bodyPreview&&t.matchLine!=null&&t.matchLine>=0){let h=s.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(h,t.bodyPreview,n)}let l="";if(t.crossFolder?l=i?.cross?.parentBlurb??"":l=this.parentBlurbFor(t.node),l){let h=s.createDiv({cls:"stashpad-suggest-preview"});h.appendText("Parent: "),this.highlightInto(h,l,n)}let c=t.crossFolder?this.buildCrossBreadcrumb(t):this.buildLocalBreadcrumb(t.node),d=t.crossFolder??this.opts.localFolder??null;if(d||c){let h=s.createDiv({cls:"stashpad-suggest-breadcrumb"}),m=[d?d.split("/").pop()||d:"",c].filter(g=>g&&g.length>0).join(" \u203A ");m&&h.setText(m)}let p=i?this.createdMsFor(i):null;if(p!=null||a){let h=e.createDiv({cls:"stashpad-suggest-rail"});if(p!=null){let u=h.createDiv({cls:"stashpad-suggest-time"});u.setText(this.formatRelativeTime(p)),u.title=(0,ut.moment)(p).format("YYYY-MM-DD HH:mm")}a&&h.createDiv({cls:"stashpad-suggest-folder-badge",text:a.split("/").pop()||a})}}formatRelativeTime(t){let e=(0,ut.moment)(t),s=(0,ut.moment)().startOf("day").diff((0,ut.moment)(t).startOf("day"),"days");return s===0?e.format("h:mm a"):s===1?"yesterday":s>1&&s<7?`${s}d ago`:s>=7&&s<30?`${Math.floor(s/7)}w ago`:s>=30&&s<365?e.format("MMM D"):e.format("MMM D, YYYY")}highlightInto(t,e,s){if(!e)return;let i=s.filter(l=>l&&l.length>0);if(!i.length){t.appendText(e);return}let n=e.toLowerCase(),r=[];for(let l of i){let c=0;for(;(c=n.indexOf(l,c))!==-1;)r.push([c,c+l.length]),c+=l.length}if(!r.length){t.appendText(e);return}r.sort((l,c)=>l[0]-c[0]);let o=[];for(let l of r){let c=o[o.length-1];c&&l[0]<=c[1]?c[1]=Math.max(c[1],l[1]):o.push([l[0],l[1]])}let a=0;for(let[l,c]of o)l>a&&t.appendText(e.slice(a,l)),t.createSpan({cls:"stashpad-suggest-match",text:e.slice(l,c)}),a=c;a<e.length&&t.appendText(e.slice(a))}buildLocalBreadcrumb(t){if(!t||!t.parent||t.parent===B)return"";let e=[],s=new Set([t.id]),i=this.tree.get(t.parent);for(;i&&i.id!==B&&!s.has(i.id);)s.add(i.id),e.unshift(this.titleFn(i)),i=i.parent&&i.parent!==B?this.tree.get(i.parent):null;return e.join(" \u203A ")}buildCrossBreadcrumb(t){if(!t.crossFolder)return"";if(!this.crossFolderIndex){this.crossFolderIndex=new Map;for(let a of this.notes){if(!a.cross)continue;let l=this.crossFolderIndex.get(a.cross.folder);l||(l=new Map,this.crossFolderIndex.set(a.cross.folder,l)),l.set(a.cross.id,a.cross)}}let e=this.crossFolderIndex.get(t.crossFolder);if(!e)return"";let s=t.id.replace(/^cross:/,""),i=e.get(s);if(!i)return"";let n=[],r=new Set([i.id]),o=i.parentId?e.get(i.parentId):null;for(;o&&!r.has(o.id);)r.add(o.id),n.unshift(o.title),o=o.parentId?e.get(o.parentId):null;return n.join(" \u203A ")}firstLineOfBody(t){if(!t)return"";let e=t.split(/\r?\n/);for(let s of e){let i=s.trim();if(i)return i}return""}parentBlurbFor(t){if(!t||!t.parent||t.parent===B)return"";let e=this.tree.get(t.parent);if(!e||!e.file)return"";let s=this.notes.find(i=>i.node?.id===e.id);return s?this.firstLineOfBody(s.body):""}onOpen(){if(super.onOpen(),this.opts.showFilterChips&&!ut.Platform.isMobile){let t=this.inputEl,e=this.resultContainerEl;if(!t||!e)return;this.mountFilterChipRow(t,e);return}}mountFilterChipRow(t,e){t.addEventListener("keydown",l=>{if(l.key==="["){l.preventDefault();let c=t.selectionStart??t.value.length,d=t.selectionEnd??c,p=t.value.slice(0,c),h=t.value.slice(c,d),u=t.value.slice(d);t.value=`${p}[${h}]${u}`;let m=c+1+h.length;t.setSelectionRange(m,m),t.dispatchEvent(new Event("input",{bubbles:!0}));return}if(l.key==="]"){let c=t.selectionStart??-1;c>=0&&t.value[c]==="]"&&(l.preventDefault(),t.setSelectionRange(c+1,c+1));return}if(l.key==="Backspace"&&!l.metaKey&&!l.ctrlKey&&!l.altKey&&t.selectionStart===t.selectionEnd){let c=t.selectionStart??-1;if(c>0&&t.value[c-1]==="["&&t.value[c]==="]"){l.preventDefault();let d=t.value.slice(0,c-1),p=t.value.slice(c+1);t.value=`${d}${p}`,t.setSelectionRange(c-1,c-1),t.dispatchEvent(new Event("input",{bubbles:!0}))}}});let s=document.createElement("div");s.className="stashpad-search-filter-row";let i=document.createElement("span");i.className="stashpad-search-filter-label",i.textContent="Filters:",s.appendChild(i);let n=document.createElement("button");n.className="stashpad-search-filter-chip",n.type="button",n.textContent="in:[parent note]",n.title='Insert "in:" \u2014 filter by parent note.',n.addEventListener("mousedown",l=>{l.preventDefault()}),n.addEventListener("click",l=>{l.preventDefault(),this.appendFilterToInput(t,"in","")}),n.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),l.stopPropagation(),n.click())}),s.appendChild(n);let r=document.createElement("button");r.className="stashpad-search-filter-chip stashpad-search-filter-when",r.type="button",r.textContent="when:[date / day / timeframe]",r.title="Open the time-filter builder (Before / On / After / Between).",r.addEventListener("mousedown",l=>{l.preventDefault()}),r.addEventListener("click",l=>{l.preventDefault(),this.toggleWhenBuilder(t,s)}),r.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),l.stopPropagation(),r.click())}),s.appendChild(r),e.parentElement?.insertBefore(s,e);let o=new ut.Scope(this.scope),a=l=>{let c=document.activeElement;return c?.classList?.contains("stashpad-search-filter-chip")?(l.preventDefault(),c.click(),!1):l.key==="Enter"&&!l.isComposing?(l.preventDefault(),this.selectActiveSuggestion?.(l),!1):!0};o.register([],"Enter",a),o.register([]," ",a),o.register(["Mod"],"f",l=>{l.preventDefault();let c=this.inputEl;return c&&(c.focus(),c.select()),!1}),o.register([],"Tab",l=>{let c=this.modalEl,d=this.inputEl;if(!c)return!0;let p=Array.from(c.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(m=>!m.hasAttribute("disabled")&&m.tabIndex!==-1&&m.offsetParent!==null);if(p.length===0)return!0;let h=document.activeElement,u=h?p.indexOf(h):-1;if(l.shiftKey){if(u<=0)return l.preventDefault(),p[p.length-1].focus(),!1}else if(u===p.length-1)return l.preventDefault(),(d??p[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(o),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(o)}catch{}})}appendFilterToInput(t,e,s){let i=t.value,r=`${i.length>0&&!/\s$/.test(i)?" ":""}${e}: [`,o="]",a=s;t.value=`${i}${r}${a}${o}`;let l=i.length+r.length+a.length;if(t.setSelectionRange(l,l+0),!a){let c=i.length+r.length;t.setSelectionRange(c,c)}t.focus(),t.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(t,e){let s=this.modalEl;if(this.whenBuilderEl){this.whenBuilderEl.remove(),this.whenBuilderEl=null,s?.removeClass("is-when-builder-open");return}s?.addClass("is-when-builder-open");let i=document.createElement("div");i.className="stashpad-when-builder";let n=document.createElement("div");n.className="stashpad-when-tabs";let r=[{id:"before",label:"Before"},{id:"on",label:"On"},{id:"after",label:"After"},{id:"between",label:"Between"}],o={};for(let m of r){let g=document.createElement("button");g.type="button",g.className="stashpad-when-tab",g.textContent=m.label,this.whenMode===m.id&&g.addClass("is-active"),g.addEventListener("mousedown",y=>y.preventDefault()),g.addEventListener("click",y=>{if(y.preventDefault(),this.whenMode===m.id)return;let S=this.whenMode;S!=="between"&&m.id==="between"?(this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""):S==="between"&&m.id!=="between"&&(!this.whenSingleText&&this.whenBetweenEndText&&(this.whenSingleText=this.whenBetweenEndText),!this.whenSingleDate&&this.whenBetweenEndDate&&(this.whenSingleDate=this.whenBetweenEndDate,this.whenSingleTime=this.whenBetweenEndTime),this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""),this.whenMode=m.id;for(let k in o)o[k].toggleClass("is-active",k===m.id);u()}),o[m.id]=g,n.appendChild(g)}i.appendChild(n);let a=document.createElement("div");a.className="stashpad-when-body",i.appendChild(a);let l=(m,g,y="single")=>{let S=(0,ut.moment)().format("YYYY-MM-DD"),k=!g||g===S;if(y==="betweenStart")return"00:00";if(y==="betweenEnd")return"23:59";switch(m){case"after":return"00:00";case"on":return k?(0,ut.moment)().format("HH:mm"):"23:59";case"before":return k?(0,ut.moment)().format("HH:mm"):"23:59";default:return"23:59"}},c=(m,g)=>{m.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),y.stopPropagation(),g()):y.key==="Escape"&&(y.preventDefault(),y.stopPropagation(),this.closeWhenBuilder())})},d=(m,g)=>{let y=m.selectionStart??m.value.length,S=m.selectionEnd??m.value.length,x=`${y>0&&!/\s$/.test(m.value.slice(0,y))?" ":""}${g}`,I=m.value.slice(0,y)+x+m.value.slice(S);m.value=I;let E=y+x.length;m.setSelectionRange(E,E),m.focus(),m.dispatchEvent(new Event("input",{bubbles:!0}))},p=(m,g)=>{let S=m.slice(0,g).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return S?S[1]:null},h=(m,g,y,S)=>{let k=a.createDiv({cls:"stashpad-when-input-wrap has-icons"}),x=k.createDiv({cls:"stashpad-when-icon-slot"}),I=x.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});I.type="button",I.title="Pick date",(0,ut.setIcon)(I,"calendar-days");let E=x.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});E.tabIndex=-1;let D=k.createDiv({cls:"stashpad-when-icon-slot"}),$=D.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});$.type="button",$.title="Pick time",(0,ut.setIcon)($,"clock");let F=k.createDiv({cls:"stashpad-when-icon-slot"}),P=F.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});P.type="button",P.title="Pick day",(0,ut.setIcon)(P,"calendar");let b=k.createDiv({cls:"stashpad-when-icon-slot"}),H=b.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});H.type="button",H.title="Pick timeframe",(0,ut.setIcon)(H,"history");let et=k.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:m}});et.value=g(),et.addEventListener("input",()=>y(et.value));let V=k.createEl("button",{cls:"stashpad-when-clear"});V.type="button",V.textContent="\xD7",V.title="Clear";for(let M of[I,$,P,H,V])M.addEventListener("mousedown",J=>J.preventDefault());let W=null,z=(M,J)=>{W&&W();let q=M.createDiv({cls:"stashpad-when-popover"}),Y=new ut.Scope(this.scope),pt=null,mt=it=>{pt=it},nt=!1,lt=it=>{!q.contains(it.target)&&it.target!==M&&!M.contains(it.target)&&ot()},ot=()=>{if(!nt){nt=!0,q.remove(),document.removeEventListener("mousedown",lt,!0);try{this.app.keymap?.popScope(Y)}catch{}W===ot&&(W=null)}};W=ot,Y.register([],"Escape",it=>(it.preventDefault(),ot(),!1)),Y.register([],"Enter",it=>(it.preventDefault(),pt&&pt(),!1));try{J(q,ot,mt)}catch(it){console.error("[stashpad] popover fill threw:",it),q.remove(),W=null;return}this.app.keymap?.pushScope(Y),this.pendingCleanups.push(ot),setTimeout(()=>document.addEventListener("mousedown",lt,!0),0)};H.addEventListener("click",M=>{M.preventDefault(),z(b,(J,q,Y)=>{let pt=this.whenMode==="on",mt=(R,L)=>{if(!pt)return`${R}${L}`;let T={d:"days",w:"weeks",m:"months",y:"years"}[L];return(0,ut.moment)().subtract(R,T).format("YYYY-MM-DD")},nt=J.createDiv({cls:"stashpad-when-pop-row"}),lt=[{label:"Last 7d",n:7,unit:"d"},{label:"Last 30d",n:30,unit:"d"},{label:"This week",n:1,unit:"w"},{label:"This month",n:1,unit:"m"}];for(let R of lt){let L=nt.createEl("button",{cls:"stashpad-when-pop-chip",text:R.label});L.type="button",L.addEventListener("mousedown",T=>T.preventDefault()),L.addEventListener("click",T=>{T.preventDefault(),d(et,mt(R.n,R.unit)),q()})}let ot=J.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-builder"});ot.createSpan({text:"Last",cls:"stashpad-when-pop-label"});let it=ot.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),dt=ot.createEl("select",{cls:"stashpad-when-pop-unit"});for(let R of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let L=dt.createEl("option",{text:R.label});L.value=R.v}let ht=ot.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});ht.type="button";let w=()=>{let R=parseInt(it.value,10);!Number.isFinite(R)||R<1||(d(et,mt(R,dt.value)),q())};ht.addEventListener("mousedown",R=>R.preventDefault()),ht.addEventListener("click",R=>{R.preventDefault(),w()}),Y(w),it.focus(),it.select()})});let Q=(M,J,q,Y,pt)=>{z(J,(mt,nt,lt)=>{mt.addClass("stashpad-when-pop-time");let ot=pt,it=mt.createDiv({cls:"stashpad-when-time-display"}),dt=it.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});dt.value=String(q),it.createSpan({cls:"stashpad-when-time-colon",text:":"});let ht=it.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});ht.value=String(Y).padStart(2,"0");let w=it.createDiv({cls:"stashpad-when-time-period"}),R=w.createEl("button",{cls:"stashpad-when-time-ampm",text:"AM"});R.type="button";let L=w.createEl("button",{cls:"stashpad-when-time-ampm",text:"PM"});L.type="button";let T=()=>{R.toggleClass("is-active",ot==="am"),L.toggleClass("is-active",ot==="pm")};T(),R.addEventListener("mousedown",G=>G.preventDefault()),L.addEventListener("mousedown",G=>G.preventDefault()),R.addEventListener("click",G=>{G.preventDefault(),ot="am",T()}),L.addEventListener("click",G=>{G.preventDefault(),ot="pm",T()});let C=dt;dt.addEventListener("focus",()=>{C=dt,dt.select()}),ht.addEventListener("focus",()=>{C=ht,ht.select()});let A=()=>{let rt=(parseInt(dt.value||"0",10)||0)>12;R.toggleClass("is-disabled",rt),L.toggleClass("is-disabled",rt),R.disabled=rt,L.disabled=rt},j=G=>{let rt=G.value.replace(/\D/g,"").slice(0,2);if(rt===""){G.value="",G===dt&&A();return}let bt=parseInt(rt,10);G===dt?bt>24&&(bt=24):bt>59&&(bt=59),G.value=String(bt),G===dt&&A()};for(let G of[dt,ht])G.addEventListener("input",()=>j(G));A();let U=()=>{let G=parseInt(dt.value||"12",10)||12,rt=parseInt(ht.value||"0",10)||0,bt=G>12?`${G}:${String(rt).padStart(2,"0")}`:`${G}:${String(rt).padStart(2,"0")}${ot}`;d(M,bt),nt()};lt(U);let _=[dt,ht,R,L],K=(G,rt)=>{let bt=_.indexOf(G);if(bt===-1)return;let Ct=_.length,Et=(bt+rt+Ct)%Ct;_[Et].focus()},X=G=>{G.addEventListener("keydown",rt=>{rt.key==="Enter"?(rt.preventDefault(),rt.stopPropagation(),U()):rt.key==="Escape"?(rt.preventDefault(),rt.stopPropagation(),nt()):rt.key==="Tab"&&(rt.preventDefault(),rt.stopPropagation(),K(G,rt.shiftKey?-1:1))})},Z=mt.createDiv({cls:"stashpad-when-time-pad"}),st=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],ft=null;for(let G of st){let rt=Z.createEl("button",{cls:"stashpad-when-time-padbtn"});rt.type="button",G==="backspace"?(0,ut.setIcon)(rt,"delete"):G==="insert"?(rt.setText("OK"),ft=rt):rt.setText(G),G==="insert"&&rt.addClass("is-go"),rt.addEventListener("mousedown",bt=>bt.preventDefault()),rt.addEventListener("click",bt=>{if(bt.preventDefault(),G==="insert"){U();return}if(G==="backspace"){C.value=C.value.slice(0,-1),j(C),C.focus();return}let Ct=C.selectionStart===0&&C.selectionEnd===C.value.length&&C.value.length>0,Et=2,yt=Ct||C.value.length>=Et?G:C.value+G;C.value=yt,j(C),C.focus(),C.setSelectionRange(C.value.length,C.value.length),C===dt&&C.value.length>=Et&&(ht.focus(),ht.select())})}ft&&_.push(ft);for(let G of _)X(G);dt.focus(),dt.select()})};P.addEventListener("click",M=>{M.preventDefault(),z(F,(J,q,Y)=>{let pt=J.createDiv({cls:"stashpad-when-pop-row"});for(let it of["Today","Yesterday"]){let dt=pt.createEl("button",{cls:"stashpad-when-pop-chip",text:it});dt.type="button",dt.addEventListener("mousedown",ht=>ht.preventDefault()),dt.addEventListener("click",ht=>{ht.preventDefault(),d(et,it),q()})}let mt=J.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),nt=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],ot=((0,ut.moment)().day()+6)%7;for(let it=0;it<nt.length;it++){let dt=nt[it],ht=mt.createEl("button",{cls:"stashpad-when-pop-chip",text:dt.slice(0,3)});ht.type="button",ht.title=dt,it===ot&&ht.addClass("is-today"),ht.addEventListener("mousedown",w=>w.preventDefault()),ht.addEventListener("click",w=>{if(w.preventDefault(),S==="betweenEnd"){let R=it,L=(0,ut.moment)().startOf("day"),T=(L.day()+6)%7,C=(R-T+7)%7;C===0&&(C=7);let A=L.clone().add(C,"days").format("YYYY-MM-DD");d(et,A)}else d(et,dt);q()})}})});let N=(M,J)=>{M.value||(M.value=J);let q=M;if(typeof q.showPicker=="function")try{q.showPicker();return}catch{}M.focus(),M.click()};return I.addEventListener("click",M=>{M.preventDefault(),N(E,(0,ut.moment)().format("YYYY-MM-DD"))}),E.addEventListener("change",()=>{E.value&&d(et,E.value)}),$.addEventListener("click",M=>{M.preventDefault();let J=et.selectionStart??et.value.length,q=p(et.value,J),Y=l(this.whenMode,q,S),[pt,mt]=Y.split(":"),nt=parseInt(pt,10),lt=parseInt(mt,10),ot=nt%12;ot===0&&(ot=12);let it=nt>=12?"pm":"am";Q(et,D,ot,lt,it)}),V.addEventListener("click",M=>{M.preventDefault(),et.value="",y(""),et.focus()}),et},u=()=>{if(a.empty(),this.whenMode==="between"){let m=h("start (date / day / timeframe)",()=>this.whenSingleText,I=>{this.whenSingleText=I},"betweenStart"),g=h("end (date / day / timeframe)",()=>this.whenBetweenEndText,I=>{this.whenBetweenEndText=I},"betweenEnd"),y=a.createDiv({cls:"stashpad-when-actions"}),S=y.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});S.type="button",S.addEventListener("mousedown",I=>I.preventDefault());let k=()=>{let I=m.value.trim(),E=g.value.trim();I&&this.appendFilterToInput(t,"after",I),E&&this.appendFilterToInput(t,"before",E),this.closeWhenBuilder()};S.addEventListener("click",I=>{I.preventDefault(),k()});let x=y.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});x.type="button",x.addEventListener("mousedown",I=>I.preventDefault()),x.addEventListener("click",I=>{I.preventDefault(),this.closeWhenBuilder()}),c(m,k),c(g,k),m.focus(),m.setSelectionRange(m.value.length,m.value.length)}else{let m=h("date / day / timeframe",()=>this.whenSingleText,x=>{this.whenSingleText=x},"single"),g=a.createDiv({cls:"stashpad-when-actions"}),y=g.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});y.type="button",y.addEventListener("mousedown",x=>x.preventDefault());let S=()=>{let x=m.value.trim();x&&this.appendFilterToInput(t,this.whenMode,x),this.closeWhenBuilder()};y.addEventListener("click",x=>{x.preventDefault(),S()});let k=g.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});k.type="button",k.addEventListener("mousedown",x=>x.preventDefault()),k.addEventListener("click",x=>{x.preventDefault(),this.closeWhenBuilder()}),c(m,S),m.focus(),m.setSelectionRange(m.value.length,m.value.length)}};u(),e.parentElement?.insertBefore(i,e.nextSibling),this.whenBuilderEl=i}closeWhenBuilder(){if(!this.whenBuilderEl)return;this.whenBuilderEl.remove(),this.whenBuilderEl=null,this.modalEl?.removeClass("is-when-builder-open")}onChooseSuggestion(t){if(t.kind==="create"&&this.opts.onCreate){this.opts.onCreate(this.inputEl?.value??"");return}if(t.kind==="folder-open"&&t.id==="__folder_picker__"){let e=this.opts.folderResults?.()??[];if(!e.length)return;let s=this.inputEl?.value??"",i=!1,n=p=>{i=!0;let h=p.split("/").pop()??p;this.opts.onPick({id:`folder:${p}`,label:`Open folder \u201C${h}\u201D in a new tab`,node:null,kind:"folder-open",folder:p})},r=new bs(this.app,e,n),o=r.onClose.bind(r),a=this.tree,l=this.titleFn,c=this.opts,d=this.app;r.onClose=()=>{if(o(),!i){let p=new v(d,a,l,c);p.open(),setTimeout(()=>{let h=p.inputEl;h&&(s&&(h.value=s,h.dispatchEvent(new Event("input",{bubbles:!0}))),h.focus(),h.setSelectionRange(h.value.length,h.value.length))},0)}},r.open();return}this.opts.onPick(t)}},bs=class extends ut.FuzzySuggestModal{constructor(t,e,s){super(t);this.folders=e;this.onChosen=s;this.setPlaceholder("Open which folder?")}getItems(){return this.folders}getItemText(t){let e=t.split("/").pop()??t;return e===t?t:`${e} \u2014 ${t}`}onChooseItem(t){this.onChosen(t)}};Gt();var Cs=hi(qs()),Ge=require("obsidian");Rt();xt();var ve="stash",Gs=1,ks=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function Js(v,f){let t=new Cs.default,e=Si([...f.rootNotes,...f.allDescendants]),s=new Map,i=[];for(let r of e){let o=await v.vault.read(r.file),a=o,l=ki(o);for(let c of l){let d=v.metadataCache.getFirstLinkpathDest(c,r.file.path);if(!d){i.push(`Missing attachment "${c}" in ${r.file.path}`);continue}let p=d.name;s.has(p)||s.set(p,await v.vault.readBinary(d)),a=Ci(a,c,p)}a=xi(a,v,r.file.path),t.file(`notes/${r.file.name}`,a)}for(let[r,o]of s)t.file(`attachments/${r}`,o);let n={stashSchema:Gs,exportedAt:new Date().toISOString(),sourceFolder:f.sourceFolder,noteCount:e.length,rootIds:f.rootNotes.map(r=>r.id)};return t.file("manifest.json",JSON.stringify(n,null,2)),i.length&&t.file("warnings.txt",i.join(` -`)),t.generateAsync({type:"uint8array",compression:"DEFLATE",compressionOptions:{level:6}})}async function Je(v,f,t,e){let s=await Cs.default.loadAsync(f),i=s.file("manifest.json");if(!i)throw new Error("Not a valid .stash package: missing manifest.json");let n=JSON.parse(await i.async("string"));if(typeof n.stashSchema!="number"||n.stashSchema>Gs)throw new Error(`Unsupported .stash schema: v${n.stashSchema}`);await Zs(v,t);let r=Object.values(s.files).filter(g=>!g.dir&&g.name.startsWith("notes/")&&g.name.endsWith(".md")),o=[];for(let g of r){let y=await g.async("string"),{fm:S,body:k}=Qs(y);o.push({originalName:g.name.slice(6),fm:S,body:k})}let a=new Map,l=0;for(let g of o){let y=g.fm.id;y&&(e.has(y)||a.has(y)?(a.set(y,`${y}-${Ft(4)}-Imported`),l++):a.set(y,y))}let c=new Date().toISOString(),d=[],p=`${t}/_attachments`,h=0,u=Object.values(s.files).filter(g=>!g.dir&&g.name.startsWith("attachments/"));u.length>0&&await Zs(v,p);for(let g of u){let y=g.name.slice(12);if(!y)continue;let S=`${p}/${y}`;if(await v.vault.adapter.exists(S))continue;let k=await g.async("arraybuffer");await v.vault.createBinary(S,k),h++}let m=0;for(let g of o){let y=g.fm.id;if(!y){d.push(`Skipped ${g.originalName} \u2014 no id in frontmatter`);continue}let S=a.get(y),k=g.fm.parent??null,x=k;k&&k!==B&&a.has(k)?x=a.get(k):k&&k!==B&&!a.has(k)&&(x=B);let I=Ti(g.body,p),E={...g.fm,id:S,parent:x,import_date:c};Array.isArray(E.attachments)&&(E.attachments=E.attachments.map(P=>`${p}/${Xs(P)}`));let D=ti(E,I),$=S===y?g.originalName:Ei(g.originalName,y,S),F=`${t}/${$}`;await v.vault.adapter.exists(F)&&($=`${$.replace(/\.md$/,"")}-${Ft(4)}.md`,F=`${t}/${$}`),await v.vault.create(F,D),m++}return{notesWritten:m,attachmentsWritten:h,collisionsRenamed:l,warnings:d}}function Si(v){let f=new Set,t=[];for(let e of v)f.has(e.id)||(f.add(e.id),t.push(e));return t}function ki(v){let f=new Set,t;for(ks.lastIndex=0;(t=ks.exec(v))!==null;)f.add(t[1]);return[...f]}function Ci(v,f,t){return v.replace(new RegExp(`!\\[\\[${Fi(f)}(\\|[^\\]]+)?\\]\\]`,"g"),(e,s)=>`![[${t}${s??""}]]`)}function Ti(v,f){return v.replace(ks,(t,e,s)=>e.includes("/")?t:t.replace(e,`${f}/${e}`))}function xi(v,f,t){let e=Qs(v);if(!e.fm.attachments||!Array.isArray(e.fm.attachments))return v;let s=e.fm.attachments.map(n=>{let r=f.metadataCache.getFirstLinkpathDest(n,t);return r?r.name:Xs(n)}),i={...e.fm,attachments:s};return ti(i,e.body)}function Fi(v){return v.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Xs(v){let f=v.lastIndexOf("/");return f<0?v:v.slice(f+1)}function Ei(v,f,t){return v.includes(f)?v.replace(f,t):v.replace(/\.md$/,`-${t}.md`)}function Qs(v){if(!v.startsWith("---"))return{fm:{},body:v};let f=v.indexOf(` ----`,3);if(f<0)return{fm:{},body:v};let t=v.slice(3,f).replace(/^\n/,""),e=v.slice(f+4),s={};try{s=(0,Ge.parseYaml)(t)??{}}catch{s={}}let i=e.startsWith(` -`)?e.slice(1):e;return{fm:s,body:i}}function ti(v,f){return`--- -${(0,Ge.stringifyYaml)(v).trimEnd()} +`)}renderSuggestion(t,e){if(e.addClass("stashpad-suggest-item"),t.kind==="create"){e.createDiv({cls:"stashpad-suggest-create",text:t.label});return}if(t.kind==="folder-open"){e.addClass("is-folder-open"),e.createDiv({cls:"stashpad-suggest-title",text:t.label}),t.folder?e.createDiv({cls:"stashpad-suggest-preview",text:t.folder}):e.createDiv({cls:"stashpad-suggest-preview",text:"Click to choose a folder\u2026"});return}t.crossFolder&&e.addClass("is-cross-folder"),e.addClass("stashpad-suggest-row");let s=e.createDiv({cls:"stashpad-suggest-body"}),i=this.notes.find(d=>t.crossFolder?d.cross?.id===t.id.replace(/^cross:/,""):d.node?.id===t.id),n=Xs(this.inputEl?.value??"").text,r=this.firstLineOfBody(i?.body??"")||t.label.trim(),o=s.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(o,r,n);let a=t.crossFolder??this.opts.localFolder??null;if(t.bodyPreview&&t.matchLine!=null&&t.matchLine>=0){let d=s.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(d,t.bodyPreview,n)}let l="";if(t.crossFolder?l=i?.cross?.parentBlurb??"":l=this.parentBlurbFor(t.node),l){let d=s.createDiv({cls:"stashpad-suggest-preview"});d.appendText("Parent: "),this.highlightInto(d,l,n)}let c=t.crossFolder?this.buildCrossBreadcrumb(t):this.buildLocalBreadcrumb(t.node),h=t.crossFolder??this.opts.localFolder??null;if(h||c){let d=s.createDiv({cls:"stashpad-suggest-breadcrumb"}),m=[h?h.split("/").pop()||h:"",c].filter(v=>v&&v.length>0).join(" \u203A ");m&&d.setText(m)}let u=i?this.createdMsFor(i):null;if(u!=null||a){let d=e.createDiv({cls:"stashpad-suggest-rail"});if(u!=null){let p=d.createDiv({cls:"stashpad-suggest-time"});p.setText(this.formatRelativeTime(u)),p.title=(0,dt.moment)(u).format("YYYY-MM-DD HH:mm")}a&&d.createDiv({cls:"stashpad-suggest-folder-badge",text:a.split("/").pop()||a})}}formatRelativeTime(t){let e=(0,dt.moment)(t),s=(0,dt.moment)().startOf("day").diff((0,dt.moment)(t).startOf("day"),"days");return s===0?e.format("h:mm a"):s===1?"yesterday":s>1&&s<7?`${s}d ago`:s>=7&&s<30?`${Math.floor(s/7)}w ago`:s>=30&&s<365?e.format("MMM D"):e.format("MMM D, YYYY")}highlightInto(t,e,s){if(!e)return;let i=s.filter(l=>l&&l.length>0);if(!i.length){t.appendText(e);return}let n=e.toLowerCase(),r=[];for(let l of i){let c=0;for(;(c=n.indexOf(l,c))!==-1;)r.push([c,c+l.length]),c+=l.length}if(!r.length){t.appendText(e);return}r.sort((l,c)=>l[0]-c[0]);let o=[];for(let l of r){let c=o[o.length-1];c&&l[0]<=c[1]?c[1]=Math.max(c[1],l[1]):o.push([l[0],l[1]])}let a=0;for(let[l,c]of o)l>a&&t.appendText(e.slice(a,l)),t.createSpan({cls:"stashpad-suggest-match",text:e.slice(l,c)}),a=c;a<e.length&&t.appendText(e.slice(a))}buildLocalBreadcrumb(t){if(!t||!t.parent||t.parent===R)return"";let e=[],s=new Set([t.id]),i=this.tree.get(t.parent);for(;i&&i.id!==R&&!s.has(i.id);)s.add(i.id),e.unshift(this.titleFn(i)),i=i.parent&&i.parent!==R?this.tree.get(i.parent):null;return e.join(" \u203A ")}buildCrossBreadcrumb(t){if(!t.crossFolder)return"";if(!this.crossFolderIndex){this.crossFolderIndex=new Map;for(let a of this.notes){if(!a.cross)continue;let l=this.crossFolderIndex.get(a.cross.folder);l||(l=new Map,this.crossFolderIndex.set(a.cross.folder,l)),l.set(a.cross.id,a.cross)}}let e=this.crossFolderIndex.get(t.crossFolder);if(!e)return"";let s=t.id.replace(/^cross:/,""),i=e.get(s);if(!i)return"";let n=[],r=new Set([i.id]),o=i.parentId?e.get(i.parentId):null;for(;o&&!r.has(o.id);)r.add(o.id),n.unshift(o.title),o=o.parentId?e.get(o.parentId):null;return n.join(" \u203A ")}firstLineOfBody(t){if(!t)return"";let e=t.split(/\r?\n/);for(let s of e){let i=s.trim();if(i)return i}return""}parentBlurbFor(t){if(!t||!t.parent||t.parent===R)return"";let e=this.tree.get(t.parent);if(!e||!e.file)return"";let s=this.notes.find(i=>i.node?.id===e.id);return s?this.firstLineOfBody(s.body):""}onOpen(){if(super.onOpen(),this.opts.showFilterChips&&!dt.Platform.isMobile){let t=this.inputEl,e=this.resultContainerEl;if(!t||!e)return;this.mountFilterChipRow(t,e);return}if(dt.Platform.isMobile){let t=this.inputEl;t&&t.focus()}}mountFilterChipRow(t,e){t.addEventListener("keydown",l=>{if(l.key==="["){l.preventDefault();let c=t.selectionStart??t.value.length,h=t.selectionEnd??c,u=t.value.slice(0,c),d=t.value.slice(c,h),p=t.value.slice(h);t.value=`${u}[${d}]${p}`;let m=c+1+d.length;t.setSelectionRange(m,m),t.dispatchEvent(new Event("input",{bubbles:!0}));return}if(l.key==="]"){let c=t.selectionStart??-1;c>=0&&t.value[c]==="]"&&(l.preventDefault(),t.setSelectionRange(c+1,c+1));return}if(l.key==="Backspace"&&!l.metaKey&&!l.ctrlKey&&!l.altKey&&t.selectionStart===t.selectionEnd){let c=t.selectionStart??-1;if(c>0&&t.value[c-1]==="["&&t.value[c]==="]"){l.preventDefault();let h=t.value.slice(0,c-1),u=t.value.slice(c+1);t.value=`${h}${u}`,t.setSelectionRange(c-1,c-1),t.dispatchEvent(new Event("input",{bubbles:!0}))}}});let s=document.createElement("div");s.className="stashpad-search-filter-row";let i=document.createElement("span");i.className="stashpad-search-filter-label",i.textContent="Filters:",s.appendChild(i);let n=document.createElement("button");n.className="stashpad-search-filter-chip",n.type="button",n.textContent="in:[parent note]",n.title='Insert "in:" \u2014 filter by parent note.',n.addEventListener("mousedown",l=>{l.preventDefault()}),n.addEventListener("click",l=>{l.preventDefault(),this.appendFilterToInput(t,"in","")}),n.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),l.stopPropagation(),n.click())}),s.appendChild(n);let r=document.createElement("button");r.className="stashpad-search-filter-chip stashpad-search-filter-when",r.type="button",r.textContent="when:[date / day / timeframe]",r.title="Open the time-filter builder (Before / On / After / Between).",r.addEventListener("mousedown",l=>{l.preventDefault()}),r.addEventListener("click",l=>{l.preventDefault(),this.toggleWhenBuilder(t,s)}),r.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),l.stopPropagation(),r.click())}),s.appendChild(r),e.parentElement?.insertBefore(s,e);let o=new dt.Scope(this.scope),a=l=>{let c=document.activeElement;return c?.classList?.contains("stashpad-search-filter-chip")?(l.preventDefault(),c.click(),!1):l.key==="Enter"&&!l.isComposing?(l.preventDefault(),this.selectActiveSuggestion?.(l),!1):!0};o.register([],"Enter",a),o.register([]," ",a),o.register(["Mod"],"f",l=>{l.preventDefault();let c=this.inputEl;return c&&(c.focus(),c.select()),!1}),o.register([],"Tab",l=>{let c=this.modalEl,h=this.inputEl;if(!c)return!0;let u=Array.from(c.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(m=>!m.hasAttribute("disabled")&&m.tabIndex!==-1&&m.offsetParent!==null);if(u.length===0)return!0;let d=document.activeElement,p=d?u.indexOf(d):-1;if(l.shiftKey){if(p<=0)return l.preventDefault(),u[u.length-1].focus(),!1}else if(p===u.length-1)return l.preventDefault(),(h??u[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(o),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(o)}catch{}})}appendFilterToInput(t,e,s){let i=t.value,r=`${i.length>0&&!/\s$/.test(i)?" ":""}${e}: [`,o="]",a=s;t.value=`${i}${r}${a}${o}`;let l=i.length+r.length+a.length;if(t.setSelectionRange(l,l+0),!a){let c=i.length+r.length;t.setSelectionRange(c,c)}t.focus(),t.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(t,e){let s=this.modalEl;if(this.whenBuilderEl){this.whenBuilderEl.remove(),this.whenBuilderEl=null,s?.removeClass("is-when-builder-open");return}s?.addClass("is-when-builder-open");let i=document.createElement("div");i.className="stashpad-when-builder";let n=document.createElement("div");n.className="stashpad-when-tabs";let r=[{id:"before",label:"Before"},{id:"on",label:"On"},{id:"after",label:"After"},{id:"between",label:"Between"}],o={};for(let m of r){let v=document.createElement("button");v.type="button",v.className="stashpad-when-tab",v.textContent=m.label,this.whenMode===m.id&&v.addClass("is-active"),v.addEventListener("mousedown",y=>y.preventDefault()),v.addEventListener("click",y=>{if(y.preventDefault(),this.whenMode===m.id)return;let b=this.whenMode;b!=="between"&&m.id==="between"?(this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""):b==="between"&&m.id!=="between"&&(!this.whenSingleText&&this.whenBetweenEndText&&(this.whenSingleText=this.whenBetweenEndText),!this.whenSingleDate&&this.whenBetweenEndDate&&(this.whenSingleDate=this.whenBetweenEndDate,this.whenSingleTime=this.whenBetweenEndTime),this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""),this.whenMode=m.id;for(let k in o)o[k].toggleClass("is-active",k===m.id);p()}),o[m.id]=v,n.appendChild(v)}i.appendChild(n);let a=document.createElement("div");a.className="stashpad-when-body",i.appendChild(a);let l=(m,v,y="single")=>{let b=(0,dt.moment)().format("YYYY-MM-DD"),k=!v||v===b;if(y==="betweenStart")return"00:00";if(y==="betweenEnd")return"23:59";switch(m){case"after":return"00:00";case"on":return k?(0,dt.moment)().format("HH:mm"):"23:59";case"before":return k?(0,dt.moment)().format("HH:mm"):"23:59";default:return"23:59"}},c=(m,v)=>{m.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),y.stopPropagation(),v()):y.key==="Escape"&&(y.preventDefault(),y.stopPropagation(),this.closeWhenBuilder())})},h=(m,v)=>{let y=m.selectionStart??m.value.length,b=m.selectionEnd??m.value.length,C=`${y>0&&!/\s$/.test(m.value.slice(0,y))?" ":""}${v}`,E=m.value.slice(0,y)+C+m.value.slice(b);m.value=E;let I=y+C.length;m.setSelectionRange(I,I),m.focus(),m.dispatchEvent(new Event("input",{bubbles:!0}))},u=(m,v)=>{let b=m.slice(0,v).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return b?b[1]:null},d=(m,v,y,b)=>{let k=a.createDiv({cls:"stashpad-when-input-wrap has-icons"}),C=k.createDiv({cls:"stashpad-when-icon-slot"}),E=C.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});E.type="button",E.title="Pick date",(0,dt.setIcon)(E,"calendar-days");let I=C.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});I.tabIndex=-1;let A=k.createDiv({cls:"stashpad-when-icon-slot"}),O=A.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});O.type="button",O.title="Pick time",(0,dt.setIcon)(O,"clock");let F=k.createDiv({cls:"stashpad-when-icon-slot"}),D=F.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});D.type="button",D.title="Pick day",(0,dt.setIcon)(D,"calendar");let S=k.createDiv({cls:"stashpad-when-icon-slot"}),B=S.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});B.type="button",B.title="Pick timeframe",(0,dt.setIcon)(B,"history");let tt=k.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:m}});tt.value=v(),tt.addEventListener("input",()=>y(tt.value));let U=k.createEl("button",{cls:"stashpad-when-clear"});U.type="button",U.textContent="\xD7",U.title="Clear";for(let P of[E,O,D,B,U])P.addEventListener("mousedown",J=>J.preventDefault());let z=null,W=(P,J)=>{z&&z();let K=P.createDiv({cls:"stashpad-when-popover"}),Y=new dt.Scope(this.scope),ct=null,ht=st=>{ct=st},nt=!1,rt=st=>{!K.contains(st.target)&&st.target!==P&&!P.contains(st.target)&&at()},at=()=>{if(!nt){nt=!0,K.remove(),document.removeEventListener("mousedown",rt,!0);try{this.app.keymap?.popScope(Y)}catch{}z===at&&(z=null)}};z=at,Y.register([],"Escape",st=>(st.preventDefault(),at(),!1)),Y.register([],"Enter",st=>(st.preventDefault(),ct&&ct(),!1));try{J(K,at,ht)}catch(st){console.error("[stashpad] popover fill threw:",st),K.remove(),z=null;return}this.app.keymap?.pushScope(Y),this.pendingCleanups.push(at),setTimeout(()=>document.addEventListener("mousedown",rt,!0),0)};B.addEventListener("click",P=>{P.preventDefault(),W(S,(J,K,Y)=>{let ct=this.whenMode==="on",ht=(H,$)=>{if(!ct)return`${H}${$}`;let x={d:"days",w:"weeks",m:"months",y:"years"}[$];return(0,dt.moment)().subtract(H,x).format("YYYY-MM-DD")},nt=J.createDiv({cls:"stashpad-when-pop-row"}),rt=[{label:"Last 7d",n:7,unit:"d"},{label:"Last 30d",n:30,unit:"d"},{label:"This week",n:1,unit:"w"},{label:"This month",n:1,unit:"m"}];for(let H of rt){let $=nt.createEl("button",{cls:"stashpad-when-pop-chip",text:H.label});$.type="button",$.addEventListener("mousedown",x=>x.preventDefault()),$.addEventListener("click",x=>{x.preventDefault(),h(tt,ht(H.n,H.unit)),K()})}let at=J.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-builder"});at.createSpan({text:"Last",cls:"stashpad-when-pop-label"});let st=at.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),gt=at.createEl("select",{cls:"stashpad-when-pop-unit"});for(let H of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let $=gt.createEl("option",{text:H.label});$.value=H.v}let ft=at.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});ft.type="button";let w=()=>{let H=parseInt(st.value,10);!Number.isFinite(H)||H<1||(h(tt,ht(H,gt.value)),K())};ft.addEventListener("mousedown",H=>H.preventDefault()),ft.addEventListener("click",H=>{H.preventDefault(),w()}),Y(w),st.focus(),st.select()})});let X=(P,J,K,Y,ct)=>{W(J,(ht,nt,rt)=>{Te(ht,{seedH:K,seedM:Y,seedPeriod:ct,close:nt,setOnEnter:rt,onFinalize:at=>h(P,Os(at))})})};D.addEventListener("click",P=>{P.preventDefault(),W(F,(J,K,Y)=>{let ct=J.createDiv({cls:"stashpad-when-pop-row"});for(let st of["Today","Yesterday"]){let gt=ct.createEl("button",{cls:"stashpad-when-pop-chip",text:st});gt.type="button",gt.addEventListener("mousedown",ft=>ft.preventDefault()),gt.addEventListener("click",ft=>{ft.preventDefault(),h(tt,st),K()})}let ht=J.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),nt=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],at=((0,dt.moment)().day()+6)%7;for(let st=0;st<nt.length;st++){let gt=nt[st],ft=ht.createEl("button",{cls:"stashpad-when-pop-chip",text:gt.slice(0,3)});ft.type="button",ft.title=gt,st===at&&ft.addClass("is-today"),ft.addEventListener("mousedown",w=>w.preventDefault()),ft.addEventListener("click",w=>{if(w.preventDefault(),b==="betweenEnd"){let H=st,$=(0,dt.moment)().startOf("day"),x=($.day()+6)%7,T=(H-x+7)%7;T===0&&(T=7);let M=$.clone().add(T,"days").format("YYYY-MM-DD");h(tt,M)}else h(tt,gt);K()})}})});let L=(P,J)=>{P.value||(P.value=J);let K=P;if(typeof K.showPicker=="function")try{K.showPicker();return}catch{}P.focus(),P.click()};return E.addEventListener("click",P=>{P.preventDefault(),L(I,(0,dt.moment)().format("YYYY-MM-DD"))}),I.addEventListener("change",()=>{I.value&&h(tt,I.value)}),O.addEventListener("click",P=>{P.preventDefault();let J=tt.selectionStart??tt.value.length,K=u(tt.value,J),Y=l(this.whenMode,K,b),[ct,ht]=Y.split(":"),nt=parseInt(ct,10),rt=parseInt(ht,10),at=nt%12;at===0&&(at=12);let st=nt>=12?"pm":"am";X(tt,A,at,rt,st)}),U.addEventListener("click",P=>{P.preventDefault(),tt.value="",y(""),tt.focus()}),tt},p=()=>{if(a.empty(),this.whenMode==="between"){let m=d("start (date / day / timeframe)",()=>this.whenSingleText,E=>{this.whenSingleText=E},"betweenStart"),v=d("end (date / day / timeframe)",()=>this.whenBetweenEndText,E=>{this.whenBetweenEndText=E},"betweenEnd"),y=a.createDiv({cls:"stashpad-when-actions"}),b=y.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});b.type="button",b.addEventListener("mousedown",E=>E.preventDefault());let k=()=>{let E=m.value.trim(),I=v.value.trim();E&&this.appendFilterToInput(t,"after",E),I&&this.appendFilterToInput(t,"before",I),this.closeWhenBuilder()};b.addEventListener("click",E=>{E.preventDefault(),k()});let C=y.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});C.type="button",C.addEventListener("mousedown",E=>E.preventDefault()),C.addEventListener("click",E=>{E.preventDefault(),this.closeWhenBuilder()}),c(m,k),c(v,k),m.focus(),m.setSelectionRange(m.value.length,m.value.length)}else{let m=d("date / day / timeframe",()=>this.whenSingleText,C=>{this.whenSingleText=C},"single"),v=a.createDiv({cls:"stashpad-when-actions"}),y=v.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});y.type="button",y.addEventListener("mousedown",C=>C.preventDefault());let b=()=>{let C=m.value.trim();C&&this.appendFilterToInput(t,this.whenMode,C),this.closeWhenBuilder()};y.addEventListener("click",C=>{C.preventDefault(),b()});let k=v.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});k.type="button",k.addEventListener("mousedown",C=>C.preventDefault()),k.addEventListener("click",C=>{C.preventDefault(),this.closeWhenBuilder()}),c(m,b),m.focus(),m.setSelectionRange(m.value.length,m.value.length)}};p(),e.parentElement?.insertBefore(i,e.nextSibling),this.whenBuilderEl=i}closeWhenBuilder(){if(!this.whenBuilderEl)return;this.whenBuilderEl.remove(),this.whenBuilderEl=null,this.modalEl?.removeClass("is-when-builder-open")}onChooseSuggestion(t){if(t.kind==="create"&&this.opts.onCreate){this.opts.onCreate(this.inputEl?.value??"");return}if(t.kind==="folder-open"&&t.id==="__folder_picker__"){let e=this.opts.folderResults?.()??[];if(!e.length)return;let s=this.inputEl?.value??"",i=!1,n=u=>{i=!0;let d=u.split("/").pop()??u;this.opts.onPick({id:`folder:${u}`,label:`Open folder \u201C${d}\u201D in a new tab`,node:null,kind:"folder-open",folder:u})},r=new Ts(this.app,e,n),o=r.onClose.bind(r),a=this.tree,l=this.titleFn,c=this.opts,h=this.app;r.onClose=()=>{if(o(),!i){let u=new g(h,a,l,c);u.open(),setTimeout(()=>{let d=u.inputEl;d&&(s&&(d.value=s,d.dispatchEvent(new Event("input",{bubbles:!0}))),d.focus(),d.setSelectionRange(d.value.length,d.value.length))},0)}},r.open();return}this.opts.onPick(t)}},Ts=class extends dt.FuzzySuggestModal{constructor(t,e,s){super(t);this.folders=e;this.onChosen=s;this.setPlaceholder("Open which folder?")}getItems(){return this.folders}getItemText(t){let e=t.split("/").pop()??t;return e===t?t:`${e} \u2014 ${t}`}onChooseItem(t){this.onChosen(t)}};Gt();var Es=vi(ti()),Xe=require("obsidian");Ot();Ct();var ye="stash",si=1,Fs=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function ii(g,f){let t=new Es.default,e=Ii([...f.rootNotes,...f.allDescendants]),s=new Map,i=[];for(let r of e){let o=await g.vault.read(r.file),a=o,l=Ai(o);for(let c of l){let h=g.metadataCache.getFirstLinkpathDest(c,r.file.path);if(!h){i.push(`Missing attachment "${c}" in ${r.file.path}`);continue}let u=h.name;s.has(u)||s.set(u,await g.vault.readBinary(h)),a=Di(a,c,u)}a=Mi(a,g,r.file.path),t.file(`notes/${r.file.name}`,a)}for(let[r,o]of s)t.file(`attachments/${r}`,o);let n={stashSchema:si,exportedAt:new Date().toISOString(),sourceFolder:f.sourceFolder,noteCount:e.length,rootIds:f.rootNotes.map(r=>r.id)};return t.file("manifest.json",JSON.stringify(n,null,2)),i.length&&t.file("warnings.txt",i.join(` +`)),t.generateAsync({type:"uint8array",compression:"DEFLATE",compressionOptions:{level:6}})}async function Qe(g,f,t,e){let s=await Es.default.loadAsync(f),i=s.file("manifest.json");if(!i)throw new Error("Not a valid .stash package: missing manifest.json");let n=JSON.parse(await i.async("string"));if(typeof n.stashSchema!="number"||n.stashSchema>si)throw new Error(`Unsupported .stash schema: v${n.stashSchema}`);await ei(g,t);let r=Object.values(s.files).filter(v=>!v.dir&&v.name.startsWith("notes/")&&v.name.endsWith(".md")),o=[];for(let v of r){let y=await v.async("string"),{fm:b,body:k}=ri(y);o.push({originalName:v.name.slice(6),fm:b,body:k})}let a=new Map,l=0;for(let v of o){let y=v.fm.id;y&&(e.has(y)||a.has(y)?(a.set(y,`${y}-${Tt(4)}-Imported`),l++):a.set(y,y))}let c=new Date().toISOString(),h=[],u=`${t}/_attachments`,d=0,p=Object.values(s.files).filter(v=>!v.dir&&v.name.startsWith("attachments/"));p.length>0&&await ei(g,u);for(let v of p){let y=v.name.slice(12);if(!y)continue;let b=`${u}/${y}`;if(await g.vault.adapter.exists(b))continue;let k=await v.async("arraybuffer");await g.vault.createBinary(b,k),d++}let m=0;for(let v of o){let y=v.fm.id;if(!y){h.push(`Skipped ${v.originalName} \u2014 no id in frontmatter`);continue}let b=a.get(y),k=v.fm.parent??null,C=k;k&&k!==R&&a.has(k)?C=a.get(k):k&&k!==R&&!a.has(k)&&(C=R);let E=Pi(v.body,u),I={...v.fm,id:b,parent:C,import_date:c};Array.isArray(I.attachments)&&(I.attachments=I.attachments.map(D=>`${u}/${ni(D)}`));let A=ai(I,E),O=b===y?v.originalName:Li(v.originalName,y,b),F=`${t}/${O}`;await g.vault.adapter.exists(F)&&(O=`${O.replace(/\.md$/,"")}-${Tt(4)}.md`,F=`${t}/${O}`),await g.vault.create(F,A),m++}return{notesWritten:m,attachmentsWritten:d,collisionsRenamed:l,warnings:h}}function Ii(g){let f=new Set,t=[];for(let e of g)f.has(e.id)||(f.add(e.id),t.push(e));return t}function Ai(g){let f=new Set,t;for(Fs.lastIndex=0;(t=Fs.exec(g))!==null;)f.add(t[1]);return[...f]}function Di(g,f,t){return g.replace(new RegExp(`!\\[\\[${_i(f)}(\\|[^\\]]+)?\\]\\]`,"g"),(e,s)=>`![[${t}${s??""}]]`)}function Pi(g,f){return g.replace(Fs,(t,e,s)=>e.includes("/")?t:t.replace(e,`${f}/${e}`))}function Mi(g,f,t){let e=ri(g);if(!e.fm.attachments||!Array.isArray(e.fm.attachments))return g;let s=e.fm.attachments.map(n=>{let r=f.metadataCache.getFirstLinkpathDest(n,t);return r?r.name:ni(n)}),i={...e.fm,attachments:s};return ai(i,e.body)}function _i(g){return g.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ni(g){let f=g.lastIndexOf("/");return f<0?g:g.slice(f+1)}function Li(g,f,t){return g.includes(f)?g.replace(f,t):g.replace(/\.md$/,`-${t}.md`)}function ri(g){if(!g.startsWith("---"))return{fm:{},body:g};let f=g.indexOf(` +---`,3);if(f<0)return{fm:{},body:g};let t=g.slice(3,f).replace(/^\n/,""),e=g.slice(f+4),s={};try{s=(0,Xe.parseYaml)(t)??{}}catch{s={}}let i=e.startsWith(` +`)?e.slice(1):e;return{fm:s,body:i}}function ai(g,f){return`--- +${(0,Xe.stringifyYaml)(g).trimEnd()} --- -${f}`}async function Zs(v,f){if(!(!f||await v.vault.adapter.exists(f)))try{await v.vault.createFolder(f)}catch(e){let s=e?.message??"";if(!/already exists/i.test(s))throw e}}var Ii=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]),Xe={nested:"Nested",flat:"Flat",everything:"Everything"};function Di(v){if(v instanceof Element&&v.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let f=new Set([document]);v instanceof Element&&v.ownerDocument&&f.add(v.ownerDocument);for(let t of f)if(t.body?.querySelector(".modal-bg")||t.body?.querySelector(".modal-container .modal")||t.body?.querySelector(".suggestion-container")||t.body?.querySelector(".menu.mod-active"))return!0;return!1}var Qe=[{key:"day",calShort:"Today",rollShort:"24h",calLong:"Since midnight today",rollLong:"Last 24 hours"},{key:"week",calShort:"Week",rollShort:"7d",calLong:"Since Monday this week",rollLong:"Last 7 days"},{key:"month",calShort:"Month",rollShort:"30d",calLong:"Since the 1st of this month",rollLong:"Last 30 days"},{key:"year",calShort:"Year",rollShort:"365d",calLong:"Since January 1 this year",rollLong:"Last 365 days"},{key:"all",calShort:"All",rollShort:"ad infinitum",calLong:"All time",rollLong:"All time"}],Dt=class Dt extends O.ItemView{constructor(t,e){super(t);this.focusId=B;this.timeFilter="all";this.timeFilterCalendar=!1;this.tagFilter=null;this.colorFilter=null;this.noteFolder="Stashpad";this.folderOverride=null;this.tinyMode=!1;this.tinyAlwaysOnTop=!1;this.compactMode=!1;this.detachTreeHook=null;this.detachSettings=null;this.slugDebouncers=new Map;this.attachmentDebouncers=new Map;this.bootstrappedFolders=new Set;this.selection=new Set;this.lastSelected=null;this.cursorIdx=-1;this.currentChildren=[];this.modeSplit=null;this.modeEnterSubmits=!0;this.nextDestination=null;this.nextDestinationFolder=null;this.nextDestinationLabel=null;this.inListPicker=null;this.listEl=null;this.composerInputEl=null;this.composerDraft="";this.draftsLoadedFor=null;this.autoSelectNewest=!1;this.scrollToBottomOnNextRender=!1;this.scrollListenerSaveTimer=null;this.suppressScrollSave=!1;this.selectionGuardKey=0;this.pendingRenderPolicy=null;this.stickToListBottom=!1;this.stickyRowObserver=null;this.listResizeObserver=null;this.composerNarrowObserver=null;this.lastCursorByFocus=new Map;this.expandedNotes=new Set;this.focusComposerOnNextRender=!1;this.composerAutocomplete=null;this.firstSelectedId=null;this.mobileSelectMode=!1;this.focusedMiniObserver=null;this.pendingComposerCaret=null;this.navBackStack=[];this.navForwardSnapshots=[];this.stampLastCursorTimer=null;this.renderCache=new Map;this.lastListWidth=0;this.onDocKeyDown=t=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||Di(t.target))return;let e=kt().bindings;if(ct(t,e.toggleSplit)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.toggleSplit();return}if(ct(t,e.pickDestination)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openDestinationPicker();return}if(ct(t,e.search)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchModal();return}if(ct(t,e.searchInParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchInParentModal();return}if(ct(t,e.exportStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdExportStash();return}if(ct(t,e.importStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdImportStash();return}if(ct(t,e.pickFolder)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenFolderPicker();return}if(ct(t,e.cloneStashpadTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCloneStashpadTab();return}let s=t.target,i=!!s&&(s.tagName==="INPUT"||s.tagName==="TEXTAREA");if(t.key===" "&&!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&!i){let a=this.composerInputEl;if(a){t.preventDefault(),t.stopPropagation(),a.focus();let l=a.value.length;a.setSelectionRange(l,l);return}}let n=!!s&&(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="BUTTON"||s.tagName==="SELECT");if(t.key==="Escape"&&s instanceof HTMLElement&&(s.tagName==="BUTTON"||s.tagName==="SELECT")&&this.viewRoot.contains(s)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&t.key==="Escape"){t.preventDefault(),t.stopPropagation(),this.inListPicker=null;let a=this.listEl,l=!!a&&a.scrollTop+a.clientHeight>=a.scrollHeight-2,c=a?.scrollTop??0;if(this.render(),a){let d=l?a.scrollHeight:c;a.scrollTop=d,requestAnimationFrame(()=>{a.scrollTop=l?a.scrollHeight:c}),setTimeout(()=>{a.scrollTop=l?a.scrollHeight:c},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(t.key==="ArrowDown"){t.preventDefault(),this.inListPicker.activeIdx=Math.min(this.currentChildren.length-1,this.inListPicker.activeIdx+1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="ArrowUp"){t.preventDefault(),this.inListPicker.activeIdx=Math.max(0,this.inListPicker.activeIdx-1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="Enter"){t.preventDefault(),this.commitInListPicker();return}return}if(n)return;if(ct(t,e.delete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdDelete();return}if(ct(t,e.toggleComplete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleComplete();return}if(ct(t,e.moveToTop)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToTop();return}if(ct(t,e.moveToBottom)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToBottom();return}if(ct(t,e.moveUp)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveUp();return}if(ct(t,e.moveDown)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveDown();return}if(ct(t,e.outdent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOutdent();return}if(ct(t,e.setColor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetColor();return}if(ct(t,e.selectAll)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSelectAll();return}if(ct(t,e.swapWithParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSwapWithParent();return}if(ct(t,e.undo)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdUndo();return}if(ct(t,e.redo)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdRedo();return}if(t.key===" "){t.preventDefault();let a=this.composerInputEl;if(a){a.focus();let l=a.value.length;a.setSelectionRange(l,l)}return}if(t.key==="ArrowDown"){t.preventDefault(),this.cursorIdx>=this.currentChildren.length-1?this.cursorIdx=0:this.cursorIdx++,this.selectCursor(t.shiftKey);return}if(t.key==="ArrowUp"){t.preventDefault(),this.cursorIdx<=0?this.cursorIdx=this.currentChildren.length-1:this.cursorIdx--,this.selectCursor(t.shiftKey);return}if(t.altKey&&t.key==="ArrowLeft"){t.preventDefault(),this.navigateBack();return}if(t.altKey&&t.key==="ArrowRight"){t.preventDefault(),this.navigateForward();return}if(t.key==="ArrowRight"){let a=this.currentChildren[this.cursorIdx];a&&(t.preventDefault(),this.navigateTo(a.id));return}if(t.key==="ArrowLeft"||t.key==="Backspace"){t.preventDefault(),this.navigateUp();return}if(t.key==="Escape"){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation();let a=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,a){let l=this.currentChildren.findIndex(c=>c.id===a);this.selection.add(a),this.lastSelected=a,l>=0&&(this.cursorIdx=l)}this.repaintSelectionClasses(),this.revealCursorRow();return}let r=kt().bindings;if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(ct(t,r.move)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMovePicker();return}if(ct(t,r.pickMove)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInListPicker();return}if(ct(t,r.merge)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMerge();return}if(ct(t,r.copy)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopy();return}if(ct(t,r.copyTree)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyTree();return}if(ct(t,r.copyOutline)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyOutline();return}if(ct(t,r.copyCodeBlock)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(ct(t,r.openEditor)){if(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.shiftKey){let a=this.tree.get(this.focusId);a?.file&&this.cmdOpenInEditor(a)}else this.cmdOpenInEditor();return}if(ct(t,r.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(ct(t,r.split)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSplit();return}if(ct(t,r.clone)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdClone();return}if(ct(t,r.insertTemplate)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(ct(t,r.toggleExpand)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleExpand();return}if(ct(t,r.togglePin)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdTogglePin();return}if(ct(t,r.toggleTask)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleTask();return}if(ct(t,r.setDue)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetDue();return}}let o=this.tree.get(this.focusId);if(o?.file){if(ct(t,r.openEditor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInEditor(o);return}if(ct(t,r.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(o);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0;this.pendingFocusIds=null;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map;this.onFileModify=t=>{if(!(t instanceof O.TFile)||t.extension!=="md"||!t.path.startsWith(this.noteFolder+"/"))return;let e=Date.now(),s=this.recentSelfWrites.get(t.path);s!==void 0&&e-s<Dt.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(t.path,e),this.scheduleSlugRename(t),this.scheduleAttachmentSync(t),this.scheduleContribution(t),this.debouncedRender()};this.onFileCreate=t=>{!(t instanceof O.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&this.debouncedRender()};this.plugin=e,this.tree=new Ae(this.app),this.log=e.newLog(),this.integrity=new He(this.tree,this.log),this.order=new Pe(this.app),this.sortStore=new Me(this.app),this.fmSync=new Le(this.app,()=>this.tree),this.tree.setOrderProvider(s=>{let i=this.noteFolder,n=this.sortStore.getMode(i,s);return n==="manual"?this.order.getOrder(i,s):this.computeSortedIds(s,n)}),this.debouncedRender=(0,O.debounce)(()=>this.render(),80)}getViewType(){return vt}getDisplayText(){let t=(this.noteFolder||"").trim(),e=t.split("/").pop()||t||"Stashpad";if(this.focusId&&this.focusId!==B){let s=this.tree.get(this.focusId);if(s){let i=this.titleForNode(s).trim(),n=i.length>40?i.slice(0,40)+"\u2026":i;if(n)return`${e} \u2014 ${n}`}}return e}refreshHeaderTitle(){let t=this.getDisplayText();try{this.leaf.updateHeader?.()}catch{}let s=(this.headerEl??this.containerEl?.querySelector?.(".view-header"))?.querySelector?.(".view-header-title")??this.titleEl;s&&s.textContent!==t&&s.setText(t)}getIcon(){return"list-tree"}async onOpen(){let t=this.contentEl;t.empty(),t.addClass("stashpad-scroll-host"),this.viewRoot=t.createDiv({cls:"stashpad-view"}),this.viewRoot.setAttribute("tabindex","0"),this.viewRoot.addEventListener("focusin",()=>Ye(this)),this.viewRoot.addEventListener("click",()=>Ye(this)),this.viewRoot.addEventListener("mouseup",o=>{o.button===3?(o.preventDefault(),this.navigateBack()):o.button===4&&(o.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",o=>{o.button===3?(o.preventDefault(),this.navigateBack()):o.button===4&&(o.preventDefault(),this.navigateForward())}),Ye(this);let e=null,s=()=>{e||(e=new O.Scope(this.app.scope),e.register([],"Escape",()=>{if(this.selection.size>1){let o=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,o){let a=this.currentChildren.findIndex(l=>l.id===o);this.selection.add(o),this.lastSelected=o,a>=0&&(this.cursorIdx=a)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(e))},i=()=>{if(e){try{this.app.keymap?.popScope(e)}catch{}e=null}};this.viewRoot.addEventListener("focusin",s),this.viewRoot.addEventListener("focusout",o=>{let a=o.relatedTarget;a&&this.viewRoot&&this.viewRoot.contains(a)||i()}),this.register(()=>i()),this.detachTreeHook=this.tree.hookMetadataCache(()=>this.debouncedRender()),this.registerEvent(this.app.metadataCache.on("changed",o=>{if(o.extension!=="md")return;let a=this.app.metadataCache.getFileCache(o)?.frontmatter;this.completedState.set(o.path,!!a?.completed)})),this.registerEvent(this.app.vault.on("rename",(o,a)=>{this.completedState.has(a)&&(this.completedState.set(o.path,this.completedState.get(a)),this.completedState.delete(a))})),this.registerEvent(this.app.vault.on("delete",o=>{this.completedState.delete(o.path)})),this.detachSettings=Vs(()=>{this.loadConfig();let o=this.plugin.settings.drafts?.[this.noteFolder]??"",a=this.composerInputEl?.value??"";o===""&&this.composerDraft!==""&&a===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):o===""&&a!==""&&(this.composerDraft=a),!!this.composerInputEl&&document.activeElement===this.composerInputEl&&(this.focusComposerOnNextRender=!0),this.debouncedRender()}),this.app.vault.on("modify",this.onFileModify),this.app.vault.on("create",this.onFileCreate),window.addEventListener("keydown",this.onDocKeyDown,!0),this.loadConfig();try{await this.bootstrapFolder()}catch(o){let a=o?.message??"";/already exists/i.test(a)||console.warn("[Stashpad] bootstrapFolder failed:",o)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let o=this.plugin.loadLastCursor(this.noteFolder);for(let[a,l]of o)this.lastCursorByFocus.set(a,l)}catch{}let n=this.lastCursorByFocus.get(this.focusId),r;n&&this.tree.get(n)?(r={kind:"scroll-to-id",id:n,align:"start"},this.pendingFocusIds=[n]):(this.scrollToBottomOnNextRender=!0,r={kind:"pin-bottom",until:"next-user-input"}),this.render(r),this.tinyMode&&(setTimeout(()=>this.applyTinyWindow(),1e3),setTimeout(()=>this.applyTinyWindow(),1500)),this.registerDomEvent(window,"beforeunload",()=>{this.flushDrafts(),this.stampSelectedCursor(!0)}),this.registerDomEvent(window,"blur",()=>{this.flushDrafts(),this.stampSelectedCursor(!0)}),this.focusComposer(),this.registerEvent(this.app.workspace.on("active-leaf-change",o=>{o===this.leaf?this.focusComposer():this.stickToListBottom=!1}))}focusView(){requestAnimationFrame(()=>{this.viewRoot?.isConnected&&(document.activeElement instanceof HTMLElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA")||this.viewRoot.focus({preventScroll:!0}))})}focusComposer(){let t=()=>{if(!this.viewRoot?.isConnected)return;let e=document.activeElement;e&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA")&&e!==this.composerInputEl||(e&&e.tagName==="BUTTON"&&this.viewRoot.contains(e),this.composerInputEl?.focus({preventScroll:!0}))};requestAnimationFrame(t),setTimeout(t,50),setTimeout(t,200)}async onClose(){Ws(this),this.detachTreeHook?.(),this.detachSettings?.(),this.app.vault.off("modify",this.onFileModify),this.app.vault.off("create",this.onFileCreate),window.removeEventListener("keydown",this.onDocKeyDown,!0),this.listResizeObserver?.disconnect(),this.listResizeObserver=null,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null,this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=null,this.focusedMiniObserver?.disconnect(),this.focusedMiniObserver=null,this.composerAutocomplete?.detach(),this.composerAutocomplete=null;for(let t of this.slugDebouncers.values())t.cancel();for(let t of this.attachmentDebouncers.values())t.cancel();for(let t of this.contribTimers.values())clearTimeout(t);this.contribTimers.clear();try{await this.flushDrafts()}catch{}try{await this.order.flush(this.noteFolder)}catch{}try{await this.sortStore.flush(this.noteFolder)}catch{}try{await this.fmSync.flush()}catch{}this.stampSelectedCursor(!0),this.fmSyncUnsubscribe?.(),this.fmSyncUnsubscribe=null}setEphemeralState(t){let e=t;e?.focusId&&(this.focusId=e.focusId),e?.timeFilter&&(this.timeFilter=e.timeFilter)}getEphemeralState(){return{focusId:this.focusId,timeFilter:this.timeFilter}}getState(){return{...super.getState()??{},folderOverride:this.folderOverride,timeFilter:this.timeFilter,focusId:this.focusId,tagFilter:this.tagFilter,colorFilter:this.colorFilter,timeFilterCalendar:this.timeFilterCalendar,tinyMode:this.tinyMode,tinyAlwaysOnTop:this.tinyAlwaysOnTop,compactMode:this.compactMode,navBackStack:this.navBackStack,navForwardSnapshots:this.navForwardSnapshots}}async setState(t,e){let s=t??null;if(s){"folderOverride"in s&&(this.folderOverride=s.folderOverride??null),s.timeFilter&&(this.timeFilter=s.timeFilter),s.focusId&&(this.focusId=s.focusId),"tagFilter"in s&&(this.tagFilter=s.tagFilter??null),"colorFilter"in s&&(this.colorFilter=s.colorFilter??null),"timeFilterCalendar"in s&&(this.timeFilterCalendar=!!s.timeFilterCalendar),"tinyMode"in s&&(this.tinyMode=!!s.tinyMode),"tinyAlwaysOnTop"in s&&(this.tinyAlwaysOnTop=!!s.tinyAlwaysOnTop),"compactMode"in s&&(this.compactMode=!!s.compactMode);let r=o=>o&&typeof o.folder=="string"&&typeof o.focusId=="string";Array.isArray(s.navBackStack)&&(this.navBackStack=s.navBackStack.filter(r)),Array.isArray(s.navForwardSnapshots)&&(this.navForwardSnapshots=s.navForwardSnapshots.filter(r))}let i=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),n=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null;if(this.noteFolder=n||i||"Stashpad",await super.setState(t,e),this.refreshHeaderTitle(),this.viewRoot){this.loadConfig(),await this.bootstrapFolder(),this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.defaultCursorToLast(),this.draftsLoadedFor=null,this.composerDraft="",await this.loadDraftsForFolder(),this.lastCursorByFocus.clear();try{let a=this.plugin.loadLastCursor(this.noteFolder);for(let[l,c]of a)this.lastCursorByFocus.set(l,c)}catch{}let r=this.lastCursorByFocus.get(this.focusId),o;r&&this.tree.get(r)?(this.pendingFocusIds=[r],o={kind:"scroll-to-id",id:r,align:"start"}):o={kind:"pin-bottom",until:"next-user-input"},this.render(o)}}focus(){this.viewRoot?.focus({preventScroll:!0})}loadConfig(){let t=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),s=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||t||"Stashpad";s!==this.noteFolder?(this.noteFolder=s,this.tree.rebuild(this.noteFolder)):this.noteFolder=s}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(t={}){let e=this.captureNavSnapshot(),s=this.navBackStack[this.navBackStack.length-1];s&&s.folder===e.folder&&s.focusId===e.focusId||(this.navBackStack.push(e),t.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(t,e={}){let s=t?.trim().replace(/^\/+|\/+$/g,"")||null;if(s&&this.isReservedFolder(s)){new O.Notice(`"${s}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((s||null)!==(this.folderOverride||null)){e.skipHistory||this.recordNavState(),this.folderOverride=s,this.focusId=B,this.lastCursorByFocus.clear(),this.selection.clear(),this.cursorIdx=-1,this.lastSelected=null,this.composerDraft="",await this.flushDrafts(),this.draftsLoadedFor=null,this.loadConfig();try{await this.bootstrapFolder()}catch(i){let n=i?.message??"";/already exists/i.test(n)||console.warn("[Stashpad] bootstrapFolder failed:",i)}this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),await this.loadDraftsForFolder();try{let i=this.app.workspace;typeof i.saveLayout=="function"?await i.saveLayout():this.app.workspace.requestSaveLayout()}catch{this.app.workspace.requestSaveLayout()}this.refreshHeaderTitle(),this.render()}}cmdOpenFolderPicker(){this.openFolderPicker()}openFolderPicker(){this.plugin.openFolderPicker()}listVaultFolders(){let t=[];for(let e of this.app.vault.getAllLoadedFiles())if(e instanceof O.TFolder){if(e.path==="/"||e.path===""||e.path.startsWith(".")||this.isReservedFolder(e.path))continue;t.push(e.path)}return t.sort((e,s)=>e.localeCompare(s))}isReservedFolder(t){let e=t.split("/").filter(Boolean).pop()??"";return e?new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors"].map(i=>(i??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(e):!1}persistFocus(){try{this.app.workspace.requestSaveLayout()}catch{}}cmdUndo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canUndo()){new O.Notice("Nothing to undo.");return}let e=t.peekUndoLabel(),s=this.plugin.notifications.recent()[0]?.category??"system";t.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${e}`,kind:"info",category:s,folder:this.noteFolder})).catch(i=>this.plugin.notifications.show({message:`Undo failed: ${i.message}`,kind:"error",category:"system",folder:this.noteFolder}))}cmdRedo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canRedo()){new O.Notice("Nothing to redo.");return}let e=t.peekRedoLabel(),s=this.plugin.notifications.recent()[0]?.category??"system";t.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${e}`,kind:"info",category:s,folder:this.noteFolder})).catch(i=>this.plugin.notifications.show({message:`Redo failed: ${i.message}`,kind:"error",category:"system",folder:this.noteFolder}))}async snapshotNotes(t,e){let s=[],i=new Set;for(let a of t)!a.file||i.has(a.file.path)||(i.add(a.file.path),s.push(a.file));let n=await Promise.all(s.map(a=>this.app.vault.read(a))),r=s.map((a,l)=>({path:a.path,content:n[l]})),o=[];if(e){let a=new Set,l=[];for(let d of n)for(let p of this.extractAttachments(this.stripFrontmatter(d))){let h=this.app.metadataCache.getFirstLinkpathDest(p,"");h&&!a.has(h.path)&&(a.add(h.path),l.push(h))}let c=await Promise.all(l.map(d=>this.app.vault.readBinary(d)));for(let d=0;d<l.length;d++)o.push({path:l[d].path,data:c[d]})}return{notes:r,attachments:o}}async restoreSnapshots(t,e){for(let i of t.attachments)try{await this.app.vault.adapter.exists(i.path)||await this.app.vault.createBinary(i.path,i.data)}catch{}for(let i of t.notes)try{await this.app.vault.adapter.exists(i.path)||await this.app.vault.create(i.path,i.content)}catch{}let s=()=>{e&&e.some(n=>this.tree.get(n))&&(this.pendingFocusIds=e.slice())};s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"}),setTimeout(()=>{s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},100),setTimeout(()=>{s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},400),setTimeout(()=>{for(let i of t.notes){let n=this.tree.idForPath(i.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(t){let e=new Set;for(let s of t.notes){let i=this.tree.idForPath(s.path);if(!i)continue;let n=this.tree.get(i);n?.parent&&e.add(n.parent)}for(let s of t.notes){let i=this.app.vault.getAbstractFileByPath(s.path);if(i)try{await this.app.fileManager.trashFile(i)}catch{}}for(let s of t.attachments){let i=this.app.vault.getAbstractFileByPath(s.path);if(i)try{await this.app.fileManager.trashFile(i)}catch{}}this.tree.rebuild(this.noteFolder),this.render();for(let s of e)this.fmSync.scheduleParentOfDeleted(s)}async loadDraftsForFolder(){if(this.draftsLoadedFor===this.noteFolder)return;this.draftsLoadedFor=this.noteFolder;let t=this.plugin.settings.drafts??{};this.composerDraft=t[this.noteFolder]??"",console.debug("[Stashpad] loadDrafts",{folder:this.noteFolder,has:!!t[this.noteFolder],available:Object.keys(t)})}async saveDraft(t){try{let e=this.noteFolder;if((this.plugin.settings.drafts?.[e]??"")===t)return;let i={...this.plugin.settings.drafts??{}};t.length===0?delete i[e]:i[e]=t,this.plugin.settings.drafts=i,t.length===0?await this.plugin.saveSettings():await this.plugin.persistSettingsQuiet()}catch(e){console.warn("Stashpad: drafts save failed",e)}}async recordLastSubmitted(t){try{let e={...this.plugin.settings.lastSubmitted??{}};e[this.noteFolder]=t,this.plugin.settings.lastSubmitted=e,await this.plugin.persistSettingsQuiet()}catch{}}hasRestorableDraft(){let t=this.plugin.settings.drafts?.[this.noteFolder];if(!t||!t.trim())return!1;let e=this.plugin.settings.lastSubmitted?.[this.noteFolder];return!(e&&e===t)}syncComposerDraftForFocus(){}async flushDrafts(){this.composerInputEl?await this.saveDraft(this.composerInputEl.value):await this.saveDraft(this.composerDraft)}timeFilterCutoff(){if(this.timeFilter==="all")return null;if(this.timeFilterCalendar){let e=(0,O.moment)();switch(this.timeFilter){case"day":return e.startOf("day").valueOf();case"week":return e.startOf("isoWeek").valueOf();case"month":return e.startOf("month").valueOf();case"year":return e.startOf("year").valueOf()}}let t=Date.now();switch(this.timeFilter){case"day":return t-864e5;case"week":return t-7*864e5;case"month":return t-30*864e5;case"year":return t-365*864e5}return null}allowedByBases(){return null}currentViewMode(){return this.plugin.settings.viewModes?.[this.noteFolder]??"nested"}currentIncludeAttachments(){return!!this.plugin.settings.includeAttachmentsInEverything?.[this.noteFolder]}async setIncludeAttachments(t){let e={...this.plugin.settings.includeAttachmentsInEverything??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.includeAttachmentsInEverything=e,await this.plugin.saveSettings()}currentHideChildless(){return!!this.plugin.settings.hideChildlessNotes?.[this.noteFolder]}async setHideChildless(t){let e={...this.plugin.settings.hideChildlessNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.hideChildlessNotes=e,await this.plugin.saveSettings()}currentHideCompleted(){return!!this.plugin.settings.hideCompletedNotes?.[this.noteFolder]}async setHideCompleted(t){let e={...this.plugin.settings.hideCompletedNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.hideCompletedNotes=e,await this.plugin.saveSettings()}hasIncompleteDescendant(t){for(let e of t.children){let s=this.tree.get(e);if(s&&(!this.isCompleted(s)||this.hasIncompleteDescendant(s)))return!0}return!1}collectEmbeddedAttachmentPaths(){let t=new Set,e=this.noteFolder,s=this.app.vault.getAbstractFileByPath(e);if(!(s instanceof O.TFolder))return t;let i=[s];for(;i.length;){let n=i.pop();for(let r of n.children){if(r instanceof O.TFolder){i.push(r);continue}if(!(r instanceof O.TFile)||r.extension!=="md")continue;let o=this.app.metadataCache.getFileCache(r)?.frontmatter;if(!(!o||!Array.isArray(o.attachments)))for(let a of o.attachments){if(typeof a!="string")continue;let l=this.app.metadataCache.getFirstLinkpathDest(a,r.path);l?t.add(l.path):t.add(a)}}}return t}collectFileItems(t){let e=this.noteFolder,s=this.app.vault.getAbstractFileByPath(e);if(!(s instanceof O.TFolder))return[];let i=this.currentIncludeAttachments(),n=i?new Set:this.collectEmbeddedAttachmentPaths(),r=new Set(["_authors","_imports","_exports","_processed"]),o=[],a=[s];for(;a.length;){let l=a.pop();for(let c of l.children){if(c instanceof O.TFolder){let d=c.name;if(l===s&&r.has(d)||l===s&&d==="_attachments"&&!i)continue;a.push(c);continue}c instanceof O.TFile&&c.extension!=="md"&&(c.name===".stashpad-order.json"||c.name===".stashpad-sort.json"||!i&&n.has(c.path)||o.push(c))}}return o}populateListBody(t,e){this.lastListWidth=t.clientWidth||this.lastListWidth,e.file&&O.Platform.isMobile&&(this.renderFocusedHeaderMini(t,e),this.renderFocusedHeader(t,e));let i=this.currentViewMode()==="everything"?this.collectFileItems(e.id):[];if(this.currentChildren.length===0&&i.length===0)t.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(i.length===0)for(let n=0;n<this.currentChildren.length;n++)this.renderNote(t,this.currentChildren[n],n);else{let r=[...this.currentChildren.map((o,a)=>({kind:"note",ts:Number.isFinite(Date.parse(o.created))?Date.parse(o.created):0,idx:a})),...i.map(o=>({kind:"file",ts:o.stat.ctime,file:o}))];r.sort((o,a)=>o.ts-a.ts);for(let o of r)o.kind==="note"?this.renderNote(t,this.currentChildren[o.idx],o.idx):this.renderFileRow(t,o.file)}e.file&&O.Platform.isMobile&&this.installFocusedMiniObserver(t)}refreshList(){if(!this.listEl){this.render();return}let t=this.tree.get(this.focusId)??this.tree.getRoot();this.currentChildren=this.filterChildren(this.collectViewItems(t.id)),this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let e=this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2,s=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,t),e?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=s}renderFileRow(t,e){let s=t.createDiv({cls:"stashpad-file-row"});s.dataset.path=e.path,s.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(e.stat.ctime).toISOString())});let n=s.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:e.name}),n.createSpan({cls:"stashpad-file-ext",text:e.extension.toUpperCase()}),s.title=`${e.path} \u2014 click to open`,s.onclick=r=>{r.preventDefault(),this.app.workspace.openLinkText(e.path,"",!1)}}async setViewMode(t){let e={...this.plugin.settings.viewModes??{}};t==="nested"?delete e[this.noteFolder]:e[this.noteFolder]=t,this.plugin.settings.viewModes=e,await this.plugin.saveSettings()}collectViewItems(t){let e=this.currentViewMode(),s=this.currentHideChildless(),i=this.tree.getChildren(t),n=s?i.filter(a=>a.children.length>0):i;if(e==="nested")return n;let r=[],o=a=>{r.push(a);for(let l of this.tree.getChildren(a.id))o(l)};for(let a of n)o(a);return r}filterChildren(t){let e=this.timeFilterCutoff(),s=this.tagFilter?.toLowerCase(),i=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted();return!e&&!s&&!i&&!n?t:t.filter(r=>{if(e&&r.created){let o=Date.parse(r.created);if(!Number.isNaN(o)&&o<e)return!1}return!(s&&(!r.file||!this.nodeHasTag(r,s))||i&&(this.colorForNode(r)?.toLowerCase()??null)!==i||n&&this.isCompleted(r)&&!this.hasIncompleteDescendant(r))})}nodeHasTag(t,e){if(!t.file)return!1;let s=this.app.metadataCache.getFileCache(t.file);if(!s)return!1;if(s.tags){for(let n of s.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===e)return!0}let i=s.frontmatter?.tags;if(i){let n=Array.isArray(i)?i:[i];for(let r of n)if(typeof r=="string"&&r.replace(/^#/,"").toLowerCase()===e)return!0}return!1}collectFolderTags(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let i of e){if(!i.file)continue;let n=this.app.metadataCache.getFileCache(i.file);if(n?.tags)for(let o of n.tags){let a=(o.tag||"").replace(/^#/,"");a&&t.set(a,(t.get(a)??0)+1)}let r=n?.frontmatter?.tags;if(r){let o=Array.isArray(r)?r:[r];for(let a of o){if(typeof a!="string")continue;let l=a.replace(/^#/,"");l&&t.set(l,(t.get(l)??0)+1)}}}let s=[...t.entries()].map(([i,n])=>({raw:i,count:n,label:this.formatTagLabel(i)}));return s.sort((i,n)=>n.count-i.count||i.label.localeCompare(n.label)),s}formatTagLabel(t){return t&&t.split("/").map(e=>e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[-_\s]+/).filter(Boolean).map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")).join(" / ")}collectFolderColors(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let i of e){let n=this.colorForNode(i);if(!n)continue;let r=n.toLowerCase();t.set(r,(t.get(r)??0)+1)}let s=[...t.entries()].map(([i,n])=>({hex:i,count:n}));return s.sort((i,n)=>n.count-i.count||i.hex.localeCompare(n.hex)),s}defaultCursorToLast(){let t=this.tree.get(this.focusId)??this.tree.getRoot(),e=this.filterChildren(this.collectViewItems(t.id));this.cursorIdx=e.length-1,this.selection.clear(),e.length>0&&(this.selection.add(e[e.length-1].id),this.lastSelected=e[e.length-1].id)}stampSelectedCursor(t=!1){let s=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;if(!s)return;this.lastCursorByFocus.set(this.focusId,s);let i=()=>{let n=this.lastCursorByFocus.get(this.focusId);n&&this.plugin.saveLastCursor(this.noteFolder,this.focusId,n)};if(t){this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=null,i();return}this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=window.setTimeout(()=>{this.stampLastCursorTimer=null,i()},400)}captureScrollAnchor(){let t=this.listEl;if(!t)return null;let e=t.getBoundingClientRect().top,s=Array.from(t.querySelectorAll(".stashpad-note"));if(s.length===0)return null;let i=null;for(let n of s){let r=n.dataset.id;if(!r)continue;let o=n.getBoundingClientRect().top-e;if(o>=0){i={id:r,offsetFromListTop:o};break}i={id:r,offsetFromListTop:o}}return i}restoreScrollAnchor(t,e){let s=this.listEl;if(s){if(t){let i=s.querySelector(`[data-id="${t.id}"]`);if(i){let n=s.getBoundingClientRect().top,r=i.getBoundingClientRect().top-n;s.scrollTop+=r-t.offsetFromListTop;return}}e>0&&(s.scrollTop=e)}}render(t){this.pendingRenderPolicy=t??{kind:"preserve"},this.loadConfig();let e=this.viewRoot,s=this.listEl?.scrollTop??0,n=(t??{kind:"preserve"}).kind==="preserve"?this.captureScrollAnchor():null;!!this.composerInputEl&&document.activeElement===this.composerInputEl&&(this.focusComposerOnNextRender=!0,this.pendingComposerCaret=this.composerInputEl?.selectionStart??null);let o=!!this.listEl&&(this.stickToListBottom||this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2);e.empty(),e.toggleClass("is-mobile",O.Platform.isMobile),e.toggleClass("is-tiny",this.tinyMode),e.toggleClass("is-compact",this.compactMode);let a=this.containerEl.closest(".workspace-leaf");a&&(a.classList.toggle("stashpad-is-tiny",this.tinyMode),a.classList.toggle("stashpad-is-compact",this.compactMode));let l=this.containerEl.closest(".workspace-tabs");l&&l.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode?this.renderTinyHeader(e):(this.compactMode||this.renderTimeFilterBar(e),this.renderBreadcrumb(e));let c=this.tree.get(this.focusId)??this.tree.getRoot();if(c.file&&!O.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(e,c),this.currentChildren=this.filterChildren(this.collectViewItems(c.id)),this.autoSelectNewest&&this.currentChildren.length>0){let h=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(h.id),this.lastSelected=h.id,this.autoSelectNewest=!1}else if(this.pendingFocusIds){let h=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let u=-1;for(let m of h){let g=this.currentChildren.findIndex(y=>y.id===m);g>=0&&(this.selection.add(m),u<0&&(u=g))}this.cursorIdx=u,u>=0&&(this.lastSelected=h.find(m=>this.currentChildren.some(g=>g.id===m))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let d=e.createDiv({cls:"stashpad-list"});if(this.listEl=d,d.addEventListener("dragover",h=>{if(!this.dragSourceIds)return;let u=h.target;if(u&&u.closest&&u.closest(".stashpad-note"))return;h.preventDefault(),h.dataTransfer&&(h.dataTransfer.dropEffect="move");let m=Array.from(d.querySelectorAll(".stashpad-note"));if(m.length!==0){for(let g of m){let y=g.getBoundingClientRect();if(h.clientY<y.top+y.height/2){this.placePlaceholder(g,"before");return}}this.placePlaceholder(m[m.length-1],"after")}}),d.addEventListener("drop",h=>{if(!this.dragSourceIds)return;h.preventDefault();let u=this.dragSourceIds.slice();if(this.dragSourceIds=null,!this.dragPlaceholder)return;let m=this.dragPlaceholder.nextElementSibling,g=this.dragPlaceholder.previousElementSibling;if(this.removeDragPlaceholder(),m&&m.classList.contains("stashpad-note")){let y=m.dataset.id;y&&this.reorderToTarget(u,y,"before")}else if(g&&g.classList.contains("stashpad-note")){let y=g.dataset.id;y&&this.reorderToTarget(u,y,"after")}}),this.populateListBody(d,c),this.renderComposer(e),O.Platform.isMobile&&this.renderMobileNav(e),this.plugin.notifyStashpadContentChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let h=this.pendingComposerCaret;this.pendingComposerCaret=null;let u=this.composerInputEl;if(u&&u.isConnected){if(u.focus({preventScroll:!0}),h!=null){let m=Math.min(h,u.value.length);try{u.setSelectionRange(m,m)}catch{}}}else requestAnimationFrame(()=>{let m=this.composerInputEl;if(m&&(m.focus({preventScroll:!0}),h!=null)){let g=Math.min(h,m.value.length);try{m.setSelectionRange(g,g)}catch{}}})}let p=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,p&&this.listEl){let h=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,p.kind){case"preserve":h?this.scrollListToBottom():o?this.scrollListToBottom():this.restoreScrollAnchor(n,s);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let u=p.scrollTop,m=this.listEl,g=()=>{this.suppressScrollSave=!0;let y=Math.max(0,m.scrollHeight-m.clientHeight);m.scrollTop=Math.min(u,y),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};g(),requestAnimationFrame(g),setTimeout(g,60),setTimeout(g,200),setTimeout(g,600);break}case"follow-cursor":s>0&&(this.listEl.scrollTop=s),this.revealCursorRow();break;case"scroll-to-id":{let u=p.id,m=p.align,g=this.listEl,y=()=>{this.suppressScrollSave=!0;let S=g.querySelector(`[data-id="${u}"]`);S&&S.scrollIntoView({block:m,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};y(),requestAnimationFrame(y),setTimeout(y,60),setTimeout(y,200),setTimeout(y,600),setTimeout(()=>{this.suppressScrollSave=!1},700);break}}}else this.scrollToBottomOnNextRender?(this.scrollToBottomOnNextRender=!1,this.scrollListToBottom()):this.listEl&&o?this.scrollListToBottom():this.listEl&&s>0&&(this.listEl.scrollTop=s);if(this.stampSelectedCursor(),this.listEl){this.listResizeObserver?.disconnect();let h=this.listEl,u=h.scrollTop,m=new ResizeObserver(()=>{if(this.stickToListBottom){h.scrollTop=h.scrollHeight,u=h.scrollTop;return}let y=Math.max(0,h.scrollHeight-h.clientHeight);h.scrollTop<u&&u<=y?h.scrollTop=u:u=h.scrollTop});m.observe(h),this.listResizeObserver=m,h.addEventListener("wheel",y=>{y.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let g=0;h.addEventListener("touchstart",y=>{g=y.touches[0]?.clientY??0},{passive:!0}),h.addEventListener("touchmove",y=>{let S=y.touches[0]?.clientY??g;S>g&&(this.stickToListBottom=!1),g=S},{passive:!0}),h.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),h.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}renderTimeFilterBar(t){let e=t.createDiv({cls:"stashpad-time-filter-bar"}),s=e.createEl("button",{cls:"stashpad-folder-btn"}),i=!!this.folderOverride,n=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,O.setIcon)(s.createSpan({cls:"stashpad-btn-icon"}),"folder"),s.createSpan({text:n,cls:"stashpad-btn-text"}),s.title=i?`Folder (override): ${this.noteFolder} +${f}`}async function ei(g,f){if(!(!f||await g.vault.adapter.exists(f)))try{await g.vault.createFolder(f)}catch(e){let s=e?.message??"";if(!/already exists/i.test(s))throw e}}var Ni=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]);function Yt(g,f,t){g.empty();try{(0,N.setIcon)(g,f)}catch{}let e=g.querySelector("svg");e&&e.querySelector("path, line, circle, rect, polyline, polygon, ellipse")||(g.empty(),g.createSpan({cls:"stashpad-icon-fallback",text:t}))}var ts={nested:"Nested",flat:"Flat",everything:"Everything"};function Oi(g){if(g instanceof Element&&g.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let f=new Set([document]);g instanceof Element&&g.ownerDocument&&f.add(g.ownerDocument);for(let t of f)if(t.body?.querySelector(".modal-bg")||t.body?.querySelector(".modal-container .modal")||t.body?.querySelector(".suggestion-container")||t.body?.querySelector(".menu.mod-active"))return!0;return!1}var es=[{key:"day",calShort:"Today",rollShort:"24h",calLong:"Since midnight today",rollLong:"Last 24 hours"},{key:"week",calShort:"Week",rollShort:"7d",calLong:"Since Monday this week",rollLong:"Last 7 days"},{key:"month",calShort:"Month",rollShort:"30d",calLong:"Since the 1st of this month",rollLong:"Last 30 days"},{key:"year",calShort:"Year",rollShort:"365d",calLong:"Since January 1 this year",rollLong:"Last 365 days"},{key:"all",calShort:"All",rollShort:"ad infinitum",calLong:"All time",rollLong:"All time"}],It=class It extends N.ItemView{constructor(t,e){super(t);this.focusId=R;this.timeFilter="all";this.timeFilterCalendar=!1;this.tagFilter=null;this.colorFilter=null;this.noteFolder="Stashpad";this.folderOverride=null;this.tinyMode=!1;this.tinyAlwaysOnTop=!1;this.tinyOpacity=1;this.compactMode=!1;this.detachTreeHook=null;this.detachSettings=null;this.slugDebouncers=new Map;this.attachmentDebouncers=new Map;this.bootstrappedFolders=new Set;this.selection=new Set;this.lastSelected=null;this.cursorIdx=-1;this.currentChildren=[];this.modeSplit=null;this.modeEnterSubmits=!0;this.nextDestination=null;this.nextDestinationFolder=null;this.nextDestinationLabel=null;this.inListPicker=null;this.listEl=null;this.composerInputEl=null;this.composerDraft="";this.draftsLoadedFor=null;this.autoSelectNewest=!1;this.scrollToBottomOnNextRender=!1;this.scrollListenerSaveTimer=null;this.suppressScrollSave=!1;this.selectionGuardKey=0;this.pendingRenderPolicy=null;this.stickToListBottom=!1;this.keyboardTransitionUntil=0;this.stickyRowObserver=null;this.listResizeObserver=null;this.composerNarrowObserver=null;this.lastCursorByFocus=new Map;this.expandedNotes=new Set;this.focusComposerOnNextRender=!1;this.suppressComposerFocusUntil=0;this.composerAutocomplete=null;this.firstSelectedId=null;this.mobileSelectMode=!1;this.focusedMiniObserver=null;this.pendingComposerCaret=null;this.navBackStack=[];this.navForwardSnapshots=[];this.treeReconcileTimer=null;this.stampLastCursorTimer=null;this.tinyOpacityPopover=null;this.renderCache=new Map;this.lastListWidth=0;this.onDocKeyDown=t=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||Oi(t.target))return;let e=wt().bindings;if(ot(t,e.toggleSplit)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.toggleSplit();return}if(ot(t,e.pickDestination)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openDestinationPicker();return}if(ot(t,e.search)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchModal();return}if(ot(t,e.searchInParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchInParentModal();return}if(ot(t,e.exportStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdExportStash();return}if(ot(t,e.importStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdImportStash();return}if(ot(t,e.pickFolder)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenFolderPicker();return}if(ot(t,e.cloneStashpadTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCloneStashpadTab();return}let s=t.target,i=!!s&&(s.tagName==="INPUT"||s.tagName==="TEXTAREA");if(t.key===" "&&!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&!i){let a=this.composerInputEl;if(a){t.preventDefault(),t.stopPropagation(),a.focus();let l=a.value.length;a.setSelectionRange(l,l);return}}let n=!!s&&(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="BUTTON"||s.tagName==="SELECT");if(t.key==="Escape"&&s instanceof HTMLElement&&(s.tagName==="BUTTON"||s.tagName==="SELECT")&&this.viewRoot.contains(s)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&t.key==="Escape"){t.preventDefault(),t.stopPropagation(),this.inListPicker=null;let a=this.listEl,l=!!a&&a.scrollTop+a.clientHeight>=a.scrollHeight-2,c=a?.scrollTop??0;if(this.render(),a){let h=l?a.scrollHeight:c;a.scrollTop=h,requestAnimationFrame(()=>{a.scrollTop=l?a.scrollHeight:c}),setTimeout(()=>{a.scrollTop=l?a.scrollHeight:c},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(t.key==="ArrowDown"){t.preventDefault(),this.inListPicker.activeIdx=Math.min(this.currentChildren.length-1,this.inListPicker.activeIdx+1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="ArrowUp"){t.preventDefault(),this.inListPicker.activeIdx=Math.max(0,this.inListPicker.activeIdx-1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="Enter"){t.preventDefault(),this.commitInListPicker();return}return}if(n)return;if(ot(t,e.delete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdDelete();return}if(ot(t,e.toggleComplete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleComplete();return}if(ot(t,e.moveToTop)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToTop();return}if(ot(t,e.moveToBottom)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToBottom();return}if(ot(t,e.moveUp)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveUp();return}if(ot(t,e.moveDown)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveDown();return}if(ot(t,e.outdent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOutdent();return}if(ot(t,e.setColor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetColor();return}if(ot(t,e.selectAll)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSelectAll();return}if(ot(t,e.swapWithParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSwapWithParent();return}if(ot(t,e.undo)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdUndo();return}if(ot(t,e.redo)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdRedo();return}if(t.key===" "){t.preventDefault();let a=this.composerInputEl;if(a){a.focus();let l=a.value.length;a.setSelectionRange(l,l)}return}if(t.key==="ArrowDown"){t.preventDefault(),this.cursorIdx>=this.currentChildren.length-1?this.cursorIdx=0:this.cursorIdx++,this.selectCursor(t.shiftKey);return}if(t.key==="ArrowUp"){t.preventDefault(),this.cursorIdx<=0?this.cursorIdx=this.currentChildren.length-1:this.cursorIdx--,this.selectCursor(t.shiftKey);return}if(t.altKey&&t.key==="ArrowLeft"){t.preventDefault(),this.navigateBack();return}if(t.altKey&&t.key==="ArrowRight"){t.preventDefault(),this.navigateForward();return}if(t.key==="ArrowRight"){let a=this.currentChildren[this.cursorIdx];a&&(t.preventDefault(),this.navigateTo(a.id));return}if(t.key==="ArrowLeft"||t.key==="Backspace"){t.preventDefault(),this.navigateUp();return}if(t.key==="Escape"){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation();let a=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,a){let l=this.currentChildren.findIndex(c=>c.id===a);this.selection.add(a),this.lastSelected=a,l>=0&&(this.cursorIdx=l)}this.repaintSelectionClasses(),this.revealCursorRow();return}let r=wt().bindings;if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(ot(t,r.move)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMovePicker();return}if(ot(t,r.pickMove)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInListPicker();return}if(ot(t,r.merge)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMerge();return}if(ot(t,r.copy)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopy();return}if(ot(t,r.copyTree)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyTree();return}if(ot(t,r.copyOutline)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyOutline();return}if(ot(t,r.copyCodeBlock)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(ot(t,r.openEditor)){if(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.shiftKey){let a=this.tree.get(this.focusId);a?.file&&this.cmdOpenInEditor(a)}else this.cmdOpenInEditor();return}if(ot(t,r.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(ot(t,r.split)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSplit();return}if(ot(t,r.clone)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdClone();return}if(ot(t,r.insertTemplate)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(ot(t,r.toggleExpand)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleExpand();return}if(ot(t,r.togglePin)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdTogglePin();return}if(ot(t,r.toggleTask)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleTask();return}if(ot(t,r.setDue)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetDue();return}}let o=this.tree.get(this.focusId);if(o?.file){if(ot(t,r.openEditor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInEditor(o);return}if(ot(t,r.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(o);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0;this.pendingFocusIds=null;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map;this.onFileModify=t=>{if(!(t instanceof N.TFile)||t.extension!=="md"||!t.path.startsWith(this.noteFolder+"/"))return;let e=Date.now(),s=this.recentSelfWrites.get(t.path);s!==void 0&&e-s<It.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(t.path,e),this.scheduleSlugRename(t),this.scheduleAttachmentSync(t),this.scheduleContribution(t),this.debouncedRender()};this.onFileCreate=t=>{!(t instanceof N.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&this.debouncedRender()};this.plugin=e,this.tree=new Me(this.app),this.log=e.newLog(),this.integrity=new We(this.tree,this.log),this.order=new _e(this.app),this.sortStore=new Le(this.app),this.fmSync=new Oe(this.app,()=>this.tree),this.tree.setOrderProvider(s=>{let i=this.noteFolder,n=this.sortStore.getMode(i,s);return n==="manual"?this.order.getOrder(i,s):this.computeSortedIds(s,n)}),this.debouncedRender=(0,N.debounce)(()=>this.render(),80)}getViewType(){return mt}getDisplayText(){let t=(this.noteFolder||"").trim(),e=t.split("/").pop()||t||"Stashpad";if(this.focusId&&this.focusId!==R){let s=this.tree.get(this.focusId);if(s){let i=this.titleForNode(s).trim(),n=i.length>40?i.slice(0,40)+"\u2026":i;if(n)return`${e} \u2014 ${n}`}}return e}refreshHeaderTitle(){let t=this.getDisplayText();try{this.leaf.updateHeader?.()}catch{}let s=(this.headerEl??this.containerEl?.querySelector?.(".view-header"))?.querySelector?.(".view-header-title")??this.titleEl;s&&s.textContent!==t&&s.setText(t)}getIcon(){return"list-tree"}async onOpen(){let t=this.contentEl;t.empty(),t.addClass("stashpad-scroll-host"),this.viewRoot=t.createDiv({cls:"stashpad-view"}),this.viewRoot.setAttribute("tabindex","0"),this.viewRoot.addEventListener("focusin",()=>qe(this)),this.viewRoot.addEventListener("click",()=>qe(this)),this.viewRoot.addEventListener("mouseup",o=>{o.button===3?(o.preventDefault(),this.navigateBack()):o.button===4&&(o.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",o=>{o.button===3?(o.preventDefault(),this.navigateBack()):o.button===4&&(o.preventDefault(),this.navigateForward())}),qe(this);let e=null,s=()=>{e||(e=new N.Scope(this.app.scope),e.register([],"Escape",()=>{if(this.selection.size>1){let o=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,o){let a=this.currentChildren.findIndex(l=>l.id===o);this.selection.add(o),this.lastSelected=o,a>=0&&(this.cursorIdx=a)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(e))},i=()=>{if(e){try{this.app.keymap?.popScope(e)}catch{}e=null}};this.viewRoot.addEventListener("focusin",s),this.viewRoot.addEventListener("focusout",o=>{let a=o.relatedTarget;a&&this.viewRoot&&this.viewRoot.contains(a)||i()}),this.register(()=>i()),this.detachTreeHook=this.tree.hookMetadataCache(()=>this.debouncedRender()),this.registerEvent(this.app.metadataCache.on("resolved",()=>this.scheduleTreeReconcile())),this.registerEvent(this.app.metadataCache.on("changed",o=>{if(o.extension!=="md")return;let a=this.app.metadataCache.getFileCache(o)?.frontmatter;this.completedState.set(o.path,!!a?.completed)})),this.registerEvent(this.app.vault.on("rename",(o,a)=>{this.completedState.has(a)&&(this.completedState.set(o.path,this.completedState.get(a)),this.completedState.delete(a))})),this.registerEvent(this.app.vault.on("delete",o=>{this.completedState.delete(o.path)})),this.detachSettings=Js(()=>{this.loadConfig();let o=this.plugin.settings.drafts?.[this.noteFolder]??"",a=this.composerInputEl?.value??"";o===""&&this.composerDraft!==""&&a===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):o===""&&a!==""&&(this.composerDraft=a),!!this.composerInputEl&&document.activeElement===this.composerInputEl&&(this.focusComposerOnNextRender=!0),this.debouncedRender()}),this.app.vault.on("modify",this.onFileModify),this.app.vault.on("create",this.onFileCreate),window.addEventListener("keydown",this.onDocKeyDown,!0),this.loadConfig();try{await this.bootstrapFolder()}catch(o){let a=o?.message??"";/already exists/i.test(a)||console.warn("[Stashpad] bootstrapFolder failed:",o)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let o=this.plugin.loadLastCursor(this.noteFolder);for(let[a,l]of o)this.lastCursorByFocus.set(a,l)}catch{}let n=this.lastCursorByFocus.get(this.focusId),r;n&&this.tree.get(n)?(r={kind:"scroll-to-id",id:n,align:"start"},this.pendingFocusIds=[n]):(this.scrollToBottomOnNextRender=!0,r={kind:"pin-bottom",until:"next-user-input"}),this.render(r),this.tinyMode&&(setTimeout(()=>this.applyTinyWindow(),1e3),setTimeout(()=>this.applyTinyWindow(),1500)),this.registerDomEvent(window,"beforeunload",()=>{this.flushDrafts(),this.stampSelectedCursor(!0)}),this.registerDomEvent(window,"blur",()=>{this.flushDrafts(),this.stampSelectedCursor(!0)}),this.focusComposer(),this.registerEvent(this.app.workspace.on("active-leaf-change",o=>{o===this.leaf?this.focusComposer():this.stickToListBottom=!1}))}scheduleTreeReconcile(){this.treeReconcileTimer==null&&(this.treeReconcileTimer=window.setTimeout(()=>{if(this.treeReconcileTimer=null,!this.viewRoot?.isConnected)return;let t=this.noteFolder,e=t+"/",s=0;for(let i of this.app.vault.getMarkdownFiles()){let n=i.parent?.path?.replace(/\/+$/,"")??"";if(!(n===t||t!==""&&n.startsWith(e)))continue;let r=this.app.metadataCache.getFileCache(i)?.frontmatter?.id;typeof r=="string"&&r&&s++}s!==this.tree.fileBackedCount()&&(this.tree.rebuild(t),this.debouncedRender())},400))}focusView(){requestAnimationFrame(()=>{this.viewRoot?.isConnected&&(document.activeElement instanceof HTMLElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA")||this.viewRoot.focus({preventScroll:!0}))})}focusComposer(){if(!wt().autofocusComposerAfterSend)return;let t=()=>{if(!this.viewRoot?.isConnected||Date.now()<this.suppressComposerFocusUntil)return;let e=document.activeElement;e&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA")&&e!==this.composerInputEl||(e&&e.tagName==="BUTTON"&&this.viewRoot.contains(e),this.composerInputEl?.focus({preventScroll:!0}))};requestAnimationFrame(t),setTimeout(t,50),setTimeout(t,200)}async onClose(){qs(this),this.detachTreeHook?.(),this.detachSettings?.(),this.app.vault.off("modify",this.onFileModify),this.app.vault.off("create",this.onFileCreate),window.removeEventListener("keydown",this.onDocKeyDown,!0),this.listResizeObserver?.disconnect(),this.listResizeObserver=null,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null,this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=null,this.focusedMiniObserver?.disconnect(),this.focusedMiniObserver=null,this.treeReconcileTimer!=null&&(window.clearTimeout(this.treeReconcileTimer),this.treeReconcileTimer=null),this.composerAutocomplete?.detach(),this.composerAutocomplete=null;for(let t of this.slugDebouncers.values())t.cancel();for(let t of this.attachmentDebouncers.values())t.cancel();for(let t of this.contribTimers.values())clearTimeout(t);this.contribTimers.clear();try{await this.flushDrafts()}catch{}try{await this.order.flush(this.noteFolder)}catch{}try{await this.sortStore.flush(this.noteFolder)}catch{}try{await this.fmSync.flush()}catch{}this.stampSelectedCursor(!0),this.fmSyncUnsubscribe?.(),this.fmSyncUnsubscribe=null}setEphemeralState(t){let e=t;e?.focusId&&(this.focusId=e.focusId),e?.timeFilter&&(this.timeFilter=e.timeFilter)}getEphemeralState(){return{focusId:this.focusId,timeFilter:this.timeFilter}}getState(){return{...super.getState()??{},folderOverride:this.folderOverride,timeFilter:this.timeFilter,focusId:this.focusId,tagFilter:this.tagFilter,colorFilter:this.colorFilter,timeFilterCalendar:this.timeFilterCalendar,tinyMode:this.tinyMode,tinyAlwaysOnTop:this.tinyAlwaysOnTop,tinyOpacity:this.tinyOpacity,compactMode:this.compactMode,navBackStack:this.navBackStack,navForwardSnapshots:this.navForwardSnapshots}}async setState(t,e){let s=t??null;if(s){"folderOverride"in s&&(this.folderOverride=s.folderOverride??null),s.timeFilter&&(this.timeFilter=s.timeFilter),s.focusId&&(this.focusId=s.focusId),"tagFilter"in s&&(this.tagFilter=s.tagFilter??null),"colorFilter"in s&&(this.colorFilter=s.colorFilter??null),"timeFilterCalendar"in s&&(this.timeFilterCalendar=!!s.timeFilterCalendar),"tinyMode"in s&&(this.tinyMode=!!s.tinyMode),"tinyAlwaysOnTop"in s&&(this.tinyAlwaysOnTop=!!s.tinyAlwaysOnTop),typeof s.tinyOpacity=="number"&&Number.isFinite(s.tinyOpacity)&&(this.tinyOpacity=Math.min(1,Math.max(.3,s.tinyOpacity))),"compactMode"in s&&(this.compactMode=!!s.compactMode);let r=o=>o&&typeof o.folder=="string"&&typeof o.focusId=="string";Array.isArray(s.navBackStack)&&(this.navBackStack=s.navBackStack.filter(r)),Array.isArray(s.navForwardSnapshots)&&(this.navForwardSnapshots=s.navForwardSnapshots.filter(r))}let i=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),n=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null;if(this.noteFolder=n||i||"Stashpad",await super.setState(t,e),this.refreshHeaderTitle(),this.viewRoot){this.loadConfig(),await this.bootstrapFolder(),this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.defaultCursorToLast(),this.draftsLoadedFor=null,this.composerDraft="",await this.loadDraftsForFolder(),this.lastCursorByFocus.clear();try{let a=this.plugin.loadLastCursor(this.noteFolder);for(let[l,c]of a)this.lastCursorByFocus.set(l,c)}catch{}let r=this.lastCursorByFocus.get(this.focusId),o;r&&this.tree.get(r)?(this.pendingFocusIds=[r],o={kind:"scroll-to-id",id:r,align:"start"}):o={kind:"pin-bottom",until:"next-user-input"},this.render(o)}}focus(){this.viewRoot?.focus({preventScroll:!0})}loadConfig(){let t=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),s=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||t||"Stashpad";s!==this.noteFolder?(this.noteFolder=s,this.tree.rebuild(this.noteFolder)):this.noteFolder=s}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(t={}){let e=this.captureNavSnapshot(),s=this.navBackStack[this.navBackStack.length-1];s&&s.folder===e.folder&&s.focusId===e.focusId||(this.navBackStack.push(e),t.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(t,e={}){let s=t?.trim().replace(/^\/+|\/+$/g,"")||null;if(s&&this.isReservedFolder(s)){new N.Notice(`"${s}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((s||null)!==(this.folderOverride||null)){e.skipHistory||this.recordNavState(),this.folderOverride=s,this.focusId=R,this.lastCursorByFocus.clear(),this.selection.clear(),this.cursorIdx=-1,this.lastSelected=null,this.composerDraft="",await this.flushDrafts(),this.draftsLoadedFor=null,this.loadConfig();try{await this.bootstrapFolder()}catch(i){let n=i?.message??"";/already exists/i.test(n)||console.warn("[Stashpad] bootstrapFolder failed:",i)}this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),await this.loadDraftsForFolder();try{let i=this.app.workspace;typeof i.saveLayout=="function"?await i.saveLayout():this.app.workspace.requestSaveLayout()}catch{this.app.workspace.requestSaveLayout()}this.refreshHeaderTitle(),this.render()}}cmdOpenFolderPicker(){this.openFolderPicker()}openFolderPicker(){this.plugin.openFolderPicker()}listVaultFolders(){let t=[];for(let e of this.app.vault.getAllLoadedFiles())if(e instanceof N.TFolder){if(e.path==="/"||e.path===""||e.path.startsWith(".")||this.isReservedFolder(e.path))continue;t.push(e.path)}return t.sort((e,s)=>e.localeCompare(s))}isReservedFolder(t){let e=t.split("/").filter(Boolean).pop()??"";return e?new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors"].map(i=>(i??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(e):!1}persistFocus(){try{this.app.workspace.requestSaveLayout()}catch{}}cmdUndo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canUndo()){new N.Notice("Nothing to undo.");return}let e=t.peekUndoLabel(),s=this.plugin.notifications.recent()[0]?.category??"system";t.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${e}`,kind:"info",category:s,folder:this.noteFolder})).catch(i=>this.plugin.notifications.show({message:`Undo failed: ${i.message}`,kind:"error",category:"system",folder:this.noteFolder}))}cmdRedo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canRedo()){new N.Notice("Nothing to redo.");return}let e=t.peekRedoLabel(),s=this.plugin.notifications.recent()[0]?.category??"system";t.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${e}`,kind:"info",category:s,folder:this.noteFolder})).catch(i=>this.plugin.notifications.show({message:`Redo failed: ${i.message}`,kind:"error",category:"system",folder:this.noteFolder}))}async snapshotNotes(t,e){let s=[],i=new Set;for(let a of t)!a.file||i.has(a.file.path)||(i.add(a.file.path),s.push(a.file));let n=await Promise.all(s.map(a=>this.app.vault.read(a))),r=s.map((a,l)=>({path:a.path,content:n[l]})),o=[];if(e){let a=new Set,l=[];for(let h of n)for(let u of this.extractAttachments(this.stripFrontmatter(h))){let d=this.app.metadataCache.getFirstLinkpathDest(u,"");d&&!a.has(d.path)&&(a.add(d.path),l.push(d))}let c=await Promise.all(l.map(h=>this.app.vault.readBinary(h)));for(let h=0;h<l.length;h++)o.push({path:l[h].path,data:c[h]})}return{notes:r,attachments:o}}async restoreSnapshots(t,e){for(let i of t.attachments)try{await this.app.vault.adapter.exists(i.path)||await this.app.vault.createBinary(i.path,i.data)}catch{}for(let i of t.notes)try{await this.app.vault.adapter.exists(i.path)||await this.app.vault.create(i.path,i.content)}catch{}let s=()=>{e&&e.some(n=>this.tree.get(n))&&(this.pendingFocusIds=e.slice())};s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"}),setTimeout(()=>{s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},100),setTimeout(()=>{s(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},400),setTimeout(()=>{for(let i of t.notes){let n=this.tree.idForPath(i.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(t){let e=new Set;for(let s of t.notes){let i=this.tree.idForPath(s.path);if(!i)continue;let n=this.tree.get(i);n?.parent&&e.add(n.parent)}for(let s of t.notes){let i=this.app.vault.getAbstractFileByPath(s.path);if(i)try{await this.app.fileManager.trashFile(i)}catch{}}for(let s of t.attachments){let i=this.app.vault.getAbstractFileByPath(s.path);if(i)try{await this.app.fileManager.trashFile(i)}catch{}}this.tree.rebuild(this.noteFolder),this.render();for(let s of e)this.fmSync.scheduleParentOfDeleted(s)}async loadDraftsForFolder(){if(this.draftsLoadedFor===this.noteFolder)return;this.draftsLoadedFor=this.noteFolder;let t=this.plugin.settings.drafts??{};this.composerDraft=t[this.noteFolder]??"",console.debug("[Stashpad] loadDrafts",{folder:this.noteFolder,has:!!t[this.noteFolder],available:Object.keys(t)})}async saveDraft(t){try{let e=this.noteFolder;if((this.plugin.settings.drafts?.[e]??"")===t)return;let i={...this.plugin.settings.drafts??{}};t.length===0?delete i[e]:i[e]=t,this.plugin.settings.drafts=i,t.length===0?await this.plugin.saveSettings():await this.plugin.persistSettingsQuiet()}catch(e){console.warn("Stashpad: drafts save failed",e)}}async recordLastSubmitted(t){try{let e={...this.plugin.settings.lastSubmitted??{}};e[this.noteFolder]=t,this.plugin.settings.lastSubmitted=e,await this.plugin.persistSettingsQuiet()}catch{}}hasRestorableDraft(){let t=this.plugin.settings.drafts?.[this.noteFolder];if(!t||!t.trim())return!1;let e=this.plugin.settings.lastSubmitted?.[this.noteFolder];return!(e&&e===t)}syncComposerDraftForFocus(){}async flushDrafts(){this.composerInputEl?await this.saveDraft(this.composerInputEl.value):await this.saveDraft(this.composerDraft)}timeFilterCutoff(){if(this.timeFilter==="all")return null;if(this.timeFilterCalendar){let e=(0,N.moment)();switch(this.timeFilter){case"day":return e.startOf("day").valueOf();case"week":return e.startOf("isoWeek").valueOf();case"month":return e.startOf("month").valueOf();case"year":return e.startOf("year").valueOf()}}let t=Date.now();switch(this.timeFilter){case"day":return t-864e5;case"week":return t-7*864e5;case"month":return t-30*864e5;case"year":return t-365*864e5}return null}allowedByBases(){return null}currentViewMode(){return this.plugin.settings.viewModes?.[this.noteFolder]??"nested"}currentIncludeAttachments(){return!!this.plugin.settings.includeAttachmentsInEverything?.[this.noteFolder]}async setIncludeAttachments(t){let e={...this.plugin.settings.includeAttachmentsInEverything??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.includeAttachmentsInEverything=e,await this.plugin.saveSettings()}currentHideChildless(){return!!this.plugin.settings.hideChildlessNotes?.[this.noteFolder]}async setHideChildless(t){let e={...this.plugin.settings.hideChildlessNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.hideChildlessNotes=e,await this.plugin.saveSettings()}currentHideCompleted(){return!!this.plugin.settings.hideCompletedNotes?.[this.noteFolder]}async setHideCompleted(t){let e={...this.plugin.settings.hideCompletedNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.hideCompletedNotes=e,await this.plugin.saveSettings()}hasIncompleteDescendant(t){for(let e of t.children){let s=this.tree.get(e);if(s&&(!this.isCompleted(s)||this.hasIncompleteDescendant(s)))return!0}return!1}collectEmbeddedAttachmentPaths(){let t=new Set,e=this.noteFolder,s=this.app.vault.getAbstractFileByPath(e);if(!(s instanceof N.TFolder))return t;let i=[s];for(;i.length;){let n=i.pop();for(let r of n.children){if(r instanceof N.TFolder){i.push(r);continue}if(!(r instanceof N.TFile)||r.extension!=="md")continue;let o=this.app.metadataCache.getFileCache(r)?.frontmatter;if(!(!o||!Array.isArray(o.attachments)))for(let a of o.attachments){if(typeof a!="string")continue;let l=this.app.metadataCache.getFirstLinkpathDest(a,r.path);l?t.add(l.path):t.add(a)}}}return t}collectFileItems(t){let e=this.noteFolder,s=this.app.vault.getAbstractFileByPath(e);if(!(s instanceof N.TFolder))return[];let i=this.currentIncludeAttachments(),n=i?new Set:this.collectEmbeddedAttachmentPaths(),r=new Set(["_authors","_imports","_exports","_processed"]),o=[],a=[s];for(;a.length;){let l=a.pop();for(let c of l.children){if(c instanceof N.TFolder){let h=c.name;if(l===s&&r.has(h)||l===s&&h==="_attachments"&&!i)continue;a.push(c);continue}c instanceof N.TFile&&c.extension!=="md"&&(c.name===".stashpad-order.json"||c.name===".stashpad-sort.json"||!i&&n.has(c.path)||o.push(c))}}return o}populateListBody(t,e){this.lastListWidth=t.clientWidth||this.lastListWidth,e.file&&N.Platform.isMobile&&(this.renderFocusedHeaderMini(t,e),this.renderFocusedHeader(t,e));let i=this.currentViewMode()==="everything"?this.collectFileItems(e.id):[];if(this.currentChildren.length===0&&i.length===0)t.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(i.length===0)for(let n=0;n<this.currentChildren.length;n++)this.renderNote(t,this.currentChildren[n],n);else{let r=[...this.currentChildren.map((o,a)=>({kind:"note",ts:Number.isFinite(Date.parse(o.created))?Date.parse(o.created):0,idx:a})),...i.map(o=>({kind:"file",ts:o.stat.ctime,file:o}))];r.sort((o,a)=>o.ts-a.ts);for(let o of r)o.kind==="note"?this.renderNote(t,this.currentChildren[o.idx],o.idx):this.renderFileRow(t,o.file)}e.file&&N.Platform.isMobile&&this.installFocusedMiniObserver(t)}refreshList(){if(!this.listEl){this.render();return}let t=this.tree.get(this.focusId)??this.tree.getRoot();this.currentChildren=this.filterChildren(this.collectViewItems(t.id)),this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let e=this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2,s=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,t),e?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=s}renderFileRow(t,e){let s=t.createDiv({cls:"stashpad-file-row"});s.dataset.path=e.path,s.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(e.stat.ctime).toISOString())});let n=s.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:e.name}),n.createSpan({cls:"stashpad-file-ext",text:e.extension.toUpperCase()}),s.title=`${e.path} \u2014 click to open`,s.onclick=r=>{r.preventDefault(),this.app.workspace.openLinkText(e.path,"",!1)}}async setViewMode(t){let e={...this.plugin.settings.viewModes??{}};t==="nested"?delete e[this.noteFolder]:e[this.noteFolder]=t,this.plugin.settings.viewModes=e,await this.plugin.saveSettings()}collectViewItems(t){let e=this.currentViewMode(),s=this.currentHideChildless(),i=this.tree.getChildren(t),n=s?i.filter(a=>a.children.length>0):i;if(e==="nested")return n;let r=[],o=a=>{r.push(a);for(let l of this.tree.getChildren(a.id))o(l)};for(let a of n)o(a);return r}filterChildren(t){let e=this.timeFilterCutoff(),s=this.tagFilter?.toLowerCase(),i=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted();return!e&&!s&&!i&&!n?t:t.filter(r=>{if(e&&r.created){let o=Date.parse(r.created);if(!Number.isNaN(o)&&o<e)return!1}return!(s&&(!r.file||!this.nodeHasTag(r,s))||i&&(this.colorForNode(r)?.toLowerCase()??null)!==i||n&&this.isCompleted(r)&&!this.hasIncompleteDescendant(r))})}nodeHasTag(t,e){if(!t.file)return!1;let s=this.app.metadataCache.getFileCache(t.file);if(!s)return!1;if(s.tags){for(let n of s.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===e)return!0}let i=s.frontmatter?.tags;if(i){let n=Array.isArray(i)?i:[i];for(let r of n)if(typeof r=="string"&&r.replace(/^#/,"").toLowerCase()===e)return!0}return!1}collectFolderTags(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let i of e){if(!i.file)continue;let n=this.app.metadataCache.getFileCache(i.file);if(n?.tags)for(let o of n.tags){let a=(o.tag||"").replace(/^#/,"");a&&t.set(a,(t.get(a)??0)+1)}let r=n?.frontmatter?.tags;if(r){let o=Array.isArray(r)?r:[r];for(let a of o){if(typeof a!="string")continue;let l=a.replace(/^#/,"");l&&t.set(l,(t.get(l)??0)+1)}}}let s=[...t.entries()].map(([i,n])=>({raw:i,count:n,label:this.formatTagLabel(i)}));return s.sort((i,n)=>n.count-i.count||i.label.localeCompare(n.label)),s}formatTagLabel(t){return t&&t.split("/").map(e=>e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[-_\s]+/).filter(Boolean).map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")).join(" / ")}collectFolderColors(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let i of e){let n=this.colorForNode(i);if(!n)continue;let r=n.toLowerCase();t.set(r,(t.get(r)??0)+1)}let s=[...t.entries()].map(([i,n])=>({hex:i,count:n}));return s.sort((i,n)=>n.count-i.count||i.hex.localeCompare(n.hex)),s}defaultCursorToLast(){let t=this.tree.get(this.focusId)??this.tree.getRoot(),e=this.filterChildren(this.collectViewItems(t.id));this.cursorIdx=e.length-1,this.selection.clear(),e.length>0&&(this.selection.add(e[e.length-1].id),this.lastSelected=e[e.length-1].id)}stampSelectedCursor(t=!1){let s=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;if(!s)return;this.lastCursorByFocus.set(this.focusId,s);let i=()=>{let n=this.lastCursorByFocus.get(this.focusId);n&&this.plugin.saveLastCursor(this.noteFolder,this.focusId,n)};if(t){this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=null,i();return}this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=window.setTimeout(()=>{this.stampLastCursorTimer=null,i()},400)}captureScrollAnchor(){let t=this.listEl;if(!t)return null;let e=t.getBoundingClientRect().top,s=Array.from(t.querySelectorAll(".stashpad-note"));if(s.length===0)return null;let i=null;for(let n of s){let r=n.dataset.id;if(!r)continue;let o=n.getBoundingClientRect().top-e;if(o>=0){i={id:r,offsetFromListTop:o};break}i={id:r,offsetFromListTop:o}}return i}restoreScrollAnchor(t,e){let s=this.listEl;if(s){if(t){let i=s.querySelector(`[data-id="${t.id}"]`);if(i){let n=s.getBoundingClientRect().top,r=i.getBoundingClientRect().top-n;s.scrollTop+=r-t.offsetFromListTop;return}}e>0&&(s.scrollTop=e)}}render(t){this.pendingRenderPolicy=t??{kind:"preserve"},this.loadConfig();let e=this.viewRoot,s=this.listEl?.scrollTop??0,n=(t??{kind:"preserve"}).kind==="preserve"?this.captureScrollAnchor():null;!!this.composerInputEl&&document.activeElement===this.composerInputEl&&(this.focusComposerOnNextRender=!0,this.pendingComposerCaret=this.composerInputEl?.selectionStart??null);let o=!!this.listEl&&(this.stickToListBottom||this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2);e.empty(),e.toggleClass("is-mobile",N.Platform.isMobile),e.toggleClass("is-tiny",this.tinyMode),e.toggleClass("is-compact",this.compactMode);let a=this.containerEl.closest(".workspace-leaf");a&&(a.classList.toggle("stashpad-is-tiny",this.tinyMode),a.classList.toggle("stashpad-is-compact",this.compactMode));let l=this.containerEl.closest(".workspace-tabs");l&&l.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode?this.renderTinyHeader(e):(this.compactMode||this.renderTimeFilterBar(e),this.renderBreadcrumb(e));let c=this.tree.get(this.focusId)??this.tree.getRoot();if(c.file&&!N.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(e,c),this.currentChildren=this.filterChildren(this.collectViewItems(c.id)),this.autoSelectNewest&&this.currentChildren.length>0){let d=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(d.id),this.lastSelected=d.id,this.autoSelectNewest=!1}else if(this.pendingFocusIds){let d=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let p=-1;for(let m of d){let v=this.currentChildren.findIndex(y=>y.id===m);v>=0&&(this.selection.add(m),p<0&&(p=v))}this.cursorIdx=p,p>=0&&(this.lastSelected=d.find(m=>this.currentChildren.some(v=>v.id===m))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let h=e.createDiv({cls:"stashpad-list"});if(this.listEl=h,h.addEventListener("dragover",d=>{if(!this.dragSourceIds)return;let p=d.target;if(p&&p.closest&&p.closest(".stashpad-note"))return;d.preventDefault(),d.dataTransfer&&(d.dataTransfer.dropEffect="move");let m=Array.from(h.querySelectorAll(".stashpad-note"));if(m.length!==0){for(let v of m){let y=v.getBoundingClientRect();if(d.clientY<y.top+y.height/2){this.placePlaceholder(v,"before");return}}this.placePlaceholder(m[m.length-1],"after")}}),h.addEventListener("drop",d=>{if(!this.dragSourceIds)return;d.preventDefault();let p=this.dragSourceIds.slice();if(this.dragSourceIds=null,!this.dragPlaceholder)return;let m=this.dragPlaceholder.nextElementSibling,v=this.dragPlaceholder.previousElementSibling;if(this.removeDragPlaceholder(),m&&m.classList.contains("stashpad-note")){let y=m.dataset.id;y&&this.reorderToTarget(p,y,"before")}else if(v&&v.classList.contains("stashpad-note")){let y=v.dataset.id;y&&this.reorderToTarget(p,y,"after")}}),this.populateListBody(h,c),this.renderComposer(e),N.Platform.isMobile&&this.renderMobileNav(e),this.plugin.notifyStashpadContentChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let d=this.pendingComposerCaret;this.pendingComposerCaret=null;let p=this.composerInputEl;if(p&&p.isConnected){if(p.focus({preventScroll:!0}),d!=null){let m=Math.min(d,p.value.length);try{p.setSelectionRange(m,m)}catch{}}}else requestAnimationFrame(()=>{let m=this.composerInputEl;if(m&&(m.focus({preventScroll:!0}),d!=null)){let v=Math.min(d,m.value.length);try{m.setSelectionRange(v,v)}catch{}}})}let u=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,u&&this.listEl){let d=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,u.kind){case"preserve":d?this.scrollListToBottom():o?this.scrollListToBottom():this.restoreScrollAnchor(n,s);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let p=u.scrollTop,m=this.listEl,v=()=>{this.suppressScrollSave=!0;let y=Math.max(0,m.scrollHeight-m.clientHeight);m.scrollTop=Math.min(p,y),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};v(),requestAnimationFrame(v),setTimeout(v,60),setTimeout(v,200),setTimeout(v,600);break}case"follow-cursor":s>0&&(this.listEl.scrollTop=s),this.revealCursorRow();break;case"scroll-to-id":{let p=u.id,m=u.align,v=this.listEl,y=()=>{this.suppressScrollSave=!0;let b=v.querySelector(`[data-id="${p}"]`);b&&b.scrollIntoView({block:m,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};y(),requestAnimationFrame(y),setTimeout(y,60),setTimeout(y,200),setTimeout(y,600),setTimeout(()=>{this.suppressScrollSave=!1},700);break}}}else this.scrollToBottomOnNextRender?(this.scrollToBottomOnNextRender=!1,this.scrollListToBottom()):this.listEl&&o?this.scrollListToBottom():this.listEl&&s>0&&(this.listEl.scrollTop=s);if(this.stampSelectedCursor(),this.listEl){this.listResizeObserver?.disconnect();let d=this.listEl,p=d.scrollTop,m=new ResizeObserver(()=>{if(Date.now()<this.keyboardTransitionUntil)return;if(this.stickToListBottom){d.scrollTop=d.scrollHeight,p=d.scrollTop;return}let y=Math.max(0,d.scrollHeight-d.clientHeight);d.scrollTop<p&&p<=y?d.scrollTop=p:p=d.scrollTop});m.observe(d),this.listResizeObserver=m,d.addEventListener("wheel",y=>{y.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let v=0;d.addEventListener("touchstart",y=>{v=y.touches[0]?.clientY??0},{passive:!0}),d.addEventListener("touchmove",y=>{let b=y.touches[0]?.clientY??v;b>v&&(this.stickToListBottom=!1),v=b},{passive:!0}),d.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),d.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}renderTimeFilterBar(t){let e=t.createDiv({cls:"stashpad-time-filter-bar"}),s=e.createEl("button",{cls:"stashpad-folder-btn"}),i=!!this.folderOverride,n=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,N.setIcon)(s.createSpan({cls:"stashpad-btn-icon"}),"folder"),s.createSpan({text:n,cls:"stashpad-btn-text"}),s.title=i?`Folder (override): ${this.noteFolder} Click to change or revert to default.`:`Folder: ${this.noteFolder} -Click to override for this tab.`,i&&s.addClass("is-override"),s.onclick=h=>{h.preventDefault(),this.openFolderPicker()};let r=e.createEl("button",{cls:"stashpad-search-btn"});(0,O.setIcon)(r,"search"),r.title="Search notes (Mod+F)",r.onclick=h=>{h.preventDefault(),this.openSearchModal()},O.Platform.isMobile?this.renderMobileFiltersButton(e):(this.renderTagFilterDropdown(e),this.renderColorFilterDropdown(e),this.renderSortDropdown(e),this.renderViewDropdown(e));let o=e.createDiv({cls:"stashpad-time-filter-btns"}),a=o.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,O.setIcon)(a,this.timeFilterCalendar?"calendar":"history"),a.title=this.timeFilterCalendar?"Calendar mode: filters use start-of-day/week/month/year. Click for rolling windows.":"Rolling mode: filters look back N days from now. Click for calendar boundaries.",this.timeFilterCalendar&&a.addClass("is-active"),a.onclick=h=>{h.preventDefault(),this.timeFilterCalendar=!this.timeFilterCalendar,this.persistFocus(),this.render()};for(let h of Qe){let u=this.timeFilterCalendar?h.calShort:h.rollShort,m=this.timeFilterCalendar?h.calLong:h.rollLong,g=o.createEl("button",{cls:"stashpad-time-filter-btn",text:u});g.title=m,this.timeFilter===h.key&&g.addClass("is-active"),g.onclick=y=>{y.preventDefault(),this.setTimeFilter(h.key)}}let l=e.createEl("select",{cls:"stashpad-time-filter-select"});for(let h of Qe){let u=this.timeFilterCalendar?h.calLong:h.rollLong,m=l.createEl("option",{text:u});m.value=h.key,this.timeFilter===h.key&&(m.selected=!0)}l.onchange=()=>this.setTimeFilter(l.value);let c=e.createDiv({cls:"stashpad-view-mode-btns"});if(!O.Platform.isMobile){let h=c.createEl("button",{cls:"stashpad-view-mode-btn"});(0,O.setIcon)(h,"minimize-2"),h.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",h.onclick=u=>{u.preventDefault(),this.plugin.openTinyWindow()}}let d=c.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,O.setIcon)(d,this.compactMode?"panel-top":"rows-2"),d.title=this.compactMode?"Compact mode is ON \u2014 click to restore full chrome.":"Compact mode \u2014 hide the filter row + focused header; keep breadcrumb + list + composer.",this.compactMode&&d.addClass("is-active"),d.onclick=h=>{h.preventDefault(),this.toggleCompactMode()},O.Platform.isMobile)return;let p=c.createEl("button",{cls:"stashpad-view-mode-btn"});(0,O.setIcon)(p,"external-link"),p.title=kt().popoutDuplicates?"Duplicate this Stashpad tab into a new Obsidian window. (Toggle in Settings \u2192 Open in new window \u2014 duplicate tab.)":"Move this Stashpad tab to a new Obsidian window. (Toggle in Settings \u2192 Open in new window \u2014 duplicate tab.)",p.onclick=h=>{h.preventDefault();let u=kt().popoutDuplicates;try{let m=this.app.workspace;if(u){let g=this.leaf.getViewState(),y=m.openPopoutLeaf?.();y?y.setViewState({...g,active:!0}):new O.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else m.moveLeafToPopout?.(this.leaf)}catch(m){new O.Notice(`Stashpad: open-in-new-window failed (${m.message})`)}}}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(t){let e=t.createDiv({cls:"stashpad-mobile-actions"}),s=e.createEl("button",{cls:"stashpad-mobile-action-btn"});(0,O.setIcon)(s,"arrow-left");let i=this.navBackStack.length>0||this.focusId!==B;s.title=this.navBackStack.length>0?"Back":this.focusId!==B?"Back (up to parent)":"No back history",i||s.addClass("is-disabled"),s.onclick=c=>{c.preventDefault(),this.navigateBack()};let n=e.createEl("button",{cls:"stashpad-mobile-action-btn"});(0,O.setIcon)(n,"arrow-right");let r=this.navForwardSnapshots.length>0;n.title=r?"Forward":"No forward history",r||n.addClass("is-disabled"),n.onclick=c=>{c.preventDefault(),this.navigateForward()};let o=e.createEl("button",{cls:"stashpad-mobile-action-btn"}),a=this.mobileSelectMode;(0,O.setIcon)(o,a?"check-square":"square"),o.title=a?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",a&&o.addClass("is-active"),o.onclick=c=>{if(c.preventDefault(),this.mobileSelectMode){let d=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),d){let p=this.currentChildren.findIndex(h=>h.id===d);this.selection.add(d),this.lastSelected=d,p>=0&&(this.cursorIdx=p)}this.firstSelectedId=null,this.mobileSelectMode=!1,this.render()}else{let d=this.currentChildren[Math.max(0,this.cursorIdx)];this.mobileSelectMode=!0,this.selection.clear(),d&&(this.selection.add(d.id),this.lastSelected=d.id,this.firstSelectedId=d.id),this.render(),new O.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let l=e.createEl("button",{cls:"stashpad-mobile-action-btn"});(0,O.setIcon)(l,"zap"),l.title="Actions (move, delete, undo, \u2026)",l.onclick=c=>{c.preventDefault(),this.openMobileActionsMenu(l)}}openMobileActionsMenu(t){let e=new O.Menu,s=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],i=this.selection.size<=1;e.addItem(r=>r.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),e.addItem(r=>r.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),e.addSeparator(),e.addItem(r=>r.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),e.addSeparator(),e.addItem(r=>r.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!s).onClick(()=>this.cmdOpenInNewStashpadTab())),e.addItem(r=>r.setTitle("Open in editor").setIcon("pencil").setDisabled(!s).onClick(()=>this.cmdOpenInEditor())),e.addSeparator(),e.addItem(r=>r.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!s).onClick(()=>this.cmdMovePicker())),e.addItem(r=>r.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!s).onClick(()=>this.cmdInListPicker())),e.addItem(r=>r.setTitle("Outdent").setIcon("outdent").setDisabled(!s).onClick(()=>void this.cmdOutdent())),e.addItem(r=>r.setTitle("Set color\u2026").setIcon("palette").setDisabled(!s).onClick(()=>this.cmdSetColor())),e.addItem(r=>r.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!s).onClick(()=>void this.cmdToggleComplete())),e.addItem(r=>r.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!s).onClick(()=>void this.cmdToggleTask())),e.addItem(r=>r.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!s).onClick(()=>this.cmdSetDue())),e.addSeparator(),e.addItem(r=>r.setTitle("Copy").setIcon("copy").setDisabled(!s).onClick(()=>void this.cmdCopy())),e.addItem(r=>r.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!s).onClick(()=>void this.cmdCopyTree())),e.addItem(r=>r.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!s).onClick(()=>void this.cmdClone())),e.addItem(r=>r.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),e.addItem(r=>r.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),e.addItem(r=>r.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!s||!i).onClick(()=>void this.cmdSplit())),e.addSeparator(),e.addItem(r=>r.setTitle("Delete").setIcon("trash-2").setDisabled(!s).onClick(()=>void this.cmdDelete()));let n=t.getBoundingClientRect();e.showAtPosition({x:n.left,y:n.bottom+4})}renderTagFilterDropdown(t){let e=t.createEl("select",{cls:"stashpad-tag-filter-select"}),s=e.createEl("option",{text:"All tags"});s.value="",this.tagFilter||(s.selected=!0);let i=this.collectFolderTags();if(i.length===0)e.disabled=!0,s.text="No tags";else for(let n of i){let r=e.createEl("option",{text:`${n.label} (${n.count})`});r.value=n.raw,this.tagFilter&&this.tagFilter.toLowerCase()===n.raw.toLowerCase()&&(r.selected=!0)}e.onchange=()=>this.setTagFilter(e.value||null)}renderColorFilterDropdown(t){let e=this.collectFolderColors(),s=t.createDiv({cls:"stashpad-color-filter-btn"});s.setAttribute("role","button"),s.setAttribute("tabindex","0"),(()=>{s.empty();let r=s.createSpan({cls:"stashpad-color-filter-swatch"}),o=s.createSpan({cls:"stashpad-color-filter-label"});if(this.colorFilter){let a=this.colorFilter.toLowerCase();r.style.background=a;let l=this.plugin.getColorAlias(this.noteFolder,a);o.setText(l??a)}else e.length===0?(r.addClass("is-empty"),o.setText("No colors"),s.addClass("is-disabled")):(r.addClass("is-empty"),o.setText("All colors"))})();let n=r=>{r.preventDefault(),!(e.length===0&&!this.colorFilter)&&this.openColorFilterMenu(s,e)};s.onclick=n,s.onkeydown=r=>{(r.key==="Enter"||r.key===" ")&&n(r)}}openColorFilterMenu(t,e){let s=t.ownerDocument??document;s.querySelectorAll(".stashpad-color-filter-popover").forEach(l=>l.remove());let i=s.body.createDiv({cls:"stashpad-color-filter-popover"}),n=t.getBoundingClientRect();i.style.left=`${Math.max(8,n.left)}px`,i.style.top=`${n.bottom+4}px`,i.style.minWidth=`${n.width}px`,i.style.maxWidth="min(280px, calc(100vw - 16px))",i.style.width="max-content";let r=new O.Scope(this.app.scope),o=()=>{i.remove(),s.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(r)}catch{}},a=l=>{!i.contains(l.target)&&l.target!==t&&!t.contains(l.target)&&o()};r.register([],"Escape",l=>(l.preventDefault(),o(),!1)),this.app.keymap?.pushScope(r),this.populateColorMenuBody(i,e,o),setTimeout(()=>{s.addEventListener("mousedown",a,!0)},0)}renderSortDropdown(t){let e=this.noteFolder,s=this.focusId,i=this.sortStore.getMode(e,s),n=this.currentViewMode(),r=n!=="nested",o=t.createDiv({cls:"stashpad-sort-btn"});o.setAttribute("role","button"),o.setAttribute("tabindex",r?"-1":"0"),r&&o.addClass("is-disabled");let a=o.createSpan({cls:"stashpad-sort-icon"});(0,O.setIcon)(a,"arrow-up-down");let l=o.createSpan({cls:"stashpad-sort-label"});r?(l.setText("Sort: \u2014"),o.title=`Sort is per-parent and applies only to Nested view. The current view (${Xe[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(l.setText(he[i]),i!=="manual"&&o.addClass("is-active"),o.title=i==="manual"?"Sort children of this view. Click to change. Drag-reorder always reverts the affected parent to Manual.":`Currently: ${he[i]}. Drag-reorder will revert this parent to Manual.`);let c=d=>{r||(d.preventDefault(),this.openSortMenu(o))};o.onclick=c,o.onkeydown=d=>{r||(d.key==="Enter"||d.key===" ")&&c(d)}}openSortMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-sort-popover").forEach(a=>a.remove());let s=e.body.createDiv({cls:"stashpad-sort-popover"}),i=t.getBoundingClientRect();s.style.left=`${Math.max(8,i.left)}px`,s.style.top=`${i.bottom+4}px`,s.style.minWidth=`${i.width}px`,s.style.maxWidth="min(280px, calc(100vw - 16px))",s.style.width="max-content";let n=()=>{s.remove(),e.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(o)}catch{}},r=a=>{!s.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateSortMenuBody(s,n);let o=new O.Scope(this.app.scope);o.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(o),setTimeout(()=>{e.addEventListener("mousedown",r,!0)},0)}renderMobileFiltersButton(t){let e=t.createDiv({cls:"stashpad-mobile-filters-btn"});e.setAttribute("role","button"),e.setAttribute("tabindex","0");let s=e.createSpan({cls:"stashpad-mobile-filters-icon"});(0,O.setIcon)(s,"sliders-horizontal"),e.title="Filters / view options";let i=!!this.tagFilter,n=!!this.colorFilter,r=this.timeFilter!=="all",o=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",a=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentIncludeAttachments();(i||n||r||o||a)&&e.addClass("is-active");let l=c=>{c.preventDefault(),this.openMobileFiltersMenu(e)};e.onclick=l,e.onkeydown=c=>{(c.key==="Enter"||c.key===" ")&&l(c)}}openMobileFiltersMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-mobile-filters-popover").forEach(p=>p.remove());let s=e.body.createDiv({cls:"stashpad-mobile-filters-popover"}),i=t.getBoundingClientRect(),n=e.defaultView??window;s.style.right=`${Math.max(8,n.innerWidth-i.right)}px`,s.style.left="auto",s.style.top=`${i.bottom+4}px`,s.style.maxWidth="min(360px, calc(100vw - 16px))",s.style.width="max-content",s.style.minWidth="260px";let r=()=>{s.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(d)}catch{}},o=p=>{!s.contains(p.target)&&p.target!==t&&!t.contains(p.target)&&r()},a=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:p=>this.populateTagMenuBody(p,r)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:p=>this.populateColorMenuBody(p,this.collectFolderColors(),r)},{key:"time",title:"Time filter",summary:()=>{let p=Qe.find(h=>h.key===this.timeFilter);return p?this.timeFilterCalendar?p.calShort:p.rollShort:"All"},populate:p=>this.populateTimeMenuBody(p,r)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":he[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:p=>{if(this.currentViewMode()!=="nested"){p.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(p,r)}},{key:"view",title:"View",summary:()=>Xe[this.currentViewMode()],populate:p=>this.populateViewMenuBody(p,r)}],l="",c=()=>{s.empty();for(let p of a){let h=s.createDiv({cls:"stashpad-mobile-filters-section"}),u=h.createDiv({cls:"stashpad-mobile-filters-header"}),m=u.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,O.setIcon)(m,l===p.key?"chevron-down":"chevron-right"),u.createSpan({cls:"stashpad-mobile-filters-title",text:p.title}),u.createSpan({cls:"stashpad-mobile-filters-summary",text:p.summary()}),u.onclick=g=>{g.preventDefault(),g.stopPropagation(),l=l===p.key?"":p.key,c()},l===p.key){let g=h.createDiv({cls:"stashpad-mobile-filters-body"});p.populate(g)}}};c();let d=new O.Scope(this.app.scope);d.register([],"Escape",p=>(p.preventDefault(),r(),!1)),this.app.keymap?.pushScope(d),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}renderViewDropdown(t){let e=this.currentViewMode(),s=t.createDiv({cls:"stashpad-view-btn"});s.setAttribute("role","button"),s.setAttribute("tabindex","0");let i=s.createSpan({cls:"stashpad-view-icon"});(0,O.setIcon)(i,e==="flat"?"list":e==="everything"?"layout-grid":"list-tree"),s.createSpan({cls:"stashpad-view-label"}).setText(Xe[e]),e!=="nested"&&s.addClass("is-active"),s.title=e==="nested"?"View: Nested (the default). Click to switch to Flat or Everything.":e==="flat"?"View: Flat \u2014 all descendants of the current focus, flat by sort order. Drag-reorder is disabled in this mode. Click to change.":"View: Everything \u2014 all descendants of the current focus PLUS non-Stashpad files in the folder, flat by created/ctime. Click to change.";let r=o=>{o.preventDefault(),this.openViewMenu(s)};s.onclick=r,s.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&r(o)}}openViewMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-view-popover").forEach(a=>a.remove());let s=e.body.createDiv({cls:"stashpad-view-popover"});O.Platform.isMobile&&s.addClass("is-mobile");let i=t.getBoundingClientRect();s.style.left=`${Math.max(8,i.left)}px`,s.style.top=`${i.bottom+4}px`,s.style.minWidth=`${i.width}px`,s.style.maxWidth="min(320px, calc(100vw - 16px))",s.style.width="max-content";let n=()=>{s.remove(),e.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(o)}catch{}},r=a=>{!s.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateViewMenuBody(s,n);let o=new O.Scope(this.app.scope);o.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(o),setTimeout(()=>{e.addEventListener("mousedown",r,!0)},0)}populateViewMenuBody(t,e){let s=this.currentViewMode(),i=(d,p)=>{let h=t.createDiv({cls:"stashpad-view-popover-row"});d===s&&h.addClass("is-active"),h.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:Xe[d]}),h.createDiv({cls:"stashpad-view-popover-desc",text:p}),h.onclick=async m=>{m.preventDefault(),m.stopPropagation(),e(),d!==s&&(await this.setViewMode(d),this.render())}};i("nested","Tree of immediate children (default)."),i("flat","All descendants of the current focus, flat by sort."),i("everything","All descendants PLUS non-Stashpad files in the folder."),t.createDiv({cls:"stashpad-view-popover-divider"});let n=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),r=n.createEl("input",{type:"checkbox"});r.checked=this.currentHideChildless(),n.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide childless notes"}),n.createDiv({cls:"stashpad-view-popover-desc",text:s==="nested"?"Show only notes that have children. Applied at this level.":"Hide top-level notes without children; keep every parent's full subtree so no task is overlooked."}),n.onclick=async d=>{d.target!==r&&(d.preventDefault(),r.checked=!r.checked),await this.setHideChildless(r.checked),this.refreshList()};let o=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),a=o.createEl("input",{type:"checkbox"});a.checked=this.currentHideCompleted(),o.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide completed notes"}),o.createDiv({cls:"stashpad-view-popover-desc",text:"Hide notes marked complete. A completed parent stays visible while any descendant is still incomplete."}),o.onclick=async d=>{d.target!==a&&(d.preventDefault(),a.checked=!a.checked),await this.setHideCompleted(a.checked),this.refreshList()},t.createDiv({cls:"stashpad-view-popover-divider"});let l=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});s!=="everything"&&l.addClass("is-disabled");let c=l.createEl("input",{type:"checkbox"});c.checked=this.currentIncludeAttachments(),c.disabled=s!=="everything",l.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),l.createDiv({cls:"stashpad-view-popover-desc",text:s==="everything"?"Show attachments referenced by notes as their own rows in the file list. Off by default \u2014 they already appear inline on the notes that embed them.":"Only applies in Everything mode."}),l.onclick=async d=>{s==="everything"&&(d.target!==c&&(d.preventDefault(),c.checked=!c.checked),await this.setIncludeAttachments(c.checked),this.refreshList())}}setTagFilter(t){(this.tagFilter??null)!==(t??null)&&(this.tagFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(t,e){let s=this.noteFolder,i=this.focusId,n=this.sortStore.getMode(s,i);for(let r of cs){let o=t.createDiv({cls:"stashpad-sort-popover-row"});r===n&&o.addClass("is-active"),o.createSpan({cls:"stashpad-sort-popover-label",text:he[r]}),o.onclick=async a=>{a.preventDefault(),a.stopPropagation(),e(),r!==n&&(this.sortStore.setMode(s,i,r),await this.sortStore.save(s),this.tree.rebuild(s),this.render())}}}populateTimeMenuBody(t,e){let s=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),i=s.createEl("input",{type:"checkbox"});i.checked=this.timeFilterCalendar,s.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Calendar mode"}),s.createDiv({cls:"stashpad-view-popover-desc",text:"Use calendar boundaries (start of today/week/month/year). Off = rolling windows back from now."}),s.onclick=n=>{n.target!==i&&(n.preventDefault(),i.checked=!i.checked),this.timeFilterCalendar=i.checked,this.persistFocus(),this.refreshList()};for(let n of Qe){let r=t.createDiv({cls:"stashpad-sort-popover-row"});this.timeFilter===n.key&&r.addClass("is-active");let o=this.timeFilterCalendar?n.calLong:n.rollLong;r.createSpan({cls:"stashpad-sort-popover-label",text:o}),r.onclick=a=>{a.preventDefault(),a.stopPropagation(),e(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(t,e,s){let i=(n,r,o)=>{let a=t.createDiv({cls:"stashpad-color-filter-popover-row"}),l=a.createSpan({cls:"stashpad-color-filter-swatch"});r?l.style.background=r:l.addClass("is-empty");let c=a.createSpan({cls:"stashpad-color-filter-popover-label"});c.setText(n),r&&(c.style.color=r),a.onclick=d=>{d.preventDefault(),d.stopPropagation(),o(),s()}};i("All colors",null,()=>this.setColorFilter(null));for(let n of e){let r=this.plugin.getColorAlias(this.noteFolder,n.hex),o=r?`${r} (${n.count})`:`${n.hex} (${n.count})`;i(o,n.hex,()=>this.setColorFilter(n.hex))}}populateTagMenuBody(t,e){let s=this.collectFolderTags(),i=(n,r)=>{let o=t.createDiv({cls:"stashpad-color-filter-popover-row"});o.createSpan({cls:"stashpad-color-filter-swatch is-empty"}),o.createSpan({cls:"stashpad-color-filter-popover-label"}).setText(n),(this.tagFilter??"")===(r??"")&&o.addClass("is-active"),o.onclick=c=>{c.preventDefault(),c.stopPropagation(),this.setTagFilter(r),e()}};i(s.length===0?"No tags":"All tags",null);for(let n of s)i(`${n.label} (${n.count})`,n.raw)}setColorFilter(t){let e=t?t.toLowerCase():null;(this.colorFilter??null)!==e&&(this.colorFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}setTimeFilter(t){this.timeFilter!==t&&(this.timeFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}reconcileSelectionAfterFilter(){let t=this.filterChildren(this.collectViewItems(this.focusId)),e=new Set(t.map(s=>s.id));for(let s of[...this.selection])e.has(s)||this.selection.delete(s);if(this.firstSelectedId&&!e.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!e.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let s=t.findIndex(i=>this.selection.has(i.id));this.cursorIdx=s>=0?s:Math.min(this.cursorIdx,t.length-1)}else this.cursorIdx>=t.length&&(this.cursorIdx=t.length-1)}renderTinyHeader(t){let e=t.createDiv({cls:"stashpad-tiny-header"}),s=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});(0,O.setIcon)(s,"arrow-left"),s.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==B||s.addClass("is-disabled"),s.title=this.navBackStack.length>0?"Back":this.focusId!==B?"Back (up to parent)":"No back history",s.onclick=()=>this.navigateBack();let n=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});(0,O.setIcon)(n,"arrow-right"),n.title=this.navForwardSnapshots.length>0?"Forward":"No forward history",this.navForwardSnapshots.length===0&&n.addClass("is-disabled"),n.onclick=()=>this.navigateForward();let r=this.tree.get(this.focusId)??this.tree.getRoot(),o=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),a=this.focusId===B?o:`${o} / ${this.titleForNode(r).trim()}`,l=e.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),c=l.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,O.setIcon)(c,"folder"),l.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:a}),l.title=`${this.noteFolder}${this.focusId!==B?` / ${this.titleForNode(r).trim()}`:""} -Click to switch / create folder.`,l.onclick=m=>{m.preventDefault(),this.plugin.openFolderPicker()};let d=e.createDiv({cls:"stashpad-tiny-sticky"}),p=d.createEl("input",{type:"checkbox"});p.checked=this.tinyAlwaysOnTop,d.createSpan({text:"Sticky"}),p.onchange=()=>{this.tinyAlwaysOnTop=p.checked,this.applyTinyAlwaysOnTop()};let h=e.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,O.setIcon)(h,this.compactMode?"panel-top":"rows-2"),h.title=this.compactMode?"Compact mode is ON \u2014 click to turn off.":"Compact mode \u2014 click to turn on (strips row metadata).",this.compactMode&&h.addClass("is-active"),h.onclick=()=>{this.toggleCompactMode()};let u=e.createEl("button",{cls:"stashpad-tiny-expand"});(0,O.setIcon)(u,"maximize-2"),u.title="Exit tiny mode",u.onclick=()=>{this.exitTinyMode()}}getOwnElectronWindow(){try{let t=this.containerEl?.ownerDocument?.defaultView??window,i=((t?.require?.("electron")??window.require?.("electron"))?.remote??t?.electron?.remote??t?.["@electron/remote"])?.getCurrentWindow?.()??t?.electronWindow??null;if(!i)try{let n=window.require?.("electron"),r=n?.remote??n?.["@electron/remote"],a=(r?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];a.length===1?i=a[0]:a.length>1&&(i=r?.getFocusedWindow?.()??null??a[a.length-1])}catch(n){console.debug("[Stashpad] BrowserWindow.getAllWindows fallback failed",n)}return i||console.debug("[Stashpad] couldn't resolve own electron window"),i??null}catch(t){return console.debug("[Stashpad] resolve own electron window failed",t),null}}applyTinyAlwaysOnTop(){let t=this.getOwnElectronWindow();if(t)try{t.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop)}catch(e){console.debug("[Stashpad] setAlwaysOnTop failed",e)}}applyTinyWindow(){let t=this.getOwnElectronWindow();if(t)try{if(this.tinyMode){t.setMinimumSize?.(220,260);let i=100,n=100;try{let r=t.getBounds?.();r&&typeof r.x=="number"&&(i=r.x,n=r.y)}catch{}try{t.setBounds?.({x:i,y:n,width:280,height:360})}catch{}try{t.setSize?.(280,360)}catch{}t.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop)}else t.setAlwaysOnTop?.(!1)}catch(e){console.debug("[Stashpad] tiny window apply failed",e)}}async exitTinyMode(){this.tinyMode=!1,this.tinyAlwaysOnTop=!1,this.compactMode=!1,this.applyTinyWindow();let t=this.getOwnElectronWindow();try{if(t?.setMinimumSize?.(400,300),O.Platform.isMacOS??!1){let s=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(s?.remote?.screen??s?.screen)?.getPrimaryDisplay?.().workArea;n?t?.setBounds?.({x:n.x,y:n.y,width:n.width,height:n.height}):t?.maximize?.()}else t?.maximize?.()}catch{}this.render();try{await this.app.workspace.requestSaveLayout?.()}catch{}}enterTinyMode(){this.tinyMode=!0,this.applyTinyWindow(),this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderBreadcrumb(t){let e=t.createDiv({cls:"stashpad-breadcrumb"});this.renderActionsCluster(e);let s=e.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(O.Platform.isMobile?((0,O.setIcon)(s,"home"),s.title="Home"):s.setText("Home"),s.onclick=()=>this.navigateTo(B),this.focusId===B){let c=this.tree.getChildren(this.focusId).length;if(c>0&&(e.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${c}`}).title=`${c} direct child${c===1?"":"ren"}`),this.compactMode){let d=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,O.setIcon)(d,"panel-top"),d.title="Exit compact mode",d.onclick=p=>{p.preventDefault(),this.toggleCompactMode()}}return}let i=28,n=100,r=this.tree.pathTo(this.focusId),o=r.map(c=>{let d=this.titleForNode(c),p=d.length>i?d.slice(0,i-1)+"\u2026":d;return{id:c.id,label:p}}),a=c=>c.reduce((d,p)=>d+p.label.length+3,0);if(a(o)>n&&o.length>2){let c=!1;for(;a(o)>n&&o.length>2;)o.splice(1,1),c||(o.splice(1,0,{id:"__ellipsis__",label:"\u2026",isEllipsis:!0}),c=!0)}for(let c of o)if(e.createSpan({cls:"stashpad-crumb-sep",text:" / "}),c.isEllipsis)e.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:c.label}).title=r.map(d=>this.titleForNode(d)).join(" / ");else{let d=c.id,p=e.createSpan({cls:"stashpad-crumb",text:c.label});p.title=c.label,p.onclick=()=>this.navigateTo(d),p.oncontextmenu=h=>{h.preventDefault(),this.openCrumbMenu(h,d)},O.Platform.isMobile&&this.attachLongPress(p,()=>this.openCrumbMenu(null,d))}if(e.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",c=>{c.preventDefault(),this.openCrumbMenu(c,B)}),O.Platform.isMobile){let c=e.querySelector(".stashpad-crumb-home");c&&this.attachLongPress(c,()=>this.openCrumbMenu(null,B))}let l=this.tree.getChildren(this.focusId).length;if(l>0&&(e.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${l}`}).title=`${l} direct child${l===1?"":"ren"}`),this.compactMode){let c=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,O.setIcon)(c,"panel-top"),c.title="Exit compact mode",c.onclick=d=>{d.preventDefault(),this.toggleCompactMode()}}}attachLongPress(t,e){let s=null,i=0,n=0,r=()=>{s!=null&&(window.clearTimeout(s),s=null)};t.addEventListener("touchstart",o=>{let a=o.touches[0];i=a?.clientX??0,n=a?.clientY??0,r(),s=window.setTimeout(()=>{s=null,e()},500)},{passive:!0}),t.addEventListener("touchmove",o=>{let a=o.touches[0];a&&(Math.abs(a.clientX-i)>10||Math.abs(a.clientY-n)>10)&&r()},{passive:!0}),t.addEventListener("touchend",r),t.addEventListener("touchcancel",r)}openCrumbMenu(t,e){let s=this.tree.get(e);if(!s)return;let i=new O.Menu;if(i.addItem(n=>n.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>this.navigateTo(e))),i.addItem(n=>n.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>this.cmdOpenInNewStashpadTab(s))),s.file&&i.addItem(n=>n.setTitle("Open in editor (new tab)").setIcon("pencil").onClick(()=>this.cmdOpenInEditor(s))),t&&(t.clientX>0||t.clientY>0))i.showAtMouseEvent(t);else{let r=(t?.target??null)?.getBoundingClientRect();i.showAtPosition({x:r?.left??8,y:(r?.bottom??60)+4})}}renderFocusedHeaderMini(t,e){if(!e.file)return;let s=e.file,i=t.createDiv({cls:"stashpad-focused-mini"});i.dataset.id=e.id,i.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(e).trim());let r=i.createEl("button",{cls:"stashpad-pencil stashpad-focused-mini-pencil"});(0,O.setIcon)(r,"pencil"),r.title="Edit in new tab",r.onclick=o=>{o.stopPropagation(),this.openFileAtEnd(s)}}installFocusedMiniObserver(t){let e=t.querySelector(".stashpad-focused"),s=t.querySelector(".stashpad-focused-mini");!e||!s||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(i=>{for(let n of i)s.toggleClass("is-visible",!n.isIntersecting)},{root:t,threshold:.05}),this.focusedMiniObserver.observe(e))}renderFocusedHeader(t,e){if(!e.file)return;let s=e.file,i=t.createDiv({cls:"stashpad-focused"}),r=i.createDiv({cls:"stashpad-focused-meta"}).createDiv({cls:"stashpad-focused-meta-top"});r.createSpan({cls:"stashpad-focused-time stashpad-note-time",text:this.formatTime(e.created)}),r.createDiv({cls:"stashpad-focused-grip-spacer"});let o=i.createDiv({cls:"stashpad-focused-body"});o.addEventListener("click",d=>this.handleRenderedClick(d,e));let a=i.createDiv({cls:"stashpad-focused-actions"}),l=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,O.setIcon)(l,"pencil"),l.title="Edit in new tab",l.onclick=()=>void this.openFileAtEnd(s);let c=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,O.setIcon)(c,"copy"),c.title="Open this Stashpad in a new tab (clone)",c.onclick=()=>this.cmdOpenInNewStashpadTab(e),this.renderNoteBody(o,e,{clamp:O.Platform.isMobile,toggleHost:a,toggleAnchor:l})}renderRowBreadcrumb(t,e){let s=this.tree.pathTo(e.id),i=s.findIndex(o=>o.id===this.focusId),n=s.slice(i+1,s.length-1);if(n.length===0)return;let r=t.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((o,a)=>{let l=r.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(o)});l.title=`Focus into "${this.titleForNode(o)}"`,l.onclick=c=>{c.stopPropagation(),this.navigateTo(o.id)},a<n.length-1&&r.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(t){return Re(this.app,t,O.Platform.isMobile)}collectAuthorIds(t){let e=new Set,s=i=>{if(typeof i!="string")return null;let n=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let i of t){if(!i.file)continue;let n=this.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!n)continue;let r=s(n.author);if(r&&e.add(r),Array.isArray(n.contributors))for(let o of n.contributors){let a=s(o);a&&e.add(a)}}return Array.from(e)}bulkActionMessage(t){let e=t.nodes.map(o=>`"${this.titleForNode(o).trim()||"(untitled)"}"`),s=t.suffix?` ${t.suffix}`:"",i=t.destination?` ${t.destination}`:"";if(e.length===0)return`${t.verb}${s}${i}`;if(e.length===1)return`${t.verb} ${e[0]}${s}${i}`;let n=t.bulletMax??10,r=e.length<=n?e.map(o=>`\u2022 ${o}`).join(` +Click to override for this tab.`,i&&s.addClass("is-override"),s.onclick=d=>{d.preventDefault(),this.openFolderPicker()};let r=e.createEl("button",{cls:"stashpad-search-btn"});Yt(r,"search","\u{1F50D}"),r.title="Search notes (Mod+F)",r.onclick=d=>{d.preventDefault(),this.openSearchModal()},N.Platform.isMobile?this.renderMobileFiltersButton(e):(this.renderTagFilterDropdown(e),this.renderColorFilterDropdown(e),this.renderSortDropdown(e),this.renderViewDropdown(e));let o=e.createDiv({cls:"stashpad-time-filter-btns"}),a=o.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,N.setIcon)(a,this.timeFilterCalendar?"calendar":"history"),a.title=this.timeFilterCalendar?"Calendar mode: filters use start-of-day/week/month/year. Click for rolling windows.":"Rolling mode: filters look back N days from now. Click for calendar boundaries.",this.timeFilterCalendar&&a.addClass("is-active"),a.onclick=d=>{d.preventDefault(),this.timeFilterCalendar=!this.timeFilterCalendar,this.persistFocus(),this.render()};for(let d of es){let p=this.timeFilterCalendar?d.calShort:d.rollShort,m=this.timeFilterCalendar?d.calLong:d.rollLong,v=o.createEl("button",{cls:"stashpad-time-filter-btn",text:p});v.title=m,this.timeFilter===d.key&&v.addClass("is-active"),v.onclick=y=>{y.preventDefault(),this.setTimeFilter(d.key)}}let l=e.createEl("select",{cls:"stashpad-time-filter-select"});for(let d of es){let p=this.timeFilterCalendar?d.calLong:d.rollLong,m=l.createEl("option",{text:p});m.value=d.key,this.timeFilter===d.key&&(m.selected=!0)}l.onchange=()=>this.setTimeFilter(l.value);let c=e.createDiv({cls:"stashpad-view-mode-btns"});if(!N.Platform.isMobile){let d=c.createEl("button",{cls:"stashpad-view-mode-btn"});(0,N.setIcon)(d,"minimize-2"),d.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",d.onclick=p=>{p.preventDefault(),this.plugin.openTinyWindow()}}let h=c.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,N.setIcon)(h,this.compactMode?"panel-top":"rows-2"),h.title=this.compactMode?"Compact mode is ON \u2014 click to restore full chrome.":"Compact mode \u2014 hide the filter row + focused header; keep breadcrumb + list + composer.",this.compactMode&&h.addClass("is-active"),h.onclick=d=>{d.preventDefault(),this.toggleCompactMode()},N.Platform.isMobile)return;let u=c.createEl("button",{cls:"stashpad-view-mode-btn"});(0,N.setIcon)(u,"external-link"),u.title=wt().popoutDuplicates?"Duplicate this Stashpad tab into a new Obsidian window. (Toggle in Settings \u2192 Open in new window \u2014 duplicate tab.)":"Move this Stashpad tab to a new Obsidian window. (Toggle in Settings \u2192 Open in new window \u2014 duplicate tab.)",u.onclick=d=>{d.preventDefault();let p=wt().popoutDuplicates;try{let m=this.app.workspace;if(p){let v=this.leaf.getViewState(),y=m.openPopoutLeaf?.();y?y.setViewState({...v,active:!0}):new N.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else m.moveLeafToPopout?.(this.leaf)}catch(m){new N.Notice(`Stashpad: open-in-new-window failed (${m.message})`)}}}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(t){let e=t.createDiv({cls:"stashpad-mobile-actions"}),s=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Yt(s,"arrow-left","\u2039");let i=this.navBackStack.length>0||this.focusId!==R;s.title=this.navBackStack.length>0?"Back":this.focusId!==R?"Back (up to parent)":"No back history",i||s.addClass("is-disabled"),s.onclick=c=>{c.preventDefault(),this.navigateBack()};let n=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Yt(n,"arrow-right","\u203A");let r=this.navForwardSnapshots.length>0;n.title=r?"Forward":"No forward history",r||n.addClass("is-disabled"),n.onclick=c=>{c.preventDefault(),this.navigateForward()};let o=e.createEl("button",{cls:"stashpad-mobile-action-btn"}),a=this.mobileSelectMode;Yt(o,a?"check-square":"square",a?"\u2611":"\u2610"),o.title=a?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",a&&o.addClass("is-active"),o.onclick=c=>{if(c.preventDefault(),this.mobileSelectMode){let h=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),h){let u=this.currentChildren.findIndex(d=>d.id===h);this.selection.add(h),this.lastSelected=h,u>=0&&(this.cursorIdx=u)}this.firstSelectedId=null,this.mobileSelectMode=!1,this.render()}else{let h=this.currentChildren[Math.max(0,this.cursorIdx)];this.mobileSelectMode=!0,this.selection.clear(),h&&(this.selection.add(h.id),this.lastSelected=h.id,this.firstSelectedId=h.id),this.render(),new N.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let l=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Yt(l,"zap","\u26A1"),l.title="Actions (move, delete, undo, \u2026)",l.onclick=c=>{c.preventDefault(),this.openMobileActionsMenu(l)}}openMobileActionsMenu(t){let e=new N.Menu,s=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],i=this.selection.size<=1;e.addItem(r=>r.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),e.addItem(r=>r.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),e.addSeparator(),e.addItem(r=>r.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),e.addSeparator(),e.addItem(r=>r.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!s).onClick(()=>this.cmdOpenInNewStashpadTab())),e.addItem(r=>r.setTitle("Open in editor").setIcon("pencil").setDisabled(!s).onClick(()=>this.cmdOpenInEditor())),e.addSeparator(),e.addItem(r=>r.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!s).onClick(()=>this.cmdMovePicker())),e.addItem(r=>r.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!s).onClick(()=>this.cmdInListPicker())),e.addItem(r=>r.setTitle("Outdent").setIcon("outdent").setDisabled(!s).onClick(()=>void this.cmdOutdent())),e.addItem(r=>r.setTitle("Set color\u2026").setIcon("palette").setDisabled(!s).onClick(()=>this.cmdSetColor())),e.addItem(r=>r.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!s).onClick(()=>void this.cmdToggleComplete())),e.addItem(r=>r.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!s).onClick(()=>void this.cmdToggleTask())),e.addItem(r=>r.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!s).onClick(()=>this.cmdSetDue())),e.addSeparator(),e.addItem(r=>r.setTitle("Copy").setIcon("copy").setDisabled(!s).onClick(()=>void this.cmdCopy())),e.addItem(r=>r.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!s).onClick(()=>void this.cmdCopyTree())),e.addItem(r=>r.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!s).onClick(()=>void this.cmdClone())),e.addItem(r=>r.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),e.addItem(r=>r.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),e.addItem(r=>r.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!s||!i).onClick(()=>void this.cmdSplit())),e.addSeparator(),e.addItem(r=>r.setTitle("Delete").setIcon("trash-2").setDisabled(!s).onClick(()=>void this.cmdDelete()));let n=t.getBoundingClientRect();e.showAtPosition({x:n.left,y:n.bottom+4})}renderTagFilterDropdown(t){let e=t.createEl("select",{cls:"stashpad-tag-filter-select"}),s=e.createEl("option",{text:"All tags"});s.value="",this.tagFilter||(s.selected=!0);let i=this.collectFolderTags();if(i.length===0)e.disabled=!0,s.text="No tags";else for(let n of i){let r=e.createEl("option",{text:`${n.label} (${n.count})`});r.value=n.raw,this.tagFilter&&this.tagFilter.toLowerCase()===n.raw.toLowerCase()&&(r.selected=!0)}e.onchange=()=>this.setTagFilter(e.value||null)}renderColorFilterDropdown(t){let e=this.collectFolderColors(),s=t.createDiv({cls:"stashpad-color-filter-btn"});s.setAttribute("role","button"),s.setAttribute("tabindex","0"),(()=>{s.empty();let r=s.createSpan({cls:"stashpad-color-filter-swatch"}),o=s.createSpan({cls:"stashpad-color-filter-label"});if(this.colorFilter){let a=this.colorFilter.toLowerCase();r.style.background=a;let l=this.plugin.getColorAlias(this.noteFolder,a);o.setText(l??a)}else e.length===0?(r.addClass("is-empty"),o.setText("No colors"),s.addClass("is-disabled")):(r.addClass("is-empty"),o.setText("All colors"))})();let n=r=>{r.preventDefault(),!(e.length===0&&!this.colorFilter)&&this.openColorFilterMenu(s,e)};s.onclick=n,s.onkeydown=r=>{(r.key==="Enter"||r.key===" ")&&n(r)}}openColorFilterMenu(t,e){let s=t.ownerDocument??document;s.querySelectorAll(".stashpad-color-filter-popover").forEach(l=>l.remove());let i=s.body.createDiv({cls:"stashpad-color-filter-popover"}),n=t.getBoundingClientRect();i.style.left=`${Math.max(8,n.left)}px`,i.style.top=`${n.bottom+4}px`,i.style.minWidth=`${n.width}px`,i.style.maxWidth="min(280px, calc(100vw - 16px))",i.style.width="max-content";let r=new N.Scope(this.app.scope),o=()=>{i.remove(),s.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(r)}catch{}},a=l=>{!i.contains(l.target)&&l.target!==t&&!t.contains(l.target)&&o()};r.register([],"Escape",l=>(l.preventDefault(),o(),!1)),this.app.keymap?.pushScope(r),this.populateColorMenuBody(i,e,o),setTimeout(()=>{s.addEventListener("mousedown",a,!0)},0)}renderSortDropdown(t){let e=this.noteFolder,s=this.focusId,i=this.sortStore.getMode(e,s),n=this.currentViewMode(),r=n!=="nested",o=t.createDiv({cls:"stashpad-sort-btn"});o.setAttribute("role","button"),o.setAttribute("tabindex",r?"-1":"0"),r&&o.addClass("is-disabled");let a=o.createSpan({cls:"stashpad-sort-icon"});(0,N.setIcon)(a,"arrow-up-down");let l=o.createSpan({cls:"stashpad-sort-label"});r?(l.setText("Sort: \u2014"),o.title=`Sort is per-parent and applies only to Nested view. The current view (${ts[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(l.setText(pe[i]),i!=="manual"&&o.addClass("is-active"),o.title=i==="manual"?"Sort children of this view. Click to change. Drag-reorder always reverts the affected parent to Manual.":`Currently: ${pe[i]}. Drag-reorder will revert this parent to Manual.`);let c=h=>{r||(h.preventDefault(),this.openSortMenu(o))};o.onclick=c,o.onkeydown=h=>{r||(h.key==="Enter"||h.key===" ")&&c(h)}}openSortMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-sort-popover").forEach(a=>a.remove());let s=e.body.createDiv({cls:"stashpad-sort-popover"}),i=t.getBoundingClientRect();s.style.left=`${Math.max(8,i.left)}px`,s.style.top=`${i.bottom+4}px`,s.style.minWidth=`${i.width}px`,s.style.maxWidth="min(280px, calc(100vw - 16px))",s.style.width="max-content";let n=()=>{s.remove(),e.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(o)}catch{}},r=a=>{!s.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateSortMenuBody(s,n);let o=new N.Scope(this.app.scope);o.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(o),setTimeout(()=>{e.addEventListener("mousedown",r,!0)},0)}renderMobileFiltersButton(t){let e=t.createDiv({cls:"stashpad-mobile-filters-btn"});e.setAttribute("role","button"),e.setAttribute("tabindex","0");let s=e.createSpan({cls:"stashpad-mobile-filters-icon"});(0,N.setIcon)(s,"sliders-horizontal"),e.title="Filters / view options";let i=!!this.tagFilter,n=!!this.colorFilter,r=this.timeFilter!=="all",o=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",a=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentIncludeAttachments();(i||n||r||o||a)&&e.addClass("is-active");let l=c=>{c.preventDefault(),this.openMobileFiltersMenu(e)};e.onclick=l,e.onkeydown=c=>{(c.key==="Enter"||c.key===" ")&&l(c)}}openMobileFiltersMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-mobile-filters-popover").forEach(u=>u.remove());let s=e.body.createDiv({cls:"stashpad-mobile-filters-popover"}),i=t.getBoundingClientRect(),n=e.defaultView??window;s.style.right=`${Math.max(8,n.innerWidth-i.right)}px`,s.style.left="auto",s.style.top=`${i.bottom+4}px`,s.style.maxWidth="min(360px, calc(100vw - 16px))",s.style.width="max-content",s.style.minWidth="260px";let r=()=>{s.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(h)}catch{}},o=u=>{!s.contains(u.target)&&u.target!==t&&!t.contains(u.target)&&r()},a=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:u=>this.populateTagMenuBody(u,r)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:u=>this.populateColorMenuBody(u,this.collectFolderColors(),r)},{key:"time",title:"Time filter",summary:()=>{let u=es.find(d=>d.key===this.timeFilter);return u?this.timeFilterCalendar?u.calShort:u.rollShort:"All"},populate:u=>this.populateTimeMenuBody(u,r)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":pe[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:u=>{if(this.currentViewMode()!=="nested"){u.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(u,r)}},{key:"view",title:"View",summary:()=>ts[this.currentViewMode()],populate:u=>this.populateViewMenuBody(u,r)}],l="",c=()=>{s.empty();for(let u of a){let d=s.createDiv({cls:"stashpad-mobile-filters-section"}),p=d.createDiv({cls:"stashpad-mobile-filters-header"}),m=p.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,N.setIcon)(m,l===u.key?"chevron-down":"chevron-right"),p.createSpan({cls:"stashpad-mobile-filters-title",text:u.title}),p.createSpan({cls:"stashpad-mobile-filters-summary",text:u.summary()}),p.onclick=v=>{v.preventDefault(),v.stopPropagation(),l=l===u.key?"":u.key,c()},l===u.key){let v=d.createDiv({cls:"stashpad-mobile-filters-body"});u.populate(v)}}};c();let h=new N.Scope(this.app.scope);h.register([],"Escape",u=>(u.preventDefault(),r(),!1)),this.app.keymap?.pushScope(h),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}renderViewDropdown(t){let e=this.currentViewMode(),s=t.createDiv({cls:"stashpad-view-btn"});s.setAttribute("role","button"),s.setAttribute("tabindex","0");let i=s.createSpan({cls:"stashpad-view-icon"});(0,N.setIcon)(i,e==="flat"?"list":e==="everything"?"layout-grid":"list-tree"),s.createSpan({cls:"stashpad-view-label"}).setText(ts[e]),e!=="nested"&&s.addClass("is-active"),s.title=e==="nested"?"View: Nested (the default). Click to switch to Flat or Everything.":e==="flat"?"View: Flat \u2014 all descendants of the current focus, flat by sort order. Drag-reorder is disabled in this mode. Click to change.":"View: Everything \u2014 all descendants of the current focus PLUS non-Stashpad files in the folder, flat by created/ctime. Click to change.";let r=o=>{o.preventDefault(),this.openViewMenu(s)};s.onclick=r,s.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&r(o)}}openViewMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-view-popover").forEach(a=>a.remove());let s=e.body.createDiv({cls:"stashpad-view-popover"});N.Platform.isMobile&&s.addClass("is-mobile");let i=t.getBoundingClientRect();s.style.left=`${Math.max(8,i.left)}px`,s.style.top=`${i.bottom+4}px`,s.style.minWidth=`${i.width}px`,s.style.maxWidth="min(320px, calc(100vw - 16px))",s.style.width="max-content";let n=()=>{s.remove(),e.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(o)}catch{}},r=a=>{!s.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateViewMenuBody(s,n);let o=new N.Scope(this.app.scope);o.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(o),setTimeout(()=>{e.addEventListener("mousedown",r,!0)},0)}populateViewMenuBody(t,e){let s=this.currentViewMode(),i=(h,u)=>{let d=t.createDiv({cls:"stashpad-view-popover-row"});h===s&&d.addClass("is-active"),d.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:ts[h]}),d.createDiv({cls:"stashpad-view-popover-desc",text:u}),d.onclick=async m=>{m.preventDefault(),m.stopPropagation(),e(),h!==s&&(await this.setViewMode(h),this.render())}};i("nested","Tree of immediate children (default)."),i("flat","All descendants of the current focus, flat by sort."),i("everything","All descendants PLUS non-Stashpad files in the folder."),t.createDiv({cls:"stashpad-view-popover-divider"});let n=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),r=n.createEl("input",{type:"checkbox"});r.checked=this.currentHideChildless(),n.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide childless notes"}),n.createDiv({cls:"stashpad-view-popover-desc",text:s==="nested"?"Show only notes that have children. Applied at this level.":"Hide top-level notes without children; keep every parent's full subtree so no task is overlooked."}),n.onclick=async h=>{h.target!==r&&(h.preventDefault(),r.checked=!r.checked),await this.setHideChildless(r.checked),this.refreshList()};let o=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),a=o.createEl("input",{type:"checkbox"});a.checked=this.currentHideCompleted(),o.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide completed notes"}),o.createDiv({cls:"stashpad-view-popover-desc",text:"Hide notes marked complete. A completed parent stays visible while any descendant is still incomplete."}),o.onclick=async h=>{h.target!==a&&(h.preventDefault(),a.checked=!a.checked),await this.setHideCompleted(a.checked),this.refreshList()},t.createDiv({cls:"stashpad-view-popover-divider"});let l=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});s!=="everything"&&l.addClass("is-disabled");let c=l.createEl("input",{type:"checkbox"});c.checked=this.currentIncludeAttachments(),c.disabled=s!=="everything",l.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),l.createDiv({cls:"stashpad-view-popover-desc",text:s==="everything"?"Show attachments referenced by notes as their own rows in the file list. Off by default \u2014 they already appear inline on the notes that embed them.":"Only applies in Everything mode."}),l.onclick=async h=>{s==="everything"&&(h.target!==c&&(h.preventDefault(),c.checked=!c.checked),await this.setIncludeAttachments(c.checked),this.refreshList())}}setTagFilter(t){(this.tagFilter??null)!==(t??null)&&(this.tagFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(t,e){let s=this.noteFolder,i=this.focusId,n=this.sortStore.getMode(s,i);for(let r of us){let o=t.createDiv({cls:"stashpad-sort-popover-row"});r===n&&o.addClass("is-active"),o.createSpan({cls:"stashpad-sort-popover-label",text:pe[r]}),o.onclick=async a=>{a.preventDefault(),a.stopPropagation(),e(),r!==n&&(this.sortStore.setMode(s,i,r),await this.sortStore.save(s),this.tree.rebuild(s),this.render())}}}populateTimeMenuBody(t,e){let s=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),i=s.createEl("input",{type:"checkbox"});i.checked=this.timeFilterCalendar,s.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Calendar mode"}),s.createDiv({cls:"stashpad-view-popover-desc",text:"Use calendar boundaries (start of today/week/month/year). Off = rolling windows back from now."}),s.onclick=n=>{n.target!==i&&(n.preventDefault(),i.checked=!i.checked),this.timeFilterCalendar=i.checked,this.persistFocus(),this.refreshList()};for(let n of es){let r=t.createDiv({cls:"stashpad-sort-popover-row"});this.timeFilter===n.key&&r.addClass("is-active");let o=this.timeFilterCalendar?n.calLong:n.rollLong;r.createSpan({cls:"stashpad-sort-popover-label",text:o}),r.onclick=a=>{a.preventDefault(),a.stopPropagation(),e(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(t,e,s){let i=(n,r,o)=>{let a=t.createDiv({cls:"stashpad-color-filter-popover-row"}),l=a.createSpan({cls:"stashpad-color-filter-swatch"});r?l.style.background=r:l.addClass("is-empty");let c=a.createSpan({cls:"stashpad-color-filter-popover-label"});c.setText(n),r&&(c.style.color=r),a.onclick=h=>{h.preventDefault(),h.stopPropagation(),o(),s()}};i("All colors",null,()=>this.setColorFilter(null));for(let n of e){let r=this.plugin.getColorAlias(this.noteFolder,n.hex),o=r?`${r} (${n.count})`:`${n.hex} (${n.count})`;i(o,n.hex,()=>this.setColorFilter(n.hex))}}populateTagMenuBody(t,e){let s=this.collectFolderTags(),i=(n,r)=>{let o=t.createDiv({cls:"stashpad-color-filter-popover-row"});o.createSpan({cls:"stashpad-color-filter-swatch is-empty"}),o.createSpan({cls:"stashpad-color-filter-popover-label"}).setText(n),(this.tagFilter??"")===(r??"")&&o.addClass("is-active"),o.onclick=c=>{c.preventDefault(),c.stopPropagation(),this.setTagFilter(r),e()}};i(s.length===0?"No tags":"All tags",null);for(let n of s)i(`${n.label} (${n.count})`,n.raw)}setColorFilter(t){let e=t?t.toLowerCase():null;(this.colorFilter??null)!==e&&(this.colorFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}setTimeFilter(t){this.timeFilter!==t&&(this.timeFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}reconcileSelectionAfterFilter(){let t=this.filterChildren(this.collectViewItems(this.focusId)),e=new Set(t.map(s=>s.id));for(let s of[...this.selection])e.has(s)||this.selection.delete(s);if(this.firstSelectedId&&!e.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!e.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let s=t.findIndex(i=>this.selection.has(i.id));this.cursorIdx=s>=0?s:Math.min(this.cursorIdx,t.length-1)}else this.cursorIdx>=t.length&&(this.cursorIdx=t.length-1)}renderTinyHeader(t){let e=t.createDiv({cls:"stashpad-tiny-header"}),s=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});Yt(s,"arrow-left","\u2039"),s.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==R||s.addClass("is-disabled"),s.title=this.navBackStack.length>0?"Back":this.focusId!==R?"Back (up to parent)":"No back history",s.onclick=()=>this.navigateBack();let n=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});Yt(n,"arrow-right","\u203A"),n.title=this.navForwardSnapshots.length>0?"Forward":"No forward history",this.navForwardSnapshots.length===0&&n.addClass("is-disabled"),n.onclick=()=>this.navigateForward();let r=this.tree.get(this.focusId)??this.tree.getRoot(),o=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),a=this.focusId===R?o:`${o} / ${this.titleForNode(r).trim()}`,l=e.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),c=l.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,N.setIcon)(c,"folder"),l.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:a}),l.title=`${this.noteFolder}${this.focusId!==R?` / ${this.titleForNode(r).trim()}`:""} +Click to switch / create folder.`,l.onclick=m=>{m.preventDefault(),this.plugin.openFolderPicker()};let h=e.createDiv({cls:"stashpad-tiny-sticky"}),u=h.createEl("input",{type:"checkbox"});if(u.checked=this.tinyAlwaysOnTop,h.createSpan({text:"Sticky"}),u.onchange=()=>{this.tinyAlwaysOnTop=u.checked,this.applyTinyAlwaysOnTop()},!N.Platform.isMobile){let m=e.createEl("button",{cls:"stashpad-tiny-nav-btn stashpad-tiny-opacity-btn"});(0,N.setIcon)(m,"contrast"),m.title="Window transparency",this.tinyOpacity<1&&m.addClass("is-active"),m.onclick=v=>{v.stopPropagation(),this.toggleTinyOpacityPopover(m)}}let d=e.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,N.setIcon)(d,this.compactMode?"panel-top":"rows-2"),d.title=this.compactMode?"Compact mode is ON \u2014 click to turn off.":"Compact mode \u2014 click to turn on (strips row metadata).",this.compactMode&&d.addClass("is-active"),d.onclick=()=>{this.toggleCompactMode()};let p=e.createEl("button",{cls:"stashpad-tiny-expand"});(0,N.setIcon)(p,"maximize-2"),p.title="Exit tiny mode",p.onclick=()=>{this.exitTinyMode()}}toggleTinyOpacityPopover(t){if(this.tinyOpacityPopover){this.tinyOpacityPopover.remove(),this.tinyOpacityPopover=null;return}let e=document.createElement("div");e.className="stashpad-tiny-opacity-popover",e.createSpan({cls:"stashpad-tiny-opacity-label",text:"Transparency"});let s=e.createEl("input",{type:"range"});s.min="30",s.max="100",s.step="1",s.value=String(Math.round(this.tinyOpacity*100));let i=e.createSpan({cls:"stashpad-tiny-opacity-pct",text:`${s.value}%`});s.addEventListener("input",()=>{let c=Math.min(100,Math.max(30,parseInt(s.value,10)||100));this.tinyOpacity=c/100,i.setText(`${c}%`),this.applyTinyOpacity(),t.toggleClass("is-active",this.tinyOpacity<1)}),s.addEventListener("change",()=>{this.app.workspace.requestSaveLayout()}),this.viewRoot.appendChild(e);let n=t.getBoundingClientRect(),r=this.viewRoot.getBoundingClientRect();e.style.top=`${n.bottom-r.top+4}px`,e.style.left=`${Math.max(4,Math.min(n.left-r.left,r.width-180))}px`;let o=c=>{e.contains(c.target)||c.target===t||t.contains(c.target)||l()},a=c=>{c.key==="Escape"&&l()},l=()=>{e.remove(),this.tinyOpacityPopover=null,document.removeEventListener("mousedown",o,!0),document.removeEventListener("keydown",a,!0)};setTimeout(()=>{document.addEventListener("mousedown",o,!0),document.addEventListener("keydown",a,!0)},0),this.tinyOpacityPopover=e,s.focus()}getOwnElectronWindow(){try{let t=this.containerEl?.ownerDocument?.defaultView??window,i=((t?.require?.("electron")??window.require?.("electron"))?.remote??t?.electron?.remote??t?.["@electron/remote"])?.getCurrentWindow?.()??t?.electronWindow??null;if(!i)try{let n=window.require?.("electron"),r=n?.remote??n?.["@electron/remote"],a=(r?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];a.length===1?i=a[0]:a.length>1&&(i=r?.getFocusedWindow?.()??null??a[a.length-1])}catch(n){console.debug("[Stashpad] BrowserWindow.getAllWindows fallback failed",n)}return i||console.debug("[Stashpad] couldn't resolve own electron window"),i??null}catch(t){return console.debug("[Stashpad] resolve own electron window failed",t),null}}applyTinyAlwaysOnTop(){let t=this.getOwnElectronWindow();if(t)try{t.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop)}catch(e){console.debug("[Stashpad] setAlwaysOnTop failed",e)}}applyTinyOpacity(){let t=this.getOwnElectronWindow();if(!t)return;let e=Math.min(1,Math.max(.3,this.tinyOpacity));try{t.setOpacity?.(e)}catch(s){console.debug("[Stashpad] setOpacity failed",s)}}applyTinyWindow(){let t=this.getOwnElectronWindow();if(t)try{if(this.tinyMode){t.setMinimumSize?.(220,260);let i=100,n=100;try{let r=t.getBounds?.();r&&typeof r.x=="number"&&(i=r.x,n=r.y)}catch{}try{t.setBounds?.({x:i,y:n,width:280,height:360})}catch{}try{t.setSize?.(280,360)}catch{}t.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop);try{t.setOpacity?.(Math.min(1,Math.max(.3,this.tinyOpacity)))}catch{}}else t.setAlwaysOnTop?.(!1)}catch(e){console.debug("[Stashpad] tiny window apply failed",e)}}async exitTinyMode(){this.tinyMode=!1,this.tinyAlwaysOnTop=!1,this.tinyOpacity=1;try{this.getOwnElectronWindow()?.setOpacity?.(1)}catch{}this.compactMode=!1,this.applyTinyWindow();let t=this.getOwnElectronWindow();try{if(t?.setMinimumSize?.(400,300),N.Platform.isMacOS??!1){let s=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(s?.remote?.screen??s?.screen)?.getPrimaryDisplay?.().workArea;n?t?.setBounds?.({x:n.x,y:n.y,width:n.width,height:n.height}):t?.maximize?.()}else t?.maximize?.()}catch{}this.render();try{await this.app.workspace.requestSaveLayout?.()}catch{}}enterTinyMode(){this.tinyMode=!0,this.applyTinyWindow(),this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderBreadcrumb(t){let e=t.createDiv({cls:"stashpad-breadcrumb"});this.renderActionsCluster(e);let s=e.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(N.Platform.isMobile?((0,N.setIcon)(s,"home"),s.title="Home"):s.setText("Home"),s.onclick=()=>this.navigateTo(R),this.focusId===R){let c=this.tree.getChildren(this.focusId).length;if(c>0&&(e.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${c}`}).title=`${c} direct child${c===1?"":"ren"}`),this.compactMode){let h=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,N.setIcon)(h,"panel-top"),h.title="Exit compact mode",h.onclick=u=>{u.preventDefault(),this.toggleCompactMode()}}return}let i=28,n=100,r=this.tree.pathTo(this.focusId),o=r.map(c=>{let h=this.titleForNode(c),u=h.length>i?h.slice(0,i-1)+"\u2026":h;return{id:c.id,label:u}}),a=c=>c.reduce((h,u)=>h+u.label.length+3,0);if(a(o)>n&&o.length>2){let c=!1;for(;a(o)>n&&o.length>2;)o.splice(1,1),c||(o.splice(1,0,{id:"__ellipsis__",label:"\u2026",isEllipsis:!0}),c=!0)}for(let c of o)if(e.createSpan({cls:"stashpad-crumb-sep",text:" / "}),c.isEllipsis)e.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:c.label}).title=r.map(h=>this.titleForNode(h)).join(" / ");else{let h=c.id,u=e.createSpan({cls:"stashpad-crumb",text:c.label});u.title=c.label,u.onclick=()=>this.navigateTo(h),u.oncontextmenu=d=>{d.preventDefault(),this.openCrumbMenu(d,h)},N.Platform.isMobile&&this.attachLongPress(u,()=>this.openCrumbMenu(null,h))}if(e.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",c=>{c.preventDefault(),this.openCrumbMenu(c,R)}),N.Platform.isMobile){let c=e.querySelector(".stashpad-crumb-home");c&&this.attachLongPress(c,()=>this.openCrumbMenu(null,R))}let l=this.tree.getChildren(this.focusId).length;if(l>0&&(e.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${l}`}).title=`${l} direct child${l===1?"":"ren"}`),this.compactMode){let c=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,N.setIcon)(c,"panel-top"),c.title="Exit compact mode",c.onclick=h=>{h.preventDefault(),this.toggleCompactMode()}}}attachLongPress(t,e){let s=null,i=0,n=0,r=()=>{s!=null&&(window.clearTimeout(s),s=null)};t.addEventListener("touchstart",o=>{let a=o.touches[0];i=a?.clientX??0,n=a?.clientY??0,r(),s=window.setTimeout(()=>{s=null,e()},500)},{passive:!0}),t.addEventListener("touchmove",o=>{let a=o.touches[0];a&&(Math.abs(a.clientX-i)>10||Math.abs(a.clientY-n)>10)&&r()},{passive:!0}),t.addEventListener("touchend",r),t.addEventListener("touchcancel",r)}openCrumbMenu(t,e){let s=this.tree.get(e);if(!s)return;let i=new N.Menu;if(i.addItem(n=>n.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>this.navigateTo(e))),i.addItem(n=>n.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>this.cmdOpenInNewStashpadTab(s))),s.file&&i.addItem(n=>n.setTitle("Open in editor (new tab)").setIcon("pencil").onClick(()=>this.cmdOpenInEditor(s))),t&&(t.clientX>0||t.clientY>0))i.showAtMouseEvent(t);else{let r=(t?.target??null)?.getBoundingClientRect();i.showAtPosition({x:r?.left??8,y:(r?.bottom??60)+4})}}renderFocusedHeaderMini(t,e){if(!e.file)return;let s=e.file,i=t.createDiv({cls:"stashpad-focused-mini"});i.dataset.id=e.id,i.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(e).trim());let r=i.createEl("button",{cls:"stashpad-pencil stashpad-focused-mini-pencil"});(0,N.setIcon)(r,"pencil"),r.title="Edit in new tab",r.onclick=o=>{o.stopPropagation(),this.openFileAtEnd(s)}}installFocusedMiniObserver(t){let e=t.querySelector(".stashpad-focused"),s=t.querySelector(".stashpad-focused-mini");!e||!s||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(i=>{for(let n of i)s.toggleClass("is-visible",!n.isIntersecting)},{root:t,threshold:.05}),this.focusedMiniObserver.observe(e))}renderFocusedHeader(t,e){if(!e.file)return;let s=e.file,i=t.createDiv({cls:"stashpad-focused"}),r=i.createDiv({cls:"stashpad-focused-meta"}).createDiv({cls:"stashpad-focused-meta-top"});r.createSpan({cls:"stashpad-focused-time stashpad-note-time",text:this.formatTime(e.created)}),r.createDiv({cls:"stashpad-focused-grip-spacer"});let o=i.createDiv({cls:"stashpad-focused-body"});o.addEventListener("click",h=>this.handleRenderedClick(h,e));let a=i.createDiv({cls:"stashpad-focused-actions"}),l=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,N.setIcon)(l,"pencil"),l.title="Edit in new tab",l.onclick=()=>void this.openFileAtEnd(s);let c=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,N.setIcon)(c,"copy"),c.title="Open this Stashpad in a new tab (clone)",c.onclick=()=>this.cmdOpenInNewStashpadTab(e),this.renderNoteBody(o,e,{clamp:N.Platform.isMobile,toggleHost:a,toggleAnchor:l})}renderRowBreadcrumb(t,e){let s=this.tree.pathTo(e.id),i=s.findIndex(o=>o.id===this.focusId),n=s.slice(i+1,s.length-1);if(n.length===0)return;let r=t.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((o,a)=>{let l=r.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(o)});l.title=`Focus into "${this.titleForNode(o)}"`,l.onclick=c=>{c.stopPropagation(),this.navigateTo(o.id)},a<n.length-1&&r.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(t){return He(this.app,t,N.Platform.isMobile)}collectAuthorIds(t){let e=new Set,s=i=>{if(typeof i!="string")return null;let n=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let i of t){if(!i.file)continue;let n=this.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!n)continue;let r=s(n.author);if(r&&e.add(r),Array.isArray(n.contributors))for(let o of n.contributors){let a=s(o);a&&e.add(a)}}return Array.from(e)}bulkActionMessage(t){let e=t.nodes.map(o=>`"${this.titleForNode(o).trim()||"(untitled)"}"`),s=t.suffix?` ${t.suffix}`:"",i=t.destination?` ${t.destination}`:"";if(e.length===0)return`${t.verb}${s}${i}`;if(e.length===1)return`${t.verb} ${e[0]}${s}${i}`;let n=t.bulletMax??10,r=e.length<=n?e.map(o=>`\u2022 ${o}`).join(` `):e.slice(0,n).map(o=>`\u2022 ${o}`).join(` `)+` \u2026+ ${e.length-n} more`;return`${t.verb} ${e.length} notes${s}${i}: -${r}`}titleList(t,e=3){if(!t.length)return"";let s=t.map(n=>this.titleForNode(n).trim()||"(untitled)");return s.length<=e?s.map(n=>`"${n}"`).join(", "):`${s.slice(0,e).map(n=>`"${n}"`).join(", ")}, +${s.length-e} more`}titleForNode(t){if(!t.file)return"Untitled";let s=this.app.metadataCache.getFileCache(t.file)?.headings?.[0]?.heading;return s||t.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}computeSortedIds(t,e){return this.tree.getChildren(t).slice().sort((i,n)=>this.compareForSort(i,n,e)).map(i=>i.id)}compareForSort(t,e,s){switch(s){case"created-asc":return(t.created||"").localeCompare(e.created||"");case"created-desc":return(e.created||"").localeCompare(t.created||"");case"modified-asc":case"modified-desc":{let i=this.modifiedFor(t)||t.created||"",n=this.modifiedFor(e)||e.created||"";return s==="modified-asc"?i.localeCompare(n):n.localeCompare(i)}case"title-az":case"title-za":{let i=this.titleForNode(t),n=this.titleForNode(e),r={numeric:!0,sensitivity:"base"};return s==="title-az"?i.localeCompare(n,void 0,r):n.localeCompare(i,void 0,r)}default:return 0}}modifiedFor(t){if(!t.file)return"";let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return(typeof e?.modified=="string"?e.modified:"")||""}async forceManualMode(t){let e=this.noteFolder;this.sortStore.getMode(e,t)!=="manual"&&(this.sortStore.setMode(e,t,"manual"),await this.sortStore.save(e))}renderNote(t,e,s){if(!e.file)return;let i=e.file,n=this.tree.getChildren(e.id).length,r=this.selection.has(e.id),o=s===this.cursorIdx,a=this.inListPicker?.activeIdx===s,l=t.createDiv({cls:"stashpad-note"});r&&l.addClass("is-selected"),o&&l.addClass("is-cursor"),o&&this.plugin.settings.autoExpandCursorRow&&l.addClass("is-cursor-expanded"),a&&l.addClass("is-pick-target"),this.isCompleted(e)&&l.addClass("is-completed"),l.dataset.idx=String(s),l.dataset.id=e.id;let c=this.currentViewMode()==="nested";if(l.draggable=c,c&&this.attachRowDnD(l,e,s),l.addEventListener("click",x=>this.handleRowClick(x,s,e)),l.addEventListener("dblclick",x=>{!this.plugin.settings.doubleClickToFocus||x.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(x.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(e.id))}),this.isTask(e)){l.addClass("is-task");let x=l.createSpan({cls:"stashpad-note-task-checkbox"}),I=this.isCompleted(e);(0,O.setIcon)(x,I?"check-square":"square"),x.title=I?"Mark not done":"Mark done",x.addEventListener("mousedown",E=>E.stopPropagation()),x.addEventListener("dblclick",E=>{E.preventDefault(),E.stopPropagation()}),x.onclick=E=>{E.preventDefault(),E.stopPropagation(),this.toggleCompletedForNode(e)}}let d=l.createDiv({cls:"stashpad-note-meta"}),p=d.createDiv({cls:"stashpad-note-meta-top"});p.createSpan({cls:"stashpad-note-time",text:this.formatTime(e.created)});let h=this.colorForNode(e),u=p.createDiv({cls:"stashpad-note-grip"});if(h&&u.addClass("has-color"),(0,O.setIcon)(u,"grip-vertical"),u.title=h?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",u.draggable=c,c||(u.title=h?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),h&&u.style.setProperty("--stashpad-note-color",h),n>0){let x=d.createSpan({cls:"stashpad-note-enter"});h&&(x.style.color=h),(0,O.setIcon)(x.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),x.createSpan({text:` ${n}`}),x.onclick=I=>{I.stopPropagation(),this.navigateTo(e.id)}}if(h)l.addClass("has-color"),l.style.setProperty("--stashpad-note-color",h);else{let x=this.inheritedColorForNode(e);x&&x.depth>0&&(l.addClass("has-inherited-color"),l.style.setProperty("--stashpad-inherited-color",x.hex),l.style.setProperty("--stashpad-inherited-depth",String(x.depth)))}let m=l.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(m,e);let g=m.createDiv({cls:"stashpad-note-body-content"}),y=l.createDiv({cls:"stashpad-note-actions"}),S=y.createEl("button",{cls:"stashpad-pencil"});(0,O.setIcon)(S,"pencil"),S.title="Edit in new tab",S.onclick=x=>{x.stopPropagation(),this.openFileAtEnd(i)};let k=y.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,O.setIcon)(k,"arrow-right"),k.title="Open in Stashpad view",k.onclick=x=>{x.stopPropagation(),this.navigateTo(e.id)},this.renderNoteBody(g,e,{clamp:!0,toggleHost:y,toggleAnchor:S}),l.oncontextmenu=x=>{x.preventDefault(),this.openNoteMenu(x,e)}}async getOrComputeRender(t){let e=this.renderCache.get(t.path);if(e&&e.mtime===t.stat.mtime)return e;let s=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(s),{text:n,attachments:r}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await O.MarkdownRenderer.render(this.app,n,o,t.path,this);let a=o.innerHTML,l={mtime:t.stat.mtime,text:n,attachments:r,html:a};return this.renderCache.set(t.path,l),l}renderNoteBody(t,e,s={clamp:!0}){if(!e.file)return;let i=e.file,n=(t.__stashpadRenderToken??0)+1;t.__stashpadRenderToken=n,this.getOrComputeRender(i).then(r=>{if(t.__stashpadRenderToken!==n)return;let{text:o,attachments:a,html:l}=r;t.empty();let c=t.createDiv({cls:"stashpad-note-text"}),d=this.expandedNotes.has(e.id);if(s.clamp&&!d&&c.addClass("is-clamped"),this.compactMode||this.tinyMode?(c.addClass("is-plain"),c.textContent=o):c.innerHTML=l,a.length>0&&this.renderAttachmentRail(t,a),this.renderAuthorshipFooter(t,e),!s.clamp)return;let p=this.lastListWidth;if(r.ovW===p&&r.ovV!==void 0&&!d){r.ovV?this.attachExpandToggle(s,t,e,d):c.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(t.closest?.(".stashpad-note.is-cursor-expanded"))return;let h=c.scrollHeight>c.clientHeight+4;if(r.ovW=p,r.ovV=h,!h&&!d){c.removeClass("is-clamped");return}this.attachExpandToggle(s,t,e,d)})})}attachExpandToggle(t,e,s,i){let n=!!t.toggleHost,r=t.toggleHost??e;r.querySelector(".stashpad-expand-toggle")?.remove();let o=r.createEl("button",{cls:"stashpad-expand-toggle"});o.title=i?"Show less":"Show more",n||O.Platform.isMobile?((0,O.setIcon)(o,i?"chevron-up":"chevron-down"),o.addClass("is-icon"),n&&o.addClass("is-inline")):o.setText(i?"Show less":"Show more"),t.toggleAnchor&&t.toggleAnchor.parentElement===r&&r.insertBefore(o,t.toggleAnchor),o.onclick=a=>{a.stopPropagation(),this.expandedNotes.has(s.id)?this.expandedNotes.delete(s.id):this.expandedNotes.add(s.id),e.empty(),this.renderNoteBody(e,s,t)}}splitAttachments(t){let e=[];return{text:t.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,n)=>(e.push(n),"")).replace(/\n{3,}/g,` +${r}`}titleList(t,e=3){if(!t.length)return"";let s=t.map(n=>this.titleForNode(n).trim()||"(untitled)");return s.length<=e?s.map(n=>`"${n}"`).join(", "):`${s.slice(0,e).map(n=>`"${n}"`).join(", ")}, +${s.length-e} more`}titleForNode(t){if(!t.file)return"Untitled";let s=this.app.metadataCache.getFileCache(t.file)?.headings?.[0]?.heading;return s||t.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}computeSortedIds(t,e){return this.tree.getChildren(t).slice().sort((i,n)=>this.compareForSort(i,n,e)).map(i=>i.id)}compareForSort(t,e,s){switch(s){case"created-asc":return(t.created||"").localeCompare(e.created||"");case"created-desc":return(e.created||"").localeCompare(t.created||"");case"modified-asc":case"modified-desc":{let i=this.modifiedFor(t)||t.created||"",n=this.modifiedFor(e)||e.created||"";return s==="modified-asc"?i.localeCompare(n):n.localeCompare(i)}case"title-az":case"title-za":{let i=this.titleForNode(t),n=this.titleForNode(e),r={numeric:!0,sensitivity:"base"};return s==="title-az"?i.localeCompare(n,void 0,r):n.localeCompare(i,void 0,r)}default:return 0}}modifiedFor(t){if(!t.file)return"";let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return(typeof e?.modified=="string"?e.modified:"")||""}async forceManualMode(t){let e=this.noteFolder;this.sortStore.getMode(e,t)!=="manual"&&(this.sortStore.setMode(e,t,"manual"),await this.sortStore.save(e))}renderNote(t,e,s){if(!e.file)return;let i=e.file,n=this.tree.getChildren(e.id).length,r=this.selection.has(e.id),o=s===this.cursorIdx,a=this.inListPicker?.activeIdx===s,l=t.createDiv({cls:"stashpad-note"});r&&l.addClass("is-selected"),o&&l.addClass("is-cursor"),o&&this.plugin.settings.autoExpandCursorRow&&l.addClass("is-cursor-expanded"),a&&l.addClass("is-pick-target"),this.isCompleted(e)&&l.addClass("is-completed"),l.dataset.idx=String(s),l.dataset.id=e.id;let c=this.currentViewMode()==="nested";if(l.draggable=c,c&&this.attachRowDnD(l,e,s),l.addEventListener("click",C=>this.handleRowClick(C,s,e)),l.addEventListener("dblclick",C=>{!this.plugin.settings.doubleClickToFocus||C.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(C.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(e.id))}),this.isTask(e)){l.addClass("is-task");let C=l.createSpan({cls:"stashpad-note-task-checkbox"}),E=this.isCompleted(e);(0,N.setIcon)(C,E?"check-square":"square"),C.title=E?"Mark not done":"Mark done",C.addEventListener("mousedown",I=>I.stopPropagation()),C.addEventListener("dblclick",I=>{I.preventDefault(),I.stopPropagation()}),C.onclick=I=>{I.preventDefault(),I.stopPropagation(),this.toggleCompletedForNode(e)}}let h=l.createDiv({cls:"stashpad-note-meta"}),u=h.createDiv({cls:"stashpad-note-meta-top"});u.createSpan({cls:"stashpad-note-time",text:this.formatTime(e.created)});let d=this.colorForNode(e),p=u.createDiv({cls:"stashpad-note-grip"});if(d&&p.addClass("has-color"),(0,N.setIcon)(p,"grip-vertical"),p.title=d?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",p.draggable=c,c||(p.title=d?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),d&&p.style.setProperty("--stashpad-note-color",d),n>0){let C=h.createSpan({cls:"stashpad-note-enter"});d&&(C.style.color=d),(0,N.setIcon)(C.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),C.createSpan({text:` ${n}`}),C.onclick=E=>{E.stopPropagation(),this.navigateTo(e.id)}}if(d)l.addClass("has-color"),l.style.setProperty("--stashpad-note-color",d);else{let C=this.inheritedColorForNode(e);C&&C.depth>0&&(l.addClass("has-inherited-color"),l.style.setProperty("--stashpad-inherited-color",C.hex),l.style.setProperty("--stashpad-inherited-depth",String(C.depth)))}let m=l.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(m,e);let v=m.createDiv({cls:"stashpad-note-body-content"}),y=l.createDiv({cls:"stashpad-note-actions"}),b=y.createEl("button",{cls:"stashpad-pencil"});(0,N.setIcon)(b,"pencil"),b.title="Edit in new tab",b.onclick=C=>{C.stopPropagation(),this.openFileAtEnd(i)};let k=y.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,N.setIcon)(k,"arrow-right"),k.title="Open in Stashpad view",k.onclick=C=>{C.stopPropagation(),this.navigateTo(e.id)},this.renderNoteBody(v,e,{clamp:!0,toggleHost:y,toggleAnchor:b}),l.oncontextmenu=C=>{C.preventDefault(),this.openNoteMenu(C,e)}}async getOrComputeRender(t){let e=this.renderCache.get(t.path);if(e&&e.mtime===t.stat.mtime)return e;let s=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(s),{text:n,attachments:r}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await N.MarkdownRenderer.render(this.app,n,o,t.path,this);let a=o.innerHTML,l={mtime:t.stat.mtime,text:n,attachments:r,html:a};return this.renderCache.set(t.path,l),l}renderNoteBody(t,e,s={clamp:!0}){if(!e.file)return;let i=e.file,n=(t.__stashpadRenderToken??0)+1;t.__stashpadRenderToken=n,this.getOrComputeRender(i).then(r=>{if(t.__stashpadRenderToken!==n)return;let{text:o,attachments:a,html:l}=r;t.empty();let c=t.createDiv({cls:"stashpad-note-text"}),h=this.expandedNotes.has(e.id);if(s.clamp&&!h&&c.addClass("is-clamped"),this.compactMode||this.tinyMode?(c.addClass("is-plain"),c.textContent=o):c.innerHTML=l,a.length>0&&this.renderAttachmentRail(t,a),this.renderAuthorshipFooter(t,e),!s.clamp)return;let u=this.lastListWidth;if(r.ovW===u&&r.ovV!==void 0&&!h){r.ovV?this.attachExpandToggle(s,t,e,h):c.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(t.closest?.(".stashpad-note.is-cursor-expanded"))return;let d=c.scrollHeight>c.clientHeight+4;if(r.ovW=u,r.ovV=d,!d&&!h){c.removeClass("is-clamped");return}this.attachExpandToggle(s,t,e,h)})})}attachExpandToggle(t,e,s,i){let n=!!t.toggleHost,r=t.toggleHost??e;r.querySelector(".stashpad-expand-toggle")?.remove();let o=r.createEl("button",{cls:"stashpad-expand-toggle"});o.title=i?"Show less":"Show more",n||N.Platform.isMobile?((0,N.setIcon)(o,i?"chevron-up":"chevron-down"),o.addClass("is-icon"),n&&o.addClass("is-inline")):o.setText(i?"Show less":"Show more"),t.toggleAnchor&&t.toggleAnchor.parentElement===r&&r.insertBefore(o,t.toggleAnchor),o.onclick=a=>{a.stopPropagation(),this.expandedNotes.has(s.id)?this.expandedNotes.delete(s.id):this.expandedNotes.add(s.id),e.empty(),this.renderNoteBody(e,s,t)}}splitAttachments(t){let e=[];return{text:t.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,n)=>(e.push(n),"")).replace(/\n{3,}/g,` -`).trim(),attachments:e}}renderAttachmentRail(t,e){let s=t.createDiv({cls:"stashpad-rail"});for(let i of e){let n=this.app.metadataCache.getFirstLinkpathDest(i,""),r=(i.split(".").pop()??"").toLowerCase(),o=s.createDiv({cls:"stashpad-att"});if(o.title=i,n&&Ii.has(r)){let a=o.createEl("img",{cls:"stashpad-att-img"});a.src=this.app.vault.getResourcePath(n),a.alt=i}else{o.createDiv({cls:"stashpad-att-ext",text:r.toUpperCase()||"?"});let a=(i.split("/").pop()??i).replace(/\.[^.]+$/,"");o.createDiv({cls:"stashpad-att-name",text:a})}o.onclick=a=>{a.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)}}}renderComposer(t){let e=kt(),s=this.modeEnterSubmits,i=this.modeSplit??e.splitOnLines,n=null,r=t.createDiv({cls:"stashpad-composer"}),o=r.createDiv({cls:"stashpad-composer-input-wrap"}),a=o.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(s,i)}});a.value=this.composerDraft;let l=null,c=()=>{l&&(l.remove(),l=null)};n!==null&&n.length>0&&(l=o.createEl("button",{cls:"stashpad-composer-clear"}),(0,O.setIcon)(l,"x"),l.title="Clear restored draft",l.onmousedown=W=>W.preventDefault(),l.onclick=W=>{W.preventDefault(),a.value="",this.composerDraft="",this.saveDraft(""),c(),a.focus()},requestAnimationFrame(()=>{a.focus(),a.setSelectionRange(0,a.value.length)})),this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,O.debounce)(W=>{this.saveDraft(W)},250)),a.addEventListener("input",()=>{this.composerDraft=a.value,this.debouncedSaveDraft(a.value),c()}),a.addEventListener("blur",()=>{this.saveDraft(a.value)});let d=null,p=()=>{d||(d=new O.Scope(this.app.scope),d.register([],"Escape",()=>(a.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),d.register(["Mod"],"z",()=>!0),d.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(d))},h=()=>{if(d){try{this.app.keymap?.popScope(d)}catch{}d=null}};a.addEventListener("focus",p),a.addEventListener("blur",h),document.activeElement===a&&p(),O.Platform.isMobile&&(a.addEventListener("focus",()=>document.body.classList.add("stashpad-keyboard-open")),a.addEventListener("blur",()=>document.body.classList.remove("stashpad-keyboard-open"))),this.composerInputEl=a,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Jt(this.app,a),this.composerAutocomplete.attach();let u=async W=>{let z="";for(let Q of W){let N=await this.importAttachment(Q);if(!N)continue;let M=a.value+z,J=M&&!M.endsWith(` +`).trim(),attachments:e}}renderAttachmentRail(t,e){let s=t.createDiv({cls:"stashpad-rail"});for(let i of e){let n=this.app.metadataCache.getFirstLinkpathDest(i,""),r=(i.split(".").pop()??"").toLowerCase(),o=s.createDiv({cls:"stashpad-att"});if(o.title=i,n&&Ni.has(r)){let a=o.createEl("img",{cls:"stashpad-att-img"});a.src=this.app.vault.getResourcePath(n),a.alt=i}else{o.createDiv({cls:"stashpad-att-ext",text:r.toUpperCase()||"?"});let a=(i.split("/").pop()??i).replace(/\.[^.]+$/,"");o.createDiv({cls:"stashpad-att-name",text:a})}o.onclick=a=>{a.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)}}}renderComposer(t){let e=wt(),s=this.modeEnterSubmits,i=this.modeSplit??e.splitOnLines,n=null,r=t.createDiv({cls:"stashpad-composer"}),o=r.createDiv({cls:"stashpad-composer-input-wrap"}),a=o.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(s,i)}});a.value=this.composerDraft;let l=null,c=()=>{l&&(l.remove(),l=null)};n!==null&&n.length>0&&(l=o.createEl("button",{cls:"stashpad-composer-clear"}),(0,N.setIcon)(l,"x"),l.title="Clear restored draft",l.onmousedown=z=>z.preventDefault(),l.onclick=z=>{z.preventDefault(),a.value="",this.composerDraft="",this.saveDraft(""),c(),a.focus()},requestAnimationFrame(()=>{a.focus(),a.setSelectionRange(0,a.value.length)})),this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,N.debounce)(z=>{this.saveDraft(z)},250)),a.addEventListener("input",()=>{this.composerDraft=a.value,this.debouncedSaveDraft(a.value),c()}),a.addEventListener("blur",()=>{this.saveDraft(a.value)});let h=null,u=()=>{h||(h=new N.Scope(this.app.scope),h.register([],"Escape",()=>(a.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),h.register(["Mod"],"z",()=>!0),h.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(h))},d=()=>{if(h){try{this.app.keymap?.popScope(h)}catch{}h=null}};if(a.addEventListener("focus",u),a.addEventListener("blur",d),document.activeElement===a&&u(),N.Platform.isMobile){let z=()=>{this.keyboardTransitionUntil=Date.now()+600};a.addEventListener("focus",()=>{document.body.classList.add("stashpad-keyboard-open"),z()}),a.addEventListener("blur",()=>{document.body.classList.remove("stashpad-keyboard-open"),z()})}this.composerInputEl=a,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Jt(this.app,a),this.composerAutocomplete.attach();let p=async z=>{let W="";for(let X of z){let L=await this.importAttachment(X);if(!L)continue;let P=a.value+W,J=P&&!P.endsWith(` `)?` -`:"";z+=`${J}${N} -`}z&&(a.value=a.value+z,this.composerDraft=a.value,this.saveDraft(a.value),a.focus(),a.setSelectionRange(a.value.length,a.value.length))};a.addEventListener("dragover",W=>{if(!(!W.dataTransfer||!Array.from(W.dataTransfer.types).includes("Files"))){W.preventDefault(),W.stopPropagation();try{W.dataTransfer.dropEffect="copy"}catch{}}}),a.addEventListener("drop",W=>{let z=Array.from(W.dataTransfer?.files??[]);z.length!==0&&(W.preventDefault(),W.stopPropagation(),u(z))}),a.addEventListener("paste",W=>{let z=[],Q=W.clipboardData;if(Q){for(let N of Array.from(Q.files??[]))z.push(N);if(z.length===0){for(let N of Array.from(Q.items??[]))if(N.kind==="file"){let M=N.getAsFile();M&&z.push(M)}}z.length!==0&&(W.preventDefault(),W.stopPropagation(),u(z))}});let m=r.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});m.style.display="none";let g=r.createDiv({cls:"stashpad-composer-btn-rail"}),y=g.createDiv({cls:"stashpad-composer-btn-group"}),S=y.createEl("button",{cls:"stashpad-composer-btn"});(0,O.setIcon)(S,"list-end"),S.title=i?"Split on newlines: ON (Mod+/)":"Split on newlines (Mod+/)",i&&S.addClass("is-active"),S.onmousedown=W=>W.preventDefault(),S.onclick=W=>{W.preventDefault(),this.toggleSplit()};let k=y.createEl("button",{cls:"stashpad-composer-btn"});(0,O.setIcon)(k,"map-pin"),this.nextDestination&&k.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),k.title="Set destination (Mod+D)",this.nextDestination&&k.addClass("is-active"),k.onmousedown=W=>W.preventDefault(),k.onclick=W=>{W.preventDefault();let z=document.activeElement===a;if(this.openDestinationPicker(),z){let Q=()=>{a.focus()};setTimeout(Q,50),setTimeout(Q,250)}};let x=y.createEl("button",{cls:"stashpad-composer-btn"});(0,O.setIcon)(x,s?"corner-down-left":"arrow-big-down-dash"),x.title=s?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",x.onmousedown=W=>W.preventDefault(),x.onclick=W=>{W.preventDefault(),this.modeEnterSubmits=!s,this.render(),this.composerInputEl?.focus()};let I=W=>{let z=a.value&&!a.value.endsWith(` +`:"";W+=`${J}${L} +`}W&&(a.value=a.value+W,this.composerDraft=a.value,this.saveDraft(a.value),a.focus(),a.setSelectionRange(a.value.length,a.value.length))};a.addEventListener("dragover",z=>{if(!(!z.dataTransfer||!Array.from(z.dataTransfer.types).includes("Files"))){z.preventDefault(),z.stopPropagation();try{z.dataTransfer.dropEffect="copy"}catch{}}}),a.addEventListener("drop",z=>{let W=Array.from(z.dataTransfer?.files??[]);W.length!==0&&(z.preventDefault(),z.stopPropagation(),p(W))}),a.addEventListener("paste",z=>{let W=[],X=z.clipboardData;if(X){for(let L of Array.from(X.files??[]))W.push(L);if(W.length===0){for(let L of Array.from(X.items??[]))if(L.kind==="file"){let P=L.getAsFile();P&&W.push(P)}}W.length!==0&&(z.preventDefault(),z.stopPropagation(),p(W))}});let m=r.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});m.style.display="none";let v=r.createDiv({cls:"stashpad-composer-btn-rail"}),y=v.createDiv({cls:"stashpad-composer-btn-group"}),b=y.createEl("button",{cls:"stashpad-composer-btn"});(0,N.setIcon)(b,"list-end"),b.title=i?"Split on newlines: ON (Mod+/)":"Split on newlines (Mod+/)",i&&b.addClass("is-active"),b.onmousedown=z=>z.preventDefault(),b.onclick=z=>{z.preventDefault(),this.toggleSplit()};let k=y.createEl("button",{cls:"stashpad-composer-btn"});(0,N.setIcon)(k,"map-pin"),this.nextDestination&&k.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),k.title="Set destination (Mod+D)",this.nextDestination&&k.addClass("is-active"),k.onmousedown=z=>z.preventDefault(),k.onclick=z=>{z.preventDefault();let W=document.activeElement===a;if(this.openDestinationPicker(),W){let X=()=>{a.focus()};setTimeout(X,50),setTimeout(X,250)}};let C=y.createEl("button",{cls:"stashpad-composer-btn"});(0,N.setIcon)(C,s?"corner-down-left":"arrow-big-down-dash"),C.title=s?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",C.onmousedown=z=>z.preventDefault(),C.onclick=z=>{z.preventDefault(),this.modeEnterSubmits=!s,this.render(),this.composerInputEl?.focus()};let E=z=>{let W=a.value&&!a.value.endsWith(` `)?` -`:"";a.value+=`${z}${W} -`,this.composerDraft=a.value},E=y.createEl("button",{cls:"stashpad-composer-btn"});(0,O.setIcon)(E,"paperclip"),E.title="Attach files",E.onmousedown=W=>W.preventDefault(),E.onclick=W=>{W.preventDefault();let z=document.activeElement===a;if(m.click(),z){let Q=()=>{a.focus()};setTimeout(Q,100),setTimeout(Q,500)}},m.addEventListener("change",async()=>{let W=Array.from(m.files??[]);m.value="";for(let z of W){let Q=await this.importAttachment(z);Q&&I(Q)}a.focus()});let D=g.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,O.setIcon)(D,"chevron-left"),D.title="Show more composer options",g.insertBefore(D,y);let $=W=>{g.toggleClass("is-expanded",W),D.title=W?"Hide options":"Show more composer options",(0,O.setIcon)(D,W?"chevron-right":"chevron-left")};D.onmousedown=W=>W.preventDefault(),D.onclick=W=>{W.preventDefault(),$(!g.hasClass("is-expanded"))},$(!1);let F=()=>r.clientWidth<700,P=()=>{let W=F();r.toggleClass("is-narrow",W),$(!W)};P(),requestAnimationFrame(P);let b=new ResizeObserver(P);b.observe(r),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=b;let H=g.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});H.title="Send (Enter)",(0,O.setIcon)(H,"arrow-up");let et=async()=>{let W=a.value.trim();if(!W)return;a.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(W)}catch{}let z=this.modeSplit??kt().splitOnLines,Q=this.nextDestination,N=this.nextDestinationFolder,M=!!N&&N!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!M,this.scrollToBottomOnNextRender=!M;let J=M?{targetFolder:N}:void 0;if(z)for(let q of W.split(/\r?\n/)){let Y=q.trim();Y&&await this.createNoteUnder(Y,Q,J)}else await this.createNoteUnder(W,Q,J);kt().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,M&&this.composerInputEl?.focus())};H.onclick=()=>void et(),a.addEventListener("keydown",W=>{let z=this.modeEnterSubmits;if(W.key==="Escape"){W.preventDefault(),W.stopPropagation(),a.blur(),this.viewRoot.focus({preventScroll:!0});return}if(W.key==="ArrowUp"&&a.selectionStart===0&&a.selectionEnd===0){W.preventDefault(),a.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0&&(this.cursorIdx=this.currentChildren.length-1,this.selectCursor(!1));return}W.key==="Enter"&&!W.isComposing&&(z?!W.shiftKey:W.shiftKey)&&(W.preventDefault(),W.stopPropagation(),W.stopImmediatePropagation(),et())}),t.createDiv({cls:"stashpad-composer-help"}).setText(this.composerHelperText(s,i))}composerPlaceholder(t,e){return O.Platform.isMobile?e?"New notes (split on newlines)":"New note":`Type a note. ${t?"Enter":"Shift+Enter"} = send, ${t?"Shift+Enter":"Enter"} = newline${e?" (each line \u2192 a note)":""}\u2026`}composerHelperText(t,e){let s=t?"Enter":"Shift+Enter",i=t?"Shift+Enter":"Enter",n=kt().bindings,r=d=>{let p=n[d];return p.primary&&p.secondary?p.preferRight?p.secondary:p.primary:p.primary||p.secondary},o=Ts(r("toggleSplit")),a=Ts(r("pickDestination")),l=Ts(r("search")),c=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${s} sends \xB7 ${i} newline \xB7 ${o} split: ${e?"ON":"off"} \xB7 ${a} destination \xB7 ${l} search${c}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===B)return"Home";let t=this.tree.get(this.nextDestination);return t?this.titleForNode(t).trim():"?"}renderMobileNav(t){let e=t.createDiv({cls:"stashpad-mobile-nav"});e.createEl("button",{text:"Home"}).onclick=()=>this.navigateTo(B),e.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),e.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(t,e){let s=t.target,i=s?.closest?.(".tag");if(i){t.preventDefault(),t.stopPropagation();let o=(i.getAttribute("href")||i.textContent||"").replace(/^#/,"").trim();if(o){let a=this.app.internalPlugins?.plugins?.["global-search"],l=a?.instance?.openGlobalSearch?.bind(a.instance);l&&l(`tag:#${o}`)}return}let n=s?.closest?.(".internal-link");if(n){t.preventDefault(),t.stopPropagation();let r=n.getAttribute("data-href")||n.getAttribute("href");if(r){let o=e.file?.path||"";this.app.workspace.openLinkText(r,o,!0)}}}handleRowClick(t,e,s){let i=t.target,n=i?.closest?.(".tag");if(n){t.preventDefault(),t.stopPropagation();let l=(n.getAttribute("href")||n.textContent||"").replace(/^#/,"").trim();if(l){let c=this.app.internalPlugins?.plugins?.["global-search"],d=c?.instance?.openGlobalSearch?.bind(c.instance);d&&d(`tag:#${l}`)}return}let r=i?.closest?.(".internal-link");if(r){t.preventDefault(),t.stopPropagation();let a=r.getAttribute("data-href")||r.getAttribute("href");if(a){let l=s.file?.path||"";this.app.workspace.openLinkText(a,l,!0)}return}if(i?.tagName==="A"&&i.href)return;if(t.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=e,this.commitInListPicker();return}let o=this.selection.size===0;if(t.shiftKey&&this.lastSelected){this.cursorIdx=e;let a=this.currentChildren.findIndex(l=>l.id===this.lastSelected);if(o&&(this.firstSelectedId=this.lastSelected),a!==-1){let[l,c]=a<e?[a,e]:[e,a];for(let d=l;d<=c;d++)this.selection.add(this.currentChildren[d].id)}else this.selection.add(s.id)}else if(t.metaKey||t.ctrlKey)if(this.selection.has(s.id))if(this.selection.delete(s.id),this.firstSelectedId===s.id&&(this.firstSelectedId=null),this.lastSelected===s.id&&(this.lastSelected=this.selection.size>0?[...this.selection][this.selection.size-1]:null),this.selection.size===0)this.cursorIdx=-1;else{let a=this.lastSelected??[...this.selection][this.selection.size-1],l=a?this.currentChildren.findIndex(c=>c.id===a):-1;l>=0&&(this.cursorIdx=l)}else this.cursorIdx=e,o&&(this.firstSelectedId=s.id),this.selection.add(s.id);else this.mobileSelectMode?(this.cursorIdx=e,this.selection.has(s.id)?(this.selection.delete(s.id),this.firstSelectedId===s.id&&(this.firstSelectedId=null)):this.selection.add(s.id)):(this.cursorIdx=e,this.selection.clear(),this.selection.add(s.id),this.firstSelectedId=s.id,this.lastSelected=s.id);this.selection.size===0&&(this.firstSelectedId=null),this.selection.has(s.id)&&(this.lastSelected=s.id),this.viewRoot.focus({preventScroll:!0}),this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}revealCursorRow(){let t=()=>{let e=this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`);if(!e||!this.listEl)return;let s=this.listEl,i=s.getBoundingClientRect(),n=e.getBoundingClientRect(),r=4;n.top<i.top+r?s.scrollTop+=n.top-i.top-r:n.bottom>i.bottom-r&&(s.scrollTop+=n.bottom-i.bottom+r)};t(),requestAnimationFrame(t),setTimeout(t,60),setTimeout(t,200)}selectCursor(t){let e=this.currentChildren[this.cursorIdx];if(e){if(!t)this.selection.clear(),this.selection.add(e.id),this.firstSelectedId=e.id,this.lastSelected=e.id;else{let s=this.firstSelectedId??e.id,i=this.currentChildren.findIndex(n=>n.id===s);if(i===-1)this.selection.add(e.id),this.firstSelectedId=e.id;else{let[n,r]=i<this.cursorIdx?[i,this.cursorIdx]:[this.cursorIdx,i];this.selection.clear();for(let o=n;o<=r;o++)this.selection.add(this.currentChildren[o].id);this.firstSelectedId=s}this.lastSelected=e.id}this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}}repaintSelectionClasses(){if(!this.listEl)return;let t=!!this.plugin.settings.autoExpandCursorRow,e=this.inListPicker?.activeIdx??-1;this.listEl.querySelectorAll(".stashpad-note").forEach(i=>{let n=Number(i.dataset.idx),r=i.dataset.id??"",o=n===this.cursorIdx;i.classList.toggle("is-cursor",o),i.classList.toggle("is-selected",this.selection.has(r)),i.classList.toggle("is-cursor-expanded",t&&o),i.classList.toggle("is-pick-target",n===e)})}revealRowAt(t){if(!this.listEl)return;let e=this.listEl.querySelector(`.stashpad-note[data-idx="${t}"]`);if(!e)return;let s=e.getBoundingClientRect(),i=this.listEl.getBoundingClientRect();(s.top<i.top||s.bottom>i.bottom)&&e.scrollIntoView({block:"nearest",behavior:"auto"})}getActionTargets(){if(this.selection.size>0)return[...this.selection].map(e=>this.tree.get(e)).filter(e=>!!e&&!!e.file);let t=this.currentChildren[this.cursorIdx];return t?[t]:[]}toggleSplit(){let t=this.modeSplit??kt().splitOnLines;this.modeSplit=!t,this.render(),this.composerInputEl?.focus()}openDestinationPicker(){new Lt(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Send next note(s) under which note?",allowCreate:!0,onPick:async t=>{if(t.crossFolder){let e=t.id.replace(/^cross:/,"");this.nextDestination=e,this.nextDestinationFolder=t.crossFolder;let s=t.crossFolder.split("/").pop()||t.crossFolder,i=e===B?"Home":(t.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${s} \u25B8 ${i}`,this.render(),this.composerInputEl?.focus();return}this.nextDestination=t.id,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus()},onCreate:async t=>{let e=await this.createNoteUnder(t,this.focusId);e&&(this.nextDestination=e,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus())},crossFolderNotes:()=>this.collectCrossFolderDestinations()}).open()}collectCrossFolderDestinations(){let t=this.collectCrossFolderNotes(),e=this.plugin.searchableFolders(this.noteFolder).filter(n=>n!==this.noteFolder),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(!e.includes(r))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===B&&s.set(r,n)}return[...e.map(n=>({file:s.get(n),folder:n,id:B,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}openSearchInParentModal(){let t=this.focusId,e=i=>{if(i===t)return!0;let n=this.tree.get(i);for(;n&&n.id!==B;){if(n.parent===t||n.id===t)return!0;if(!n.parent)return!1;n=this.tree.get(n.parent)}return t===B},s=new Proxy(this.tree,{get:(i,n)=>n==="getRoot"?()=>i.get(t)??i.getRoot():n==="getChildren"?r=>i.getChildren(r):i[n]});new Lt(this.app,s,i=>this.titleForNode(i),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(t)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:i=>{i.node&&e(i.node.id)?this.navigateTo(i.node.id):i.node&&this.navigateTo(i.node.id)}}).open()}openSearchModal(){if(this.openSearchInstance){let s=this.openSearchInstance.inputEl;s&&(s.focus(),s.select());return}let t=new Lt(this.app,this.tree,s=>this.titleForNode(s),{mode:"search",placeholder:"Search Stashpad notes\u2026",allowCreate:!0,onCreate:async s=>{let i=s.trim();i&&new Lt(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${i}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let r=n.crossFolder?n.id.replace(/^cross:/,""):n.node?.id,o=n.crossFolder??this.noteFolder;if(!r)return;let a=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",l=this.app.workspace,c=l.getLeaf("tab");await c.setViewState({type:vt,active:!0,state:{focusId:r,folderOverride:o===a?null:o}}),l.revealLeaf(c);let d=c.view;if(d&&typeof d.createNoteUnder=="function"){let p=await d.createNoteUnder(i,r);p&&typeof d.navigateTo=="function"&&d.navigateTo(p)}}}).open()},onPick:s=>{if(s.kind==="folder-open"&&s.folder){this.openFolderInNewTab(s.folder);return}if(s.crossFolder&&s.crossFile){let i=s.id.replace(/^cross:/,"");this.switchToFolderAndFocus(s.crossFolder,i);return}s.node&&this.navigateTo(s.node.id)},crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(s=>s!==this.noteFolder),showFilterChips:!0,localFolder:this.noteFolder});this.openSearchInstance=t;let e=t.onClose.bind(t);t.onClose=()=>{e(),this.openSearchInstance===t&&(this.openSearchInstance=null)},t.open()}collectCrossFolderNotes(){let t=[],e=this.plugin.searchableFolders(this.noteFolder).filter(n=>n!==this.noteFolder);if(!e.length)return t;let s=new Set(e),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(r))continue;let o=i.get(r);o||(o=[],i.set(r,o)),o.push(n)}for(let n of e){let r=i.get(n)??[],o=new Map;for(let a of r){let l=this.app.metadataCache.getFileCache(a)?.frontmatter;typeof l?.id=="string"&&o.set(l.id,a)}for(let a of r){let l=this.app.metadataCache.getFileCache(a)?.frontmatter,c=typeof l?.id=="string"?l.id:"";if(!c||c===B)continue;let d=a.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),p,h=l?.parent??null;if(h&&h!==B){let u=o.get(h);u&&(p=u.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:a,folder:n,id:c,title:d,body:"",parentBlurb:p,parentId:h??null})}}return t}async switchToFolderAndFocus(t,e){await this.setFolderOverride(t),this.tree.get(e)&&this.navigateTo(e)}async cmdOutdent(){let t=this.getActionTargets();if(!t.length)return;let e=[],s=[];for(let i of t){let n=i.parent?this.tree.get(i.parent):null;if(!n||n.id===B){s.push(i.id);continue}let r=n.parent??B;await this.changeParent(i,r),e.push(i)}if(e.length===0){new O.Notice(s.length?"Already at the top level.":"Nothing to outdent.");return}if(this.render(),s.length){let i=e.map(n=>this.tree.get(n)).filter(n=>!!n);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:i,suffix:s.length?`(${s.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:e,folder:this.noteFolder})}if(this.plugin.settings.autoNavOnMoveOut&&e.length>0){let i=e[0].parent;i!=null&&e.every(r=>r.parent===i)&&i!==this.focusId&&this.navigateTo(i)}}cmdSetColor(){let t=this.getActionTargets();if(!t.length)return;let e=new Set(t.map(n=>this.colorForNode(n)??"")),s=e.size===1&&Array.from(e)[0]||null,i=this.plugin.settings.customPalette??[];new Kt(this.app,s,i,async(n,r)=>{let o=[];for(let d of t)if(d.file){o.push({id:d.id,path:d.file.path,was:this.colorForNode(d)??null});try{await this.app.fileManager.processFrontMatter(d.file,p=>{n?p.color=n:delete p.color})}catch(p){new O.Notice(`Couldn't set color for ${d.id}: ${p.message}`)}}if(r.addToPalette&&typeof n=="string"){let d=[...this.plugin.settings.customPalette??[]],p=n.toLowerCase();d.some(h=>h.toLowerCase()===p)||(d.push(n),this.plugin.settings.customPalette=d,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:B,payload:{color:n}}))}this.render();let a=this.noteFolder,l=n,c=async d=>{for(let p of d){let h=this.app.vault.getAbstractFileByPath(p.path);if(h)try{await this.app.fileManager.processFrontMatter(h,u=>{p.col?u.color=p.col:delete u.color})}catch{}}this.tree.rebuild(a),this.render()};this.plugin.getUndoStack(a).push({label:o.length===1?"Color change":`Color change (${o.length})`,undo:()=>c(o.map(d=>({path:d.path,col:d.was}))),redo:()=>c(o.map(d=>({path:d.path,col:l})))})},async n=>{let r=(this.plugin.settings.customPalette??[]).filter(o=>o.toLowerCase()!==n.toLowerCase());return this.plugin.settings.customPalette=r,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_remove",id:B,payload:{color:n}}),r}).open()}cmdMovePicker(){let t=this.getActionTargets();t.length&&new Lt(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async e=>{if(e.crossFolder){let i=e.id.replace(/^cross:/,"");await this.moveAcrossFolders(t,e.crossFolder,i),this.selection.clear(),this.render();return}let s=e.id;for(let i of t)await this.changeParent(i,s);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&s!==this.focusId&&this.navigateTo(s)},onCreate:async e=>{let s=await this.createNoteUnder(e,this.focusId);if(s){for(let i of t)await this.changeParent(i,s);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&this.navigateTo(s)}},crossFolderNotes:()=>this.collectCrossFolderDestinations(),showFilterChips:!0}).open()}async moveAcrossFolders(t,e,s){if(!t.length)return;let i=(e||"").replace(/\/+$/,"");if(!i){new O.Notice("Target folder is empty");return}let n=[],r=new Set;for(let d of this.app.vault.getMarkdownFiles())(d.parent?.path?.replace(/\/+$/,"")??"")===i&&r.add(d.path);let o=(d,p)=>{if(!d.file)return;let h=d.file,u=`${i}/${h.name}`;if(r.has(u)){let m=h.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),g=m?m[1]:h.basename,y=m?m[2]:"";for(let S=1;S<1e3;S++){let k=`${g}-${S}${y}.md`,x=`${i}/${k}`;if(!r.has(x)){u=x;break}}}r.add(u),n.push({id:d.id,file:h,oldPath:h.path,newPath:u,oldParent:d.parent,isRoot:p});for(let m of this.tree.getChildren(d.id))o(m,!1)};for(let d of t)o(d,!0);if(!n.length)return;await this.ensureFolder(i);for(let d of n)try{await this.app.fileManager.renameFile(d.file,d.newPath),d.isRoot&&await this.app.fileManager.processFrontMatter(d.file,p=>{p.parent=s}),await this.log.append({type:"parent_change",id:d.id,payload:{from:d.oldParent,to:d.isRoot?s:d.oldParent,crossFolder:{from:this.noteFolder,to:i}}})}catch(p){new O.Notice(`Move failed for ${d.id}: ${p.message}`)}this.tree.rebuild(this.noteFolder);let a=t.map(d=>this.tree.get(d.id)).filter(d=>!!d),l=a.length>0?this.titleList(a):`${t.length} note${t.length===1?"":"s"}`,c=s===B?"Open home":"Open parent";this.plugin.notifications.show({message:`Moved ${l} \u2192 \`${i}\``,kind:"success",category:"move",affectedIds:t.map(d=>d.id),folder:this.noteFolder,actions:[{label:c,onClick:()=>{this.switchToFolderAndFocus(i,s)}}]}),this.plugin.getUndoStack(this.noteFolder).push({label:`Cross-Stashpad move (${n.length})`,undo:async()=>{for(let d of n){let p=this.app.vault.getAbstractFileByPath(d.newPath);if(p)try{await this.app.fileManager.renameFile(p,d.oldPath),d.isRoot&&await this.app.fileManager.processFrontMatter(p,h=>{h.parent=d.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let d of n){let p=this.app.vault.getAbstractFileByPath(d.oldPath);if(p)try{await this.app.fileManager.renameFile(p,d.newPath),d.isRoot&&await this.app.fileManager.processFrontMatter(p,h=>{h.parent=s})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}cmdInListPicker(){if(this.currentChildren.length===0)return;let t=this.cursorIdx>0?this.cursorIdx-1:0;this.inListPicker={activeIdx:t},new O.Notice("Arrows to pick parent, Enter confirms, Esc cancels.");let e=this.listEl?.scrollTop??0;if(this.render(),this.listEl){let s=this.listEl;s.scrollTop=e,requestAnimationFrame(()=>{s.scrollTop=e}),setTimeout(()=>{s.scrollTop=e},60)}}async commitInListPicker(){if(!this.inListPicker)return;let t=this.currentChildren[this.inListPicker.activeIdx];if(this.inListPicker=null,!t){this.render();return}let e=this.getActionTargets().filter(n=>n.id!==t.id);for(let n of e)await this.changeParent(n,t.id);if(this.plugin.settings.autoNavOnMoveIn){this.navigateTo(t.id);return}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"});let s=this.selectionGuardKey,i=()=>{if(this.selectionGuardKey!==s||this.selection.has(t.id))return;let n=this.currentChildren.findIndex(r=>r.id===t.id);n<0||(this.selection.add(t.id),this.cursorIdx=n,this.render({kind:"follow-cursor"}))};setTimeout(i,120),setTimeout(i,400)}async cmdMerge(){let t=this.getActionTargets();if(t.length<2){new O.Notice("Select 2+ notes to merge.");return}t.sort((m,g)=>(m.created||"").localeCompare(g.created||""));let e=t[0];if(!e.file)return;let s=e.file.path,i=await this.app.vault.read(e.file),n=await this.snapshotNotes(t.slice(1),!1),r=[],o=[];for(let m of t){if(!m.file)continue;let g=await this.app.vault.cachedRead(m.file);o.push(this.stripFrontmatter(g).trim())}let a=o.map(m=>m.trim()).filter(Boolean).join(` +`:"";a.value+=`${W}${z} +`,this.composerDraft=a.value},I=y.createEl("button",{cls:"stashpad-composer-btn"});(0,N.setIcon)(I,"paperclip"),I.title="Attach files",I.onmousedown=z=>z.preventDefault(),I.onclick=z=>{z.preventDefault();let W=document.activeElement===a;if(m.click(),W){let X=()=>{a.focus()};setTimeout(X,100),setTimeout(X,500)}},m.addEventListener("change",async()=>{let z=Array.from(m.files??[]);m.value="";for(let W of z){let X=await this.importAttachment(W);X&&E(X)}a.focus()});let A=v.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,N.setIcon)(A,"chevron-left"),A.title="Show more composer options",v.insertBefore(A,y);let O=z=>{v.toggleClass("is-expanded",z),A.title=z?"Hide options":"Show more composer options",(0,N.setIcon)(A,z?"chevron-right":"chevron-left")};A.onmousedown=z=>z.preventDefault(),A.onclick=z=>{z.preventDefault(),O(!v.hasClass("is-expanded"))},O(!1);let F=()=>r.clientWidth<700,D=()=>{let z=F();r.toggleClass("is-narrow",z),O(!z)};D(),requestAnimationFrame(D);let S=new ResizeObserver(D);S.observe(r),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=S;let B=v.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});B.title="Send (Enter)",(0,N.setIcon)(B,"arrow-up");let tt=async()=>{let z=a.value.trim();if(!z)return;a.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(z)}catch{}let W=this.modeSplit??wt().splitOnLines,X=this.nextDestination,L=this.nextDestinationFolder,P=!!L&&L!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!P,this.scrollToBottomOnNextRender=!P;let J=P?{targetFolder:L}:void 0;if(W)for(let K of z.split(/\r?\n/)){let Y=K.trim();Y&&await this.createNoteUnder(Y,X,J)}else await this.createNoteUnder(z,X,J);wt().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,P&&this.composerInputEl?.focus())};B.onclick=()=>void tt(),a.addEventListener("keydown",z=>{let W=this.modeEnterSubmits;if(z.key==="Escape"){z.preventDefault(),z.stopPropagation(),a.blur(),this.viewRoot.focus({preventScroll:!0});return}if(z.key==="ArrowUp"&&a.selectionStart===0&&a.selectionEnd===0){z.preventDefault(),a.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0&&(this.cursorIdx=this.currentChildren.length-1,this.selectCursor(!1));return}z.key==="Enter"&&!z.isComposing&&(W?!z.shiftKey:z.shiftKey)&&(z.preventDefault(),z.stopPropagation(),z.stopImmediatePropagation(),tt())}),t.createDiv({cls:"stashpad-composer-help"}).setText(this.composerHelperText(s,i))}composerPlaceholder(t,e){return N.Platform.isMobile?e?"New notes (split on newlines)":"New note":`Type a note. ${t?"Enter":"Shift+Enter"} = send, ${t?"Shift+Enter":"Enter"} = newline${e?" (each line \u2192 a note)":""}\u2026`}composerHelperText(t,e){let s=t?"Enter":"Shift+Enter",i=t?"Shift+Enter":"Enter",n=wt().bindings,r=h=>{let u=n[h];return u.primary&&u.secondary?u.preferRight?u.secondary:u.primary:u.primary||u.secondary},o=Is(r("toggleSplit")),a=Is(r("pickDestination")),l=Is(r("search")),c=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${s} sends \xB7 ${i} newline \xB7 ${o} split: ${e?"ON":"off"} \xB7 ${a} destination \xB7 ${l} search${c}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===R)return"Home";let t=this.tree.get(this.nextDestination);return t?this.titleForNode(t).trim():"?"}renderMobileNav(t){let e=t.createDiv({cls:"stashpad-mobile-nav"});e.createEl("button",{text:"Home"}).onclick=()=>this.navigateTo(R),e.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),e.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(t,e){let s=t.target,i=s?.closest?.(".tag");if(i){t.preventDefault(),t.stopPropagation();let o=(i.getAttribute("href")||i.textContent||"").replace(/^#/,"").trim();if(o){let a=this.app.internalPlugins?.plugins?.["global-search"],l=a?.instance?.openGlobalSearch?.bind(a.instance);l&&l(`tag:#${o}`)}return}let n=s?.closest?.(".internal-link");if(n){t.preventDefault(),t.stopPropagation();let r=n.getAttribute("data-href")||n.getAttribute("href");if(r){let o=e.file?.path||"";this.app.workspace.openLinkText(r,o,!0)}}}handleRowClick(t,e,s){let i=t.target,n=i?.closest?.(".tag");if(n){t.preventDefault(),t.stopPropagation();let l=(n.getAttribute("href")||n.textContent||"").replace(/^#/,"").trim();if(l){let c=this.app.internalPlugins?.plugins?.["global-search"],h=c?.instance?.openGlobalSearch?.bind(c.instance);h&&h(`tag:#${l}`)}return}let r=i?.closest?.(".internal-link");if(r){t.preventDefault(),t.stopPropagation();let a=r.getAttribute("data-href")||r.getAttribute("href");if(a){let l=s.file?.path||"";this.app.workspace.openLinkText(a,l,!0)}return}if(i?.tagName==="A"&&i.href)return;if(t.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=e,this.commitInListPicker();return}let o=this.selection.size===0;if(t.shiftKey&&this.lastSelected){this.cursorIdx=e;let a=this.currentChildren.findIndex(l=>l.id===this.lastSelected);if(o&&(this.firstSelectedId=this.lastSelected),a!==-1){let[l,c]=a<e?[a,e]:[e,a];for(let h=l;h<=c;h++)this.selection.add(this.currentChildren[h].id)}else this.selection.add(s.id)}else if(t.metaKey||t.ctrlKey)if(this.selection.has(s.id))if(this.selection.delete(s.id),this.firstSelectedId===s.id&&(this.firstSelectedId=null),this.lastSelected===s.id&&(this.lastSelected=this.selection.size>0?[...this.selection][this.selection.size-1]:null),this.selection.size===0)this.cursorIdx=-1;else{let a=this.lastSelected??[...this.selection][this.selection.size-1],l=a?this.currentChildren.findIndex(c=>c.id===a):-1;l>=0&&(this.cursorIdx=l)}else this.cursorIdx=e,o&&(this.firstSelectedId=s.id),this.selection.add(s.id);else this.mobileSelectMode?(this.cursorIdx=e,this.selection.has(s.id)?(this.selection.delete(s.id),this.firstSelectedId===s.id&&(this.firstSelectedId=null)):this.selection.add(s.id)):(this.cursorIdx=e,this.selection.clear(),this.selection.add(s.id),this.firstSelectedId=s.id,this.lastSelected=s.id);this.selection.size===0&&(this.firstSelectedId=null),this.selection.has(s.id)&&(this.lastSelected=s.id),this.viewRoot.focus({preventScroll:!0}),this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}revealCursorRow(){let t=()=>{let e=this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`);if(!e||!this.listEl)return;let s=this.listEl,i=s.getBoundingClientRect(),n=e.getBoundingClientRect(),r=4;n.top<i.top+r?s.scrollTop+=n.top-i.top-r:n.bottom>i.bottom-r&&(s.scrollTop+=n.bottom-i.bottom+r)};t(),requestAnimationFrame(t),setTimeout(t,60),setTimeout(t,200)}selectCursor(t){let e=this.currentChildren[this.cursorIdx];if(e){if(!t)this.selection.clear(),this.selection.add(e.id),this.firstSelectedId=e.id,this.lastSelected=e.id;else{let s=this.firstSelectedId??e.id,i=this.currentChildren.findIndex(n=>n.id===s);if(i===-1)this.selection.add(e.id),this.firstSelectedId=e.id;else{let[n,r]=i<this.cursorIdx?[i,this.cursorIdx]:[this.cursorIdx,i];this.selection.clear();for(let o=n;o<=r;o++)this.selection.add(this.currentChildren[o].id);this.firstSelectedId=s}this.lastSelected=e.id}this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}}repaintSelectionClasses(){if(!this.listEl)return;let t=!!this.plugin.settings.autoExpandCursorRow,e=this.inListPicker?.activeIdx??-1;this.listEl.querySelectorAll(".stashpad-note").forEach(i=>{let n=Number(i.dataset.idx),r=i.dataset.id??"",o=n===this.cursorIdx;i.classList.toggle("is-cursor",o),i.classList.toggle("is-selected",this.selection.has(r)),i.classList.toggle("is-cursor-expanded",t&&o),i.classList.toggle("is-pick-target",n===e)})}revealRowAt(t){if(!this.listEl)return;let e=this.listEl.querySelector(`.stashpad-note[data-idx="${t}"]`);if(!e)return;let s=e.getBoundingClientRect(),i=this.listEl.getBoundingClientRect();(s.top<i.top||s.bottom>i.bottom)&&e.scrollIntoView({block:"nearest",behavior:"auto"})}getActionTargets(){if(this.selection.size>0)return[...this.selection].map(e=>this.tree.get(e)).filter(e=>!!e&&!!e.file);let t=this.currentChildren[this.cursorIdx];return t?[t]:[]}toggleSplit(){let t=this.modeSplit??wt().splitOnLines;this.modeSplit=!t,this.render(),this.composerInputEl?.focus()}openDestinationPicker(){new Mt(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Send next note(s) under which note?",allowCreate:!0,onPick:async t=>{if(t.crossFolder){let e=t.id.replace(/^cross:/,"");this.nextDestination=e,this.nextDestinationFolder=t.crossFolder;let s=t.crossFolder.split("/").pop()||t.crossFolder,i=e===R?"Home":(t.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${s} \u25B8 ${i}`,this.render(),this.composerInputEl?.focus();return}this.nextDestination=t.id,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus()},onCreate:async t=>{let e=await this.createNoteUnder(t,this.focusId);e&&(this.nextDestination=e,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus())},crossFolderNotes:()=>this.collectCrossFolderDestinations()}).open()}collectCrossFolderDestinations(){let t=this.collectCrossFolderNotes(),e=this.plugin.searchableFolders(this.noteFolder).filter(n=>n!==this.noteFolder),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(!e.includes(r))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===R&&s.set(r,n)}return[...e.map(n=>({file:s.get(n),folder:n,id:R,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}openSearchInParentModal(){let t=this.focusId,e=i=>{if(i===t)return!0;let n=this.tree.get(i);for(;n&&n.id!==R;){if(n.parent===t||n.id===t)return!0;if(!n.parent)return!1;n=this.tree.get(n.parent)}return t===R},s=new Proxy(this.tree,{get:(i,n)=>n==="getRoot"?()=>i.get(t)??i.getRoot():n==="getChildren"?r=>i.getChildren(r):i[n]});new Mt(this.app,s,i=>this.titleForNode(i),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(t)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:i=>{i.node&&e(i.node.id)?this.navigateTo(i.node.id):i.node&&this.navigateTo(i.node.id)}}).open()}openSearchModal(){if(this.openSearchInstance){let s=this.openSearchInstance.inputEl;s&&(s.focus(),s.select());return}let t=new Mt(this.app,this.tree,s=>this.titleForNode(s),{mode:"search",placeholder:"Search Stashpad notes\u2026",allowCreate:!0,onCreate:async s=>{let i=s.trim();i&&new Mt(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${i}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let r=n.crossFolder?n.id.replace(/^cross:/,""):n.node?.id,o=n.crossFolder??this.noteFolder;if(!r)return;let a=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",l=this.app.workspace,c=l.getLeaf("tab");await c.setViewState({type:mt,active:!0,state:{focusId:r,folderOverride:o===a?null:o}}),l.revealLeaf(c);let h=c.view;if(h&&typeof h.createNoteUnder=="function"){let u=await h.createNoteUnder(i,r);u&&typeof h.navigateTo=="function"&&h.navigateTo(u)}}}).open()},onPick:s=>{if(s.kind==="folder-open"&&s.folder){this.openFolderInNewTab(s.folder);return}if(s.crossFolder&&s.crossFile){let i=s.id.replace(/^cross:/,"");this.switchToFolderAndFocus(s.crossFolder,i);return}s.node&&this.navigateTo(s.node.id)},crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(s=>s!==this.noteFolder),showFilterChips:!0,localFolder:this.noteFolder});this.openSearchInstance=t;let e=t.onClose.bind(t);t.onClose=()=>{e(),this.openSearchInstance===t&&(this.openSearchInstance=null)},t.open()}collectCrossFolderNotes(){let t=[],e=this.plugin.searchableFolders(this.noteFolder).filter(n=>n!==this.noteFolder);if(!e.length)return t;let s=new Set(e),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(r))continue;let o=i.get(r);o||(o=[],i.set(r,o)),o.push(n)}for(let n of e){let r=i.get(n)??[],o=new Map;for(let a of r){let l=this.app.metadataCache.getFileCache(a)?.frontmatter;typeof l?.id=="string"&&o.set(l.id,a)}for(let a of r){let l=this.app.metadataCache.getFileCache(a)?.frontmatter,c=typeof l?.id=="string"?l.id:"";if(!c||c===R)continue;let h=a.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),u,d=l?.parent??null;if(d&&d!==R){let p=o.get(d);p&&(u=p.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:a,folder:n,id:c,title:h,body:"",parentBlurb:u,parentId:d??null})}}return t}async switchToFolderAndFocus(t,e){await this.setFolderOverride(t),this.tree.get(e)&&this.navigateTo(e)}async cmdOutdent(){let t=this.getActionTargets();if(!t.length)return;let e=[],s=[];for(let i of t){let n=i.parent?this.tree.get(i.parent):null;if(!n||n.id===R){s.push(i.id);continue}let r=n.parent??R;await this.changeParent(i,r),e.push(i)}if(e.length===0){new N.Notice(s.length?"Already at the top level.":"Nothing to outdent.");return}if(this.render(),s.length){let i=e.map(n=>this.tree.get(n)).filter(n=>!!n);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:i,suffix:s.length?`(${s.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:e,folder:this.noteFolder})}if(this.plugin.settings.autoNavOnMoveOut&&e.length>0){let i=e[0].parent;i!=null&&e.every(r=>r.parent===i)&&i!==this.focusId&&this.navigateTo(i)}}cmdSetColor(){let t=this.getActionTargets();if(!t.length)return;let e=new Set(t.map(n=>this.colorForNode(n)??"")),s=e.size===1&&Array.from(e)[0]||null,i=this.plugin.settings.customPalette??[];new Vt(this.app,s,i,async(n,r)=>{let o=[];for(let h of t)if(h.file){o.push({id:h.id,path:h.file.path,was:this.colorForNode(h)??null});try{await this.app.fileManager.processFrontMatter(h.file,u=>{n?u.color=n:delete u.color})}catch(u){new N.Notice(`Couldn't set color for ${h.id}: ${u.message}`)}}if(r.addToPalette&&typeof n=="string"){let h=[...this.plugin.settings.customPalette??[]],u=n.toLowerCase();h.some(d=>d.toLowerCase()===u)||(h.push(n),this.plugin.settings.customPalette=h,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:R,payload:{color:n}}))}this.render();let a=this.noteFolder,l=n,c=async h=>{for(let u of h){let d=this.app.vault.getAbstractFileByPath(u.path);if(d)try{await this.app.fileManager.processFrontMatter(d,p=>{u.col?p.color=u.col:delete p.color})}catch{}}this.tree.rebuild(a),this.render()};this.plugin.getUndoStack(a).push({label:o.length===1?"Color change":`Color change (${o.length})`,undo:()=>c(o.map(h=>({path:h.path,col:h.was}))),redo:()=>c(o.map(h=>({path:h.path,col:l})))})},async n=>{let r=(this.plugin.settings.customPalette??[]).filter(o=>o.toLowerCase()!==n.toLowerCase());return this.plugin.settings.customPalette=r,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_remove",id:R,payload:{color:n}}),r}).open()}cmdMovePicker(){let t=this.getActionTargets();t.length&&new Mt(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async e=>{if(e.crossFolder){let i=e.id.replace(/^cross:/,"");await this.moveAcrossFolders(t,e.crossFolder,i),this.selection.clear(),this.render();return}let s=e.id;for(let i of t)await this.changeParent(i,s);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&s!==this.focusId&&this.navigateTo(s)},onCreate:async e=>{let s=await this.createNoteUnder(e,this.focusId);if(s){for(let i of t)await this.changeParent(i,s);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&this.navigateTo(s)}},crossFolderNotes:()=>this.collectCrossFolderDestinations(),showFilterChips:!0}).open()}async moveAcrossFolders(t,e,s){if(!t.length)return;let i=(e||"").replace(/\/+$/,"");if(!i){new N.Notice("Target folder is empty");return}let n=[],r=new Set;for(let h of this.app.vault.getMarkdownFiles())(h.parent?.path?.replace(/\/+$/,"")??"")===i&&r.add(h.path);let o=(h,u)=>{if(!h.file)return;let d=h.file,p=`${i}/${d.name}`;if(r.has(p)){let m=d.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),v=m?m[1]:d.basename,y=m?m[2]:"";for(let b=1;b<1e3;b++){let k=`${v}-${b}${y}.md`,C=`${i}/${k}`;if(!r.has(C)){p=C;break}}}r.add(p),n.push({id:h.id,file:d,oldPath:d.path,newPath:p,oldParent:h.parent,isRoot:u});for(let m of this.tree.getChildren(h.id))o(m,!1)};for(let h of t)o(h,!0);if(!n.length)return;await this.ensureFolder(i);for(let h of n)try{await this.app.fileManager.renameFile(h.file,h.newPath),h.isRoot&&await this.app.fileManager.processFrontMatter(h.file,u=>{u.parent=s}),await this.log.append({type:"parent_change",id:h.id,payload:{from:h.oldParent,to:h.isRoot?s:h.oldParent,crossFolder:{from:this.noteFolder,to:i}}})}catch(u){new N.Notice(`Move failed for ${h.id}: ${u.message}`)}this.tree.rebuild(this.noteFolder);let a=t.map(h=>this.tree.get(h.id)).filter(h=>!!h),l=a.length>0?this.titleList(a):`${t.length} note${t.length===1?"":"s"}`,c=s===R?"Open home":"Open parent";this.plugin.notifications.show({message:`Moved ${l} \u2192 \`${i}\``,kind:"success",category:"move",affectedIds:t.map(h=>h.id),folder:this.noteFolder,actions:[{label:c,onClick:()=>{this.switchToFolderAndFocus(i,s)}}]}),this.plugin.getUndoStack(this.noteFolder).push({label:`Cross-Stashpad move (${n.length})`,undo:async()=>{for(let h of n){let u=this.app.vault.getAbstractFileByPath(h.newPath);if(u)try{await this.app.fileManager.renameFile(u,h.oldPath),h.isRoot&&await this.app.fileManager.processFrontMatter(u,d=>{d.parent=h.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let h of n){let u=this.app.vault.getAbstractFileByPath(h.oldPath);if(u)try{await this.app.fileManager.renameFile(u,h.newPath),h.isRoot&&await this.app.fileManager.processFrontMatter(u,d=>{d.parent=s})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}cmdInListPicker(){if(this.currentChildren.length===0)return;let t=this.cursorIdx>0?this.cursorIdx-1:0;this.inListPicker={activeIdx:t},new N.Notice("Arrows to pick parent, Enter confirms, Esc cancels.");let e=this.listEl?.scrollTop??0;if(this.render(),this.listEl){let s=this.listEl;s.scrollTop=e,requestAnimationFrame(()=>{s.scrollTop=e}),setTimeout(()=>{s.scrollTop=e},60)}}async commitInListPicker(){if(!this.inListPicker)return;let t=this.currentChildren[this.inListPicker.activeIdx];if(this.inListPicker=null,!t){this.render();return}let e=this.getActionTargets().filter(n=>n.id!==t.id);for(let n of e)await this.changeParent(n,t.id);if(this.plugin.settings.autoNavOnMoveIn){this.navigateTo(t.id);return}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"});let s=this.selectionGuardKey,i=()=>{if(this.selectionGuardKey!==s||this.selection.has(t.id))return;let n=this.currentChildren.findIndex(r=>r.id===t.id);n<0||(this.selection.add(t.id),this.cursorIdx=n,this.render({kind:"follow-cursor"}))};setTimeout(i,120),setTimeout(i,400)}async cmdMerge(){let t=this.getActionTargets();if(t.length<2){new N.Notice("Select 2+ notes to merge.");return}t.sort((m,v)=>(m.created||"").localeCompare(v.created||""));let e=t[0];if(!e.file)return;let s=e.file.path,i=await this.app.vault.read(e.file),n=await this.snapshotNotes(t.slice(1),!1),r=[],o=[];for(let m of t){if(!m.file)continue;let v=await this.app.vault.cachedRead(m.file);o.push(this.stripFrontmatter(v).trim())}let a=o.map(m=>m.trim()).filter(Boolean).join(` `),l=await this.app.vault.read(e.file),c=l.startsWith("---")?l.indexOf(` ----`,3)+4:0,p=`${l.slice(0,c)} +---`,3)+4:0,u=`${l.slice(0,c)} ${a} -`;await this.app.vault.modify(e.file,p);for(let m=1;m<t.length;m++){let g=t[m];if(g.file){for(let y of this.tree.getChildren(g.id))y.file&&r.push({childId:y.id,childPath:y.file.path,oldParent:y.parent}),await this.changeParent(y,e.id,{record:!1});await this.app.fileManager.trashFile(g.file),await this.log.append({type:"delete",id:g.id,payload:{mergedInto:e.id}})}}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[e.id];let h=this.titleForNode(e);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Merged",nodes:t,destination:`\u2192 kept "${h}"`}),kind:"success",category:"merge",affectedIds:t.map(m=>m.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let m=e.id,g=this.selectionGuardKey,y=()=>{if(this.selectionGuardKey!==g||this.selection.has(m))return;let S=this.currentChildren.findIndex(k=>k.id===m);S<0||(this.selection.add(m),this.cursorIdx=S,this.render({kind:"follow-cursor"}))};setTimeout(y,120),setTimeout(y,400)}let u=this.noteFolder;this.plugin.getUndoStack(u).push({label:`Merge ${t.length} notes`,undo:async()=>{await this.restoreSnapshots(n,t.map(g=>g.id));let m=this.app.vault.getAbstractFileByPath(s);m&&await this.app.vault.modify(m,i);for(let g of r){let y=this.app.vault.getAbstractFileByPath(g.childPath);y&&await this.app.fileManager.processFrontMatter(y,S=>{S.parent=g.oldParent})}this.pendingFocusIds=t.map(g=>g.id),this.tree.rebuild(u),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let m=this.app.vault.getAbstractFileByPath(s);m&&await this.app.vault.modify(m,p);for(let g of r){let y=this.app.vault.getAbstractFileByPath(g.childPath);y&&await this.app.fileManager.processFrontMatter(y,S=>{S.parent=e.id})}this.tree.rebuild(u),this.render()}})}async cmdCopy(){let t=this.getActionTargets();if(!t.length)return;let e=kt().prefixTimestampsOnCopy,s=[];for(let i of t){if(!i.file)continue;let n=await this.app.vault.cachedRead(i.file),r=this.stripFrontmatter(n).trim();s.push(e?`${this.formatTimeInline(i.created)} ${r}`:r)}await navigator.clipboard.writeText(s.join(` +`;await this.app.vault.modify(e.file,u);for(let m=1;m<t.length;m++){let v=t[m];if(v.file){for(let y of this.tree.getChildren(v.id))y.file&&r.push({childId:y.id,childPath:y.file.path,oldParent:y.parent}),await this.changeParent(y,e.id,{record:!1});await this.app.fileManager.trashFile(v.file),await this.log.append({type:"delete",id:v.id,payload:{mergedInto:e.id}})}}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[e.id];let d=this.titleForNode(e);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Merged",nodes:t,destination:`\u2192 kept "${d}"`}),kind:"success",category:"merge",affectedIds:t.map(m=>m.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let m=e.id,v=this.selectionGuardKey,y=()=>{if(this.selectionGuardKey!==v||this.selection.has(m))return;let b=this.currentChildren.findIndex(k=>k.id===m);b<0||(this.selection.add(m),this.cursorIdx=b,this.render({kind:"follow-cursor"}))};setTimeout(y,120),setTimeout(y,400)}let p=this.noteFolder;this.plugin.getUndoStack(p).push({label:`Merge ${t.length} notes`,undo:async()=>{await this.restoreSnapshots(n,t.map(v=>v.id));let m=this.app.vault.getAbstractFileByPath(s);m&&await this.app.vault.modify(m,i);for(let v of r){let y=this.app.vault.getAbstractFileByPath(v.childPath);y&&await this.app.fileManager.processFrontMatter(y,b=>{b.parent=v.oldParent})}this.pendingFocusIds=t.map(v=>v.id),this.tree.rebuild(p),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let m=this.app.vault.getAbstractFileByPath(s);m&&await this.app.vault.modify(m,u);for(let v of r){let y=this.app.vault.getAbstractFileByPath(v.childPath);y&&await this.app.fileManager.processFrontMatter(y,b=>{b.parent=e.id})}this.tree.rebuild(p),this.render()}})}async cmdCopy(){let t=this.getActionTargets();if(!t.length)return;let e=wt().prefixTimestampsOnCopy,s=[];for(let i of t){if(!i.file)continue;let n=await this.app.vault.cachedRead(i.file),r=this.stripFrontmatter(n).trim();s.push(e?`${this.formatTimeInline(i.created)} ${r}`:r)}await navigator.clipboard.writeText(s.join(` -`)),this.plugin.notifications.show({message:`Copied ${this.titleList(t)} to clipboard`,kind:"success",category:"system",affectedIds:t.map(i=>i.id),folder:this.noteFolder})}async cmdCopyCodeBlock(){let t=this.getActionTargets();if(!t.length||!t[0].file){new O.Notice("Nothing to copy from.");return}let e=t[0],s=await this.app.vault.cachedRead(e.file),i=this.stripFrontmatter(s),n=Mi(i);if(n.length===0){this.plugin.notifications.show({message:`No codeblock found in "${this.titleForNode(e)}".`,kind:"info",category:"system",affectedIds:[e.id],folder:this.noteFolder});return}if(n.length===1){await navigator.clipboard.writeText(n[0].code),this.plugin.notifications.show({message:`Copied codeblock${n[0].lang?` (${n[0].lang})`:""} from "${this.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:this.noteFolder});return}let r=n.map((l,c)=>({kind:"one",idx:c,label:`${c+1}. ${l.lang||"(no language)"} \u2014 ${l.code.split(` +`)),this.plugin.notifications.show({message:`Copied ${this.titleList(t)} to clipboard`,kind:"success",category:"system",affectedIds:t.map(i=>i.id),folder:this.noteFolder})}async cmdCopyCodeBlock(){let t=this.getActionTargets();if(!t.length||!t[0].file){new N.Notice("Nothing to copy from.");return}let e=t[0],s=await this.app.vault.cachedRead(e.file),i=this.stripFrontmatter(s),n=Bi(i);if(n.length===0){this.plugin.notifications.show({message:`No codeblock found in "${this.titleForNode(e)}".`,kind:"info",category:"system",affectedIds:[e.id],folder:this.noteFolder});return}if(n.length===1){await navigator.clipboard.writeText(n[0].code),this.plugin.notifications.show({message:`Copied codeblock${n[0].lang?` (${n[0].lang})`:""} from "${this.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:this.noteFolder});return}let r=n.map((l,c)=>({kind:"one",idx:c,label:`${c+1}. ${l.lang||"(no language)"} \u2014 ${l.code.split(` `)[0].slice(0,60)}${l.code.includes(` -`)?"\u2026":""}`}));r.push({kind:"all",idx:-1,label:`Copy all ${n.length} blocks (joined with blank lines)`});let o=this,a=new class extends O.SuggestModal{getSuggestions(l){let c=l.trim().toLowerCase();if(!c)return r;let d=c.split(/\s+/).filter(Boolean);return r.filter(p=>{let h=p.label.toLowerCase();return d.every(u=>h.includes(u))})}renderSuggestion(l,c){c.createDiv({cls:"stashpad-suggest-title",text:l.label})}async onChooseSuggestion(l){let c=l.kind==="all"?n.map(d=>d.code).join(` +`)?"\u2026":""}`}));r.push({kind:"all",idx:-1,label:`Copy all ${n.length} blocks (joined with blank lines)`});let o=this,a=new class extends N.SuggestModal{getSuggestions(l){let c=l.trim().toLowerCase();if(!c)return r;let h=c.split(/\s+/).filter(Boolean);return r.filter(u=>{let d=u.label.toLowerCase();return h.every(p=>d.includes(p))})}renderSuggestion(l,c){c.createDiv({cls:"stashpad-suggest-title",text:l.label})}async onChooseSuggestion(l){let c=l.kind==="all"?n.map(h=>h.code).join(` -`):n[l.idx].code;await navigator.clipboard.writeText(c),o.plugin.notifications.show({message:l.kind==="all"?`Copied all ${n.length} codeblocks from "${o.titleForNode(e)}".`:`Copied codeblock${n[l.idx].lang?` (${n[l.idx].lang})`:""} from "${o.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:o.noteFolder})}}(this.app);a.setPlaceholder(`${n.length} codeblocks in "${this.titleForNode(e)}" \u2014 pick one to copy.`),a.open()}async cmdCopyTree(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new O.Notice("Nothing to copy.");return}let e=kt().prefixTimestampsOnCopy,s=[],i=async(n,r)=>{if(n.file){let o=await this.app.vault.cachedRead(n.file),a=this.stripFrontmatter(o).trim().split(/\r?\n/).join(" "),l=e?`${this.formatTimeInline(n.created)} `:"";s.push(`${" ".repeat(r)}- ${l}${a}`)}for(let o of this.tree.getChildren(n.id))await i(o,r+1)};for(let n of t)await i(n,0);await navigator.clipboard.writeText(s.join(` -`)),this.plugin.notifications.show({message:`Copied tree of ${this.titleList(t)} (${s.length} entries)`,kind:"success",category:"system",affectedIds:t.map(n=>n.id),folder:this.noteFolder})}async cmdCopyOutline(){let t=this.getActionTargets();if(t.length===0){let i=this.tree.get(this.focusId);i?.file&&(t=[i])}if(t.length===0){new O.Notice("Nothing to copy.");return}let e=[],s=(i,n)=>{if(!i.file)return;let r=" ".repeat(n);e.push(`${r}- ![[${i.file.basename}]]`);for(let o of this.tree.getChildren(i.id))s(o,n+1)};for(let i of t)s(i,0);await navigator.clipboard.writeText(e.join(` -`)),this.plugin.notifications.show({message:`Copied outline of ${this.titleList(t)} (${e.length} entr${e.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:t.map(i=>i.id),folder:this.noteFolder})}cmdToggleExpand(){let t=this.getActionTargets();if(!t.length)return;let e=t.some(s=>!this.expandedNotes.has(s.id));for(let s of t)e?this.expandedNotes.add(s.id):this.expandedNotes.delete(s.id);this.render()}async cloneSubtree(t,e,s){if(!t.file)return null;if(t.id===e||this.isDescendant(e,t.id))return new O.Notice(`Can't insert "${this.titleForNode(t)}" into itself or a descendant \u2014 that would loop forever.`),null;let i=this.tree.getChildren(t.id).slice(),n=t.file,r=await this.app.vault.read(n),o=this.stripFrontmatter(r),a=this.app.metadataCache.getFileCache(n)?.frontmatter??{},l=Ft(),c=Bt(o,this.activeStopwords()),d=Ht(c,l),p=`${this.noteFolder}/${d}`,h=new Date().toISOString(),u=this.extractAttachments(o),m=["---",`id: ${l}`,`parent: ${e}`,`created: ${h}`];if(u.length>0){m.push("attachments:");for(let y of u)m.push(` - "${y.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",o),await this.ensureFolder(this.noteFolder),await this.app.vault.create(p,m.join(` -`)),s.push(p);let g=this.app.vault.getAbstractFileByPath(p);if(g){try{await this.app.fileManager.processFrontMatter(g,y=>{for(let[S,k]of Object.entries(a))re.includes(S)||(y[S]=k)})}catch(y){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",y)}try{this.tree.insertSynthetic({id:l,parent:e,children:[],file:g,created:h})}catch{}this.fmSync.scheduleParentChange(l,null,e)}for(let y of i)await this.cloneSubtree(y,l,s);return l}async cmdClone(){let t=this.getActionTargets();if(!t.length){new O.Notice("Nothing to clone.");return}let e=this.noteFolder,s=[],i=[];for(let a of t){if(!a.file)continue;let l=a.parent??this.focusId,c=await this.cloneSubtree(a,l,s);c&&i.push(c)}if(!i.length)return;this.tree.rebuild(e),this.pendingFocusIds=i.slice(),this.render();let n=s.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Qt(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),r=await this.snapshotNotes(n,!1);this.plugin.getUndoStack(e).push({label:`Clone ${i.length} note${i.length===1?"":"s"}`,undo:async()=>{for(let a of[...s].reverse()){let l=this.app.vault.getAbstractFileByPath(a);if(l)try{await this.app.fileManager.trashFile(l)}catch{}}this.tree.rebuild(e),this.render()},redo:async()=>{await this.restoreSnapshots(r,i)}});let o=i.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:o,suffix:`(${s.length} file${s.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:i,folder:this.noteFolder})}cmdInsertTemplate(){new Lt(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Insert which note as a template?",allowCreate:!1,onPick:async t=>{if(t.crossFolder){new O.Notice("Cross-Stashpad templates aren't supported yet \u2014 pick a note from this Stashpad.");return}let e=this.tree.get(t.id);if(!e?.file)return;let s=this.noteFolder,i=[],n=await this.cloneSubtree(e,this.focusId,i);if(!n)return;this.tree.rebuild(s),this.pendingFocusIds=[n],this.render();let r=i.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Qt(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),o=await this.snapshotNotes(r,!1);this.plugin.getUndoStack(s).push({label:"Insert template",undo:async()=>{for(let a of[...i].reverse()){let l=this.app.vault.getAbstractFileByPath(a);if(l)try{await this.app.fileManager.trashFile(l)}catch{}}this.tree.rebuild(s),this.render()},redo:async()=>{await this.restoreSnapshots(o,[n])}}),this.plugin.notifications.show({message:`Inserted template (${i.length} file${i.length===1?"":"s"})`,kind:"success",category:"clone",folder:this.noteFolder})}}).open()}navigateTo(t,e={}){if(e.keepForwardStack||this.recordNavState(),this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=t,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus(),this.tagFilter){let n=this.tagFilter.toLowerCase();this.collectFolderTags().some(o=>o.raw.toLowerCase()===n)||(this.tagFilter=null)}if(this.colorFilter){let n=this.colorFilter.toLowerCase();this.collectFolderColors().some(o=>o.hex===n)||(this.colorFilter=null)}let s=this.lastCursorByFocus.get(t),i;s&&this.tree.get(s)?(this.pendingFocusIds=[s],i={kind:"scroll-to-id",id:s,align:"start"}):i={kind:"preserve"},this.render(i),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateBack(){let t=this.navBackStack.pop();if(!t){this.focusId!==B&&this.navigateUp();return}this.navForwardSnapshots.push(this.captureNavSnapshot()),this.applyNavSnapshot(t)}navigateForward(){let t=this.navForwardSnapshots.pop();t&&(this.navBackStack.push(this.captureNavSnapshot()),this.applyNavSnapshot(t))}async applyNavSnapshot(t){if(this.tagFilter=null,this.colorFilter=null,t.folder!==this.noteFolder){await this.setFolderOverride(t.folder,{skipHistory:!0}),t.focusId!==this.focusId&&this.tree.get(t.focusId)&&(this.focusId=t.focusId,this.render({kind:"preserve"}));return}if(!this.tree.get(t.focusId))return;this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=t.focusId,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus();let e=this.lastCursorByFocus.get(t.focusId),s;e&&this.tree.get(e)?(this.pendingFocusIds=[e],s={kind:"scroll-to-id",id:e,align:"start"}):s={kind:"preserve"},this.render(s),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0})}navigateUp(){this.selectionGuardKey++,this.tagFilter=null,this.colorFilter=null;let t=this.tree.get(this.focusId);if(!t||t.parent==null){if(this.navBackStack.length>0){this.navigateBack();return}return this.navigateTo(B)}let e=this.focusId;if(this.recordNavState(),this.listEl){let r=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;r&&this.plugin.saveLastCursor(this.noteFolder,e,r)}this.focusId=t.parent,this.persistFocus(),this.syncComposerDraftForFocus();let s=this.filterChildren(this.tree.getChildren(this.focusId)),i=s.findIndex(n=>n.id===e);this.selection.clear(),i>=0?(this.cursorIdx=i,this.selection.add(e),this.lastSelected=e):(this.cursorIdx=s.length-1,s.length>0&&(this.selection.add(s[s.length-1].id),this.lastSelected=s[s.length-1].id)),this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),this.revealCursorRow()}openBookmarks(){let t=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],e=this.allowedByBases(),s=new O.Menu,i=0;for(let n of t){if(n.type!=="file"||e&&!e.has(n.path))continue;let r=this.tree.idForPath(n.path);r&&(s.addItem(o=>o.setTitle(n.title||n.path).onClick(()=>this.navigateTo(r))),i++)}i||s.addItem(n=>n.setTitle("(no bookmarks in scope)").setDisabled(!0)),s.showAtMouseEvent(new MouseEvent("click",{clientX:200,clientY:400}))}async bootstrapFolder(){if(this.bootstrappedFolders.has(this.noteFolder))return;await this.ensureFolder(this.noteFolder),await this.ensureHomeNote(),await this.migrateNullParents();let t=(this.plugin.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),e=(this.plugin.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");t&&await this.ensureFolder(`${this.noteFolder}/${t}`),e&&await this.ensureFolder(`${this.noteFolder}/${e}`),await this.order.load(this.noteFolder),await this.sortStore.load(this.noteFolder),this.bootstrappedFolders.add(this.noteFolder)}backfillFrontmatterSync(){let t=[B],e=this.tree.getRoot(),s=i=>{for(let n of this.tree.getChildren(i))t.push(n.id),s(n.id)};for(let i of e.children)s(i);for(let i of t)this.fmSync.wouldWrite(i)&&this.fmSync.schedule(i)}installFmSyncActivityNotice(){this.fmSyncUnsubscribe||(this.fmSyncUnsubscribe=this.fmSync.onError((t,e)=>{this.plugin.notifications.show({message:`Stashpad: couldn't update recovery metadata +`):n[l.idx].code;await navigator.clipboard.writeText(c),o.plugin.notifications.show({message:l.kind==="all"?`Copied all ${n.length} codeblocks from "${o.titleForNode(e)}".`:`Copied codeblock${n[l.idx].lang?` (${n[l.idx].lang})`:""} from "${o.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:o.noteFolder})}}(this.app);a.setPlaceholder(`${n.length} codeblocks in "${this.titleForNode(e)}" \u2014 pick one to copy.`),a.open()}async cmdCopyTree(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new N.Notice("Nothing to copy.");return}let e=wt().prefixTimestampsOnCopy,s=[],i=async(n,r)=>{if(n.file){let o=await this.app.vault.cachedRead(n.file),a=this.stripFrontmatter(o).trim().split(/\r?\n/).join(" "),l=e?`${this.formatTimeInline(n.created)} `:"";s.push(`${" ".repeat(r)}- ${l}${a}`)}for(let o of this.tree.getChildren(n.id))await i(o,r+1)};for(let n of t)await i(n,0);await navigator.clipboard.writeText(s.join(` +`)),this.plugin.notifications.show({message:`Copied tree of ${this.titleList(t)} (${s.length} entries)`,kind:"success",category:"system",affectedIds:t.map(n=>n.id),folder:this.noteFolder})}async cmdCopyOutline(){let t=this.getActionTargets();if(t.length===0){let i=this.tree.get(this.focusId);i?.file&&(t=[i])}if(t.length===0){new N.Notice("Nothing to copy.");return}let e=[],s=(i,n)=>{if(!i.file)return;let r=" ".repeat(n);e.push(`${r}- ![[${i.file.basename}]]`);for(let o of this.tree.getChildren(i.id))s(o,n+1)};for(let i of t)s(i,0);await navigator.clipboard.writeText(e.join(` +`)),this.plugin.notifications.show({message:`Copied outline of ${this.titleList(t)} (${e.length} entr${e.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:t.map(i=>i.id),folder:this.noteFolder})}cmdToggleExpand(){let t=this.getActionTargets();if(!t.length)return;let e=t.some(s=>!this.expandedNotes.has(s.id));for(let s of t)e?this.expandedNotes.add(s.id):this.expandedNotes.delete(s.id);this.render()}async cloneSubtree(t,e,s){if(!t.file)return null;if(t.id===e||this.isDescendant(e,t.id))return new N.Notice(`Can't insert "${this.titleForNode(t)}" into itself or a descendant \u2014 that would loop forever.`),null;let i=this.tree.getChildren(t.id).slice(),n=t.file,r=await this.app.vault.read(n),o=this.stripFrontmatter(r),a=this.app.metadataCache.getFileCache(n)?.frontmatter??{},l=Tt(),c=$t(o,this.activeStopwords()),h=Rt(c,l),u=`${this.noteFolder}/${h}`,d=new Date().toISOString(),p=this.extractAttachments(o),m=["---",`id: ${l}`,`parent: ${e}`,`created: ${d}`];if(p.length>0){m.push("attachments:");for(let y of p)m.push(` - "${y.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",o),await this.ensureFolder(this.noteFolder),await this.app.vault.create(u,m.join(` +`)),s.push(u);let v=this.app.vault.getAbstractFileByPath(u);if(v){try{await this.app.fileManager.processFrontMatter(v,y=>{for(let[b,k]of Object.entries(a))ae.includes(b)||(y[b]=k)})}catch(y){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",y)}try{this.tree.insertSynthetic({id:l,parent:e,children:[],file:v,created:d})}catch{}this.fmSync.scheduleParentChange(l,null,e)}for(let y of i)await this.cloneSubtree(y,l,s);return l}async cmdClone(){let t=this.getActionTargets();if(!t.length){new N.Notice("Nothing to clone.");return}let e=this.noteFolder,s=[],i=[];for(let a of t){if(!a.file)continue;let l=a.parent??this.focusId,c=await this.cloneSubtree(a,l,s);c&&i.push(c)}if(!i.length)return;this.tree.rebuild(e),this.pendingFocusIds=i.slice(),this.render();let n=s.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Qt(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),r=await this.snapshotNotes(n,!1);this.plugin.getUndoStack(e).push({label:`Clone ${i.length} note${i.length===1?"":"s"}`,undo:async()=>{for(let a of[...s].reverse()){let l=this.app.vault.getAbstractFileByPath(a);if(l)try{await this.app.fileManager.trashFile(l)}catch{}}this.tree.rebuild(e),this.render()},redo:async()=>{await this.restoreSnapshots(r,i)}});let o=i.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:o,suffix:`(${s.length} file${s.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:i,folder:this.noteFolder})}cmdInsertTemplate(){new Mt(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Insert which note as a template?",allowCreate:!1,onPick:async t=>{if(t.crossFolder){new N.Notice("Cross-Stashpad templates aren't supported yet \u2014 pick a note from this Stashpad.");return}let e=this.tree.get(t.id);if(!e?.file)return;let s=this.noteFolder,i=[],n=await this.cloneSubtree(e,this.focusId,i);if(!n)return;this.tree.rebuild(s),this.pendingFocusIds=[n],this.render();let r=i.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Qt(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),o=await this.snapshotNotes(r,!1);this.plugin.getUndoStack(s).push({label:"Insert template",undo:async()=>{for(let a of[...i].reverse()){let l=this.app.vault.getAbstractFileByPath(a);if(l)try{await this.app.fileManager.trashFile(l)}catch{}}this.tree.rebuild(s),this.render()},redo:async()=>{await this.restoreSnapshots(o,[n])}}),this.plugin.notifications.show({message:`Inserted template (${i.length} file${i.length===1?"":"s"})`,kind:"success",category:"clone",folder:this.noteFolder})}}).open()}navigateTo(t,e={}){if(e.keepForwardStack||this.recordNavState(),this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=t,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus(),this.tagFilter){let n=this.tagFilter.toLowerCase();this.collectFolderTags().some(o=>o.raw.toLowerCase()===n)||(this.tagFilter=null)}if(this.colorFilter){let n=this.colorFilter.toLowerCase();this.collectFolderColors().some(o=>o.hex===n)||(this.colorFilter=null)}let s=this.lastCursorByFocus.get(t),i;s&&this.tree.get(s)?(this.pendingFocusIds=[s],i={kind:"scroll-to-id",id:s,align:"start"}):i={kind:"preserve"},this.render(i),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateBack(){let t=this.navBackStack.pop();if(!t){this.focusId!==R&&this.navigateUp();return}this.navForwardSnapshots.push(this.captureNavSnapshot()),this.applyNavSnapshot(t)}navigateForward(){let t=this.navForwardSnapshots.pop();t&&(this.navBackStack.push(this.captureNavSnapshot()),this.applyNavSnapshot(t))}async applyNavSnapshot(t){if(this.tagFilter=null,this.colorFilter=null,t.folder!==this.noteFolder){await this.setFolderOverride(t.folder,{skipHistory:!0}),t.focusId!==this.focusId&&this.tree.get(t.focusId)&&(this.focusId=t.focusId,this.render({kind:"preserve"}));return}if(!this.tree.get(t.focusId))return;this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=t.focusId,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus();let e=this.lastCursorByFocus.get(t.focusId),s;e&&this.tree.get(e)?(this.pendingFocusIds=[e],s={kind:"scroll-to-id",id:e,align:"start"}):s={kind:"preserve"},this.render(s),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0})}navigateUp(){this.selectionGuardKey++,this.tagFilter=null,this.colorFilter=null;let t=this.tree.get(this.focusId);if(!t||t.parent==null){if(this.navBackStack.length>0){this.navigateBack();return}return this.navigateTo(R)}let e=this.focusId;if(this.recordNavState(),this.listEl){let r=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;r&&this.plugin.saveLastCursor(this.noteFolder,e,r)}this.focusId=t.parent,this.persistFocus(),this.syncComposerDraftForFocus();let s=this.filterChildren(this.tree.getChildren(this.focusId)),i=s.findIndex(n=>n.id===e);this.selection.clear(),i>=0?(this.cursorIdx=i,this.selection.add(e),this.lastSelected=e):(this.cursorIdx=s.length-1,s.length>0&&(this.selection.add(s[s.length-1].id),this.lastSelected=s[s.length-1].id)),this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),this.revealCursorRow()}openBookmarks(){let t=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],e=this.allowedByBases(),s=new N.Menu,i=0;for(let n of t){if(n.type!=="file"||e&&!e.has(n.path))continue;let r=this.tree.idForPath(n.path);r&&(s.addItem(o=>o.setTitle(n.title||n.path).onClick(()=>this.navigateTo(r))),i++)}i||s.addItem(n=>n.setTitle("(no bookmarks in scope)").setDisabled(!0)),s.showAtMouseEvent(new MouseEvent("click",{clientX:200,clientY:400}))}async bootstrapFolder(){if(this.bootstrappedFolders.has(this.noteFolder))return;await this.ensureFolder(this.noteFolder),await this.ensureHomeNote(),await this.migrateNullParents();let t=(this.plugin.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),e=(this.plugin.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");t&&await this.ensureFolder(`${this.noteFolder}/${t}`),e&&await this.ensureFolder(`${this.noteFolder}/${e}`),await this.order.load(this.noteFolder),await this.sortStore.load(this.noteFolder),this.bootstrappedFolders.add(this.noteFolder)}backfillFrontmatterSync(){let t=[R],e=this.tree.getRoot(),s=i=>{for(let n of this.tree.getChildren(i))t.push(n.id),s(n.id)};for(let i of e.children)s(i);for(let i of t)this.fmSync.wouldWrite(i)&&this.fmSync.schedule(i)}installFmSyncActivityNotice(){this.fmSyncUnsubscribe||(this.fmSyncUnsubscribe=this.fmSync.onError((t,e)=>{this.plugin.notifications.show({message:`Stashpad: couldn't update recovery metadata File: \`${t}\` -Error: ${e.message}`,kind:"error",category:"system",duration:0,affectedPaths:[t],folder:this.noteFolder})}))}async ensureHomeNote(){let t=this.noteFolder,e=`${t}/${this.buildHomeFilename(t)}`,s=this.app.vault.getMarkdownFiles().filter(r=>r.path.startsWith(t+"/"));for(let r of s){if(this.app.metadataCache.getFileCache(r)?.frontmatter?.id!==B)continue;if(r.path===e||this.app.vault.getAbstractFileByPath(e))return r;try{await this.app.fileManager.renameFile(r,e);let l=this.app.vault.getAbstractFileByPath(e);if(l instanceof O.TFile)return l}catch(l){console.warn("[Stashpad] home note rename failed; keeping legacy path",l)}return r}let i=new Date().toISOString(),n=["---",`id: ${B}`,"parent: null",`created: ${i}`,"attachments: []","---","","# Home","","This is your Stashpad home note. Edit me freely \u2014 everything else nests below.",""].join(` -`);return this.app.vault.create(e,n)}buildHomeFilename(t){return`Home-${(t.split("/").filter(Boolean).pop()??"Stashpad").replace(/[^A-Za-z0-9_-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"Stashpad"}.md`}async migrateNullParents(){let t=this.noteFolder,e=this.app.vault.getMarkdownFiles().filter(s=>s.path.startsWith(t+"/"));for(let s of e){let i=this.app.metadataCache.getFileCache(s)?.frontmatter,n=i?.id;if(!n||n===B)continue;let r=i?.parent;(r==null||r===""||r==="null")&&(await this.app.fileManager.processFrontMatter(s,o=>{o.parent=B}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:B,reason:"migration"}}))}}async openInNewStashpadTab(t){let e=this.app.workspace,s=this.leaf,i=e.getLeaf("tab");await i.setViewState({type:vt,active:!0,state:{focusId:t,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i);let n=e.on("active-leaf-change",()=>{if((()=>{let a=!1;return e.iterateAllLeaves(l=>{l===i&&(a=!0)}),a})())return;e.offref(n),(()=>{let a=!1;return e.iterateAllLeaves(l=>{l===s&&(a=!0)}),a})()&&(e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s))})}async openFolderInNewTab(t){let e=(t||"").trim().replace(/^\/+|\/+$/g,"");if(!e)return;let s=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",i=this.app.workspace,n=this.leaf,r=i.getLeaf("tab");await r.setViewState({type:vt,active:!0,state:{focusId:B,folderOverride:e===s?null:e}}),i.setActiveLeaf(r,{focus:!0}),i.revealLeaf(r);let o=i.on("active-leaf-change",()=>{if((()=>{let c=!1;return i.iterateAllLeaves(d=>{d===r&&(c=!0)}),c})())return;i.offref(o),(()=>{let c=!1;return i.iterateAllLeaves(d=>{d===n&&(c=!0)}),c})()&&(i.setActiveLeaf(n,{focus:!0}),i.revealLeaf(n))})}cmdOpenInEditor(t){if(t){this.openFileAtEnd(t.file);return}let e=this.getActionTargets();if(e.length)for(let s of e)s.file&&this.openFileAtEnd(s.file)}cmdOpenParentInEditor(){let t=this.tree.get(this.focusId);if(!t?.file){new O.Notice("No focused parent to open.");return}this.openFileAtEnd(t.file)}async openFileAtEnd(t){let e=this.app.workspace,s=this.leaf,i=e.getLeaf("tab");await i.openFile(t,{active:!0}),e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i);let n=e.on("active-leaf-change",()=>{if((()=>{let c=!1;return e.iterateAllLeaves(d=>{d===i&&(c=!0)}),c})())return;e.offref(n),(()=>{let c=!1;return e.iterateAllLeaves(d=>{d===s&&(c=!0)}),c})()&&(e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s))}),o=i.view?.editor;o&&requestAnimationFrame(()=>{try{let a=o.lastLine(),l=o.getLine(a)?.length??0;o.setCursor({line:a,ch:l}),o.scrollIntoView({from:{line:a,ch:l},to:{line:a,ch:l}},!0),o.focus()}catch{}})}cmdSelectAll(){if(this.currentChildren.length!==0){this.selection.clear();for(let t of this.currentChildren)this.selection.add(t.id);this.firstSelectedId=this.currentChildren[0].id,this.lastSelected=this.currentChildren[this.currentChildren.length-1].id,this.cursorIdx=this.currentChildren.length-1,this.render()}}async cmdTogglePin(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new O.Notice("Nothing to pin.");return}let e=t.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),s=0,i=0;for(let n of t){let r={folder:this.noteFolder,id:n.id};e?this.plugin.isPinned(r)||(await this.plugin.pinNote(r),s++):this.plugin.isPinned(r)&&(await this.plugin.unpinNote(r),i++)}s>0?new O.Notice(`Pinned ${s} note${s===1?"":"s"} to sidebar.`):i>0&&new O.Notice(`Unpinned ${i} note${i===1?"":"s"} from sidebar.`)}async cmdToggleComplete(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new O.Notice("Nothing to toggle.");return}let s=t.some(o=>!this.isCompleted(o)),i=[],n=[];for(let o of t){if(!o.file)continue;let a=this.isCompleted(o);i.push({id:o.id,path:o.file.path,was:a}),a!==s&&(await this.app.fileManager.processFrontMatter(o.file,l=>{s?l.completed=!0:delete l.completed}),this.completedState.set(o.file.path,s),n.push(o.id))}if(this.render(),n.length>0){await this.log.append({type:s?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let o=n.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:s?"Marked complete":"Unmarked",nodes:o}),kind:"success",category:s?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let r=this.noteFolder;this.plugin.getUndoStack(r).push({label:`${s?"Mark complete":"Unmark complete"} (${t.length})`,undo:async()=>{let o=[];for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);l&&(await this.app.fileManager.processFrontMatter(l,c=>{a.was?c.completed=!0:delete c.completed}),n.includes(a.id)&&o.push(a.id))}o.length>0&&await this.log.append({type:s?"uncomplete":"complete",id:o[0],payload:{ids:o,count:o.length,undo:!0}}),this.tree.rebuild(r),this.render()},redo:async()=>{for(let o of i){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{s?l.completed=!0:delete l.completed})}n.length>0&&await this.log.append({type:s?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length,redo:!0}}),this.tree.rebuild(r),this.render()}})}isCompleted(t){if(!t.file)return!1;let e=t.file.path,s=this.completedState.get(e);if(s!==void 0)return s;let n=!!this.app.metadataCache.getFileCache(t.file)?.frontmatter?.completed;return this.completedState.set(e,n),n}cmdSetDue(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new O.Notice("Nothing to schedule.");return}let e=t[0],s=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,i=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null;new le(this.app,i,n=>{this.applyDue(t,n)}).open()}async applyDue(t,e){let s=[],i=[];for(let r of t){if(!r.file)continue;let o=this.app.metadataCache.getFileCache(r.file)?.frontmatter;s.push({id:r.id,path:r.file.path,due:o?.due,task:o?.task}),await this.app.fileManager.processFrontMatter(r.file,a=>{e===null?delete a.due:(a.due=e,a.task=!0)}),i.push(r.id)}if(this.render(),i.length>0){let r=i.map(o=>this.tree.get(o)).filter(o=>!!o);this.plugin.notifications.show({message:this.bulkActionMessage({verb:e===null?"Cleared due date":`Due ${Ut(Date.parse(e),this.plugin.settings)}`,nodes:r}),kind:"success",category:"edit",affectedIds:i,folder:this.noteFolder})}let n=this.noteFolder;this.plugin.getUndoStack(n).push({label:e===null?`Clear due date (${t.length})`:`Set due date (${t.length})`,undo:async()=>{for(let r of s){let o=this.app.vault.getAbstractFileByPath(r.path);o&&await this.app.fileManager.processFrontMatter(o,a=>{r.due===void 0?delete a.due:a.due=r.due,r.task===void 0?delete a.task:a.task=r.task})}this.tree.rebuild(n),this.render()}})}isTask(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?jt(e,"task")||e.task===!0||e.completed!==void 0:!1}async cmdToggleTask(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new O.Notice("Nothing to toggle.");return}let e=t.some(o=>!this.isTaskTagged(o)),s=[],i=[];for(let o of t){if(!o.file)continue;let a=this.isTaskTagged(o),l=this.app.metadataCache.getFileCache(o.file)?.frontmatter;if(s.push({id:o.id,path:o.file.path,tags:l?.tags,completed:l?.completed,task:l?.task}),a===e)continue;let c=!1;await this.app.fileManager.processFrontMatter(o.file,d=>{e?(os(d,"task"),d.completed===void 0&&(d.completed=!1),c=d.completed===!0,delete d.task):(ls(d,"task"),delete d.completed,delete d.task,c=!1)}),this.completedState.set(o.file.path,c),i.push(o.id)}if(this.render(),i.length>0){let o=e?"marked as task":"unmarked as task",a;if(i.length===1){let l=this.tree.get(i[0]);a=`"${l&&this.titleForNode(l).trim()||"(untitled)"}" ${o}`}else a=`${i.length} notes ${o}`;this.plugin.notifications.show({message:a,kind:"success",category:"edit",affectedIds:i,folder:this.noteFolder})}let n=this.noteFolder,r=async()=>{for(let o of s){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{o.tags===void 0?delete l.tags:l.tags=o.tags,o.completed===void 0?delete l.completed:l.completed=o.completed,o.task===void 0?delete l.task:l.task=o.task})}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${e?"Mark task":"Unmark task"} (${t.length})`,undo:r,redo:async()=>{for(let o of s){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{e?(os(l,"task"),l.completed===void 0&&(l.completed=!1),delete l.task):(ls(l,"task"),delete l.completed,delete l.task)})}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(t){if(!t.file)return;let e=t.file.path,s=this.isCompleted(t);await this.app.fileManager.processFrontMatter(t.file,n=>{n.completed=!s}),this.completedState.set(e,!s),await this.log.append({type:s?"uncomplete":"complete",id:t.id}),this.render();let i=this.noteFolder;this.plugin.getUndoStack(i).push({label:s?"Mark incomplete":"Mark complete",undo:async()=>{let n=this.app.vault.getAbstractFileByPath(e);n&&(await this.app.fileManager.processFrontMatter(n,r=>{r.completed=s}),this.tree.rebuild(i),this.render())}})}isTaskTagged(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?jt(e,"task")||e.task===!0:!1}colorForNode(t){if(!t.file)return null;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.color;if(typeof e!="string")return null;let s=e.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(s)?s:null}inheritedColorForNode(t){let e=t,s=0;for(;e&&e.id!==B;){let i=this.colorForNode(e);if(i)return{hex:i,depth:s};e=e.parent?this.tree.get(e.parent):void 0,s+=1}return null}attachRowDnD(t,e,s){t.addEventListener("dragstart",i=>{let n=this.selection.has(e.id)&&this.selection.size>1?[...this.selection]:[e.id];if(this.dragSourceIds=n,this.dragRowHeight=t.offsetHeight,t.addClass("is-dragging"),this.listEl&&(this.dragPlaceholder=this.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.style.height="0px",this.dragPlaceholder.addEventListener("dragover",r=>{this.dragSourceIds&&(r.preventDefault(),r.dataTransfer&&(r.dataTransfer.dropEffect="move"))}),this.dragPlaceholder.addEventListener("drop",r=>{if(!this.dragSourceIds||!this.dragPlaceholder)return;r.preventDefault(),r.stopPropagation();let o=this.dragSourceIds.slice();this.dragSourceIds=null;let a=this.dragPlaceholder.nextElementSibling,l=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,d="before";a&&a.classList.contains("stashpad-note")?(c=a.dataset.id,d="before"):l&&l.classList.contains("stashpad-note")&&(c=l.dataset.id,d="after"),c&&this.reorderToTarget(o,c,d)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",n.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(t,12,12)}catch{}}}),t.addEventListener("dragend",()=>{t.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),t.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let n=this.dropZone(i,t);this.clearDropIndicators(),n==="drop-into"?(this.removeDragPlaceholder(),t.addClass("drop-into")):(t.removeClass("drop-into"),this.placePlaceholder(t,n==="drop-above"?"before":"after"))}),t.addEventListener("dragleave",i=>{let n=t.getBoundingClientRect();(i.clientX<n.left||i.clientX>n.right||i.clientY<n.top||i.clientY>n.bottom)&&t.removeClass("drop-into")}),t.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let n=this.dragSourceIds.slice();this.dragSourceIds=null;let r=this.dropZone(i,t);this.clearDropIndicators(),this.removeDragPlaceholder(),t.removeClass("is-dragging"),r==="drop-into"?this.reorderToTarget(n,e.id,"into"):this.reorderToTarget(n,e.id,r==="drop-above"?"before":"after")})}placePlaceholder(t,e){if(!this.dragPlaceholder||!this.listEl)return;let s=e==="before"?t:t.nextSibling;if(e==="before"&&this.dragPlaceholder.nextSibling===t||e==="after"&&this.dragPlaceholder.previousSibling===t)return;let i=!!this.dragPlaceholder.parentElement;this.listEl.insertBefore(this.dragPlaceholder,s),this.dragPlaceholder.style.opacity="1",i?this.dragPlaceholder.style.height=`${this.dragRowHeight}px`:(this.dragPlaceholder.style.height="0px",this.dragPlaceholder.offsetHeight,this.dragPlaceholder.style.height=`${this.dragRowHeight}px`)}removeDragPlaceholder(){if(!this.dragPlaceholder?.parentElement)return;let t=this.dragPlaceholder;t.style.height="0px",t.style.opacity="0",setTimeout(()=>{t.parentElement&&t.remove()},150)}dropZone(t,e){let s=e.getBoundingClientRect(),i=t.clientY-s.top;return i<s.height*.3?"drop-above":i>s.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.listEl)for(let t of Array.from(this.listEl.querySelectorAll(".drop-into")))t.removeClass("drop-into")}isDescendant(t,e){let s=this.tree.get(t),i=new Set;for(;s&&s.parent&&!i.has(s.id);){if(s.parent===e)return!0;i.add(s.id),s=this.tree.get(s.parent)}return!1}async moveAcrossThenReorder(t,e,s,i){let n=[],r=new Set;for(let D of t){let $=this.tree.get(D);$?.file&&(n.push({id:D,path:$.file.path,oldParent:$.parent}),r.add($.parent??B))}r.add(e);let o=this.collectAuthorIds(t.map(D=>this.tree.get(D)).filter(D=>!!D)),a=this.noteFolder,l={};for(let D of r)l[D]=this.order.getOrder(a,D).slice();for(let D of n){let $=this.app.vault.getAbstractFileByPath(D.path);$&&(await this.app.fileManager.processFrontMatter($,F=>{F.parent=e}),this.fmSync.scheduleParentChange(D.id,D.oldParent,e),await this.log.append({type:"parent_change",id:D.id,payload:{from:D.oldParent,to:e,reason:"drag"}}),this.order.removeChild(a,D.id))}this.tree.rebuild(a);let c=this.tree.getChildren(e).map(D=>D.id),d=new Set(t),p=c.filter(D=>!d.has(D)),h=p.indexOf(s);h<0&&(h=p.length),i==="after"&&(h+=1);let u=[...p.slice(0,h),...t.filter(D=>!!this.tree.get(D)),...p.slice(h)];this.order.setOrder(a,e,u),await this.order.save(a),await this.forceManualMode(e),await this.log.append({type:"reorder",id:e,payload:{dir:"drag-cross",parent:e,ids:t,count:t.length}});let m=this.focusId===e,g=m?t[0]:e,y=m?t.slice():[e];m?this.pendingFocusIds=y:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=y),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let S=this.selectionGuardKey,k=()=>{if(this.selectionGuardKey!==S||this.selection.has(g))return;let D=this.currentChildren.findIndex($=>$.id===g);D<0||(this.selection.add(g),this.cursorIdx=D,this.render({kind:"follow-cursor"}))};setTimeout(k,120),setTimeout(k,400);let x=t.map(D=>this.tree.get(D)).filter(D=>!!D),I=this.tree.get(e),E=I?this.titleForNode(I):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reparented",nodes:x,destination:`\u2192 "${E}"`}),kind:"success",category:"move",affectedIds:t,affectedAuthorIds:o,folder:a,actions:e===B?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]}),this.plugin.getUndoStack(a).push({label:`Move + reorder (${t.length})`,undo:async()=>{for(let D of n){let $=this.app.vault.getAbstractFileByPath(D.path);$&&(await this.app.fileManager.processFrontMatter($,F=>{D.oldParent===null||D.oldParent===void 0?F.parent=B:F.parent=D.oldParent}),await this.log.append({type:"parent_change",id:D.id,payload:{from:e,to:D.oldParent,reason:"drag-undo"}}))}for(let[D,$]of Object.entries(l))if($.length===0){let F=this.order.cache.get(a)??{};delete F[D],this.order.cache.set(a,F)}else this.order.setOrder(a,D,$);await this.order.save(a),this.pendingFocusIds=t.slice(),this.selection.clear(),this.cursorIdx=-1,this.tree.rebuild(a),this.render()},redo:async()=>{for(let D of n){let $=this.app.vault.getAbstractFileByPath(D.path);$&&(await this.app.fileManager.processFrontMatter($,F=>{F.parent=e}),this.order.removeChild(a,D.id))}this.order.setOrder(a,e,u),await this.order.save(a),this.pendingFocusIds=t.slice(),this.focusId!==e&&(this.selection.clear(),this.cursorIdx=-1),this.tree.rebuild(a),this.render()}})}async reorderToTarget(t,e,s){let i=this.tree.get(e);if(!i)return;let n=t.map(S=>this.tree.get(S)).filter(S=>!!S&&!!S.file);if(n.length===0)return;if(n.some(S=>S.id===e)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}if(s==="into"){for(let S of n)if(this.isDescendant(e,S.id)){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(S)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}}let r=s==="into"?e:i.parent??B;if(n.some(S=>(S.parent??B)!==r)){let S=kt(),k=async()=>{s==="into"?await this.moveAcrossThenReorder(n.map(x=>x.id),r,"","after"):await this.moveAcrossThenReorder(n.map(x=>x.id),r,e,s)};if(S.confirmCrossParentDrag){let x=this.titleForNode(i),I=n.length,E=s==="into"?"Nest":"Move",D=s==="into"?"as children of":"under";new Mt(this.app,s==="into"?"Nest under target?":"Move under different parent?",`${E} ${I} note${I===1?"":"s"} ${D} "${x}"? Their parent will change.`,E,$=>{$&&k()}).open()}else await k();return}let a=r,l=n.map(S=>S.id),c=this.tree.getChildren(a).map(S=>S.id),d=new Set(l),p=c.filter(S=>!d.has(S)),h=p.indexOf(e);if(h<0)return;s==="after"&&(h+=1);let u=[...p.slice(0,h),...l,...p.slice(h)];if(ei(u,c))return;let m=this.noteFolder,g=this.order.getOrder(m,a).slice();this.order.setOrder(m,a,u),await this.order.save(m),await this.forceManualMode(a),await this.log.append({type:"reorder",id:a,payload:{dir:"drag",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render();let y=l.map(S=>this.tree.get(S)).filter(S=>!!S);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:y}),kind:"success",category:"reorder",affectedIds:l,folder:m}),this.plugin.getUndoStack(m).push({label:`Reorder (drag, ${l.length})`,undo:async()=>{if(g.length===0){let S=this.order.cache.get(m)??{};delete S[a],this.order.cache.set(m,S)}else this.order.setOrder(m,a,g);await this.order.save(m),await this.log.append({type:"reorder",id:a,payload:{dir:"undo",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render()},redo:async()=>{this.order.setOrder(m,a,u),await this.order.save(m),await this.log.append({type:"reorder",id:a,payload:{dir:"redo:drag",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render()}})}cmdMoveUp(){this.reorderSelection("up")}cmdMoveDown(){this.reorderSelection("down")}cmdMoveToTop(){this.reorderSelection("top")}cmdMoveToBottom(){this.reorderSelection("bottom")}async reorderSelection(t){let e=[];if(this.selection.size>0){let d=[...this.selection].map(h=>this.tree.get(h)).filter(h=>!!h&&!!h.file);if(d.length===0)return;if(new Set(d.map(h=>h.parent)).size>1){new O.Notice("Reorder requires a single-parent selection.");return}e=d}else this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]&&(e=[this.currentChildren[this.cursorIdx]]);if(e.length===0){new O.Notice("Nothing to reorder.");return}let s=e[0].parent??B,i=this.tree.getChildren(s).map(d=>d.id);if(i.length===0)return;let n=new Set(e.map(d=>d.id)),r=i.filter(d=>n.has(d));if(r.length===0)return;let o=_i(i,r,t);if(ei(o,i))return;let a=this.noteFolder,l=this.order.getOrder(a,s).slice();this.order.setOrder(a,s,o),await this.order.save(a),await this.forceManualMode(s),await this.log.append({type:"reorder",id:s,payload:{dir:t,parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let c=r.map(d=>this.tree.get(d)).filter(d=>!!d);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:c,destination:t}),kind:"success",category:"reorder",affectedIds:r,folder:a}),this.plugin.getUndoStack(a).push({label:`Reorder (${t})`,undo:async()=>{if(l.length===0){let d=this.order.cache.get(a)??{};delete d[s],this.order.cache.set(a,d)}else this.order.setOrder(a,s,l);await this.order.save(a),await this.log.append({type:"reorder",id:s,payload:{dir:"undo",parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render()},redo:async()=>{this.order.setOrder(a,s,o),await this.order.save(a),await this.log.append({type:"reorder",id:s,payload:{dir:`redo:${t}`,parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render()}})}async cmdDelete(){let t=this.getActionTargets();if(t.length===0){let u=this.tree.get(this.focusId);u?.file&&(t=[u])}if(t.length===0){new O.Notice("Nothing selected to delete.");return}if(t.length===1){await this.deleteNote(t[0]);return}let e=[],s=new Set,i=u=>{if(!s.has(u.id)){s.add(u.id);for(let m of this.tree.getChildren(u.id))i(m);e.push(u)}};for(let u of t)i(u);let n=e.filter(u=>!!u.file),r=await Promise.all(n.map(u=>this.app.vault.read(u.file))),o=[];for(let u=0;u<n.length;u++){let m=n[u];o.push(...this.extractAttachments(this.stripFrontmatter(r[u])));let g=this.app.metadataCache.getFileCache(m.file)?.frontmatter;if(Array.isArray(g?.attachments))for(let y of g.attachments)typeof y=="string"&&y.trim()&&o.push(y)}let a=[...new Set(o)],l=e.length-t.length,c=async u=>{let m=await this.snapshotNotes(e,u),g=0;if(u)for(let P of a){let b=this.app.metadataCache.getFirstLinkpathDest(P,"");if(b)try{await this.app.fileManager.trashFile(b),await this.log.append({type:"attachment_remove",id:B,payload:{path:b.path}}),this.plugin.notifications.show({message:`Deleted attachment "${b.name}"`,kind:"warning",category:"attachment",affectedPaths:[b.path],folder:this.noteFolder}),g+=1}catch{}}let y=new Set;for(let P of e)P.parent&&y.add(P.parent);let S=this.collectAuthorIds(e),k=new Set(t.map(P=>P.id)),x=this.currentChildren.map((P,b)=>k.has(P.id)?b:-1).filter(P=>P>=0),I=x.length>0?x[0]:-1,E=null;if(I>=0){for(let P=I+1;P<this.currentChildren.length;P++)if(!k.has(this.currentChildren[P].id)){E=this.currentChildren[P].id;break}if(!E){for(let P=I-1;P>=0;P--)if(!k.has(this.currentChildren[P].id)){E=this.currentChildren[P].id;break}}}for(let P of e)if(P.file){try{await this.app.fileManager.trashFile(P.file)}catch{}await this.log.append({type:"delete",id:P.id,payload:{path:P.file.path,attachmentsRemoved:u?a:[]}})}this.selection.clear(),this.cursorIdx=-1,E&&(this.pendingFocusIds=[E]),this.tree.rebuild(this.noteFolder);for(let P of y)e.some(b=>b.id===P)||this.fmSync.scheduleParentOfDeleted(P);this.render({kind:"follow-cursor"});let D=g>0?` with ${g} attachment${g===1?"":"s"}`:"";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:D.trim()||void 0}),kind:"warning",category:"delete",affectedIds:t.map(P=>P.id),affectedAuthorIds:S,folder:this.noteFolder});let $=this.noteFolder,F=t.map(P=>P.id);this.plugin.getUndoStack($).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(m,F.slice())},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.trashNotesAndAttachments(m)}}),this.focusView()},d=kt(),p=d.confirmBulkDelete,h=a.length>0&&d.confirmAttachmentDelete;if(!p&&!h){await c(!1);return}new Zt(this.app,`${t.length} selected note${t.length===1?"":"s"}`,l,a.length,h,c).open()}async cmdSplit(t){let e=t??this.resolveActionTarget();if(!e?.file){new O.Notice("Pick a note to split.");return}let s=e.file,i=await this.app.vault.read(s),n=this.stripFrontmatter(i).replace(/\s+$/,""),r=n.split(/\r?\n/);if(n.trim().length<2){new O.Notice("Note is too short to split.");return}let o=i,a=s.path,l=async(c,d,p)=>{if(!c.trim()||!d.trim()){new O.Notice("Split would leave one part empty.");return}try{let h=i.startsWith("---")?i.slice(0,i.indexOf(` ----`,3)+4):"",u=h+(h?` +Error: ${e.message}`,kind:"error",category:"system",duration:0,affectedPaths:[t],folder:this.noteFolder})}))}async ensureHomeNote(){let t=this.noteFolder,e=`${t}/${this.buildHomeFilename(t)}`,s=this.app.vault.getMarkdownFiles().filter(r=>r.path.startsWith(t+"/"));for(let r of s){if(this.app.metadataCache.getFileCache(r)?.frontmatter?.id!==R)continue;if(r.path===e||this.app.vault.getAbstractFileByPath(e))return r;try{await this.app.fileManager.renameFile(r,e);let l=this.app.vault.getAbstractFileByPath(e);if(l instanceof N.TFile)return l}catch(l){console.warn("[Stashpad] home note rename failed; keeping legacy path",l)}return r}let i=new Date().toISOString(),n=["---",`id: ${R}`,"parent: null",`created: ${i}`,"attachments: []","---","","# Home","","This is your Stashpad home note. Edit me freely \u2014 everything else nests below.",""].join(` +`);return this.app.vault.create(e,n)}buildHomeFilename(t){return`Home-${(t.split("/").filter(Boolean).pop()??"Stashpad").replace(/[^A-Za-z0-9_-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"Stashpad"}.md`}async migrateNullParents(){let t=this.noteFolder,e=this.app.vault.getMarkdownFiles().filter(s=>s.path.startsWith(t+"/"));for(let s of e){let i=this.app.metadataCache.getFileCache(s)?.frontmatter,n=i?.id;if(!n||n===R)continue;let r=i?.parent;(r==null||r===""||r==="null")&&(await this.app.fileManager.processFrontMatter(s,o=>{o.parent=R}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:R,reason:"migration"}}))}}async openInNewStashpadTab(t){let e=this.app.workspace,s=this.leaf,i=e.getLeaf("tab");await i.setViewState({type:mt,active:!0,state:{focusId:t,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i);let n=e.on("active-leaf-change",()=>{if((()=>{let a=!1;return e.iterateAllLeaves(l=>{l===i&&(a=!0)}),a})())return;e.offref(n),(()=>{let a=!1;return e.iterateAllLeaves(l=>{l===s&&(a=!0)}),a})()&&(e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s))})}async openFolderInNewTab(t){let e=(t||"").trim().replace(/^\/+|\/+$/g,"");if(!e)return;let s=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",i=this.app.workspace,n=this.leaf,r=i.getLeaf("tab");await r.setViewState({type:mt,active:!0,state:{focusId:R,folderOverride:e===s?null:e}}),i.setActiveLeaf(r,{focus:!0}),i.revealLeaf(r);let o=i.on("active-leaf-change",()=>{if((()=>{let c=!1;return i.iterateAllLeaves(h=>{h===r&&(c=!0)}),c})())return;i.offref(o),(()=>{let c=!1;return i.iterateAllLeaves(h=>{h===n&&(c=!0)}),c})()&&(i.setActiveLeaf(n,{focus:!0}),i.revealLeaf(n))})}cmdOpenInEditor(t){if(t){this.openFileAtEnd(t.file);return}let e=this.getActionTargets();if(e.length)for(let s of e)s.file&&this.openFileAtEnd(s.file)}cmdOpenParentInEditor(){let t=this.tree.get(this.focusId);if(!t?.file){new N.Notice("No focused parent to open.");return}this.openFileAtEnd(t.file)}async openFileAtEnd(t){let e=this.app.workspace,s=this.leaf,i=e.getLeaf("tab");await i.openFile(t,{active:!0}),e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i);let n=e.on("active-leaf-change",()=>{if((()=>{let c=!1;return e.iterateAllLeaves(h=>{h===i&&(c=!0)}),c})())return;e.offref(n),(()=>{let c=!1;return e.iterateAllLeaves(h=>{h===s&&(c=!0)}),c})()&&(e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s))}),o=i.view?.editor;o&&requestAnimationFrame(()=>{try{let a=o.lastLine(),l=o.getLine(a)?.length??0;o.setCursor({line:a,ch:l}),o.scrollIntoView({from:{line:a,ch:l},to:{line:a,ch:l}},!0),o.focus()}catch{}})}cmdSelectAll(){if(this.currentChildren.length!==0){this.selection.clear();for(let t of this.currentChildren)this.selection.add(t.id);this.firstSelectedId=this.currentChildren[0].id,this.lastSelected=this.currentChildren[this.currentChildren.length-1].id,this.cursorIdx=this.currentChildren.length-1,this.render()}}async cmdTogglePin(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new N.Notice("Nothing to pin.");return}let e=t.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),s=0,i=0;for(let n of t){let r={folder:this.noteFolder,id:n.id};e?this.plugin.isPinned(r)||(await this.plugin.pinNote(r),s++):this.plugin.isPinned(r)&&(await this.plugin.unpinNote(r),i++)}s>0?new N.Notice(`Pinned ${s} note${s===1?"":"s"} to sidebar.`):i>0&&new N.Notice(`Unpinned ${i} note${i===1?"":"s"} from sidebar.`)}async cmdToggleComplete(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new N.Notice("Nothing to toggle.");return}let s=t.some(o=>!this.isCompleted(o)),i=[],n=[];for(let o of t){if(!o.file)continue;let a=this.isCompleted(o);i.push({id:o.id,path:o.file.path,was:a}),a!==s&&(await this.app.fileManager.processFrontMatter(o.file,l=>{s?l.completed=!0:delete l.completed}),this.completedState.set(o.file.path,s),n.push(o.id))}if(this.render(),n.length>0){await this.log.append({type:s?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let o=n.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:s?"Marked complete":"Unmarked",nodes:o}),kind:"success",category:s?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let r=this.noteFolder;this.plugin.getUndoStack(r).push({label:`${s?"Mark complete":"Unmark complete"} (${t.length})`,undo:async()=>{let o=[];for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);l&&(await this.app.fileManager.processFrontMatter(l,c=>{a.was?c.completed=!0:delete c.completed}),n.includes(a.id)&&o.push(a.id))}o.length>0&&await this.log.append({type:s?"uncomplete":"complete",id:o[0],payload:{ids:o,count:o.length,undo:!0}}),this.tree.rebuild(r),this.render()},redo:async()=>{for(let o of i){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{s?l.completed=!0:delete l.completed})}n.length>0&&await this.log.append({type:s?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length,redo:!0}}),this.tree.rebuild(r),this.render()}})}isCompleted(t){if(!t.file)return!1;let e=this.completedState.get(t.file.path);return e!==void 0?e:!!this.app.metadataCache.getFileCache(t.file)?.frontmatter?.completed}cmdSetDue(){let t=this.getActionTargets();if(t.length===0){let n=this.tree.get(this.focusId);n?.file&&(t=[n])}if(t.length===0){new N.Notice("Nothing to schedule.");return}let e=t[0],s=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,i=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null;new ce(this.app,i,n=>{this.applyDue(t,n)}).open()}async applyDue(t,e){let s=[],i=[];for(let r of t){if(!r.file)continue;let o=this.app.metadataCache.getFileCache(r.file)?.frontmatter;s.push({id:r.id,path:r.file.path,due:o?.due,task:o?.task}),await this.app.fileManager.processFrontMatter(r.file,a=>{e===null?delete a.due:(a.due=e,a.task=!0)}),i.push(r.id)}if(this.render(),i.length>0){let r=i.map(o=>this.tree.get(o)).filter(o=>!!o);this.plugin.notifications.show({message:this.bulkActionMessage({verb:e===null?"Cleared due date":`Due ${Wt(Date.parse(e),this.plugin.settings)}`,nodes:r}),kind:"success",category:"edit",affectedIds:i,folder:this.noteFolder})}let n=this.noteFolder;this.plugin.getUndoStack(n).push({label:e===null?`Clear due date (${t.length})`:`Set due date (${t.length})`,undo:async()=>{for(let r of s){let o=this.app.vault.getAbstractFileByPath(r.path);o&&await this.app.fileManager.processFrontMatter(o,a=>{r.due===void 0?delete a.due:a.due=r.due,r.task===void 0?delete a.task:a.task=r.task})}this.tree.rebuild(n),this.render()}})}isTask(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?zt(e,"task")||e.task===!0||e.completed!==void 0:!1}async cmdToggleTask(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new N.Notice("Nothing to toggle.");return}let e=t.some(o=>!this.isTaskTagged(o)),s=[],i=[];for(let o of t){if(!o.file)continue;let a=this.isTaskTagged(o),l=this.app.metadataCache.getFileCache(o.file)?.frontmatter;if(s.push({id:o.id,path:o.file.path,tags:l?.tags,completed:l?.completed,task:l?.task}),a===e)continue;let c=!1;await this.app.fileManager.processFrontMatter(o.file,h=>{e?(ds(h,"task"),h.completed===void 0&&(h.completed=!1),c=h.completed===!0,delete h.task):(hs(h,"task"),delete h.completed,delete h.task,c=!1)}),this.completedState.set(o.file.path,c),i.push(o.id)}if(this.render(),i.length>0){let o=e?"marked as task":"unmarked as task",a;if(i.length===1){let l=this.tree.get(i[0]);a=`"${l&&this.titleForNode(l).trim()||"(untitled)"}" ${o}`}else a=`${i.length} notes ${o}`;this.plugin.notifications.show({message:a,kind:"success",category:"edit",affectedIds:i,folder:this.noteFolder})}let n=this.noteFolder,r=async()=>{for(let o of s){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{o.tags===void 0?delete l.tags:l.tags=o.tags,o.completed===void 0?delete l.completed:l.completed=o.completed,o.task===void 0?delete l.task:l.task=o.task})}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${e?"Mark task":"Unmark task"} (${t.length})`,undo:r,redo:async()=>{for(let o of s){let a=this.app.vault.getAbstractFileByPath(o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{e?(ds(l,"task"),l.completed===void 0&&(l.completed=!1),delete l.task):(hs(l,"task"),delete l.completed,delete l.task)})}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(t){if(!t.file)return;let e=t.file.path,s=this.isCompleted(t);await this.app.fileManager.processFrontMatter(t.file,n=>{n.completed=!s}),this.completedState.set(e,!s),await this.log.append({type:s?"uncomplete":"complete",id:t.id}),this.render();let i=this.noteFolder;this.plugin.getUndoStack(i).push({label:s?"Mark incomplete":"Mark complete",undo:async()=>{let n=this.app.vault.getAbstractFileByPath(e);n&&(await this.app.fileManager.processFrontMatter(n,r=>{r.completed=s}),this.tree.rebuild(i),this.render())}})}isTaskTagged(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?zt(e,"task")||e.task===!0:!1}colorForNode(t){if(!t.file)return null;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.color;if(typeof e!="string")return null;let s=e.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(s)?s:null}inheritedColorForNode(t){let e=t,s=0;for(;e&&e.id!==R;){let i=this.colorForNode(e);if(i)return{hex:i,depth:s};e=e.parent?this.tree.get(e.parent):void 0,s+=1}return null}attachRowDnD(t,e,s){t.addEventListener("dragstart",i=>{let n=this.selection.has(e.id)&&this.selection.size>1?[...this.selection]:[e.id];if(this.dragSourceIds=n,this.dragRowHeight=t.offsetHeight,t.addClass("is-dragging"),this.listEl&&(this.dragPlaceholder=this.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.style.height="0px",this.dragPlaceholder.addEventListener("dragover",r=>{this.dragSourceIds&&(r.preventDefault(),r.dataTransfer&&(r.dataTransfer.dropEffect="move"))}),this.dragPlaceholder.addEventListener("drop",r=>{if(!this.dragSourceIds||!this.dragPlaceholder)return;r.preventDefault(),r.stopPropagation();let o=this.dragSourceIds.slice();this.dragSourceIds=null;let a=this.dragPlaceholder.nextElementSibling,l=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,h="before";a&&a.classList.contains("stashpad-note")?(c=a.dataset.id,h="before"):l&&l.classList.contains("stashpad-note")&&(c=l.dataset.id,h="after"),c&&this.reorderToTarget(o,c,h)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",n.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(t,12,12)}catch{}}}),t.addEventListener("dragend",()=>{t.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),t.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let n=this.dropZone(i,t);this.clearDropIndicators(),n==="drop-into"?(this.removeDragPlaceholder(),t.addClass("drop-into")):(t.removeClass("drop-into"),this.placePlaceholder(t,n==="drop-above"?"before":"after"))}),t.addEventListener("dragleave",i=>{let n=t.getBoundingClientRect();(i.clientX<n.left||i.clientX>n.right||i.clientY<n.top||i.clientY>n.bottom)&&t.removeClass("drop-into")}),t.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let n=this.dragSourceIds.slice();this.dragSourceIds=null;let r=this.dropZone(i,t);this.clearDropIndicators(),this.removeDragPlaceholder(),t.removeClass("is-dragging"),r==="drop-into"?this.reorderToTarget(n,e.id,"into"):this.reorderToTarget(n,e.id,r==="drop-above"?"before":"after")})}placePlaceholder(t,e){if(!this.dragPlaceholder||!this.listEl)return;let s=e==="before"?t:t.nextSibling;if(e==="before"&&this.dragPlaceholder.nextSibling===t||e==="after"&&this.dragPlaceholder.previousSibling===t)return;let i=!!this.dragPlaceholder.parentElement;this.listEl.insertBefore(this.dragPlaceholder,s),this.dragPlaceholder.style.opacity="1",i?this.dragPlaceholder.style.height=`${this.dragRowHeight}px`:(this.dragPlaceholder.style.height="0px",this.dragPlaceholder.offsetHeight,this.dragPlaceholder.style.height=`${this.dragRowHeight}px`)}removeDragPlaceholder(){if(!this.dragPlaceholder?.parentElement)return;let t=this.dragPlaceholder;t.style.height="0px",t.style.opacity="0",setTimeout(()=>{t.parentElement&&t.remove()},150)}dropZone(t,e){let s=e.getBoundingClientRect(),i=t.clientY-s.top;return i<s.height*.3?"drop-above":i>s.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.listEl)for(let t of Array.from(this.listEl.querySelectorAll(".drop-into")))t.removeClass("drop-into")}isDescendant(t,e){let s=this.tree.get(t),i=new Set;for(;s&&s.parent&&!i.has(s.id);){if(s.parent===e)return!0;i.add(s.id),s=this.tree.get(s.parent)}return!1}async moveAcrossThenReorder(t,e,s,i){let n=[],r=new Set;for(let A of t){let O=this.tree.get(A);O?.file&&(n.push({id:A,path:O.file.path,oldParent:O.parent}),r.add(O.parent??R))}r.add(e);let o=this.collectAuthorIds(t.map(A=>this.tree.get(A)).filter(A=>!!A)),a=this.noteFolder,l={};for(let A of r)l[A]=this.order.getOrder(a,A).slice();for(let A of n){let O=this.app.vault.getAbstractFileByPath(A.path);O&&(await this.app.fileManager.processFrontMatter(O,F=>{F.parent=e}),this.fmSync.scheduleParentChange(A.id,A.oldParent,e),await this.log.append({type:"parent_change",id:A.id,payload:{from:A.oldParent,to:e,reason:"drag"}}),this.order.removeChild(a,A.id))}this.tree.rebuild(a);let c=this.tree.getChildren(e).map(A=>A.id),h=new Set(t),u=c.filter(A=>!h.has(A)),d=u.indexOf(s);d<0&&(d=u.length),i==="after"&&(d+=1);let p=[...u.slice(0,d),...t.filter(A=>!!this.tree.get(A)),...u.slice(d)];this.order.setOrder(a,e,p),await this.order.save(a),await this.forceManualMode(e),await this.log.append({type:"reorder",id:e,payload:{dir:"drag-cross",parent:e,ids:t,count:t.length}});let m=this.focusId===e,v=m?t[0]:e,y=m?t.slice():[e];m?this.pendingFocusIds=y:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=y),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let b=this.selectionGuardKey,k=()=>{if(this.selectionGuardKey!==b||this.selection.has(v))return;let A=this.currentChildren.findIndex(O=>O.id===v);A<0||(this.selection.add(v),this.cursorIdx=A,this.render({kind:"follow-cursor"}))};setTimeout(k,120),setTimeout(k,400);let C=t.map(A=>this.tree.get(A)).filter(A=>!!A),E=this.tree.get(e),I=E?this.titleForNode(E):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reparented",nodes:C,destination:`\u2192 "${I}"`}),kind:"success",category:"move",affectedIds:t,affectedAuthorIds:o,folder:a,actions:e===R?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]}),this.plugin.getUndoStack(a).push({label:`Move + reorder (${t.length})`,undo:async()=>{for(let A of n){let O=this.app.vault.getAbstractFileByPath(A.path);O&&(await this.app.fileManager.processFrontMatter(O,F=>{A.oldParent===null||A.oldParent===void 0?F.parent=R:F.parent=A.oldParent}),await this.log.append({type:"parent_change",id:A.id,payload:{from:e,to:A.oldParent,reason:"drag-undo"}}))}for(let[A,O]of Object.entries(l))if(O.length===0){let F=this.order.cache.get(a)??{};delete F[A],this.order.cache.set(a,F)}else this.order.setOrder(a,A,O);await this.order.save(a),this.pendingFocusIds=t.slice(),this.selection.clear(),this.cursorIdx=-1,this.tree.rebuild(a),this.render()},redo:async()=>{for(let A of n){let O=this.app.vault.getAbstractFileByPath(A.path);O&&(await this.app.fileManager.processFrontMatter(O,F=>{F.parent=e}),this.order.removeChild(a,A.id))}this.order.setOrder(a,e,p),await this.order.save(a),this.pendingFocusIds=t.slice(),this.focusId!==e&&(this.selection.clear(),this.cursorIdx=-1),this.tree.rebuild(a),this.render()}})}async reorderToTarget(t,e,s){let i=this.tree.get(e);if(!i)return;let n=t.map(b=>this.tree.get(b)).filter(b=>!!b&&!!b.file);if(n.length===0)return;if(n.some(b=>b.id===e)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}if(s==="into"){for(let b of n)if(this.isDescendant(e,b.id)){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(b)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}}let r=s==="into"?e:i.parent??R;if(n.some(b=>(b.parent??R)!==r)){let b=wt(),k=async()=>{s==="into"?await this.moveAcrossThenReorder(n.map(C=>C.id),r,"","after"):await this.moveAcrossThenReorder(n.map(C=>C.id),r,e,s)};if(b.confirmCrossParentDrag){let C=this.titleForNode(i),E=n.length,I=s==="into"?"Nest":"Move",A=s==="into"?"as children of":"under";new Ft(this.app,s==="into"?"Nest under target?":"Move under different parent?",`${I} ${E} note${E===1?"":"s"} ${A} "${C}"? Their parent will change.`,I,O=>{O&&k()}).open()}else await k();return}let a=r,l=n.map(b=>b.id),c=this.tree.getChildren(a).map(b=>b.id),h=new Set(l),u=c.filter(b=>!h.has(b)),d=u.indexOf(e);if(d<0)return;s==="after"&&(d+=1);let p=[...u.slice(0,d),...l,...u.slice(d)];if(oi(p,c))return;let m=this.noteFolder,v=this.order.getOrder(m,a).slice();this.order.setOrder(m,a,p),await this.order.save(m),await this.forceManualMode(a),await this.log.append({type:"reorder",id:a,payload:{dir:"drag",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render();let y=l.map(b=>this.tree.get(b)).filter(b=>!!b);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:y}),kind:"success",category:"reorder",affectedIds:l,folder:m}),this.plugin.getUndoStack(m).push({label:`Reorder (drag, ${l.length})`,undo:async()=>{if(v.length===0){let b=this.order.cache.get(m)??{};delete b[a],this.order.cache.set(m,b)}else this.order.setOrder(m,a,v);await this.order.save(m),await this.log.append({type:"reorder",id:a,payload:{dir:"undo",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render()},redo:async()=>{this.order.setOrder(m,a,p),await this.order.save(m),await this.log.append({type:"reorder",id:a,payload:{dir:"redo:drag",parent:a,ids:l,count:l.length}}),this.pendingFocusIds=l.slice(),this.tree.rebuild(m),this.render()}})}cmdMoveUp(){this.reorderSelection("up")}cmdMoveDown(){this.reorderSelection("down")}cmdMoveToTop(){this.reorderSelection("top")}cmdMoveToBottom(){this.reorderSelection("bottom")}async reorderSelection(t){let e=[];if(this.selection.size>0){let h=[...this.selection].map(d=>this.tree.get(d)).filter(d=>!!d&&!!d.file);if(h.length===0)return;if(new Set(h.map(d=>d.parent)).size>1){new N.Notice("Reorder requires a single-parent selection.");return}e=h}else this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]&&(e=[this.currentChildren[this.cursorIdx]]);if(e.length===0){new N.Notice("Nothing to reorder.");return}let s=e[0].parent??R,i=this.tree.getChildren(s).map(h=>h.id);if(i.length===0)return;let n=new Set(e.map(h=>h.id)),r=i.filter(h=>n.has(h));if(r.length===0)return;let o=Hi(i,r,t);if(oi(o,i))return;let a=this.noteFolder,l=this.order.getOrder(a,s).slice();this.order.setOrder(a,s,o),await this.order.save(a),await this.forceManualMode(s),await this.log.append({type:"reorder",id:s,payload:{dir:t,parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let c=r.map(h=>this.tree.get(h)).filter(h=>!!h);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:c,destination:t}),kind:"success",category:"reorder",affectedIds:r,folder:a}),this.plugin.getUndoStack(a).push({label:`Reorder (${t})`,undo:async()=>{if(l.length===0){let h=this.order.cache.get(a)??{};delete h[s],this.order.cache.set(a,h)}else this.order.setOrder(a,s,l);await this.order.save(a),await this.log.append({type:"reorder",id:s,payload:{dir:"undo",parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render()},redo:async()=>{this.order.setOrder(a,s,o),await this.order.save(a),await this.log.append({type:"reorder",id:s,payload:{dir:`redo:${t}`,parent:s,ids:r,count:r.length}}),this.pendingFocusIds=r.slice(),this.tree.rebuild(a),this.render()}})}async cmdDelete(){let t=this.getActionTargets();if(t.length===0){let p=this.tree.get(this.focusId);p?.file&&(t=[p])}if(t.length===0){new N.Notice("Nothing selected to delete.");return}if(t.length===1){await this.deleteNote(t[0]);return}let e=[],s=new Set,i=p=>{if(!s.has(p.id)){s.add(p.id);for(let m of this.tree.getChildren(p.id))i(m);e.push(p)}};for(let p of t)i(p);let n=e.filter(p=>!!p.file),r=await Promise.all(n.map(p=>this.app.vault.read(p.file))),o=[];for(let p=0;p<n.length;p++){let m=n[p];o.push(...this.extractAttachments(this.stripFrontmatter(r[p])));let v=this.app.metadataCache.getFileCache(m.file)?.frontmatter;if(Array.isArray(v?.attachments))for(let y of v.attachments)typeof y=="string"&&y.trim()&&o.push(y)}let a=[...new Set(o)],l=e.length-t.length,c=async p=>{let m=await this.snapshotNotes(e,p),v=0;if(p)for(let D of a){let S=this.app.metadataCache.getFirstLinkpathDest(D,"");if(S)try{await this.app.fileManager.trashFile(S),await this.log.append({type:"attachment_remove",id:R,payload:{path:S.path}}),this.plugin.notifications.show({message:`Deleted attachment "${S.name}"`,kind:"warning",category:"attachment",affectedPaths:[S.path],folder:this.noteFolder}),v+=1}catch{}}let y=new Set;for(let D of e)D.parent&&y.add(D.parent);let b=this.collectAuthorIds(e),k=new Set(t.map(D=>D.id)),C=this.currentChildren.map((D,S)=>k.has(D.id)?S:-1).filter(D=>D>=0),E=C.length>0?C[0]:-1,I=null;if(E>=0){for(let D=E+1;D<this.currentChildren.length;D++)if(!k.has(this.currentChildren[D].id)){I=this.currentChildren[D].id;break}if(!I){for(let D=E-1;D>=0;D--)if(!k.has(this.currentChildren[D].id)){I=this.currentChildren[D].id;break}}}for(let D of e)if(D.file){try{await this.app.fileManager.trashFile(D.file)}catch{}await this.log.append({type:"delete",id:D.id,payload:{path:D.file.path,attachmentsRemoved:p?a:[]}})}this.selection.clear(),this.cursorIdx=-1,I&&(this.pendingFocusIds=[I]),this.tree.rebuild(this.noteFolder);for(let D of y)e.some(S=>S.id===D)||this.fmSync.scheduleParentOfDeleted(D);this.render({kind:"follow-cursor"});let A=v>0?` with ${v} attachment${v===1?"":"s"}`:"";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:A.trim()||void 0}),kind:"warning",category:"delete",affectedIds:t.map(D=>D.id),affectedAuthorIds:b,folder:this.noteFolder});let O=this.noteFolder,F=t.map(D=>D.id);this.plugin.getUndoStack(O).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(m,F.slice())},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.trashNotesAndAttachments(m)}}),this.focusView()},h=wt(),u=h.confirmBulkDelete,d=a.length>0&&h.confirmAttachmentDelete;if(!u&&!d){await c(!1);return}new Zt(this.app,`${t.length} selected note${t.length===1?"":"s"}`,l,a.length,d,c).open()}async cmdSplit(t){let e=t??this.resolveActionTarget();if(!e?.file){new N.Notice("Pick a note to split.");return}let s=e.file,i=await this.app.vault.read(s),n=this.stripFrontmatter(i).replace(/\s+$/,""),r=n.split(/\r?\n/);if(n.trim().length<2){new N.Notice("Note is too short to split.");return}let o=i,a=s.path,l=async(c,h,u)=>{if(!c.trim()||!h.trim()){new N.Notice("Split would leave one part empty.");return}try{let d=i.startsWith("---")?i.slice(0,i.indexOf(` +---`,3)+4):"",p=d+(d?` `:"")+c+` -`;await this.app.vault.modify(s,u);let m=e.parent??B,g=Date.parse(e.created||""),y=Number.isFinite(g)?new Date(g+1).toISOString():new Date().toISOString(),S=await this.createNoteUnder(d,m,{record:!1,createdOverride:y});await this.log.append({type:"rename",id:e.id,payload:{action:"split",into:S,...p}}),this.tree.rebuild(this.noteFolder),this.render(),this.plugin.notifications.show({message:`Split "${this.titleForNode(e)}" into two`,kind:"success",category:"split",affectedIds:[e.id],folder:this.noteFolder});let k=S?this.tree.get(S):void 0,x=k?.file?.path,I=x?await this.app.vault.read(k.file):null,E=this.noteFolder;this.plugin.getUndoStack(E).push({label:"Split note",undo:async()=>{if(x){let $=this.app.vault.getAbstractFileByPath(x);if($)try{await this.app.fileManager.trashFile($)}catch{}}let D=this.app.vault.getAbstractFileByPath(a);D&&await this.app.vault.modify(D,o),this.tree.rebuild(E),this.render()},redo:async()=>{let D=this.app.vault.getAbstractFileByPath(a);D&&await this.app.vault.modify(D,u),x&&I&&!await this.app.vault.adapter.exists(x)&&await this.app.vault.create(x,I),this.tree.rebuild(E),this.render()}})}catch(h){new O.Notice(`Stashpad: split failed (${h.message})`),console.error(h)}};new oe(this.app,n,async c=>{let d=r.slice(0,c).join(` -`).replace(/\s+$/,""),p=r.slice(c).join(` -`).replace(/^\s+|\s+$/g,"");await l(d,p,{mode:"line",splitAtLine:c})},async c=>{let d=n.slice(0,c).replace(/\s+$/,""),p=n.slice(c).replace(/^\s+|\s+$/g,"");await l(d,p,{mode:"cursor",splitAtChar:c})}).open()}cmdOpenInNewStashpadTab(t){let e=t??this.resolveActionTarget();e?.file&&this.openInNewStashpadTab(e.id)}cmdCloneStashpadTab(){let t=this.tree.get(this.focusId);t?.file?this.cmdOpenInNewStashpadTab(t):this.openInNewStashpadTab(this.focusId)}resolveActionTarget(){if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return this.currentChildren[this.cursorIdx];let t=this.tree.get(this.focusId);return t?.file?t:void 0}async cmdExportStash(t){let e=this.collectExportRoots(t);if(e.length===0){new O.Notice("Nothing to export.");return}let s=this.collectExportSubtree(e);if(s.length===0){new O.Notice("No exportable notes (no files attached).");return}try{let i=await Js(this.app,{rootNotes:e.filter(p=>!!p.file).map(p=>({id:p.id,file:p.file})),allDescendants:s.filter(p=>!e.some(h=>h.id===p.id)).filter(p=>!!p.file).map(p=>({id:p.id,file:p.file})),sourceFolder:this.noteFolder}),n=(0,O.moment)().format("YYYYMMDD-HHmmss"),r=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),a=(e.length===1?this.titleForNode(e[0]):`${r}-${e.length}notes`).replace(/[^\w.\-]+/g,"_").slice(0,60)||"stash-export",l=(this.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),c=`${this.noteFolder}/${l}`;await this.ensureFolder(c);let d=`${c}/${a}-${n}.${ve}`;await this.app.vault.createBinary(d,i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength)),await this.log.append({type:"stash_export",id:e[0].id,payload:{path:d,noteCount:s.length,rootIds:e.map(p=>p.id)}}),this.plugin.notifications.show({message:`Exported ${s.length} note${s.length===1?"":"s"} \u2192 \`${d}\``,kind:"success",category:"export",affectedPaths:[d],folder:this.noteFolder,actions:this.actionsForFile(d),duration:0})}catch(i){this.plugin.notifications.show({message:`Stashpad: export failed +`;await this.app.vault.modify(s,p);let m=e.parent??R,v=Date.parse(e.created||""),y=Number.isFinite(v)?new Date(v+1).toISOString():new Date().toISOString(),b=await this.createNoteUnder(h,m,{record:!1,createdOverride:y});await this.log.append({type:"rename",id:e.id,payload:{action:"split",into:b,...u}}),this.tree.rebuild(this.noteFolder),this.render(),this.suppressComposerFocusUntil=Date.now()+500,this.viewRoot?.focus({preventScroll:!0}),this.plugin.notifications.show({message:`Split "${this.titleForNode(e)}" into two`,kind:"success",category:"split",affectedIds:[e.id],folder:this.noteFolder});let k=b?this.tree.get(b):void 0,C=k?.file?.path,E=C?await this.app.vault.read(k.file):null,I=this.noteFolder;this.plugin.getUndoStack(I).push({label:"Split note",undo:async()=>{if(C){let O=this.app.vault.getAbstractFileByPath(C);if(O)try{await this.app.fileManager.trashFile(O)}catch{}}let A=this.app.vault.getAbstractFileByPath(a);A&&await this.app.vault.modify(A,o),this.tree.rebuild(I),this.render()},redo:async()=>{let A=this.app.vault.getAbstractFileByPath(a);A&&await this.app.vault.modify(A,p),C&&E&&!await this.app.vault.adapter.exists(C)&&await this.app.vault.create(C,E),this.tree.rebuild(I),this.render()}})}catch(d){new N.Notice(`Stashpad: split failed (${d.message})`),console.error(d)}};new le(this.app,n,async c=>{let h=r.slice(0,c).join(` +`).replace(/\s+$/,""),u=r.slice(c).join(` +`).replace(/^\s+|\s+$/g,"");await l(h,u,{mode:"line",splitAtLine:c})},async c=>{let h=n.slice(0,c).replace(/\s+$/,""),u=n.slice(c).replace(/^\s+|\s+$/g,"");await l(h,u,{mode:"cursor",splitAtChar:c})}).open()}cmdOpenInNewStashpadTab(t){let e=t??this.resolveActionTarget();e?.file&&this.openInNewStashpadTab(e.id)}cmdCloneStashpadTab(){let t=this.tree.get(this.focusId);t?.file?this.cmdOpenInNewStashpadTab(t):this.openInNewStashpadTab(this.focusId)}resolveActionTarget(){if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return this.currentChildren[this.cursorIdx];let t=this.tree.get(this.focusId);return t?.file?t:void 0}async cmdExportStash(t){let e=this.collectExportRoots(t);if(e.length===0){new N.Notice("Nothing to export.");return}let s=this.collectExportSubtree(e);if(s.length===0){new N.Notice("No exportable notes (no files attached).");return}try{let i=await ii(this.app,{rootNotes:e.filter(u=>!!u.file).map(u=>({id:u.id,file:u.file})),allDescendants:s.filter(u=>!e.some(d=>d.id===u.id)).filter(u=>!!u.file).map(u=>({id:u.id,file:u.file})),sourceFolder:this.noteFolder}),n=(0,N.moment)().format("YYYYMMDD-HHmmss"),r=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),a=(e.length===1?this.titleForNode(e[0]):`${r}-${e.length}notes`).replace(/[^\w.\-]+/g,"_").slice(0,60)||"stash-export",l=(this.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),c=`${this.noteFolder}/${l}`;await this.ensureFolder(c);let h=`${c}/${a}-${n}.${ye}`;await this.app.vault.createBinary(h,i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength)),await this.log.append({type:"stash_export",id:e[0].id,payload:{path:h,noteCount:s.length,rootIds:e.map(u=>u.id)}}),this.plugin.notifications.show({message:`Exported ${s.length} note${s.length===1?"":"s"} \u2192 \`${h}\``,kind:"success",category:"export",affectedPaths:[h],folder:this.noteFolder,actions:this.actionsForFile(h),duration:0})}catch(i){this.plugin.notifications.show({message:`Stashpad: export failed Error: ${i.message} -Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(i)}}collectExportRoots(t){if(t?.file)return[t];if(this.selection.size>0)return[...this.selection].map(s=>this.tree.get(s)).filter(s=>!!s?.file);if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return[this.currentChildren[this.cursorIdx]];let e=this.tree.get(this.focusId);return e?.file?[e]:[]}collectExportSubtree(t){let e=new Set,s=[],i=n=>{if(!e.has(n.id)){e.add(n.id),n.file&&s.push(n);for(let r of this.tree.getChildren(n.id))i(r)}};for(let n of t)i(n);return s}async cmdImportStash(){let t=this.app.vault.getFiles().filter(i=>i.extension===ve);if(t.length===0){new O.Notice("No .stash files found in this vault.");return}let e=this,s=new class extends O.FuzzySuggestModal{getItems(){return t}getItemText(i){return i.path}onChooseItem(i){e.processStashFile(i)}}(this.app);s.setPlaceholder("Pick a .stash file to import\u2026"),s.open()}async processStashFile(t){try{let e=await this.app.vault.readBinary(t),s=await Je(this.app,new Uint8Array(e),this.noteFolder,this.collectExistingIds());this.tree.rebuild(this.noteFolder),this.render(),await this.log.append({type:"stash_import",id:B,payload:{from:t.path,into:this.noteFolder,noteCount:s.notesWritten,attachmentsWritten:s.attachmentsWritten,collisionsRenamed:s.collisionsRenamed}});try{await this.app.fileManager.trashFile(t)}catch{}let i=[`Imported ${s.notesWritten} note${s.notesWritten===1?"":"s"}`];s.attachmentsWritten&&i.push(`+ ${s.attachmentsWritten} attachment${s.attachmentsWritten===1?"":"s"}`),s.collisionsRenamed&&i.push(`(${s.collisionsRenamed} id collision${s.collisionsRenamed===1?"":"s"} renamed)`),this.plugin.notifications.show({message:i.join(" "),kind:"success",category:"import",folder:this.noteFolder})}catch(e){this.plugin.notifications.show({message:`Stashpad: import failed +Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(i)}}collectExportRoots(t){if(t?.file)return[t];if(this.selection.size>0)return[...this.selection].map(s=>this.tree.get(s)).filter(s=>!!s?.file);if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return[this.currentChildren[this.cursorIdx]];let e=this.tree.get(this.focusId);return e?.file?[e]:[]}collectExportSubtree(t){let e=new Set,s=[],i=n=>{if(!e.has(n.id)){e.add(n.id),n.file&&s.push(n);for(let r of this.tree.getChildren(n.id))i(r)}};for(let n of t)i(n);return s}async cmdImportStash(){let t=this.app.vault.getFiles().filter(i=>i.extension===ye);if(t.length===0){new N.Notice("No .stash files found in this vault.");return}let e=this,s=new class extends N.FuzzySuggestModal{getItems(){return t}getItemText(i){return i.path}onChooseItem(i){e.processStashFile(i)}}(this.app);s.setPlaceholder("Pick a .stash file to import\u2026"),s.open()}async processStashFile(t){try{let e=await this.app.vault.readBinary(t),s=await Qe(this.app,new Uint8Array(e),this.noteFolder,this.collectExistingIds());this.tree.rebuild(this.noteFolder),this.render(),await this.log.append({type:"stash_import",id:R,payload:{from:t.path,into:this.noteFolder,noteCount:s.notesWritten,attachmentsWritten:s.attachmentsWritten,collisionsRenamed:s.collisionsRenamed}});try{await this.app.fileManager.trashFile(t)}catch{}let i=[`Imported ${s.notesWritten} note${s.notesWritten===1?"":"s"}`];s.attachmentsWritten&&i.push(`+ ${s.attachmentsWritten} attachment${s.attachmentsWritten===1?"":"s"}`),s.collisionsRenamed&&i.push(`(${s.collisionsRenamed} id collision${s.collisionsRenamed===1?"":"s"} renamed)`),this.plugin.notifications.show({message:i.join(" "),kind:"success",category:"import",folder:this.noteFolder})}catch(e){this.plugin.notifications.show({message:`Stashpad: import failed File: \`${t.name}\` Error: ${e.message} -Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[t.path],actions:this.actionsForFile(t.path)}),console.error(e)}}collectExistingIds(){let t=new Set,e=s=>{if(t.add(s),!!this.tree.get(s))for(let n of this.tree.getChildren(s))e(n.id)};return e(B),t}async createNoteUnder(t,e,s={record:!0}){let i=(s.targetFolder??this.noteFolder).replace(/\/+$/,""),n=i!==this.noteFolder;await this.ensureFolder(i);let r=Ft(),o=null;{let g=(this.plugin.settings.noteTemplates??{})[i];if(g){let y=this.app.vault.getAbstractFileByPath(g);if(y&&y.extension==="md")try{let S=await this.app.vault.cachedRead(y),k=this.stripFrontmatter(S);o=this.app.metadataCache.getFileCache(y)?.frontmatter??{},k.includes("{{body}}")?t=k.replace(/\{\{body\}\}/g,t):t.trim()?k.trim()&&(t=`${t} +Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[t.path],actions:this.actionsForFile(t.path)}),console.error(e)}}collectExistingIds(){let t=new Set,e=s=>{if(t.add(s),!!this.tree.get(s))for(let n of this.tree.getChildren(s))e(n.id)};return e(R),t}async createNoteUnder(t,e,s={record:!0}){let i=(s.targetFolder??this.noteFolder).replace(/\/+$/,""),n=i!==this.noteFolder;await this.ensureFolder(i);let r=Tt(),o=null;{let v=(this.plugin.settings.noteTemplates??{})[i];if(v){let y=this.app.vault.getAbstractFileByPath(v);if(y&&y.extension==="md")try{let b=await this.app.vault.cachedRead(y),k=this.stripFrontmatter(b);o=this.app.metadataCache.getFileCache(y)?.frontmatter??{},k.includes("{{body}}")?t=k.replace(/\{\{body\}\}/g,t):t.trim()?k.trim()&&(t=`${t} -${k}`):t=k}catch(S){console.warn("[Stashpad] template read failed",S)}}}let a=Bt(t,this.activeStopwords()),l=Ht(a,r),c=`${i}/${l}`,d=e??this.focusId,p=s.createdOverride??new Date().toISOString(),h=this.extractAttachments(t),u=this.currentAuthorLink();u&&this.ensureAuthorFile(u);let m=["---",`id: ${r}`,`parent: ${d}`,`created: ${p}`,`modified: ${p}`];if(u&&m.push(`author: "${u.link.replace(/"/g,'\\"')}"`),h.length>0){m.push("attachments:");for(let g of h)m.push(` - "${g.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",t);try{let g=m.join(` -`);await this.app.vault.create(c,g);try{let y=this.app.vault.getAbstractFileByPath(c);if(y&&y.extension==="md"){if(!n)this.tree.insertSynthetic({id:r,parent:d,children:[],file:y,created:p}),this.render(),this.fmSync.scheduleParentChange(r,null,d);else{this.render();let S=i.split("/").pop()||i,k=(t.split(` -`).find(x=>x.trim())??"note").trim().slice(0,60);this.plugin.notifications.show({message:`"${k}" landed in \`${S}\``,kind:"success",category:"create",duration:0,folder:i,affectedIds:[r],actions:[{label:"Jump to note",onClick:()=>{this.switchToFolderAndFocus(i,r)}}]})}if(o)try{await this.app.fileManager.processFrontMatter(y,S=>{for(let[k,x]of Object.entries(o))re.includes(k)||S[k]===void 0&&(S[k]=x)})}catch(S){console.warn("[Stashpad] template fm overlay failed",S)}}}catch{}if(await this.log.append({type:"create",id:r,payload:{path:c,parent:d}}),s.record!==!1){let y=t;this.plugin.getUndoStack(i).push({label:n?"Send note":"Create note",undo:async()=>{let S=this.app.vault.getAbstractFileByPath(c);if(S)try{await this.app.fileManager.trashFile(S)}catch{}if(this.composerDraft=y,this.saveDraft(y),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=y;let k=y.length;this.composerInputEl.setSelectionRange(k,k),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(c)||await this.app.vault.create(c,g),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(y),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return r}catch(g){return new O.Notice(`Stashpad: failed to create note (${g.message})`),null}}extractAttachments(t){let e=[],s=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,i;for(;(i=s.exec(t))!==null;)e.push(i[1]);return e}async ensureFolder(t){if(await this.app.vault.adapter.exists(t)){let e=this.app.vault.getAbstractFileByPath(t);if(e&&!(e instanceof O.TFolder))throw new Error(`${t} exists and is not a folder`);return}try{await this.app.vault.createFolder(t)}catch(e){let s=e?.message??"";if(!/already exists/i.test(s))throw e}}async importAttachment(t){try{let e=await t.arrayBuffer(),s=`${this.noteFolder}/_attachments`;await this.ensureFolder(s);let i=t.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),r=`${s}/${n}-${i}`;return await this.app.vault.createBinary(r,e),await this.log.append({type:"attachment_add",id:B,payload:{path:r,name:t.name,size:t.size}}),this.plugin.notifications.show({message:`Attached ${t.name}`,kind:"success",category:"attachment",affectedPaths:[r],folder:this.noteFolder}),`![[${r}]]`}catch(e){return new O.Notice(`Stashpad: attachment failed (${e.message})`),null}}currentAuthorLink(){let t=(this.plugin.settings.authorName??"").trim(),e=(this.plugin.settings.authorId??"").trim();if(!t||!e)return null;let s=t.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.noteFolder}/_authors/${s}-${e}.md`;return{link:`[[${i}|${t}]]`,path:i,name:t,id:e}}async ensureAuthorFile(t){try{let e=`${this.noteFolder}/_authors`;if(await this.ensureFolder(e),await this.app.vault.adapter.exists(t.path))return;let s=new Date().toISOString(),i=["---",`authorId: ${t.id}`,`name: "${t.name.replace(/"/g,'\\"')}"`,`created: ${s}`,"---",`# ${t.name}`].join(` -`);await this.app.vault.create(t.path,i)}catch(e){console.warn("[Stashpad] ensureAuthorFile failed",e)}}renderAuthorshipFooter(t,e){if(!e.file)return;let s=this.plugin.settings;if(!s.showAuthor&&!s.showContributors&&!s.showLastEdit)return;let i=this.app.metadataCache.getFileCache(e.file)?.frontmatter??{},n=typeof i.author=="string"?i.author:"",r=Array.isArray(i.contributors)?i.contributors.filter(u=>typeof u=="string"&&u.trim()!==""):[],o=typeof i.modified=="string"?i.modified:typeof i.created=="string"?i.created:"",a=s.showAuthor&&!!n,l=s.showContributors&&r.length>0,c=s.showLastEdit&&!!o;if(!a&&!l&&!c)return;let d=t.createDiv({cls:"stashpad-note-authorship"}),p=(u,m)=>{let g=m.replace(/^\[\[/,"").replace(/\]\]$/,""),y=g.indexOf("|"),S=y>=0?g.slice(0,y):g,k=y>=0?g.slice(y+1):g.split("/").pop()??g,x=u.createEl("a",{cls:"internal-link",text:k});x.setAttribute("data-href",S),x.setAttribute("href",S)},h=[];a&&h.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"by "}),p(u,n)}),l&&h.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"with "}),r.forEach((m,g)=>{g>0&&u.createSpan({text:", "}),p(u,m)})}),c&&h.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"edited "}),u.createSpan({text:this.formatTimeInline(o)})}),h.forEach((u,m)=>{m>0&&d.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let g=d.createSpan({cls:"stashpad-authorship-piece"});u(g)}),d.addEventListener("click",u=>this.handleRenderedClick(u,e))}scheduleContribution(t){let e=this.contribTimers.get(t.path);e&&clearTimeout(e);let s=this.isFileActivelyEdited(t),i=Dt.CONTRIB_DEBOUNCE_MS+(s?Dt.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),n=setTimeout(()=>{if(this.contribTimers.delete(t.path),this.isFileActivelyEdited(t)){this.scheduleContribution(t);return}let r=this.lastExternalModify.get(t.path);if(r!==void 0&&Date.now()-r<Dt.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(t);return}this.maybeRecordContribution(t)},i);this.contribTimers.set(t.path,n)}isFileActivelyEdited(t){try{let e=this.app.workspace.activeLeaf;if(!e)return!1;let s=e.view;if(!s||s.getViewType?.()!=="markdown"||s.file?.path!==t.path)return!1;let i=s.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(t){let e="";try{e=await this.app.vault.cachedRead(t)}catch{return}let s=this.stripFrontmatter(e),i=this.knownBodies.get(t.path);if(this.knownBodies.set(t.path,s),i===void 0||i===s)return;let n=this.currentAuthorLink();if(!n)return;this.ensureAuthorFile(n);let r=new Date().toISOString();this.recentSelfWrites.set(t.path,Date.now());try{await this.app.fileManager.processFrontMatter(t,o=>{o.modified=r;let a=typeof o.author=="string"?o.author:"",l=Array.isArray(o.contributors)?o.contributors.filter(h=>typeof h=="string"):[],c=`-${n.id}`,d=a.includes(c),p=l.some(h=>h.includes(c));!d&&!p&&l.push(n.link),o.contributors=l})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}activeStopwords(){return this.plugin.settings.slugStopWords??It}scheduleSlugRename(t){let e=this.slugDebouncers.get(t.path);e&&e.cancel(),e=(0,O.debounce)(()=>void this.maybeRenameForSlug(t),3e4),this.slugDebouncers.set(t.path,e),e()}async maybeRenameForSlug(t){let e=Qt(t.basename);if(!e||e===B)return;let s=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(s),n=Bt(i,this.activeStopwords()),r=Ht(n,e);if(t.name===r)return;let o=t.parent?`${t.parent.path}/${r}`:r;if(this.app.vault.getAbstractFileByPath(o))return;let a=t.path;try{await this.app.fileManager.renameFile(t,o),await this.log.append({type:"rename",id:e,payload:{from:a,to:o}})}catch{}}scheduleAttachmentSync(t){let e=this.attachmentDebouncers.get(t.path);e&&e.cancel(),e=(0,O.debounce)(()=>void this.syncAttachmentsFrontmatter(t),1500),this.attachmentDebouncers.set(t.path,e),e()}async syncAttachmentsFrontmatter(t){let e=await this.app.vault.cachedRead(t),s=this.stripFrontmatter(e),i=this.extractAttachments(s),n=this.app.metadataCache.getFileCache(t)?.frontmatter,r=Array.isArray(n?.attachments)?n.attachments:[];r.length===i.length&&r.every((a,l)=>a===i[l])||await this.app.fileManager.processFrontMatter(t,a=>{a.attachments=i})}stripFrontmatter(t){let e=t.replace(/^/,""),s=e.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return s?e.slice(s[0].length):e}formatTime(t){if(!t)return"";let e=(0,O.moment)(t);if(!e.isValid())return"";if(kt().useTemplatesFormat){let i=Ze(this.app);if(i)return`${e.format(i.dateFormat)} +${k}`):t=k}catch(b){console.warn("[Stashpad] template read failed",b)}}}let a=$t(t,this.activeStopwords()),l=Rt(a,r),c=`${i}/${l}`,h=e??this.focusId,u=s.createdOverride??new Date().toISOString(),d=this.extractAttachments(t),p=this.currentAuthorLink();p&&this.ensureAuthorFile(p);let m=["---",`id: ${r}`,`parent: ${h}`,`created: ${u}`,`modified: ${u}`];if(p&&m.push(`author: "${p.link.replace(/"/g,'\\"')}"`),d.length>0){m.push("attachments:");for(let v of d)m.push(` - "${v.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",t);try{let v=m.join(` +`);await this.app.vault.create(c,v);try{let y=this.app.vault.getAbstractFileByPath(c);if(y&&y.extension==="md"){if(!n)this.tree.insertSynthetic({id:r,parent:h,children:[],file:y,created:u}),this.render(),this.fmSync.scheduleParentChange(r,null,h);else{this.render();let b=i.split("/").pop()||i,k=(t.split(` +`).find(C=>C.trim())??"note").trim().slice(0,60);this.plugin.notifications.show({message:`"${k}" landed in \`${b}\``,kind:"success",category:"create",duration:0,folder:i,affectedIds:[r],actions:[{label:"Jump to note",onClick:()=>{this.switchToFolderAndFocus(i,r)}}]})}if(o)try{await this.app.fileManager.processFrontMatter(y,b=>{for(let[k,C]of Object.entries(o))ae.includes(k)||b[k]===void 0&&(b[k]=C)})}catch(b){console.warn("[Stashpad] template fm overlay failed",b)}}}catch{}if(await this.log.append({type:"create",id:r,payload:{path:c,parent:h}}),s.record!==!1){let y=t;this.plugin.getUndoStack(i).push({label:n?"Send note":"Create note",undo:async()=>{let b=this.app.vault.getAbstractFileByPath(c);if(b)try{await this.app.fileManager.trashFile(b)}catch{}if(this.composerDraft=y,this.saveDraft(y),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=y;let k=y.length;this.composerInputEl.setSelectionRange(k,k),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(c)||await this.app.vault.create(c,v),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(y),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return r}catch(v){return new N.Notice(`Stashpad: failed to create note (${v.message})`),null}}extractAttachments(t){let e=[],s=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,i;for(;(i=s.exec(t))!==null;)e.push(i[1]);return e}async ensureFolder(t){if(await this.app.vault.adapter.exists(t)){let e=this.app.vault.getAbstractFileByPath(t);if(e&&!(e instanceof N.TFolder))throw new Error(`${t} exists and is not a folder`);return}try{await this.app.vault.createFolder(t)}catch(e){let s=e?.message??"";if(!/already exists/i.test(s))throw e}}async importAttachment(t){try{let e=await t.arrayBuffer(),s=`${this.noteFolder}/_attachments`;await this.ensureFolder(s);let i=t.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),r=`${s}/${n}-${i}`;return await this.app.vault.createBinary(r,e),await this.log.append({type:"attachment_add",id:R,payload:{path:r,name:t.name,size:t.size}}),this.plugin.notifications.show({message:`Attached ${t.name}`,kind:"success",category:"attachment",affectedPaths:[r],folder:this.noteFolder}),`![[${r}]]`}catch(e){return new N.Notice(`Stashpad: attachment failed (${e.message})`),null}}currentAuthorLink(){let t=(this.plugin.settings.authorName??"").trim(),e=(this.plugin.settings.authorId??"").trim();if(!t||!e)return null;let s=t.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.noteFolder}/_authors/${s}-${e}.md`;return{link:`[[${i}|${t}]]`,path:i,name:t,id:e}}claimSelectedAsAuthor(){this.claimAuthorship({scope:"selection",contributorMode:!1})}claimFolderAsAuthor(){this.claimAuthorship({scope:"folder",contributorMode:!1})}claimSelectedWithContributor(){this.claimAuthorship({scope:"selection",contributorMode:!0})}claimFolderWithContributor(){this.claimAuthorship({scope:"folder",contributorMode:!0})}fileBackedNotesInFolder(){let t=this.noteFolder.replace(/\/+$/,"");return this.app.vault.getMarkdownFiles().filter(e=>{let s=e.parent?.path?.replace(/\/+$/,"")??"";if(s!==t&&!s.startsWith(t+"/")||e.path.includes("/_authors/"))return!1;let i=this.app.metadataCache.getFileCache(e)?.frontmatter;return typeof i?.id=="string"&&!!i.id})}async pacedFrontmatter(t,e){for(let n=0;n<t.length;n++){let r=this.app.vault.getAbstractFileByPath(t[n]);if(r instanceof N.TFile){this.recentSelfWrites.set(r.path,Date.now());try{await this.app.fileManager.processFrontMatter(r,o=>e(o,t[n]))}catch(o){console.warn("[Stashpad] claim: frontmatter write failed",t[n],o)}}(n+1)%25===0&&await new Promise(o=>setTimeout(o,30))}}async claimAuthorship(t){let e=this.currentAuthorLink();if(!e){new N.Notice("Set your author name in Stashpad settings first.");return}let s=`-${e.id}`,i=t.scope==="selection"?this.getActionTargets().map(d=>d.file).filter(d=>!!d):this.fileBackedNotesInFolder();if(i.length===0){new N.Notice(t.scope==="selection"?"No notes selected.":"No notes in this folder.");return}let n=[],r=[];for(let d of i){let p=this.app.metadataCache.getFileCache(d)?.frontmatter,m=typeof p?.author=="string"?p.author:"";if(!m.trim()){n.push(d.path);continue}if(m.includes(s)||!t.contributorMode)continue;(Array.isArray(p?.contributors)?p.contributors.filter(y=>typeof y=="string"):[]).some(y=>y.includes(s))||r.push(d.path)}let o=n.length+r.length;if(o===0){new N.Notice("Nothing to claim \u2014 those notes are already authored by you.");return}if(t.scope==="folder"){let d=[`Stamp yourself as author on ${n.length} unauthored note(s)`];if(r.length&&d.push(`and as a contributor on ${r.length} already-authored note(s)`),!await new Promise(m=>{new Ft(this.app,"Claim authorship",`${d.join(" ")}? +Existing authors are never overwritten. This can be undone.`,"Claim",m).open()}))return}let a=this.noteFolder,l=e.link,c=new Set,h=async()=>{await this.pacedFrontmatter(n,(d,p)=>{typeof d.author=="string"&&d.author.trim()||(d.author=l),Array.isArray(d.contributors)&&d.contributors.some(m=>typeof m=="string"&&m.includes(s))&&(d.contributors=d.contributors.filter(m=>!(typeof m=="string"&&m.includes(s))),c.add(p))}),await this.pacedFrontmatter(r,d=>{let p=Array.isArray(d.contributors)?d.contributors.filter(m=>typeof m=="string"):[];p.some(m=>m.includes(s))||p.push(l),d.contributors=p})};this.ensureAuthorFile(e),await h(),this.plugin.getUndoStack(a).push({label:`Claim authorship (${o} note${o===1?"":"s"})`,undo:async()=>{await this.pacedFrontmatter(n,(d,p)=>{if(typeof d.author=="string"&&d.author.includes(s)&&delete d.author,c.has(p)){let m=Array.isArray(d.contributors)?d.contributors.filter(v=>typeof v=="string"):[];m.some(v=>v.includes(s))||m.push(l),d.contributors=m}}),await this.pacedFrontmatter(r,d=>{Array.isArray(d.contributors)&&(d.contributors=d.contributors.filter(p=>!(typeof p=="string"&&p.includes(s))))}),this.debouncedRender()},redo:async()=>{c.clear(),await h(),this.debouncedRender()}});let u=[];n.length&&u.push(`authored ${n.length}`),r.length&&u.push(`contributing to ${r.length}`),new N.Notice(`Claimed authorship: ${u.join(", ")}. Undo available.`),this.debouncedRender()}async ensureAuthorFile(t){try{t.id&&this.plugin.authorRegistry.record({id:t.id,name:t.name});let e=`${this.noteFolder}/_authors`;if(await this.ensureFolder(e),await this.app.vault.adapter.exists(t.path))return;let s=t.id===(this.plugin.settings.authorId??"").trim(),i=this.plugin.buildAuthorStub({id:t.id,name:t.name,role:s?this.plugin.settings.authorRole:void 0,department:s?this.plugin.settings.authorDepartment:void 0},new Date().toISOString());await this.app.vault.create(t.path,i)}catch(e){console.warn("[Stashpad] ensureAuthorFile failed",e)}}renderAuthorshipFooter(t,e){if(!e.file)return;let s=this.plugin.settings;if(!s.showAuthor&&!s.showContributors&&!s.showLastEdit)return;let i=this.app.metadataCache.getFileCache(e.file)?.frontmatter??{},n=typeof i.author=="string"?i.author:"",r=Array.isArray(i.contributors)?i.contributors.filter(p=>typeof p=="string"&&p.trim()!==""):[],o=typeof i.modified=="string"?i.modified:typeof i.created=="string"?i.created:"",a=s.showAuthor&&!!n,l=s.showContributors&&r.length>0,c=s.showLastEdit&&!!o;if(!a&&!l&&!c)return;let h=t.createDiv({cls:"stashpad-note-authorship"}),u=(p,m)=>{let v=m.replace(/^\[\[/,"").replace(/\]\]$/,""),y=v.indexOf("|"),b=y>=0?v.slice(0,y):v,k=y>=0?v.slice(y+1):v.split("/").pop()??v,C=p.createEl("a",{cls:"internal-link",text:k});C.setAttribute("data-href",b),C.setAttribute("href",b)},d=[];a&&d.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"by "}),u(p,n)}),l&&d.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"with "}),r.forEach((m,v)=>{v>0&&p.createSpan({text:", "}),u(p,m)})}),c&&d.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"edited "}),p.createSpan({text:this.formatTimeInline(o)})}),d.forEach((p,m)=>{m>0&&h.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let v=h.createSpan({cls:"stashpad-authorship-piece"});p(v)}),h.addEventListener("click",p=>this.handleRenderedClick(p,e))}scheduleContribution(t){let e=this.contribTimers.get(t.path);e&&clearTimeout(e);let s=this.isFileActivelyEdited(t),i=It.CONTRIB_DEBOUNCE_MS+(s?It.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),n=setTimeout(()=>{if(this.contribTimers.delete(t.path),this.isFileActivelyEdited(t)){this.scheduleContribution(t);return}let r=this.lastExternalModify.get(t.path);if(r!==void 0&&Date.now()-r<It.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(t);return}this.maybeRecordContribution(t)},i);this.contribTimers.set(t.path,n)}isFileActivelyEdited(t){try{let e=this.app.workspace.activeLeaf;if(!e)return!1;let s=e.view;if(!s||s.getViewType?.()!=="markdown"||s.file?.path!==t.path)return!1;let i=s.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(t){let e="";try{e=await this.app.vault.cachedRead(t)}catch{return}let s=this.stripFrontmatter(e),i=this.knownBodies.get(t.path);if(this.knownBodies.set(t.path,s),i===void 0||i===s)return;let n=this.currentAuthorLink();if(!n)return;this.ensureAuthorFile(n);let r=new Date().toISOString();this.recentSelfWrites.set(t.path,Date.now());try{await this.app.fileManager.processFrontMatter(t,o=>{o.modified=r;let a=typeof o.author=="string"?o.author:"",l=Array.isArray(o.contributors)?o.contributors.filter(d=>typeof d=="string"):[],c=`-${n.id}`,h=a.includes(c),u=l.some(d=>d.includes(c));!h&&!u&&l.push(n.link),o.contributors=l})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}activeStopwords(){return this.plugin.settings.slugStopWords??Et}scheduleSlugRename(t){let e=this.slugDebouncers.get(t.path);e&&e.cancel(),e=(0,N.debounce)(()=>void this.maybeRenameForSlug(t),3e4),this.slugDebouncers.set(t.path,e),e()}async maybeRenameForSlug(t){let e=Qt(t.basename);if(!e||e===R)return;let s=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(s),n=$t(i,this.activeStopwords()),r=Rt(n,e);if(t.name===r)return;let o=t.parent?`${t.parent.path}/${r}`:r;if(this.app.vault.getAbstractFileByPath(o))return;let a=t.path;try{await this.app.fileManager.renameFile(t,o),await this.log.append({type:"rename",id:e,payload:{from:a,to:o}})}catch{}}scheduleAttachmentSync(t){let e=this.attachmentDebouncers.get(t.path);e&&e.cancel(),e=(0,N.debounce)(()=>void this.syncAttachmentsFrontmatter(t),1500),this.attachmentDebouncers.set(t.path,e),e()}async syncAttachmentsFrontmatter(t){let e=await this.app.vault.cachedRead(t),s=this.stripFrontmatter(e),i=this.extractAttachments(s),n=this.app.metadataCache.getFileCache(t)?.frontmatter,r=Array.isArray(n?.attachments)?n.attachments:[];r.length===i.length&&r.every((a,l)=>a===i[l])||await this.app.fileManager.processFrontMatter(t,a=>{a.attachments=i})}stripFrontmatter(t){let e=t.replace(/^/,""),s=e.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return s?e.slice(s[0].length):e}formatTime(t){if(!t)return"";let e=(0,N.moment)(t);if(!e.isValid())return"";if(wt().useTemplatesFormat){let i=Je(this.app);if(i)return`${e.format(i.dateFormat)} ${e.format(i.timeFormat)}`}return`${e.format("YYYY.MM.DD")} -${e.format("HH:mm A")}`}formatTimeInline(t){if(!t)return"";let e=(0,O.moment)(t);if(!e.isValid())return"";if(kt().useTemplatesFormat){let i=Ze(this.app);if(i){let n=/:ss/.test(i.timeFormat)?i.timeFormat:i.timeFormat.replace(/(:mm)/,"$1:ss");return`${e.format(i.dateFormat)} ${e.format(n)}`}}return`${e.format("YYYY.MM.DD")} ${e.format("HH:mm:ss A")}`}scrollListToBottom(){let t=this.listEl;if(!t)return;this.stickToListBottom=!0,t.scrollTop=t.scrollHeight,this.stickyRowObserver?.disconnect();let e=()=>{if(!this.stickToListBottom){this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null;return}t.scrollTop=t.scrollHeight},s=new ResizeObserver(e);for(let o of Array.from(t.children))o instanceof HTMLElement&&s.observe(o);this.stickyRowObserver=s;let i=performance.now(),n=t.scrollHeight,r=()=>{if(!this.stickToListBottom)return;let o=t.scrollHeight;o!==n&&(t.scrollTop=o,n=o),performance.now()-i<3e4?requestAnimationFrame(r):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(r)}openNoteMenu(t,e){if(!e.file)return;let s=e.file,i=new O.Menu;i.addItem(a=>a.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(e.id)})),i.addItem(a=>a.setTitle("Open in editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(s)})),i.addItem(a=>a.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(e.id))),i.addSeparator(),i.addItem(a=>a.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(e))),i.addItem(a=>a.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdClone()})),i.addItem(a=>a.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),i.addItem(a=>a.setTitle("Export to .stash").setIcon("package").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdExportStash()})),i.addSeparator(),i.addItem(a=>a.setTitle("Move to\u2026").setIcon("move").onClick(()=>this.cmdMovePicker())),i.addItem(a=>a.setTitle("Move to Home").setIcon("home").onClick(async()=>{await this.changeParent(e,B),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==B&&this.navigateTo(B)}));let n={folder:this.noteFolder,id:e.id},r=this.plugin.isPinned(n);i.addItem(a=>a.setTitle(r?"Unpin from sidebar":"Pin to sidebar").setIcon(r?"pin-off":"pin").onClick(async()=>{r?await this.plugin.unpinNote(n):await this.plugin.pinNote(n)})),i.addItem(a=>a.setTitle("Set color\u2026").setIcon("palette").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdSetColor()}));let o=this.isCompleted(e);i.addItem(a=>a.setTitle(o?"Mark incomplete":"Mark complete").setIcon(o?"circle":"check-circle").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdToggleComplete()})),i.addSeparator(),i.addItem(a=>a.setTitle("Delete").setIcon("trash").onClick(async()=>{await this.deleteNote(e)})),i.showAtMouseEvent(t)}async deleteNote(t){if(!t.file)return;let e=[],s=u=>{for(let m of this.tree.getChildren(u.id))s(m),e.push(m)};s(t);let i=[...e,t],n=i.filter(u=>!!u.file),r=await Promise.all(n.map(u=>this.app.vault.cachedRead(u.file))),o=[];for(let u=0;u<n.length;u++){let m=n[u];o.push(...this.extractAttachments(this.stripFrontmatter(r[u])));let g=this.app.metadataCache.getFileCache(m.file)?.frontmatter;if(Array.isArray(g?.attachments))for(let y of g.attachments)typeof y=="string"&&y.trim()&&o.push(y)}let a=[...new Set(o)],l=this.collectAuthorIds(i),c=async u=>{let m=await this.snapshotNotes(i,u),g=0;if(u)for(let $ of a){let F=this.app.metadataCache.getFirstLinkpathDest($,"");if(F)try{await this.app.fileManager.trashFile(F),await this.log.append({type:"attachment_remove",id:B,payload:{path:F.path}}),this.plugin.notifications.show({message:`Deleted attachment "${F.name}"`,kind:"warning",category:"attachment",affectedPaths:[F.path],folder:this.noteFolder}),g+=1}catch{}}let y=new Set;for(let $ of i)$.parent&&y.add($.parent);let S=this.currentChildren.findIndex($=>$.id===t.id),k=null;if(S>=0){for(let $=S+1;$<this.currentChildren.length;$++)if(this.currentChildren[$].id!==t.id){k=this.currentChildren[$].id;break}if(!k){for(let $=S-1;$>=0;$--)if(this.currentChildren[$].id!==t.id){k=this.currentChildren[$].id;break}}}for(let $ of i)if($.file){try{await this.app.fileManager.trashFile($.file)}catch{}await this.log.append({type:"delete",id:$.id,payload:{path:$.file.path,attachmentsRemoved:u?a:[]}})}this.selection.clear(),this.cursorIdx=-1,k&&(this.pendingFocusIds=[k]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let $ of y)i.some(F=>F.id===$)||this.fmSync.scheduleParentOfDeleted($);let x=this.noteFolder,I=`Delete "${this.titleForNode(t)}"`,E=t.id,D=g>0?` with ${g} attachment${g===1?"":"s"}`:"";this.plugin.notifications.show({message:`Deleted "${this.titleForNode(t)}"${D}`,kind:"warning",category:"delete",affectedIds:[t.id],affectedAuthorIds:l,folder:this.noteFolder}),this.plugin.getUndoStack(x).push({label:I,undo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(m,[E])},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.trashNotesAndAttachments(m)}})},d=kt(),p=e.length>0&&d.confirmBulkDelete,h=a.length>0&&d.confirmAttachmentDelete;if(!p&&!h){await c(!1),this.focusView();return}new Zt(this.app,this.titleForNode(t),e.length,a.length,h,async u=>{await c(u),this.focusView()}).open()}async cmdSwapWithParent(){let t=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!t?.file){new O.Notice("Pick a note first (move the cursor onto it).");return}if(!t.parent||t.parent===B){new O.Notice("Already at Home \u2014 no parent to swap with.");return}let e=this.tree.get(t.parent);if(!e?.file){new O.Notice("Couldn't find the parent note.");return}let s=e.parent??B,i=this.titleForNode(t),n=this.titleForNode(e),r=this.tree.getChildren(e.id).filter(a=>a.id!==t.id).length,o=[`"${n}" becomes a child of "${i}".`];r>0&&o.push(`${r} sibling${r===1?"":"s"} move with it.`),new Mt(this.app,"Swap notes?",o.join(` -`),"Swap",async a=>{a&&await this.swapParentChild(e,t,s)}).open()}offerSwapForDescendantMove(t,e){let s=this.tree.get(e);if(!s?.file){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",affectedIds:[t.id],folder:this.noteFolder});return}if(s.parent!==t.id){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under "${this.titleForNode(s)}" \u2014 it's a deeper descendant. Only direct parent \u2194 child swaps are supported (try moving "${this.titleForNode(s)}" up first, then swap).`,kind:"warning",category:"move",affectedIds:[t.id,s.id],folder:this.noteFolder});return}let i=this.titleForNode(t),n=this.titleForNode(s),r=this.tree.getChildren(t.id).filter(a=>a.id!==s.id).length,o=[`"${i}" becomes a child of "${n}".`];r>0&&o.push(`${r} sibling${r===1?"":"s"} move with it.`),new Mt(this.app,"Confirm Note Swap",o.join(` -`),"Swap",async a=>{if(!a)return;let l=t.parent??B;await this.swapParentChild(t,s,l)}).open()}async swapParentChild(t,e,s){if(!t.file||!e.file)return;if(e.parent!==t.id){new O.Notice("Swap aborted: parent/child relationship changed.");return}let i=this.noteFolder,n=t.parent,r=this.tree.getChildren(t.id).filter(h=>h.id!==e.id).filter(h=>!!h.file),o=r.map(h=>({id:h.id,path:h.file.path,was:h.parent})),a=this.order.getOrder(i,s).slice(),l=this.order.getOrder(i,e.id).slice(),c=this.order.getOrder(i,t.id).slice();await this.app.fileManager.processFrontMatter(e.file,h=>{h.parent=s}),this.fmSync.scheduleParentChange(e.id,t.id,s),await this.app.fileManager.processFrontMatter(t.file,h=>{h.parent=e.id}),this.fmSync.scheduleParentChange(t.id,n,e.id);for(let h of r)await this.app.fileManager.processFrontMatter(h.file,u=>{u.parent=e.id}),this.fmSync.scheduleParentChange(h.id,t.id,e.id);if(a.length>0){let h=a.includes(t.id)?a.map(u=>u===t.id?e.id:u):[...a.filter(u=>u!==e.id),e.id];this.order.setOrder(i,s,h)}let d=r.map(h=>h.id),p=[t.id,...l.filter(h=>h!==t.id&&!d.includes(h)),...d];this.order.setOrder(i,e.id,p),this.order.setOrder(i,t.id,[]),await this.order.save(i),await this.log.append({type:"parent_change",id:e.id,payload:{from:t.id,to:s,reason:"swap"}}),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e.id,reason:"swap"}});for(let h of o)await this.log.append({type:"parent_change",id:h.id,payload:{from:h.was,to:e.id,reason:"swap"}});this.tree.rebuild(i),this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"}),this.plugin.notifications.show({message:`Swapped "${this.titleForNode(e)}" \u2194 "${this.titleForNode(t)}".`,kind:"success",category:"move",affectedIds:[e.id,t.id,...d],folder:i}),this.plugin.getUndoStack(i).push({label:`Swap "${this.titleForNode(e)}" \u2194 parent`,undo:async()=>{let h=this.tree.get(t.id),u=this.tree.get(e.id);h?.file&&await this.app.fileManager.processFrontMatter(h.file,m=>{n==null||n===B?(delete m.parent,m.parent=B):m.parent=n}),u?.file&&await this.app.fileManager.processFrontMatter(u.file,m=>{m.parent=t.id});for(let m of o){let g=this.app.vault.getAbstractFileByPath(m.path);g&&await this.app.fileManager.processFrontMatter(g,y=>{m.was==null?y.parent=B:y.parent=m.was})}this.order.setOrder(i,s,a),this.order.setOrder(i,e.id,l),this.order.setOrder(i,t.id,c),await this.order.save(i),this.tree.rebuild(i),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(t,e,s)}})}async changeParent(t,e,s={record:!0}){if(!t.file)return;let i=t.file,n=t.parent,r=a=>a??B;if(r(n)===r(e)){if(!s.quiet){let a=this.titleForNode(t),l=e===B?"Home":`"${this.titleForNode(this.tree.get(e)??t)}"`;this.plugin.notifications.show({message:`"${a}" is already under ${l}.`,kind:"info",category:"move",affectedIds:[t.id],folder:this.noteFolder})}return}if(e===t.id){s.quiet||this.plugin.notifications.show({message:`Can't move "${this.titleForNode(t)}" into itself.`,kind:"warning",category:"move",affectedIds:[t.id],folder:this.noteFolder});return}if(e!==B&&this.isDescendant(e,t.id)){s.quiet||this.offerSwapForDescendantMove(t,e);return}let o=this.collectAuthorIds([t]);if(await this.app.fileManager.processFrontMatter(i,a=>{a.parent=e}),this.fmSync.scheduleParentChange(t.id,n,e),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e}}),this.pendingFocusIds=[t.id],this.focusId!==e&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),!s.quiet){let a=this.tree.get(e),l=a?this.titleForNode(a):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(t)}" \u2192 "${l}"`,kind:"success",category:"move",affectedIds:[t.id],affectedAuthorIds:o,folder:this.noteFolder,actions:e===B?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]})}if(s.record!==!1){let a=this.noteFolder,l=i.path,c=t.id;this.plugin.getUndoStack(a).push({label:"Move note",undo:async()=>{let d=this.app.vault.getAbstractFileByPath(l);if(d){await this.app.fileManager.processFrontMatter(d,p=>{p.parent=n}),this.pendingFocusIds=[c],this.focusId!==n&&this.focusId!==e?(this.selection.clear(),this.cursorIdx=-1):this.focusId===e&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(a),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,h=()=>{if(this.selectionGuardKey!==p||this.selection.has(c))return;let u=this.currentChildren.findIndex(m=>m.id===c);u<0||(this.selection.add(c),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(h,120),setTimeout(h,400)}}},redo:async()=>{let d=this.app.vault.getAbstractFileByPath(l);if(d){await this.app.fileManager.processFrontMatter(d,p=>{p.parent=e}),this.pendingFocusIds=[c],this.focusId!==e&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(a),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,h=()=>{if(this.selectionGuardKey!==p||this.selection.has(c))return;let u=this.currentChildren.findIndex(m=>m.id===c);u<0||(this.selection.add(c),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(h,120),setTimeout(h,400)}}}})}}};Dt.CONTRIB_DEBOUNCE_MS=4e3,Dt.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,Dt.EXTERNAL_WRITE_GRACE_MS=1500,Dt.EXTERNAL_QUIESCENCE_MS=5e3;var ts=Dt;function Ai(v,f){return!f||v.metaKey||v.ctrlKey||v.altKey?!1:v.key.toLowerCase()===f.toLowerCase()}function se(v,f){return f?f.includes("+")?Pi(v,f):Ai(v,f):!1}function ct(v,f){if(!f)return!1;let{primary:t,secondary:e,preferRight:s,useBoth:i}=f;return t&&e?i?se(v,t)||se(v,e):s?se(v,e):se(v,t):se(v,t)||se(v,e)}function Ts(v){if(!v)return"";let f=O.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac");return v.split("+").map(t=>{let e=t.trim();return e?e.toLowerCase()==="mod"?f?"Cmd":"Ctrl":e.toLowerCase()==="alt"?f?"Opt":"Alt":e.length===1?e.toUpperCase():e:""}).filter(Boolean).join("+")}function Pi(v,f){if(!f)return!1;let t=f.split("+").map(d=>d.trim()).filter(Boolean);if(t.length<2)return!1;let e=t[t.length-1].toLowerCase(),s=new Set(t.slice(0,-1).map(d=>d.toLowerCase())),i=s.has("mod"),n=s.has("ctrl")||s.has("control"),r=s.has("cmd")||s.has("meta")||s.has("command"),o=s.has("alt")||s.has("option"),a=s.has("shift"),c=O.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac")?v.metaKey:v.ctrlKey;return i&&!c||n&&!v.ctrlKey||r&&!v.metaKey||o!==v.altKey||a!==v.shiftKey||!i&&(!n&&v.ctrlKey||!r&&v.metaKey)?!1:v.key.toLowerCase()===e}function Mi(v){let f=[],t=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,e;for(;(e=t.exec(v))!=null;)f.push({lang:e[3].trim(),code:e[4]});return f}function es(v){return v.split("/").map(f=>f.split(" ").map(t=>t&&/^[a-z]/.test(t)?t[0].toUpperCase()+t.slice(1):t).join(" ")).join("/")}function _i(v,f,t){let e=new Set(f),s=v.filter(n=>!e.has(n)),i=v.findIndex(n=>e.has(n));if(i<0)return v.slice();switch(t){case"top":return[...f,...s];case"bottom":return[...s,...f];case"up":{let n=Math.max(0,i-1),r=s.slice();return r.splice(n,0,...f),r}case"down":{let n=(()=>{let l=-1;return v.forEach((c,d)=>{e.has(c)&&(l=d)}),l})(),r=0;for(let l=0;l<Math.min(v.length,n+2);l++)e.has(v[l])||r++;let o=Math.min(s.length,r),a=s.slice();return a.splice(o,0,...f),a}}}function ei(v,f){if(v.length!==f.length)return!1;for(let t=0;t<v.length;t++)if(v[t]!==f[t])return!1;return!0}pe();var ss=class{constructor(f,t,e){this.app=f;this.dirOk=!1;this.writeChain=Promise.resolve();this.baseDir=t.replace(/\/+$/,""),this.logPath=`${this.baseDir}/log.jsonl`,this.statePath=`${this.baseDir}/state.json`,this.getAuthor=e??(()=>"")}getLogPath(){return this.logPath}getDir(){return this.baseDir}async ensureDir(){if(this.dirOk)return;let f=this.app.vault.adapter,t=this.baseDir.split("/").filter(Boolean),e="";for(let s of t)e=e?`${e}/${s}`:s,await f.exists(e)||await f.mkdir(e);this.dirOk=!0}append(f){let t=f.author??this.getAuthor()??"",e={ts:new Date().toISOString(),...f};t?e.author=t:delete e.author;let s=JSON.stringify(e)+` -`;return this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let i=this.app.vault.adapter;if(typeof i.append=="function")await i.append(this.logPath,s);else{let n=await i.exists(this.logPath)?await i.read(this.logPath):"";await i.write(this.logPath,n+s)}}catch(i){console.warn("Stashpad: log append failed",i)}}),Promise.resolve()}async readState(){let f=this.app.vault.adapter;if(!await f.exists(this.statePath))return{};try{return JSON.parse(await f.read(this.statePath))}catch{return{}}}async writeState(f){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(f,null,2))}};xt();var is=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(f){for(this.undoStack.push(f),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let f=this.undoStack.pop();if(!f)return null;try{await f.undo()}catch(t){throw console.error("Stashpad: undo failed",t),t}return this.redoStack.push(f),f}async redo(){let f=this.redoStack.pop();if(!f)return null;try{await f.redo()}catch(t){throw console.error("Stashpad: redo failed",t),t}return this.undoStack.push(f),f}peekUndoLabel(){return this.undoStack[this.undoStack.length-1]?.label??null}peekRedoLabel(){return this.redoStack[this.redoStack.length-1]?.label??null}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}clear(){this.undoStack=[],this.redoStack=[]}};var ns=class extends at.Plugin{constructor(){super(...arguments);this.settings={...zt};this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.settingTab=null;this.stashpadSelectionListeners=new Set;this.stashpadContentListeners=new Set;this._notifications=null;this.sweptFolders=new Set;this.authorRenameInFlight=new Set;this.notifPersistenceWired=!1;this.notifSaveTimer=null;this.LAST_CURSOR_LS_KEY="stashpad:last-cursor";this.writeChain=Promise.resolve()}get notifications(){return this._notifications||(this._notifications=new Oe(this.app)),this._notifications}pluginPrivatePath(t=""){let s=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return t?`${s}/${t.replace(/^\/+/,"")}`:s}newLog(){return new ss(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let t=this.app.vault.adapter,e=this.pluginPrivatePath(),s=async()=>{let o=e.split("/").filter(Boolean),a="";for(let l of o)a=a?`${a}/${l}`:l,await t.exists(a)||await t.mkdir(a)},i=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await t.exists(i)&&!await t.exists(n))try{await s();let o=await t.read(i);await t.write(n,o),console.debug("[Stashpad] migrated data.json \u2192",n)}catch(o){console.warn("Stashpad: data.json migration failed",o)}let r=".stashpad";if(await t.exists(r))try{await s();let o=await t.list(r);for(let a of o.files){let l=a.replace(/^.*\//,""),c=this.pluginPrivatePath(l);if(!await t.exists(c))try{let d=await t.read(a);await t.write(c,d),console.debug("[Stashpad] migrated",a,"\u2192",c)}catch(d){console.warn(`Stashpad: failed to migrate ${a}`,d)}}}catch(o){console.warn("Stashpad: .stashpad migration scan failed",o)}}async loadData(){let t=this.app.vault.adapter,e=this.pluginPrivatePath("data.json");if(!await t.exists(e))return null;try{return JSON.parse(await t.read(e))}catch(s){return console.warn("Stashpad: data.json parse failed",s),null}}async saveData(t){let e=this.app.vault.adapter,s=this.pluginPrivatePath();if(!await e.exists(s)){let i=s.split("/").filter(Boolean),n="";for(let r of i)n=n?`${n}/${r}`:r,await e.exists(n)||await e.mkdir(n)}await e.write(this.pluginPrivatePath("data.json"),JSON.stringify(t,null,2))}async createNewStashpad(t){let e=t.trim().replace(/^\/+|\/+$/g,"");if(!e)throw new Error("Folder name is empty");let s=this.app.vault.adapter,i=e.split("/").filter(Boolean),n="";for(let l of i)n=n?`${n}/${l}`:l,await s.exists(n)||await s.mkdir(n);let r=`${e}/Home.md`;if(await s.exists(r)){let l=this.app.vault.getAbstractFileByPath(r);l&&await this.app.fileManager.processFrontMatter(l,c=>{(typeof c.id!="string"||!c.id)&&(c.id=B),"parent"in c||(c.parent=null),(typeof c.created!="string"||!c.created)&&(c.created=new Date().toISOString())});return}let o=new Date().toISOString(),a=["---",`id: ${B}`,"parent: null",`created: ${o}`,"---","Home"].join(` -`);await this.app.vault.create(r,a)}collectColorsInFolder(t){let e=new Map,s=t.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(r!==s&&!r.startsWith(s+"/"))continue;let o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=typeof o?.color=="string"?o.color.trim():"";if(!a||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(a))continue;let l=a.toLowerCase();e.set(l,(e.get(l)??0)+1)}let i=[...e.entries()].map(([n,r])=>({hex:n,count:r}));return i.sort((n,r)=>r.count-n.count||n.hex.localeCompare(r.hex)),i}async recolorAllInFolder(t,e,s){let i=t.replace(/\/+$/,""),n=e.toLowerCase(),r=0;for(let a of this.app.vault.getMarkdownFiles()){let l=a.parent?.path?.replace(/\/+$/,"")??"";if(l!==i&&!l.startsWith(i+"/"))continue;let c=this.app.metadataCache.getFileCache(a)?.frontmatter;if((typeof c?.color=="string"?c.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(a,p=>{s?p.color=s:delete p.color}),r++}catch(p){console.warn(`Stashpad: recolor failed for ${a.path}`,p)}}let o=this.settings.colorAliases?.[i];if(o){let a=o[n];a&&(delete o[n],s&&(o[s.toLowerCase()]=a),Object.keys(o).length===0&&delete this.settings.colorAliases[i],await this.saveSettings())}return r}getColorAlias(t,e){let s=t.replace(/\/+$/,""),i=this.settings.colorAliases?.[s];if(!i)return;let n=i[e.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(t,e,s){let i=t.replace(/\/+$/,""),n=e.toLowerCase();this.settings.colorAliases||(this.settings.colorAliases={}),this.settings.colorAliases[i]||(this.settings.colorAliases[i]={});let r=this.settings.colorAliases[i],o=s.trim();o?r[n]=o:delete r[n],Object.keys(r).length===0&&delete this.settings.colorAliases[i],await this.saveSettings()}async waitForStashpadFolder(t,e=2e3){let s=t.trim().replace(/^\/+|\/+$/g,"");if(!s)return;let i=Date.now();for(;Date.now()-i<e;){if(this.discoverStashpadFolders().includes(s))return;await new Promise(n=>setTimeout(n,80))}}discoverStashpadFolders(){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){let s=this.app.metadataCache.getFileCache(e)?.frontmatter;if(typeof s?.id!="string"||!s.id.trim()||!s||!("parent"in s))continue;let i=e.parent?.path?.replace(/\/+$/,"")??"";i&&t.add(i)}return[...t].sort()}searchableFolders(t){let e=new Set(this.settings.searchIncludedFolders),s=new Set(this.settings.searchExcludedFolders),n=this.discoverStashpadFolders().filter(a=>e.size>0?e.has(a):!s.has(a)),r=(t||"").trim().replace(/\/+$/,""),o=n.filter(a=>a!==r);return r&&o.unshift(r),o}async maybeSweepFolder(t){let e=(t||"").trim().replace(/\/+$/,"");!e||this.sweptFolders.has(e)||(this.sweptFolders.add(e),setTimeout(()=>{this.runSweep(e,{silent:!0})},3e3))}async runIntegrityCheckOnFolder(t){let e=(t||"").trim().replace(/\/+$/,"");e&&await this.runSweep(e,{silent:!1})}async runSweep(t,e){try{let s=this.newLog(),i={},n=this.app.vault.getMarkdownFiles().filter(l=>l.path===t||l.path.startsWith(t+"/"));for(let l of n){let c=this.app.metadataCache.getFileCache(l)?.frontmatter,d=typeof c?.id=="string"?c.id.trim():"";if(!d)continue;let p=c&&"parent"in c?c.parent??null:null;i[d]={parent:p,path:l.path}}let r=await s.readState(),o=l=>l===t||l.startsWith(t+"/");if(!e.silent){for(let[l,c]of Object.entries(i)){let d=r[l];d?d.parent!==c.parent?await s.append({type:"parent_change",id:l,payload:{from:d.parent,to:c.parent}}):d.path!==c.path&&await s.append({type:"rename",id:l,payload:{from:d.path,to:c.path}}):await s.append({type:"create",id:l,payload:{path:c.path,parent:c.parent}})}for(let[l,c]of Object.entries(r))!i[l]&&o(c.path)&&await s.append({type:"missing",id:l,payload:{lastPath:c.path}})}let a={};for(let[l,c]of Object.entries(r))o(c.path)||(a[l]=c);for(let[l,c]of Object.entries(i))a[l]=c;await s.writeState(a)}catch(s){console.warn("Stashpad: integrity sweep failed",s)}}getUndoStack(t){let e=this.undoStacks.get(t);return e||(e=new is,this.undoStacks.set(t,e)),e}async onload(){await this.migrateLegacyPaths(),await this.loadSettings(),this.settingTab=new qe(this.app,this),this.addSettingTab(this.settingTab),this.registerView(vt,h=>new ts(h,this)),this.registerView(Wt,h=>new Ie(h,this)),this.registerView(Nt,h=>new Fe(h,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",h=>{h&&h.view.getViewType()===vt&&(this.lastActiveStashpadLeaf=h,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(Wt).length===0&&setTimeout(()=>{De(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let h=_t(),u=!!h&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===h,m=!!u&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",m),document.body.classList.toggle("stashpad-active",!!u)};this.register(js(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let e=h=>{try{let u=Array.from(document.querySelectorAll("style")).filter(m=>(m.textContent??"").includes(".stashpad-"));for(let m of u){let g=m.id||"",y=g?`style[data-stashpad-source="${g}"]`:null;if(y&&h.head.querySelector(y))continue;let S=h.createElement("style");g?S.setAttribute("data-stashpad-source",g):S.setAttribute("data-stashpad-source","anon"),S.textContent=m.textContent??"",h.head.appendChild(S)}}catch(u){console.warn("[Stashpad] inject popout styles failed",u)}};this.registerEvent(this.app.workspace.on("window-open",h=>{let u=h?.doc??h?.win?.document??null;u&&e(u)})),setTimeout(()=>{try{let h=this.app.workspace;typeof h.iterateAllLeaves=="function"&&h.iterateAllLeaves(u=>{let m=u?.view?.containerEl?.ownerDocument;m&&m!==document&&e(m)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let s=window.visualViewport,i=()=>{let h=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),u=h&&h.isConnected?h.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${u}px`);let m=0;s&&(m=Math.max(0,window.innerHeight-s.height-s.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${m}px`),document.body.classList.toggle("stashpad-keyboard-open",m>100)};i(),s&&(s.addEventListener("resize",i),s.addEventListener("scroll",i),this.register(()=>{s.removeEventListener("resize",i),s.removeEventListener("scroll",i)})),window.addEventListener("resize",i),this.register(()=>window.removeEventListener("resize",i)),requestAnimationFrame(i),setTimeout(i,250),setTimeout(i,1e3),this.addRibbonIcon("list-tree","Open Stashpad",()=>{if(this.discoverStashpadFolders().length===0){this.activateView({reveal:!0});return}this.openFolderPicker()}).addEventListener("contextmenu",h=>{h.preventDefault(),this.openFolderPicker()}),this.addRibbonIcon("panel-left","Open Stashpad panels (sidebar)",()=>{Ee(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{De(this.app)}),this.addCommand({id:"stashpad-open",name:"Open Stashpad in new tab",callback:()=>{if(this.discoverStashpadFolders().length>=2){this.openFolderPicker();return}this.activateView({reveal:!1})}}),this.addCommand({id:"stashpad-reveal",name:"Reveal or open Stashpad",callback:()=>void this.activateView({reveal:!0})});let r=h=>{let u=_t();u&&typeof u[h]=="function"&&u[h]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>r("toggleSplit")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>r("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>r("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>r("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>r("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>r("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>r("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>r("cmdCopyTree")}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>r("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>r("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Edit note in new tab (selection)",callback:()=>r("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>r("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>r("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>r("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>r("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>r("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>r("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>r("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>r("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>r("cmdClone")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>r("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>r("cmdToggleExpand")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>r("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>r("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>r("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>r("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>r("cmdSetDue")}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>r("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>r("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void Ee(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void De(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:h=>{let u=this.app.workspace.getActiveFile(),m=!!u&&u.extension==="md"&&this.isStashpadNoteFile(u);return h||m&&u&&this.revealNoteInStashpad(u),m}});let o=Object.keys(de);for(let h of o){let u=de[h];this.addCommand({id:`stashpad-open-panels-${h}`,name:`Open Stashpad panel: ${u.label}`,callback:async()=>{await Ee(this.app),this.app.workspace.getLeavesOfType(Nt)[0]?.view?.setActivePanel?.(h)}})}this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>r("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>r("cmdTogglePin")}),this.addCommand({id:"stashpad-open-tiny",name:"Open Stashpad in tiny window",callback:()=>void this.openTinyWindow()}),this.addCommand({id:"stashpad-clone-tab",name:"Clone (duplicate / copy) this Stashpad tab",callback:()=>r("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>r("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>r("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection to .stash",callback:()=>r("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>r("cmdImportStash")}),this.addCommand({id:"stashpad-pick-folder",name:"Stashpad: open / switch / create folder\u2026",callback:()=>this.openFolderPicker()}),this.addCommand({id:"stashpad-run-integrity-check",name:"Run integrity check on active Stashpad folder",checkCallback:h=>{let u=_t(),m=u&&u.noteFolder;return m?(h||(new at.Notice(`Running integrity check on "${m}"\u2026`),this.runIntegrityCheckOnFolder(m).then(()=>{new at.Notice("Integrity check complete \u2014 see Stashpad log.")})),!0):!1}}),this.addCommand({id:"stashpad-fix-orphans",name:"Set missing parents to Home (orphan fix)",callback:()=>void this.fixOrphanParents()}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:async()=>{new at.Notice("Stashpad: rebootstrapping\u2026");try{let{touched:h,fmChecked:u,fmWritten:m,slugsRenamed:g}=await this.rebootstrapAllFolders(),y=[];y.push(`rebootstrapped ${h.length} folder${h.length===1?"":"s"}`),m>0&&y.push(`updated ${m} note${m===1?"":"s"}' metadata`),g>0&&y.push(`renamed ${g} note${g===1?"":"s"}`),y.push(`(checked ${u} total)`),new at.Notice(`Stashpad: ${y.join(" \xB7 ")}`)}catch(h){new at.Notice(`Stashpad: rebootstrap failed (${h.message})`)}}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:h=>{let u=this.app.workspace.getActiveFile();return!u||u.extension!=="md"?!1:(h||this.adoptNote(u),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(Gt(),Te)).then(({NotificationHistoryModal:h,LogModal:u})=>{new h(this.app,this.notifications,async()=>{let m=this.app.vault.adapter,g=this.pluginPrivatePath("log.jsonl");if(!await m.exists(g)){new at.Notice("No log yet \u2014 make some changes first.");return}let y=await m.read(g);new u(this.app,y,g).open()},this.settings.authorId||null,m=>this.lookupNoteAuthorIds(m)).open()})}});let a=[{key:"prefixTimestampsOnCopy",label:"Prefix timestamps when copying"},{key:"useTemplatesFormat",label:"Use Templates plugin date/time formats"},{key:"autoNavOnMoveIn",label:"Auto-navigate into parent on move IN"},{key:"autoNavOnMoveOut",label:"Auto-navigate to destination on move OUT"},{key:"confirmCrossParentDrag",label:"Confirm cross-parent drag-and-drop"},{key:"confirmBulkDelete",label:"Confirm bulk deletes"},{key:"confirmAttachmentDelete",label:"Offer to delete attachments with note"},{key:"autofocusComposerAfterSend",label:"Autofocus composer after sending"},{key:"popoutDuplicates",label:"Open in new window \u2014 duplicate tab"},{key:"autoExpandCursorRow",label:"Expand the cursor row's body automatically"},{key:"autoOpenDetailPanel",label:"Auto-open the detail panel"},{key:"doubleClickToFocus",label:"Double-click a note to open it"}];for(let h of a){let u=`stashpad-toggle-${String(h.key).replace(/[A-Z]/g,m=>`-${m.toLowerCase()}`)}`;this.addCommand({id:u,name:`Toggle: ${h.label}`,callback:async()=>{let m=!this.settings[h.key];this.settings[h.key]=m,await this.saveSettings(),new at.Notice(`${h.label}: ${m?"ON":"OFF"}`)}})}this.addCommand({id:"stashpad-open-settings",name:"Open Stashpad settings",callback:()=>{let h=this.app.setting;!h?.open||!h?.openTabById||(h.open(),h.openTabById(this.manifest.id))}}),this.addCommand({id:"stashpad-search-settings",name:"Search Stashpad settings\u2026",callback:()=>{let h=this.app.setting;!h?.open||!h?.openTabById||(h.open(),h.openTabById(this.manifest.id),setTimeout(()=>this.settingTab?.focusSearchInput?.(),0))}});for(let h of Ke)this.addCommand({id:`stashpad-open-settings-${h.id}`,name:`Open Stashpad settings: ${h.label}`,callback:()=>{let u=this.app.setting;!u?.open||!u?.openTabById||(this.settingTab?.openToTab(h.id),u.open(),u.openTabById(this.manifest.id))}});let l=()=>{let h=this.app.setting;!h?.open||!h?.openTabById||(h.open(),h.openTabById(this.manifest.id),setTimeout(()=>{document.getElementById("stashpad-jd-index-section")?.scrollIntoView({behavior:"smooth",block:"start"})},100))};this.addCommand({id:"stashpad-preview-jd-index",name:"Preview JD index (overwrites home note body)",callback:async()=>{try{let{buildJdIndexPreview:h}=await Promise.resolve().then(()=>(fe(),je)),u=await h(this.app,this,this.settings);if(u.error==="no-dest"){new at.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}if(u.error==="no-home"){new at.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:m}=await Promise.resolve().then(()=>(fe(),je));m(this.app,u)}catch(h){console.error("[stashpad] preview failed",h),new at.Notice(`Preview failed: ${h?.message??h}`,8e3)}}}),this.addCommand({id:"stashpad-build-jd-index",name:"Build JD index notes (creates Stashpad-note hierarchy)",callback:async()=>{try{let{buildJdIndexNotes:h,scanForJdNotes:u,JdBuildConfirmModal:m}=await Promise.resolve().then(()=>(fe(),je));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new at.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}let y=u(this.app,this,this.settings);new m(this.app,this,this.settings,y.indexed.length,async()=>{try{let k=await h(this.app,this,this.settings);if(k.error==="no-dest"){new at.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}if(k.error==="dest-not-stashpad"){new at.Notice(`"${k.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),l();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new at.Notice(`Index built: ${k.created} created, ${k.updated} updated, ${k.skipped} skipped \u2192 ${k.destFolder}`,6e3)}catch(k){console.error("[stashpad] build failed",k),new at.Notice(`Build failed: ${k?.message??k}`,8e3)}}).open()}catch(h){console.error("[stashpad] build failed",h),new at.Notice(`Build failed: ${h?.message??h}`,8e3)}}});let c=h=>{if(h.extension!==ve)return;let u=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),m=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!u)return;let g=h.parent?.path||"";if((g.split("/").pop()??"")!==u||m&&g.endsWith(`/${m}`))return;let S=g.slice(0,g.length-u.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(h,S)};this.registerEvent(this.app.vault.on("create",h=>{h instanceof at.TFile&&c(h)})),this.registerEvent(this.app.vault.on("rename",h=>{h instanceof at.TFile&&c(h)}));let d=h=>{if(h.extension!=="md")return;let u=h.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(u)&&setTimeout(()=>{this.fixOrphanParentForFile(h)},800)},p=h=>{if(h.extension!=="md")return;let u=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!u)return;let m=h.parent?.path?.replace(/\/+$/,"")??"";if((m.split("/").pop()??"")!==u)return;let y=m.slice(0,m.length-u.length).replace(/\/+$/,"");!y||!this.discoverStashpadFolders().includes(y)||setTimeout(()=>{this.adoptMarkdownDrop(h,y)},200)};this.registerEvent(this.app.vault.on("create",h=>{h instanceof at.TFile&&(d(h),p(h))})),this.registerEvent(this.app.vault.on("rename",h=>{h instanceof at.TFile&&(d(h),p(h))})),this.registerEvent(this.app.vault.on("rename",(h,u)=>{h instanceof at.TFile&&this.maybeAdoptAuthorRename(h,u)}))}parseAuthorFilePath(t){let e=t.match(/\/_authors\/([^/]+?)-([a-z0-9]{4,12})\.md$/i);return e?{name:e[1].replace(/-/g," "),id:e[2]}:null}authorNameToSafe(t){return t.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author"}async syncAuthorFilesToName(){let t=(this.settings.authorId??"").trim(),e=(this.settings.authorName??"").trim();if(!t||!e)return;let s=this.authorNameToSafe(e);for(let i of this.discoverStashpadFolders()){let n=`${i}/_authors`;if(await this.app.vault.adapter.exists(n))for(let r of this.app.vault.getMarkdownFiles()){if(!r.path.startsWith(n+"/"))continue;let o=this.parseAuthorFilePath(r.path);if(!o||o.id!==t)continue;let a=`${n}/${s}-${t}.md`,l=r;if(r.path!==a)try{this.authorRenameInFlight.add(r.path),this.authorRenameInFlight.add(a),await this.app.fileManager.renameFile(r,a);let c=this.app.vault.getAbstractFileByPath(a);c&&(l=c)}catch(c){console.warn("[Stashpad] author file rename failed",c);continue}try{await this.refreshAuthorStub(l)}catch{}}}}async refreshAuthorStub(t){let e=(this.settings.authorName??"").trim(),s=(this.settings.authorRole??"").trim(),i=(this.settings.authorDepartment??"").trim();if(e)try{let n=await this.app.vault.read(t),r=n.replace(/^# .*$/m,`# ${e}`);r!==n&&await this.app.vault.modify(t,r),await this.app.fileManager.processFrontMatter(t,o=>{o.name=e,s?o.role=s:delete o.role,i?o.department=i:delete o.department})}catch(n){console.warn("[Stashpad] refreshAuthorStub failed",n)}}async maybeAdoptAuthorRename(t,e){if(this.authorRenameInFlight.delete(t.path)||this.authorRenameInFlight.delete(e))return;let s=this.parseAuthorFilePath(t.path);if(!s)return;let i=(this.settings.authorId??"").trim();if(!i||s.id!==i)return;let n=s.name.trim();!n||n===(this.settings.authorName??"").trim()||(this.settings.authorName=n,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(t,e){try{let s=this.app.vault.adapter,i=t.name,n=i.lastIndexOf("."),r=n>0?i.slice(0,n):i,o=n>0?i.slice(n):"",a=0;for(;await s.exists(`${e}/${i}`);)a+=1,i=`${r}-${a}${o}`;let l=`${e}/${i}`;await this.app.fileManager.renameFile(t,l);let c=this.app.vault.getAbstractFileByPath(l);c instanceof at.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(c)},500),this.notifications.show({message:`Imported \`${t.name}\` \u2192 \`${e}\``,kind:"success",category:"import",folder:e,affectedPaths:[l]})}catch(s){console.warn("Stashpad: markdown drop adoption failed",s),this.notifications.show({message:`Couldn't import \`${t.name}\`: ${s.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(t){try{let e=this.app.metadataCache.getFileCache(t)?.frontmatter,s=typeof e?.id=="string"?e.id.trim():"",i=e?.parent,n=typeof i=="string"?i.trim()!=="":i!=null,r=typeof e?.created=="string"&&e.created.trim()!=="",o=!s,a=!n,l=!r;if(!o&&!a&&!l)return;let{newId:c}=await Promise.resolve().then(()=>(Rt(),Be)),d,p=!1,h=!1;if(await this.app.fileManager.processFrontMatter(t,g=>{if(o&&(typeof g.id=="string"&&g.id.trim()||(d=c(),g.id=d)),a){let y=g.parent;(typeof y=="string"?y.trim()!=="":y!=null)||(g.parent=B,p=!0)}l&&(typeof g.created=="string"&&g.created.trim()||(g.created=new Date(t.stat.ctime).toISOString(),h=!0))}),!d&&!p&&!h)return;let u=this.newLog(),m=d||s;m&&await u.append({type:"parent_change",id:m,payload:{from:null,to:B,reason:"orphan_auto_fix",path:t.path,addedId:!!d,addedParent:p,addedCreated:h}}),new at.Notice(`Adopted ${t.basename} \u2192 Home`)}catch(e){console.warn("Stashpad: orphan auto-fix failed",e)}}async autoImportStash(t,e){try{let s=new Uint8Array(await this.app.vault.readBinary(t)),i=_t(),n=new Set;if(i&&typeof i.collectExistingIds=="function"&&i.noteFolder===e)for(let a of i.collectExistingIds())n.add(a);else for(let a of this.app.vault.getMarkdownFiles()){if(!a.path.startsWith(e+"/"))continue;let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id;typeof l=="string"&&n.add(l)}let r=await Je(this.app,s,e,n);try{await this.newLog().append({type:"stash_import",id:B,payload:{from:t.path,into:e,noteCount:r.notesWritten,attachmentsWritten:r.attachmentsWritten,collisionsRenamed:r.collisionsRenamed,auto:!0}})}catch{}try{await this.app.fileManager.trashFile(t)}catch{}let o=[`Auto-imported ${r.notesWritten} note${r.notesWritten===1?"":"s"} from ${t.name}`];r.attachmentsWritten&&o.push(`+ ${r.attachmentsWritten} attachment${r.attachmentsWritten===1?"":"s"}`),r.collisionsRenamed&&o.push(`(${r.collisionsRenamed} renamed)`),this.notifications.show({message:o.join(" "),kind:"success",category:"import",folder:e}),i&&typeof i.debouncedRender=="function"&&i.debouncedRender()}catch(s){this.notifications.show({message:`Stashpad: auto-import failed +${e.format("HH:mm A")}`}formatTimeInline(t){if(!t)return"";let e=(0,N.moment)(t);if(!e.isValid())return"";if(wt().useTemplatesFormat){let i=Je(this.app);if(i){let n=/:ss/.test(i.timeFormat)?i.timeFormat:i.timeFormat.replace(/(:mm)/,"$1:ss");return`${e.format(i.dateFormat)} ${e.format(n)}`}}return`${e.format("YYYY.MM.DD")} ${e.format("HH:mm:ss A")}`}scrollListToBottom(){let t=this.listEl;if(!t)return;if(this.stickToListBottom=!0,t.scrollTop=t.scrollHeight,N.Platform.isMobile){let o=0,a=()=>{!this.stickToListBottom||o>=8||(o++,Date.now()>=this.keyboardTransitionUntil&&(t.scrollTop=t.scrollHeight),window.setTimeout(a,120))};window.setTimeout(a,60);return}this.stickyRowObserver?.disconnect();let e=()=>{if(!this.stickToListBottom){this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null;return}t.scrollTop=t.scrollHeight},s=new ResizeObserver(e);for(let o of Array.from(t.children))o instanceof HTMLElement&&s.observe(o);this.stickyRowObserver=s;let i=performance.now(),n=t.scrollHeight,r=()=>{if(!this.stickToListBottom)return;let o=t.scrollHeight;o!==n&&(t.scrollTop=o,n=o),performance.now()-i<3e4?requestAnimationFrame(r):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(r)}openNoteMenu(t,e){if(!e.file)return;let s=e.file,i=new N.Menu;i.addItem(a=>a.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(e.id)})),i.addItem(a=>a.setTitle("Open in editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(s)})),i.addItem(a=>a.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(e.id))),i.addSeparator(),i.addItem(a=>a.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(e))),i.addItem(a=>a.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdClone()})),i.addItem(a=>a.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),i.addItem(a=>a.setTitle("Export to .stash").setIcon("package").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdExportStash()})),i.addSeparator(),i.addItem(a=>a.setTitle("Move to\u2026").setIcon("move").onClick(()=>this.cmdMovePicker())),i.addItem(a=>a.setTitle("Move to Home").setIcon("home").onClick(async()=>{await this.changeParent(e,R),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==R&&this.navigateTo(R)}));let n={folder:this.noteFolder,id:e.id},r=this.plugin.isPinned(n);i.addItem(a=>a.setTitle(r?"Unpin from sidebar":"Pin to sidebar").setIcon(r?"pin-off":"pin").onClick(async()=>{r?await this.plugin.unpinNote(n):await this.plugin.pinNote(n)})),i.addItem(a=>a.setTitle("Set color\u2026").setIcon("palette").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdSetColor()}));let o=this.isCompleted(e);i.addItem(a=>a.setTitle(o?"Mark incomplete":"Mark complete").setIcon(o?"circle":"check-circle").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdToggleComplete()})),i.addSeparator(),i.addItem(a=>a.setTitle("Delete").setIcon("trash").onClick(async()=>{await this.deleteNote(e)})),i.showAtMouseEvent(t)}async deleteNote(t){if(!t.file)return;let e=[],s=p=>{for(let m of this.tree.getChildren(p.id))s(m),e.push(m)};s(t);let i=[...e,t],n=i.filter(p=>!!p.file),r=await Promise.all(n.map(p=>this.app.vault.cachedRead(p.file))),o=[];for(let p=0;p<n.length;p++){let m=n[p];o.push(...this.extractAttachments(this.stripFrontmatter(r[p])));let v=this.app.metadataCache.getFileCache(m.file)?.frontmatter;if(Array.isArray(v?.attachments))for(let y of v.attachments)typeof y=="string"&&y.trim()&&o.push(y)}let a=[...new Set(o)],l=this.collectAuthorIds(i),c=async p=>{let m=await this.snapshotNotes(i,p),v=0;if(p)for(let O of a){let F=this.app.metadataCache.getFirstLinkpathDest(O,"");if(F)try{await this.app.fileManager.trashFile(F),await this.log.append({type:"attachment_remove",id:R,payload:{path:F.path}}),this.plugin.notifications.show({message:`Deleted attachment "${F.name}"`,kind:"warning",category:"attachment",affectedPaths:[F.path],folder:this.noteFolder}),v+=1}catch{}}let y=new Set;for(let O of i)O.parent&&y.add(O.parent);let b=this.currentChildren.findIndex(O=>O.id===t.id),k=null;if(b>=0){for(let O=b+1;O<this.currentChildren.length;O++)if(this.currentChildren[O].id!==t.id){k=this.currentChildren[O].id;break}if(!k){for(let O=b-1;O>=0;O--)if(this.currentChildren[O].id!==t.id){k=this.currentChildren[O].id;break}}}for(let O of i)if(O.file){try{await this.app.fileManager.trashFile(O.file)}catch{}await this.log.append({type:"delete",id:O.id,payload:{path:O.file.path,attachmentsRemoved:p?a:[]}})}this.selection.clear(),this.cursorIdx=-1,k&&(this.pendingFocusIds=[k]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let O of y)i.some(F=>F.id===O)||this.fmSync.scheduleParentOfDeleted(O);let C=this.noteFolder,E=`Delete "${this.titleForNode(t)}"`,I=t.id,A=v>0?` with ${v} attachment${v===1?"":"s"}`:"";this.plugin.notifications.show({message:`Deleted "${this.titleForNode(t)}"${A}`,kind:"warning",category:"delete",affectedIds:[t.id],affectedAuthorIds:l,folder:this.noteFolder}),this.plugin.getUndoStack(C).push({label:E,undo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(m,[I])},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,await this.trashNotesAndAttachments(m)}})},h=wt(),u=e.length>0&&h.confirmBulkDelete,d=a.length>0&&h.confirmAttachmentDelete;if(!u&&!d){await c(!1),this.focusView();return}new Zt(this.app,this.titleForNode(t),e.length,a.length,d,async p=>{await c(p),this.focusView()}).open()}async cmdSwapWithParent(){let t=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!t?.file){new N.Notice("Pick a note first (move the cursor onto it).");return}if(!t.parent||t.parent===R){new N.Notice("Already at Home \u2014 no parent to swap with.");return}let e=this.tree.get(t.parent);if(!e?.file){new N.Notice("Couldn't find the parent note.");return}let s=e.parent??R,i=this.titleForNode(t),n=this.titleForNode(e),r=this.tree.getChildren(e.id).filter(a=>a.id!==t.id).length,o=[`"${n}" becomes a child of "${i}".`];r>0&&o.push(`${r} sibling${r===1?"":"s"} move with it.`),new Ft(this.app,"Swap notes?",o.join(` +`),"Swap",async a=>{a&&await this.swapParentChild(e,t,s)}).open()}offerSwapForDescendantMove(t,e){let s=this.tree.get(e);if(!s?.file){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",affectedIds:[t.id],folder:this.noteFolder});return}if(s.parent!==t.id){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under "${this.titleForNode(s)}" \u2014 it's a deeper descendant. Only direct parent \u2194 child swaps are supported (try moving "${this.titleForNode(s)}" up first, then swap).`,kind:"warning",category:"move",affectedIds:[t.id,s.id],folder:this.noteFolder});return}let i=this.titleForNode(t),n=this.titleForNode(s),r=this.tree.getChildren(t.id).filter(a=>a.id!==s.id).length,o=[`"${i}" becomes a child of "${n}".`];r>0&&o.push(`${r} sibling${r===1?"":"s"} move with it.`),new Ft(this.app,"Confirm Note Swap",o.join(` +`),"Swap",async a=>{if(!a)return;let l=t.parent??R;await this.swapParentChild(t,s,l)}).open()}async swapParentChild(t,e,s){if(!t.file||!e.file)return;if(e.parent!==t.id){new N.Notice("Swap aborted: parent/child relationship changed.");return}let i=this.noteFolder,n=t.parent,r=this.tree.getChildren(t.id).filter(d=>d.id!==e.id).filter(d=>!!d.file),o=r.map(d=>({id:d.id,path:d.file.path,was:d.parent})),a=this.order.getOrder(i,s).slice(),l=this.order.getOrder(i,e.id).slice(),c=this.order.getOrder(i,t.id).slice();await this.app.fileManager.processFrontMatter(e.file,d=>{d.parent=s}),this.fmSync.scheduleParentChange(e.id,t.id,s),await this.app.fileManager.processFrontMatter(t.file,d=>{d.parent=e.id}),this.fmSync.scheduleParentChange(t.id,n,e.id);for(let d of r)await this.app.fileManager.processFrontMatter(d.file,p=>{p.parent=e.id}),this.fmSync.scheduleParentChange(d.id,t.id,e.id);if(a.length>0){let d=a.includes(t.id)?a.map(p=>p===t.id?e.id:p):[...a.filter(p=>p!==e.id),e.id];this.order.setOrder(i,s,d)}let h=r.map(d=>d.id),u=[t.id,...l.filter(d=>d!==t.id&&!h.includes(d)),...h];this.order.setOrder(i,e.id,u),this.order.setOrder(i,t.id,[]),await this.order.save(i),await this.log.append({type:"parent_change",id:e.id,payload:{from:t.id,to:s,reason:"swap"}}),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e.id,reason:"swap"}});for(let d of o)await this.log.append({type:"parent_change",id:d.id,payload:{from:d.was,to:e.id,reason:"swap"}});this.tree.rebuild(i),this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"}),this.plugin.notifications.show({message:`Swapped "${this.titleForNode(e)}" \u2194 "${this.titleForNode(t)}".`,kind:"success",category:"move",affectedIds:[e.id,t.id,...h],folder:i}),this.plugin.getUndoStack(i).push({label:`Swap "${this.titleForNode(e)}" \u2194 parent`,undo:async()=>{let d=this.tree.get(t.id),p=this.tree.get(e.id);d?.file&&await this.app.fileManager.processFrontMatter(d.file,m=>{n==null||n===R?(delete m.parent,m.parent=R):m.parent=n}),p?.file&&await this.app.fileManager.processFrontMatter(p.file,m=>{m.parent=t.id});for(let m of o){let v=this.app.vault.getAbstractFileByPath(m.path);v&&await this.app.fileManager.processFrontMatter(v,y=>{m.was==null?y.parent=R:y.parent=m.was})}this.order.setOrder(i,s,a),this.order.setOrder(i,e.id,l),this.order.setOrder(i,t.id,c),await this.order.save(i),this.tree.rebuild(i),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(t,e,s)}})}async changeParent(t,e,s={record:!0}){if(!t.file)return;let i=t.file,n=t.parent,r=a=>a??R;if(r(n)===r(e)){if(!s.quiet){let a=this.titleForNode(t),l=e===R?"Home":`"${this.titleForNode(this.tree.get(e)??t)}"`;this.plugin.notifications.show({message:`"${a}" is already under ${l}.`,kind:"info",category:"move",affectedIds:[t.id],folder:this.noteFolder})}return}if(e===t.id){s.quiet||this.plugin.notifications.show({message:`Can't move "${this.titleForNode(t)}" into itself.`,kind:"warning",category:"move",affectedIds:[t.id],folder:this.noteFolder});return}if(e!==R&&this.isDescendant(e,t.id)){s.quiet||this.offerSwapForDescendantMove(t,e);return}let o=this.collectAuthorIds([t]);if(await this.app.fileManager.processFrontMatter(i,a=>{a.parent=e}),this.fmSync.scheduleParentChange(t.id,n,e),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e}}),this.pendingFocusIds=[t.id],this.focusId!==e&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),!s.quiet){let a=this.tree.get(e),l=a?this.titleForNode(a):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(t)}" \u2192 "${l}"`,kind:"success",category:"move",affectedIds:[t.id],affectedAuthorIds:o,folder:this.noteFolder,actions:e===R?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]})}if(s.record!==!1){let a=this.noteFolder,l=i.path,c=t.id;this.plugin.getUndoStack(a).push({label:"Move note",undo:async()=>{let h=this.app.vault.getAbstractFileByPath(l);if(h){await this.app.fileManager.processFrontMatter(h,u=>{u.parent=n}),this.pendingFocusIds=[c],this.focusId!==n&&this.focusId!==e?(this.selection.clear(),this.cursorIdx=-1):this.focusId===e&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(a),this.render({kind:"follow-cursor"});{let u=this.selectionGuardKey,d=()=>{if(this.selectionGuardKey!==u||this.selection.has(c))return;let p=this.currentChildren.findIndex(m=>m.id===c);p<0||(this.selection.add(c),this.cursorIdx=p,this.render({kind:"follow-cursor"}))};setTimeout(d,120),setTimeout(d,400)}}},redo:async()=>{let h=this.app.vault.getAbstractFileByPath(l);if(h){await this.app.fileManager.processFrontMatter(h,u=>{u.parent=e}),this.pendingFocusIds=[c],this.focusId!==e&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(a),this.render({kind:"follow-cursor"});{let u=this.selectionGuardKey,d=()=>{if(this.selectionGuardKey!==u||this.selection.has(c))return;let p=this.currentChildren.findIndex(m=>m.id===c);p<0||(this.selection.add(c),this.cursorIdx=p,this.render({kind:"follow-cursor"}))};setTimeout(d,120),setTimeout(d,400)}}}})}}};It.CONTRIB_DEBOUNCE_MS=4e3,It.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,It.EXTERNAL_WRITE_GRACE_MS=1500,It.EXTERNAL_QUIESCENCE_MS=5e3;var ss=It;function $i(g,f){return!f||g.metaKey||g.ctrlKey||g.altKey?!1:g.key.toLowerCase()===f.toLowerCase()}function se(g,f){return f?f.includes("+")?Ri(g,f):$i(g,f):!1}function ot(g,f){if(!f)return!1;let{primary:t,secondary:e,preferRight:s,useBoth:i}=f;return t&&e?i?se(g,t)||se(g,e):s?se(g,e):se(g,t):se(g,t)||se(g,e)}function Is(g){if(!g)return"";let f=N.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac");return g.split("+").map(t=>{let e=t.trim();return e?e.toLowerCase()==="mod"?f?"Cmd":"Ctrl":e.toLowerCase()==="alt"?f?"Opt":"Alt":e.length===1?e.toUpperCase():e:""}).filter(Boolean).join("+")}function Ri(g,f){if(!f)return!1;let t=f.split("+").map(h=>h.trim()).filter(Boolean);if(t.length<2)return!1;let e=t[t.length-1].toLowerCase(),s=new Set(t.slice(0,-1).map(h=>h.toLowerCase())),i=s.has("mod"),n=s.has("ctrl")||s.has("control"),r=s.has("cmd")||s.has("meta")||s.has("command"),o=s.has("alt")||s.has("option"),a=s.has("shift"),c=N.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac")?g.metaKey:g.ctrlKey;return i&&!c||n&&!g.ctrlKey||r&&!g.metaKey||o!==g.altKey||a!==g.shiftKey||!i&&(!n&&g.ctrlKey||!r&&g.metaKey)?!1:g.key.toLowerCase()===e}function Bi(g){let f=[],t=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,e;for(;(e=t.exec(g))!=null;)f.push({lang:e[3].trim(),code:e[4]});return f}function is(g){return g.split("/").map(f=>f.split(" ").map(t=>t&&/^[a-z]/.test(t)?t[0].toUpperCase()+t.slice(1):t).join(" ")).join("/")}function Hi(g,f,t){let e=new Set(f),s=g.filter(n=>!e.has(n)),i=g.findIndex(n=>e.has(n));if(i<0)return g.slice();switch(t){case"top":return[...f,...s];case"bottom":return[...s,...f];case"up":{let n=Math.max(0,i-1),r=s.slice();return r.splice(n,0,...f),r}case"down":{let n=(()=>{let l=-1;return g.forEach((c,h)=>{e.has(c)&&(l=h)}),l})(),r=0;for(let l=0;l<Math.min(g.length,n+2);l++)e.has(g[l])||r++;let o=Math.min(s.length,r),a=s.slice();return a.splice(o,0,...f),a}}}function oi(g,f){if(g.length!==f.length)return!1;for(let t=0;t<g.length;t++)if(g[t]!==f[t])return!1;return!0}ue();var ns=class{constructor(f,t,e){this.app=f;this.dirOk=!1;this.writeChain=Promise.resolve();this.baseDir=t.replace(/\/+$/,""),this.logPath=`${this.baseDir}/log.jsonl`,this.statePath=`${this.baseDir}/state.json`,this.getAuthor=e??(()=>"")}getLogPath(){return this.logPath}getDir(){return this.baseDir}async ensureDir(){if(this.dirOk)return;let f=this.app.vault.adapter,t=this.baseDir.split("/").filter(Boolean),e="";for(let s of t)e=e?`${e}/${s}`:s,await f.exists(e)||await f.mkdir(e);this.dirOk=!0}append(f){let t=f.author??this.getAuthor()??"",e={ts:new Date().toISOString(),...f};t?e.author=t:delete e.author;let s=JSON.stringify(e)+` +`;return this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let i=this.app.vault.adapter;if(typeof i.append=="function")await i.append(this.logPath,s);else{let n=await i.exists(this.logPath)?await i.read(this.logPath):"";await i.write(this.logPath,n+s)}}catch(i){console.warn("Stashpad: log append failed",i)}}),Promise.resolve()}async readState(){let f=this.app.vault.adapter;if(!await f.exists(this.statePath))return{};try{return JSON.parse(await f.read(this.statePath))}catch{return{}}}async writeState(f){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(f,null,2))}};Ct();var rs=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(f){for(this.undoStack.push(f),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let f=this.undoStack.pop();if(!f)return null;try{await f.undo()}catch(t){throw console.error("Stashpad: undo failed",t),t}return this.redoStack.push(f),f}async redo(){let f=this.redoStack.pop();if(!f)return null;try{await f.redo()}catch(t){throw console.error("Stashpad: redo failed",t),t}return this.undoStack.push(f),f}peekUndoLabel(){return this.undoStack[this.undoStack.length-1]?.label??null}peekRedoLabel(){return this.redoStack[this.redoStack.length-1]?.label??null}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}clear(){this.undoStack=[],this.redoStack=[]}};var as=class{constructor(f,t){this.app=f;this.data={version:1,authors:{}};this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${t.replace(/\/+$/,"")}/authors.json`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let f=this.app.vault.adapter;if(await f.exists(this.path)){let t=JSON.parse(await f.read(this.path));t&&typeof t=="object"&&t.authors&&(this.data={version:typeof t.version=="number"?t.version:1,authors:t.authors})}}catch(f){console.warn("[Stashpad] author registry load failed; starting empty",f),this.data={version:1,authors:{}}}}}all(){return Object.values(this.data.authors).sort((f,t)=>(t.lastSeen??"").localeCompare(f.lastSeen??""))}get(f){return this.data.authors[f]??null}record(f){let t=(f.id??"").trim();if(!t)return!1;let e=f.at??new Date().toISOString(),s=(f.name??"").trim(),i=this.data.authors[t],n=!1;if(!i)this.data.authors[t]={id:t,name:s,role:f.role?.trim()||void 0,department:f.department?.trim()||void 0,firstSeen:e,lastSeen:e,renames:[]},n=!0;else{if(s&&s!==i.name&&(i.renames.push({from:i.name,to:s,at:e}),i.name=s,n=!0),f.role!==void 0){let r=f.role.trim()||void 0;r!==i.role&&(i.role=r,n=!0)}if(f.department!==void 0){let r=f.department.trim()||void 0;r!==i.department&&(i.department=r,n=!0)}i.lastSeen=e}return n&&this.save(),n}replaceAll(f,t){let e=t??new Date().toISOString(),s={};for(let i of f){let n=(i.id??"").trim();if(!n)continue;let r=this.data.authors[n],o=(i.name??"").trim()||r?.name||"",a=r?.renames?[...r.renames]:[];r&&o&&o!==r.name&&a.push({from:r.name,to:o,at:e}),s[n]={id:n,name:o,role:i.role?.trim()||r?.role||void 0,department:i.department?.trim()||r?.department||void 0,firstSeen:r?.firstSeen??e,lastSeen:e,renames:a}}this.data={version:1,authors:s},this.save()}async ensureDir(){if(this.dirOk)return;let f=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),s="";for(let i of e)s=s?`${s}/${i}`:i,await f.exists(s)||await f.mkdir(s);this.dirOk=!0}save(){return this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir(),await this.app.vault.adapter.write(this.path,JSON.stringify(this.data,null,2))}catch(f){console.warn("[Stashpad] author registry save failed",f)}}),this.writeChain}};var os=class extends it.Plugin{constructor(){super(...arguments);this.settings={...Bt};this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.settingTab=null;this.stashpadSelectionListeners=new Set;this.stashpadContentListeners=new Set;this._notifications=null;this._authorRegistry=null;this.sweptFolders=new Set;this.notifiedBuildVersion=null;this.authorRenameInFlight=new Set;this.notifPersistenceWired=!1;this.notifSaveTimer=null;this.LAST_CURSOR_LS_KEY="stashpad:last-cursor";this.writeChain=Promise.resolve()}get notifications(){return this._notifications||(this._notifications=new Re(this.app)),this._notifications}get authorRegistry(){return this._authorRegistry||(this._authorRegistry=new as(this.app,this.pluginPrivatePath())),this._authorRegistry}pluginPrivatePath(t=""){let s=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return t?`${s}/${t.replace(/^\/+/,"")}`:s}newLog(){return new ns(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let t=this.app.vault.adapter,e=this.pluginPrivatePath(),s=async()=>{let o=e.split("/").filter(Boolean),a="";for(let l of o)a=a?`${a}/${l}`:l,await t.exists(a)||await t.mkdir(a)},i=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await t.exists(i)&&!await t.exists(n))try{await s();let o=await t.read(i);await t.write(n,o),console.debug("[Stashpad] migrated data.json \u2192",n)}catch(o){console.warn("Stashpad: data.json migration failed",o)}let r=".stashpad";if(await t.exists(r))try{await s();let o=await t.list(r);for(let a of o.files){let l=a.replace(/^.*\//,""),c=this.pluginPrivatePath(l);if(!await t.exists(c))try{let h=await t.read(a);await t.write(c,h),console.debug("[Stashpad] migrated",a,"\u2192",c)}catch(h){console.warn(`Stashpad: failed to migrate ${a}`,h)}}}catch(o){console.warn("Stashpad: .stashpad migration scan failed",o)}}async loadData(){let t=this.app.vault.adapter,e=this.pluginPrivatePath("data.json");if(!await t.exists(e))return null;try{return JSON.parse(await t.read(e))}catch(s){return console.warn("Stashpad: data.json parse failed",s),null}}async saveData(t){let e=this.app.vault.adapter,s=this.pluginPrivatePath();if(!await e.exists(s)){let i=s.split("/").filter(Boolean),n="";for(let r of i)n=n?`${n}/${r}`:r,await e.exists(n)||await e.mkdir(n)}await e.write(this.pluginPrivatePath("data.json"),JSON.stringify(t,null,2))}async createNewStashpad(t){let e=t.trim().replace(/^\/+|\/+$/g,"");if(!e)throw new Error("Folder name is empty");let s=this.app.vault.adapter,i=e.split("/").filter(Boolean),n="";for(let l of i)n=n?`${n}/${l}`:l,await s.exists(n)||await s.mkdir(n);let r=`${e}/Home.md`;if(await s.exists(r)){let l=this.app.vault.getAbstractFileByPath(r);l&&await this.app.fileManager.processFrontMatter(l,c=>{(typeof c.id!="string"||!c.id)&&(c.id=R),"parent"in c||(c.parent=null),(typeof c.created!="string"||!c.created)&&(c.created=new Date().toISOString())});return}let o=new Date().toISOString(),a=["---",`id: ${R}`,"parent: null",`created: ${o}`,"---","Home"].join(` +`);await this.app.vault.create(r,a);try{await this.seedLocalAuthorStub(e)}catch{}}collectColorsInFolder(t){let e=new Map,s=t.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let r=n.parent?.path?.replace(/\/+$/,"")??"";if(r!==s&&!r.startsWith(s+"/"))continue;let o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=typeof o?.color=="string"?o.color.trim():"";if(!a||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(a))continue;let l=a.toLowerCase();e.set(l,(e.get(l)??0)+1)}let i=[...e.entries()].map(([n,r])=>({hex:n,count:r}));return i.sort((n,r)=>r.count-n.count||n.hex.localeCompare(r.hex)),i}async recolorAllInFolder(t,e,s){let i=t.replace(/\/+$/,""),n=e.toLowerCase(),r=0;for(let a of this.app.vault.getMarkdownFiles()){let l=a.parent?.path?.replace(/\/+$/,"")??"";if(l!==i&&!l.startsWith(i+"/"))continue;let c=this.app.metadataCache.getFileCache(a)?.frontmatter;if((typeof c?.color=="string"?c.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(a,u=>{s?u.color=s:delete u.color}),r++}catch(u){console.warn(`Stashpad: recolor failed for ${a.path}`,u)}}let o=this.settings.colorAliases?.[i];if(o){let a=o[n];a&&(delete o[n],s&&(o[s.toLowerCase()]=a),Object.keys(o).length===0&&delete this.settings.colorAliases[i],await this.saveSettings())}return r}getColorAlias(t,e){let s=t.replace(/\/+$/,""),i=this.settings.colorAliases?.[s];if(!i)return;let n=i[e.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(t,e,s){let i=t.replace(/\/+$/,""),n=e.toLowerCase();this.settings.colorAliases||(this.settings.colorAliases={}),this.settings.colorAliases[i]||(this.settings.colorAliases[i]={});let r=this.settings.colorAliases[i],o=s.trim();o?r[n]=o:delete r[n],Object.keys(r).length===0&&delete this.settings.colorAliases[i],await this.saveSettings()}async waitForStashpadFolder(t,e=2e3){let s=t.trim().replace(/^\/+|\/+$/g,"");if(!s)return;let i=Date.now();for(;Date.now()-i<e;){if(this.discoverStashpadFolders().includes(s))return;await new Promise(n=>setTimeout(n,80))}}discoverStashpadFolders(){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){let s=this.app.metadataCache.getFileCache(e)?.frontmatter;if(typeof s?.id!="string"||!s.id.trim()||!s||!("parent"in s))continue;let i=e.parent?.path?.replace(/\/+$/,"")??"";i&&t.add(i)}return[...t].sort()}searchableFolders(t){let e=new Set(this.settings.searchIncludedFolders),s=new Set(this.settings.searchExcludedFolders),n=this.discoverStashpadFolders().filter(a=>e.size>0?e.has(a):!s.has(a)),r=(t||"").trim().replace(/\/+$/,""),o=n.filter(a=>a!==r);return r&&o.unshift(r),o}async maybeSweepFolder(t){let e=(t||"").trim().replace(/\/+$/,"");!e||this.sweptFolders.has(e)||(this.sweptFolders.add(e),setTimeout(()=>{this.runSweep(e,{silent:!0})},3e3))}async runIntegrityCheckOnFolder(t){let e=(t||"").trim().replace(/\/+$/,"");e&&await this.runSweep(e,{silent:!1})}async runSweep(t,e){try{let s=this.newLog(),i={},n=this.app.vault.getMarkdownFiles().filter(l=>l.path===t||l.path.startsWith(t+"/"));for(let l of n){let c=this.app.metadataCache.getFileCache(l)?.frontmatter,h=typeof c?.id=="string"?c.id.trim():"";if(!h)continue;let u=c&&"parent"in c?c.parent??null:null;i[h]={parent:u,path:l.path}}let r=await s.readState(),o=l=>l===t||l.startsWith(t+"/");if(!e.silent){for(let[l,c]of Object.entries(i)){let h=r[l];h?h.parent!==c.parent?await s.append({type:"parent_change",id:l,payload:{from:h.parent,to:c.parent}}):h.path!==c.path&&await s.append({type:"rename",id:l,payload:{from:h.path,to:c.path}}):await s.append({type:"create",id:l,payload:{path:c.path,parent:c.parent}})}for(let[l,c]of Object.entries(r))!i[l]&&o(c.path)&&await s.append({type:"missing",id:l,payload:{lastPath:c.path}})}let a={};for(let[l,c]of Object.entries(r))o(c.path)||(a[l]=c);for(let[l,c]of Object.entries(i))a[l]=c;await s.writeState(a)}catch(s){console.warn("Stashpad: integrity sweep failed",s)}}getUndoStack(t){let e=this.undoStacks.get(t);return e||(e=new rs,this.undoStacks.set(t,e)),e}async onload(){await this.migrateLegacyPaths(),await this.loadSettings(),this.settingTab=new Ge(this.app,this),this.addSettingTab(this.settingTab),await this.authorRegistry.load();{let d=(this.settings.authorId??"").trim();d&&this.authorRegistry.record({id:d,name:this.settings.authorName,role:this.settings.authorRole,department:this.settings.authorDepartment})}this.app.workspace.onLayoutReady(()=>{window.setTimeout(()=>{this.seedLocalAuthorStubsEverywhere()},4e3)}),this.registerView(mt,d=>new ss(d,this)),this.registerView(Ht,d=>new De(d,this)),this.registerView(_t,d=>new Ie(d,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",d=>{d&&d.view.getViewType()===mt&&(this.lastActiveStashpadLeaf=d,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(Ht).length===0&&setTimeout(()=>{Pe(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let d=Pt(),p=!!d&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===d,m=!!p&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",m),document.body.classList.toggle("stashpad-active",!!p)};this.register(Zs(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let e=d=>{try{let p=Array.from(document.querySelectorAll("style")).filter(m=>(m.textContent??"").includes(".stashpad-"));for(let m of p){let v=m.id||"",y=v?`style[data-stashpad-source="${v}"]`:null;if(y&&d.head.querySelector(y))continue;let b=d.createElement("style");v?b.setAttribute("data-stashpad-source",v):b.setAttribute("data-stashpad-source","anon"),b.textContent=m.textContent??"",d.head.appendChild(b)}}catch(p){console.warn("[Stashpad] inject popout styles failed",p)}};this.registerEvent(this.app.workspace.on("window-open",d=>{let p=d?.doc??d?.win?.document??null;p&&e(p)})),setTimeout(()=>{try{let d=this.app.workspace;typeof d.iterateAllLeaves=="function"&&d.iterateAllLeaves(p=>{let m=p?.view?.containerEl?.ownerDocument;m&&m!==document&&e(m)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let s=window.visualViewport,i=()=>{let d=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),p=d&&d.isConnected?d.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${p}px`);let m=0;s&&(m=Math.max(0,window.innerHeight-s.height-s.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${m}px`),document.body.classList.toggle("stashpad-keyboard-open",m>100)};i(),s&&(s.addEventListener("resize",i),s.addEventListener("scroll",i),this.register(()=>{s.removeEventListener("resize",i),s.removeEventListener("scroll",i)})),window.addEventListener("resize",i),this.register(()=>window.removeEventListener("resize",i)),requestAnimationFrame(i),setTimeout(i,250),setTimeout(i,1e3),this.addRibbonIcon("list-tree","Open Stashpad",()=>{if(this.discoverStashpadFolders().length===0){this.activateView({reveal:!0});return}this.openFolderPicker()}).addEventListener("contextmenu",d=>{d.preventDefault(),this.openFolderPicker()}),this.addRibbonIcon("panel-left","Open Stashpad panels (sidebar)",()=>{Ae(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{Pe(this.app)}),this.addCommand({id:"stashpad-open",name:"Open Stashpad in new tab",callback:()=>{if(this.discoverStashpadFolders().length>=2){this.openFolderPicker();return}this.activateView({reveal:!1})}}),this.addCommand({id:"stashpad-reveal",name:"Reveal or open Stashpad",callback:()=>void this.activateView({reveal:!0})});let r=d=>{let p=Pt();p&&typeof p[d]=="function"&&p[d]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>r("toggleSplit")}),this.addCommand({id:"stashpad-claim-selected-author",name:"Claim authorship of selected notes",callback:()=>r("claimSelectedAsAuthor")}),this.addCommand({id:"stashpad-claim-folder-author",name:"Claim authorship of all unauthored notes in this folder",callback:()=>r("claimFolderAsAuthor")}),this.addCommand({id:"stashpad-claim-selected-contributor",name:"Claim selected notes (author if unowned, else add me as contributor)",callback:()=>r("claimSelectedWithContributor")}),this.addCommand({id:"stashpad-claim-folder-contributor",name:"Claim all notes in this folder (author if unowned, else add me as contributor)",callback:()=>r("claimFolderWithContributor")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>r("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>r("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>r("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>r("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>r("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>r("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>r("cmdCopyTree")}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>r("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>r("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Edit note in new tab (selection)",callback:()=>r("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>r("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>r("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>r("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>r("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>r("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>r("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>r("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>r("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>r("cmdClone")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>r("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>r("cmdToggleExpand")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>r("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>r("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>r("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>r("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>r("cmdSetDue")}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>r("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>r("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void Ae(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void Pe(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:d=>{let p=this.app.workspace.getActiveFile(),m=!!p&&p.extension==="md"&&this.isStashpadNoteFile(p);return d||m&&p&&this.revealNoteInStashpad(p),m}});let o=Object.keys(he);for(let d of o){let p=he[d];this.addCommand({id:`stashpad-open-panels-${d}`,name:`Open Stashpad panel: ${p.label}`,callback:async()=>{await Ae(this.app),this.app.workspace.getLeavesOfType(_t)[0]?.view?.setActivePanel?.(d)}})}this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>r("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>r("cmdTogglePin")}),this.addCommand({id:"stashpad-open-tiny",name:"Open Stashpad in tiny window",callback:()=>void this.openTinyWindow()}),this.addCommand({id:"stashpad-clone-tab",name:"Clone (duplicate / copy) this Stashpad tab",callback:()=>r("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>r("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>r("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection to .stash",callback:()=>r("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>r("cmdImportStash")}),this.addCommand({id:"stashpad-pick-folder",name:"Stashpad: open / switch / create folder\u2026",callback:()=>this.openFolderPicker()}),this.addCommand({id:"stashpad-run-integrity-check",name:"Run integrity check on active Stashpad folder",checkCallback:d=>{let p=Pt(),m=p&&p.noteFolder;return m?(d||(new it.Notice(`Running integrity check on "${m}"\u2026`),this.runIntegrityCheckOnFolder(m).then(()=>{new it.Notice("Integrity check complete \u2014 see Stashpad log.")})),!0):!1}}),this.addCommand({id:"stashpad-fix-orphans",name:"Set missing parents to Home (orphan fix)",callback:()=>void this.fixOrphanParents()}),this.addCommand({id:"stashpad-rebuild-author-registry",name:"Rebuild author registry (scan authors + note frontmatter)",callback:async()=>{new it.Notice("Stashpad: rebuilding author registry\u2026");try{let d=await this.rebuildAuthorRegistry();this.notifications.show({message:`Author registry rebuilt: ${d.total} author(s) \u2014 ${d.fromStubs} from stubs, ${d.fromNotes} from note links.`,kind:"success",category:"system"})}catch(d){new it.Notice(`Author registry rebuild failed: ${d.message}`)}}}),this.addCommand({id:"stashpad-restore-author-stubs",name:"Restore missing author stubs (from registry)",callback:async()=>{new it.Notice("Stashpad: restoring author stubs\u2026");try{let d=await this.restoreMissingAuthorStubs();this.notifications.show({message:d.created>0?`Restored ${d.created} author stub(s) across ${d.folders} folder(s).`:`No missing author stubs \u2014 all present across ${d.folders} folder(s).`,kind:"success",category:"system"})}catch(d){new it.Notice(`Restore author stubs failed: ${d.message}`)}}}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:async()=>{new it.Notice("Stashpad: rebootstrapping\u2026");try{let{touched:d,fmChecked:p,fmWritten:m,slugsRenamed:v,authors:y}=await this.rebootstrapAllFolders(),b=[];b.push(`rebootstrapped ${d.length} folder${d.length===1?"":"s"}`),m>0&&b.push(`updated ${m} note${m===1?"":"s"}' metadata`),v>0&&b.push(`renamed ${v} note${v===1?"":"s"}`),y>0&&b.push(`${y} author${y===1?"":"s"} in registry`),b.push(`(checked ${p} total)`),new it.Notice(`Stashpad: ${b.join(" \xB7 ")}`)}catch(d){new it.Notice(`Stashpad: rebootstrap failed (${d.message})`)}}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:d=>{let p=this.app.workspace.getActiveFile();return!p||p.extension!=="md"?!1:(d||this.adoptNote(p),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(Gt(),Fe)).then(({NotificationHistoryModal:d,LogModal:p})=>{new d(this.app,this.notifications,async()=>{let m=this.app.vault.adapter,v=this.pluginPrivatePath("log.jsonl");if(!await m.exists(v)){new it.Notice("No log yet \u2014 make some changes first.");return}let y=await m.read(v);new p(this.app,y,v).open()},this.settings.authorId||null,m=>this.lookupNoteAuthorIds(m)).open()})}});let a=[{key:"prefixTimestampsOnCopy",label:"Prefix timestamps when copying"},{key:"useTemplatesFormat",label:"Use Templates plugin date/time formats"},{key:"autoNavOnMoveIn",label:"Auto-navigate into parent on move IN"},{key:"autoNavOnMoveOut",label:"Auto-navigate to destination on move OUT"},{key:"confirmCrossParentDrag",label:"Confirm cross-parent drag-and-drop"},{key:"confirmBulkDelete",label:"Confirm bulk deletes"},{key:"confirmAttachmentDelete",label:"Offer to delete attachments with note"},{key:"autofocusComposerAfterSend",label:"Autofocus composer after sending"},{key:"popoutDuplicates",label:"Open in new window \u2014 duplicate tab"},{key:"autoExpandCursorRow",label:"Expand the cursor row's body automatically"},{key:"autoOpenDetailPanel",label:"Auto-open the detail panel"},{key:"doubleClickToFocus",label:"Double-click a note to open it"}];for(let d of a){let p=`stashpad-toggle-${String(d.key).replace(/[A-Z]/g,m=>`-${m.toLowerCase()}`)}`;this.addCommand({id:p,name:`Toggle: ${d.label}`,callback:async()=>{let m=!this.settings[d.key];this.settings[d.key]=m,await this.saveSettings(),new it.Notice(`${d.label}: ${m?"ON":"OFF"}`)}})}this.addCommand({id:"stashpad-open-settings",name:"Open Stashpad settings",callback:()=>{let d=this.app.setting;!d?.open||!d?.openTabById||(d.open(),d.openTabById(this.manifest.id))}}),this.addCommand({id:"stashpad-search-settings",name:"Search Stashpad settings\u2026",callback:()=>{let d=this.app.setting;!d?.open||!d?.openTabById||(d.open(),d.openTabById(this.manifest.id),setTimeout(()=>this.settingTab?.focusSearchInput?.(),0))}});for(let d of Ze)this.addCommand({id:`stashpad-open-settings-${d.id}`,name:`Open Stashpad settings: ${d.label}`,callback:()=>{let p=this.app.setting;!p?.open||!p?.openTabById||(this.settingTab?.openToTab(d.id),p.open(),p.openTabById(this.manifest.id))}});let l=()=>{let d=this.app.setting;!d?.open||!d?.openTabById||(d.open(),d.openTabById(this.manifest.id),setTimeout(()=>{document.getElementById("stashpad-jd-index-section")?.scrollIntoView({behavior:"smooth",block:"start"})},100))};this.addCommand({id:"stashpad-preview-jd-index",name:"Preview JD index (overwrites home note body)",callback:async()=>{try{let{buildJdIndexPreview:d}=await Promise.resolve().then(()=>(me(),Ve)),p=await d(this.app,this,this.settings);if(p.error==="no-dest"){new it.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}if(p.error==="no-home"){new it.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:m}=await Promise.resolve().then(()=>(me(),Ve));m(this.app,p)}catch(d){console.error("[stashpad] preview failed",d),new it.Notice(`Preview failed: ${d?.message??d}`,8e3)}}}),this.addCommand({id:"stashpad-build-jd-index",name:"Build JD index notes (creates Stashpad-note hierarchy)",callback:async()=>{try{let{buildJdIndexNotes:d,scanForJdNotes:p,JdBuildConfirmModal:m}=await Promise.resolve().then(()=>(me(),Ve));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new it.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}let y=p(this.app,this,this.settings);new m(this.app,this,this.settings,y.indexed.length,async()=>{try{let k=await d(this.app,this,this.settings);if(k.error==="no-dest"){new it.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),l();return}if(k.error==="dest-not-stashpad"){new it.Notice(`"${k.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),l();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new it.Notice(`Index built: ${k.created} created, ${k.updated} updated, ${k.skipped} skipped \u2192 ${k.destFolder}`,6e3)}catch(k){console.error("[stashpad] build failed",k),new it.Notice(`Build failed: ${k?.message??k}`,8e3)}}).open()}catch(d){console.error("[stashpad] build failed",d),new it.Notice(`Build failed: ${d?.message??d}`,8e3)}}});let c=d=>{if(d.extension!==ye)return;let p=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),m=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!p)return;let v=d.parent?.path||"";if((v.split("/").pop()??"")!==p||m&&v.endsWith(`/${m}`))return;let b=v.slice(0,v.length-p.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(d,b)};this.registerEvent(this.app.vault.on("create",d=>{d instanceof it.TFile&&c(d)})),this.registerEvent(this.app.vault.on("rename",d=>{d instanceof it.TFile&&c(d)}));let h=d=>{if(d.extension!=="md")return;let p=d.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(p)&&setTimeout(()=>{this.fixOrphanParentForFile(d)},800)},u=d=>{if(d.extension!=="md")return;let p=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!p)return;let m=d.parent?.path?.replace(/\/+$/,"")??"";if((m.split("/").pop()??"")!==p)return;let y=m.slice(0,m.length-p.length).replace(/\/+$/,"");!y||!this.discoverStashpadFolders().includes(y)||setTimeout(()=>{this.adoptMarkdownDrop(d,y)},200)};this.registerEvent(this.app.vault.on("create",d=>{d instanceof it.TFile&&(h(d),u(d))})),this.registerEvent(this.app.vault.on("rename",d=>{d instanceof it.TFile&&(h(d),u(d))})),this.registerEvent(this.app.vault.on("rename",(d,p)=>{d instanceof it.TFile&&this.maybeAdoptAuthorRename(d,p)})),this.registerDomEvent(window,"focus",()=>void this.checkForSyncedBuild()),setTimeout(()=>void this.checkForSyncedBuild(),5e3)}async checkForSyncedBuild(){try{let t=this.manifest.dir;if(!t)return;let e=`${t.replace(/\/+$/,"")}/manifest.json`,s=this.app.vault.adapter;if(!await s.exists(e))return;let i=JSON.parse(await s.read(e))?.version,n=this.manifest.version;if(typeof i!="string"||!i||i===n||!this.isSemverGreater(i,n)||this.notifiedBuildVersion===i)return;this.notifiedBuildVersion=i,this.notifications.show({message:`A newer Stashpad build synced in (\`${n}\` \u2192 \`${i}\`). Reload to apply.`,kind:"info",category:"system",duration:0,actions:[{label:"Reload Stashpad",onClick:async()=>{let r=this.app.plugins;try{await r?.disablePlugin?.(this.manifest.id),await r?.enablePlugin?.(this.manifest.id)}catch(o){new it.Notice(`Couldn't reload \u2014 toggle Stashpad off/on in settings. (${o.message})`)}}}]})}catch(t){console.debug("[Stashpad] synced-build check failed",t)}}isSemverGreater(t,e){let s=t.split(".").map(r=>parseInt(r,10)||0),i=e.split(".").map(r=>parseInt(r,10)||0),n=Math.max(s.length,i.length);for(let r=0;r<n;r++){let o=s[r]??0,a=i[r]??0;if(o!==a)return o>a}return!1}parseAuthorFilePath(t){let e=t.match(/\/_authors\/([^/]+?)-([a-z0-9]{4,12})\.md$/i);return e?{name:e[1].replace(/-/g," "),id:e[2]}:null}authorNameToSafe(t){return t.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author"}async syncAuthorFilesToName(){let t=(this.settings.authorId??"").trim(),e=(this.settings.authorName??"").trim();if(!t||!e)return;let s=this.authorNameToSafe(e);for(let i of this.discoverStashpadFolders()){let n=`${i}/_authors`;if(await this.app.vault.adapter.exists(n))for(let r of this.app.vault.getMarkdownFiles()){if(!r.path.startsWith(n+"/"))continue;let o=this.parseAuthorFilePath(r.path);if(!o||o.id!==t)continue;let a=`${n}/${s}-${t}.md`,l=r;if(r.path!==a)try{this.authorRenameInFlight.add(r.path),this.authorRenameInFlight.add(a),await this.app.fileManager.renameFile(r,a);let c=this.app.vault.getAbstractFileByPath(a);c&&(l=c)}catch(c){console.warn("[Stashpad] author file rename failed",c);continue}try{await this.refreshAuthorStub(l)}catch{}}}}async refreshAuthorStub(t){let e=(this.settings.authorName??"").trim(),s=(this.settings.authorRole??"").trim(),i=(this.settings.authorDepartment??"").trim();if(e)try{let n=await this.app.vault.read(t),r=n.replace(/^# .*$/m,`# ${e}`);r!==n&&await this.app.vault.modify(t,r),await this.app.fileManager.processFrontMatter(t,o=>{o.aliases=[e],delete o.name,s?o.role=s:delete o.role,i?o.department=i:delete o.department})}catch(n){console.warn("[Stashpad] refreshAuthorStub failed",n)}}async maybeAdoptAuthorRename(t,e){if(this.authorRenameInFlight.delete(t.path)||this.authorRenameInFlight.delete(e))return;let s=this.parseAuthorFilePath(t.path);if(!s)return;let i=(this.settings.authorId??"").trim();if(!i||s.id!==i)return;let n=s.name.trim();!n||n===(this.settings.authorName??"").trim()||(this.settings.authorName=n,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(t,e){try{let s=this.app.vault.adapter,i=t.name,n=i.lastIndexOf("."),r=n>0?i.slice(0,n):i,o=n>0?i.slice(n):"",a=0;for(;await s.exists(`${e}/${i}`);)a+=1,i=`${r}-${a}${o}`;let l=`${e}/${i}`;await this.app.fileManager.renameFile(t,l);let c=this.app.vault.getAbstractFileByPath(l);c instanceof it.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(c)},500),this.notifications.show({message:`Imported \`${t.name}\` \u2192 \`${e}\``,kind:"success",category:"import",folder:e,affectedPaths:[l]})}catch(s){console.warn("Stashpad: markdown drop adoption failed",s),this.notifications.show({message:`Couldn't import \`${t.name}\`: ${s.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(t){try{let e=this.app.metadataCache.getFileCache(t)?.frontmatter,s=typeof e?.id=="string"?e.id.trim():"",i=e?.parent,n=typeof i=="string"?i.trim()!=="":i!=null,r=typeof e?.created=="string"&&e.created.trim()!=="",o=!s,a=!n,l=!r;if(!o&&!a&&!l)return;let{newId:c}=await Promise.resolve().then(()=>(Ot(),ze)),h,u=!1,d=!1;if(await this.app.fileManager.processFrontMatter(t,v=>{if(o&&(typeof v.id=="string"&&v.id.trim()||(h=c(),v.id=h)),a){let y=v.parent;(typeof y=="string"?y.trim()!=="":y!=null)||(v.parent=R,u=!0)}l&&(typeof v.created=="string"&&v.created.trim()||(v.created=new Date(t.stat.ctime).toISOString(),d=!0))}),!h&&!u&&!d)return;let p=this.newLog(),m=h||s;m&&await p.append({type:"parent_change",id:m,payload:{from:null,to:R,reason:"orphan_auto_fix",path:t.path,addedId:!!h,addedParent:u,addedCreated:d}}),new it.Notice(`Adopted ${t.basename} \u2192 Home`)}catch(e){console.warn("Stashpad: orphan auto-fix failed",e)}}async autoImportStash(t,e){try{let s=new Uint8Array(await this.app.vault.readBinary(t)),i=Pt(),n=new Set;if(i&&typeof i.collectExistingIds=="function"&&i.noteFolder===e)for(let a of i.collectExistingIds())n.add(a);else for(let a of this.app.vault.getMarkdownFiles()){if(!a.path.startsWith(e+"/"))continue;let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id;typeof l=="string"&&n.add(l)}let r=await Qe(this.app,s,e,n);try{await this.newLog().append({type:"stash_import",id:R,payload:{from:t.path,into:e,noteCount:r.notesWritten,attachmentsWritten:r.attachmentsWritten,collisionsRenamed:r.collisionsRenamed,auto:!0}})}catch{}try{await this.app.fileManager.trashFile(t)}catch{}let o=[`Auto-imported ${r.notesWritten} note${r.notesWritten===1?"":"s"} from ${t.name}`];r.attachmentsWritten&&o.push(`+ ${r.attachmentsWritten} attachment${r.attachmentsWritten===1?"":"s"}`),r.collisionsRenamed&&o.push(`(${r.collisionsRenamed} renamed)`),this.notifications.show({message:o.join(" "),kind:"success",category:"import",folder:e}),i&&typeof i.debouncedRender=="function"&&i.debouncedRender()}catch(s){this.notifications.show({message:`Stashpad: auto-import failed File: \`${t.name}\` Error: ${s.message} -Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[t.path],actions:Re(this.app,t.path,at.Platform.isMobile)}),console.error(s)}}lookupNoteAuthorIds(t){let e=new Set,s=i=>{if(typeof i!="string")return null;let n=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let i of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(i)?.frontmatter;if(n?.id!==t)continue;let r=s(n?.author);r&&e.add(r);let o=n?.contributors;if(Array.isArray(o))for(let a of o){let l=s(a);l&&e.add(l)}break}return Array.from(e)}lookupNoteAuthorId(t){return this.lookupNoteAuthorIds(t)[0]??null}async rebootstrapAllFolders(){let t="__root__",e=new Set;for(let c of this.app.vault.getMarkdownFiles()){if(this.app.metadataCache.getFileCache(c)?.frontmatter?.id!==t)continue;let p=c.parent?.path;p&&e.add(p)}let s=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),i=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),n=[],r=async c=>{if(c&&!await this.app.vault.adapter.exists(c))try{await this.app.vault.createFolder(c)}catch(d){let p=d?.message??"";if(!/already exists/i.test(p))throw d}},o=0,a=0,l=0;for(let c of e)try{s&&await r(`${c}/${s}`),i&&await r(`${c}/${i}`);let d=await Ls(this.app,c);o+=d.checked,a+=d.written,l+=await this.rebootstrapFolderSlugs(c),n.push(c)}catch(d){console.warn(`Stashpad: rebootstrap skipped ${c}`,d)}return{touched:n,fmChecked:o,fmWritten:a,slugsRenamed:l}}async rebootstrapFolderSlugs(t){let e="__root__",s=t.replace(/\/+$/,""),i=this.settings.slugStopWords??It,n=0,r=this.app.vault.getMarkdownFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===s);for(let o of r){let a=Qt(o.basename);if(!(!a||a===e||this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==a))try{let c=await this.app.vault.cachedRead(o),d=c.startsWith("---")?c.slice(c.indexOf(` ----`,3)+4).replace(/^\r?\n/,""):c,p=Bt(d,i),h=Ht(p,a);if(o.name===h)continue;let u=o.parent?`${o.parent.path}/${h}`:h;if(this.app.vault.getAbstractFileByPath(u))continue;await this.app.fileManager.renameFile(o,u),n+=1}catch(c){console.warn(`Stashpad: slug rebootstrap skipped ${o.path}`,c)}}return n}onStashpadSelectionChange(t){return this.stashpadSelectionListeners.add(t),()=>this.stashpadSelectionListeners.delete(t)}notifyStashpadSelectionChanged(){for(let t of this.stashpadSelectionListeners)try{t()}catch(e){console.warn("[Stashpad] selection listener failed",e)}}onStashpadContentChange(t){return this.stashpadContentListeners.add(t),()=>this.stashpadContentListeners.delete(t)}notifyStashpadContentChanged(){for(let t of this.stashpadContentListeners)try{t()}catch(e){console.warn("[Stashpad] content listener failed",e)}}getActiveStashpadSelection(){let e=this.lastActiveStashpadLeaf?.view;if(!e||e.getViewType?.()!==vt)return null;let s=e.noteFolder??"";if(!s)return null;let i=e.currentChildren??[],n;if(typeof e.cursorIdx=="number"&&e.cursorIdx>=0&&(n=i[e.cursorIdx]),!n&&e.selection?.size>0){let r=e.firstSelectedId??[...e.selection][0];n=i.find(o=>o.id===r)}return n?.file?{folder:s,id:n.id,file:n.file}:null}async pinNote(t){let e=this.settings.pinnedNotes??[];e.some(s=>s.folder===t.folder&&s.id===t.id)||(this.settings.pinnedNotes=[...e,t],await this.saveSettings(),this.refreshPanelsView())}async unpinNote(t){let e=this.settings.pinnedNotes??[],s=e.filter(i=>!(i.folder===t.folder&&i.id===t.id));s.length!==e.length&&(this.settings.pinnedNotes=s,await this.saveSettings(),this.refreshPanelsView())}isPinned(t){return(this.settings.pinnedNotes??[]).some(e=>e.folder===t.folder&&e.id===t.id)}refreshPanelsView(){let t=this.app.workspace.getLeavesOfType(Nt);for(let e of t){let s=e.view;s&&typeof s.render=="function"&&s.render()}}openFolderPicker(){let t=u=>{let g=u.getViewState().state?.folderOverride;return typeof g=="string"&&g.trim()?g.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},e=this.app.workspace.getLeavesOfType(vt),s=this.discoverStashpadFolders(),i=_t(),n=i?(i.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",r=new Set;for(let u of this.app.vault.getAllLoadedFiles())if(u.children){let m=u.path;m&&m!=="/"&&!m.startsWith(".")&&r.add(m)}let o=u=>{let m=u.split("/").filter(Boolean).pop()??"";return m?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors"].map(y=>(y??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(m):!1},a=new Set,l=[],c=[],d=new Set;for(let u of e){let m=t(u);if(d.has(m))continue;d.add(m),a.add(m);let g=m.split("/").pop()||m;l.push({kind:"reveal",folder:m,label:`Reveal "${g}" tab`,leaf:u,icon:"layout-grid"}),c.push({kind:"open-anyway",folder:m,label:`Open "${g}" in another new tab`,icon:"layout-template"})}for(let u of s.filter(m=>!a.has(m))){let m=u.split("/").pop()||u;l.push({kind:"open",folder:u,label:`Open "${m}" in new tab`,icon:"layout-template"})}let p=this,h=new class extends at.SuggestModal{getSuggestions(u){let m=u.trim().toLowerCase(),g=m?m.split(/\s+/).filter(Boolean):[],y=I=>{if(!g.length)return!0;let E=I.toLowerCase();for(let D of g)if(!E.includes(D))return!1;return!0},S=m?l.filter(I=>{let E="folder"in I?I.folder:"";return y(I.label)||y(E)}):l.slice();if(m&&i&&n)for(let I of s){if(I.toLowerCase()===n.toLowerCase())continue;let E=I.split("/").pop()??I,D=`${I} ${E}`;y(D)&&S.push({kind:"switch-current",folder:I,label:`Switch this tab to "${E}"`,icon:"folder-input"})}let k=u.trim().replace(/^\/+|\/+$/g,"");if(k&&!o(k)){let I=Array.from(r).find(D=>D.toLowerCase()===k.toLowerCase()),E=s.some(D=>D.toLowerCase()===k.toLowerCase());if(I&&!E)S.push({kind:"convert",folder:I,label:`Convert \u201C${es(I)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!I){let D=es(k);S.push({kind:"create",folder:k,label:`+ Create new Stashpad \u201C${D}\u201D`,icon:"folder-plus"})}}let x=c.filter(I=>y(I.label)||y(I.folder));return S.push(...x),S}renderSuggestion(u,m){m.addClass("stashpad-suggest-item"),m.addClass("stashpad-ribbon-suggest-item"),u.kind==="create"&&m.addClass("stashpad-suggest-create");let g=m.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,at.setIcon)(g,u.icon);let y=m.createDiv({cls:"stashpad-ribbon-suggest-body"});y.createDiv({cls:"stashpad-suggest-title",text:u.label}),"folder"in u&&u.folder&&u.label!==u.folder&&y.createDiv({cls:"stashpad-suggest-preview",text:u.folder})}async onChooseSuggestion(u){if(u.kind==="reveal"){p.app.workspace.revealLeaf(u.leaf);return}if(u.kind==="open"||u.kind==="open-anyway"){await p.activateViewForFolder(u.folder);return}if(u.kind==="switch-current"){let m=i;m&&typeof m.setFolderOverride=="function"&&(await m.setFolderOverride(u.folder),p.app.workspace.revealLeaf(m.leaf));return}if(u.kind==="create"){try{let m=es(u.folder);await p.app.vault.adapter.exists(m)||await p.app.vault.createFolder(m),await p.activateViewForFolder(m)}catch(m){new at.Notice(`Stashpad: couldn't create folder (${m.message})`)}return}if(u.kind==="convert"){let{ConfirmModal:m}=await Promise.resolve().then(()=>(Gt(),Te)),g=u.folder,y=[`\u201C${g}\u201D already exists as a regular vault folder.`,"Converting will add a Home note + _imports / _exports subfolders inside it.","Existing files are NOT touched."];new m(p.app,"Convert into a Stashpad?",y.join(` -`),"Convert",async S=>{if(S)try{await p.activateViewForFolder(g)}catch(k){new at.Notice(`Stashpad: couldn't convert folder (${k.message})`)}}).open();return}}}(this.app);h.setPlaceholder(i?"Open, switch this tab, or create a Stashpad folder \u2014 type to filter\u2026":"Open or create a Stashpad folder \u2014 type to filter\u2026"),h.open()}async openTinyWindow(){let t=_t(),e=t?.folderOverride??null,s=t?.focusId??"__root__",i=!!t?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new at.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:vt,active:!0,state:{folderOverride:e,focusId:s,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:i}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(t={reveal:!0}){let{workspace:e}=this.app;if(t.reveal){let i=e.getLeavesOfType(vt);if(i.length>0){e.revealLeaf(i[0]);return}}let s=e.getLeaf("tab");await s.setViewState({type:vt,active:!0}),e.revealLeaf(s)}async activateViewForFolder(t){let e=(t||"").replace(/^\/+|\/+$/g,"");if(!e)return;let s=this.app.workspace.getLeaf("tab");await s.setViewState({type:vt,active:!0,state:{folderOverride:e}}),this.app.workspace.revealLeaf(s)}isStashpadNoteFile(t){let e=t.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(e))return!1;let s=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;return typeof s=="string"&&s.length>0}async revealNoteInStashpad(t){let e=t.parent?.path?.replace(/\/+$/,"")??"",s=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;if(!e||typeof s!="string"||!s){new at.Notice("That note isn't a Stashpad note.");return}let i=this.app.workspace.getLeavesOfType(vt).find(r=>(r.view?.noteFolder??"")===e);if(i){this.app.workspace.revealLeaf(i);let r=i.view;typeof r?.navigateTo=="function"&&r.navigateTo(s);return}await this.activateViewForFolder(e);let n=this.lastActiveStashpadLeaf?.view;typeof n?.navigateTo=="function"&&n.navigateTo(s)}collectAuthoredFolders(){let t=(this.settings.authorId??"").trim();if(!t)return[];let e=`-${t}`,s=this.discoverStashpadFolders(),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!r)continue;let o=typeof r.author=="string"?r.author:"",a=Array.isArray(r.contributors)?r.contributors.filter(u=>typeof u=="string"):[],l=o.includes(e),c=a.some(u=>u.includes(e));if(!l&&!c)continue;let d=n.parent?.path??"",p=s.find(u=>d===u||d.startsWith(u+"/"));if(!p)continue;i.has(p)||i.set(p,{authored:0,contributed:0});let h=i.get(p);l&&h.authored++,c&&h.contributed++}return[...i.entries()].map(([n,r])=>({folder:n,...r})).sort((n,r)=>r.authored+r.contributed-(n.authored+n.contributed))}async loadSettings(){let t=await this.loadData()??{};typeof t?.confirmMultiDelete=="boolean"&&(typeof t.confirmBulkDelete!="boolean"&&(t.confirmBulkDelete=t.confirmMultiDelete),typeof t.confirmAttachmentDelete!="boolean"&&(t.confirmAttachmentDelete=t.confirmMultiDelete),delete t.confirmMultiDelete),typeof t?.jdIndexDestFolder=="string"&&typeof t?.jdIndexStashpadFolder!="string"&&(t.jdIndexStashpadFolder=t.jdIndexDestFolder),this.settings={...zt,...t,shortcuts:{...zt.shortcuts,...t?.shortcuts??{}},mod:{...zt.mod,...t?.mod??{}},bindings:Li(t?.bindings,t?.shortcuts,t?.mod),customPalette:Array.isArray(t?.customPalette)?t.customPalette.filter(e=>typeof e=="string"&&/^#[0-9a-f]{6}$/i.test(e)):[],colorAliases:t?.colorAliases&&typeof t.colorAliases=="object"?t.colorAliases:{},noteTemplates:t?.noteTemplates&&typeof t.noteTemplates=="object"?t.noteTemplates:{},authorName:typeof t?.authorName=="string"?t.authorName:"",authorId:typeof t?.authorId=="string"?t.authorId:"",authorRole:typeof t?.authorRole=="string"?t.authorRole:"",authorDepartment:typeof t?.authorDepartment=="string"?t.authorDepartment:"",showAuthor:typeof t?.showAuthor=="boolean"?t.showAuthor:!0,showContributors:typeof t?.showContributors=="boolean"?t.showContributors:!0,showLastEdit:typeof t?.showLastEdit=="boolean"?t.showLastEdit:!0,viewModes:t?.viewModes&&typeof t.viewModes=="object"&&!Array.isArray(t.viewModes)?t.viewModes:{},includeAttachmentsInEverything:t?.includeAttachmentsInEverything&&typeof t.includeAttachmentsInEverything=="object"&&!Array.isArray(t.includeAttachmentsInEverything)?t.includeAttachmentsInEverything:{},hideChildlessNotes:t?.hideChildlessNotes&&typeof t.hideChildlessNotes=="object"&&!Array.isArray(t.hideChildlessNotes)?t.hideChildlessNotes:{},hideCompletedNotes:t?.hideCompletedNotes&&typeof t.hideCompletedNotes=="object"&&!Array.isArray(t.hideCompletedNotes)?t.hideCompletedNotes:{},mutedNotificationCategories:Array.isArray(t?.mutedNotificationCategories)?t.mutedNotificationCategories.filter(e=>typeof e=="string"):[],notificationHistoryLimit:typeof t?.notificationHistoryLimit=="number"&&Number.isFinite(t.notificationHistoryLimit)?t.notificationHistoryLimit:5e3,drafts:Ni(t?.drafts),lastSubmitted:t?.lastSubmitted&&typeof t.lastSubmitted=="object"?t.lastSubmitted:{},slugStopWords:Array.isArray(t?.slugStopWords)?t.slugStopWords:[...It]},ys(this.settings),this.notifications.loadMutedFromList(this.settings.mutedNotificationCategories),this.notifications.setHistoryLimit(this.settings.notificationHistoryLimit),this.notifications.setDefaultAuthorId(this.settings.authorId),this.attachNotificationPersistence()}notificationsPath(){return this.pluginPrivatePath("notifications.json")}async attachNotificationPersistence(){if(this.notifPersistenceWired)return;this.notifPersistenceWired=!0;let t=this.app.vault.adapter,e=this.notificationsPath();try{if(await t.exists(e)){let s=await t.read(e),i=JSON.parse(s);Array.isArray(i)&&this.notifications.loadHistory(i)}}catch(s){console.warn("[Stashpad] failed to load notification history",s)}this.notifications.onChange(()=>{this.notifSaveTimer!=null&&window.clearTimeout(this.notifSaveTimer),this.notifSaveTimer=window.setTimeout(()=>{this.notifSaveTimer=null,this.persistNotificationHistory()},1e3)})}async persistNotificationHistory(){try{let t=this.notifications.recent().slice().reverse(),e=this.notificationsPath(),s=e.replace(/\/[^/]+$/,""),i=this.app.vault.adapter;s&&!await i.exists(s)&&await i.mkdir(s),await i.write(e,JSON.stringify(t))}catch(t){console.warn("[Stashpad] failed to save notification history",t)}}readLastCursorFile(){try{let t=window.localStorage.getItem(this.LAST_CURSOR_LS_KEY);if(!t)return{};let e=JSON.parse(t);return e&&typeof e=="object"?e:{}}catch{return{}}}loadLastCursor(t){let s=this.readLastCursorFile()[t]??{};return new Map(Object.entries(s))}saveLastCursor(t,e,s){try{let i=this.readLastCursorFile();i[t]||(i[t]={}),i[t][e]=s,window.localStorage.setItem(this.LAST_CURSOR_LS_KEY,JSON.stringify(i))}catch(i){console.warn("[Stashpad] failed to save last-cursor",i)}}queueWrite(){let t=this.writeChain.then(()=>this.saveData(this.settings));return this.writeChain=t.catch(()=>{}),t}async saveSettings(){await this.queueWrite(),ys(this.settings),console.debug("[Stashpad] saveSettings",{shortcuts:this.settings.shortcuts,mod:this.settings.mod})}async persistSettingsQuiet(){await this.queueWrite()}async fixOrphanParents(){let t=new Set(this.discoverStashpadFolders());if(t.size===0){new at.Notice("No Stashpad folders found.");return}let e=new Set,s=this.app.vault.getMarkdownFiles();for(let d of s){let p=this.app.metadataCache.getFileCache(d)?.frontmatter,h=typeof p?.id=="string"?p.id.trim():"";h&&e.add(h)}let{newId:i}=await Promise.resolve().then(()=>(Rt(),Be)),n=()=>{for(let d=0;d<100;d++){let p=i();if(!e.has(p))return e.add(p),p}for(let d=8;d<=16;d+=2){let p=i(d);if(!e.has(p))return e.add(p),p}throw new Error("Could not generate a unique id")},r=[];for(let d of s){let p=d.parent?.path?.replace(/\/+$/,"")??"";if(!t.has(p))continue;let h=this.app.metadataCache.getFileCache(d)?.frontmatter,u=typeof h?.id=="string"?h.id.trim():"",m=h?.parent,g=typeof m=="string"?m.trim()!=="":m!=null,y=typeof h?.created=="string"&&h.created.trim()!=="",S=!u,k=!g,x=!y;!S&&!k&&!x||r.push({file:d,addId:S,addParent:k,addCreated:x})}if(r.length===0){new at.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let o=0,a=0,l=this.newLog();for(let d of r)try{let p;await this.app.fileManager.processFrontMatter(d.file,m=>{if(d.addId&&(typeof m.id=="string"&&m.id.trim()||(p=n(),m.id=p)),d.addParent){let g=m.parent;(typeof g=="string"?g.trim()!=="":g!=null)||(m.parent=B)}d.addCreated&&(typeof m.created=="string"&&m.created.trim()||(m.created=new Date(d.file.stat.ctime).toISOString()))});let h=this.app.metadataCache.getFileCache(d.file)?.frontmatter,u=p??h?.id??"";u&&await l.append({type:"parent_change",id:u,payload:{from:null,to:B,reason:"orphan_fix",path:d.file.path,addedId:d.addId,addedParent:d.addParent,addedCreated:d.addCreated}}),o++}catch(p){console.warn("Stashpad: orphan fix failed for",d.file.path,p),a++}let c=a?` (${a} failed \u2014 see console)`:"";new at.Notice(`Fixed ${o} note${o===1?"":"s"} in Stashpad folders${c}.`)}async adoptNote(t){let{newId:e}=await Promise.resolve().then(()=>(Rt(),Be)),s=new Set;for(let l of this.app.vault.getMarkdownFiles()){if(l.path===t.path)continue;let c=this.app.metadataCache.getFileCache(l)?.frontmatter,d=typeof c?.id=="string"?c.id.trim():"";d&&s.add(d)}let i=()=>{for(let l=0;l<50;l++){let c=e();if(!s.has(c))return c}for(let l=8;l<=16;l+=2){let c=e(l);if(!s.has(c))return c}throw new Error("Could not generate a unique id")},n=[],r=[];try{await this.app.fileManager.processFrontMatter(t,l=>{let c=typeof l.id=="string"?l.id.trim():"";!c||/\s/.test(c)||s.has(c)?(l.id=i(),n.push("id")):r.push("id"),l.parent!==void 0&&l.parent!==null&&String(l.parent).trim()!==""?r.push("parent"):(l.parent=B,n.push("parent")),typeof l.created=="string"&&l.created.trim()!==""?r.push("created"):(l.created=new Date(t.stat.ctime).toISOString(),n.push("created"))})}catch(l){new at.Notice(`Adopt failed: ${l.message}`);return}let o=!1;try{let l=this.app.metadataCache.getFileCache(t)?.frontmatter,c=typeof l?.id=="string"?l.id.trim():"";if(c&&t.basename&&!t.basename.endsWith(`-${c}`)){let d=`${t.parent?t.parent.path+"/":""}${t.basename}-${c}.md`;await this.app.vault.adapter.exists(d)||(await this.app.fileManager.renameFile(t,d),o=!0)}}catch(l){console.warn("Stashpad: adopt rename failed",l)}if(n.length===0&&!o){new at.Notice(`Already a Stashpad note (${r.join(", ")} present).`);return}let a=[];n.length&&a.push(`added: ${n.join(", ")}`),o&&a.push("renamed with id"),new at.Notice(`Adopted into Stashpad \u2014 ${a.join("; ")}.`);try{let l=this.newLog(),c=this.app.metadataCache.getFileCache(t)?.frontmatter,d=c?.id??"";d&&await l.append({type:"create",id:d,payload:{path:t.path,parent:c?.parent??B,source:"adopt",added:n}})}catch{}}};function Li(v,f,t){let e=vs();for(let s of ge){let i=f&&typeof f[s.id]=="string"?f[s.id]:t&&typeof t[s.id]=="string"?t[s.id]:null;i!=null&&i!==""&&(e[s.id].primary=i)}if(v&&typeof v=="object")for(let s of ge){let i=v[s.id];!i||typeof i!="object"||(e[s.id]={primary:typeof i.primary=="string"?i.primary:e[s.id].primary,secondary:typeof i.secondary=="string"?i.secondary:"",preferRight:!!i.preferRight,useBoth:!!i.useBoth})}return e}function Ni(v){let f={};if(!v||typeof v!="object")return f;for(let[t,e]of Object.entries(v))if(typeof e=="string")f[t]=e;else if(e&&typeof e=="object"){for(let s of Object.values(e))if(typeof s=="string"&&s.length>0){f[t]=s;break}}return f} +Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[t.path],actions:He(this.app,t.path,it.Platform.isMobile)}),console.error(s)}}lookupNoteAuthorIds(t){let e=new Set,s=i=>{if(typeof i!="string")return null;let n=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let i of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(i)?.frontmatter;if(n?.id!==t)continue;let r=s(n?.author);r&&e.add(r);let o=n?.contributors;if(Array.isArray(o))for(let a of o){let l=s(a);l&&e.add(l)}break}return Array.from(e)}lookupNoteAuthorId(t){return this.lookupNoteAuthorIds(t)[0]??null}async rebootstrapAllFolders(){let t="__root__",e=new Set;for(let h of this.app.vault.getMarkdownFiles()){if(this.app.metadataCache.getFileCache(h)?.frontmatter?.id!==t)continue;let d=h.parent?.path;d&&e.add(d)}let s=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),i=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),n=[],r=async h=>{if(h&&!await this.app.vault.adapter.exists(h))try{await this.app.vault.createFolder(h)}catch(u){let d=u?.message??"";if(!/already exists/i.test(d))throw u}},o=0,a=0,l=0;for(let h of e)try{s&&await r(`${h}/${s}`),i&&await r(`${h}/${i}`);let u=await Hs(this.app,h);o+=u.checked,a+=u.written,l+=await this.rebootstrapFolderSlugs(h),n.push(h)}catch(u){console.warn(`Stashpad: rebootstrap skipped ${h}`,u)}let c=0;try{c=(await this.rebuildAuthorRegistry()).total}catch(h){console.warn("Stashpad: rebootstrap author-registry rebuild failed",h)}return{touched:n,fmChecked:o,fmWritten:a,slugsRenamed:l,authors:c}}async rebootstrapFolderSlugs(t){let e="__root__",s=t.replace(/\/+$/,""),i=this.settings.slugStopWords??Et,n=0,r=this.app.vault.getMarkdownFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===s);for(let o of r){let a=Qt(o.basename);if(!(!a||a===e||this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==a))try{let c=await this.app.vault.cachedRead(o),h=c.startsWith("---")?c.slice(c.indexOf(` +---`,3)+4).replace(/^\r?\n/,""):c,u=$t(h,i),d=Rt(u,a);if(o.name===d)continue;let p=o.parent?`${o.parent.path}/${d}`:d;if(this.app.vault.getAbstractFileByPath(p))continue;await this.app.fileManager.renameFile(o,p),n+=1}catch(c){console.warn(`Stashpad: slug rebootstrap skipped ${o.path}`,c)}}return n}onStashpadSelectionChange(t){return this.stashpadSelectionListeners.add(t),()=>this.stashpadSelectionListeners.delete(t)}notifyStashpadSelectionChanged(){for(let t of this.stashpadSelectionListeners)try{t()}catch(e){console.warn("[Stashpad] selection listener failed",e)}}onStashpadContentChange(t){return this.stashpadContentListeners.add(t),()=>this.stashpadContentListeners.delete(t)}notifyStashpadContentChanged(){for(let t of this.stashpadContentListeners)try{t()}catch(e){console.warn("[Stashpad] content listener failed",e)}}getActiveStashpadSelection(){let e=this.lastActiveStashpadLeaf?.view;if(!e||e.getViewType?.()!==mt)return null;let s=e.noteFolder??"";if(!s)return null;let i=e.currentChildren??[],n;if(typeof e.cursorIdx=="number"&&e.cursorIdx>=0&&(n=i[e.cursorIdx]),!n&&e.selection?.size>0){let r=e.firstSelectedId??[...e.selection][0];n=i.find(o=>o.id===r)}return n?.file?{folder:s,id:n.id,file:n.file}:null}async pinNote(t){let e=this.settings.pinnedNotes??[];e.some(s=>s.folder===t.folder&&s.id===t.id)||(this.settings.pinnedNotes=[...e,t],await this.saveSettings(),this.refreshPanelsView())}async unpinNote(t){let e=this.settings.pinnedNotes??[],s=e.filter(i=>!(i.folder===t.folder&&i.id===t.id));s.length!==e.length&&(this.settings.pinnedNotes=s,await this.saveSettings(),this.refreshPanelsView())}isPinned(t){return(this.settings.pinnedNotes??[]).some(e=>e.folder===t.folder&&e.id===t.id)}refreshPanelsView(){let t=this.app.workspace.getLeavesOfType(_t);for(let e of t){let s=e.view;s&&typeof s.render=="function"&&s.render()}}openFolderPicker(){let t=p=>{let v=p.getViewState().state?.folderOverride;return typeof v=="string"&&v.trim()?v.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},e=this.app.workspace.getLeavesOfType(mt),s=this.discoverStashpadFolders(),i=Pt(),n=i?(i.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",r=new Set;for(let p of this.app.vault.getAllLoadedFiles())if(p.children){let m=p.path;m&&m!=="/"&&!m.startsWith(".")&&r.add(m)}let o=p=>{let m=p.split("/").filter(Boolean).pop()??"";return m?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors"].map(y=>(y??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(m):!1},a=new Set,l=[],c=[],h=new Set;for(let p of e){let m=t(p);if(h.has(m))continue;h.add(m),a.add(m);let v=m.split("/").pop()||m;l.push({kind:"reveal",folder:m,label:`Reveal "${v}" tab`,leaf:p,icon:"layout-grid"}),c.push({kind:"open-anyway",folder:m,label:`Open "${v}" in another new tab`,icon:"layout-template"})}for(let p of s.filter(m=>!a.has(m))){let m=p.split("/").pop()||p;l.push({kind:"open",folder:p,label:`Open "${m}" in new tab`,icon:"layout-template"})}let u=this,d=new class extends it.SuggestModal{getSuggestions(p){let m=p.trim().toLowerCase(),v=m?m.split(/\s+/).filter(Boolean):[],y=E=>{if(!v.length)return!0;let I=E.toLowerCase();for(let A of v)if(!I.includes(A))return!1;return!0},b=m?l.filter(E=>{let I="folder"in E?E.folder:"";return y(E.label)||y(I)}):l.slice();if(m&&i&&n)for(let E of s){if(E.toLowerCase()===n.toLowerCase())continue;let I=E.split("/").pop()??E,A=`${E} ${I}`;y(A)&&b.push({kind:"switch-current",folder:E,label:`Switch this tab to "${I}"`,icon:"folder-input"})}let k=p.trim().replace(/^\/+|\/+$/g,"");if(k&&!o(k)){let E=Array.from(r).find(A=>A.toLowerCase()===k.toLowerCase()),I=s.some(A=>A.toLowerCase()===k.toLowerCase());if(E&&!I)b.push({kind:"convert",folder:E,label:`Convert \u201C${is(E)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!E){let A=is(k);b.push({kind:"create",folder:k,label:`+ Create new Stashpad \u201C${A}\u201D`,icon:"folder-plus"})}}let C=c.filter(E=>y(E.label)||y(E.folder));return b.push(...C),b}renderSuggestion(p,m){m.addClass("stashpad-suggest-item"),m.addClass("stashpad-ribbon-suggest-item"),p.kind==="create"&&m.addClass("stashpad-suggest-create");let v=m.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,it.setIcon)(v,p.icon);let y=m.createDiv({cls:"stashpad-ribbon-suggest-body"});y.createDiv({cls:"stashpad-suggest-title",text:p.label}),"folder"in p&&p.folder&&p.label!==p.folder&&y.createDiv({cls:"stashpad-suggest-preview",text:p.folder})}async onChooseSuggestion(p){if(p.kind==="reveal"){u.app.workspace.revealLeaf(p.leaf);return}if(p.kind==="open"||p.kind==="open-anyway"){await u.activateViewForFolder(p.folder);return}if(p.kind==="switch-current"){let m=i;m&&typeof m.setFolderOverride=="function"&&(await m.setFolderOverride(p.folder),u.app.workspace.revealLeaf(m.leaf));return}if(p.kind==="create"){try{let m=is(p.folder);await u.app.vault.adapter.exists(m)||await u.app.vault.createFolder(m),await u.activateViewForFolder(m)}catch(m){new it.Notice(`Stashpad: couldn't create folder (${m.message})`)}return}if(p.kind==="convert"){let{ConfirmModal:m}=await Promise.resolve().then(()=>(Gt(),Fe)),v=p.folder,y=[`\u201C${v}\u201D already exists as a regular vault folder.`,"Converting will add a Home note + _imports / _exports subfolders inside it.","Existing files are NOT touched."];new m(u.app,"Convert into a Stashpad?",y.join(` +`),"Convert",async b=>{if(b)try{await u.activateViewForFolder(v)}catch(k){new it.Notice(`Stashpad: couldn't convert folder (${k.message})`)}}).open();return}}}(this.app);d.setPlaceholder(i?"Open, switch this tab, or create a Stashpad folder \u2014 type to filter\u2026":"Open or create a Stashpad folder \u2014 type to filter\u2026"),d.open()}async openTinyWindow(){let t=Pt(),e=t?.folderOverride??null,s=t?.focusId??"__root__",i=!!t?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new it.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:mt,active:!0,state:{folderOverride:e,focusId:s,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:i}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(t={reveal:!0}){let{workspace:e}=this.app;if(t.reveal){let i=e.getLeavesOfType(mt);if(i.length>0){e.revealLeaf(i[0]);return}}let s=e.getLeaf("tab");await s.setViewState({type:mt,active:!0}),e.revealLeaf(s)}async activateViewForFolder(t){let e=(t||"").replace(/^\/+|\/+$/g,"");if(!e)return;let s=this.app.workspace.getLeaf("tab");await s.setViewState({type:mt,active:!0,state:{folderOverride:e}}),this.app.workspace.revealLeaf(s)}isStashpadNoteFile(t){let e=t.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(e))return!1;let s=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;return typeof s=="string"&&s.length>0}async revealNoteInStashpad(t){let e=t.parent?.path?.replace(/\/+$/,"")??"",s=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;if(!e||typeof s!="string"||!s){new it.Notice("That note isn't a Stashpad note.");return}let i=this.app.workspace.getLeavesOfType(mt).find(r=>(r.view?.noteFolder??"")===e);if(i){this.app.workspace.revealLeaf(i);let r=i.view;typeof r?.navigateTo=="function"&&r.navigateTo(s);return}await this.activateViewForFolder(e);let n=this.lastActiveStashpadLeaf?.view;typeof n?.navigateTo=="function"&&n.navigateTo(s)}collectAuthoredFolders(){let t=(this.settings.authorId??"").trim();if(!t)return[];let e=`-${t}`,s=this.discoverStashpadFolders(),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let r=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!r)continue;let o=typeof r.author=="string"?r.author:"",a=Array.isArray(r.contributors)?r.contributors.filter(p=>typeof p=="string"):[],l=o.includes(e),c=a.some(p=>p.includes(e));if(!l&&!c)continue;let h=n.parent?.path??"",u=s.find(p=>h===p||h.startsWith(p+"/"));if(!u)continue;i.has(u)||i.set(u,{authored:0,contributed:0});let d=i.get(u);l&&d.authored++,c&&d.contributed++}return[...i.entries()].map(([n,r])=>({folder:n,...r})).sort((n,r)=>r.authored+r.contributed-(n.authored+n.contributed))}parseAuthorRef(t){if(typeof t!="string")return null;let e=t.replace(/^\[\[/,"").replace(/\]\]$/,""),[s,i]=e.split("|"),n=s.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i);if(!n)return null;let r=n[2],o=(i??"").trim()||n[1].replace(/-/g," ").trim();return{id:r,name:o}}async rebuildAuthorRegistry(){let t=this.discoverStashpadFolders(),e=new Map,s=0;for(let n of this.app.vault.getMarkdownFiles()){let r=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!r)continue;let o=[];if(typeof r.author=="string"&&o.push(r.author),Array.isArray(r.contributors))for(let a of r.contributors)typeof a=="string"&&o.push(a);for(let a of o){let l=this.parseAuthorRef(a);if(l)if(!e.has(l.id))e.set(l.id,{id:l.id,name:l.name,fromStub:!1}),s++;else{let c=e.get(l.id);!c.name&&l.name&&(c.name=l.name)}}}let i=0;for(let n of t){let r=`${n}/_authors`;for(let o of this.app.vault.getMarkdownFiles()){if(!o.path.startsWith(r+"/"))continue;let a=this.parseAuthorFilePath(o.path);if(!a)continue;let l=this.app.metadataCache.getFileCache(o)?.frontmatter,h=((Array.isArray(l?.aliases)?l.aliases.find(m=>typeof m=="string")??"":typeof l?.aliases=="string"?l.aliases:"")||(typeof l?.name=="string"?l.name:"")||a.name).trim(),u=typeof l?.role=="string"?l.role:void 0,d=typeof l?.department=="string"?l.department:void 0,p=e.get(a.id);p||i++,e.set(a.id,{id:a.id,name:h||p?.name,role:u??p?.role,department:d??p?.department,fromStub:!0})}}return await this.authorRegistry.load(),this.authorRegistry.replaceAll([...e.values()]),await this.authorRegistry.save(),{total:e.size,fromStubs:i,fromNotes:s}}buildAuthorStub(t,e){let s=n=>n.replace(/"/g,'\\"'),i=["---",`authorId: ${t.id}`,"aliases:",` - "${s(t.name)}"`];return t.role&&i.push(`role: "${s(t.role)}"`),t.department&&i.push(`department: "${s(t.department)}"`),i.push(`created: ${e}`,"---",`# ${t.name}`),i.join(` +`)}async restoreMissingAuthorStubs(){await this.authorRegistry.load();let t=this.authorRegistry.all().filter(i=>i.id&&i.name),e=this.discoverStashpadFolders(),s=0;for(let i of e){let n=`${i}/_authors`;for(let r of t){let o=this.authorNameToSafe(r.name),a=`${n}/${o}-${r.id}.md`;if(!this.app.vault.getMarkdownFiles().some(c=>c.path.startsWith(n+"/")&&this.parseAuthorFilePath(c.path)?.id===r.id))try{if(await this.ensureFolderPath(n),await this.app.vault.adapter.exists(a))continue;await this.app.vault.create(a,this.buildAuthorStub(r,r.firstSeen??new Date().toISOString())),s++}catch(c){console.warn("[Stashpad] restore author stub failed",a,c)}}}return{created:s,folders:e.length}}async seedLocalAuthorStub(t){let e=(this.settings.authorId??"").trim(),s=(this.settings.authorName??"").trim();if(!e||!s)return!1;let i=`${t.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(a=>a.path.startsWith(i+"/")&&this.parseAuthorFilePath(a.path)?.id===e))return!1;let r=this.authorNameToSafe(s),o=`${i}/${r}-${e}.md`;try{return await this.ensureFolderPath(i),await this.app.vault.adapter.exists(o)?!1:(await this.app.vault.create(o,this.buildAuthorStub({id:e,name:s,role:this.settings.authorRole,department:this.settings.authorDepartment},new Date().toISOString())),this.authorRegistry.record({id:e,name:s,role:this.settings.authorRole,department:this.settings.authorDepartment}),!0)}catch(a){return console.warn("[Stashpad] seedLocalAuthorStub failed",o,a),!1}}async seedLocalAuthorStubsEverywhere(){if(!(this.settings.authorName??"").trim())return 0;let e=0;for(let s of this.discoverStashpadFolders())await this.seedLocalAuthorStub(s)&&e++;return e}async ensureFolderPath(t){let e=this.app.vault.adapter,s=t.split("/").filter(Boolean),i="";for(let n of s){i=i?`${i}/${n}`:n;try{await e.exists(i)||await e.mkdir(i)}catch(r){if(!/already exists/i.test(r.message))throw r}}}async loadSettings(){let t=await this.loadData()??{};typeof t?.confirmMultiDelete=="boolean"&&(typeof t.confirmBulkDelete!="boolean"&&(t.confirmBulkDelete=t.confirmMultiDelete),typeof t.confirmAttachmentDelete!="boolean"&&(t.confirmAttachmentDelete=t.confirmMultiDelete),delete t.confirmMultiDelete),typeof t?.jdIndexDestFolder=="string"&&typeof t?.jdIndexStashpadFolder!="string"&&(t.jdIndexStashpadFolder=t.jdIndexDestFolder),this.settings={...Bt,...t,shortcuts:{...Bt.shortcuts,...t?.shortcuts??{}},mod:{...Bt.mod,...t?.mod??{}},bindings:zi(t?.bindings,t?.shortcuts,t?.mod),customPalette:Array.isArray(t?.customPalette)?t.customPalette.filter(e=>typeof e=="string"&&/^#[0-9a-f]{6}$/i.test(e)):[],colorAliases:t?.colorAliases&&typeof t.colorAliases=="object"?t.colorAliases:{},noteTemplates:t?.noteTemplates&&typeof t.noteTemplates=="object"?t.noteTemplates:{},authorName:typeof t?.authorName=="string"?t.authorName:"",authorId:typeof t?.authorId=="string"?t.authorId:"",authorRole:typeof t?.authorRole=="string"?t.authorRole:"",authorDepartment:typeof t?.authorDepartment=="string"?t.authorDepartment:"",showAuthor:typeof t?.showAuthor=="boolean"?t.showAuthor:!0,showContributors:typeof t?.showContributors=="boolean"?t.showContributors:!0,showLastEdit:typeof t?.showLastEdit=="boolean"?t.showLastEdit:!0,viewModes:t?.viewModes&&typeof t.viewModes=="object"&&!Array.isArray(t.viewModes)?t.viewModes:{},includeAttachmentsInEverything:t?.includeAttachmentsInEverything&&typeof t.includeAttachmentsInEverything=="object"&&!Array.isArray(t.includeAttachmentsInEverything)?t.includeAttachmentsInEverything:{},hideChildlessNotes:t?.hideChildlessNotes&&typeof t.hideChildlessNotes=="object"&&!Array.isArray(t.hideChildlessNotes)?t.hideChildlessNotes:{},hideCompletedNotes:t?.hideCompletedNotes&&typeof t.hideCompletedNotes=="object"&&!Array.isArray(t.hideCompletedNotes)?t.hideCompletedNotes:{},mutedNotificationCategories:Array.isArray(t?.mutedNotificationCategories)?t.mutedNotificationCategories.filter(e=>typeof e=="string"):[],notificationHistoryLimit:typeof t?.notificationHistoryLimit=="number"&&Number.isFinite(t.notificationHistoryLimit)?t.notificationHistoryLimit:5e3,drafts:Wi(t?.drafts),lastSubmitted:t?.lastSubmitted&&typeof t.lastSubmitted=="object"?t.lastSubmitted:{},slugStopWords:Array.isArray(t?.slugStopWords)?t.slugStopWords:[...Et]},ks(this.settings),this.notifications.loadMutedFromList(this.settings.mutedNotificationCategories),this.notifications.setHistoryLimit(this.settings.notificationHistoryLimit),this.notifications.setDefaultAuthorId(this.settings.authorId),this.attachNotificationPersistence()}notificationsPath(){return this.pluginPrivatePath("notifications.json")}async attachNotificationPersistence(){if(this.notifPersistenceWired)return;this.notifPersistenceWired=!0;let t=this.app.vault.adapter,e=this.notificationsPath();try{if(await t.exists(e)){let s=await t.read(e),i=JSON.parse(s);Array.isArray(i)&&this.notifications.loadHistory(i)}}catch(s){console.warn("[Stashpad] failed to load notification history",s)}this.notifications.onChange(()=>{this.notifSaveTimer!=null&&window.clearTimeout(this.notifSaveTimer),this.notifSaveTimer=window.setTimeout(()=>{this.notifSaveTimer=null,this.persistNotificationHistory()},1e3)})}async persistNotificationHistory(){try{let t=this.notifications.recent().slice().reverse(),e=this.notificationsPath(),s=e.replace(/\/[^/]+$/,""),i=this.app.vault.adapter;s&&!await i.exists(s)&&await i.mkdir(s),await i.write(e,JSON.stringify(t))}catch(t){console.warn("[Stashpad] failed to save notification history",t)}}readLastCursorFile(){try{let t=window.localStorage.getItem(this.LAST_CURSOR_LS_KEY);if(!t)return{};let e=JSON.parse(t);return e&&typeof e=="object"?e:{}}catch{return{}}}loadLastCursor(t){let s=this.readLastCursorFile()[t]??{};return new Map(Object.entries(s))}saveLastCursor(t,e,s){try{let i=this.readLastCursorFile();i[t]||(i[t]={}),i[t][e]=s,window.localStorage.setItem(this.LAST_CURSOR_LS_KEY,JSON.stringify(i))}catch(i){console.warn("[Stashpad] failed to save last-cursor",i)}}queueWrite(){let t=this.writeChain.then(()=>this.saveData(this.settings));return this.writeChain=t.catch(()=>{}),t}async saveSettings(){await this.queueWrite(),ks(this.settings);let t=(this.settings.authorId??"").trim();t&&this.authorRegistry.record({id:t,name:this.settings.authorName,role:this.settings.authorRole,department:this.settings.authorDepartment}),console.debug("[Stashpad] saveSettings",{shortcuts:this.settings.shortcuts,mod:this.settings.mod})}async persistSettingsQuiet(){await this.queueWrite()}async fixOrphanParents(){let t=new Set(this.discoverStashpadFolders());if(t.size===0){new it.Notice("No Stashpad folders found.");return}let e=new Set,s=this.app.vault.getMarkdownFiles();for(let h of s){let u=this.app.metadataCache.getFileCache(h)?.frontmatter,d=typeof u?.id=="string"?u.id.trim():"";d&&e.add(d)}let{newId:i}=await Promise.resolve().then(()=>(Ot(),ze)),n=()=>{for(let h=0;h<100;h++){let u=i();if(!e.has(u))return e.add(u),u}for(let h=8;h<=16;h+=2){let u=i(h);if(!e.has(u))return e.add(u),u}throw new Error("Could not generate a unique id")},r=[];for(let h of s){let u=h.parent?.path?.replace(/\/+$/,"")??"";if(!t.has(u))continue;let d=this.app.metadataCache.getFileCache(h)?.frontmatter,p=typeof d?.id=="string"?d.id.trim():"",m=d?.parent,v=typeof m=="string"?m.trim()!=="":m!=null,y=typeof d?.created=="string"&&d.created.trim()!=="",b=!p,k=!v,C=!y;!b&&!k&&!C||r.push({file:h,addId:b,addParent:k,addCreated:C})}if(r.length===0){new it.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let o=0,a=0,l=this.newLog();for(let h of r)try{let u;await this.app.fileManager.processFrontMatter(h.file,m=>{if(h.addId&&(typeof m.id=="string"&&m.id.trim()||(u=n(),m.id=u)),h.addParent){let v=m.parent;(typeof v=="string"?v.trim()!=="":v!=null)||(m.parent=R)}h.addCreated&&(typeof m.created=="string"&&m.created.trim()||(m.created=new Date(h.file.stat.ctime).toISOString()))});let d=this.app.metadataCache.getFileCache(h.file)?.frontmatter,p=u??d?.id??"";p&&await l.append({type:"parent_change",id:p,payload:{from:null,to:R,reason:"orphan_fix",path:h.file.path,addedId:h.addId,addedParent:h.addParent,addedCreated:h.addCreated}}),o++}catch(u){console.warn("Stashpad: orphan fix failed for",h.file.path,u),a++}let c=a?` (${a} failed \u2014 see console)`:"";new it.Notice(`Fixed ${o} note${o===1?"":"s"} in Stashpad folders${c}.`)}async adoptNote(t){let{newId:e}=await Promise.resolve().then(()=>(Ot(),ze)),s=new Set;for(let l of this.app.vault.getMarkdownFiles()){if(l.path===t.path)continue;let c=this.app.metadataCache.getFileCache(l)?.frontmatter,h=typeof c?.id=="string"?c.id.trim():"";h&&s.add(h)}let i=()=>{for(let l=0;l<50;l++){let c=e();if(!s.has(c))return c}for(let l=8;l<=16;l+=2){let c=e(l);if(!s.has(c))return c}throw new Error("Could not generate a unique id")},n=[],r=[];try{await this.app.fileManager.processFrontMatter(t,l=>{let c=typeof l.id=="string"?l.id.trim():"";!c||/\s/.test(c)||s.has(c)?(l.id=i(),n.push("id")):r.push("id"),l.parent!==void 0&&l.parent!==null&&String(l.parent).trim()!==""?r.push("parent"):(l.parent=R,n.push("parent")),typeof l.created=="string"&&l.created.trim()!==""?r.push("created"):(l.created=new Date(t.stat.ctime).toISOString(),n.push("created"))})}catch(l){new it.Notice(`Adopt failed: ${l.message}`);return}let o=!1;try{let l=this.app.metadataCache.getFileCache(t)?.frontmatter,c=typeof l?.id=="string"?l.id.trim():"";if(c&&t.basename&&!t.basename.endsWith(`-${c}`)){let h=`${t.parent?t.parent.path+"/":""}${t.basename}-${c}.md`;await this.app.vault.adapter.exists(h)||(await this.app.fileManager.renameFile(t,h),o=!0)}}catch(l){console.warn("Stashpad: adopt rename failed",l)}if(n.length===0&&!o){new it.Notice(`Already a Stashpad note (${r.join(", ")} present).`);return}let a=[];n.length&&a.push(`added: ${n.join(", ")}`),o&&a.push("renamed with id"),new it.Notice(`Adopted into Stashpad \u2014 ${a.join("; ")}.`);try{let l=this.newLog(),c=this.app.metadataCache.getFileCache(t)?.frontmatter,h=c?.id??"";h&&await l.append({type:"create",id:h,payload:{path:t.path,parent:c?.parent??R,source:"adopt",added:n}})}catch{}}};function zi(g,f,t){let e=Ss();for(let s of ve){let i=f&&typeof f[s.id]=="string"?f[s.id]:t&&typeof t[s.id]=="string"?t[s.id]:null;i!=null&&i!==""&&(e[s.id].primary=i)}if(g&&typeof g=="object")for(let s of ve){let i=g[s.id];!i||typeof i!="object"||(e[s.id]={primary:typeof i.primary=="string"?i.primary:e[s.id].primary,secondary:typeof i.secondary=="string"?i.secondary:"",preferRight:!!i.preferRight,useBoth:!!i.useBoth})}return e}function Wi(g){let f={};if(!g||typeof g!="object")return f;for(let[t,e]of Object.entries(g))if(typeof e=="string")f[t]=e;else if(e&&typeof e=="object"){for(let s of Object.values(e))if(typeof s=="string"&&s.length>0){f[t]=s;break}}return f} /*! Bundled license information: jszip/dist/jszip.min.js: diff --git a/manifest.json b/manifest.json index 37f763c..5bd2603 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "stashpad", "name": "Stashpad", - "version": "0.76.19", + "version": "0.77.9", "minAppVersion": "1.7.0", "description": "Chat-style nested-notes view: rapid capture, outliner navigation, in-place editing.", "author": "Human", diff --git a/package.json b/package.json index 93b74d5..34aaa5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stashpad-obsidian", - "version": "0.76.19", + "version": "0.77.9", "private": true, "scripts": { "dev": "node esbuild.config.mjs", diff --git a/release-notes/0.77.9.md b/release-notes/0.77.9.md new file mode 100644 index 0000000..f1a3e81 --- /dev/null +++ b/release-notes/0.77.9.md @@ -0,0 +1,69 @@ +# 0.77.9 — Author registry + claim authorship + +A multi-step pass over Stashpad's authorship model. The headline is a new +**author registry** that makes contributor/author data resilient to deleted +stubs, plus a way to **retroactively claim** notes you wrote before setting +your author name. + +## Author registry (0.77.1–0.77.6) +A rebuildable recovery cache + append-only rename history for every author +the vault has seen. Explicitly *not* a source of truth — the truth still +lives in note frontmatter and `_authors/` stubs. + +- **`authors.json`** lives in the plugin private dir. Records the local + user on load + every settings save, plus any author seen on stamp + (`ensureAuthorFile`). +- **Rebuild from a full vault scan.** New command **Rebuild author + registry** reconstructs `authors.json` by scanning author/contributor + wikilinks across every note's frontmatter (catches ids whose stub was + deleted) plus the existing `_authors/` stubs (authoritative for + name/role/department). `firstSeen` + rename history is preserved across + rebuilds. +- **Restore missing author stubs.** New command **Restore missing author + stubs (from registry)** regenerates any deleted `_authors/<name>.md` in + every Stashpad folder from the registry's remembered name / role / + department. Never overwrites or duplicates an existing one (matched by + id). +- **Settings UI.** New **Known authors (registry)** section in the + Authorship tab — Rebuild + Restore-missing-pages buttons and a list of + every recorded author with role / department, id, and rename history. + Presented as a recovery / audit tool, not a source of truth. +- **Rebootstrap refreshes the registry.** `rebootstrapAllFolders` now + refreshes the registry cache from its scan (read-only w.r.t. notes — + only plugin-private `authors.json` is rewritten). Stub-file restoration + is deliberately not folded in: a missing page may have been deleted on + purpose. + +## Author stubs use Obsidian-native aliases (0.77.4) +- Display name now lives in the stub's `aliases` array — so `[[Name]]` + resolves and the quick switcher finds the author — rather than a custom + `name` key. +- `ensureAuthorFile` delegates to a single canonical writer + (`buildAuthorStub`). The legacy `name` key is read as a fallback so + existing stubs keep resolving, then migrated off on next refresh. + +## Auto-seed your own author page (0.77.7) +- `seedLocalAuthorStub(folder)` creates *only* your own author page in any + folder that lacks it. No-op if your id already has a stub there. +- Runs at new-folder creation and once at startup across existing folders + (deferred ~4s after `onLayoutReady` so discovery + dedupe see a settled + metadata cache). +- Coworker pages stay lazy — they appear where they actually stamp — so + this stays an O(local user) cost instead of O(authors × folders). + +## Claim authorship retroactively (0.77.8–0.77.9) +For notes you wrote before setting an author name in Stashpad. + +- **Author-only variants** claim unowned notes (notes with no author set). +- **"+ contributor" variants** also add you to `contributors` on already- + authored notes — original author is left untouched. +- Two scopes: **selection** (current row + multi-selection) and **folder** + (confirms with a count first). +- **Never overwrites an existing author.** Only fills blanks. +- **Dedup:** already-yours notes are skipped; you're never set as both + author and contributor on the same note. +- **Drops a redundant contributor entry** when you become the author of a + note you'd previously edited (author supersedes contributor), and + remembers that so undo restores it. +- **Fully undoable.** Undo touches only the captured changed paths — never + paths that were skipped. diff --git a/src/author-registry.ts b/src/author-registry.ts new file mode 100644 index 0000000..6e7a96c --- /dev/null +++ b/src/author-registry.ts @@ -0,0 +1,189 @@ +import type { App } from "obsidian"; + +/** One rename event in an author's history. `at` is an ISO timestamp. */ +export interface AuthorRename { + from: string; + to: string; + at: string; +} + +/** A single author's record in the registry. Keyed by the stable + * `authorId`. Everything except `id` is cosmetic / recoverable — the id + * is the only durable join key (it's also baked into every note's + * author/contributors frontmatter wikilink and into the stub filename). */ +export interface AuthorRecord { + id: string; + /** Current best-known display name. */ + name: string; + role?: string; + department?: string; + /** ISO timestamp first observed by the registry. */ + firstSeen: string; + /** ISO timestamp last observed/updated. */ + lastSeen: string; + /** Append-only rename history (oldest → newest). */ + renames: AuthorRename[]; +} + +interface RegistryFile { + version: number; + authors: Record<string, AuthorRecord>; +} + +const REGISTRY_VERSION = 1; + +/** AuthorRegistry — a REBUILDABLE cache + append-only rename history of + * every author the plugin has ever seen, persisted as `authors.json` in + * the plugin's private dir (next to log.jsonl / state.json). + * + * IMPORTANT: this is explicitly NOT a source of truth. The authoritative + * identity is `settings.authorId` (for the local user) plus the id baked + * into each note's frontmatter + the `_authors/<name>-<id>.md` stub + * filenames. The registry can always be reconstructed by scanning the + * vault (see `rebuild()` in main.ts), so if it drifts, is corrupted, or + * is deleted, nothing breaks — we just rebuild it. Its value is: + * - recovery: regenerate a deleted stub from a remembered name/role/dept + * - history: an audit trail of display-name renames over time + * - directory: a fast "who exists" lookup that avoids a full vault scan + */ +export class AuthorRegistry { + private readonly path: string; + private data: RegistryFile = { version: REGISTRY_VERSION, authors: {} }; + private loaded = false; + private dirOk = false; + /** Serializes saves so concurrent writes don't trample each other. */ + private writeChain: Promise<void> = Promise.resolve(); + + constructor(private app: App, baseDir: string) { + this.path = `${baseDir.replace(/\/+$/, "")}/authors.json`; + } + + getPath(): string { return this.path; } + + async load(): Promise<void> { + if (this.loaded) return; + this.loaded = true; + try { + const adapter = this.app.vault.adapter; + if (await adapter.exists(this.path)) { + const parsed = JSON.parse(await adapter.read(this.path)) as Partial<RegistryFile>; + if (parsed && typeof parsed === "object" && parsed.authors) { + this.data = { + version: typeof parsed.version === "number" ? parsed.version : REGISTRY_VERSION, + authors: parsed.authors as Record<string, AuthorRecord>, + }; + } + } + } catch (e) { + console.warn("[Stashpad] author registry load failed; starting empty", e); + this.data = { version: REGISTRY_VERSION, authors: {} }; + } + } + + /** Snapshot of all known authors, newest-activity first. */ + all(): AuthorRecord[] { + return Object.values(this.data.authors) + .sort((a, b) => (b.lastSeen ?? "").localeCompare(a.lastSeen ?? "")); + } + + get(id: string): AuthorRecord | null { + return this.data.authors[id] ?? null; + } + + /** Upsert an author. If the display name changed, appends a rename + * event to the history. Updates lastSeen. Persists in the background. + * Returns true if anything changed (so callers can skip a redundant + * save when nothing did). */ + record(info: { id: string; name?: string; role?: string; department?: string; at?: string }): boolean { + const id = (info.id ?? "").trim(); + if (!id) return false; + const now = info.at ?? new Date().toISOString(); + const name = (info.name ?? "").trim(); + const existing = this.data.authors[id]; + let changed = false; + + if (!existing) { + this.data.authors[id] = { + id, + name, + role: info.role?.trim() || undefined, + department: info.department?.trim() || undefined, + firstSeen: now, + lastSeen: now, + renames: [], + }; + changed = true; + } else { + if (name && name !== existing.name) { + existing.renames.push({ from: existing.name, to: name, at: now }); + existing.name = name; + changed = true; + } + if (info.role !== undefined) { + const r = info.role.trim() || undefined; + if (r !== existing.role) { existing.role = r; changed = true; } + } + if (info.department !== undefined) { + const d = info.department.trim() || undefined; + if (d !== existing.department) { existing.department = d; changed = true; } + } + existing.lastSeen = now; + } + if (changed) void this.save(); + return changed; + } + + /** Replace the entire author set (used by rebuild()). Preserves + * firstSeen + rename history for ids that already existed. */ + replaceAll(records: Array<{ id: string; name?: string; role?: string; department?: string }>, at?: string): void { + const now = at ?? new Date().toISOString(); + const next: Record<string, AuthorRecord> = {}; + for (const rec of records) { + const id = (rec.id ?? "").trim(); + if (!id) continue; + const prior = this.data.authors[id]; + const name = (rec.name ?? "").trim() || prior?.name || ""; + const renames = prior?.renames ? [...prior.renames] : []; + if (prior && name && name !== prior.name) { + renames.push({ from: prior.name, to: name, at: now }); + } + next[id] = { + id, + name, + role: rec.role?.trim() || prior?.role || undefined, + department: rec.department?.trim() || prior?.department || undefined, + firstSeen: prior?.firstSeen ?? now, + lastSeen: now, + renames, + }; + } + this.data = { version: REGISTRY_VERSION, authors: next }; + void this.save(); + } + + private async ensureDir(): Promise<void> { + if (this.dirOk) return; + const adapter = this.app.vault.adapter; + const dir = this.path.slice(0, this.path.lastIndexOf("/")); + const parts = dir.split("/").filter(Boolean); + let cur = ""; + for (const p of parts) { + cur = cur ? `${cur}/${p}` : p; + if (!(await adapter.exists(cur))) await adapter.mkdir(cur); + } + this.dirOk = true; + } + + /** Persist the registry. Chained so overlapping saves serialize. */ + save(): Promise<void> { + this.writeChain = this.writeChain.then(async () => { + try { + await this.ensureDir(); + await this.app.vault.adapter.write(this.path, JSON.stringify(this.data, null, 2)); + } catch (e) { + console.warn("[Stashpad] author registry save failed", e); + } + }); + return this.writeChain; + } +} diff --git a/src/folder-suggest.ts b/src/folder-suggest.ts index f614752..703bd25 100644 --- a/src/folder-suggest.ts +++ b/src/folder-suggest.ts @@ -18,14 +18,19 @@ export class FolderSuggest extends AbstractInputSuggest<TFolder> { } protected getSuggestions(query: string): TFolder[] { - const q = query.toLowerCase(); + // 0.76.26: Sift — all-tokens, any-order match (see docs/sift.md) + // so "proj notes" finds "Notes/Projects" etc., not just literal + // substrings. + const tokens = query.toLowerCase().split(/\s+/).filter(Boolean); + const sift = (path: string): boolean => + tokens.every((t) => path.toLowerCase().includes(t)); const out: TFolder[] = []; const walk = (folder: TFolder): void => { // Skip the vault root from the suggestion list — its path is "/" // and selecting it sets the input to "/" which most callers // normalize away anyway. Children are still suggested. if (folder.path !== "/") { - if (!q || folder.path.toLowerCase().includes(q)) out.push(folder); + if (sift(folder.path)) out.push(folder); } for (const child of folder.children) { if (child instanceof TFolder) walk(child); diff --git a/src/main.ts b/src/main.ts index 5fb56b4..3793b9d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,6 +15,7 @@ import { ROOT_ID } from "./types"; import { UndoStack } from "./undo-stack"; import { rebootstrapFolderFrontmatter } from "./frontmatter-sync"; import { NotificationService, buildFileActions } from "./notifications"; +import { AuthorRegistry } from "./author-registry"; export default class StashpadPlugin extends Plugin { settings: StashpadSettings = { ...DEFAULT_SETTINGS }; @@ -47,6 +48,17 @@ export default class StashpadPlugin extends Plugin { if (!this._notifications) this._notifications = new NotificationService(this.app); return this._notifications; } + /** 0.77.1: rebuildable author registry (authors.json in the plugin + * private dir). NOT a source of truth — a recovery cache + rename + * history. See author-registry.ts. Lazily constructed; load() is + * awaited once during onload. */ + private _authorRegistry: AuthorRegistry | null = null; + get authorRegistry(): AuthorRegistry { + if (!this._authorRegistry) { + this._authorRegistry = new AuthorRegistry(this.app, this.pluginPrivatePath()); + } + return this._authorRegistry; + } /** Vault-relative path to a file/dir inside the plugin's private * folder (`.obsidian/plugins/<id>/.stashpad/...`). Used for the log, @@ -199,6 +211,9 @@ export default class StashpadPlugin extends Plugin { "Home", ].join("\n"); await this.app.vault.create(homePath, body); + // 0.77.7: seed the local user's author page into the new folder so + // their links resolve everywhere from the start. + try { await this.seedLocalAuthorStub(cleaned); } catch {} } /** Tally per-note colors found in EVERY markdown file under `folder`. @@ -444,6 +459,28 @@ export default class StashpadPlugin extends Plugin { this.settingTab = new StashpadSettingTab(this.app, this); this.addSettingTab(this.settingTab); + // 0.77.1: load the author registry and seed it with the local user. + await this.authorRegistry.load(); + { + const id = (this.settings.authorId ?? "").trim(); + if (id) { + this.authorRegistry.record({ + id, + name: this.settings.authorName, + role: this.settings.authorRole, + department: this.settings.authorDepartment, + }); + } + } + // 0.77.7: backfill the local user's author page into any existing + // Stashpad folder that lacks it. Deferred + after the metadata cache + // has settled so folder discovery + the "already has my stub" check + // are accurate (avoids creating a duplicate before the cache lists + // the existing one). New folders are seeded at creation time instead. + this.app.workspace.onLayoutReady(() => { + window.setTimeout(() => { void this.seedLocalAuthorStubsEverywhere(); }, 4000); + }); + this.registerView( STASHPAD_VIEW_TYPE, (leaf: WorkspaceLeaf) => new StashpadView(leaf, this), @@ -663,6 +700,30 @@ export default class StashpadPlugin extends Plugin { name: "Toggle split-on-newlines", callback: () => call("toggleSplit"), }); + // 0.77.8: claim authorship retroactively (for notes created before the + // user set their author name). Author-only variants only fill blank + // author fields; the "+ contributor" variants also add the user as a + // contributor to notes someone else already authored. All undoable. + this.addCommand({ + id: "stashpad-claim-selected-author", + name: "Claim authorship of selected notes", + callback: () => call("claimSelectedAsAuthor"), + }); + this.addCommand({ + id: "stashpad-claim-folder-author", + name: "Claim authorship of all unauthored notes in this folder", + callback: () => call("claimFolderAsAuthor"), + }); + this.addCommand({ + id: "stashpad-claim-selected-contributor", + name: "Claim selected notes (author if unowned, else add me as contributor)", + callback: () => call("claimSelectedWithContributor"), + }); + this.addCommand({ + id: "stashpad-claim-folder-contributor", + name: "Claim all notes in this folder (author if unowned, else add me as contributor)", + callback: () => call("claimFolderWithContributor"), + }); this.addCommand({ id: "stashpad-pick-destination", name: "Pick destination for next note", @@ -850,6 +911,45 @@ export default class StashpadPlugin extends Plugin { name: "Set missing parents to Home (orphan fix)", callback: () => void this.fixOrphanParents(), }); + // 0.77.2: rebuild the author registry from a full vault scan. + this.addCommand({ + id: "stashpad-rebuild-author-registry", + name: "Rebuild author registry (scan authors + note frontmatter)", + callback: async () => { + new Notice("Stashpad: rebuilding author registry…"); + try { + const r = await this.rebuildAuthorRegistry(); + this.notifications.show({ + message: `Author registry rebuilt: ${r.total} author(s) — ${r.fromStubs} from stubs, ${r.fromNotes} from note links.`, + kind: "success", + category: "system", + }); + } catch (e) { + new Notice(`Author registry rebuild failed: ${(e as Error).message}`); + } + }, + }); + // 0.77.3: regenerate any author stub files that were deleted, from + // the registry's remembered name/role/department. + this.addCommand({ + id: "stashpad-restore-author-stubs", + name: "Restore missing author stubs (from registry)", + callback: async () => { + new Notice("Stashpad: restoring author stubs…"); + try { + const r = await this.restoreMissingAuthorStubs(); + this.notifications.show({ + message: r.created > 0 + ? `Restored ${r.created} author stub(s) across ${r.folders} folder(s).` + : `No missing author stubs — all present across ${r.folders} folder(s).`, + kind: "success", + category: "system", + }); + } catch (e) { + new Notice(`Restore author stubs failed: ${(e as Error).message}`); + } + }, + }); // 0.58.0: rebootstrap as a command palette entry — mirrors the // "Rebootstrap now" button in settings. Useful when troubleshooting // / migrating without opening Settings. @@ -859,11 +959,12 @@ export default class StashpadPlugin extends Plugin { callback: async () => { new Notice("Stashpad: rebootstrapping…"); try { - const { touched, fmChecked, fmWritten, slugsRenamed } = await this.rebootstrapAllFolders(); + const { touched, fmChecked, fmWritten, slugsRenamed, authors } = await this.rebootstrapAllFolders(); const parts: string[] = []; parts.push(`rebootstrapped ${touched.length} folder${touched.length === 1 ? "" : "s"}`); if (fmWritten > 0) parts.push(`updated ${fmWritten} note${fmWritten === 1 ? "" : "s"}' metadata`); if (slugsRenamed > 0) parts.push(`renamed ${slugsRenamed} note${slugsRenamed === 1 ? "" : "s"}`); + if (authors > 0) parts.push(`${authors} author${authors === 1 ? "" : "s"} in registry`); parts.push(`(checked ${fmChecked} total)`); new Notice(`Stashpad: ${parts.join(" · ")}`); } catch (e) { @@ -1156,6 +1257,75 @@ export default class StashpadPlugin extends Plugin { if (!(file instanceof TFile)) return; void this.maybeAdoptAuthorRename(file, oldPath); })); + + // 0.76.31: detect when a newer plugin build has synced in but + // Obsidian is still running the old code (no hot-reload). Check + // shortly after load (let Sync settle) and whenever the app + // foregrounds. Nudges the user to reload so they're not stuck on + // stale code (the "old UI after opening the app" report). + this.registerDomEvent(window, "focus", () => void this.checkForSyncedBuild()); + setTimeout(() => void this.checkForSyncedBuild(), 5000); + } + + /** 0.76.31: compare the version Obsidian LOADED (this.manifest, read + * from manifest.json at launch) against the manifest.json currently + * on disk. If they differ, a different build has synced in since + * launch and the user is running stale code — surface a persistent + * notice with a Reload action (disable+enable re-reads main.js, + * works on mobile too). Notifies once per detected on-disk version. */ + private notifiedBuildVersion: string | null = null; + private async checkForSyncedBuild(): Promise<void> { + try { + const dir = (this.manifest as any).dir as string | undefined; + if (!dir) return; + const path = `${dir.replace(/\/+$/, "")}/manifest.json`; + const adapter = this.app.vault.adapter; + if (!(await adapter.exists(path))) return; + const onDisk = JSON.parse(await adapter.read(path))?.version as string | undefined; + const loaded = this.manifest.version; + if (typeof onDisk !== "string" || !onDisk || onDisk === loaded) return; + // 0.76.35: ONLY nudge when the on-disk build is strictly newer than + // what's running. If on-disk is OLDER (e.g. Obsidian Sync pushed a + // stale manifest.json back onto disk — a known Sync regression), + // reloading wouldn't help and the nudge would recur on every window + // focus forever. Silently ignore older/equal on-disk versions. + if (!this.isSemverGreater(onDisk, loaded)) return; + if (this.notifiedBuildVersion === onDisk) return; + this.notifiedBuildVersion = onDisk; + this.notifications.show({ + message: `A newer Stashpad build synced in (\`${loaded}\` → \`${onDisk}\`). Reload to apply.`, + kind: "info", + category: "system", + duration: 0, + actions: [{ + label: "Reload Stashpad", + onClick: async () => { + const plugins = (this.app as any).plugins; + try { + await plugins?.disablePlugin?.(this.manifest.id); + await plugins?.enablePlugin?.(this.manifest.id); + } catch (e) { + new Notice(`Couldn't reload — toggle Stashpad off/on in settings. (${(e as Error).message})`); + } + }, + }], + }); + } catch (e) { + console.debug("[Stashpad] synced-build check failed", e); + } + } + + /** Tiny semver-ish compare: is `a` greater than `b`? Pads to equal + * length, numeric per segment. Non-numeric segments compare as 0. */ + private isSemverGreater(a: string, b: string): boolean { + const pa = a.split(".").map((n) => parseInt(n, 10) || 0); + const pb = b.split(".").map((n) => parseInt(n, 10) || 0); + const len = Math.max(pa.length, pb.length); + for (let i = 0; i < len; i++) { + const x = pa[i] ?? 0, y = pb[i] ?? 0; + if (x !== y) return x > y; + } + return false; } /** Author files live at "<stashpadFolder>/_authors/<safe-name>-<id>.md". @@ -1212,8 +1382,10 @@ export default class StashpadPlugin extends Plugin { } } - /** Rewrite an author stub file's H1 heading + name/role/department - * frontmatter to match the current settings. Idempotent. */ + /** Rewrite an author stub file's H1 heading + aliases/role/department + * frontmatter to match the current settings. Idempotent. 0.77.4: the + * display name now lives in the Obsidian-native `aliases` array; the + * legacy custom `name` key is migrated away (deleted) here. */ private async refreshAuthorStub(file: TFile): Promise<void> { const name = (this.settings.authorName ?? "").trim(); const role = (this.settings.authorRole ?? "").trim(); @@ -1224,7 +1396,13 @@ export default class StashpadPlugin extends Plugin { const replaced = raw.replace(/^# .*$/m, `# ${name}`); if (replaced !== raw) await this.app.vault.modify(file, replaced); await this.app.fileManager.processFrontMatter(file, (m: any) => { - m.name = name; + // Stashpad owns these stubs, so the alias list is authoritative: + // set it to exactly the current display name. This avoids + // accumulating stale names across renames (an old name would + // otherwise linger as an "extra" alias). Migrate off the legacy + // custom `name` key. + m.aliases = [name]; + delete m.name; if (role) m.role = role; else delete m.role; if (dept) m.department = dept; else delete m.department; }); @@ -1464,7 +1642,7 @@ export default class StashpadPlugin extends Plugin { * ensure it has the import/export subfolders, and run the redundant-frontmatter * backfill (parentLink + children) so older notes pick up the recovery fields. * Used by the "Rebootstrap" button in settings to retrofit older folders. */ - async rebootstrapAllFolders(): Promise<{ touched: string[]; fmChecked: number; fmWritten: number; slugsRenamed: number }> { + async rebootstrapAllFolders(): Promise<{ touched: string[]; fmChecked: number; fmWritten: number; slugsRenamed: number; authors: number }> { const ROOT_ID = "__root__"; const seen = new Set<string>(); for (const f of this.app.vault.getMarkdownFiles()) { @@ -1510,7 +1688,16 @@ export default class StashpadPlugin extends Plugin { console.warn(`Stashpad: rebootstrap skipped ${folder}`, e); } } - return { touched, fmChecked, fmWritten, slugsRenamed }; + // 0.77.6: rebootstrap is the catch-all full-vault repair, so refresh + // the author registry cache from the same scan. This is read-only + // w.r.t. the user's notes (it only rewrites the plugin-private + // authors.json). NOTE: we deliberately do NOT restore deleted author + // STUB files here — that creates files and a user may have deleted a + // page on purpose; stub restoration stays an explicit action. + let authors = 0; + try { authors = (await this.rebuildAuthorRegistry()).total; } + catch (e) { console.warn("Stashpad: rebootstrap author-registry rebuild failed", e); } + return { touched, fmChecked, fmWritten, slugsRenamed, authors }; } /** Walk every Stashpad note in `folder`. For each one whose filename @@ -2020,6 +2207,190 @@ export default class StashpadPlugin extends Plugin { .sort((a, b) => (b.authored + b.contributed) - (a.authored + a.contributed)); } + /** Pull the display-name + id out of an author wikilink as written into + * note frontmatter, e.g. `[[demo/_authors/Jane-743jcy.md|Jane Doe]]` + * → { id: "743jcy", name: "Jane Doe" }. The alias (after `|`) is the + * display name; if absent we fall back to de-slugging the filename + * stem. Returns null when no id is present. */ + private parseAuthorRef(raw: string): { id: string; name: string } | null { + if (typeof raw !== "string") return null; + const inner = raw.replace(/^\[\[/, "").replace(/\]\]$/, ""); + const [target, alias] = inner.split("|"); + const m = target.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i); + if (!m) return null; + const id = m[2]; + const name = (alias ?? "").trim() || m[1].replace(/-/g, " ").trim(); + return { id, name }; + } + + /** 0.77.2: rebuild the author registry from scratch by scanning the + * vault. The authoritative inputs are (a) the `_authors` stub files + * (id from filename, display name from `aliases`/`name`/H1, plus role/ + * department frontmatter) and (b) author/contributor wikilinks across + * all note frontmatter (for ids whose stub was deleted). Stub metadata + * wins over note-link names when both exist. Preserves firstSeen + + * rename history for ids already in the registry. Returns a summary. */ + async rebuildAuthorRegistry(): Promise<{ total: number; fromStubs: number; fromNotes: number }> { + const stashpads = this.discoverStashpadFolders(); + const byId = new Map<string, { id: string; name?: string; role?: string; department?: string; fromStub: boolean }>(); + + // Pass 1: author wikilinks across all note frontmatter. + let fromNotes = 0; + for (const file of this.app.vault.getMarkdownFiles()) { + const fm = this.app.metadataCache.getFileCache(file)?.frontmatter as any; + if (!fm) continue; + const refs: string[] = []; + if (typeof fm.author === "string") refs.push(fm.author); + if (Array.isArray(fm.contributors)) { + for (const c of fm.contributors) if (typeof c === "string") refs.push(c); + } + for (const raw of refs) { + const parsed = this.parseAuthorRef(raw); + if (!parsed) continue; + if (!byId.has(parsed.id)) { byId.set(parsed.id, { id: parsed.id, name: parsed.name, fromStub: false }); fromNotes++; } + else { const e = byId.get(parsed.id)!; if (!e.name && parsed.name) e.name = parsed.name; } + } + } + + // Pass 2: stub files (authoritative for name/role/department). + let fromStubs = 0; + for (const folder of stashpads) { + const dir = `${folder}/_authors`; + for (const file of this.app.vault.getMarkdownFiles()) { + if (!file.path.startsWith(dir + "/")) continue; + const parsed = this.parseAuthorFilePath(file.path); + if (!parsed) continue; + const fm = this.app.metadataCache.getFileCache(file)?.frontmatter as any; + const aliasName = Array.isArray(fm?.aliases) ? (fm.aliases.find((a: any) => typeof a === "string") ?? "") + : (typeof fm?.aliases === "string" ? fm.aliases : ""); + const name = (aliasName || (typeof fm?.name === "string" ? fm.name : "") || parsed.name).trim(); + const role = typeof fm?.role === "string" ? fm.role : undefined; + const department = typeof fm?.department === "string" ? fm.department : undefined; + const existing = byId.get(parsed.id); + if (!existing) fromStubs++; + byId.set(parsed.id, { + id: parsed.id, + name: name || existing?.name, + role: role ?? existing?.role, + department: department ?? existing?.department, + fromStub: true, + }); + } + } + + await this.authorRegistry.load(); + this.authorRegistry.replaceAll([...byId.values()]); + await this.authorRegistry.save(); + return { total: byId.size, fromStubs, fromNotes }; + } + + /** Build the markdown content for an author stub file. Uses the + * Obsidian-native `aliases` for the display name (so `[[Name]]` + * resolves to the stub and it surfaces in quick switcher) plus role/ + * department + a created stamp + an H1. Stashpad-owned; safe to + * regenerate. */ + buildAuthorStub(rec: { id: string; name: string; role?: string; department?: string }, created: string): string { + const esc = (s: string) => s.replace(/"/g, '\\"'); + const lines = ["---", `authorId: ${rec.id}`, `aliases:`, ` - "${esc(rec.name)}"`]; + if (rec.role) lines.push(`role: "${esc(rec.role)}"`); + if (rec.department) lines.push(`department: "${esc(rec.department)}"`); + lines.push(`created: ${created}`, "---", `# ${rec.name}`); + return lines.join("\n"); + } + + /** 0.77.3: for every author the registry knows about, ensure a stub + * file exists in every discovered Stashpad folder — regenerating any + * that were deleted, from the remembered name/role/department. Never + * overwrites an existing stub (that's syncAuthorFilesToName's job). + * Returns the count of stubs created. */ + async restoreMissingAuthorStubs(): Promise<{ created: number; folders: number }> { + await this.authorRegistry.load(); + const authors = this.authorRegistry.all().filter((a) => a.id && a.name); + const folders = this.discoverStashpadFolders(); + let created = 0; + for (const folder of folders) { + const dir = `${folder}/_authors`; + for (const rec of authors) { + const safe = this.authorNameToSafe(rec.name); + const path = `${dir}/${safe}-${rec.id}.md`; + // Skip if a stub for this id already exists anywhere in this dir + // (under any name) — don't duplicate after a rename. + const exists = this.app.vault.getMarkdownFiles().some( + (f) => f.path.startsWith(dir + "/") && this.parseAuthorFilePath(f.path)?.id === rec.id, + ); + if (exists) continue; + try { + await this.ensureFolderPath(dir); + if (await this.app.vault.adapter.exists(path)) continue; + await this.app.vault.create(path, this.buildAuthorStub(rec, rec.firstSeen ?? new Date().toISOString())); + created++; + } catch (e) { + console.warn("[Stashpad] restore author stub failed", path, e); + } + } + } + return { created, folders: folders.length }; + } + + /** 0.77.7: ensure the LOCAL user's author page exists in `folder`, + * creating it from settings if missing. Targeted counterpart to + * restoreMissingAuthorStubs — seeds only YOUR page (not every known + * author), so links/quick-switcher resolve in every folder without the + * N×M clutter of propagating coworker pages into folders they've never + * touched. No-op if your name isn't set or a stub for your id already + * exists in that folder (under any name). */ + async seedLocalAuthorStub(folder: string): Promise<boolean> { + const id = (this.settings.authorId ?? "").trim(); + const name = (this.settings.authorName ?? "").trim(); + if (!id || !name) return false; + const dir = `${folder.replace(/\/+$/, "")}/_authors`; + const exists = this.app.vault.getMarkdownFiles().some( + (f) => f.path.startsWith(dir + "/") && this.parseAuthorFilePath(f.path)?.id === id, + ); + if (exists) return false; + const safe = this.authorNameToSafe(name); + const path = `${dir}/${safe}-${id}.md`; + try { + await this.ensureFolderPath(dir); + if (await this.app.vault.adapter.exists(path)) return false; + await this.app.vault.create(path, this.buildAuthorStub( + { id, name, role: this.settings.authorRole, department: this.settings.authorDepartment }, + new Date().toISOString(), + )); + this.authorRegistry.record({ id, name, role: this.settings.authorRole, department: this.settings.authorDepartment }); + return true; + } catch (e) { + console.warn("[Stashpad] seedLocalAuthorStub failed", path, e); + return false; + } + } + + /** Seed the local user's author page into every discovered Stashpad + * folder that lacks it. Run once at startup so existing folders get + * backfilled; new folders are handled at creation time. */ + async seedLocalAuthorStubsEverywhere(): Promise<number> { + const name = (this.settings.authorName ?? "").trim(); + if (!name) return 0; + let created = 0; + for (const folder of this.discoverStashpadFolders()) { + if (await this.seedLocalAuthorStub(folder)) created++; + } + return created; + } + + /** mkdir a vault dir path, intermediates included. Tolerates races and + * the "already exists" error Obsidian sometimes throws. */ + private async ensureFolderPath(dir: string): Promise<void> { + const adapter = this.app.vault.adapter; + const parts = dir.split("/").filter(Boolean); + let cur = ""; + for (const p of parts) { + cur = cur ? `${cur}/${p}` : p; + try { if (!(await adapter.exists(cur))) await adapter.mkdir(cur); } + catch (e) { if (!/already exists/i.test((e as Error).message)) throw e; } + } + } + async loadSettings(): Promise<void> { const data = (await this.loadData()) ?? {}; // Migrate legacy `confirmMultiDelete` (split in 0.51.12 into two flags: @@ -2206,6 +2577,19 @@ export default class StashpadPlugin extends Plugin { async saveSettings(): Promise<void> { await this.queueWrite(); setSettings(this.settings); + // 0.77.1: keep the registry's record of the local user current. The + // registry is a recovery cache — recording here means a name/role/ + // department change is remembered (with rename history) even if the + // _authors stubs are later deleted. + const id = (this.settings.authorId ?? "").trim(); + if (id) { + this.authorRegistry.record({ + id, + name: this.settings.authorName, + role: this.settings.authorRole, + department: this.settings.authorDepartment, + }); + } console.debug("[Stashpad] saveSettings", { shortcuts: this.settings.shortcuts, mod: this.settings.mod, diff --git a/src/modals.ts b/src/modals.ts index a0d9e5e..63e933f 100644 --- a/src/modals.ts +++ b/src/modals.ts @@ -1,4 +1,5 @@ import { App, Modal, Platform, moment, Notice, setIcon } from "obsidian"; +import { buildTimePickerInto } from "./time-picker"; import type { NotificationCategory, NotificationKind, NotificationRecord, NotificationService } from "./notifications"; interface LogEv { ts: string; type: string; id: string; payload?: any; author?: string; } @@ -864,7 +865,11 @@ export class DueDatePickerModal extends Modal { // gesture or on platforms that lack it (the input is still // directly editable / clickable as a fallback). dateIcon.onclick = () => { try { (dateInput as any).showPicker?.(); } catch { /* noop */ } }; - timeIcon.onclick = () => { try { (timeInput as any).showPicker?.(); } catch { /* noop */ } }; + // 0.76.23: the clock opens Stashpad's numpad time picker (the same + // control as the search When-builder) instead of the OS time + // picker — consistent UX + works the same everywhere. The time + // input stays directly editable too. + timeIcon.onclick = () => this.openTimeNumpad(timeIcon, timeInput); if (initial) { dateInput.value = this.toDateValue(initial); timeInput.value = this.toTimeValue(initial); @@ -886,13 +891,27 @@ export class DueDatePickerModal extends Modal { addPreset("Tomorrow", () => { const d = this.startOfTodayLocal(); d.setDate(d.getDate() + 1); return atNine(d); }); addPreset("Next week", () => { const d = this.startOfTodayLocal(); d.setDate(d.getDate() + 7); return atNine(d); }); + // 0.76.22: "Clear" only empties the fields and stays open — so you + // can clear a misapplied date and pick a new one without + // re-opening. To actually REMOVE the due, clear then Set (empty + // Set commits null). To keep the existing due, Cancel. const clear = grid.createEl("button", { cls: "stashpad-due-btn", text: "Clear" }); - clear.onclick = () => { this.didChoose = true; this.close(); this.onPick(null); }; + clear.onclick = () => { + dateInput.value = ""; + timeInput.value = ""; + dateInput.focus(); + }; const cancel = grid.createEl("button", { cls: "stashpad-due-btn", text: "Cancel" }); cancel.onclick = () => { this.didChoose = true; this.close(); }; const ok = grid.createEl("button", { cls: "stashpad-due-btn mod-cta", text: "Set" }); ok.onclick = () => { - if (!dateInput.value) { new Notice("Pick a date first (or use Clear)."); return; } + // Empty Set = remove the due date. + if (!dateInput.value) { + this.didChoose = true; + this.close(); + this.onPick(null); + return; + } // Default time to 09:00 when only a date was chosen. const [y, m, d] = dateInput.value.split("-").map((n) => parseInt(n, 10)); let hh = 9, mm = 0; @@ -905,7 +924,72 @@ export class DueDatePickerModal extends Modal { requestAnimationFrame(() => dateInput.focus()); } - onClose(): void { this.contentEl.empty(); void this.didChoose; } + onClose(): void { + this.tinyClosePopover?.(); + this.contentEl.empty(); + void this.didChoose; + } + + /** 0.76.23: open the shared numpad time picker anchored under the + * clock icon, writing the result back to the native time input as + * 24-hour HH:MM. Plain-DOM popover host (the modal isn't a + * SuggestModal, so no Obsidian Scope) with click-outside + Escape + + * Enter handling. */ + private tinyClosePopover: (() => void) | null = null; + private openTimeNumpad(anchor: HTMLElement, timeInput: HTMLInputElement): void { + this.tinyClosePopover?.(); + // Seed from the current time value, else the current clock time. + let h24 = 9, mm = 0; + if (timeInput.value) { + const [h, mi] = timeInput.value.split(":").map((n) => parseInt(n, 10)); + if (Number.isFinite(h)) h24 = h; + if (Number.isFinite(mi)) mm = mi; + } else { + const now = new Date(); + h24 = now.getHours(); + mm = now.getMinutes(); + } + const period: "am" | "pm" = h24 >= 12 ? "pm" : "am"; + const seedH = h24 === 0 ? 12 : (h24 > 12 ? h24 - 12 : h24); + + const pop = document.body.createDiv({ cls: "stashpad-when-popover stashpad-due-time-pop" }); + pop.style.position = "fixed"; + // Above the modal (Obsidian modals sit ~var(--layer-modal)). + pop.style.zIndex = "9999"; + + let onEnter: (() => void) | null = null; + const close = (): void => { + pop.remove(); + document.removeEventListener("mousedown", outside, true); + document.removeEventListener("keydown", onKey, true); + if (this.tinyClosePopover === close) this.tinyClosePopover = null; + }; + const outside = (e: MouseEvent): void => { + if (!pop.contains(e.target as Node) && e.target !== anchor && !anchor.contains(e.target as Node)) close(); + }; + const onKey = (e: KeyboardEvent): void => { + if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); close(); } + else if (e.key === "Enter" && onEnter) { e.preventDefault(); e.stopPropagation(); onEnter(); } + }; + this.tinyClosePopover = close; + + buildTimePickerInto(pop, { + seedH, seedM: mm, seedPeriod: period, + close, + setOnEnter: (cb) => { onEnter = cb; }, + onFinalize: (r) => { + timeInput.value = `${String(r.hours24).padStart(2, "0")}:${String(r.minutes).padStart(2, "0")}`; + }, + }); + + const rect = anchor.getBoundingClientRect(); + pop.style.left = `${Math.max(8, Math.min(rect.left, window.innerWidth - 220))}px`; + pop.style.top = `${rect.bottom + 4}px`; + setTimeout(() => { + document.addEventListener("mousedown", outside, true); + document.addEventListener("keydown", onKey, true); + }, 0); + } private startOfTodayLocal(): Date { const d = new Date(); diff --git a/src/note-picker.ts b/src/note-picker.ts index abbaa84..7be4c35 100644 --- a/src/note-picker.ts +++ b/src/note-picker.ts @@ -2,6 +2,7 @@ import { App, FuzzySuggestModal, Platform, Scope, SuggestModal, TFile, moment, s import type { TreeIndex } from "./tree-index"; import type { TreeNode } from "./types"; import { ROOT_ID } from "./types"; +import { buildTimePickerInto, formatWhenTime } from "./time-picker"; /** Parsed shape of a search query string. The original free-text tokens * go into `text` (token-order-agnostic match against title/body); each @@ -776,6 +777,20 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { this.mountFilterChipRow(inputEl, resultsEl); return; } + // 0.76.36: on mobile, when the picker opens while the composer holds + // the soft keyboard, focus doesn't move to the picker input on its + // own — typed queries land in the composer. Obsidian's SuggestModal + // deliberately doesn't autofocus its input on mobile (to avoid popping + // the keyboard). We DO want it here, and crucially this onOpen runs + // synchronously inside Modal.open(), which we call inside the button's + // tap handler — so this focus() executes while the user gesture is + // still live, letting iOS hop the keyboard from the composer textarea + // straight to the picker input WITHOUT dismissing it. (Deferred + // focus() via setTimeout would be outside the gesture and fail.) + if (Platform.isMobile) { + const inputEl = (this as any).inputEl as HTMLInputElement | undefined; + if (inputEl) inputEl.focus(); + } } private mountFilterChipRow(inputEl: HTMLInputElement, resultsEl: HTMLElement): void { @@ -1373,158 +1388,15 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { seedPeriod: "am" | "pm", ): void => { openInsertPopover(anchor, (pop, close, setOnEnter) => { - pop.addClass("stashpad-when-pop-time"); - let period = seedPeriod; - // Top row: HH : MM AM/PM toggle - const display = pop.createDiv({ cls: "stashpad-when-time-display" }); - const hField = display.createEl("input", { - cls: "stashpad-when-time-field", - attr: { type: "text", inputmode: "numeric", maxlength: "2" }, - }) as HTMLInputElement; - hField.value = String(seedH); - display.createSpan({ cls: "stashpad-when-time-colon", text: ":" }); - const mField = display.createEl("input", { - cls: "stashpad-when-time-field", - attr: { type: "text", inputmode: "numeric", maxlength: "2" }, - }) as HTMLInputElement; - mField.value = String(seedM).padStart(2, "0"); - const periodWrap = display.createDiv({ cls: "stashpad-when-time-period" }); - const amBtn = periodWrap.createEl("button", { cls: "stashpad-when-time-ampm", text: "AM" }); - amBtn.type = "button"; - const pmBtn = periodWrap.createEl("button", { cls: "stashpad-when-time-ampm", text: "PM" }); - pmBtn.type = "button"; - const syncPeriod = (): void => { - amBtn.toggleClass("is-active", period === "am"); - pmBtn.toggleClass("is-active", period === "pm"); - }; - syncPeriod(); - amBtn.addEventListener("mousedown", (ev) => ev.preventDefault()); - pmBtn.addEventListener("mousedown", (ev) => ev.preventDefault()); - amBtn.addEventListener("click", (ev) => { ev.preventDefault(); period = "am"; syncPeriod(); }); - pmBtn.addEventListener("click", (ev) => { ev.preventDefault(); period = "pm"; syncPeriod(); }); - - // Track focused field for the numpad. When a field gains focus - // we select-all so the next digit replaces (0.69.15 fix). - let focused: HTMLInputElement = hField; - hField.addEventListener("focus", () => { focused = hField; hField.select(); }); - mField.addEventListener("focus", () => { focused = mField; mField.select(); }); - - /** 0.69.15: when HH exceeds 12, AM/PM is meaningless (24h mode) - * — grey out both buttons and treat the value as 24-hour. */ - const syncAmpmEnabled = (): void => { - const h = parseInt(hField.value || "0", 10) || 0; - const is24 = h > 12; - amBtn.toggleClass("is-disabled", is24); - pmBtn.toggleClass("is-disabled", is24); - amBtn.disabled = is24; - pmBtn.disabled = is24; - }; - - // Constrain typed input — digits only, max 2 chars, clamp to range. - // 0.69.15: hours now accept 0-24 (24h), minutes 0-59. - const clamp = (el: HTMLInputElement): void => { - let v = el.value.replace(/\D/g, "").slice(0, 2); - if (v === "") { el.value = ""; if (el === hField) syncAmpmEnabled(); return; } - let n = parseInt(v, 10); - if (el === hField) { if (n > 24) n = 24; } - else { if (n > 59) n = 59; } - el.value = String(n); - if (el === hField) syncAmpmEnabled(); - }; - for (const el of [hField, mField]) { - el.addEventListener("input", () => clamp(el)); - } - syncAmpmEnabled(); - - const finalize = (): void => { - const hNum = parseInt(hField.value || "12", 10) || 12; - const mm = parseInt(mField.value || "0", 10) || 0; - // 0.69.15: when HH > 12, output 24-hour without am/pm suffix. - // Otherwise output 12-hour with the toggled am/pm. - const time = hNum > 12 - ? `${hNum}:${String(mm).padStart(2, "0")}` - : `${hNum}:${String(mm).padStart(2, "0")}${period}`; - insertAtCursor(targetInput, time); - close(); - }; - // 0.69.29: route popover-level Enter to finalize so it - // works regardless of which sub-element has focus (numpad - // buttons aren't focusable enough for the DOM Enter listener - // to be reliable). - setOnEnter(finalize); - - // 0.69.15: list every tabbable element in the popover and trap - // Tab on each to cycle within (Tab forward, Shift+Tab back). - // Numpad buttons are constructed below — we collect them after. - const tabRing: HTMLElement[] = [hField, mField, amBtn, pmBtn]; - const cycleFocus = (cur: HTMLElement, dir: 1 | -1): void => { - const idx = tabRing.indexOf(cur); - if (idx === -1) return; - const len = tabRing.length; - const next = (idx + dir + len) % len; - tabRing[next].focus(); - }; - const trapKey = (el: HTMLElement): void => { - el.addEventListener("keydown", (ev) => { - if (ev.key === "Enter") { ev.preventDefault(); ev.stopPropagation(); finalize(); } - else if (ev.key === "Escape") { ev.preventDefault(); ev.stopPropagation(); close(); } - else if (ev.key === "Tab") { - ev.preventDefault(); - ev.stopPropagation(); - cycleFocus(el, ev.shiftKey ? -1 : 1); - } - }); - }; - - // Numpad — 3x4 grid: 1 2 3 / 4 5 6 / 7 8 9 / ⌫ 0 Insert. - const pad = pop.createDiv({ cls: "stashpad-when-time-pad" }); - const keys = ["1","2","3","4","5","6","7","8","9","backspace","0","insert"]; - let okBtn: HTMLButtonElement | null = null; - for (const key of keys) { - const b = pad.createEl("button", { cls: "stashpad-when-time-padbtn" }); - b.type = "button"; - if (key === "backspace") setIcon(b, "delete"); - else if (key === "insert") { b.setText("OK"); okBtn = b; } - else b.setText(key); - if (key === "insert") b.addClass("is-go"); - b.addEventListener("mousedown", (ev) => ev.preventDefault()); - b.addEventListener("click", (ev) => { - ev.preventDefault(); - if (key === "insert") { finalize(); return; } - if (key === "backspace") { - focused.value = focused.value.slice(0, -1); - clamp(focused); - focused.focus(); - return; - } - // 0.69.15: if the field's current value is fully selected - // (e.g. just got focus and select() ran), REPLACE with the - // digit. Otherwise append until the 2-char cap, then replace. - const allSelected = - focused.selectionStart === 0 && - focused.selectionEnd === focused.value.length && - focused.value.length > 0; - const cap = 2; - const next = allSelected || focused.value.length >= cap - ? key - : focused.value + key; - focused.value = next; - clamp(focused); - focused.focus(); - // Move caret to end so subsequent presses append. - focused.setSelectionRange(focused.value.length, focused.value.length); - // Auto-advance from hours to minutes once full. - if (focused === hField && focused.value.length >= cap) { - mField.focus(); - mField.select(); - } - }); - } - // 0.69.15: complete the tab ring (HH → MM → AM → PM → OK → HH). - if (okBtn) tabRing.push(okBtn); - for (const el of tabRing) trapKey(el); - hField.focus(); - hField.select(); + // 0.76.23: the picker UI now lives in src/time-picker.ts so + // the due-date modal can reuse the exact same control. This + // host keeps the SuggestModal scope-aware popover behaviour; + // the shared builder fills it + reports the result, which we + // format the same way as before and insert at the caret. + buildTimePickerInto(pop, { + seedH, seedM, seedPeriod, close, setOnEnter, + onFinalize: (r) => insertAtCursor(targetInput, formatWhenTime(r)), + }); }); }; diff --git a/src/settings.ts b/src/settings.ts index d8369fc..6f1e300 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -536,16 +536,24 @@ export class StashpadSettingTab extends PluginSettingTab { /** Hide every .setting-item whose name + desc doesn't match the * current query, then collapse any group whose body has no - * visible matches. Called after rendering in search mode. */ + * visible matches. Called after rendering in search mode. + * + * 0.76.24: all-tokens, order-agnostic matching (same approach as + * the composer's link/tag autocomplete) instead of a single + * substring. The query is split on whitespace; EVERY token must + * appear somewhere in the item's name+desc, in any order — so + * "folder import" matches "Stash import subfolder" and "date tz" + * matches "Display timezone" via the date-format neighbours, etc. */ private applySearchFilter(body: HTMLElement): void { const q = this.searchQuery.trim().toLowerCase(); if (!q) return; + const tokens = q.split(/\s+/).filter(Boolean); + const matchesAll = (haystack: string): boolean => tokens.every((t) => haystack.includes(t)); const items = body.querySelectorAll<HTMLElement>(".setting-item"); items.forEach((el) => { const name = el.querySelector(".setting-item-name")?.textContent?.toLowerCase() ?? ""; const desc = el.querySelector(".setting-item-description")?.textContent?.toLowerCase() ?? ""; - const match = name.includes(q) || desc.includes(q); - el.style.display = match ? "" : "none"; + el.style.display = matchesAll(`${name} ${desc}`) ? "" : "none"; }); body.querySelectorAll<HTMLElement>(".stashpad-settings-search-group").forEach((g) => { const any = Array.from(g.querySelectorAll<HTMLElement>(".setting-item")) @@ -706,12 +714,13 @@ export class StashpadSettingTab extends PluginSettingTab { b.setButtonText("Rebootstrap now").onClick(async () => { b.setDisabled(true).setButtonText("Working…"); try { - const { touched, fmChecked, fmWritten, slugsRenamed } = await this.plugin.rebootstrapAllFolders(); + const { touched, fmChecked, fmWritten, slugsRenamed, authors } = await this.plugin.rebootstrapAllFolders(); const parts: string[] = []; parts.push(`rebootstrapped ${touched.length} folder${touched.length === 1 ? "" : "s"}`); if (fmWritten > 0) parts.push(`updated frontmatter on ${fmWritten} of ${fmChecked} notes`); else if (fmChecked > 0) parts.push(`frontmatter already in sync (${fmChecked} notes checked)`); if (slugsRenamed > 0) parts.push(`renamed ${slugsRenamed} note${slugsRenamed === 1 ? "" : "s"} to match body`); + if (authors > 0) parts.push(`rebuilt author registry (${authors} author${authors === 1 ? "" : "s"})`); new Notice(`Stashpad: ${parts.join("; ")}.`); } catch (e) { new Notice(`Stashpad: rebootstrap failed (${(e as Error).message})`); @@ -1341,6 +1350,64 @@ export class StashpadSettingTab extends PluginSettingTab { row.createSpan({ cls: "stashpad-authored-folder-counts", text: ` · ${counts.join(", ")}` }); } } + + this.renderKnownAuthorsSection(parent); + } + + /** 0.77.5: surface the author registry — a rebuildable cache + rename + * history of every author the plugin has seen. Lists known authors + * with role/department + rename history, plus rebuild/restore actions. + * The registry is NOT authoritative (the id baked into note frontmatter + * is); this is recovery + an audit trail. */ + private renderKnownAuthorsSection(parent: HTMLElement): void { + parent.createEl("h4", { text: "Known authors (registry)" }); + parent.createEl("div", { + cls: "setting-item-description", + text: "A rebuildable cache of every author Stashpad has seen, with rename history. Not a source of truth — the author id stored in each note is authoritative. Use it to recover deleted author pages or audit name changes.", + }); + + new Setting(parent) + .setName("Registry maintenance") + .setDesc("Rebuild scans the whole vault to reconstruct the list. Restore regenerates any deleted author pages across every Stashpad folder.") + .addButton((b) => b.setButtonText("Rebuild").onClick(async () => { + b.setDisabled(true).setButtonText("Rebuilding…"); + try { + const r = await this.plugin.rebuildAuthorRegistry(); + new Notice(`Author registry rebuilt: ${r.total} author(s).`); + } catch (e) { new Notice(`Rebuild failed: ${(e as Error).message}`); } + b.setDisabled(false).setButtonText("Rebuild"); + this.display(); + })) + .addButton((b) => b.setButtonText("Restore missing pages").onClick(async () => { + b.setDisabled(true).setButtonText("Restoring…"); + try { + const r = await this.plugin.restoreMissingAuthorStubs(); + new Notice(r.created > 0 ? `Restored ${r.created} author page(s).` : "No missing author pages."); + } catch (e) { new Notice(`Restore failed: ${(e as Error).message}`); } + b.setDisabled(false).setButtonText("Restore missing pages"); + })); + + const authors = this.plugin.authorRegistry.all(); + if (authors.length === 0) { + parent.createEl("div", { cls: "setting-item-description", text: "No authors recorded yet. Rebuild to scan the vault." }); + return; + } + const list = parent.createDiv({ cls: "stashpad-known-authors-list" }); + for (const a of authors) { + const row = list.createDiv({ cls: "stashpad-known-author-row" }); + const main = row.createDiv({ cls: "stashpad-known-author-main" }); + main.createSpan({ cls: "stashpad-known-author-name", text: a.name || "(unnamed)" }); + const meta: string[] = []; + if (a.role) meta.push(a.role); + if (a.department) meta.push(a.department); + meta.push(`id ${a.id}`); + main.createSpan({ cls: "stashpad-known-author-meta", text: ` · ${meta.join(" · ")}` }); + if (a.renames && a.renames.length > 0) { + const hist = row.createDiv({ cls: "stashpad-known-author-history" }); + const trail = a.renames.map((r) => `${r.from} → ${r.to}`).join(", "); + hist.setText(`Renamed: ${trail}`); + } + } } private renderNoteTemplatesSection(parent: HTMLElement): void { @@ -1391,9 +1458,14 @@ export class StashpadSettingTab extends PluginSettingTab { const renderSuggestions = (): void => { sugg.empty(); - const q = input.value.trim().toLowerCase(); + // 0.76.26: Sift — all-tokens, any-order match (see docs/sift.md). + const tokens = input.value.trim().toLowerCase().split(/\s+/).filter(Boolean); + const sift = (p: string): boolean => { + const h = p.toLowerCase(); + return tokens.every((t) => h.includes(t)); + }; const matches = allMd() - .filter((p) => !q || p.toLowerCase().includes(q)) + .filter((p) => sift(p)) .slice(0, 12); if (matches.length === 0) { sugg.style.display = "none"; return; } sugg.style.display = ""; diff --git a/src/time-picker.ts b/src/time-picker.ts new file mode 100644 index 0000000..35a7a5a --- /dev/null +++ b/src/time-picker.ts @@ -0,0 +1,174 @@ +import { setIcon } from "obsidian"; + +/** 0.76.23: the numpad time-picker UI, extracted from the search + * When-builder so the due-date modal can reuse the exact same + * control. PURE UI — it builds its widgets into a host element you + * provide and reports the result via `onFinalize`; the caller owns + * the popover lifecycle (positioning, click-outside, close). That + * keeps the search picker's scope-aware host and the modal's plain + * host independent while sharing one control. */ + +export interface TimePickResult { + /** 24-hour hours (0–23) — convenient for native <input type=time>. */ + hours24: number; + minutes: number; + /** Raw entry so a caller can reproduce an exact display string: + * `hh` is what was typed (1–24), `period` the am/pm toggle, and + * `is24` true when hh > 12 (am/pm meaningless). */ + raw: { hh: number; mm: number; period: "am" | "pm"; is24: boolean }; +} + +export interface BuildTimePickerOpts { + seedH: number; // 1–24 (or 1–12) to prefill the HH field + seedM: number; // 0–59 + seedPeriod: "am" | "pm"; + onFinalize: (r: TimePickResult) => void; + /** Close the host popover (called after finalize / on OK). */ + close: () => void; + /** Register the host's Enter handler so Enter anywhere finalizes. */ + setOnEnter?: (cb: () => void) => void; +} + +/** Convert a typed (hh 1–24, period) into 24-hour hours. */ +function to24(hh: number, period: "am" | "pm"): number { + if (hh > 12) return hh >= 24 ? 0 : hh; // already 24-hour + if (period === "am") return hh === 12 ? 0 : hh; + return hh === 12 ? 12 : hh + 12; +} + +/** Build the numpad time picker into `pop`. Mirrors the search + * When-builder's control exactly (HH : MM + AM/PM toggle on top, + * 3×4 numpad below). */ +export function buildTimePickerInto(pop: HTMLElement, opts: BuildTimePickerOpts): void { + pop.addClass("stashpad-when-pop-time"); + let period = opts.seedPeriod; + + const display = pop.createDiv({ cls: "stashpad-when-time-display" }); + const hField = display.createEl("input", { + cls: "stashpad-when-time-field", + attr: { type: "text", inputmode: "numeric", maxlength: "2" }, + }) as HTMLInputElement; + hField.value = String(opts.seedH); + display.createSpan({ cls: "stashpad-when-time-colon", text: ":" }); + const mField = display.createEl("input", { + cls: "stashpad-when-time-field", + attr: { type: "text", inputmode: "numeric", maxlength: "2" }, + }) as HTMLInputElement; + mField.value = String(opts.seedM).padStart(2, "0"); + + const periodWrap = display.createDiv({ cls: "stashpad-when-time-period" }); + const amBtn = periodWrap.createEl("button", { cls: "stashpad-when-time-ampm", text: "AM" }); + amBtn.type = "button"; + const pmBtn = periodWrap.createEl("button", { cls: "stashpad-when-time-ampm", text: "PM" }); + pmBtn.type = "button"; + const syncPeriod = (): void => { + amBtn.toggleClass("is-active", period === "am"); + pmBtn.toggleClass("is-active", period === "pm"); + }; + syncPeriod(); + amBtn.addEventListener("mousedown", (ev) => ev.preventDefault()); + pmBtn.addEventListener("mousedown", (ev) => ev.preventDefault()); + amBtn.addEventListener("click", (ev) => { ev.preventDefault(); period = "am"; syncPeriod(); }); + pmBtn.addEventListener("click", (ev) => { ev.preventDefault(); period = "pm"; syncPeriod(); }); + + let focused: HTMLInputElement = hField; + hField.addEventListener("focus", () => { focused = hField; hField.select(); }); + mField.addEventListener("focus", () => { focused = mField; mField.select(); }); + + const syncAmpmEnabled = (): void => { + const h = parseInt(hField.value || "0", 10) || 0; + const is24 = h > 12; + amBtn.toggleClass("is-disabled", is24); + pmBtn.toggleClass("is-disabled", is24); + amBtn.disabled = is24; + pmBtn.disabled = is24; + }; + + const clamp = (el: HTMLInputElement): void => { + const v = el.value.replace(/\D/g, "").slice(0, 2); + if (v === "") { el.value = ""; if (el === hField) syncAmpmEnabled(); return; } + let n = parseInt(v, 10); + if (el === hField) { if (n > 24) n = 24; } + else { if (n > 59) n = 59; } + el.value = String(n); + if (el === hField) syncAmpmEnabled(); + }; + for (const el of [hField, mField]) el.addEventListener("input", () => clamp(el)); + syncAmpmEnabled(); + + const finalize = (): void => { + const hh = parseInt(hField.value || "12", 10) || 12; + const mm = parseInt(mField.value || "0", 10) || 0; + const is24 = hh > 12; + opts.onFinalize({ + hours24: to24(hh, period), + minutes: mm, + raw: { hh, mm, period, is24 }, + }); + opts.close(); + }; + opts.setOnEnter?.(finalize); + + const tabRing: HTMLElement[] = [hField, mField, amBtn, pmBtn]; + const cycleFocus = (cur: HTMLElement, dir: 1 | -1): void => { + const idx = tabRing.indexOf(cur); + if (idx === -1) return; + const next = (idx + dir + tabRing.length) % tabRing.length; + tabRing[next].focus(); + }; + const trapKey = (el: HTMLElement): void => { + el.addEventListener("keydown", (ev) => { + if (ev.key === "Enter") { ev.preventDefault(); ev.stopPropagation(); finalize(); } + else if (ev.key === "Escape") { ev.preventDefault(); ev.stopPropagation(); opts.close(); } + else if (ev.key === "Tab") { ev.preventDefault(); ev.stopPropagation(); cycleFocus(el, ev.shiftKey ? -1 : 1); } + }); + }; + + const pad = pop.createDiv({ cls: "stashpad-when-time-pad" }); + const keys = ["1","2","3","4","5","6","7","8","9","backspace","0","insert"]; + let okBtn: HTMLButtonElement | null = null; + for (const key of keys) { + const b = pad.createEl("button", { cls: "stashpad-when-time-padbtn" }); + b.type = "button"; + if (key === "backspace") setIcon(b, "delete"); + else if (key === "insert") { b.setText("OK"); okBtn = b; } + else b.setText(key); + if (key === "insert") b.addClass("is-go"); + b.addEventListener("mousedown", (ev) => ev.preventDefault()); + b.addEventListener("click", (ev) => { + ev.preventDefault(); + if (key === "insert") { finalize(); return; } + if (key === "backspace") { + focused.value = focused.value.slice(0, -1); + clamp(focused); + focused.focus(); + return; + } + const allSelected = + focused.selectionStart === 0 && + focused.selectionEnd === focused.value.length && + focused.value.length > 0; + const cap = 2; + const next = allSelected || focused.value.length >= cap ? key : focused.value + key; + focused.value = next; + clamp(focused); + focused.focus(); + focused.setSelectionRange(focused.value.length, focused.value.length); + if (focused === hField && focused.value.length >= cap) { mField.focus(); mField.select(); } + }); + } + if (okBtn) tabRing.push(okBtn); + for (const el of tabRing) trapKey(el); + hField.focus(); + hField.select(); +} + +/** Format a finalized pick the way the search When-builder inserts it: + * `h:MMam` / `h:MMpm` for 12-hour, or `HH:MM` (no suffix) for 24-hour + * entries. */ +export function formatWhenTime(r: TimePickResult): string { + const { hh, mm, period, is24 } = r.raw; + return is24 + ? `${hh}:${String(mm).padStart(2, "0")}` + : `${hh}:${String(mm).padStart(2, "0")}${period}`; +} diff --git a/src/tree-index.ts b/src/tree-index.ts index 8ad10b6..52f4175 100644 --- a/src/tree-index.ts +++ b/src/tree-index.ts @@ -188,6 +188,15 @@ export class TreeIndex { .filter((n): n is TreeNode => !!n); } + /** 0.76.30: number of nodes backed by an actual file. Compared + * against the on-disk Stashpad-note count to detect a tree that + * drifted out of sync (mobile cold start / post-sync burst). */ + fileBackedCount(): number { + let n = 0; + for (const node of this.nodes.values()) if (node.file) n++; + return n; + } + pathTo(id: StashpadId): TreeNode[] { const out: TreeNode[] = []; let cur = this.nodes.get(id); diff --git a/src/view.ts b/src/view.ts index 3bc19ed..07b3a26 100644 --- a/src/view.ts +++ b/src/view.ts @@ -1,6 +1,7 @@ import { FuzzySuggestModal, ItemView, MarkdownRenderer, Menu, Notice, Platform, - Scope, SuggestModal, TFile, TFolder, WorkspaceLeaf, debounce, moment, setIcon, + Scope, SuggestModal, TFile, TFolder, WorkspaceLeaf, debounce, + moment, setIcon, } from "obsidian"; import { ROOT_ID, STASHPAD_VIEW_TYPE, RESERVED_FRONTMATTER, fmHasTag, fmAddTag, fmRemoveTag, @@ -26,6 +27,30 @@ import type StashpadPlugin from "./main"; const IMG_EXT = new Set(["png", "jpg", "jpeg", "gif", "webp", "svg", "bmp", "avif"]); +/** 0.76.33: setIcon that never leaves a blank button. If `name` isn't + * in this Obsidian build's bundled Lucide set (older iPad/iOS app + * versions lag desktop, so some names that resolve on desktop don't + * resolve there), setIcon injects no <svg> and the button renders + * empty. We detect that (setIcon is synchronous) and drop in a + * Unicode glyph so there's always a visible affordance. */ +function setIconSafe(el: HTMLElement, name: string, fallbackGlyph: string): void { + el.empty(); + try { setIcon(el, name); } catch { /* ignore */ } + // The ONLY reliable signal that the icon actually rendered is the + // presence of a drawable shape element inside the injected <svg>. + // Older/stripped mobile Lucide bundles can inject an empty (or + // whitespace-only) <svg class="svg-icon"></svg> for names they don't + // know — an svg node that exists but draws nothing. Checking for a + // path/line/circle/etc. distinguishes "real icon" from "empty shell". + const svg = el.querySelector("svg"); + const drawn = !!svg && !!svg.querySelector( + "path, line, circle, rect, polyline, polygon, ellipse" + ); + if (drawn) return; + el.empty(); + el.createSpan({ cls: "stashpad-icon-fallback", text: fallbackGlyph }); +} + const VIEW_MODE_LABELS: Record<ViewMode, string> = { nested: "Nested", flat: "Flat", @@ -124,6 +149,10 @@ export class StashpadView extends ItemView { * survives reloads. */ private tinyMode = false; private tinyAlwaysOnTop = false; + /** 0.77.0-feat: tiny-mode popout window opacity (0.3–1.0). Electron + * `BrowserWindow.setOpacity` — desktop popouts only; a no-op on + * mobile / non-popout. Persisted via view state. 1 = fully opaque. */ + private tinyOpacity = 1; /** 0.61.2: compact mode — like tiny mode but stays in the current * tab/leaf (no popout, no resize). Hides the time filter row and * focused-header; keeps breadcrumb + list + composer. Persisted. */ @@ -184,6 +213,13 @@ export class StashpadView extends ItemView { /** When true, the listResizeObserver re-pins scroll to the bottom each time * the list grows. Set after scrollListToBottom; cleared on user scroll. */ private stickToListBottom = false; + /** 0.76.27: timestamp until which the listResizeObserver ignores + * scroll adjustments. Set on mobile composer focus/blur — the + * keyboard show/hide resizes the list, which otherwise fired the + * observer and yanked the scroll position each time (the list + * "moving" on every composer interaction). During this window we + * let the browser's own reflow settle without fighting it. */ + private keyboardTransitionUntil = 0; /** Per-row ResizeObserver attached during scrollListToBottom — re-pins * the list to the bottom whenever a row's height changes. Survives * past the initial paint so cold-cache markdown / late font loads @@ -203,6 +239,12 @@ export class StashpadView extends ItemView { private lastCursorByFocus = new Map<StashpadId, StashpadId>(); private expandedNotes = new Set<StashpadId>(); private focusComposerOnNextRender = false; + /** 0.76.21: timestamp until which the activation auto-focus + * (focusComposer) is suppressed. Set after actions that close a + * modal and re-activate the leaf (e.g. Split) — the leaf + * re-activation otherwise yanks focus into the composer regardless + * of the autofocus-after-send setting. */ + private suppressComposerFocusUntil = 0; /** Debounced wrapper around saveDraft for the input event. Lazily * initialized on first composer render. */ private debouncedSaveDraft?: (v: string) => void; @@ -367,6 +409,17 @@ export class StashpadView extends ItemView { this.register(() => popViewScope()); this.detachTreeHook = this.tree.hookMetadataCache(() => this.debouncedRender()); + // 0.76.30: self-heal stale trees after a sync burst / cold start. + // The per-file create/changed hooks above can miss files that + // sync in before the view's listeners attach (mobile cold start) + // or land in a burst — leaving the folder showing fewer notes + // (or a stale layout) until a manual reload. metadataCache + // "resolved" fires when Obsidian finishes (re)indexing, which is + // exactly when synced-in files become known; reconcile then. The + // reconcile only rebuilds + renders when this folder's markdown + // file count actually differs from the tree, so it's a no-op + // during normal editing. + this.registerEvent(this.app.metadataCache.on("resolved", () => this.scheduleTreeReconcile())); // 0.76.11: keep the authoritative completed-state map in sync with // the metadataCache. A "changed" event means the cache is fresh // for that file, so re-sync our cached value from it. This is what @@ -510,6 +563,37 @@ export class StashpadView extends ItemView { })); } + /** 0.76.30: debounced reconcile against the metadata cache. Counts + * the markdown files actually under this folder and, if that count + * differs from what the tree knows, rebuilds + re-renders — so a + * folder that mounted with a stale/partial tree (mobile cold start, + * post-sync burst) self-heals without a manual reload. No-op when + * the counts already match. */ + private treeReconcileTimer: number | null = null; + private scheduleTreeReconcile(): void { + if (this.treeReconcileTimer != null) return; + this.treeReconcileTimer = window.setTimeout(() => { + this.treeReconcileTimer = null; + if (!this.viewRoot?.isConnected) return; + const folder = this.noteFolder; + const prefix = folder + "/"; + // Count actual Stashpad NOTES on disk (markdown files under this + // folder whose frontmatter carries an id) — matching what the + // tree tracks. Counting all markdown would over-count _authors + // stubs / templates and trigger perpetual no-op rebuilds. + let onDisk = 0; + for (const f of this.app.vault.getMarkdownFiles()) { + const dir = f.parent?.path?.replace(/\/+$/, "") ?? ""; + if (!(dir === folder || (folder !== "" && dir.startsWith(prefix)))) continue; + const id = this.app.metadataCache.getFileCache(f)?.frontmatter?.id; + if (typeof id === "string" && id) onDisk++; + } + if (onDisk === this.tree.fileBackedCount()) return; // in sync — no-op + this.tree.rebuild(folder); + this.debouncedRender(); + }, 400); + } + private focusView(): void { // Defer to next frame so Obsidian's own focus handling has settled first. requestAnimationFrame(() => { @@ -525,8 +609,20 @@ export class StashpadView extends ItemView { /** Focus the composer input. Used when activating the view so users can type immediately. * Runs multiple times to outlast Obsidian's own focus management on leaf activation. */ private focusComposer(): void { + // 0.76.24: honour the autofocus setting. This activation auto-focus + // previously ignored it, so the composer kept grabbing focus on + // view open / leaf re-activation even with the setting OFF. When + // off, the user clicks the composer to type. (Focus PRESERVATION + // across renders — focusComposerOnNextRender — is separate and + // still works: it only re-focuses when the composer already had + // focus.) + if (!getSettings().autofocusComposerAfterSend) return; const tryFocus = () => { if (!this.viewRoot?.isConnected) return; + // 0.76.21: skip the activation auto-focus during the suppression + // window (set right after a Split etc. so the modal-close leaf + // re-activation doesn't steal focus into the composer). + if (Date.now() < this.suppressComposerFocusUntil) return; const ae = document.activeElement as HTMLElement | null; // Don't steal from another input/modal that the user is intentionally in. if (ae && (ae.tagName === "INPUT" || ae.tagName === "TEXTAREA") && ae !== this.composerInputEl) return; @@ -557,6 +653,7 @@ export class StashpadView extends ItemView { this.composerNarrowObserver = null; this.focusedMiniObserver?.disconnect(); this.focusedMiniObserver = null; + if (this.treeReconcileTimer != null) { window.clearTimeout(this.treeReconcileTimer); this.treeReconcileTimer = null; } this.composerAutocomplete?.detach(); this.composerAutocomplete = null; for (const d of this.slugDebouncers.values()) d.cancel(); @@ -609,6 +706,7 @@ export class StashpadView extends ItemView { timeFilterCalendar: this.timeFilterCalendar, tinyMode: this.tinyMode, tinyAlwaysOnTop: this.tinyAlwaysOnTop, + tinyOpacity: this.tinyOpacity, compactMode: this.compactMode, // 0.67.2: persist nav stacks so reloads keep the back/forward // history. Without this every reload starts the user with empty @@ -625,6 +723,7 @@ export class StashpadView extends ItemView { timeFilterCalendar?: boolean; tinyMode?: boolean; tinyAlwaysOnTop?: boolean; + tinyOpacity?: number; compactMode?: boolean; navBackStack?: NavSnapshot[]; navForwardSnapshots?: NavSnapshot[]; @@ -638,6 +737,9 @@ export class StashpadView extends ItemView { if ("timeFilterCalendar" in s) this.timeFilterCalendar = !!s.timeFilterCalendar; if ("tinyMode" in s) this.tinyMode = !!s.tinyMode; if ("tinyAlwaysOnTop" in s) this.tinyAlwaysOnTop = !!s.tinyAlwaysOnTop; + if (typeof s.tinyOpacity === "number" && Number.isFinite(s.tinyOpacity)) { + this.tinyOpacity = Math.min(1, Math.max(0.3, s.tinyOpacity)); + } if ("compactMode" in s) this.compactMode = !!s.compactMode; // 0.67.2: restore nav stacks from view state. Validate the // shape so a malformed entry doesn't crash navigation later. @@ -1921,6 +2023,10 @@ export class StashpadView extends ItemView { const targetList = this.listEl; let settleTop = targetList.scrollTop; const ro = new ResizeObserver(() => { + // 0.76.27: during a mobile keyboard show/hide the list resizes; + // don't touch scrollTop then, or the list visibly jumps on + // every composer tap. Let the browser's reflow settle. + if (Date.now() < this.keyboardTransitionUntil) return; // Sticky-to-bottom mode: every growth of the list jumps to the new bottom. if (this.stickToListBottom) { targetList.scrollTop = targetList.scrollHeight; @@ -1993,7 +2099,7 @@ export class StashpadView extends ItemView { // 0.68.4: icon-only Search button between the folder switcher and // the tags dropdown. Mirrors the Mod+F binding for mouse users. const searchBtn = bar.createEl("button", { cls: "stashpad-search-btn" }); - setIcon(searchBtn, "search"); + setIconSafe(searchBtn, "search", "🔍"); searchBtn.title = "Search notes (Mod+F)"; searchBtn.onclick = (e) => { e.preventDefault(); this.openSearchModal(); }; @@ -2126,13 +2232,13 @@ export class StashpadView extends ItemView { // sit at the start of the actions cluster so they're always // visible alongside the breadcrumb. const backBtn = actions.createEl("button", { cls: "stashpad-mobile-action-btn" }); - setIcon(backBtn, "arrow-left"); + setIconSafe(backBtn, "arrow-left", "‹"); const canGoBack = this.navBackStack.length > 0 || this.focusId !== ROOT_ID; backBtn.title = this.navBackStack.length > 0 ? "Back" : (this.focusId !== ROOT_ID ? "Back (up to parent)" : "No back history"); if (!canGoBack) backBtn.addClass("is-disabled"); backBtn.onclick = (e) => { e.preventDefault(); this.navigateBack(); }; const fwdBtn = actions.createEl("button", { cls: "stashpad-mobile-action-btn" }); - setIcon(fwdBtn, "arrow-right"); + setIconSafe(fwdBtn, "arrow-right", "›"); const canGoFwd = this.navForwardSnapshots.length > 0; fwdBtn.title = canGoFwd ? "Forward" : "No forward history"; if (!canGoFwd) fwdBtn.addClass("is-disabled"); @@ -2140,7 +2246,7 @@ export class StashpadView extends ItemView { const selectBtn = actions.createEl("button", { cls: "stashpad-mobile-action-btn" }); const inSelect = this.mobileSelectMode; - setIcon(selectBtn, inSelect ? "check-square" : "square"); + setIconSafe(selectBtn, inSelect ? "check-square" : "square", inSelect ? "☑" : "☐"); selectBtn.title = inSelect ? `${this.selection.size} selected — tap to exit (keeps the first selection)` : "Enter select mode (tap notes to add)"; @@ -2177,7 +2283,7 @@ export class StashpadView extends ItemView { }; const moreBtn = actions.createEl("button", { cls: "stashpad-mobile-action-btn" }); - setIcon(moreBtn, "zap"); + setIconSafe(moreBtn, "zap", "⚡"); moreBtn.title = "Actions (move, delete, undo, …)"; moreBtn.onclick = (e) => { e.preventDefault(); @@ -2936,7 +3042,7 @@ export class StashpadView extends ItemView { // both the view-header and the breadcrumb, so without these the // user is stuck unless they ⤢ out of tiny mode first. const backBtn = bar.createEl("button", { cls: "stashpad-tiny-nav-btn" }); - setIcon(backBtn, "arrow-left"); + setIconSafe(backBtn, "arrow-left", "‹"); backBtn.title = "Back (up to parent)"; const tinyCanBack = this.navBackStack.length > 0 || this.focusId !== ROOT_ID; if (!tinyCanBack) backBtn.addClass("is-disabled"); @@ -2945,7 +3051,7 @@ export class StashpadView extends ItemView { : (this.focusId !== ROOT_ID ? "Back (up to parent)" : "No back history"); backBtn.onclick = () => this.navigateBack(); const fwdBtn = bar.createEl("button", { cls: "stashpad-tiny-nav-btn" }); - setIcon(fwdBtn, "arrow-right"); + setIconSafe(fwdBtn, "arrow-right", "›"); fwdBtn.title = this.navForwardSnapshots.length > 0 ? "Forward" : "No forward history"; if (this.navForwardSnapshots.length === 0) fwdBtn.addClass("is-disabled"); fwdBtn.onclick = () => this.navigateForward(); @@ -2979,6 +3085,17 @@ export class StashpadView extends ItemView { this.applyTinyAlwaysOnTop(); }; + // 0.77.0-feat: window-transparency button. Desktop popouts only + // (Electron setOpacity) — hidden on mobile, where there's no + // window to make transparent. Click toggles a small slider popover. + if (!Platform.isMobile) { + const opacityBtn = bar.createEl("button", { cls: "stashpad-tiny-nav-btn stashpad-tiny-opacity-btn" }); + setIcon(opacityBtn, "contrast"); + opacityBtn.title = "Window transparency"; + if (this.tinyOpacity < 1) opacityBtn.addClass("is-active"); + opacityBtn.onclick = (e) => { e.stopPropagation(); this.toggleTinyOpacityPopover(opacityBtn); }; + } + // 0.61.8: ALWAYS render the compact-toggle button in the tiny // header. Carrying compactMode through to tiny was meant to surface // the exit, but if a user enters tiny WITHOUT being in compact @@ -3005,6 +3122,59 @@ export class StashpadView extends ItemView { expandBtn.onclick = () => { void this.exitTinyMode(); }; } + /** 0.77.0-feat: handle to the open opacity popover so a second click + * (or click-outside) closes it. */ + private tinyOpacityPopover: HTMLElement | null = null; + private toggleTinyOpacityPopover(anchor: HTMLElement): void { + if (this.tinyOpacityPopover) { + this.tinyOpacityPopover.remove(); + this.tinyOpacityPopover = null; + return; + } + const pop = document.createElement("div"); + pop.className = "stashpad-tiny-opacity-popover"; + pop.createSpan({ cls: "stashpad-tiny-opacity-label", text: "Transparency" }); + const slider = pop.createEl("input", { type: "range" }) as HTMLInputElement; + slider.min = "30"; slider.max = "100"; slider.step = "1"; + slider.value = String(Math.round(this.tinyOpacity * 100)); + const pct = pop.createSpan({ cls: "stashpad-tiny-opacity-pct", text: `${slider.value}%` }); + // Live-apply as the user drags — opacity is cheap to set. + slider.addEventListener("input", () => { + const v = Math.min(100, Math.max(30, parseInt(slider.value, 10) || 100)); + this.tinyOpacity = v / 100; + pct.setText(`${v}%`); + this.applyTinyOpacity(); + anchor.toggleClass("is-active", this.tinyOpacity < 1); + }); + // Persist on release so the value survives reloads (view state). + slider.addEventListener("change", () => { this.app.workspace.requestSaveLayout(); }); + // Position under the anchor button. + this.viewRoot.appendChild(pop); + const r = anchor.getBoundingClientRect(); + const rootR = this.viewRoot.getBoundingClientRect(); + pop.style.top = `${r.bottom - rootR.top + 4}px`; + pop.style.left = `${Math.max(4, Math.min(r.left - rootR.left, rootR.width - 180))}px`; + // Close on click-outside / Escape. Added next tick so the opening + // click doesn't immediately dismiss it. + const onDoc = (ev: Event) => { + if (pop.contains(ev.target as Node) || ev.target === anchor || anchor.contains(ev.target as Node)) return; + close(); + }; + const onKey = (ev: KeyboardEvent) => { if (ev.key === "Escape") close(); }; + const close = () => { + pop.remove(); + this.tinyOpacityPopover = null; + document.removeEventListener("mousedown", onDoc, true); + document.removeEventListener("keydown", onKey, true); + }; + setTimeout(() => { + document.addEventListener("mousedown", onDoc, true); + document.addEventListener("keydown", onKey, true); + }, 0); + this.tinyOpacityPopover = pop; + slider.focus(); + } + /** Resolve the Electron BrowserWindow that hosts THIS view's leaf — * not the main app window. Each Obsidian popout runs its own renderer, * so require() must be invoked through the leaf's owner-document's @@ -3067,6 +3237,18 @@ export class StashpadView extends ItemView { } } + /** 0.77.0-feat: push this.tinyOpacity onto the host BrowserWindow. + * Electron-only; silent no-op on mobile / sandboxed builds. Clamped + * to [0.3, 1] so the window can't vanish entirely. */ + private applyTinyOpacity(): void { + const win = this.getOwnElectronWindow(); + if (!win) return; + const o = Math.min(1, Math.max(0.3, this.tinyOpacity)); + try { win.setOpacity?.(o); } catch (e) { + console.debug("[Stashpad] setOpacity failed", e); + } + } + /** Apply tiny-mode side-effects to the BrowserWindow that hosts this * leaf: resize down + optionally pin always-on-top. Best-effort — * bails silently if Electron's window APIs aren't reachable @@ -3095,6 +3277,8 @@ export class StashpadView extends ItemView { try { win.setBounds?.({ x, y, width: targetW, height: targetH }); } catch {} try { win.setSize?.(targetW, targetH); } catch {} win.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop); + // 0.77.0-feat: restore the saved opacity when entering tiny. + try { win.setOpacity?.(Math.min(1, Math.max(0.3, this.tinyOpacity))); } catch {} } else { win.setAlwaysOnTop?.(false); } @@ -3109,6 +3293,10 @@ export class StashpadView extends ItemView { private async exitTinyMode(): Promise<void> { this.tinyMode = false; this.tinyAlwaysOnTop = false; + // 0.77.0-feat: restore full opacity on the way out so the + // expanded window isn't left see-through. + this.tinyOpacity = 1; + try { this.getOwnElectronWindow()?.setOpacity?.(1); } catch {} // 0.61.10: also clear compact when leaving tiny. The user expected // expand-out to restore the full chrome, not retain the compact // row-stripping. (They can still toggle compact back on via the @@ -4019,8 +4207,9 @@ export class StashpadView extends ItemView { // events don't fire reliably inside Obsidian's webview, so this is a // more dependable proxy for "keyboard is showing right now." if (Platform.isMobile) { - ta.addEventListener("focus", () => document.body.classList.add("stashpad-keyboard-open")); - ta.addEventListener("blur", () => document.body.classList.remove("stashpad-keyboard-open")); + const keyboardTransition = () => { this.keyboardTransitionUntil = Date.now() + 600; }; + ta.addEventListener("focus", () => { document.body.classList.add("stashpad-keyboard-open"); keyboardTransition(); }); + ta.addEventListener("blur", () => { document.body.classList.remove("stashpad-keyboard-open"); keyboardTransition(); }); } this.composerInputEl = ta; // Tear down any previous autocomplete (the textarea was just rebuilt @@ -4872,6 +5061,13 @@ export class StashpadView extends ItemView { } openDestinationPicker(): void { + // 0.76.36: do NOT blur the composer here. On iOS, blur() dismisses the + // soft keyboard, and once dismissed a programmatic focus() on the + // picker input can't bring it back (iOS only re-summons the keyboard + // inside a live user gesture). Instead the picker focuses its own + // input synchronously inside the tap gesture (see note-picker onOpen), + // which lets iOS hop the keyboard straight from the composer textarea + // to the picker input without ever dismissing it. // 0.57.2: destination picker now spans all Stashpad folders + offers // each external Stashpad's root (Home) as its own pick. Picking a // cross-folder destination switches the view to that folder first @@ -6666,22 +6862,29 @@ export class StashpadView extends ItemView { }); } - /** 0.76.11: authoritative completed-state per path. Decouples - * isCompleted from the live metadataCache, which can transiently - * return stale frontmatter for sibling rows during the synthetic - * create-render. Seeded lazily from the cache, kept fresh by the - * metadataCache "changed" listener + our own toggles. */ + /** 0.76.11 / 0.76.32: completed-state OVERRIDE per path. Holds only + * values written authoritatively — our own toggles + the + * metadataCache "changed" listener (which fires as files parse). + * isCompleted prefers an override when present (keeps a row stable + * during the synthetic create-render, when getFileCache can + * transiently return stale frontmatter for siblings); otherwise it + * reads the LIVE cache. + * + * 0.76.32 fix: we no longer lazily cache a live read into the map. + * That poisoned hide-completed on mobile cold start — the first + * render ran before frontmatter parsed, cached `false` for a + * completed note, and the cached value stuck forever (so the note + * was treated as incomplete). Reading live when there's no override + * self-corrects on the parse-triggered re-render, and the "changed" + * listener still fills the map for create-render stability. */ private completedState = new Map<string, boolean>(); private isCompleted(node: TreeNode): boolean { if (!node.file) return false; - const path = node.file.path; - const cached = this.completedState.get(path); - if (cached !== undefined) return cached; + const override = this.completedState.get(node.file.path); + if (override !== undefined) return override; const fm = this.app.metadataCache.getFileCache(node.file)?.frontmatter; - const v = !!fm?.completed; - this.completedState.set(path, v); - return v; + return !!fm?.completed; } /** 0.76.1: open the due-date picker for the action targets and write @@ -7744,6 +7947,13 @@ export class StashpadView extends ItemView { }); this.tree.rebuild(this.noteFolder); this.render(); + // 0.76.21: keep focus in the list, not the composer. Splitting + // closes a modal which re-activates the leaf and (via + // focusComposer) used to pull focus into the composer even + // with autofocus-after-send OFF. Suppress that activation + // focus briefly and land on the list instead. + this.suppressComposerFocusUntil = Date.now() + 500; + this.viewRoot?.focus({ preventScroll: true } as any); this.plugin.notifications.show({ message: `Split "${this.titleForNode(target)}" into two`, kind: "success", @@ -8235,6 +8445,151 @@ export class StashpadView extends ItemView { return { link, path, name, id }; } + // --- 0.77.8: Claim authorship (retroactive stamping) --- + + /** Public entry points (called from main.ts command palette). */ + claimSelectedAsAuthor(): void { void this.claimAuthorship({ scope: "selection", contributorMode: false }); } + claimFolderAsAuthor(): void { void this.claimAuthorship({ scope: "folder", contributorMode: false }); } + claimSelectedWithContributor(): void { void this.claimAuthorship({ scope: "selection", contributorMode: true }); } + claimFolderWithContributor(): void { void this.claimAuthorship({ scope: "folder", contributorMode: true }); } + + /** All file-backed Stashpad notes (frontmatter `id`) under this view's + * folder, excluding the _authors stubs. */ + private fileBackedNotesInFolder(): TFile[] { + const folder = this.noteFolder.replace(/\/+$/, ""); + return this.app.vault.getMarkdownFiles().filter((f) => { + const dir = f.parent?.path?.replace(/\/+$/, "") ?? ""; + if (dir !== folder && !dir.startsWith(folder + "/")) return false; + if (f.path.includes("/_authors/")) return false; + const fm = this.app.metadataCache.getFileCache(f)?.frontmatter as any; + return typeof fm?.id === "string" && !!fm.id; + }); + } + + /** Apply a frontmatter mutation across many files, paced in batches so + * a bulk claim/unclaim doesn't choke the filesystem. Marks each as a + * self-write so the multiplayer external-modify detector doesn't park + * the change. */ + private async pacedFrontmatter(paths: string[], mutate: (m: any, path: string) => void): Promise<void> { + const BATCH = 25, DELAY = 30; + for (let i = 0; i < paths.length; i++) { + const f = this.app.vault.getAbstractFileByPath(paths[i]); + if (f instanceof TFile) { + this.recentSelfWrites.set(f.path, Date.now()); + try { await this.app.fileManager.processFrontMatter(f, (m) => mutate(m, paths[i])); } + catch (e) { console.warn("[Stashpad] claim: frontmatter write failed", paths[i], e); } + } + if ((i + 1) % BATCH === 0) await new Promise((r) => setTimeout(r, DELAY)); + } + } + + /** Retroactively stamp the local user onto notes that predate authorship + * setup. SAFETY MODEL: + * - Never overwrites an existing `author` (only fills blank ones). + * - contributorMode=false: only blank-author notes are claimed. + * - contributorMode=true: blank → authored; already-authored-by- + * someone-else → we're added to `contributors` (original author + * untouched). Notes already authored/contributed by us are skipped. + * - Folder scope shows a counted confirmation first. + * - Undo stores ONLY the changed paths (not content snapshots), so + * undoing a big claim is cheap; undo guards against clobbering a + * real author that landed after the claim. */ + private async claimAuthorship(opts: { scope: "selection" | "folder"; contributorMode: boolean }): Promise<void> { + const author = this.currentAuthorLink(); + if (!author) { new Notice("Set your author name in Stashpad settings first."); return; } + const idTag = `-${author.id}`; + + const files = opts.scope === "selection" + ? this.getActionTargets().map((n) => n.file).filter((f): f is TFile => !!f) + : this.fileBackedNotesInFolder(); + if (files.length === 0) { new Notice(opts.scope === "selection" ? "No notes selected." : "No notes in this folder."); return; } + + const toAuthor: string[] = []; + const toContributor: string[] = []; + for (const f of files) { + const fm = this.app.metadataCache.getFileCache(f)?.frontmatter as any; + const a = typeof fm?.author === "string" ? fm.author : ""; + if (!a.trim()) { toAuthor.push(f.path); continue; } + if (a.includes(idTag)) continue; // already ours + if (!opts.contributorMode) continue; // skip authored + const contributors: string[] = Array.isArray(fm?.contributors) + ? fm.contributors.filter((c: any) => typeof c === "string") : []; + if (!contributors.some((c) => c.includes(idTag))) toContributor.push(f.path); + } + + const total = toAuthor.length + toContributor.length; + if (total === 0) { new Notice("Nothing to claim — those notes are already authored by you."); return; } + + if (opts.scope === "folder") { + const parts = [`Stamp yourself as author on ${toAuthor.length} unauthored note(s)`]; + if (toContributor.length) parts.push(`and as a contributor on ${toContributor.length} already-authored note(s)`); + const ok = await new Promise<boolean>((resolve) => { + new ConfirmModal(this.app, "Claim authorship", + `${parts.join(" ")}?\nExisting authors are never overwritten. This can be undone.`, + "Claim", resolve).open(); + }); + if (!ok) return; + } + + const folder = this.noteFolder; + const authorLink = author.link; + // 0.77.9: when we author-claim a note where we were ALSO a contributor, + // drop the (now-redundant) contributor entry — author supersedes. Track + // those paths so undo can faithfully restore the contributor entry. + const demotedFromContributor = new Set<string>(); + + // Forward apply, reused by redo. + const applyClaim = async () => { + await this.pacedFrontmatter(toAuthor, (m, path) => { + if (!(typeof m.author === "string" && m.author.trim())) m.author = authorLink; + if (Array.isArray(m.contributors) && m.contributors.some((c: any) => typeof c === "string" && c.includes(idTag))) { + m.contributors = m.contributors.filter((c: any) => !(typeof c === "string" && c.includes(idTag))); + demotedFromContributor.add(path); + } + }); + await this.pacedFrontmatter(toContributor, (m) => { + const contributors: string[] = Array.isArray(m.contributors) + ? m.contributors.filter((c: any) => typeof c === "string") : []; + if (!contributors.some((c) => c.includes(idTag))) contributors.push(authorLink); + m.contributors = contributors; + }); + }; + + void this.ensureAuthorFile(author); + await applyClaim(); + + this.plugin.getUndoStack(folder).push({ + label: `Claim authorship (${total} note${total === 1 ? "" : "s"})`, + undo: async () => { + // Only strip what we added, and only if it's still ours (a real + // author/contributor that landed afterwards is left intact). + await this.pacedFrontmatter(toAuthor, (m, path) => { + if (typeof m.author === "string" && m.author.includes(idTag)) delete m.author; + // Restore a contributor entry we demoted during the claim. + if (demotedFromContributor.has(path)) { + const contributors: string[] = Array.isArray(m.contributors) + ? m.contributors.filter((c: any) => typeof c === "string") : []; + if (!contributors.some((c) => c.includes(idTag))) contributors.push(authorLink); + m.contributors = contributors; + } + }); + await this.pacedFrontmatter(toContributor, (m) => { + if (Array.isArray(m.contributors)) { + m.contributors = m.contributors.filter((c: any) => !(typeof c === "string" && c.includes(idTag))); + } + }); + this.debouncedRender(); + }, + redo: async () => { demotedFromContributor.clear(); await applyClaim(); this.debouncedRender(); }, + }); + + const bits: string[] = []; + if (toAuthor.length) bits.push(`authored ${toAuthor.length}`); + if (toContributor.length) bits.push(`contributing to ${toContributor.length}`); + new Notice(`Claimed authorship: ${bits.join(", ")}. Undo available.`); + this.debouncedRender(); + } + /** Lazily create the author stub file under <stashpad>/_authors/. * Idempotent: skips if the file already exists. The stub carries a * small frontmatter with id + display name + created stamp, plus a @@ -8243,18 +8598,22 @@ export class StashpadView extends ItemView { * block note creation) but logged for diagnosis. */ private async ensureAuthorFile(info: { path: string; name: string; id: string }): Promise<void> { try { + // 0.77.1: register the author in the rebuildable registry (recovery + // cache + rename history). Cheap upsert; no-op if unchanged. + if (info.id) this.plugin.authorRegistry.record({ id: info.id, name: info.name }); const folder = `${this.noteFolder}/_authors`; await this.ensureFolder(folder); if (await this.app.vault.adapter.exists(info.path)) return; - const created = new Date().toISOString(); - const content = [ - "---", - `authorId: ${info.id}`, - `name: "${info.name.replace(/"/g, '\\"')}"`, - `created: ${created}`, - "---", - `# ${info.name}`, - ].join("\n"); + // 0.77.4: stub uses the Obsidian-native `aliases` for the display + // name (so [[Name]] resolves + quick-switcher finds it). Role/dept + // come from the local user's settings when this stub is theirs. + const isSelf = info.id === (this.plugin.settings.authorId ?? "").trim(); + const content = this.plugin.buildAuthorStub({ + id: info.id, + name: info.name, + role: isSelf ? this.plugin.settings.authorRole : undefined, + department: isSelf ? this.plugin.settings.authorDepartment : undefined, + }, new Date().toISOString()); await this.app.vault.create(info.path, content); } catch (e) { console.warn("[Stashpad] ensureAuthorFile failed", e); @@ -8617,6 +8976,28 @@ export class StashpadView extends ItemView { this.stickToListBottom = true; list.scrollTop = list.scrollHeight; + // 0.76.37: on mobile, skip the continuous re-pin entirely. The soft + // keyboard animating in/out, visualViewport resizes, and late + // markdown/attachment layout all change scrollHeight repeatedly after + // a composer submit — and the desktop watchdog below would yank the + // list to the bottom on every one of those, producing a visible + // up/down bounce. Instead do a few discrete, transition-aware + // settle scrolls and then leave the list alone. + if (Platform.isMobile) { + let tries = 0; + const settle = (): void => { + if (!this.stickToListBottom || tries >= 8) return; + tries++; + // Don't fight the keyboard while it's animating — just wait it out. + if (Date.now() >= this.keyboardTransitionUntil) { + list.scrollTop = list.scrollHeight; + } + window.setTimeout(settle, 120); + }; + window.setTimeout(settle, 60); + return; + } + // Per-row ResizeObserver: re-pin to bottom whenever any row's height // changes. Catches direct size changes (block re-layout, expand // toggles, etc.). diff --git a/styles.css b/styles.css index b0d54ae..10ba62b 100644 --- a/styles.css +++ b/styles.css @@ -1748,6 +1748,36 @@ margin-right: 6px; align-items: center; } +/* 0.77.5: known-authors registry list in settings. */ +.stashpad-known-authors-list { + display: flex; + flex-direction: column; + gap: 6px; + margin: 8px 0 4px; +} +.stashpad-known-author-row { + padding: 6px 10px; + border: 1px solid var(--background-modifier-border); + border-radius: 6px; + background: var(--background-secondary); +} +.stashpad-known-author-name { font-weight: 600; } +.stashpad-known-author-meta { color: var(--text-muted); font-size: 0.85em; } +.stashpad-known-author-history { + margin-top: 3px; + color: var(--text-faint); + font-size: 0.8em; +} +/* 0.76.33: glyph shown when an icon name isn't in the device's + bundled Lucide set (older iPad/iOS app) so the button isn't blank. + Sized to read like the icon it replaces. */ +.stashpad-icon-fallback { + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 15px; + line-height: 1; +} .stashpad-mobile-action-btn { width: 32px; height: 28px; @@ -2139,19 +2169,31 @@ margin-top: 12px; } -/* 0.76.18: compact confirm dialogs (delete, generic confirm, due - picker) size to their content instead of Obsidian's default tall - box — the leftover empty space looked oversized, especially on - mobile where modals lean large. */ +/* 0.76.28: compact confirm dialogs (delete, generic confirm, due + picker) size to their content. 0.76.18's `width: auto` shrank the + box to content width (cut the text off on mobile); now we use a + definite, readable width (capped on desktop, near-full on mobile) + and force the height to hug content with !important so Obsidian's + mobile modal min-height can't re-inflate it. */ .modal.stashpad-compact-modal { - height: auto; - min-height: 0; - width: auto; - max-width: min(440px, 92vw); + width: min(440px, 94vw) !important; + max-width: 94vw !important; + height: auto !important; + min-height: unset !important; + max-height: 85vh; + /* 0.76.29: don't clip the content — the bottom button row was + getting shaved by the modal's rounded-corner overflow when the + box hugged content exactly. */ + overflow: visible !important; } .modal.stashpad-compact-modal .modal-content { - max-height: 70vh; + height: auto; + min-height: 0; + max-height: 80vh; overflow-y: auto; + /* Clearance so the Cancel/Delete/Set row clears the modal's + bottom edge. */ + padding-bottom: 16px; } /* 0.76.1 / 0.76.5: due-date picker modal. Native date/time inputs @@ -2166,14 +2208,23 @@ gap: 8px; max-width: 260px; } +/* 0.76.22: give the picker icons a button-like background so they + read as clickable (they open the OS date/time picker). */ .stashpad-due-field-icon { display: inline-flex; align-items: center; - color: var(--text-muted); + justify-content: center; + width: 30px; + height: 30px; flex: 0 0 auto; + color: var(--text-muted); cursor: pointer; + border-radius: 6px; + border: 1px solid var(--background-modifier-border); + background: var(--interactive-normal); } -.stashpad-due-field-icon:hover { color: var(--text-normal); } +.stashpad-due-field-icon:hover { color: var(--text-normal); background: var(--interactive-hover); } +.stashpad-due-field-icon:active { background: var(--background-modifier-active-hover); } .stashpad-due-field-icon svg { width: 16px; height: 16px; } /* 0.76.8: hide the native right-side picker indicator — our left icon is the picker button now (calls showPicker). */ @@ -2193,13 +2244,17 @@ /* 0.76.17: uppercase any letters (month abbreviation / AM·PM). */ text-transform: uppercase; } -/* 0.76.17: kill the leading gap webkit reserves inside the value - editor (looked like stray space before the date now that the - picker indicator is hidden). */ +/* 0.76.17 / 0.76.22: kill the leading gap webkit reserves inside the + value editor so the date sits flush-left in its box (no stray + space where the picker indicator used to be). */ .stashpad-due-date::-webkit-datetime-edit, -.stashpad-due-time::-webkit-datetime-edit { padding: 0; } +.stashpad-due-time::-webkit-datetime-edit { padding: 0; margin: 0; } .stashpad-due-date::-webkit-datetime-edit-fields-wrapper, -.stashpad-due-time::-webkit-datetime-edit-fields-wrapper { padding: 0; } +.stashpad-due-time::-webkit-datetime-edit-fields-wrapper { padding: 0; margin: 0; } +.stashpad-due-date::-webkit-datetime-edit-text:first-child, +.stashpad-due-date::-webkit-datetime-edit-month-field:first-child, +.stashpad-due-date::-webkit-datetime-edit-year-field:first-child, +.stashpad-due-date::-webkit-datetime-edit-day-field:first-child { padding-left: 0; margin-left: 0; } .stashpad-due-grid { display: grid; grid-template-columns: repeat(3, 1fr); @@ -2384,6 +2439,33 @@ border-bottom: 1px solid var(--background-modifier-border); font-size: 0.85em; } +/* 0.77.0-feat: tiny-window transparency button + slider popover. */ +.stashpad-tiny-opacity-btn.is-active { color: var(--text-accent); } +.stashpad-tiny-opacity-popover { + position: absolute; + z-index: 50; + display: flex; + flex-direction: column; + gap: 6px; + width: 170px; + padding: 10px 12px; + border-radius: 8px; + background: var(--background-secondary); + border: 1px solid var(--background-modifier-border); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); +} +.stashpad-tiny-opacity-label { + font-size: var(--font-ui-smaller); + font-weight: 600; + color: var(--text-muted); +} +.stashpad-tiny-opacity-popover input[type="range"] { width: 100%; } +.stashpad-tiny-opacity-pct { + font-size: var(--font-ui-smaller); + color: var(--text-muted); + text-align: right; + font-variant-numeric: tabular-nums; +} .stashpad-tiny-title { flex: 1 1 auto; overflow: hidden;